2019-05-29 05:21:06 -04:00
|
|
|
const { User } = require('../../models/User')
|
|
|
|
const UserCreator = require('./UserCreator')
|
|
|
|
const UserGetter = require('./UserGetter')
|
|
|
|
const AuthenticationManager = require('../Authentication/AuthenticationManager')
|
2019-08-28 08:59:41 -04:00
|
|
|
const NewsletterManager = require('../Newsletter/NewsletterManager')
|
2019-05-29 05:21:06 -04:00
|
|
|
const async = require('async')
|
|
|
|
const logger = require('logger-sharelatex')
|
|
|
|
const crypto = require('crypto')
|
|
|
|
const EmailHandler = require('../Email/EmailHandler')
|
|
|
|
const OneTimeTokenHandler = require('../Security/OneTimeTokenHandler')
|
|
|
|
const Analytics = require('../Analytics/AnalyticsManager')
|
2021-07-07 05:38:56 -04:00
|
|
|
const settings = require('@overleaf/settings')
|
2019-05-29 05:21:06 -04:00
|
|
|
const EmailHelper = require('../Helpers/EmailHelper')
|
|
|
|
|
2019-08-28 08:59:41 -04:00
|
|
|
const UserRegistrationHandler = {
|
2021-03-31 05:24:39 -04:00
|
|
|
_registrationRequestIsValid(body) {
|
2019-05-29 05:21:06 -04:00
|
|
|
const invalidEmail = AuthenticationManager.validateEmail(body.email || '')
|
|
|
|
const invalidPassword = AuthenticationManager.validatePassword(
|
2020-10-22 04:11:43 -04:00
|
|
|
body.password || '',
|
|
|
|
body.email
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
2021-03-31 05:24:39 -04:00
|
|
|
return !(invalidEmail || invalidPassword)
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_createNewUserIfRequired(user, userDetails, callback) {
|
2021-03-31 05:24:39 -04:00
|
|
|
if (!user) {
|
2019-05-29 05:21:06 -04:00
|
|
|
userDetails.holdingAccount = false
|
2019-08-28 08:59:41 -04:00
|
|
|
UserCreator.createNewUser(
|
2019-05-29 05:21:06 -04:00
|
|
|
{
|
|
|
|
holdingAccount: false,
|
|
|
|
email: userDetails.email,
|
|
|
|
first_name: userDetails.first_name,
|
2021-04-27 03:52:58 -04:00
|
|
|
last_name: userDetails.last_name,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2020-09-01 08:37:09 -04:00
|
|
|
{},
|
2019-05-29 05:21:06 -04:00
|
|
|
callback
|
|
|
|
)
|
|
|
|
} else {
|
2019-08-28 08:59:41 -04:00
|
|
|
callback(null, user)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
registerNewUser(userDetails, callback) {
|
|
|
|
const self = this
|
|
|
|
const requestIsValid = this._registrationRequestIsValid(userDetails)
|
|
|
|
if (!requestIsValid) {
|
|
|
|
return callback(new Error('request is not valid'))
|
|
|
|
}
|
|
|
|
userDetails.email = EmailHelper.parseEmail(userDetails.email)
|
2021-03-31 05:24:39 -04:00
|
|
|
UserGetter.getUserByAnyEmail(userDetails.email, (error, user) => {
|
|
|
|
if (error) {
|
|
|
|
return callback(error)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2021-03-31 05:24:39 -04:00
|
|
|
if (user && user.holdingAccount === false) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return callback(new Error('EmailAlreadyRegistered'), user)
|
|
|
|
}
|
2021-03-31 05:24:39 -04:00
|
|
|
self._createNewUserIfRequired(user, userDetails, (error, user) => {
|
|
|
|
if (error) {
|
|
|
|
return callback(error)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-08-28 08:59:41 -04:00
|
|
|
async.series(
|
2019-05-29 05:21:06 -04:00
|
|
|
[
|
2021-03-31 05:24:39 -04:00
|
|
|
callback =>
|
2020-11-03 04:19:05 -05:00
|
|
|
User.updateOne(
|
2019-05-29 05:21:06 -04:00
|
|
|
{ _id: user._id },
|
|
|
|
{ $set: { holdingAccount: false } },
|
2021-03-31 05:24:39 -04:00
|
|
|
callback
|
2019-05-29 05:21:06 -04:00
|
|
|
),
|
2021-03-31 05:24:39 -04:00
|
|
|
callback =>
|
2019-05-29 05:21:06 -04:00
|
|
|
AuthenticationManager.setUserPassword(
|
2020-10-22 04:11:43 -04:00
|
|
|
user,
|
2019-05-29 05:21:06 -04:00
|
|
|
userDetails.password,
|
2021-03-31 05:24:39 -04:00
|
|
|
callback
|
2019-05-29 05:21:06 -04:00
|
|
|
),
|
2021-03-31 05:24:39 -04:00
|
|
|
callback => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (userDetails.subscribeToNewsletter === 'true') {
|
2021-03-31 05:24:39 -04:00
|
|
|
NewsletterManager.subscribe(user, error => {
|
|
|
|
if (error) {
|
2019-08-28 08:59:41 -04:00
|
|
|
logger.warn(
|
2021-03-31 05:24:39 -04:00
|
|
|
{ err: error, user },
|
2019-08-28 08:59:41 -04:00
|
|
|
'Failed to subscribe user to newsletter'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2021-03-31 05:24:39 -04:00
|
|
|
callback()
|
2021-04-27 03:52:58 -04:00
|
|
|
}, // this can be slow, just fire it off
|
2019-05-29 05:21:06 -04:00
|
|
|
],
|
2021-03-31 05:24:39 -04:00
|
|
|
error => {
|
2019-05-29 05:21:06 -04:00
|
|
|
Analytics.recordEvent(user._id, 'user-registered')
|
2021-03-31 05:24:39 -04:00
|
|
|
callback(error, user)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
registerNewUserAndSendActivationEmail(email, callback) {
|
2019-08-28 08:59:41 -04:00
|
|
|
UserRegistrationHandler.registerNewUser(
|
2019-05-29 05:21:06 -04:00
|
|
|
{
|
|
|
|
email,
|
2021-04-27 03:52:58 -04:00
|
|
|
password: crypto.randomBytes(32).toString('hex'),
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2021-03-31 05:24:39 -04:00
|
|
|
(error, user) => {
|
|
|
|
if (error && error.message !== 'EmailAlreadyRegistered') {
|
|
|
|
return callback(error)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
|
2021-03-31 05:24:39 -04:00
|
|
|
if (error && error.message === 'EmailAlreadyRegistered') {
|
2019-05-29 05:21:06 -04:00
|
|
|
logger.log({ email }, 'user already exists, resending welcome email')
|
|
|
|
}
|
|
|
|
|
|
|
|
const ONE_WEEK = 7 * 24 * 60 * 60 // seconds
|
2019-08-28 08:59:41 -04:00
|
|
|
OneTimeTokenHandler.getNewToken(
|
2019-05-29 05:21:06 -04:00
|
|
|
'password',
|
2021-01-27 05:10:53 -05:00
|
|
|
{ user_id: user._id.toString(), email: user.email },
|
2019-05-29 05:21:06 -04:00
|
|
|
{ expiresIn: ONE_WEEK },
|
2021-03-31 05:24:39 -04:00
|
|
|
(error, token) => {
|
|
|
|
if (error) {
|
|
|
|
return callback(error)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
|
2020-12-15 05:23:54 -05:00
|
|
|
const setNewPasswordUrl = `${settings.siteUrl}/user/activate?token=${token}&user_id=${user._id}`
|
2019-05-29 05:21:06 -04:00
|
|
|
|
|
|
|
EmailHandler.sendEmail(
|
|
|
|
'registered',
|
|
|
|
{
|
|
|
|
to: user.email,
|
2021-04-27 03:52:58 -04:00
|
|
|
setNewPasswordUrl,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2021-03-31 05:24:39 -04:00
|
|
|
error => {
|
|
|
|
if (error) {
|
|
|
|
logger.warn({ err: error }, 'failed to send activation email')
|
2019-10-15 09:12:11 -04:00
|
|
|
}
|
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
|
|
|
|
2019-08-28 08:59:41 -04:00
|
|
|
callback(null, user, setNewPasswordUrl)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-08-28 08:59:41 -04:00
|
|
|
|
|
|
|
module.exports = UserRegistrationHandler
|