9f2d68a027
refs #9866
197 lines
6.4 KiB
JavaScript
197 lines
6.4 KiB
JavaScript
const moment = require('moment-timezone');
|
|
const semver = require('semver');
|
|
const Promise = require('bluebird');
|
|
const _ = require('lodash');
|
|
const settingsCache = require('../../services/settings/cache');
|
|
const ghostVersion = require('../../lib/ghost-version');
|
|
const common = require('../../lib/common');
|
|
const ObjectId = require('bson-objectid');
|
|
const api = require('./index');
|
|
const internalContext = {context: {internal: true}};
|
|
const _private = {};
|
|
|
|
_private.fetchAllNotifications = () => {
|
|
let allNotifications = settingsCache.get('notifications');
|
|
|
|
allNotifications.forEach((notification) => {
|
|
notification.addedAt = moment(notification.addedAt).toDate();
|
|
});
|
|
|
|
return allNotifications;
|
|
};
|
|
|
|
module.exports = {
|
|
docName: 'notifications',
|
|
|
|
browse: {
|
|
permissions: true,
|
|
query() {
|
|
let allNotifications = _private.fetchAllNotifications();
|
|
allNotifications = _.orderBy(allNotifications, 'addedAt', 'desc');
|
|
|
|
allNotifications = allNotifications.filter((notification) => {
|
|
// CASE: do not return old release notification
|
|
if (!notification.custom && notification.message) {
|
|
const notificationVersion = notification.message.match(/(\d+\.)(\d+\.)(\d+)/),
|
|
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;
|
|
});
|
|
|
|
return allNotifications;
|
|
}
|
|
},
|
|
|
|
add: {
|
|
statusCode(result) {
|
|
if (result.notifications.length) {
|
|
return 201;
|
|
} else {
|
|
return 200;
|
|
}
|
|
},
|
|
permissions: true,
|
|
query(frame) {
|
|
const defaults = {
|
|
dismissible: true,
|
|
location: 'bottom',
|
|
status: 'alert',
|
|
id: ObjectId.generate()
|
|
};
|
|
|
|
const overrides = {
|
|
seen: false,
|
|
addedAt: moment().toDate()
|
|
};
|
|
|
|
let notificationsToCheck = frame.data.notifications;
|
|
let addedNotifications = [];
|
|
|
|
const allNotifications = _private.fetchAllNotifications();
|
|
|
|
notificationsToCheck.forEach((notification) => {
|
|
const isDuplicate = allNotifications.find((n) => {
|
|
return n.id === notification.id;
|
|
});
|
|
|
|
if (!isDuplicate) {
|
|
addedNotifications.push(Object.assign({}, defaults, notification, overrides));
|
|
}
|
|
});
|
|
|
|
const hasReleaseNotification = notificationsToCheck.find((notification) => {
|
|
return !notification.custom;
|
|
});
|
|
|
|
// CASE: remove any existing release notifications if a new release notification comes in
|
|
if (hasReleaseNotification) {
|
|
_.remove(allNotifications, (el) => {
|
|
return !el.custom;
|
|
});
|
|
}
|
|
|
|
// CASE: nothing to add, skip
|
|
if (!addedNotifications.length) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
const addedReleaseNotifications = addedNotifications.filter((notification) => {
|
|
return !notification.custom;
|
|
});
|
|
|
|
// CASE: only latest release notification
|
|
if (addedReleaseNotifications.length > 1) {
|
|
addedNotifications = addedNotifications.filter((notification) => {
|
|
return notification.custom;
|
|
});
|
|
addedNotifications.push(_.orderBy(addedReleaseNotifications, 'created_at', 'desc')[0]);
|
|
}
|
|
|
|
return api.settings.edit({
|
|
settings: [{
|
|
key: 'notifications',
|
|
value: allNotifications.concat(addedNotifications)
|
|
}]
|
|
}, internalContext).then(() => {
|
|
return addedNotifications;
|
|
});
|
|
}
|
|
},
|
|
|
|
destroy: {
|
|
statusCode: 204,
|
|
options: ['notification_id'],
|
|
validation: {
|
|
options: {
|
|
notification_id: {
|
|
required: true
|
|
}
|
|
}
|
|
},
|
|
permissions: true,
|
|
query(frame) {
|
|
const allNotifications = _private.fetchAllNotifications();
|
|
|
|
const notificationToMarkAsSeen = allNotifications.find((notification) => {
|
|
return notification.id === frame.options.notification_id;
|
|
}),
|
|
notificationToMarkAsSeenIndex = allNotifications.findIndex((notification) => {
|
|
return notification.id === frame.options.notification_id;
|
|
});
|
|
|
|
if (notificationToMarkAsSeenIndex > -1 && !notificationToMarkAsSeen.dismissible) {
|
|
return Promise.reject(new common.errors.NoPermissionError({
|
|
message: common.i18n.t('errors.api.notifications.noPermissionToDismissNotif')
|
|
}));
|
|
}
|
|
|
|
if (notificationToMarkAsSeenIndex < 0) {
|
|
return Promise.reject(new common.errors.NotFoundError({
|
|
message: common.i18n.t('errors.api.notifications.notificationDoesNotExist')
|
|
}));
|
|
}
|
|
|
|
if (notificationToMarkAsSeen.seen) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
allNotifications[notificationToMarkAsSeenIndex].seen = true;
|
|
|
|
return api.settings.edit({
|
|
settings: [{
|
|
key: 'notifications',
|
|
value: allNotifications
|
|
}]
|
|
}, internalContext).return();
|
|
}
|
|
},
|
|
|
|
destroyAll: {
|
|
statusCode: 204,
|
|
permissions: {
|
|
method: 'destroy'
|
|
},
|
|
query() {
|
|
const allNotifications = _private.fetchAllNotifications();
|
|
|
|
allNotifications.forEach((notification) => {
|
|
notification.seen = true;
|
|
});
|
|
|
|
return api.settings.edit({
|
|
settings: [{
|
|
key: 'notifications',
|
|
value: allNotifications
|
|
}]
|
|
}, internalContext).return();
|
|
}
|
|
}
|
|
};
|