diff --git a/src/boxerror.js b/src/boxerror.js index d727611c0..9d32b6a3d 100644 --- a/src/boxerror.js +++ b/src/boxerror.js @@ -60,3 +60,9 @@ BoxError.UNKNOWN_ERROR = 'Unknown Error'; // only used for porting BoxError.prototype.toPlainObject = function () { return _.extend({}, { message: this.message, reason: this.reason }, this.details); }; + +BoxError.prototype.setMessage = function (message) { + assert.strictEqual(typeof message, 'string'); + + this.message = message; +}; \ No newline at end of file diff --git a/src/ldap.js b/src/ldap.js index c03ee4667..1d2747fa9 100644 --- a/src/ldap.js +++ b/src/ldap.js @@ -11,12 +11,10 @@ var assert = require('assert'), async = require('async'), constants = require('./constants.js'), BoxError = require('./boxerror.js'), - DatabaseError = require('./databaseerror.js'), debug = require('debug')('box:ldap'), eventlog = require('./eventlog.js'), ldap = require('ldapjs'), mail = require('./mail.js'), - MailError = mail.MailError, mailboxdb = require('./mailboxdb.js'), path = require('path'), safe = require('safetydance'), @@ -262,7 +260,7 @@ function mailboxSearch(req, res, next) { if (parts.length !== 2) return next(new ldap.NoSuchObjectError(req.dn.toString())); mailboxdb.getMailbox(parts[0], parts[1], function (error, mailbox) { - if (error && error.reason === DatabaseError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.toString())); var obj = { @@ -335,7 +333,7 @@ function mailAliasSearch(req, res, next) { if (parts.length !== 2) return next(new ldap.NoSuchObjectError(req.dn.toString())); mailboxdb.getAlias(parts[0], parts[1], function (error, alias) { - if (error && error.reason === DatabaseError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.toString())); // https://wiki.debian.org/LDAP/MigrationTools/Examples @@ -373,7 +371,7 @@ function mailingListSearch(req, res, next) { if (parts.length !== 2) return next(new ldap.NoSuchObjectError(req.dn.toString())); mailboxdb.getList(parts[0], parts[1], function (error, list) { - if (error && error.reason === DatabaseError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.toString())); // http://ldapwiki.willeke.com/wiki/Original%20Mailgroup%20Schema%20From%20Netscape @@ -458,13 +456,13 @@ function authenticateUserMailbox(req, res, next) { if (parts.length !== 2) return next(new ldap.NoSuchObjectError(req.dn.toString())); mail.getDomain(parts[1], function (error, domain) { - if (error && error.reason === MailError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.message)); if (!domain.enabled) return next(new ldap.NoSuchObjectError(req.dn.toString())); mailboxdb.getMailbox(parts[0], parts[1], function (error, mailbox) { - if (error && error.reason === DatabaseError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.message)); users.verify(mailbox.ownerId, req.credentials || '', function (error, result) { @@ -556,7 +554,7 @@ function authenticateMailAddon(req, res, next) { const addonId = req.dn.rdns[1].attrs.ou.value.toLowerCase(); // 'sendmail' or 'recvmail' mail.getDomain(parts[1], function (error, domain) { - if (error && error.reason === MailError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.message)); if (addonId === 'recvmail' && !domain.enabled) return next(new ldap.NoSuchObjectError(req.dn.toString())); @@ -575,7 +573,7 @@ function authenticateMailAddon(req, res, next) { } mailboxdb.getMailbox(parts[0], parts[1], function (error, mailbox) { - if (error && error.reason === DatabaseError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); + if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString())); if (error) return next(new ldap.OperationsError(error.message)); users.verify(mailbox.ownerId, req.credentials || '', function (error, result) { diff --git a/src/mail.js b/src/mail.js index e6cd76275..99c4842e9 100644 --- a/src/mail.js +++ b/src/mail.js @@ -46,15 +46,13 @@ exports = module.exports = { updateList: updateList, removeList: removeList, - _readDkimPublicKeySync: readDkimPublicKeySync, - - MailError: MailError + _readDkimPublicKeySync: readDkimPublicKeySync }; var assert = require('assert'), async = require('async'), + BoxError = require('./boxerror.js'), constants = require('./constants.js'), - DatabaseError = require('./databaseerror.js'), debug = require('debug')('box:mail'), dns = require('./native-dns.js'), domains = require('./domains.js'), @@ -75,47 +73,20 @@ var assert = require('assert'), smtpTransport = require('nodemailer-smtp-transport'), sysinfo = require('./sysinfo.js'), users = require('./users.js'), - util = require('util'), validator = require('validator'), _ = require('underscore'); const DNS_OPTIONS = { timeout: 5000 }; var NOOP_CALLBACK = function (error) { if (error) debug(error); }; -function MailError(reason, errorOrMessage) { - assert.strictEqual(typeof reason, 'string'); - assert(errorOrMessage instanceof Error || typeof errorOrMessage === 'string' || typeof errorOrMessage === 'undefined'); - - Error.call(this); - Error.captureStackTrace(this, this.constructor); - - this.name = this.constructor.name; - this.reason = reason; - if (typeof errorOrMessage === 'undefined') { - this.message = reason; - } else if (typeof errorOrMessage === 'string') { - this.message = errorOrMessage; - } else { - this.message = 'Internal error'; - this.nestedError = errorOrMessage; - } -} -util.inherits(MailError, Error); -MailError.INTERNAL_ERROR = 'Internal Error'; -MailError.EXTERNAL_ERROR = 'External Error'; -MailError.BAD_FIELD = 'Bad Field'; -MailError.ALREADY_EXISTS = 'Already Exists'; -MailError.NOT_FOUND = 'Not Found'; -MailError.IN_USE = 'In Use'; - function validateName(name) { assert.strictEqual(typeof name, 'string'); - if (name.length < 1) return new MailError(MailError.BAD_FIELD, 'mailbox name must be atleast 1 char'); - if (name.length >= 200) return new MailError(MailError.BAD_FIELD, 'mailbox name too long'); + if (name.length < 1) return new BoxError(BoxError.BAD_FIELD, 'mailbox name must be atleast 1 char'); + if (name.length >= 200) return new BoxError(BoxError.BAD_FIELD, 'mailbox name too long'); // also need to consider valid LDAP characters here (e.g '+' is reserved) - if (/[^a-zA-Z0-9.-]/.test(name)) return new MailError(MailError.BAD_FIELD, 'mailbox name can only contain alphanumerals and dot'); + if (/[^a-zA-Z0-9.-]/.test(name)) return new BoxError(BoxError.BAD_FIELD, 'mailbox name can only contain alphanumerals and dot'); return null; } @@ -204,7 +175,7 @@ function verifyRelay(relay, callback) { if (relay.provider === 'cloudron-smtp' || relay.provider === 'noop') return callback(); checkSmtpRelay(relay, function (error) { - if (error) return callback(new MailError(MailError.BAD_FIELD, error.message)); + if (error) return callback(new BoxError(BoxError.BAD_FIELD, error.message)); callback(); }); @@ -701,7 +672,8 @@ function restartMailIfActivated(callback) { assert.strictEqual(typeof callback, 'function'); users.isActivated(function (error, activated) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); + if (!activated) { debug('restartMailIfActivated: skipping restart of mail container since Cloudron is not activated yet'); return callback(); // not provisioned yet, do not restart container after dns setup @@ -723,8 +695,7 @@ function getDomain(domain, callback) { assert.strictEqual(typeof callback, 'function'); maildb.get(domain, function (error, result) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); return callback(null, result); }); @@ -734,7 +705,7 @@ function getDomains(callback) { assert.strictEqual(typeof callback, 'function'); maildb.list(function (error, results) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); return callback(null, results); }); @@ -747,7 +718,7 @@ function txtRecordsWithSpf(domain, mailFqdn, callback) { assert.strictEqual(typeof callback, 'function'); domains.getDnsRecords('', domain, 'TXT', function (error, txtRecords) { - if (error) return new MailError(MailError.EXTERNAL_ERROR, error.message); + if (error) return error; debug('txtRecordsWithSpf: current txt records - %j', txtRecords); @@ -796,16 +767,16 @@ function ensureDkimKeySync(mailDomain) { if (!safe.fs.mkdirSync(dkimPath) && safe.error.code !== 'EEXIST') { debug('Error creating dkim.', safe.error); - return new MailError(MailError.INTERNAL_ERROR, safe.error); + return new BoxError(BoxError.FS_ERROR, safe.error); } - if (!safe.child_process.execSync('openssl genrsa -out ' + dkimPrivateKeyFile + ' 1024')) return new MailError(MailError.INTERNAL_ERROR, safe.error); - if (!safe.child_process.execSync('openssl rsa -in ' + dkimPrivateKeyFile + ' -out ' + dkimPublicKeyFile + ' -pubout -outform PEM')) return new MailError(MailError.INTERNAL_ERROR, safe.error); + if (!safe.child_process.execSync('openssl genrsa -out ' + dkimPrivateKeyFile + ' 1024')) return new BoxError(BoxError.OPENSSL_ERROR, safe.error); + if (!safe.child_process.execSync('openssl rsa -in ' + dkimPrivateKeyFile + ' -out ' + dkimPublicKeyFile + ' -pubout -outform PEM')) return new BoxError(BoxError.OPENSSL_ERROR, safe.error); - if (!safe.fs.writeFileSync(dkimSelectorFile, mailDomain.dkimSelector, 'utf8')) return new MailError(MailError.INTERNAL_ERROR, safe.error); + if (!safe.fs.writeFileSync(dkimSelectorFile, mailDomain.dkimSelector, 'utf8')) return new BoxError(BoxError.FS_ERROR, safe.error); // if the 'yellowtent' user of OS and the 'cloudron' user of mail container don't match, the keys become inaccessible by mail code - if (!safe.fs.chmodSync(dkimPrivateKeyFile, 0o644)) return new MailError(MailError.INTERNAL_ERROR, safe.error); + if (!safe.fs.chmodSync(dkimPrivateKeyFile, 0o644)) return new BoxError(BoxError.FS_ERROR, safe.error); return null; } @@ -837,8 +808,7 @@ function upsertDnsRecords(domain, mailFqdn, callback) { debug(`upsertDnsRecords: updating mail dns records of domain ${domain} and mail fqdn ${mailFqdn}`); maildb.get(domain, function (error, mailDomain) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); error = ensureDkimKeySync(mailDomain); if (error) return callback(error); @@ -846,7 +816,7 @@ function upsertDnsRecords(domain, mailFqdn, callback) { if (process.env.BOX_ENV === 'test') return callback(); var dkimKey = readDkimPublicKeySync(domain); - if (!dkimKey) return callback(new MailError(MailError.INTERNAL_ERROR, new Error('Failed to read dkim public key'))); + if (!dkimKey) return callback(new BoxError(BoxError.FS_ERROR, new Error('Failed to read dkim public key'))); // t=s limits the domainkey to this domain and not it's subdomains var dkimRecord = { subdomain: `${mailDomain.dkimSelector}._domainkey`, domain: domain, type: 'TXT', values: [ '"v=DKIM1; t=s; p=' + dkimKey + '"' ] }; @@ -870,7 +840,7 @@ function upsertDnsRecords(domain, mailFqdn, callback) { }, function (error, changeIds) { if (error) { debug(`upsertDnsRecords: failed to update: ${error}`); - return callback(new MailError(MailError.EXTERNAL_ERROR, error.message)); + return callback(error); } debug('upsertDnsRecords: records %j added with changeIds %j', records, changeIds); @@ -895,12 +865,12 @@ function onMailFqdnChanged(callback) { mailDomain = settings.adminDomain(); domains.getAll(function (error, allDomains) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error.setMessage('Error getting domains')); async.eachOfSeries(allDomains, function (domainObject, idx, iteratorDone) { upsertDnsRecords(domainObject.domain, mailFqdn, iteratorDone); }, function (error) { - if (error) return callback(new MailError(MailError.EXTERNAL_ERROR, error.message)); + if (error) return callback(error); configureMail(mailFqdn, mailDomain, callback); }); @@ -914,9 +884,7 @@ function addDomain(domain, callback) { const dkimSelector = domain === settings.adminDomain() ? 'cloudron' : ('cloudron-' + settings.adminDomain().replace(/\./g, '')); maildb.add(domain, { dkimSelector }, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, 'Domain already exists')); - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'No such domain')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); async.series([ upsertDnsRecords.bind(null, domain, settings.mailFqdn()), // do this first to ensure DKIM keys @@ -931,12 +899,10 @@ function removeDomain(domain, callback) { assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof callback, 'function'); - if (domain === settings.adminDomain()) return callback(new MailError(MailError.IN_USE)); + if (domain === settings.adminDomain()) return callback(new BoxError(BoxError.CONFLICT)); maildb.del(domain, function (error) { - if (error && error.reason === DatabaseError.IN_USE) return callback(new MailError(MailError.IN_USE)); - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, error.message)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); restartMail(NOOP_CALLBACK); @@ -948,7 +914,7 @@ function clearDomains(callback) { assert.strictEqual(typeof callback, 'function'); maildb.clear(function (error) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(); }); @@ -970,8 +936,7 @@ function setMailFromValidation(domain, enabled, callback) { assert.strictEqual(typeof callback, 'function'); maildb.update(domain, { mailFromValidation: enabled }, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); restartMail(NOOP_CALLBACK); // have to restart mail container since haraka cannot watch symlinked config files (mail.ini) @@ -985,8 +950,7 @@ function setCatchAllAddress(domain, addresses, callback) { assert.strictEqual(typeof callback, 'function'); maildb.update(domain, { catchAll: addresses }, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); restartMail(NOOP_CALLBACK); // have to restart mail container since haraka cannot watch symlinked config files (mail.ini) @@ -1012,8 +976,7 @@ function setMailRelay(domain, relay, callback) { if (error) return callback(error); maildb.update(domain, { relay: relay }, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); restartMail(NOOP_CALLBACK); @@ -1030,8 +993,7 @@ function setMailEnabled(domain, enabled, auditSource, callback) { assert.strictEqual(typeof callback, 'function'); maildb.update(domain, { enabled: enabled }, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); restartMail(NOOP_CALLBACK); @@ -1050,7 +1012,7 @@ function sendTestMail(domain, to, callback) { if (error) return callback(error); mailer.sendTestMail(result.domain, to, function (error) { - if (error) return callback(new MailError(MailError.EXTERNAL_ERROR, error.message)); + if (error) return callback(error); callback(); }); @@ -1064,7 +1026,7 @@ function listMailboxes(domain, page, perPage, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.listMailboxes(domain, page, perPage, function (error, result) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, result); }); @@ -1075,7 +1037,7 @@ function removeMailboxes(domain, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.delByDomain(domain, function (error) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(); }); @@ -1087,8 +1049,7 @@ function getMailbox(name, domain, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.getMailbox(name, domain, function (error, result) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, result); }); @@ -1107,8 +1068,7 @@ function addMailbox(name, domain, userId, auditSource, callback) { if (error) return callback(error); mailboxdb.addMailbox(name, domain, userId, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, `mailbox ${name} already exists`)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); eventlog.add(eventlog.ACTION_MAIL_MAILBOX_ADD, auditSource, { name, domain, userId }); @@ -1125,8 +1085,7 @@ function updateMailboxOwner(name, domain, userId, callback) { name = name.toLowerCase(); mailboxdb.updateMailboxOwner(name, domain, userId, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null); }); @@ -1139,8 +1098,7 @@ function removeMailbox(name, domain, auditSource, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.del(name, domain, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); eventlog.add(eventlog.ACTION_MAIL_MAILBOX_REMOVE, auditSource, { name, domain }); @@ -1155,8 +1113,7 @@ function listAliases(domain, page, perPage, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.listAliases(domain, page, perPage, function (error, result) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, error.message)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, result); }); @@ -1171,8 +1128,7 @@ function getAliases(name, domain, callback) { if (error) return callback(error); mailboxdb.getAliasesForName(name, domain, function (error, aliases) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, aliases); }); @@ -1193,14 +1149,12 @@ function setAliases(name, domain, aliases, callback) { } mailboxdb.setAliasesForName(name, domain, aliases, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS && error.message.indexOf('mailboxes_name_domain_unique_index') !== -1) { + if (error && error.reason === BoxError.ALREADY_EXISTS && error.message.indexOf('mailboxes_name_domain_unique_index') !== -1) { var aliasMatch = error.message.match(new RegExp(`^ER_DUP_ENTRY: Duplicate entry '(.*)-${domain}' for key 'mailboxes_name_domain_unique_index'$`)); - if (!aliasMatch) return callback(new MailError(MailError.ALREADY_EXISTS, error.message)); - return callback(new MailError(MailError.ALREADY_EXISTS, `Mailbox, mailinglist or alias for ${aliasMatch[1]} already exists`)); + if (!aliasMatch) return callback(error); + return callback(error.setMessage(`Mailbox, mailinglist or alias for ${aliasMatch[1]} already exists`)); } - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, error.message)); - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null); }); @@ -1211,7 +1165,7 @@ function getLists(domain, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.getLists(domain, function (error, result) { - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, result); }); @@ -1223,8 +1177,7 @@ function getList(domain, listName, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.getList(listName, domain, function (error, result) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such list')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, result); }); @@ -1243,12 +1196,11 @@ function addList(name, domain, members, auditSource, callback) { if (error) return callback(error); for (var i = 0; i < members.length; i++) { - if (!validator.isEmail(members[i])) return callback(new MailError(MailError.BAD_FIELD, 'Invalid mail member: ' + members[i])); + if (!validator.isEmail(members[i])) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid mail member: ' + members[i])); } mailboxdb.addList(name, domain, members, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new MailError(MailError.ALREADY_EXISTS, 'list already exits')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); eventlog.add(eventlog.ACTION_MAIL_LIST_ADD, auditSource, { name, domain }); @@ -1268,12 +1220,11 @@ function updateList(name, domain, members, callback) { if (error) return callback(error); for (var i = 0; i < members.length; i++) { - if (!validator.isEmail(members[i])) return callback(new MailError(MailError.BAD_FIELD, 'Invalid email: ' + members[i])); + if (!validator.isEmail(members[i])) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid email: ' + members[i])); } mailboxdb.updateList(name, domain, members, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such mailbox')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null); }); @@ -1286,8 +1237,7 @@ function removeList(name, domain, auditSource, callback) { assert.strictEqual(typeof callback, 'function'); mailboxdb.del(name, domain, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND, 'no such list')); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); + if (error) return callback(error); eventlog.add(eventlog.ACTION_MAIL_LIST_ADD, auditSource, { name, domain }); diff --git a/src/mailboxdb.js b/src/mailboxdb.js index d5952686a..4d22f76b9 100644 --- a/src/mailboxdb.js +++ b/src/mailboxdb.js @@ -33,8 +33,8 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('./boxerror.js'), database = require('./database.js'), - DatabaseError = require('./databaseerror.js'), safe = require('safetydance'), util = require('util'); @@ -54,8 +54,8 @@ function addMailbox(name, domain, ownerId, callback) { assert.strictEqual(typeof callback, 'function'); database.query('INSERT INTO mailboxes (name, type, domain, ownerId) VALUES (?, ?, ?, ?)', [ name, exports.TYPE_MAILBOX, domain, ownerId ], function (error) { - if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS, 'mailbox already exists')); - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS, 'mailbox already exists')); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); @@ -68,8 +68,8 @@ function updateMailboxOwner(name, domain, ownerId, callback) { assert.strictEqual(typeof callback, 'function'); database.query('UPDATE mailboxes SET ownerId = ? WHERE name = ? AND domain = ?', [ ownerId, name, domain ], function (error, result) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.affectedRows === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (result.affectedRows === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null); }); @@ -83,8 +83,8 @@ function addList(name, domain, members, callback) { database.query('INSERT INTO mailboxes (name, type, domain, ownerId, membersJson) VALUES (?, ?, ?, ?, ?)', [ name, exports.TYPE_LIST, domain, 'admin', JSON.stringify(members) ], function (error) { - if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS, 'mailbox already exists')); - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS, 'mailbox already exists')); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); @@ -98,8 +98,8 @@ function updateList(name, domain, members, callback) { database.query('UPDATE mailboxes SET membersJson = ? WHERE name = ? AND domain = ?', [ JSON.stringify(members), name, domain ], function (error, result) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.affectedRows === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (result.affectedRows === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null); }); @@ -109,7 +109,7 @@ function clear(callback) { assert.strictEqual(typeof callback, 'function'); database.query('TRUNCATE TABLE mailboxes', [], function (error) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); } @@ -121,8 +121,8 @@ function del(name, domain, callback) { // deletes aliases as well database.query('DELETE FROM mailboxes WHERE (name=? OR aliasTarget = ?) AND domain = ?', [ name, name, domain ], function (error, result) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.affectedRows === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (result.affectedRows === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null); }); @@ -133,7 +133,7 @@ function delByDomain(domain, callback) { assert.strictEqual(typeof callback, 'function'); database.query('DELETE FROM mailboxes WHERE domain = ?', [ domain ], function (error) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); @@ -144,7 +144,7 @@ function delByOwnerId(id, callback) { assert.strictEqual(typeof callback, 'function'); database.query('DELETE FROM mailboxes WHERE ownerId=?', [ id ], function (error) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); @@ -161,9 +161,9 @@ function updateName(oldName, oldDomain, newName, newDomain, callback) { if (oldName === newName && oldDomain === newDomain) return callback(null); database.query('UPDATE mailboxes SET name=?, domain=? WHERE name=? AND domain = ?', [ newName, newDomain, oldName, oldDomain ], function (error, result) { - if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS, 'mailbox already exists')); - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.affectedRows !== 1) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS, 'mailbox already exists')); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (result.affectedRows !== 1) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null); }); @@ -176,8 +176,8 @@ function getMailbox(name, domain, callback) { database.query('SELECT ' + MAILBOX_FIELDS + ' FROM mailboxes WHERE name = ? AND type = ? AND domain = ?', [ name, exports.TYPE_MAILBOX, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (results.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (results.length === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null, postProcess(results[0])); }); @@ -191,7 +191,7 @@ function listMailboxes(domain, page, perPage, callback) { database.query(`SELECT ${MAILBOX_FIELDS} FROM mailboxes WHERE type = ? AND domain = ? ORDER BY name LIMIT ${(page-1)*perPage},${perPage}`, [ exports.TYPE_MAILBOX, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); @@ -205,7 +205,7 @@ function getLists(domain, callback) { database.query('SELECT ' + MAILBOX_FIELDS + ' FROM mailboxes WHERE type = ? AND domain = ?', [ exports.TYPE_LIST, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); @@ -220,8 +220,8 @@ function getList(name, domain, callback) { database.query('SELECT ' + MAILBOX_FIELDS + ' FROM mailboxes WHERE type = ? AND name = ? AND domain = ?', [ exports.TYPE_LIST, name, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (results.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (results.length === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null, postProcess(results[0])); }); @@ -232,8 +232,8 @@ function getByOwnerId(ownerId, callback) { assert.strictEqual(typeof callback, 'function'); database.query('SELECT ' + MAILBOX_FIELDS + ' FROM mailboxes WHERE ownerId = ? ORDER BY name', [ ownerId ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (results.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (results.length === 0) return callback(new BoxError(BoxError.NOT_FOUND)); results.forEach(function (result) { postProcess(result); }); @@ -248,8 +248,8 @@ function setAliasesForName(name, domain, aliases, callback) { assert.strictEqual(typeof callback, 'function'); database.query('SELECT ' + MAILBOX_FIELDS + ' FROM mailboxes WHERE name = ? AND domain = ?', [ name, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (results.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (results.length === 0) return callback(new BoxError(BoxError.NOT_FOUND)); var queries = []; // clear existing aliases @@ -260,8 +260,8 @@ function setAliasesForName(name, domain, aliases, callback) { }); database.transaction(queries, function (error) { - if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS, error.message)); - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS, error.message)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); @@ -275,7 +275,7 @@ function getAliasesForName(name, domain, callback) { database.query('SELECT name FROM mailboxes WHERE type = ? AND aliasTarget = ? AND domain = ? ORDER BY name', [ exports.TYPE_ALIAS, name, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results = results.map(function (r) { return r.name; }); callback(null, results); @@ -290,7 +290,7 @@ function listAliases(domain, page, perPage, callback) { database.query(`SELECT ${MAILBOX_FIELDS} FROM mailboxes WHERE domain = ? AND type = ? ORDER BY name LIMIT ${(page-1)*perPage},${perPage}`, [ domain, exports.TYPE_ALIAS ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); @@ -305,8 +305,8 @@ function getAlias(name, domain, callback) { database.query('SELECT ' + MAILBOX_FIELDS + ' FROM mailboxes WHERE name = ? AND type = ? AND domain = ?', [ name, exports.TYPE_ALIAS, domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (results.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (results.length === 0) return callback(new BoxError(BoxError.NOT_FOUND)); results.forEach(function (result) { postProcess(result); }); diff --git a/src/maildb.js b/src/maildb.js index 8e21695a1..b7c516f49 100644 --- a/src/maildb.js +++ b/src/maildb.js @@ -15,8 +15,8 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('./boxerror.js'), database = require('./database.js'), - DatabaseError = require('./databaseerror.js'), safe = require('safetydance'); var MAILDB_FIELDS = [ 'domain', 'enabled', 'mailFromValidation', 'catchAllJson', 'relayJson', 'dkimSelector' ].join(','); @@ -40,9 +40,9 @@ function add(domain, data, callback) { assert.strictEqual(typeof callback, 'function'); database.query('INSERT INTO mail (domain, dkimSelector) VALUES (?, ?)', [ domain, data.dkimSelector || 'cloudron' ], function (error) { - if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS, 'mail domain already exists')); - if (error && error.code === 'ER_NO_REFERENCED_ROW_2') return callback(new DatabaseError(DatabaseError.NOT_FOUND), 'no such domain'); - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS, 'mail domain already exists')); + if (error && error.code === 'ER_NO_REFERENCED_ROW_2') return callback(new BoxError(BoxError.NOT_FOUND), 'no such domain'); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); @@ -53,7 +53,7 @@ function clear(callback) { // using TRUNCATE makes it fail foreign key check database.query('DELETE FROM mail', [], function (error) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); } @@ -64,9 +64,9 @@ function del(domain, callback) { // deletes aliases as well database.query('DELETE FROM mail WHERE domain=?', [ domain ], function (error, result) { - if (error && error.code === 'ER_ROW_IS_REFERENCED_2') return callback(new DatabaseError(DatabaseError.IN_USE)); - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.affectedRows === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error && error.code === 'ER_ROW_IS_REFERENCED_2') return callback(new BoxError(BoxError.IN_USE)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (result.affectedRows === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null); }); @@ -77,8 +77,8 @@ function get(domain, callback) { assert.strictEqual(typeof callback, 'function'); database.query('SELECT ' + MAILDB_FIELDS + ' FROM mail WHERE domain = ?', [ domain ], function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (results.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (results.length === 0) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null, postProcess(results[0])); }); @@ -88,7 +88,7 @@ function list(callback) { assert.strictEqual(typeof callback, 'function'); database.query('SELECT ' + MAILDB_FIELDS + ' FROM mail ORDER BY domain', function (error, results) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); @@ -118,8 +118,8 @@ function update(domain, data, callback) { args.push(domain); database.query('UPDATE mail SET ' + fields.join(', ') + ' WHERE domain=?', args, function (error, result) { - if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); - if (result.affectedRows !== 1) return callback(new DatabaseError(DatabaseError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); + if (result.affectedRows !== 1) return callback(new BoxError(BoxError.NOT_FOUND)); callback(null); }); diff --git a/src/mailer.js b/src/mailer.js index 86623d74e..cebc3bfc4 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -25,6 +25,7 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('./boxerror.js'), constants = require('./constants.js'), custom = require('./custom.js'), debug = require('debug')('box:mailer'), @@ -93,7 +94,7 @@ function sendMail(mailOptions, callback) { })); transport.sendMail(mailOptions, function (error) { - if (error) return callback(error); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); debug(`Email "${mailOptions.subject}" sent to ${mailOptions.to}`); diff --git a/src/routes/mail.js b/src/routes/mail.js index 4fef919d7..e895be0d0 100644 --- a/src/routes/mail.js +++ b/src/routes/mail.js @@ -36,8 +36,8 @@ exports = module.exports = { var assert = require('assert'), auditSource = require('../auditsource.js'), + BoxError = require('../boxerror.js'), mail = require('../mail.js'), - MailError = mail.MailError, HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, middleware = require('../middleware/index.js'), @@ -45,12 +45,28 @@ var assert = require('assert'), var mailProxy = middleware.proxy(url.parse('http://127.0.0.1:2020')); +function toHttpError(error) { + switch (error.reason) { + case BoxError.NOT_FOUND: + return new HttpError(404, error); + case BoxError.ALREADY_EXISTS: + case BoxError.CONFLICT: + return new HttpError(409, error); + case BoxError.BAD_FIELD: + return new HttpError(400, error); + case BoxError.EXTERNAL_ERROR: + return new HttpError(424, error); + case BoxError.INTERNAL_ERROR: + default: + return new HttpError(500, error); + } +} + function getDomain(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); mail.getDomain(req.params.domain, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, mail.removePrivateFields(result))); }); @@ -62,9 +78,7 @@ function addDomain(req, res, next) { if (typeof req.body.domain !== 'string') return next(new HttpError(400, 'domain must be a string')); mail.addDomain(req.body.domain, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.ALREADY_EXISTS) return next(new HttpError(409, 'domain already exists')); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(201, { domain: req.body.domain })); }); @@ -92,9 +106,7 @@ function setDnsRecords(req, res, next) { req.clearTimeout(); mail.setDnsRecords(req.params.domain, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.EXTERNAL_ERROR) return next(new HttpError(424, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(201)); }); @@ -104,9 +116,7 @@ function removeDomain(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); mail.removeDomain(req.params.domain, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.IN_USE) return next(new HttpError(409, 'Mail domain is still in use. Remove existing mailboxes')); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(204)); }); @@ -119,8 +129,7 @@ function getStatus(req, res, next) { req.clearTimeout(); mail.getStatus(req.params.domain, function (error, records) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, records)); }); @@ -133,9 +142,7 @@ function setMailFromValidation(req, res, next) { if (typeof req.body.enabled !== 'boolean') return next(new HttpError(400, 'enabled is required')); mail.setMailFromValidation(req.params.domain, req.body.enabled, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(202)); }); @@ -153,9 +160,7 @@ function setCatchAllAddress(req, res, next) { } mail.setCatchAllAddress(req.params.domain, req.body.addresses, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(202)); }); @@ -173,9 +178,7 @@ function setMailRelay(req, res, next) { if ('acceptSelfSignedCerts' in req.body && typeof req.body.acceptSelfSignedCerts !== 'boolean') return next(new HttpError(400, 'acceptSelfSignedCerts must be a boolean')); mail.setMailRelay(req.params.domain, req.body, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(202)); }); @@ -188,9 +191,7 @@ function setMailEnabled(req, res, next) { if (typeof req.body.enabled !== 'boolean') return next(new HttpError(400, 'enabled is required')); mail.setMailEnabled(req.params.domain, !!req.body.enabled, auditSource.fromRequest(req), function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(202)); }); @@ -203,9 +204,7 @@ function sendTestMail(req, res, next) { if (!req.body.to || typeof req.body.to !== 'string') return next(new HttpError(400, 'to must be a non-empty string')); mail.sendTestMail(req.params.domain, req.body.to, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.EXTERNAL_ERROR) return next(new HttpError(424, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(202)); }); @@ -221,8 +220,7 @@ function listMailboxes(req, res, next) { if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); mail.listMailboxes(req.params.domain, page, perPage, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { mailboxes: result })); }); @@ -233,8 +231,7 @@ function getMailbox(req, res, next) { assert.strictEqual(typeof req.params.name, 'string'); mail.getMailbox(req.params.name, req.params.domain, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { mailbox: result })); }); @@ -247,10 +244,7 @@ function addMailbox(req, res, next) { if (typeof req.body.userId !== 'string') return next(new HttpError(400, 'userId must be a string')); mail.addMailbox(req.body.name, req.params.domain, req.body.userId, auditSource.fromRequest(req), function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.ALREADY_EXISTS) return next(new HttpError(409, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(201, {})); }); @@ -263,9 +257,7 @@ function updateMailbox(req, res, next) { if (typeof req.body.userId !== 'string') return next(new HttpError(400, 'userId must be a string')); mail.updateMailboxOwner(req.params.name, req.params.domain, req.body.userId, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(204)); }); @@ -276,8 +268,7 @@ function removeMailbox(req, res, next) { assert.strictEqual(typeof req.params.name, 'string'); mail.removeMailbox(req.params.name, req.params.domain, auditSource.fromRequest(req), function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(201, {})); }); @@ -293,8 +284,7 @@ function listAliases(req, res, next) { if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); mail.listAliases(req.params.domain, page, perPage, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { aliases: result })); }); @@ -305,8 +295,7 @@ function getAliases(req, res, next) { assert.strictEqual(typeof req.params.name, 'string'); mail.getAliases(req.params.name, req.params.domain, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { aliases: result })); }); @@ -324,10 +313,7 @@ function setAliases(req, res, next) { } mail.setAliases(req.params.name, req.params.domain, req.body.aliases, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.ALREADY_EXISTS) return next(new HttpError(409, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(202)); }); @@ -337,8 +323,7 @@ function getLists(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); mail.getLists(req.params.domain, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { lists: result })); }); @@ -349,8 +334,7 @@ function getList(req, res, next) { assert.strictEqual(typeof req.params.name, 'string'); mail.getList(req.params.domain, req.params.name, function (error, result) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { list: result })); }); @@ -369,10 +353,7 @@ function addList(req, res, next) { } mail.addList(req.body.name, req.params.domain, req.body.members, auditSource.fromRequest(req), function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.ALREADY_EXISTS) return next(new HttpError(409, 'list already exists')); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(201, {})); }); @@ -390,9 +371,7 @@ function updateList(req, res, next) { } mail.updateList(req.params.name, req.params.domain, req.body.members, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === MailError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(204)); }); @@ -403,8 +382,7 @@ function removeList(req, res, next) { assert.strictEqual(typeof req.params.name, 'string'); mail.removeList(req.params.name, req.params.domain, auditSource.fromRequest(req), function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(204)); }); diff --git a/src/test/database-test.js b/src/test/database-test.js index 89f158f39..038a864ad 100644 --- a/src/test/database-test.js +++ b/src/test/database-test.js @@ -2006,7 +2006,7 @@ describe('database', function () { it('cannot add dup entry', function (done) { mailboxdb.addMailbox('girish', DOMAIN_0.domain, 'uid-1', function (error) { - expect(error.reason).to.be(DatabaseError.ALREADY_EXISTS); + expect(error.reason).to.be(BoxError.ALREADY_EXISTS); done(); }); }); @@ -2091,7 +2091,7 @@ describe('database', function () { it('cannot get non-existing group', function (done) { mailboxdb.getList('random', DOMAIN_0.domain, function (error) { - expect(error.reason).to.be(DatabaseError.NOT_FOUND); + expect(error.reason).to.be(BoxError.NOT_FOUND); done(); }); }); @@ -2107,7 +2107,7 @@ describe('database', function () { it('cannot change name to existing one', function (done) { mailboxdb.updateName('support', DOMAIN_0.domain, 'support2', DOMAIN_0.domain, function (error) { expect(error).to.be.ok(); - expect(error.reason).to.eql(DatabaseError.ALREADY_EXISTS); + expect(error.reason).to.eql(BoxError.ALREADY_EXISTS); done(); }); @@ -2138,7 +2138,7 @@ describe('database', function () { mailboxdb.getByOwnerId('osticket', function (error) { expect(error).to.be.ok(); - expect(error.reason).to.be(DatabaseError.NOT_FOUND); + expect(error.reason).to.be(BoxError.NOT_FOUND); done(); }); }); @@ -2166,7 +2166,7 @@ describe('database', function () { it('cannot add non-existing domain', function (done) { maildb.add(MAIL_DOMAIN_0.domain + 'nope', {}, function (error) { expect(error).to.be.ok(); - expect(error.reason).to.be(DatabaseError.NOT_FOUND); + expect(error.reason).to.be(BoxError.NOT_FOUND); done(); });