|
|
@@ -1,121 +1,109 @@
|
|
|
import logger from '@overleaf/logger'
|
|
|
import { db, ObjectId } from './mongodb.js'
|
|
|
|
|
|
-export default {
|
|
|
- getUserNotifications(userId, callback) {
|
|
|
- if (callback == null) {
|
|
|
- callback = function () {}
|
|
|
- }
|
|
|
- const query = {
|
|
|
- user_id: new ObjectId(userId),
|
|
|
- templateKey: { $exists: true },
|
|
|
- }
|
|
|
- db.notifications.find(query).toArray(callback)
|
|
|
- },
|
|
|
+async function getUserNotifications(userId) {
|
|
|
+ const query = {
|
|
|
+ user_id: new ObjectId(userId),
|
|
|
+ templateKey: { $exists: true },
|
|
|
+ }
|
|
|
+ return await db.notifications.find(query).toArray()
|
|
|
+}
|
|
|
|
|
|
- _countExistingNotifications(userId, notification, callback) {
|
|
|
- if (callback == null) {
|
|
|
- callback = function () {}
|
|
|
- }
|
|
|
- const query = {
|
|
|
- user_id: new ObjectId(userId),
|
|
|
- key: notification.key,
|
|
|
+async function _countExistingNotifications(userId, notification) {
|
|
|
+ const query = {
|
|
|
+ user_id: new ObjectId(userId),
|
|
|
+ key: notification.key,
|
|
|
+ }
|
|
|
+ return await db.notifications.count(query)
|
|
|
+}
|
|
|
+
|
|
|
+async function addNotification(userId, notification, callback) {
|
|
|
+ const count = await _countExistingNotifications(userId, notification)
|
|
|
+ if (count !== 0 && !notification.forceCreate) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const doc = {
|
|
|
+ user_id: new ObjectId(userId),
|
|
|
+ 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)
|
|
|
+ // _testValue assignment will throw if `expires` is not a valid date
|
|
|
+ // eslint-disable-next-line no-unused-vars
|
|
|
+ const _testValue = doc.expires.toISOString()
|
|
|
+ } catch (error) {
|
|
|
+ logger.error(
|
|
|
+ { userId, expires: notification.expires },
|
|
|
+ 'error converting `expires` field to Date'
|
|
|
+ )
|
|
|
+ throw error
|
|
|
}
|
|
|
- return db.notifications.count(query, function (err, count) {
|
|
|
- if (err != null) {
|
|
|
- return callback(err)
|
|
|
- }
|
|
|
- return callback(null, count)
|
|
|
- })
|
|
|
- },
|
|
|
+ }
|
|
|
+ return await db.notifications.updateOne(
|
|
|
+ { user_id: doc.user_id, key: notification.key },
|
|
|
+ { $set: doc },
|
|
|
+ { upsert: true }
|
|
|
+ )
|
|
|
+}
|
|
|
|
|
|
- addNotification(userId, notification, callback) {
|
|
|
- return this._countExistingNotifications(
|
|
|
- userId,
|
|
|
- notification,
|
|
|
- function (err, count) {
|
|
|
- if (err != null) {
|
|
|
- return callback(err)
|
|
|
- }
|
|
|
- if (count !== 0 && !notification.forceCreate) {
|
|
|
- return callback()
|
|
|
- }
|
|
|
- const doc = {
|
|
|
- user_id: new ObjectId(userId),
|
|
|
- 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(
|
|
|
- { userId, 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
|
|
|
- )
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
+async function removeNotificationId(userId, notificationId) {
|
|
|
+ const searchOps = {
|
|
|
+ user_id: new ObjectId(userId),
|
|
|
+ _id: new ObjectId(notificationId),
|
|
|
+ }
|
|
|
+ const updateOperation = { $unset: { templateKey: true, messageOpts: true } }
|
|
|
+ return await db.notifications.updateOne(searchOps, updateOperation)
|
|
|
+}
|
|
|
|
|
|
- removeNotificationId(userId, notificationId, callback) {
|
|
|
- const searchOps = {
|
|
|
- user_id: new ObjectId(userId),
|
|
|
- _id: new ObjectId(notificationId),
|
|
|
- }
|
|
|
- const updateOperation = { $unset: { templateKey: true, messageOpts: true } }
|
|
|
- db.notifications.updateOne(searchOps, updateOperation, callback)
|
|
|
- },
|
|
|
+async function removeNotificationKey(userId, notificationKey) {
|
|
|
+ const searchOps = {
|
|
|
+ user_id: new ObjectId(userId),
|
|
|
+ key: notificationKey,
|
|
|
+ }
|
|
|
+ const updateOperation = { $unset: { templateKey: true } }
|
|
|
+ return await db.notifications.updateOne(searchOps, updateOperation)
|
|
|
+}
|
|
|
|
|
|
- removeNotificationKey(userId, notificationKey, callback) {
|
|
|
- const searchOps = {
|
|
|
- user_id: new ObjectId(userId),
|
|
|
- key: notificationKey,
|
|
|
- }
|
|
|
- const updateOperation = { $unset: { templateKey: true } }
|
|
|
- db.notifications.updateOne(searchOps, updateOperation, callback)
|
|
|
- },
|
|
|
+async function removeNotificationByKeyOnly(notificationKey) {
|
|
|
+ const searchOps = { key: notificationKey }
|
|
|
+ const updateOperation = { $unset: { templateKey: true } }
|
|
|
+ return await db.notifications.updateOne(searchOps, updateOperation)
|
|
|
+}
|
|
|
|
|
|
- removeNotificationByKeyOnly(notificationKey, callback) {
|
|
|
- const searchOps = { key: notificationKey }
|
|
|
- const updateOperation = { $unset: { templateKey: true } }
|
|
|
- db.notifications.updateOne(searchOps, updateOperation, callback)
|
|
|
- },
|
|
|
+async function countNotificationsByKeyOnly(notificationKey) {
|
|
|
+ const searchOps = { key: notificationKey, templateKey: { $exists: true } }
|
|
|
+ return await db.notifications.countDocuments(searchOps)
|
|
|
+}
|
|
|
|
|
|
- countNotificationsByKeyOnly(notificationKey, callback) {
|
|
|
- const searchOps = { key: notificationKey, templateKey: { $exists: true } }
|
|
|
- db.notifications.count(searchOps, callback)
|
|
|
- },
|
|
|
+async function deleteUnreadNotificationsByKeyOnlyBulk(notificationKey) {
|
|
|
+ if (typeof notificationKey !== 'string') {
|
|
|
+ throw new Error('refusing to bulk delete arbitrary notifications')
|
|
|
+ }
|
|
|
+ const searchOps = { key: notificationKey, templateKey: { $exists: true } }
|
|
|
+ const result = await db.notifications.deleteMany(searchOps)
|
|
|
+ return result.deletedCount
|
|
|
+}
|
|
|
|
|
|
- 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
|
|
|
+async function deleteNotificationByKeyOnly(notificationKey) {
|
|
|
+ const searchOps = { key: notificationKey }
|
|
|
+ return await db.notifications.deleteOne(searchOps)
|
|
|
+}
|
|
|
|
|
|
- // hard delete of doc, rather than removing the templateKey
|
|
|
- deleteNotificationByKeyOnly(notificationKey, callback) {
|
|
|
- const searchOps = { key: notificationKey }
|
|
|
- db.notifications.deleteOne(searchOps, callback)
|
|
|
- },
|
|
|
+export default {
|
|
|
+ addNotification,
|
|
|
+ getUserNotifications,
|
|
|
+ removeNotificationId,
|
|
|
+ removeNotificationKey,
|
|
|
+ removeNotificationByKeyOnly,
|
|
|
+ countNotificationsByKeyOnly,
|
|
|
+ deleteUnreadNotificationsByKeyOnlyBulk,
|
|
|
+ deleteNotificationByKeyOnly,
|
|
|
}
|