UserRegistrationHandler.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. const { User } = require('../../models/User')
  2. const UserCreator = require('./UserCreator')
  3. const UserGetter = require('./UserGetter')
  4. const AuthenticationManager = require('../Authentication/AuthenticationManager')
  5. const NewsletterManager = require('../Newsletter/NewsletterManager')
  6. const async = require('async')
  7. const logger = require('logger-sharelatex')
  8. const crypto = require('crypto')
  9. const EmailHandler = require('../Email/EmailHandler')
  10. const OneTimeTokenHandler = require('../Security/OneTimeTokenHandler')
  11. const settings = require('@overleaf/settings')
  12. const EmailHelper = require('../Helpers/EmailHelper')
  13. const UserRegistrationHandler = {
  14. _registrationRequestIsValid(body) {
  15. const invalidEmail = AuthenticationManager.validateEmail(body.email || '')
  16. const invalidPassword = AuthenticationManager.validatePassword(
  17. body.password || '',
  18. body.email
  19. )
  20. return !(invalidEmail || invalidPassword)
  21. },
  22. _createNewUserIfRequired(user, userDetails, callback) {
  23. if (!user) {
  24. userDetails.holdingAccount = false
  25. UserCreator.createNewUser(
  26. {
  27. holdingAccount: false,
  28. email: userDetails.email,
  29. first_name: userDetails.first_name,
  30. last_name: userDetails.last_name,
  31. analyticsId: userDetails.analyticsId,
  32. },
  33. {},
  34. callback
  35. )
  36. } else {
  37. callback(null, user)
  38. }
  39. },
  40. registerNewUser(userDetails, callback) {
  41. const self = this
  42. const requestIsValid = this._registrationRequestIsValid(userDetails)
  43. if (!requestIsValid) {
  44. return callback(new Error('request is not valid'))
  45. }
  46. userDetails.email = EmailHelper.parseEmail(userDetails.email)
  47. UserGetter.getUserByAnyEmail(userDetails.email, (error, user) => {
  48. if (error) {
  49. return callback(error)
  50. }
  51. if (user && user.holdingAccount === false) {
  52. return callback(new Error('EmailAlreadyRegistered'), user)
  53. }
  54. self._createNewUserIfRequired(user, userDetails, (error, user) => {
  55. if (error) {
  56. return callback(error)
  57. }
  58. async.series(
  59. [
  60. callback =>
  61. User.updateOne(
  62. { _id: user._id },
  63. { $set: { holdingAccount: false } },
  64. callback
  65. ),
  66. callback =>
  67. AuthenticationManager.setUserPassword(
  68. user,
  69. userDetails.password,
  70. callback
  71. ),
  72. callback => {
  73. if (userDetails.subscribeToNewsletter === 'true') {
  74. NewsletterManager.subscribe(user, error => {
  75. if (error) {
  76. logger.warn(
  77. { err: error, user },
  78. 'Failed to subscribe user to newsletter'
  79. )
  80. }
  81. })
  82. }
  83. callback()
  84. }, // this can be slow, just fire it off
  85. ],
  86. error => {
  87. callback(error, user)
  88. }
  89. )
  90. })
  91. })
  92. },
  93. registerNewUserAndSendActivationEmail(email, callback) {
  94. UserRegistrationHandler.registerNewUser(
  95. {
  96. email,
  97. password: crypto.randomBytes(32).toString('hex'),
  98. },
  99. (error, user) => {
  100. if (error && error.message !== 'EmailAlreadyRegistered') {
  101. return callback(error)
  102. }
  103. if (error && error.message === 'EmailAlreadyRegistered') {
  104. logger.log({ email }, 'user already exists, resending welcome email')
  105. }
  106. const ONE_WEEK = 7 * 24 * 60 * 60 // seconds
  107. OneTimeTokenHandler.getNewToken(
  108. 'password',
  109. { user_id: user._id.toString(), email: user.email },
  110. { expiresIn: ONE_WEEK },
  111. (error, token) => {
  112. if (error) {
  113. return callback(error)
  114. }
  115. const setNewPasswordUrl = `${settings.siteUrl}/user/activate?token=${token}&user_id=${user._id}`
  116. EmailHandler.sendEmail(
  117. 'registered',
  118. {
  119. to: user.email,
  120. setNewPasswordUrl,
  121. },
  122. error => {
  123. if (error) {
  124. logger.warn({ err: error }, 'failed to send activation email')
  125. }
  126. }
  127. )
  128. callback(null, user, setNewPasswordUrl)
  129. }
  130. )
  131. }
  132. )
  133. },
  134. }
  135. module.exports = UserRegistrationHandler