2020-01-13 14:00:33 -05:00
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
* DS207: Consider shorter variations of null checks
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
|
|
|
let Notifications;
|
|
|
|
const Settings = require('settings-sharelatex');
|
|
|
|
const logger = require('logger-sharelatex');
|
|
|
|
const mongojs = require('mongojs');
|
|
|
|
const db = mongojs(Settings.mongo != null ? Settings.mongo.url : undefined, ['notifications']);
|
|
|
|
const { ObjectId } = require("mongojs");
|
|
|
|
const metrics = require('metrics-sharelatex');
|
2016-01-14 07:35:16 -05:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
module.exports = (Notifications = {
|
2016-01-14 07:35:16 -05:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
getUserNotifications(user_id, callback){
|
|
|
|
if (callback == null) { callback = function(err, notifications){}; }
|
|
|
|
const query = {
|
|
|
|
user_id: ObjectId(user_id),
|
2016-01-14 15:42:48 -05:00
|
|
|
templateKey: {"$exists":true}
|
2020-01-13 14:00:33 -05:00
|
|
|
};
|
|
|
|
return db.notifications.find(query, (err, notifications)=> callback(err, notifications));
|
|
|
|
},
|
2016-01-14 07:35:16 -05:00
|
|
|
|
2016-08-17 05:52:35 -04:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
_countExistingNotifications(user_id, notification, callback){
|
|
|
|
if (callback == null) { callback = function(err, count){}; }
|
|
|
|
const query = {
|
|
|
|
user_id: ObjectId(user_id),
|
2016-01-14 07:35:16 -05:00
|
|
|
key: notification.key
|
2020-01-13 14:00:33 -05:00
|
|
|
};
|
|
|
|
return db.notifications.count(query, function(err, count){
|
|
|
|
if (err != null) { return callback(err); }
|
|
|
|
return callback(null, count);
|
|
|
|
});
|
|
|
|
},
|
2016-08-17 05:52:35 -04:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
addNotification(user_id, notification, callback){
|
|
|
|
return this._countExistingNotifications(user_id, notification, function(err, count){
|
|
|
|
if (err != null) { return callback(err); }
|
|
|
|
if ((count !== 0) && !notification.forceCreate) { return callback(); }
|
|
|
|
const doc = {
|
|
|
|
user_id: ObjectId(user_id),
|
|
|
|
key: notification.key,
|
|
|
|
messageOpts: notification.messageOpts,
|
2019-11-28 11:40:14 -05:00
|
|
|
templateKey: notification.templateKey
|
2020-01-13 14:00:33 -05:00
|
|
|
};
|
|
|
|
// TTL index on the optional `expires` field, which should arrive as an iso date-string, corresponding to
|
|
|
|
// a datetime in the future when the document should be automatically removed.
|
|
|
|
// in Mongo, TTL indexes only work on date fields, and ignore the document when that field is missing
|
|
|
|
// see `README.md` for instruction on creating TTL index
|
|
|
|
if (notification.expires != null) {
|
|
|
|
try {
|
|
|
|
doc.expires = new Date(notification.expires);
|
|
|
|
const _testValue = doc.expires.toISOString();
|
|
|
|
} catch (error) {
|
|
|
|
err = error;
|
|
|
|
logger.error({user_id, expires: notification.expires}, "error converting `expires` field to Date");
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return db.notifications.update({user_id: doc.user_id, key: notification.key}, doc, {upsert: true}, callback);
|
|
|
|
});
|
|
|
|
},
|
2016-01-14 07:35:16 -05:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
removeNotificationId(user_id, notification_id, callback){
|
|
|
|
const searchOps = {
|
|
|
|
user_id:ObjectId(user_id),
|
2016-01-14 15:42:48 -05:00
|
|
|
_id:ObjectId(notification_id)
|
2020-01-13 14:00:33 -05:00
|
|
|
};
|
|
|
|
const updateOperation =
|
|
|
|
{"$unset": {templateKey:true, messageOpts: true}};
|
|
|
|
return db.notifications.update(searchOps, updateOperation, callback);
|
|
|
|
},
|
2016-02-05 04:38:32 -05:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
removeNotificationKey(user_id, notification_key, callback){
|
|
|
|
const searchOps = {
|
|
|
|
user_id:ObjectId(user_id),
|
2016-02-05 04:38:32 -05:00
|
|
|
key: notification_key
|
2020-01-13 14:00:33 -05:00
|
|
|
};
|
|
|
|
const updateOperation =
|
|
|
|
{"$unset": {templateKey:true}};
|
|
|
|
return db.notifications.update(searchOps, updateOperation, callback);
|
|
|
|
},
|
2016-08-11 05:01:21 -04:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
removeNotificationByKeyOnly(notification_key, callback){
|
|
|
|
const searchOps =
|
|
|
|
{key: notification_key};
|
|
|
|
const updateOperation =
|
|
|
|
{"$unset": {templateKey:true}};
|
|
|
|
return db.notifications.update(searchOps, updateOperation, callback);
|
|
|
|
},
|
2016-08-17 09:10:36 -04:00
|
|
|
|
2020-01-13 14:00:33 -05:00
|
|
|
// hard delete of doc, rather than removing the templateKey
|
|
|
|
deleteNotificationByKeyOnly(notification_key, callback){
|
|
|
|
const searchOps =
|
|
|
|
{key: notification_key};
|
|
|
|
return db.notifications.remove(searchOps, {justOne: true}, callback);
|
|
|
|
}
|
|
|
|
});
|
2017-03-17 05:47:45 -04:00
|
|
|
|
|
|
|
|
2017-03-17 11:54:15 -04:00
|
|
|
[
|
|
|
|
'getUserNotifications',
|
|
|
|
'addNotification'
|
2020-01-13 14:00:33 -05:00
|
|
|
].map(method => metrics.timeAsyncMethod(Notifications, method, 'mongo.Notifications', logger));
|