diff --git a/src/mailer.js b/src/mailer.js index f5b43a5a6..f505b28d8 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -228,22 +228,23 @@ function backupFailed(mailTo, errorMessage, logUrl) { }); } -function certificateRenewalError(mailTo, domain, message) { +function certificateRenewalError(mailTo, domain, message, callback) { assert.strictEqual(typeof mailTo, 'string'); assert.strictEqual(typeof domain, 'string'); assert.strictEqual(typeof message, 'string'); + assert.strictEqual(typeof callback, 'function'); getMailConfig(function (error, mailConfig) { if (error) return debug('Error getting mail details:', error); - var mailOptions = { + const mailOptions = { from: mailConfig.notificationFrom, to: mailTo, subject: `[${mailConfig.cloudronName}] Certificate renewal error`, text: render('certificate_renewal_error.ejs', { domain: domain, message: message, format: 'text' }) }; - sendMail(mailOptions); + sendMail(mailOptions, callback); }); } diff --git a/src/notifications.js b/src/notifications.js index ea5ab95ec..8e7b8aac9 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -22,6 +22,7 @@ exports = module.exports = { }; const assert = require('assert'), + async = require('async'), auditSource = require('./auditsource.js'), BoxError = require('./boxerror.js'), changelog = require('./changelog.js'), @@ -178,15 +179,21 @@ async function certificateRenewalError(eventId, vhost, errorMessage) { assert.strictEqual(typeof vhost, 'string'); assert.strictEqual(typeof errorMessage, 'string'); - const getAdmins = util.callbackify(users.getAdmins); + return new Promise((resolve, reject) => { + users.getAdmins(function (error, admins) { + if (error) return reject(error); - const admins = await getAdmins(); + async.eachSeries(admins, function (admin, iteratorDone) { + mailer.certificateRenewalError(admin.email, vhost, errorMessage, iteratorDone); + }, async function (error) { + if (error) return reject(error); - for (const admin of admins) { - mailer.certificateRenewalError(admin.email, vhost, errorMessage); - } + await add(eventId, `Certificate renewal of ${vhost} failed`, `Failed to renew certs of ${vhost}: ${errorMessage}. Renewal will be retried in 12 hours.`); - await add(eventId, `Certificate renewal of ${vhost} failed`, `Failed to renew certs of ${vhost}: ${errorMessage}. Renewal will be retried in 12 hours`); + resolve(); + }); + }); + }); } async function backupFailed(eventId, taskId, errorMessage) { @@ -205,7 +212,7 @@ async function backupFailed(eventId, taskId, errorMessage) { } if (count !== 3) return; // less than 3 failures - const getSuperAdmins = util.callbackify(users.getSuperAdmins); + const getSuperAdmins = util.promisify(users.getSuperAdmins); const superAdmins = await getSuperAdmins(); diff --git a/src/reverseproxy.js b/src/reverseproxy.js index 32029dd69..99de3c8d8 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -438,7 +438,7 @@ function ensureCertificate(vhost, domain, auditSource, callback) { acmeApi.getCertificate(vhost, domain, acmePaths, apiOptions, async function (error) { debug(`ensureCertificate: error: ${error ? error.message : 'null'} cert: ${acmePaths.certFilePath || 'null'}`); - eventlog.add(currentBundle ? eventlog.ACTION_CERTIFICATE_RENEWAL : eventlog.ACTION_CERTIFICATE_NEW, auditSource, { domain: vhost, errorMessage: error ? error.message : '', notAfter }); + await safe(eventlog.add(currentBundle ? eventlog.ACTION_CERTIFICATE_RENEWAL : eventlog.ACTION_CERTIFICATE_NEW, auditSource, { domain: vhost, errorMessage: error ? error.message : '', notAfter })); if (error && currentBundle && (notAfter - new Date() > 0)) { // still some life left in this certificate debug('ensureCertificate: continue using existing bundle since renewal failed');