UserRegistrationHandler.js 4.6 KB

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