overleaf/services/notifications/app/js/Notifications.js

140 lines
4.6 KiB
JavaScript
Raw Normal View History

/* eslint-disable
camelcase,
handle-callback-err,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* 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 logger = require('logger-sharelatex')
const { db, ObjectId } = require('./mongodb')
const metrics = require('@overleaf/metrics')
2016-01-14 07:35:16 -05:00
module.exports = Notifications = {
getUserNotifications(user_id, callback) {
if (callback == null) {
2020-06-04 03:50:05 -04:00
callback = function (err, notifications) {}
}
const query = {
user_id: ObjectId(user_id),
2021-07-13 07:04:44 -04:00
templateKey: { $exists: true },
}
db.notifications.find(query).toArray(callback)
},
2016-01-14 07:35:16 -05:00
_countExistingNotifications(user_id, notification, callback) {
if (callback == null) {
2020-06-04 03:50:05 -04:00
callback = function (err, count) {}
}
const query = {
user_id: ObjectId(user_id),
2021-07-13 07:04:44 -04:00
key: notification.key,
}
2020-06-04 03:50:05 -04:00
return db.notifications.count(query, function (err, count) {
if (err != null) {
return callback(err)
}
return callback(null, count)
})
},
2016-01-14 07:35:16 -05:00
addNotification(user_id, notification, callback) {
2021-07-13 07:04:44 -04:00
return this._countExistingNotifications(
user_id,
notification,
function (err, count) {
if (err != null) {
return callback(err)
}
2021-07-13 07:04:44 -04:00
if (count !== 0 && !notification.forceCreate) {
return callback()
}
const doc = {
user_id: ObjectId(user_id),
key: notification.key,
messageOpts: notification.messageOpts,
templateKey: notification.templateKey,
}
// 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)
}
}
db.notifications.updateOne(
{ user_id: doc.user_id, key: notification.key },
{ $set: doc },
{ upsert: true },
callback
)
}
2021-07-13 07:04:44 -04:00
)
},
removeNotificationId(user_id, notification_id, callback) {
const searchOps = {
user_id: ObjectId(user_id),
2021-07-13 07:04:44 -04:00
_id: ObjectId(notification_id),
}
const updateOperation = { $unset: { templateKey: true, messageOpts: true } }
db.notifications.updateOne(searchOps, updateOperation, callback)
},
removeNotificationKey(user_id, notification_key, callback) {
const searchOps = {
user_id: ObjectId(user_id),
2021-07-13 07:04:44 -04:00
key: notification_key,
}
const updateOperation = { $unset: { templateKey: true } }
db.notifications.updateOne(searchOps, updateOperation, callback)
},
2016-01-14 07:35:16 -05:00
removeNotificationByKeyOnly(notification_key, callback) {
const searchOps = { key: notification_key }
const updateOperation = { $unset: { templateKey: true } }
db.notifications.updateOne(searchOps, updateOperation, callback)
},
2016-02-05 04:38:32 -05:00
countNotificationsByKeyOnly(notificationKey, callback) {
const searchOps = { key: notificationKey, templateKey: { $exists: true } }
db.notifications.count(searchOps, callback)
},
deleteUnreadNotificationsByKeyOnlyBulk(notificationKey, callback) {
if (typeof notificationKey !== 'string') {
throw new Error('refusing to bulk delete arbitrary notifications')
}
const searchOps = { key: notificationKey, templateKey: { $exists: true } }
db.notifications.deleteMany(searchOps, (err, result) => {
if (err) return callback(err)
callback(null, result.deletedCount)
})
},
// hard delete of doc, rather than removing the templateKey
deleteNotificationByKeyOnly(notification_key, callback) {
const searchOps = { key: notification_key }
db.notifications.deleteOne(searchOps, callback)
2021-07-13 07:04:44 -04:00
},
}
2021-07-13 07:04:44 -04:00
;['getUserNotifications', 'addNotification'].map(method =>
metrics.timeAsyncMethod(Notifications, method, 'mongo.Notifications', logger)
)