diff --git a/src/apps.js b/src/apps.js index 77ae74f88..bcfc46484 100644 --- a/src/apps.js +++ b/src/apps.js @@ -115,7 +115,6 @@ var appdb = require('./appdb.js'), docker = require('./docker.js'), domaindb = require('./domaindb.js'), domains = require('./domains.js'), - DomainsError = require('./domains.js').DomainsError, eventlog = require('./eventlog.js'), fs = require('fs'), mail = require('./mail.js'), @@ -1146,10 +1145,9 @@ function setCertificate(appId, bundle, auditSource, callback) { if (error) return callback(error); domains.get(app.domain, function (error, domainObject) { - if (error && error.reason === DomainsError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such domain')); + if (error && error.reason === BoxError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such domain')); if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Could not get domain info:' + error.message)); - if (bundle.cert && bundle.key) { error = reverseProxy.validateCertificate(app.location, domainObject, { cert: bundle.cert, key: bundle.key }); if (error) return callback(new AppsError(AppsError.BAD_FIELD, error.message, { field: 'cert' })); diff --git a/src/apptask.js b/src/apptask.js index bd4f2fc5d..da5b836d1 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -33,7 +33,6 @@ var addons = require('./addons.js'), df = require('@sindresorhus/df'), docker = require('./docker.js'), domains = require('./domains.js'), - DomainsError = domains.DomainsError, ejs = require('ejs'), eventlog = require('./eventlog.js'), fs = require('fs'), @@ -365,9 +364,9 @@ function registerSubdomains(app, overwrite, callback) { // get the current record before updating it domains.getDnsRecords(domain.subdomain, domain.domain, 'A', function (error, values) { - if (error && error.reason === DomainsError.EXTERNAL_ERROR) return retryCallback(new BoxError(BoxError.EXTERNAL_ERROR, error.message, { domain })); // try again - if (error && error.reason === DomainsError.ACCESS_DENIED) return retryCallback(null, new BoxError(BoxError.ACCESS_DENIED, error.message, { domain })); - if (error && error.reason === DomainsError.NOT_FOUND) return retryCallback(null, new BoxError(BoxError.NOT_FOUND, error.message, { domain })); + if (error && error.reason === BoxError.EXTERNAL_ERROR) return retryCallback(new BoxError(BoxError.EXTERNAL_ERROR, error.message, { domain })); // try again + if (error && error.reason === BoxError.ACCESS_DENIED) return retryCallback(null, new BoxError(BoxError.ACCESS_DENIED, error.message, { domain })); + if (error && error.reason === BoxError.NOT_FOUND) return retryCallback(null, new BoxError(BoxError.NOT_FOUND, error.message, { domain })); if (error) return retryCallback(null, new BoxError(BoxError.EXTERNAL_ERROR, error.message, domain)); // give up for other errors if (values.length !== 0 && values[0] === ip) return retryCallback(null); // up-to-date @@ -376,7 +375,7 @@ function registerSubdomains(app, overwrite, callback) { if (values.length !== 0 && !overwrite) return retryCallback(null, new BoxError(BoxError.ALREADY_EXISTS, 'DNS Record already exists', { domain })); domains.upsertDnsRecords(domain.subdomain, domain.domain, 'A', [ ip ], function (error) { - if (error && (error.reason === DomainsError.STILL_BUSY || error.reason === DomainsError.EXTERNAL_ERROR)) { + if (error && (error.reason === BoxError.BUSY || error.reason === BoxError.EXTERNAL_ERROR)) { debug('registerSubdomains: Upsert error. Will retry.', error.message); return retryCallback(new BoxError(BoxError.EXTERNAL_ERROR, error.message, { domain })); // try again } @@ -406,8 +405,8 @@ function unregisterSubdomains(app, allDomains, callback) { debugApp(app, 'Unregistering subdomain: %s%s', domain.subdomain ? (domain.subdomain + '.') : '', domain.domain); domains.removeDnsRecords(domain.subdomain, domain.domain, 'A', [ ip ], function (error) { - if (error && error.reason === DomainsError.NOT_FOUND) return retryCallback(null, null); - if (error && (error.reason === DomainsError.STILL_BUSY || error.reason === DomainsError.EXTERNAL_ERROR)) { + if (error && error.reason === BoxError.NOT_FOUND) return retryCallback(null, null); + if (error && (error.reason === BoxError.SBUSY || error.reason === BoxError.EXTERNAL_ERROR)) { debug('registerSubdomains: Remove error. Will retry.', error.message); return retryCallback(new BoxError(BoxError.EXTERNAL_ERROR, error.message, { domain })); // try again } diff --git a/src/boxerror.js b/src/boxerror.js index 41dfab9aa..11dcfdd48 100644 --- a/src/boxerror.js +++ b/src/boxerror.js @@ -35,6 +35,7 @@ BoxError.ACCESS_DENIED = 'Access Denied'; BoxError.ALREADY_EXISTS = 'Already Exists'; BoxError.BAD_FIELD = 'Bad Field'; BoxError.BAD_STATE = 'Bad State'; +BoxError.BUSY = 'Busy'; BoxError.COLLECTD_ERROR = 'Collectd Error'; BoxError.CONFLICT = 'Conflict'; BoxError.DATABASE_ERROR = 'Database Error'; diff --git a/src/cloudron.js b/src/cloudron.js index 950e1be3f..0e58973f0 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -32,7 +32,6 @@ var apps = require('./apps.js'), cron = require('./cron.js'), debug = require('debug')('box:cloudron'), domains = require('./domains.js'), - DomainsError = require('./domains.js').DomainsError, eventlog = require('./eventlog.js'), custom = require('./custom.js'), fs = require('fs'), @@ -256,8 +255,7 @@ function prepareDashboardDomain(domain, auditSource, callback) { debug(`prepareDashboardDomain: ${domain}`); domains.get(domain, function (error, domainObject) { - if (error && error.reason === DomainsError.NOT_FOUND) return callback(new BoxError(BoxError.BAD_FIELD, 'No such domain', { field: 'domain' })); - if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); + if (error) return callback(error); const fqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject); @@ -287,8 +285,7 @@ function setDashboardDomain(domain, auditSource, callback) { debug(`setDashboardDomain: ${domain}`); domains.get(domain, function (error, domainObject) { - if (error && error.reason === DomainsError.NOT_FOUND) return callback(new BoxError(BoxError.BAD_FIELD, 'No such domain', { field: 'domain' })); - if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); + if (error) return callback(error); reverseProxy.writeAdminConfig(domain, function (error) { if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); diff --git a/src/dns/caas.js b/src/dns/caas.js index fb26d0b3c..533dd0485 100644 --- a/src/dns/caas.js +++ b/src/dns/caas.js @@ -11,14 +11,18 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/caas'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, settings = require('../settings.js'), superagent = require('superagent'), util = require('util'), waitForDns = require('./waitfordns.js'); +function formatError(response) { + return util.format('Caas DNS error [%s] %j', response.statusCode, response.body); +} + function getFqdn(location, domain) { assert.strictEqual(typeof location, 'string'); assert.strictEqual(typeof domain, 'string'); @@ -63,10 +67,10 @@ function upsert(domainObject, location, type, values, callback) { .send(data) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 400) return callback(new DomainsError(DomainsError.BAD_FIELD, result.body.message)); - if (result.statusCode === 420) return callback(new DomainsError(DomainsError.STILL_BUSY)); - if (result.statusCode !== 201) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('%s %j', result.statusCode, result.body))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 400) return callback(new BoxError(BoxError.BAD_FIELD, result.body.message)); + if (result.statusCode === 420) return callback(new BoxError(BoxError.BUSY)); + if (result.statusCode !== 201) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null); }); @@ -88,8 +92,8 @@ function get(domainObject, location, type, callback) { .query({ token: dnsConfig.token, type: type }) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('%s %j', result.statusCode, result.body))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null, result.body.values); }); @@ -116,11 +120,11 @@ function del(domainObject, location, type, values, callback) { .send(data) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 400) return callback(new DomainsError(DomainsError.BAD_FIELD, result.body.message)); - if (result.statusCode === 420) return callback(new DomainsError(DomainsError.STILL_BUSY)); - if (result.statusCode === 404) return callback(new DomainsError(DomainsError.NOT_FOUND)); - if (result.statusCode !== 204) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('%s %j', result.statusCode, result.body))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 400) return callback(new BoxError(BoxError.BAD_FIELD, result.body.message)); + if (result.statusCode === 420) return callback(new BoxError(BoxError.BUSY)); + if (result.statusCode === 404) return callback(new BoxError(BoxError.NOT_FOUND)); + if (result.statusCode !== 204) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null); }); @@ -145,7 +149,7 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config; - if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string')); + if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'token must be a non-empty string', { field: 'token' })); const ip = '127.0.0.1'; diff --git a/src/dns/cloudflare.js b/src/dns/cloudflare.js index 194f86ddc..c2cc04faf 100644 --- a/src/dns/cloudflare.js +++ b/src/dns/cloudflare.js @@ -12,10 +12,10 @@ exports = module.exports = { var assert = require('assert'), async = require('async'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/cloudflare'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, superagent = require('superagent'), util = require('util'), waitForDns = require('./waitfordns.js'), @@ -37,15 +37,15 @@ function translateRequestError(result, callback) { assert.strictEqual(typeof result, 'object'); assert.strictEqual(typeof callback, 'function'); - if (result.statusCode === 404) return callback(new DomainsError(DomainsError.NOT_FOUND, util.format('%s %j', result.statusCode, 'API does not exist'))); - if (result.statusCode === 422) return callback(new DomainsError(DomainsError.BAD_FIELD, result.body.message)); + if (result.statusCode === 404) return callback(new BoxError(BoxError.NOT_FOUND, util.format('%s %j', result.statusCode, 'API does not exist'))); + if (result.statusCode === 422) return callback(new BoxError(BoxError.BAD_FIELD, result.body.message)); if ((result.statusCode === 400 || result.statusCode === 401 || result.statusCode === 403) && result.body.errors.length > 0) { let error = result.body.errors[0]; let message = `message: ${error.message} statusCode: ${result.statusCode} code:${error.code}`; - return callback(new DomainsError(DomainsError.ACCESS_DENIED, message)); + return callback(new BoxError(BoxError.ACCESS_DENIED, message)); } - callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('%s %j', result.statusCode, result.body))); + callback(new BoxError(BoxError.EXTERNAL_ERROR, util.format('%s %j', result.statusCode, result.body))); } function getZoneByName(dnsConfig, zoneName, callback) { @@ -60,7 +60,7 @@ function getZoneByName(dnsConfig, zoneName, callback) { .end(function (error, result) { if (error && !error.response) return callback(error); if (result.statusCode !== 200 || result.body.success !== true) return translateRequestError(result, callback); - if (!result.body.result.length) return callback(new DomainsError(DomainsError.NOT_FOUND, util.format('%s %j', result.statusCode, result.body))); + if (!result.body.result.length) return callback(new BoxError(BoxError.NOT_FOUND, util.format('%s %j', result.statusCode, result.body))); callback(null, result.body.result[0]); }); @@ -259,7 +259,7 @@ function wait(domainObject, location, type, value, options, callback) { getDnsRecords(dnsConfig, zoneId, fqdn, type, function (error, dnsRecords) { if (error) return callback(error); - if (dnsRecords.length === 0) return callback(new DomainsError(DomainsError.NOT_FOUND, 'Domain not found')); + if (dnsRecords.length === 0) return callback(new BoxError(BoxError.NOT_FOUND, 'Domain not found')); if (!dnsRecords[0].proxied) return waitForDns(fqdn, domainObject.zoneName, type, value, options, callback); @@ -277,8 +277,8 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string')); - if (!dnsConfig.email || typeof dnsConfig.email !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'email must be a non-empty string')); + if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'token must be a non-empty string', { field: 'token' })); + if (!dnsConfig.email || typeof dnsConfig.email !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'email must be a non-empty string', { field: 'email' })); const ip = '127.0.0.1'; @@ -290,15 +290,15 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); getZoneByName(dnsConfig, zoneName, function(error, zone) { if (error) return callback(error); if (!_.isEqual(zone.name_servers.sort(), nameservers.sort())) { debug('verifyDnsConfig: %j and %j do not match', nameservers, zone.name_servers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Cloudflare')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to Cloudflare', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/digitalocean.js b/src/dns/digitalocean.js index b4d7df28e..26ef5fa1d 100644 --- a/src/dns/digitalocean.js +++ b/src/dns/digitalocean.js @@ -12,10 +12,10 @@ exports = module.exports = { var assert = require('assert'), async = require('async'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/digitalocean'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, safe = require('safetydance'), superagent = require('superagent'), util = require('util'), @@ -55,10 +55,10 @@ function getInternal(dnsConfig, zoneName, name, type, callback) { .timeout(30 * 1000) .retry(5) .end(function (error, result) { - if (error && !error.response) return iteratorDone(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 404) return iteratorDone(new DomainsError(DomainsError.NOT_FOUND, formatError(result))); - if (result.statusCode === 403 || result.statusCode === 401) return iteratorDone(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 200) return iteratorDone(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return iteratorDone(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 404) return iteratorDone(new BoxError(BoxError.NOT_FOUND, formatError(result))); + if (result.statusCode === 403 || result.statusCode === 401) return iteratorDone(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 200) return iteratorDone(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); matchingRecords = matchingRecords.concat(result.body.domain_records.filter(function (record) { return (record.type === type && record.name === name); @@ -119,10 +119,10 @@ function upsert(domainObject, location, type, values, callback) { .timeout(30 * 1000) .retry(5) .end(function (error, result) { - if (error && !error.response) return iteratorCallback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 403 || result.statusCode === 401) return iteratorCallback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode === 422) return iteratorCallback(new DomainsError(DomainsError.BAD_FIELD, result.body.message)); - if (result.statusCode !== 201) return iteratorCallback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return iteratorCallback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403 || result.statusCode === 401) return iteratorCallback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode === 422) return iteratorCallback(new BoxError(BoxError.BAD_FIELD, result.body.message)); + if (result.statusCode !== 201) return iteratorCallback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); recordIds.push(safe.query(result.body, 'domain_record.id')); @@ -138,10 +138,10 @@ function upsert(domainObject, location, type, values, callback) { // increment, as we have consumed the record ++i; - if (error && !error.response) return iteratorCallback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 403 || result.statusCode === 401) return iteratorCallback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode === 422) return iteratorCallback(new DomainsError(DomainsError.BAD_FIELD, result.body.message)); - if (result.statusCode !== 200) return iteratorCallback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return iteratorCallback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403 || result.statusCode === 401) return iteratorCallback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode === 422) return iteratorCallback(new BoxError(BoxError.BAD_FIELD, result.body.message)); + if (result.statusCode !== 200) return iteratorCallback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); recordIds.push(safe.query(result.body, 'domain_record.id')); @@ -209,10 +209,10 @@ function del(domainObject, location, type, values, callback) { .timeout(30 * 1000) .retry(5) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); if (result.statusCode === 404) return callback(null); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 204) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 204) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); debug('del: done'); @@ -241,7 +241,7 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string')); + if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'token must be a non-empty string', { field: 'token' })); const ip = '127.0.0.1'; @@ -252,12 +252,12 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); if (nameservers.map(function (n) { return n.toLowerCase(); }).indexOf('ns1.digitalocean.com') === -1) { debug('verifyDnsConfig: %j does not contains DO NS', nameservers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to DigitalOcean')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to DigitalOcean', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/gandi.js b/src/dns/gandi.js index d96f30900..fd16403f1 100644 --- a/src/dns/gandi.js +++ b/src/dns/gandi.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/gandi'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, superagent = require('superagent'), util = require('util'), waitForDns = require('./waitfordns.js'); @@ -57,10 +57,10 @@ function upsert(domainObject, location, type, values, callback) { .timeout(30 * 1000) .send(data) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode === 400) return callback(new DomainsError(DomainsError.BAD_FIELD, formatError(result))); - if (result.statusCode !== 201) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode === 400) return callback(new BoxError(BoxError.BAD_FIELD, formatError(result))); + if (result.statusCode !== 201) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null); }); @@ -82,10 +82,10 @@ function get(domainObject, location, type, callback) { .set('X-Api-Key', dnsConfig.token) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); if (result.statusCode === 404) return callback(null, [ ]); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); debug('get: %j', result.body); @@ -110,10 +110,10 @@ function del(domainObject, location, type, values, callback) { .set('X-Api-Key', dnsConfig.token) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); if (result.statusCode === 404) return callback(null); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 204) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 204) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); debug('del: done'); @@ -141,7 +141,7 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string')); + if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'token must be a non-empty string', { field: 'token' })); var credentials = { token: dnsConfig.token @@ -152,12 +152,12 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); if (!nameservers.every(function (n) { return n.toLowerCase().indexOf('.gandi.net') !== -1; })) { debug('verifyDnsConfig: %j does not contain Gandi NS', nameservers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Gandi')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to Gandi', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/gcdns.js b/src/dns/gcdns.js index 87a406b70..080307e72 100644 --- a/src/dns/gcdns.js +++ b/src/dns/gcdns.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/gcdns'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, GCDNS = require('@google-cloud/dns').DNS, util = require('util'), waitForDns = require('./waitfordns.js'), @@ -49,20 +49,20 @@ function getZoneByName(dnsConfig, zoneName, callback) { var gcdns = new GCDNS(getDnsCredentials(dnsConfig)); gcdns.getZones(function (error, zones) { - if (error && error.message === 'invalid_grant') return callback(new DomainsError(DomainsError.ACCESS_DENIED, 'The key was probably revoked')); - if (error && error.reason === 'No such domain') return callback(new DomainsError(DomainsError.NOT_FOUND, error.message)); - if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 404) return callback(new DomainsError(DomainsError.NOT_FOUND, error.message)); + if (error && error.message === 'invalid_grant') return callback(new BoxError(BoxError.ACCESS_DENIED, 'The key was probably revoked')); + if (error && error.reason === 'No such domain') return callback(new BoxError(BoxError.NOT_FOUND, error.message)); + if (error && error.code === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 404) return callback(new BoxError(BoxError.NOT_FOUND, error.message)); if (error) { debug('gcdns.getZones', error); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); } var zone = zones.filter(function (zone) { return zone.metadata.dnsName.slice(0, -1) === zoneName; // the zone name contains a '.' at the end })[0]; - if (!zone) return callback(new DomainsError(DomainsError.NOT_FOUND, 'no such zone')); + if (!zone) return callback(new BoxError(BoxError.NOT_FOUND, 'no such zone')); callback(null, zone); //zone.metadata ~= {name="", dnsName="", nameServers:[]} }); @@ -85,10 +85,10 @@ function upsert(domainObject, location, type, values, callback) { if (error) return callback(error); zone.getRecords({ type: type, name: fqdn + '.' }, function (error, oldRecords) { - if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); + if (error && error.code === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); if (error) { debug('upsert->zone.getRecords', error); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); } var newRecord = zone.record(type, { @@ -98,11 +98,11 @@ function upsert(domainObject, location, type, values, callback) { }); zone.createChange({ delete: oldRecords, add: newRecord }, function(error /*, change */) { - if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 412) return callback(new DomainsError(DomainsError.STILL_BUSY, error.message)); + if (error && error.code === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 412) return callback(new BoxError(BoxError.BUSY, error.message)); if (error) { debug('upsert->zone.createChange', error); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); } callback(null); @@ -130,8 +130,8 @@ function get(domainObject, location, type, callback) { }; zone.getRecords(params, function (error, records) { - if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error)); + if (error && error.code === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); if (records.length === 0) return callback(null, [ ]); return callback(null, records[0].data); @@ -154,18 +154,18 @@ function del(domainObject, location, type, values, callback) { if (error) return callback(error); zone.getRecords({ type: type, name: fqdn + '.' }, function(error, oldRecords) { - if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); + if (error && error.code === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); if (error) { debug('del->zone.getRecords', error); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); } zone.deleteRecords(oldRecords, function (error, change) { - if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 412) return callback(new DomainsError(DomainsError.STILL_BUSY, error.message)); + if (error && error.code === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 412) return callback(new BoxError(BoxError.BUSY, error.message)); if (error) { debug('del->zone.createChange', error); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); } callback(null, change.id); @@ -194,10 +194,10 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (typeof dnsConfig.projectId !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'projectId must be a string')); - if (!dnsConfig.credentials || typeof dnsConfig.credentials !== 'object') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials must be an object')); - if (typeof dnsConfig.credentials.client_email !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials.client_email must be a string')); - if (typeof dnsConfig.credentials.private_key !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials.private_key must be a string')); + if (typeof dnsConfig.projectId !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'projectId must be a string', { field: 'projectId' })); + if (!dnsConfig.credentials || typeof dnsConfig.credentials !== 'object') return callback(new BoxError(BoxError.BAD_FIELD, 'credentials must be an object', { field: 'credentials' })); + if (typeof dnsConfig.credentials.client_email !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'credentials.client_email must be a string', { field: 'client_email' })); + if (typeof dnsConfig.credentials.private_key !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'credentials.private_key must be a string', { field: 'private_key' })); var credentials = getDnsCredentials(dnsConfig); @@ -206,8 +206,8 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); getZoneByName(credentials, zoneName, function (error, zone) { if (error) return callback(error); @@ -215,7 +215,7 @@ function verifyDnsConfig(domainObject, callback) { var definedNS = zone.metadata.nameServers.sort().map(function(r) { return r.replace(/\.$/, ''); }); if (!_.isEqual(definedNS, nameservers.sort())) { debug('verifyDnsConfig: %j and %j do not match', nameservers, definedNS); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Google Cloud DNS')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to Google Cloud DNS', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/godaddy.js b/src/dns/godaddy.js index 5794c56d8..97a295b9d 100644 --- a/src/dns/godaddy.js +++ b/src/dns/godaddy.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/godaddy'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, superagent = require('superagent'), util = require('util'), waitForDns = require('./waitfordns.js'); @@ -72,11 +72,11 @@ function upsert(domainObject, location, type, values, callback) { .timeout(30 * 1000) .send(records) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode === 400) return callback(new DomainsError(DomainsError.BAD_FIELD, formatError(result))); // no such zone - if (result.statusCode === 422) return callback(new DomainsError(DomainsError.BAD_FIELD, formatError(result))); // conflict - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode === 400) return callback(new BoxError(BoxError.BAD_FIELD, formatError(result))); // no such zone + if (result.statusCode === 422) return callback(new BoxError(BoxError.BAD_FIELD, formatError(result))); // conflict + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null); }); @@ -98,10 +98,10 @@ function get(domainObject, location, type, callback) { .set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); if (result.statusCode === 404) return callback(null, [ ]); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); debug('get: %j', result.body); @@ -126,7 +126,7 @@ function del(domainObject, location, type, values, callback) { debug(`get: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`); - if (type !== 'A' && type !== 'TXT') return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, new Error('Record deletion is not supported by GoDaddy API'))); + if (type !== 'A' && type !== 'TXT') return callback(new BoxError(BoxError.EXTERNAL_ERROR, new Error('Record deletion is not supported by GoDaddy API'))); // check if the record exists at all so that we don't insert the "Dead" record for no reason get(domainObject, location, type, function (error, values) { @@ -144,10 +144,10 @@ function del(domainObject, location, type, values, callback) { .send(records) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, util.format('Network error %s', error.message))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); if (result.statusCode === 404) return callback(null); - if (result.statusCode === 403 || result.statusCode === 401) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (result.statusCode === 403 || result.statusCode === 401) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); debug('del: done'); @@ -176,8 +176,8 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (!dnsConfig.apiKey || typeof dnsConfig.apiKey !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'apiKey must be a non-empty string')); - if (!dnsConfig.apiSecret || typeof dnsConfig.apiSecret !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'apiSecret must be a non-empty string')); + if (!dnsConfig.apiKey || typeof dnsConfig.apiKey !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'apiKey must be a non-empty string', { field: 'apiKey' })); + if (!dnsConfig.apiSecret || typeof dnsConfig.apiSecret !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'apiSecret must be a non-empty string', { field: 'apiSecret' })); const ip = '127.0.0.1'; @@ -189,12 +189,12 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); if (!nameservers.every(function (n) { return n.toLowerCase().indexOf('.domaincontrol.com') !== -1; })) { debug('verifyDnsConfig: %j does not contain GoDaddy NS', nameservers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to GoDaddy')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to GoDaddy', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/manual.js b/src/dns/manual.js index 081a2e46a..893ce2c83 100644 --- a/src/dns/manual.js +++ b/src/dns/manual.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/manual'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, util = require('util'), waitForDns = require('./waitfordns.js'); @@ -22,6 +22,7 @@ function removePrivateFields(domainObject) { return domainObject; } +// eslint-disable-next-line no-unused-vars function injectPrivateFields(newConfig, currentConfig) { } @@ -78,8 +79,8 @@ function verifyDnsConfig(domainObject, callback) { // Very basic check if the nameservers can be fetched dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); callback(null, {}); }); diff --git a/src/dns/namecheap.js b/src/dns/namecheap.js index 650f9ac20..595aea08b 100644 --- a/src/dns/namecheap.js +++ b/src/dns/namecheap.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/namecheap'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, safe = require('safetydance'), superagent = require('superagent'), sysinfo = require('../sysinfo.js'), @@ -38,7 +38,7 @@ function getQuery(dnsConfig, callback) { assert.strictEqual(typeof callback, 'function'); sysinfo.getPublicIp(function (error, ip) { - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error) return callback(error); callback(null, { ApiUser: dnsConfig.username, @@ -64,21 +64,21 @@ function getInternal(dnsConfig, zoneName, subdomain, type, callback) { query.TLD = zoneName.split('.')[1]; superagent.get(ENDPOINT).query(query).end(function (error, result) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); var parser = new xml2js.Parser(); parser.parseString(result.text, function (error, result) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); var tmp = result.ApiResponse; if (tmp['$'].Status !== 'OK') { var errorMessage = safe.query(tmp, 'Errors[0].Error[0]._', 'Invalid response'); - if (errorMessage === 'API Key is invalid or API access has not been enabled') return callback(new DomainsError(DomainsError.ACCESS_DENIED, errorMessage)); + if (errorMessage === 'API Key is invalid or API access has not been enabled') return callback(new BoxError(BoxError.ACCESS_DENIED, errorMessage)); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, errorMessage)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, errorMessage)); } - if (!tmp.CommandResponse[0]) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, 'Invalid response')); - if (!tmp.CommandResponse[0].DomainDNSGetHostsResult[0]) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, 'Invalid response')); + if (!tmp.CommandResponse[0]) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Invalid response')); + if (!tmp.CommandResponse[0].DomainDNSGetHostsResult[0]) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Invalid response')); var hosts = result.ApiResponse.CommandResponse[0].DomainDNSGetHostsResult[0].host.map(function (h) { return h['$']; @@ -118,22 +118,22 @@ function setInternal(dnsConfig, zoneName, hosts, callback) { }); superagent.post(ENDPOINT).query(query).end(function (error, result) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); var parser = new xml2js.Parser(); parser.parseString(result.text, function (error, result) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error)); var tmp = result.ApiResponse; if (tmp['$'].Status !== 'OK') { var errorMessage = safe.query(tmp, 'Errors[0].Error[0]._', 'Invalid response'); - if (errorMessage === 'API Key is invalid or API access has not been enabled') return callback(new DomainsError(DomainsError.ACCESS_DENIED, errorMessage)); + if (errorMessage === 'API Key is invalid or API access has not been enabled') return callback(new BoxError(BoxError.ACCESS_DENIED, errorMessage)); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, errorMessage)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, errorMessage)); } - if (!tmp.CommandResponse[0]) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, 'Invalid response')); - if (!tmp.CommandResponse[0].DomainDNSSetHostsResult[0]) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, 'Invalid response')); - if (tmp.CommandResponse[0].DomainDNSSetHostsResult[0]['$'].IsSuccess !== 'true') return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, 'Invalid response')); + if (!tmp.CommandResponse[0]) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Invalid response')); + if (!tmp.CommandResponse[0].DomainDNSSetHostsResult[0]) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Invalid response')); + if (tmp.CommandResponse[0].DomainDNSSetHostsResult[0]['$'].IsSuccess !== 'true') return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Invalid response')); callback(null); }); @@ -281,8 +281,8 @@ function verifyDnsConfig(domainObject, callback) { const zoneName = domainObject.zoneName; const ip = '127.0.0.1'; - if (!dnsConfig.username || typeof dnsConfig.username !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'username must be a non-empty string')); - if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string')); + if (!dnsConfig.username || typeof dnsConfig.username !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'username must be a non-empty string', { field: 'username' })); + if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'token must be a non-empty string', { field: 'token' })); let credentials = { username: dnsConfig.username, @@ -292,12 +292,12 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); if (nameservers.some(function (n) { return n.toLowerCase().indexOf('.registrar-servers.com') === -1; })) { debug('verifyDnsConfig: %j does not contains NC NS', nameservers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to NameCheap')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to NameCheap', { field: 'nameservers' })); } const testSubdomain = 'cloudrontestdns'; diff --git a/src/dns/namecom.js b/src/dns/namecom.js index a5f1ace7e..65c284a47 100644 --- a/src/dns/namecom.js +++ b/src/dns/namecom.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/namecom'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, safe = require('safetydance'), superagent = require('superagent'), util = require('util'), @@ -63,9 +63,9 @@ function addRecord(dnsConfig, zoneName, name, type, values, callback) { .timeout(30 * 1000) .send(data) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, `Network error ${error.message}`)); - if (result.statusCode === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null, 'unused-id'); }); @@ -100,9 +100,9 @@ function updateRecord(dnsConfig, zoneName, recordId, name, type, values, callbac .timeout(30 * 1000) .send(data) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, `Network error ${error.message}`)); - if (result.statusCode === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null); }); @@ -121,9 +121,9 @@ function getInternal(dnsConfig, zoneName, name, type, callback) { .auth(dnsConfig.username, dnsConfig.token) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, `Network error ${error.message}`)); - if (result.statusCode === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); // name.com does not return the correct content-type result.body = safe.JSON.parse(result.text); @@ -209,9 +209,9 @@ function del(domainObject, location, type, values, callback) { .auth(dnsConfig.username, dnsConfig.token) .timeout(30 * 1000) .end(function (error, result) { - if (error && !error.response) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, `Network error ${error.message}`)); - if (result.statusCode === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, formatError(result))); - if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result))); + if (error && !error.response) return callback(new BoxError(BoxError.NETWORK_ERROR, error.message)); + if (result.statusCode === 403) return callback(new BoxError(BoxError.ACCESS_DENIED, formatError(result))); + if (result.statusCode !== 200) return callback(new BoxError(BoxError.EXTERNAL_ERROR, formatError(result))); return callback(null); }); @@ -238,8 +238,8 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (typeof dnsConfig.username !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'username must be a string')); - if (typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a string')); + if (typeof dnsConfig.username !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'username must be a string', { field: 'username' })); + if (typeof dnsConfig.token !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'token must be a string', { field: 'token' })); var credentials = { username: dnsConfig.username, @@ -251,12 +251,12 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); if (!nameservers.every(function (n) { return n.toLowerCase().indexOf('.name.com') !== -1; })) { debug('verifyDnsConfig: %j does not contain Name.com NS', nameservers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Name.com')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to name.com', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/noop.js b/src/dns/noop.js index 639541797..83b5c951b 100644 --- a/src/dns/noop.js +++ b/src/dns/noop.js @@ -18,6 +18,7 @@ function removePrivateFields(domainObject) { return domainObject; } +// eslint-disable-next-line no-unused-vars function injectPrivateFields(newConfig, currentConfig) { } diff --git a/src/dns/route53.js b/src/dns/route53.js index 0497adeb7..cdab7a666 100644 --- a/src/dns/route53.js +++ b/src/dns/route53.js @@ -12,10 +12,10 @@ exports = module.exports = { var assert = require('assert'), AWS = require('aws-sdk'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/route53'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, util = require('util'), waitForDns = require('./waitfordns.js'), _ = require('underscore'); @@ -59,15 +59,15 @@ function getZoneByName(dnsConfig, zoneName, callback) { } listHostedZones(function (error, result) { - if (error && error.code === 'AccessDenied') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 'InvalidClientTokenId') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + if (error && error.code === 'AccessDenied') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 'InvalidClientTokenId') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); var zone = result.HostedZones.filter(function (zone) { return zone.Name.slice(0, -1) === zoneName; // aws zone name contains a '.' at the end })[0]; - if (!zone) return callback(new DomainsError(DomainsError.NOT_FOUND, 'no such zone')); + if (!zone) return callback(new BoxError(BoxError.NOT_FOUND, 'no such zone')); callback(null, zone); }); @@ -83,9 +83,9 @@ function getHostedZone(dnsConfig, zoneName, callback) { var route53 = new AWS.Route53(getDnsCredentials(dnsConfig)); route53.getHostedZone({ Id: zone.Id }, function (error, result) { - if (error && error.code === 'AccessDenied') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 'InvalidClientTokenId') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + if (error && error.code === 'AccessDenied') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 'InvalidClientTokenId') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); callback(null, result); }); @@ -127,11 +127,11 @@ function upsert(domainObject, location, type, values, callback) { var route53 = new AWS.Route53(getDnsCredentials(dnsConfig)); route53.changeResourceRecordSets(params, function(error) { - if (error && error.code === 'AccessDenied') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 'InvalidClientTokenId') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 'PriorRequestNotComplete') return callback(new DomainsError(DomainsError.STILL_BUSY, error.message)); - if (error && error.code === 'InvalidChangeBatch') return callback(new DomainsError(DomainsError.BAD_FIELD, error.message)); - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + if (error && error.code === 'AccessDenied') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 'InvalidClientTokenId') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 'PriorRequestNotComplete') return callback(new BoxError(BoxError.BUSY, error.message)); + if (error && error.code === 'InvalidChangeBatch') return callback(new BoxError(BoxError.BAD_FIELD, error.message)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); callback(null); }); @@ -160,9 +160,9 @@ function get(domainObject, location, type, callback) { var route53 = new AWS.Route53(getDnsCredentials(dnsConfig)); route53.listResourceRecordSets(params, function (error, result) { - if (error && error.code === 'AccessDenied') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 'InvalidClientTokenId') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + if (error && error.code === 'AccessDenied') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 'InvalidClientTokenId') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); if (result.ResourceRecordSets.length === 0) return callback(null, [ ]); if (result.ResourceRecordSets[0].Name !== params.StartRecordName || result.ResourceRecordSets[0].Type !== params.StartRecordType) return callback(null, [ ]); @@ -208,23 +208,23 @@ function del(domainObject, location, type, values, callback) { var route53 = new AWS.Route53(getDnsCredentials(dnsConfig)); route53.changeResourceRecordSets(params, function(error) { - if (error && error.code === 'AccessDenied') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); - if (error && error.code === 'InvalidClientTokenId') return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message)); + if (error && error.code === 'AccessDenied') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); + if (error && error.code === 'InvalidClientTokenId') return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); if (error && error.message && error.message.indexOf('it was not found') !== -1) { debug('del: resource record set not found.', error); - return callback(new DomainsError(DomainsError.NOT_FOUND, error.message)); + return callback(new BoxError(BoxError.NOT_FOUND, error.message)); } else if (error && error.code === 'NoSuchHostedZone') { debug('del: hosted zone not found.', error); - return callback(new DomainsError(DomainsError.NOT_FOUND, error.message)); + return callback(new BoxError(BoxError.NOT_FOUND, error.message)); } else if (error && error.code === 'PriorRequestNotComplete') { debug('del: resource is still busy', error); - return callback(new DomainsError(DomainsError.STILL_BUSY, error.message)); + return callback(new BoxError(BoxError.BUSY, error.message)); } else if (error && error.code === 'InvalidChangeBatch') { debug('del: invalid change batch. No such record to be deleted.'); - return callback(new DomainsError(DomainsError.NOT_FOUND, error.message)); + return callback(new BoxError(BoxError.NOT_FOUND, error.message)); } else if (error) { debug('del: error', error); - return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); } callback(null); @@ -252,8 +252,8 @@ function verifyDnsConfig(domainObject, callback) { const dnsConfig = domainObject.config, zoneName = domainObject.zoneName; - if (!dnsConfig.accessKeyId || typeof dnsConfig.accessKeyId !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'accessKeyId must be a non-empty string')); - if (!dnsConfig.secretAccessKey || typeof dnsConfig.secretAccessKey !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'secretAccessKey must be a non-empty string')); + if (!dnsConfig.accessKeyId || typeof dnsConfig.accessKeyId !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'accessKeyId must be a non-empty string', { field: 'accessKeyId' })); + if (!dnsConfig.secretAccessKey || typeof dnsConfig.secretAccessKey !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'secretAccessKey must be a non-empty string', { field: 'secretAccessKey' })); var credentials = { accessKeyId: dnsConfig.accessKeyId, @@ -268,15 +268,15 @@ function verifyDnsConfig(domainObject, callback) { if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); getHostedZone(credentials, zoneName, function (error, zone) { if (error) return callback(error); if (!_.isEqual(zone.DelegationSet.NameServers.sort(), nameservers.sort())) { debug('verifyDnsConfig: %j and %j do not match', nameservers, zone.DelegationSet.NameServers); - return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Route53')); + return callback(new BoxError(BoxError.BAD_FIELD, 'Domain nameservers are not set to Route53', { field: 'nameservers' })); } const location = 'cloudrontestdns'; diff --git a/src/dns/waitfordns.js b/src/dns/waitfordns.js index ef60b15d9..916a12ba0 100644 --- a/src/dns/waitfordns.js +++ b/src/dns/waitfordns.js @@ -4,9 +4,9 @@ exports = module.exports = waitForDns; var assert = require('assert'), async = require('async'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/waitfordns'), - dns = require('../native-dns.js'), - DomainsError = require('../domains.js').DomainsError; + dns = require('../native-dns.js'); function resolveIp(hostname, options, callback) { assert.strictEqual(typeof hostname, 'string'); @@ -92,12 +92,12 @@ function waitForDns(hostname, zoneName, type, value, options, callback) { debug(`waitForDns (try ${attempt}): ${hostname} to be ${value} in zone ${zoneName}`); dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error || !nameservers) return retryCallback(error || new DomainsError(DomainsError.EXTERNAL_ERROR, 'Unable to get nameservers')); + if (error || !nameservers) return retryCallback(error || new BoxError(BoxError.EXTERNAL_ERROR, 'Unable to get nameservers')); async.every(nameservers, isChangeSynced.bind(null, hostname, type, value), function (error, synced) { debug('waitForDns: %s %s ns: %j', hostname, synced ? 'done' : 'not done', nameservers); - retryCallback(synced ? null : new DomainsError(DomainsError.EXTERNAL_ERROR, 'ETRYAGAIN')); + retryCallback(synced ? null : new BoxError(BoxError.EXTERNAL_ERROR, 'ETRYAGAIN')); }); }); }, function retryDone(error) { diff --git a/src/dns/wildcard.js b/src/dns/wildcard.js index c6101a171..44c95c3c9 100644 --- a/src/dns/wildcard.js +++ b/src/dns/wildcard.js @@ -11,10 +11,10 @@ exports = module.exports = { }; var assert = require('assert'), + BoxError = require('../boxerror.js'), debug = require('debug')('box:dns/manual'), dns = require('../native-dns.js'), domains = require('../domains.js'), - DomainsError = require('../domains.js').DomainsError, sysinfo = require('../sysinfo.js'), util = require('util'), waitForDns = require('./waitfordns.js'); @@ -23,6 +23,7 @@ function removePrivateFields(domainObject) { return domainObject; } +// eslint-disable-next-line no-unused-vars function injectPrivateFields(newConfig, currentConfig) { } @@ -78,20 +79,20 @@ function verifyDnsConfig(domainObject, callback) { // Very basic check if the nameservers can be fetched dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain')); - if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers')); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, 'Unable to resolve nameservers for this domain', { field: 'nameservers' })); + if (error || !nameservers) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : 'Unable to get nameservers', { field: 'nameservers' })); const location = 'cloudrontestdns'; const fqdn = domains.fqdn(location, domainObject); dns.resolve(fqdn, 'A', { server: '127.0.0.1', timeout: 5000 }, function (error, result) { - if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, `Unable to resolve ${fqdn}`)); - if (error || !result) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : `Unable to resolve ${fqdn}`)); + if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, `Unable to resolve ${fqdn}`, { field: 'nameservers' })); + if (error || !result) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : `Unable to resolve ${fqdn}`, { field: 'nameservers' })); sysinfo.getPublicIp(function (error, ip) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, `Failed to detect IP of this server: ${error.message}`)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Failed to detect IP of this server: ${error.message}`)); - if (result.length !== 1 || ip !== result[0]) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, `Domain resolves to ${JSON.stringify(result)} instead of ${ip}`)); + if (result.length !== 1 || ip !== result[0]) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Domain resolves to ${JSON.stringify(result)} instead of ${ip}`)); callback(null, {}); }); diff --git a/src/domains.js b/src/domains.js index 24047d3d4..eb2a6ce81 100644 --- a/src/domains.js +++ b/src/domains.js @@ -30,13 +30,12 @@ module.exports = exports = { prepareDashboardDomain: prepareDashboardDomain, - DomainsError: DomainsError, - SECRET_PLACEHOLDER: String.fromCharCode(0x25CF).repeat(8) }; var assert = require('assert'), async = require('async'), + BoxError = require('./boxerror.js'), constants = require('./constants.js'), DatabaseError = require('./databaseerror.js'), debug = require('debug')('box:domains'), @@ -50,36 +49,6 @@ var assert = require('assert'), util = require('util'), _ = require('underscore'); -function DomainsError(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(DomainsError, Error); - -DomainsError.NOT_FOUND = 'No such domain'; -DomainsError.ALREADY_EXISTS = 'Domain already exists'; -DomainsError.EXTERNAL_ERROR = 'External error'; -DomainsError.BAD_FIELD = 'Bad Field'; -DomainsError.STILL_BUSY = 'Still busy'; -DomainsError.IN_USE = 'In Use'; -DomainsError.INTERNAL_ERROR = 'Internal error'; -DomainsError.ACCESS_DENIED = 'Access Denied'; -DomainsError.INVALID_PROVIDER = 'provider must be route53, gcdns, digitalocean, gandi, cloudflare, namecom, noop, wildcard, manual or caas'; - // choose which subdomain backend we use for test purpose we use route53 function api(provider) { assert.strictEqual(typeof provider, 'string'); @@ -114,16 +83,14 @@ function verifyDnsConfig(dnsConfig, domain, zoneName, provider, callback) { assert.strictEqual(typeof callback, 'function'); var backend = api(provider); - if (!backend) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid provider')); + if (!backend) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid provider', { field: 'provider' })); const domainObject = { config: dnsConfig, domain: domain, zoneName: zoneName }; api(provider).verifyDnsConfig(domainObject, function (error, result) { - if (error && error.reason === DomainsError.ACCESS_DENIED) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Incorrect configuration. Access denied')); - if (error && error.reason === DomainsError.NOT_FOUND) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Zone not found')); - if (error && error.reason === DomainsError.EXTERNAL_ERROR) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Configuration error: ' + error.message)); - if (error && error.reason === DomainsError.BAD_FIELD) return callback(new DomainsError(DomainsError.BAD_FIELD, error.message)); - if (error && error.reason === DomainsError.INVALID_PROVIDER) return callback(new DomainsError(DomainsError.BAD_FIELD, error.message)); - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error && error.reason === BoxError.ACCESS_DENIED) return callback(new BoxError(BoxError.BAD_FIELD, 'Incorrect configuration. Access denied')); + if (error && error.reason === BoxError.NOT_FOUND) return callback(new BoxError(BoxError.BAD_FIELD, 'Zone not found')); + if (error && error.reason === BoxError.EXTERNAL_ERROR) return callback(new BoxError(BoxError.BAD_FIELD, 'Configuration error: ' + error.message)); + if (error) return callback(error); result.hyphenatedSubdomains = !!dnsConfig.hyphenatedSubdomains; @@ -149,25 +116,25 @@ function validateHostname(location, domainObject) { constants.SMTP_LOCATION, constants.IMAP_LOCATION ]; - if (RESERVED_LOCATIONS.indexOf(location) !== -1) return new DomainsError(DomainsError.BAD_FIELD, location + ' is reserved'); + if (RESERVED_LOCATIONS.indexOf(location) !== -1) return new BoxError(BoxError.BAD_FIELD, location + ' is reserved', { field: 'location' }); - if (hostname === settings.adminFqdn()) return new DomainsError(DomainsError.BAD_FIELD, location + ' is reserved'); + if (hostname === settings.adminFqdn()) return new BoxError(BoxError.BAD_FIELD, location + ' is reserved', { field: 'location' }); // workaround https://github.com/oncletom/tld.js/issues/73 var tmp = hostname.replace('_', '-'); - if (!tld.isValid(tmp)) return new DomainsError(DomainsError.BAD_FIELD, 'Hostname is not a valid domain name'); + if (!tld.isValid(tmp)) return new BoxError(BoxError.BAD_FIELD, 'Hostname is not a valid domain name', { field: 'location' }); - if (hostname.length > 253) return new DomainsError(DomainsError.BAD_FIELD, 'Hostname length exceeds 253 characters'); + if (hostname.length > 253) return new BoxError(BoxError.BAD_FIELD, 'Hostname length exceeds 253 characters', { field: 'location' }); if (location) { // label validation - if (location.split('.').some(function (p) { return p.length > 63 || p.length < 1; })) return new DomainsError(DomainsError.BAD_FIELD, 'Invalid subdomain length'); - if (location.match(/^[A-Za-z0-9-.]+$/) === null) return new DomainsError(DomainsError.BAD_FIELD, 'Subdomain can only contain alphanumeric, hyphen and dot'); - if (/^[-.]/.test(location)) return new DomainsError(DomainsError.BAD_FIELD, 'Subdomain cannot start or end with hyphen or dot'); + if (location.split('.').some(function (p) { return p.length > 63 || p.length < 1; })) return new BoxError(BoxError.BAD_FIELD, 'Invalid subdomain length', { field: 'location' }); + if (location.match(/^[A-Za-z0-9-.]+$/) === null) return new BoxError(BoxError.BAD_FIELD, 'Subdomain can only contain alphanumeric, hyphen and dot', { field: 'location' }); + if (/^[-.]/.test(location)) return new BoxError(BoxError.BAD_FIELD, 'Subdomain cannot start or end with hyphen or dot', { field: 'location' }); } if (domainObject.config.hyphenatedSubdomains) { - if (location.indexOf('.') !== -1) return new DomainsError(DomainsError.BAD_FIELD, 'Subdomain cannot contain a dot'); + if (location.indexOf('.') !== -1) return new BoxError(BoxError.BAD_FIELD, 'Subdomain cannot contain a dot', { field: 'location' }); } return null; @@ -184,12 +151,12 @@ function validateTlsConfig(tlsConfig, dnsProvider) { case 'caas': break; default: - return new DomainsError(DomainsError.BAD_FIELD, 'tlsConfig.provider must be caas, fallback, letsencrypt-prod/staging'); + return new BoxError(BoxError.BAD_FIELD, 'tlsConfig.provider must be caas, fallback, letsencrypt-prod/staging', { field: 'tlsProvider' }); } if (tlsConfig.wildcard) { - if (!tlsConfig.provider.startsWith('letsencrypt')) return new DomainsError(DomainsError.BAD_FIELD, 'wildcard can only be set with letsencrypt'); - if (dnsProvider === 'manual' || dnsProvider === 'noop' || dnsProvider === 'wildcard') return new DomainsError(DomainsError.BAD_FIELD, 'wildcard cert requires a programmable DNS backend'); + if (!tlsConfig.provider.startsWith('letsencrypt')) return new BoxError(BoxError.BAD_FIELD, 'wildcard can only be set with letsencrypt', { field: 'wildcard' }); + if (dnsProvider === 'manual' || dnsProvider === 'noop' || dnsProvider === 'wildcard') return new BoxError(BoxError.BAD_FIELD, 'wildcard cert requires a programmable DNS backend', { field: 'tlsProvider' }); } return null; @@ -206,22 +173,22 @@ function add(domain, data, auditSource, callback) { let { zoneName, provider, config, fallbackCertificate, tlsConfig } = data; - if (!tld.isValid(domain)) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid domain')); - if (domain.endsWith('.')) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid domain')); + if (!tld.isValid(domain)) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid domain', { field: 'domain' })); + if (domain.endsWith('.')) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid domain', { field: 'domain' })); if (zoneName) { - if (!tld.isValid(zoneName)) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid zoneName')); - if (zoneName.endsWith('.')) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid zoneName')); + if (!tld.isValid(zoneName)) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid zoneName', { field: 'zoneName' })); + if (zoneName.endsWith('.')) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid zoneName', { field: 'zoneName' })); } else { zoneName = tld.getDomain(domain) || domain; } if (fallbackCertificate) { let error = reverseProxy.validateCertificate('test', { domain, config }, fallbackCertificate); - if (error) return callback(new DomainsError(DomainsError.BAD_FIELD, error.message)); + if (error) return callback(error); } else { fallbackCertificate = reverseProxy.generateFallbackCertificateSync({ domain, config }); - if (fallbackCertificate.error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, fallbackCertificate.error)); + if (fallbackCertificate.error) return callback(error); } let error = validateTlsConfig(tlsConfig, provider); @@ -231,11 +198,11 @@ function add(domain, data, auditSource, callback) { if (error) return callback(error); domaindb.add(domain, { zoneName: zoneName, provider: provider, config: sanitizedConfig, tlsConfig: tlsConfig }, function (error) { - if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new DomainsError(DomainsError.ALREADY_EXISTS)); - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new BoxError(BoxError.ALREADY_EXISTS)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); reverseProxy.setFallbackCertificate(domain, fallbackCertificate, function (error) { - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error) return callback(error); eventlog.add(eventlog.ACTION_DOMAIN_ADD, auditSource, { domain, zoneName, provider }); @@ -251,14 +218,14 @@ function get(domain, callback) { domaindb.get(domain, function (error, result) { // TODO try to find subdomain entries maybe based on zoneNames or so - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new DomainsError(DomainsError.NOT_FOUND)); - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); reverseProxy.getFallbackCertificate(domain, function (_, bundle) { // never returns an error var cert = safe.fs.readFileSync(bundle.certFilePath, 'utf-8'); var key = safe.fs.readFileSync(bundle.keyFilePath, 'utf-8'); - if (!cert || !key) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, 'unable to read certificates from disk')); + if (!cert || !key) return callback(new BoxError(BoxError.FS_ERROR, 'unable to read certificates from disk')); result.fallbackCertificate = { cert: cert, key: key }; @@ -271,7 +238,7 @@ function getAll(callback) { assert.strictEqual(typeof callback, 'function'); domaindb.getAll(function (error, result) { - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); return callback(null, result); }); @@ -290,18 +257,18 @@ function update(domain, data, auditSource, callback) { let { zoneName, provider, config, fallbackCertificate, tlsConfig } = data; domaindb.get(domain, function (error, domainObject) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new DomainsError(DomainsError.NOT_FOUND)); - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); if (zoneName) { - if (!tld.isValid(zoneName)) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid zoneName')); + if (!tld.isValid(zoneName)) return callback(new BoxError(BoxError.BAD_FIELD, 'Invalid zoneName', { field: 'zoneName' })); } else { zoneName = domainObject.zoneName; } if (fallbackCertificate) { let error = reverseProxy.validateCertificate('test', domainObject, fallbackCertificate); - if (error) return callback(new DomainsError(DomainsError.BAD_FIELD, error.message)); + if (error) return callback(error); } error = validateTlsConfig(tlsConfig, provider); @@ -320,13 +287,13 @@ function update(domain, data, auditSource, callback) { }; domaindb.update(domain, newData, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new DomainsError(DomainsError.NOT_FOUND)); - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); if (!fallbackCertificate) return callback(); reverseProxy.setFallbackCertificate(domain, fallbackCertificate, function (error) { - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error) return callback(error); eventlog.add(eventlog.ACTION_DOMAIN_UPDATE, auditSource, { domain, zoneName, provider }); @@ -342,12 +309,12 @@ function del(domain, auditSource, callback) { assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); - if (domain === settings.adminDomain()) return callback(new DomainsError(DomainsError.IN_USE)); + if (domain === settings.adminDomain()) return callback(new BoxError(BoxError.CONFLICT, 'Cannot remove admin domain')); domaindb.del(domain, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new DomainsError(DomainsError.NOT_FOUND)); - if (error && error.reason === DatabaseError.IN_USE) return callback(new DomainsError(DomainsError.IN_USE)); - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error && error.reason === DatabaseError.IN_USE) return callback(new BoxError(BoxError.CONFLICT, 'Domain is still in use. Remove all apps and mailboxes using this domain')); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); eventlog.add(eventlog.ACTION_DOMAIN_REMOVE, auditSource, { domain }); @@ -359,7 +326,7 @@ function clear(callback) { assert.strictEqual(typeof callback, 'function'); domaindb.clear(function (error) { - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); return callback(null); }); @@ -412,7 +379,7 @@ function checkDnsRecords(location, domain, callback) { if (error) return callback(error); sysinfo.getPublicIp(function (error, ip) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + if (error) return callback(error); if (values.length === 0) return callback(null, { needsOverwrite: false }); // does not exist if (values[0] === ip) return callback(null, { needsOverwrite: false }); // exists but in sync @@ -433,7 +400,7 @@ function upsertDnsRecords(location, domain, type, values, callback) { debug('upsertDNSRecord: %s on %s type %s values', location, domain, type, values); get(domain, function (error, domainObject) { - if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error)); + if (error) return callback(error); api(domainObject.provider).upsert(domainObject, location, type, values, function (error) { if (error) return callback(error); @@ -456,7 +423,7 @@ function removeDnsRecords(location, domain, type, values, callback) { if (error) return callback(error); api(domainObject.provider).del(domainObject, location, type, values, function (error) { - if (error && error.reason !== DomainsError.NOT_FOUND) return callback(error); + if (error && error.reason !== BoxError.NOT_FOUND) return callback(error); callback(null); }); @@ -514,7 +481,7 @@ function prepareDashboardDomain(domain, auditSource, progressCallback, callback) const adminFqdn = fqdn(constants.ADMIN_LOCATION, domainObject); sysinfo.getPublicIp(function (error, ip) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, error.message)); + if (error) return callback(error); async.series([ (done) => { progressCallback({ percent: 10, message: `Updating DNS of ${adminFqdn}` }); done(); }, diff --git a/src/provision.js b/src/provision.js index 993b47bb9..0ace74275 100644 --- a/src/provision.js +++ b/src/provision.js @@ -22,7 +22,6 @@ var appstore = require('./appstore.js'), cloudron = require('./cloudron.js'), debug = require('debug')('box:provision'), domains = require('./domains.js'), - DomainsError = domains.DomainsError, eventlog = require('./eventlog.js'), fs = require('fs'), mail = require('./mail.js'), @@ -159,8 +158,8 @@ function setup(dnsConfig, backupConfig, auditSource, callback) { }; domains.add(domain, data, auditSource, function (error) { - if (error && error.reason === DomainsError.BAD_FIELD) return done(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); - if (error && error.reason === DomainsError.ALREADY_EXISTS) return done(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); + if (error && error.reason === BoxError.BAD_FIELD) return done(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); + if (error && error.reason === BoxError.ALREADY_EXISTS) return done(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); if (error) return done(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); callback(); // now that args are validated run the task in the background diff --git a/src/reverseproxy.js b/src/reverseproxy.js index 86405c673..7285ff40a 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -195,11 +195,11 @@ function generateFallbackCertificateSync(domainObject) { safe.fs.unlinkSync(configFile); const cert = safe.fs.readFileSync(certFilePath, 'utf8'); - if (!cert) return { error: safe.error }; + if (!cert) return { error: new BoxError(BoxError.FS_ERROR, safe.error.message) }; safe.fs.unlinkSync(certFilePath); const key = safe.fs.readFileSync(keyFilePath, 'utf8'); - if (!key) return { error: safe.error }; + if (!key) return { error: new BoxError(BoxError.FS_ERROR, safe.error.message) }; safe.fs.unlinkSync(keyFilePath); return { cert: cert, key: key, error: null }; diff --git a/src/routes/domains.js b/src/routes/domains.js index be84a2abf..c0c28d329 100644 --- a/src/routes/domains.js +++ b/src/routes/domains.js @@ -14,17 +14,32 @@ exports = module.exports = { var assert = require('assert'), auditSource = require('../auditsource.js'), + BoxError = require('../boxerror.js'), domains = require('../domains.js'), - DomainsError = domains.DomainsError, HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess; +function toHttpError(error) { + switch (error.reason) { + case BoxError.NOT_FOUND: // + return new HttpError(404, error); + case BoxError.ALREADY_EXISTS: // + 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.DATABASE_ERROR: + default: + return new HttpError(500, error); + } +} + function verifyDomainLock(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); domains.get(req.params.domain, function (error, domain) { - if (error && error.reason === DomainsError.NOT_FOUND) return next(new HttpError(404, 'No such domain')); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); if (domain.locked) return next(new HttpError(423, 'This domain is locked')); @@ -68,10 +83,7 @@ function add(req, res, next) { }; domains.add(req.body.domain, data, auditSource.fromRequest(req), function (error) { - if (error && error.reason === DomainsError.ALREADY_EXISTS) return next(new HttpError(409, error.message)); - if (error && error.reason === DomainsError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error && error.reason === DomainsError.INVALID_PROVIDER) 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, { domain: req.body.domain, config: req.body.config })); }); @@ -81,8 +93,7 @@ function get(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); domains.get(req.params.domain, function (error, result) { - if (error && error.reason === DomainsError.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, domains.removePrivateFields(result))); }); @@ -134,10 +145,7 @@ function update(req, res, next) { }; domains.update(req.params.domain, data, auditSource.fromRequest(req), function (error) { - if (error && error.reason === DomainsError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === DomainsError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error && error.reason === DomainsError.INVALID_PROVIDER) 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, {})); }); @@ -147,9 +155,7 @@ function del(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); domains.del(req.params.domain, auditSource.fromRequest(req), function (error) { - if (error && error.reason === DomainsError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error && error.reason === DomainsError.IN_USE) return next(new HttpError(409, 'Domain is still in use. Remove all apps and mailboxes using this domain')); - if (error) return next(new HttpError(500, error)); + if (error) return next(toHttpError(error)); next(new HttpSuccess(204)); }); @@ -164,10 +170,8 @@ function checkDnsRecords(req, res, next) { req.clearTimeout(); domains.checkDnsRecords(req.query.subdomain, req.params.domain, function (error, result) { - if (error && error.reason === DomainsError.NOT_FOUND) return next(new HttpError(404, error.message)); // domain (and not record!) not found - if (error && error.reason === DomainsError.EXTERNAL_ERROR) return next(new HttpError(424, error.message)); - if (error && error.reason === DomainsError.ACCESS_DENIED) return next(new HttpSuccess(200, { error: { reason: error.reason, message: error.message }})); - if (error) return next(new HttpError(500, error)); + if (error && error.reason === BoxError.ACCESS_DENIED) return next(new HttpSuccess(200, { error: { reason: error.reason, message: error.message }})); + if (error) return next(toHttpError(error)); next(new HttpSuccess(200, { needsOverwrite: result.needsOverwrite })); });