diff --git a/src/mail.js b/src/mail.js index 20896f826..c500a6629 100644 --- a/src/mail.js +++ b/src/mail.js @@ -8,10 +8,8 @@ exports = module.exports = { getDomain: getDomain, addDomain: addDomain, removeDomain: removeDomain, - updateDomain: updateDomain, - addDnsRecords: addDnsRecords, - setDnsRecords: setDnsRecords, // TODO: merge with above + setDnsRecords: setDnsRecords, validateName: validateName, @@ -694,40 +692,49 @@ function readDkimPublicKeySync(domain) { return publicKey; } -function addDnsRecords(domain, callback) { +function setDnsRecords(domain, callback) { assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof callback, 'function'); - var error = ensureDkimKeySync(domain); - if (error) return callback(error); + maildb.get(domain, function (error, result) { + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); + if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - if (process.env.BOX_ENV === 'test') return callback(); - - var dkimKey = readDkimPublicKeySync(domain); - if (!dkimKey) return callback(new MailError(MailError.INTERNAL_ERROR, new Error('Failed to read dkim public key'))); - - // t=s limits the domainkey to this domain and not it's subdomains - var dkimRecord = { subdomain: config.dkimSelector() + '._domainkey', domain: domain, type: 'TXT', values: [ '"v=DKIM1; t=s; p=' + dkimKey + '"' ] }; - - var records = [ ]; - records.push(dkimRecord); - - debug('addDnsRecords: %j', records); - - txtRecordsWithSpf(domain, function (error, txtRecords) { + error = ensureDkimKeySync(domain); if (error) return callback(error); - if (txtRecords) records.push({ subdomain: '', domain: domain, type: 'TXT', values: txtRecords }); + if (process.env.BOX_ENV === 'test') return callback(); - debug('addDnsRecords: will update %j', records); + var dkimKey = readDkimPublicKeySync(domain); + if (!dkimKey) return callback(new MailError(MailError.INTERNAL_ERROR, new Error('Failed to read dkim public key'))); - async.mapSeries(records, function (record, iteratorCallback) { - domains.upsertDnsRecords(record.subdomain, record.domain, record.type, record.values, iteratorCallback); - }, function (error, changeIds) { - if (error) debug('addDnsRecords: failed to update : %s. will retry', error); - else debug('addDnsRecords: records %j added with changeIds %j', records, changeIds); + // t=s limits the domainkey to this domain and not it's subdomains + var dkimRecord = { subdomain: config.dkimSelector() + '._domainkey', domain: domain, type: 'TXT', values: [ '"v=DKIM1; t=s; p=' + dkimKey + '"' ] }; - callback(error); + var records = [ ]; + records.push(dkimRecord); + if (result.enabled) { + records.push({ subdomain: '_dmarc', type: 'TXT', values: [ '"v=DMARC1; p=reject; pct=100"' ] }); + records.push({ subdomain: '', type: 'MX', values: [ '10 ' + config.mailFqdn() + '.' ] }); + } + + debug('addDnsRecords: %j', records); + + txtRecordsWithSpf(domain, function (error, txtRecords) { + if (error) return callback(error); + + if (txtRecords) records.push({ subdomain: '', domain: domain, type: 'TXT', values: txtRecords }); + + debug('addDnsRecords: will update %j', records); + + async.mapSeries(records, function (record, iteratorCallback) { + domains.upsertDnsRecords(record.subdomain, record.domain, record.type, record.values, iteratorCallback); + }, function (error, changeIds) { + if (error) debug('addDnsRecords: failed to update : %s. will retry', error); + else debug('addDnsRecords: records %j added with changeIds %j', records, changeIds); + + callback(error); + }); }); }); } @@ -742,7 +749,7 @@ function addDomain(domain, callback) { if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); async.series([ - addDnsRecords.bind(null, domain), // do this first to ensure DKIM keys + setDnsRecords.bind(null, domain), // do this first to ensure DKIM keys restartMail ], NOOP_CALLBACK); // do these asynchronously @@ -750,20 +757,6 @@ function addDomain(domain, callback) { }); } -// this is just a way to resync the mail "dns" records via the UI -function updateDomain(domain, callback) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof callback, 'function'); - - getDomain(domain, function (error) { - if (error) return callback(error); - - addDnsRecords(domain, NOOP_CALLBACK); - - callback(); - }); -} - function removeDomain(domain, callback) { assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof callback, 'function'); @@ -843,31 +836,6 @@ function setMailEnabled(domain, enabled, callback) { }); } -function setDnsRecords(domain, callback) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof callback, 'function'); - - maildb.get(domain, function (error, result) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new MailError(MailError.NOT_FOUND)); - if (error) return callback(new MailError(MailError.INTERNAL_ERROR, error)); - - if (!result.enabled) return callback(null); - - // Add MX and DMARC record. Note that DMARC policy depends on DKIM signing and thus works - // only if we use our internal mail server. - var records = [ - { subdomain: '_dmarc', type: 'TXT', values: [ '"v=DMARC1; p=reject; pct=100"' ] }, - { subdomain: '', type: 'MX', values: [ '10 ' + config.mailFqdn() + '.' ] } - ]; - - async.mapSeries(records, function (record, iteratorCallback) { - domains.upsertDnsRecords(record.subdomain, domain, record.type, record.values, iteratorCallback); - }, NOOP_CALLBACK); - - callback(null); - }); -} - function sendTestMail(domain, to, callback) { assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof to, 'string'); diff --git a/src/routes/mail.js b/src/routes/mail.js index 563de9c0a..0063160d3 100644 --- a/src/routes/mail.js +++ b/src/routes/mail.js @@ -4,7 +4,6 @@ exports = module.exports = { getDomain: getDomain, addDomain: addDomain, getDomainStats: getDomainStats, - updateDomain: updateDomain, removeDomain: removeDomain, setDnsRecords: setDnsRecords, @@ -83,18 +82,6 @@ function getDomainStats(req, res, next) { mailProxy(req, res, next); } -function updateDomain(req, res, next) { - assert.strictEqual(typeof req.body, 'object'); - assert.strictEqual(typeof req.params.domain, 'string'); - - mail.updateDomain(req.params.domain, function (error) { - if (error && error.reason === MailError.NOT_FOUND) return next(new HttpError(404, error.message)); - if (error) return next(new HttpError(500, error)); - - next(new HttpSuccess(202)); - }); -} - function setDnsRecords(req, res, next) { assert.strictEqual(typeof req.body, 'object'); assert.strictEqual(typeof req.params.domain, 'string'); diff --git a/src/server.js b/src/server.js index a838bcd10..ef840c5b1 100644 --- a/src/server.js +++ b/src/server.js @@ -232,7 +232,6 @@ function initializeExpressSync() { // email routes router.get ('/api/v1/mail/:domain', mailScope, routes.mail.getDomain); - router.post('/api/v1/mail/:domain', mailScope, routes.mail.updateDomain); router.post('/api/v1/mail', mailScope, routes.mail.addDomain); router.get ('/api/v1/mail/:domain/stats', mailScope, routes.users.verifyPassword, routes.mail.getDomainStats); router.del ('/api/v1/mail/:domain', mailScope, routes.users.verifyPassword, routes.mail.removeDomain); diff --git a/src/setup.js b/src/setup.js index b6e40489f..a52d67926 100644 --- a/src/setup.js +++ b/src/setup.js @@ -292,7 +292,7 @@ function restore(backupConfig, backupId, version, callback) { autoprovision, // currently, our suggested restore flow is after a dnsSetup. This re-creates DKIM keys and updates the DNS // for this reason, we have to re-setup DNS after a restore. Once we have a 100% IP based restore, we can skip this - mail.addDnsRecords.bind(null, config.adminDomain()), + mail.setDnsRecords.bind(null, config.adminDomain()), shell.sudo.bind(null, 'restart', [ RESTART_CMD ]) ], function (error) { debug('restore:', error);