mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Added admin email for UpdateChecker's alerts
refs https://github.com/TryGhost/Team/issues/726 - When UpdateCheck service sends a notification with "type: 'alert'" an email goes out to admin users with the "message" content of the notification. - This functionality is aimed to handling critical messages like urgent instance updates - Next step will be getting as much of the update check code extracted into a "service" and then moved out of Ghost's codebase
This commit is contained in:
parent
a1556797b6
commit
df4df2a4aa
2 changed files with 69 additions and 0 deletions
|
@ -16,6 +16,7 @@ const _ = require('lodash');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const debug = require('ghost-ignition').debug('update-check');
|
const debug = require('ghost-ignition').debug('update-check');
|
||||||
const api = require('./api').v2;
|
const api = require('./api').v2;
|
||||||
|
const GhostMailer = require('./services/mail').GhostMailer;
|
||||||
const config = require('../shared/config');
|
const config = require('../shared/config');
|
||||||
const urlUtils = require('./../shared/url-utils');
|
const urlUtils = require('./../shared/url-utils');
|
||||||
const errors = require('@tryghost/errors');
|
const errors = require('@tryghost/errors');
|
||||||
|
@ -23,9 +24,12 @@ const i18n = require('../shared/i18n');
|
||||||
const logging = require('../shared/logging');
|
const logging = require('../shared/logging');
|
||||||
const request = require('./lib/request');
|
const request = require('./lib/request');
|
||||||
const ghostVersion = require('./lib/ghost-version');
|
const ghostVersion = require('./lib/ghost-version');
|
||||||
|
|
||||||
const internal = {context: {internal: true}};
|
const internal = {context: {internal: true}};
|
||||||
const allowedCheckEnvironments = ['development', 'production'];
|
const allowedCheckEnvironments = ['development', 'production'];
|
||||||
|
|
||||||
|
const ghostMailer = new GhostMailer();
|
||||||
|
|
||||||
function nextCheckTimestamp() {
|
function nextCheckTimestamp() {
|
||||||
const now = Math.round(new Date().getTime() / 1000);
|
const now = Math.round(new Date().getTime() / 1000);
|
||||||
return now + (24 * 3600);
|
return now + (24 * 3600);
|
||||||
|
@ -67,6 +71,17 @@ async function createCustomNotification(notification) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {users} = await api.users.browse(Object.assign({
|
||||||
|
limit: 'all',
|
||||||
|
include: ['roles']
|
||||||
|
}, internal));
|
||||||
|
|
||||||
|
const adminEmails = users
|
||||||
|
.filter(user => ['Owner', 'Administrator'].includes(user.roles[0].name))
|
||||||
|
.map(user => user.email);
|
||||||
|
|
||||||
|
const siteUrl = config.get('url');
|
||||||
|
|
||||||
for (const message of notification.messages) {
|
for (const message of notification.messages) {
|
||||||
const toAdd = {
|
const toAdd = {
|
||||||
// @NOTE: the update check service returns "0" or "1" (https://github.com/TryGhost/UpdateCheck/issues/43)
|
// @NOTE: the update check service returns "0" or "1" (https://github.com/TryGhost/UpdateCheck/issues/43)
|
||||||
|
@ -80,6 +95,21 @@ async function createCustomNotification(notification) {
|
||||||
message: message.content
|
message: message.content
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (toAdd.type === 'alert') {
|
||||||
|
for (const email of adminEmails) {
|
||||||
|
try {
|
||||||
|
ghostMailer.send({
|
||||||
|
to: email,
|
||||||
|
subject: `Action required: Critical alert from Ghost instance ${siteUrl}`,
|
||||||
|
html: toAdd.message,
|
||||||
|
forceTextContent: true
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
logging.err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
debug('Add Custom Notification', toAdd);
|
debug('Add Custom Notification', toAdd);
|
||||||
await api.notifications.add({notifications: [toAdd]}, {context: {internal: true}});
|
await api.notifications.add({notifications: [toAdd]}, {context: {internal: true}});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ const testUtils = require('../../utils');
|
||||||
const configUtils = require('../../utils/configUtils');
|
const configUtils = require('../../utils/configUtils');
|
||||||
const packageInfo = require('../../../package.json');
|
const packageInfo = require('../../../package.json');
|
||||||
const api = require('../../../core/server/api').v2;
|
const api = require('../../../core/server/api').v2;
|
||||||
|
const mailService = require('../../../core/server/services/mail/');
|
||||||
|
|
||||||
let updateCheck = rewire('../../../core/server/update-check');
|
let updateCheck = rewire('../../../core/server/update-check');
|
||||||
let ghostVersion = rewire('../../../core/server/lib/ghost-version');
|
let ghostVersion = rewire('../../../core/server/lib/ghost-version');
|
||||||
|
@ -17,6 +18,7 @@ describe('Update Check', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
updateCheck = rewire('../../../core/server/update-check');
|
updateCheck = rewire('../../../core/server/update-check');
|
||||||
ghostVersion = rewire('../../../core/server/lib/ghost-version');
|
ghostVersion = rewire('../../../core/server/lib/ghost-version');
|
||||||
|
sinon.stub(mailService.GhostMailer.prototype, 'send').resolves('Stubed email response');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
@ -322,6 +324,43 @@ describe('Update Check', function () {
|
||||||
})
|
})
|
||||||
.catch(done);
|
.catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should send an email for critical notification', async function () {
|
||||||
|
const createCustomNotification = updateCheck.__get__('createCustomNotification');
|
||||||
|
|
||||||
|
const notification = {
|
||||||
|
id: 1,
|
||||||
|
custom: 1,
|
||||||
|
messages: [{
|
||||||
|
id: uuid.v4(),
|
||||||
|
version: 'custom1',
|
||||||
|
content: '<p>Critical message. Upgrade your site!</p>',
|
||||||
|
dismissible: false,
|
||||||
|
top: true,
|
||||||
|
type: 'alert'
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
await createCustomNotification(notification);
|
||||||
|
|
||||||
|
mailService.GhostMailer.prototype.send.called.should.be.true();
|
||||||
|
mailService.GhostMailer.prototype.send.args[0][0].to.should.equal('jbloggs@example.com');
|
||||||
|
mailService.GhostMailer.prototype.send.args[0][0].subject.should.equal('Action required: Critical alert from Ghost instance http://127.0.0.1:2369');
|
||||||
|
mailService.GhostMailer.prototype.send.args[0][0].html.should.equal('<p>Critical message. Upgrade your site!</p>');
|
||||||
|
mailService.GhostMailer.prototype.send.args[0][0].forceTextContent.should.equal(true);
|
||||||
|
|
||||||
|
const results = await api.notifications.browse(testUtils.context.internal);
|
||||||
|
|
||||||
|
should.exist(results);
|
||||||
|
should.exist(results.notifications);
|
||||||
|
results.notifications.length.should.eql(1);
|
||||||
|
|
||||||
|
const targetNotification = _.find(results.notifications, {id: notification.messages[0].id});
|
||||||
|
should.exist(targetNotification);
|
||||||
|
targetNotification.dismissible.should.eql(notification.messages[0].dismissible);
|
||||||
|
targetNotification.top.should.eql(notification.messages[0].top);
|
||||||
|
targetNotification.type.should.eql(notification.messages[0].type);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fn: updateCheckResponse', function () {
|
describe('fn: updateCheckResponse', function () {
|
||||||
|
|
Loading…
Add table
Reference in a new issue