NotificationsBuilder.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. const NotificationsHandler = require('./NotificationsHandler')
  2. const { promisifyAll } = require('../../util/promises')
  3. const request = require('request')
  4. const settings = require('@overleaf/settings')
  5. function dropboxDuplicateProjectNames(userId) {
  6. return {
  7. key: `dropboxDuplicateProjectNames-${userId}`,
  8. create(projectName, callback) {
  9. if (callback == null) {
  10. callback = function () {}
  11. }
  12. NotificationsHandler.createNotification(
  13. userId,
  14. this.key,
  15. 'notification_dropbox_duplicate_project_names',
  16. { projectName },
  17. null,
  18. true,
  19. callback
  20. )
  21. },
  22. read(callback) {
  23. if (callback == null) {
  24. callback = function () {}
  25. }
  26. NotificationsHandler.markAsReadWithKey(userId, this.key, callback)
  27. },
  28. }
  29. }
  30. function dropboxUnlinkedDueToLapsedReconfirmation(userId) {
  31. return {
  32. key: 'drobox-unlinked-due-to-lapsed-reconfirmation',
  33. create(callback) {
  34. NotificationsHandler.createNotification(
  35. userId,
  36. this.key,
  37. 'notification_dropbox_unlinked_due_to_lapsed_reconfirmation',
  38. {},
  39. null,
  40. true,
  41. callback
  42. )
  43. },
  44. read(callback) {
  45. NotificationsHandler.markAsReadWithKey(userId, this.key, callback)
  46. },
  47. }
  48. }
  49. function featuresUpgradedByAffiliation(affiliation, user) {
  50. return {
  51. key: `features-updated-by=${affiliation.institutionId}`,
  52. create(callback) {
  53. if (callback == null) {
  54. callback = function () {}
  55. }
  56. const messageOpts = { institutionName: affiliation.institutionName }
  57. NotificationsHandler.createNotification(
  58. user._id,
  59. this.key,
  60. 'notification_features_upgraded_by_affiliation',
  61. messageOpts,
  62. null,
  63. false,
  64. callback
  65. )
  66. },
  67. read(callback) {
  68. if (callback == null) {
  69. callback = function () {}
  70. }
  71. NotificationsHandler.markAsReadWithKey(user._id, this.key, callback)
  72. },
  73. }
  74. }
  75. function redundantPersonalSubscription(affiliation, user) {
  76. return {
  77. key: `redundant-personal-subscription-${affiliation.institutionId}`,
  78. create(callback) {
  79. if (callback == null) {
  80. callback = function () {}
  81. }
  82. const messageOpts = { institutionName: affiliation.institutionName }
  83. NotificationsHandler.createNotification(
  84. user._id,
  85. this.key,
  86. 'notification_personal_subscription_not_required_due_to_affiliation',
  87. messageOpts,
  88. null,
  89. false,
  90. callback
  91. )
  92. },
  93. read(callback) {
  94. if (callback == null) {
  95. callback = function () {}
  96. }
  97. NotificationsHandler.markAsReadWithKey(user._id, this.key, callback)
  98. },
  99. }
  100. }
  101. function projectInvite(invite, project, sendingUser, user) {
  102. return {
  103. key: `project-invite-${invite._id}`,
  104. create(callback) {
  105. if (callback == null) {
  106. callback = function () {}
  107. }
  108. const messageOpts = {
  109. userName: sendingUser.first_name,
  110. projectName: project.name,
  111. projectId: project._id.toString(),
  112. token: invite.token,
  113. }
  114. NotificationsHandler.createNotification(
  115. user._id,
  116. this.key,
  117. 'notification_project_invite',
  118. messageOpts,
  119. invite.expires,
  120. callback
  121. )
  122. },
  123. read(callback) {
  124. if (callback == null) {
  125. callback = function () {}
  126. }
  127. NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
  128. },
  129. }
  130. }
  131. function ipMatcherAffiliation(userId) {
  132. return {
  133. create(ip, callback) {
  134. if (callback == null) {
  135. callback = function () {}
  136. }
  137. if (!settings.apis.v1.url) {
  138. // service is not configured
  139. return callback()
  140. }
  141. request(
  142. {
  143. method: 'GET',
  144. url: `${settings.apis.v1.url}/api/v2/users/${userId}/ip_matcher`,
  145. auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass },
  146. body: { ip },
  147. json: true,
  148. timeout: settings.apis.v1.timeout,
  149. },
  150. function (error, response, body) {
  151. if (error != null) {
  152. return callback(error)
  153. }
  154. if (response.statusCode !== 200) {
  155. return callback()
  156. }
  157. const key = `ip-matched-affiliation-${body.id}`
  158. const portalPath = body.portal_slug
  159. ? `/${body.is_university ? 'edu' : 'org'}/${body.portal_slug}`
  160. : undefined
  161. const messageOpts = {
  162. university_name: body.name,
  163. institutionId: body.id,
  164. content: body.enrolment_ad_html,
  165. portalPath,
  166. ssoEnabled: body.sso_enabled,
  167. }
  168. NotificationsHandler.createNotification(
  169. userId,
  170. key,
  171. 'notification_ip_matched_affiliation',
  172. messageOpts,
  173. null,
  174. false,
  175. callback
  176. )
  177. }
  178. )
  179. },
  180. read(universityId, callback) {
  181. if (callback == null) {
  182. callback = function () {}
  183. }
  184. const key = `ip-matched-affiliation-${universityId}`
  185. NotificationsHandler.markAsReadWithKey(userId, key, callback)
  186. },
  187. }
  188. }
  189. function tpdsFileLimit(userId) {
  190. return {
  191. key: `tpdsFileLimit-${userId}`,
  192. create(projectName, callback) {
  193. if (callback == null) {
  194. callback = function () {}
  195. }
  196. const messageOpts = {
  197. projectName,
  198. }
  199. NotificationsHandler.createNotification(
  200. userId,
  201. this.key,
  202. 'notification_tpds_file_limit',
  203. messageOpts,
  204. null,
  205. true,
  206. callback
  207. )
  208. },
  209. read(callback) {
  210. if (callback == null) {
  211. callback = function () {}
  212. }
  213. NotificationsHandler.markAsReadByKeyOnly(this.key, callback)
  214. },
  215. }
  216. }
  217. const NotificationsBuilder = {
  218. // Note: notification keys should be url-safe
  219. dropboxUnlinkedDueToLapsedReconfirmation,
  220. dropboxDuplicateProjectNames,
  221. featuresUpgradedByAffiliation,
  222. redundantPersonalSubscription,
  223. projectInvite,
  224. ipMatcherAffiliation,
  225. tpdsFileLimit,
  226. }
  227. NotificationsBuilder.promises = {
  228. dropboxUnlinkedDueToLapsedReconfirmation: function (userId) {
  229. return promisifyAll(dropboxUnlinkedDueToLapsedReconfirmation(userId))
  230. },
  231. redundantPersonalSubscription: function (affiliation, user) {
  232. return promisifyAll(redundantPersonalSubscription(affiliation, user))
  233. },
  234. dropboxDuplicateProjectNames(userId) {
  235. return promisifyAll(dropboxDuplicateProjectNames(userId))
  236. },
  237. }
  238. module.exports = NotificationsBuilder