UserUpdater.coffee 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. logger = require("logger-sharelatex")
  2. mongojs = require("../../infrastructure/mongojs")
  3. metrics = require("metrics-sharelatex")
  4. db = mongojs.db
  5. async = require("async")
  6. ObjectId = mongojs.ObjectId
  7. UserGetter = require("./UserGetter")
  8. { addAffiliation, removeAffiliation } = require("./UserAffiliationsManager")
  9. EmailHelper = require "../Helpers/EmailHelper"
  10. Errors = require "../Errors/Errors"
  11. module.exports = UserUpdater =
  12. updateUser: (query, update, callback = (error) ->) ->
  13. if typeof query == "string"
  14. query = _id: ObjectId(query)
  15. else if query instanceof ObjectId
  16. query = _id: query
  17. else if typeof query._id == "string"
  18. query._id = ObjectId(query._id)
  19. db.users.update query, update, callback
  20. #
  21. # DEPRECATED
  22. #
  23. # Change the user's main email address by adding a new email, switching the
  24. # default email and removing the old email. Prefer manipulating multiple
  25. # emails and the default rather than calling this method directly
  26. #
  27. changeEmailAddress: (userId, newEmail, callback)->
  28. newEmail = EmailHelper.parseEmail(newEmail)
  29. return callback(new Error('invalid email')) if !newEmail?
  30. logger.log userId: userId, newEmail: newEmail, "updaing email address of user"
  31. oldEmail = null
  32. async.series [
  33. (cb) ->
  34. UserGetter.getUserEmail userId, (error, email) ->
  35. oldEmail = email
  36. cb(error)
  37. (cb) -> UserUpdater.addEmailAddress userId, newEmail, cb
  38. (cb) -> UserUpdater.setDefaultEmailAddress userId, newEmail, cb
  39. (cb) -> UserUpdater.removeEmailAddress userId, oldEmail, cb
  40. ], callback
  41. # Add a new email address for the user. Email cannot be already used by this
  42. # or any other user
  43. addEmailAddress: (userId, newEmail, affiliationOptions, callback) ->
  44. unless callback? # affiliationOptions is optional
  45. callback = affiliationOptions
  46. affiliationOptions = {}
  47. newEmail = EmailHelper.parseEmail(newEmail)
  48. return callback(new Error('invalid email')) if !newEmail?
  49. UserGetter.ensureUniqueEmailAddress newEmail, (error) =>
  50. return callback(error) if error?
  51. addAffiliation userId, newEmail, affiliationOptions, (error) =>
  52. if error?
  53. logger.err error: error, 'problem adding affiliation while adding email'
  54. return callback(error)
  55. update = $push: emails: email: newEmail, createdAt: new Date()
  56. @updateUser userId, update, (error) ->
  57. if error?
  58. logger.err error: error, 'problem updating users emails'
  59. return callback(error)
  60. callback()
  61. # remove one of the user's email addresses. The email cannot be the user's
  62. # default email address
  63. removeEmailAddress: (userId, email, callback) ->
  64. email = EmailHelper.parseEmail(email)
  65. return callback(new Error('invalid email')) if !email?
  66. removeAffiliation userId, email, (error) =>
  67. if error?
  68. logger.err error: error, 'problem removing affiliation'
  69. return callback(error)
  70. query = _id: userId, email: $ne: email
  71. update = $pull: emails: email: email
  72. @updateUser query, update, (error, res) ->
  73. if error?
  74. logger.err error:error, 'problem removing users email'
  75. return callback(error)
  76. if res.n == 0
  77. return callback(new Error('Cannot remove email'))
  78. callback()
  79. # set the default email address by setting the `email` attribute. The email
  80. # must be one of the user's multiple emails (`emails` attribute)
  81. setDefaultEmailAddress: (userId, email, callback) ->
  82. email = EmailHelper.parseEmail(email)
  83. return callback(new Error('invalid email')) if !email?
  84. query = _id: userId, 'emails.email': email
  85. update = $set: email: email
  86. @updateUser query, update, (error, res) ->
  87. if error?
  88. logger.err error:error, 'problem setting default emails'
  89. return callback(error)
  90. if res.n == 0 # TODO: Check n or nMatched?
  91. return callback(new Error('Default email does not belong to user'))
  92. callback()
  93. confirmEmail: (userId, email, callback) ->
  94. email = EmailHelper.parseEmail(email)
  95. return callback(new Error('invalid email')) if !email?
  96. logger.log {userId, email}, 'confirming user email'
  97. addAffiliation userId, email, (error) =>
  98. if error?
  99. logger.err error: error, 'problem adding affiliation while confirming email'
  100. return callback(error)
  101. query =
  102. _id: userId
  103. 'emails.email': email
  104. update =
  105. $set:
  106. 'emails.$.confirmedAt': new Date()
  107. @updateUser query, update, (error, res) ->
  108. return callback(error) if error?
  109. logger.log {res, userId, email}, "tried to confirm email"
  110. if res.n == 0
  111. return callback(new Errors.NotFoundError('user id and email do no match'))
  112. callback()
  113. [
  114. 'updateUser'
  115. 'changeEmailAddress'
  116. 'setDefaultEmailAddress'
  117. 'addEmailAddress'
  118. 'removeEmailAddress'
  119. ].map (method) ->
  120. metrics.timeAsyncMethod(UserUpdater, method, 'mongo.UserUpdater', logger)