diff --git a/src/mail.js b/src/mail.js index 93e9cd987..b7be0ea81 100644 --- a/src/mail.js +++ b/src/mail.js @@ -8,6 +8,7 @@ exports = module.exports = { add: add, del: del, + update: update, setMailFromValidation: setMailFromValidation, setCatchAllAddress: setCatchAllAddress, @@ -635,12 +636,19 @@ function txtRecordsWithSpf(domain, callback) { function ensureDkimKeySync(domain) { assert.strictEqual(typeof domain, 'string'); - debug(`Generating new DKIM keys for ${domain}`); + const dkimPath = path.join(paths.MAIL_DATA_DIR, `dkim/${domain}`); + const dkimPrivateKeyFile = path.join(dkimPath, 'private'); + const dkimPublicKeyFile = path.join(dkimPath, 'public'); + const dkimSelectorFile = path.join(dkimPath, 'selector'); - var dkimPath = path.join(paths.MAIL_DATA_DIR, `dkim/${domain}`); - var dkimPrivateKeyFile = path.join(dkimPath, 'private'); - var dkimPublicKeyFile = path.join(dkimPath, 'public'); - var dkimSelectorFile = path.join(dkimPath, 'selector'); + if (safe.fs.existsSync(dkimPublicKeyFile) && + safe.fs.existsSync(dkimPublicKeyFile) && + safe.fs.existsSync(dkimPublicKeyFile)) { + debug(`Reusing existing DKIM keys for ${domain}`); + return null; + } + + debug(`Generating new DKIM keys for ${domain}`); if (!safe.fs.mkdirSync(dkimPath) && safe.error.code !== 'EEXIST') { debug('Error creating dkim.', safe.error); @@ -734,6 +742,20 @@ function add(domain, callback) { }); } +// this is just a way to resync the mail "dns" records via the UI +function update(domain, callback) { + assert.strictEqual(typeof domain, 'string'); + assert.strictEqual(typeof callback, 'function'); + + get(domain, function (error) { + if (error) return callback(error); + + addDnsRecords(domain, NOOP_CALLBACK); + + callback(); + }); +} + function del(domain, callback) { assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof callback, 'function'); diff --git a/src/routes/mail.js b/src/routes/mail.js index d68d7494a..b1c896fbf 100644 --- a/src/routes/mail.js +++ b/src/routes/mail.js @@ -4,6 +4,7 @@ exports = module.exports = { get: get, add: add, + update: update, del: del, getStatus: getStatus, @@ -60,6 +61,18 @@ function add(req, res, next) { }); } +function update(req, res, next) { + assert.strictEqual(typeof req.body, 'object'); + assert.strictEqual(typeof req.params.domain, 'string'); + + mail.update(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 del(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); diff --git a/src/server.js b/src/server.js index d76ff3758..344618542 100644 --- a/src/server.js +++ b/src/server.js @@ -215,6 +215,7 @@ function initializeExpressSync() { // email routes router.get ('/api/v1/mail/:domain', settingsScope, routes.user.requireAdmin, routes.mail.get); + router.post('/api/v1/mail/:domain', settingsScope, routes.user.requireAdmin, routes.mail.update); router.post('/api/v1/mail', settingsScope, routes.user.requireAdmin, routes.mail.add); router.del ('/api/v1/mail/:domain', settingsScope, routes.user.requireAdmin, routes.user.verifyPassword, routes.mail.del); router.get ('/api/v1/mail/:domain/status', settingsScope, routes.user.requireAdmin, routes.mail.getStatus); diff --git a/src/setup.js b/src/setup.js index 0dce0cb43..88441003e 100644 --- a/src/setup.js +++ b/src/setup.js @@ -313,6 +313,9 @@ function restore(backupConfig, backupId, version, callback) { async.series([ backups.restore.bind(null, backupConfig, backupId), 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.update.bind(null, config.adminDomain()), shell.sudo.bind(null, 'restart', [ RESTART_CMD ]) ], function (error) { debug('restore:', error);