0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

🐛 Fixed showing old release notifications in the about page

no issue

- reported in slack (https://ghost.slack.com/files/U8QV8DXQB/F8TSBQ532/image.png)
- do not expose old release notification
  - e.g. you are on 1.20.0
  - you receive a notification for 1.20.1 to update
  - you update to 1.20.1
- ensure we protect exposing the release notification (compare against blog version)
- protect against wrong formats
- @TODO: the notifications could store a `version` property
  - by that we could use `notification.version` and don't have to match the version in the message
This commit is contained in:
kirrg001 2018-01-18 11:42:26 +01:00
parent 147813c2d8
commit 357ea3dffd
5 changed files with 80 additions and 6 deletions

View file

@ -5,8 +5,10 @@
const Promise = require('bluebird'),
_ = require('lodash'),
semver = require('semver'),
moment = require('moment'),
ObjectId = require('bson-objectid'),
ghostVersion = require('../lib/ghost-version'),
pipeline = require('../lib/promise/pipeline'),
permissions = require('../services/permissions'),
localUtils = require('./utils'),
@ -63,6 +65,18 @@ notifications = {
allNotifications = _.orderBy(allNotifications, 'addedAt', 'desc');
allNotifications = allNotifications.filter(function (notification) {
// CASE: do not return old release notification
if (!notification.custom && notification.message) {
let notificationVersion = notification.message.match(/(\d+\.)(\d+\.)(\d+)/);
let blogVersion = ghostVersion.full.match(/^(\d+\.)(\d+\.)(\d+)/);
if (notificationVersion && blogVersion && semver.gt(notificationVersion[0], blogVersion[0])) {
return true;
} else {
return false;
}
}
return notification.seen !== true;
});

View file

@ -25,7 +25,8 @@ describe('Notifications API', function () {
describe('Add', function () {
var newNotification = {
type: 'info',
message: 'test notification'
message: 'test notification',
custom: true
};
it('creates a new notification', function (done) {
@ -59,7 +60,8 @@ describe('Notifications API', function () {
var newNotification = {
type: 'info',
message: 'test notification',
status: 'alert'
status: 'alert',
custom: true
};
it('deletes a notification', function (done) {

View file

@ -108,7 +108,8 @@ describe('Notifications API', function () {
it('can browse (internal)', function (done) {
var msg = {
type: 'error', // this can be 'error', 'success', 'warn' and 'info'
message: 'This is an error' // A string. Should fit in one line.
message: 'This is an error', // A string. Should fit in one line.
custom: true
};
NotificationsAPI.add({notifications: [msg]}, testUtils.context.internal).then(function () {
NotificationsAPI.browse(testUtils.context.internal).then(function (results) {
@ -124,7 +125,8 @@ describe('Notifications API', function () {
it('can browse (owner)', function (done) {
var msg = {
type: 'error', // this can be 'error', 'success', 'warn' and 'info'
message: 'This is an error' // A string. Should fit in one line.
message: 'This is an error', // A string. Should fit in one line.
custom: true
};
NotificationsAPI.add({notifications: [msg]}, testUtils.context.owner).then(function () {
NotificationsAPI.browse(testUtils.context.owner).then(function (results) {

View file

@ -9,13 +9,15 @@ var _ = require('lodash'),
configUtils = require('../utils/configUtils'),
packageInfo = require('../../../package'),
updateCheck = rewire('../../server/update-check'),
ghostVersion = rewire('../../server/lib/ghost-version'),
SettingsAPI = require('../../server/api/settings'),
NotificationsAPI = require('../../server/api/notifications'),
NotificationsAPI = rewire('../../server/api/notifications'),
sandbox = sinon.sandbox.create();
describe('Update Check', function () {
beforeEach(function () {
updateCheck = rewire('../../server/update-check');
NotificationsAPI = rewire('../../server/api/notifications');
});
afterEach(function () {
@ -168,6 +170,8 @@ describe('Update Check', function () {
}]
};
NotificationsAPI.__set__('ghostVersion.full', '0.8.1');
createCustomNotification(notification).then(function () {
return NotificationsAPI.browse(testUtils.context.internal);
}).then(function (results) {
@ -187,6 +191,58 @@ describe('Update Check', function () {
}).catch(done);
});
it('release notification version format is wrong', function (done) {
var createCustomNotification = updateCheck.__get__('createCustomNotification'),
notification = {
id: 1,
custom: 0,
messages: [{
id: uuid.v4(),
version: '0.9.x',
content: '<p>Hey there! This is for 0.9 version</p>',
dismissible: true,
top: true
}]
};
NotificationsAPI.__set__('ghostVersion.full', '0.8.1');
createCustomNotification(notification).then(function () {
return NotificationsAPI.browse(testUtils.context.internal);
}).then(function (results) {
should.exist(results);
should.exist(results.notifications);
results.notifications.length.should.eql(0);
done();
}).catch(done);
});
it('blog version format is wrong', function (done) {
var createCustomNotification = updateCheck.__get__('createCustomNotification'),
notification = {
id: 1,
custom: 0,
messages: [{
id: uuid.v4(),
version: '0.9.x',
content: '<p>Hey there! This is for 0.9.0 version</p>',
dismissible: true,
top: true
}]
};
NotificationsAPI.__set__('ghostVersion.full', '0.8');
createCustomNotification(notification).then(function () {
return NotificationsAPI.browse(testUtils.context.internal);
}).then(function (results) {
should.exist(results);
should.exist(results.notifications);
results.notifications.length.should.eql(0);
done();
}).catch(done);
});
it('should create a custom notification', function (done) {
var createCustomNotification = updateCheck.__get__('createCustomNotification'),
notification = {

View file

@ -50,7 +50,7 @@ var _ = require('lodash'),
accesstoken: _.keys(schema.accesstokens),
role: _.keys(schema.roles),
permission: _.keys(schema.permissions),
notification: ['type', 'message', 'status', 'id', 'dismissible', 'location'],
notification: ['type', 'message', 'status', 'id', 'dismissible', 'location', 'custom'],
theme: ['name', 'package', 'active'],
themes: ['themes'],
invites: _(schema.invites).keys().without('token').value(),