Notifications.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /* eslint-disable
  2. no-unused-vars,
  3. */
  4. // TODO: This file was created by bulk-decaffeinate.
  5. // Fix any style issues and re-enable lint.
  6. /*
  7. * decaffeinate suggestions:
  8. * DS102: Remove unnecessary code created because of implicit returns
  9. * DS207: Consider shorter variations of null checks
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const logger = require('@overleaf/logger')
  13. const { db, ObjectId } = require('./mongodb')
  14. module.exports = {
  15. getUserNotifications(userId, callback) {
  16. if (callback == null) {
  17. callback = function () {}
  18. }
  19. const query = {
  20. user_id: new ObjectId(userId),
  21. templateKey: { $exists: true },
  22. }
  23. db.notifications.find(query).toArray(callback)
  24. },
  25. _countExistingNotifications(userId, notification, callback) {
  26. if (callback == null) {
  27. callback = function () {}
  28. }
  29. const query = {
  30. user_id: new ObjectId(userId),
  31. key: notification.key,
  32. }
  33. return db.notifications.count(query, function (err, count) {
  34. if (err != null) {
  35. return callback(err)
  36. }
  37. return callback(null, count)
  38. })
  39. },
  40. addNotification(userId, notification, callback) {
  41. return this._countExistingNotifications(
  42. userId,
  43. notification,
  44. function (err, count) {
  45. if (err != null) {
  46. return callback(err)
  47. }
  48. if (count !== 0 && !notification.forceCreate) {
  49. return callback()
  50. }
  51. const doc = {
  52. user_id: new ObjectId(userId),
  53. key: notification.key,
  54. messageOpts: notification.messageOpts,
  55. templateKey: notification.templateKey,
  56. }
  57. // TTL index on the optional `expires` field, which should arrive as an iso date-string, corresponding to
  58. // a datetime in the future when the document should be automatically removed.
  59. // in Mongo, TTL indexes only work on date fields, and ignore the document when that field is missing
  60. // see `README.md` for instruction on creating TTL index
  61. if (notification.expires != null) {
  62. try {
  63. doc.expires = new Date(notification.expires)
  64. const _testValue = doc.expires.toISOString()
  65. } catch (error) {
  66. err = error
  67. logger.error(
  68. { userId, expires: notification.expires },
  69. 'error converting `expires` field to Date'
  70. )
  71. return callback(err)
  72. }
  73. }
  74. db.notifications.updateOne(
  75. { user_id: doc.user_id, key: notification.key },
  76. { $set: doc },
  77. { upsert: true },
  78. callback
  79. )
  80. }
  81. )
  82. },
  83. removeNotificationId(userId, notificationId, callback) {
  84. const searchOps = {
  85. user_id: new ObjectId(userId),
  86. _id: new ObjectId(notificationId),
  87. }
  88. const updateOperation = { $unset: { templateKey: true, messageOpts: true } }
  89. db.notifications.updateOne(searchOps, updateOperation, callback)
  90. },
  91. removeNotificationKey(userId, notificationKey, callback) {
  92. const searchOps = {
  93. user_id: new ObjectId(userId),
  94. key: notificationKey,
  95. }
  96. const updateOperation = { $unset: { templateKey: true } }
  97. db.notifications.updateOne(searchOps, updateOperation, callback)
  98. },
  99. removeNotificationByKeyOnly(notificationKey, callback) {
  100. const searchOps = { key: notificationKey }
  101. const updateOperation = { $unset: { templateKey: true } }
  102. db.notifications.updateOne(searchOps, updateOperation, callback)
  103. },
  104. countNotificationsByKeyOnly(notificationKey, callback) {
  105. const searchOps = { key: notificationKey, templateKey: { $exists: true } }
  106. db.notifications.count(searchOps, callback)
  107. },
  108. deleteUnreadNotificationsByKeyOnlyBulk(notificationKey, callback) {
  109. if (typeof notificationKey !== 'string') {
  110. throw new Error('refusing to bulk delete arbitrary notifications')
  111. }
  112. const searchOps = { key: notificationKey, templateKey: { $exists: true } }
  113. db.notifications.deleteMany(searchOps, (err, result) => {
  114. if (err) return callback(err)
  115. callback(null, result.deletedCount)
  116. })
  117. },
  118. // hard delete of doc, rather than removing the templateKey
  119. deleteNotificationByKeyOnly(notificationKey, callback) {
  120. const searchOps = { key: notificationKey }
  121. db.notifications.deleteOne(searchOps, callback)
  122. },
  123. }