UserRegistrationHandler.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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 Analytics = require('../Analytics/AnalyticsManager')
  12. const settings = require('@overleaf/settings')
  13. const EmailHelper = require('../Helpers/EmailHelper')
  14. const UserRegistrationHandler = {
  15. _registrationRequestIsValid(body) {
  16. const invalidEmail = AuthenticationManager.validateEmail(body.email || '')
  17. const invalidPassword = AuthenticationManager.validatePassword(
  18. body.password || '',
  19. body.email
  20. )
  21. return !(invalidEmail || invalidPassword)
  22. },
  23. _createNewUserIfRequired(user, userDetails, callback) {
  24. if (!user) {
  25. userDetails.holdingAccount = false
  26. UserCreator.createNewUser(
  27. {
  28. holdingAccount: false,
  29. email: userDetails.email,
  30. first_name: userDetails.first_name,
  31. last_name: userDetails.last_name,
  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. Analytics.recordEvent(user._id, 'user-registered')
  88. callback(error, user)
  89. }
  90. )
  91. })
  92. })
  93. },
  94. registerNewUserAndSendActivationEmail(email, callback) {
  95. UserRegistrationHandler.registerNewUser(
  96. {
  97. email,
  98. password: crypto.randomBytes(32).toString('hex'),
  99. },
  100. (error, user) => {
  101. if (error && error.message !== 'EmailAlreadyRegistered') {
  102. return callback(error)
  103. }
  104. if (error && error.message === 'EmailAlreadyRegistered') {
  105. logger.log({ email }, 'user already exists, resending welcome email')
  106. }
  107. const ONE_WEEK = 7 * 24 * 60 * 60 // seconds
  108. OneTimeTokenHandler.getNewToken(
  109. 'password',
  110. { user_id: user._id.toString(), email: user.email },
  111. { expiresIn: ONE_WEEK },
  112. (error, token) => {
  113. if (error) {
  114. return callback(error)
  115. }
  116. const setNewPasswordUrl = `${settings.siteUrl}/user/activate?token=${token}&user_id=${user._id}`
  117. EmailHandler.sendEmail(
  118. 'registered',
  119. {
  120. to: user.email,
  121. setNewPasswordUrl,
  122. },
  123. error => {
  124. if (error) {
  125. logger.warn({ err: error }, 'failed to send activation email')
  126. }
  127. }
  128. )
  129. callback(null, user, setNewPasswordUrl)
  130. }
  131. )
  132. }
  133. )
  134. },
  135. }
  136. module.exports = UserRegistrationHandler