diff --git a/src/domains.js b/src/domains.js index 5fb98af62..3c880b182 100644 --- a/src/domains.js +++ b/src/domains.js @@ -189,8 +189,9 @@ function getAll(callback) { }); } -function update(domain, provider, config, fallbackCertificate, tlsConfig, callback) { +function update(domain, zoneName, provider, config, fallbackCertificate, tlsConfig, callback) { assert.strictEqual(typeof domain, 'string'); + assert.strictEqual(typeof zoneName, 'string'); assert.strictEqual(typeof provider, 'string'); assert.strictEqual(typeof config, 'object'); assert.strictEqual(typeof fallbackCertificate, 'object'); @@ -201,6 +202,12 @@ function update(domain, provider, config, fallbackCertificate, tlsConfig, callba 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 (zoneName) { + if (!tld.isValid(zoneName)) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid zoneName')); + } else { + zoneName = result.zoneName; + } + if (fallbackCertificate) { let error = reverseProxy.validateCertificate(`test.${domain}`, fallbackCertificate.cert, fallbackCertificate.key); if (error) return callback(new DomainsError(DomainsError.BAD_FIELD, error.message)); @@ -213,7 +220,7 @@ function update(domain, provider, config, fallbackCertificate, tlsConfig, callba sysinfo.getPublicIp(function (error, ip) { if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, 'Error getting IP:' + error.message)); - verifyDnsConfig(config, domain, result.zoneName, provider, ip, function (error, result) { + verifyDnsConfig(config, domain, zoneName, provider, ip, function (error, result) { if (error && error.reason === DomainsError.ACCESS_DENIED) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Error adding A record. 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, 'Error adding A record:' + error.message)); @@ -221,7 +228,7 @@ function update(domain, provider, config, fallbackCertificate, tlsConfig, callba 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)); - domaindb.update(domain, { provider: provider, config: result, tlsConfig: tlsConfig }, function (error) { + domaindb.update(domain, { zoneName: zoneName, provider: provider, config: result, tlsConfig: tlsConfig }, 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)); diff --git a/src/routes/domains.js b/src/routes/domains.js index ed21eb5f6..9d040da17 100644 --- a/src/routes/domains.js +++ b/src/routes/domains.js @@ -67,6 +67,7 @@ function update(req, res, next) { if (typeof req.body.provider !== 'string') return next(new HttpError(400, 'provider must be an object')); if (typeof req.body.config !== 'object') return next(new HttpError(400, 'config must be an object')); + if ('zoneName' in req.body && typeof req.body.zoneName !== 'string') return next(new HttpError(400, 'zoneName must be a string')); if ('fallbackCertificate' in req.body && typeof req.body.fallbackCertificate !== 'object') return next(new HttpError(400, 'fallbackCertificate must be a object with cert and key strings')); if (req.body.fallbackCertificate && (!req.body.fallbackCertificate.cert || typeof req.body.fallbackCertificate.cert !== 'string')) return next(new HttpError(400, 'fallbackCertificate.cert must be a string')); if (req.body.fallbackCertificate && (!req.body.fallbackCertificate.key || typeof req.body.fallbackCertificate.key !== 'string')) return next(new HttpError(400, 'fallbackCertificate.key must be a string')); @@ -76,7 +77,7 @@ function update(req, res, next) { // some DNS providers like DigitalOcean take a really long time to verify credentials (https://github.com/expressjs/timeout/issues/26) req.clearTimeout(); - domains.update(req.params.domain, req.body.provider, req.body.config, req.body.fallbackCertificate || null, req.body.tlsConfig || { provider: 'letsencrypt-prod' }, function (error) { + domains.update(req.params.domain, req.body.zoneName || '', req.body.provider, req.body.config, req.body.fallbackCertificate || null, req.body.tlsConfig || { provider: 'letsencrypt-prod' }, 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)); diff --git a/src/test/dns-test.js b/src/test/dns-test.js index 064c3293d..8fcaa8812 100644 --- a/src/test/dns-test.js +++ b/src/test/dns-test.js @@ -51,7 +51,7 @@ describe('dns provider', function () { DOMAIN_0.provider = 'noop'; DOMAIN_0.config = {}; - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, DOMAIN_0.zoneName, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); it('upsert succeeds', function (done) { @@ -92,7 +92,7 @@ describe('dns provider', function () { token: TOKEN }; - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, '', DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); it('upsert non-existing record succeeds', function (done) { @@ -352,7 +352,7 @@ describe('dns provider', function () { apiSecret: SECRET }; - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, '', DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); it('upsert record succeeds', function (done) { @@ -439,7 +439,7 @@ describe('dns provider', function () { token: TOKEN }; - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, DOMAIN_0.zoneName, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); it('upsert record succeeds', function (done) { @@ -513,7 +513,7 @@ describe('dns provider', function () { token: TOKEN }; - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, '', DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); it('upsert record succeeds', function (done) { @@ -675,7 +675,7 @@ describe('dns provider', function () { AWS._originalRoute53 = AWS.Route53; AWS.Route53 = Route53Mock; - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, '', DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); after(function () { @@ -831,7 +831,7 @@ describe('dns provider', function () { _OriginalGCDNS = GCDNS.prototype.getZones; GCDNS.prototype.getZones = mockery(zoneQueue); - domains.update(DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); + domains.update(DOMAIN_0.domain, DOMAIN_0.zoneName, DOMAIN_0.provider, DOMAIN_0.config, null, DOMAIN_0.tlsConfig, done); }); after(function () { diff --git a/src/test/reverseproxy-test.js b/src/test/reverseproxy-test.js index 6db12a759..25fde6287 100644 --- a/src/test/reverseproxy-test.js +++ b/src/test/reverseproxy-test.js @@ -121,7 +121,7 @@ describe('Certificates', function () { async.series([ setup, - domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, DOMAIN_0.fallbackCertificate, DOMAIN_0.tlsConfig) + domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.zoneName, DOMAIN_0.provider, DOMAIN_0.config, DOMAIN_0.fallbackCertificate, DOMAIN_0.tlsConfig) ], done); }); @@ -152,7 +152,7 @@ describe('Certificates', function () { async.series([ setup, - domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, DOMAIN_0.fallbackCertificate, DOMAIN_0.tlsConfig) + domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.zoneName, DOMAIN_0.provider, DOMAIN_0.config, DOMAIN_0.fallbackCertificate, DOMAIN_0.tlsConfig) ], done); }); @@ -183,7 +183,7 @@ describe('Certificates', function () { async.series([ setup, - domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, DOMAIN_0.fallbackCertificate, DOMAIN_0.tlsConfig) + domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.zoneName, DOMAIN_0.provider, DOMAIN_0.config, DOMAIN_0.fallbackCertificate, DOMAIN_0.tlsConfig) ], done); });