2019-05-29 05:21:06 -04:00
|
|
|
const EmailHelper = require('../Helpers/EmailHelper')
|
|
|
|
const EmailHandler = require('../Email/EmailHandler')
|
|
|
|
const OneTimeTokenHandler = require('../Security/OneTimeTokenHandler')
|
|
|
|
const settings = require('settings-sharelatex')
|
|
|
|
const Errors = require('../Errors/Errors')
|
|
|
|
const UserUpdater = require('./UserUpdater')
|
|
|
|
const UserGetter = require('./UserGetter')
|
2020-07-27 10:34:07 -04:00
|
|
|
const { promisify } = require('util')
|
2019-05-29 05:21:06 -04:00
|
|
|
|
|
|
|
const ONE_YEAR_IN_S = 365 * 24 * 60 * 60
|
|
|
|
|
2020-07-27 10:34:07 -04:00
|
|
|
function sendConfirmationEmail(userId, email, emailTemplate, callback) {
|
|
|
|
if (arguments.length === 3) {
|
|
|
|
callback = emailTemplate
|
|
|
|
emailTemplate = 'confirmEmail'
|
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-07-27 10:34:07 -04:00
|
|
|
// when force-migrating accounts to v2 from v1, we don't want to send confirmation messages -
|
|
|
|
// setting this env var allows us to turn this behaviour off
|
|
|
|
if (process.env['SHARELATEX_NO_CONFIRMATION_MESSAGES'] != null) {
|
|
|
|
return callback(null)
|
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-07-27 10:34:07 -04:00
|
|
|
email = EmailHelper.parseEmail(email)
|
|
|
|
if (!email) {
|
|
|
|
return callback(new Error('invalid email'))
|
|
|
|
}
|
|
|
|
const data = { user_id: userId, email }
|
|
|
|
OneTimeTokenHandler.getNewToken(
|
|
|
|
'email_confirmation',
|
|
|
|
data,
|
|
|
|
{ expiresIn: ONE_YEAR_IN_S },
|
|
|
|
function(err, token) {
|
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2020-07-27 10:34:07 -04:00
|
|
|
const emailOptions = {
|
|
|
|
to: email,
|
2020-12-15 05:23:54 -05:00
|
|
|
confirmEmailUrl: `${settings.siteUrl}/user/emails/confirm?token=${token}`,
|
2020-07-27 10:34:07 -04:00
|
|
|
sendingUser_id: userId
|
|
|
|
}
|
|
|
|
EmailHandler.sendEmail(emailTemplate, emailOptions, callback)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const UserEmailsConfirmationHandler = {
|
|
|
|
sendConfirmationEmail,
|
2019-05-29 05:21:06 -04:00
|
|
|
|
|
|
|
confirmEmailFromToken(token, callback) {
|
2019-09-24 04:43:43 -04:00
|
|
|
OneTimeTokenHandler.getValueFromTokenAndExpire(
|
2019-05-29 05:21:06 -04:00
|
|
|
'email_confirmation',
|
|
|
|
token,
|
|
|
|
function(error, data) {
|
2019-09-24 04:43:43 -04:00
|
|
|
if (error) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return callback(error)
|
|
|
|
}
|
2019-09-24 04:43:43 -04:00
|
|
|
if (!data) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return callback(new Errors.NotFoundError('no token found'))
|
|
|
|
}
|
2019-09-24 04:43:43 -04:00
|
|
|
const userId = data.user_id
|
|
|
|
const email = data.email
|
2019-11-19 09:19:08 -05:00
|
|
|
|
2019-09-24 04:43:43 -04:00
|
|
|
if (!userId || email !== EmailHelper.parseEmail(email)) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return callback(new Errors.NotFoundError('invalid data'))
|
|
|
|
}
|
2019-09-24 04:43:43 -04:00
|
|
|
UserGetter.getUser(userId, {}, function(error, user) {
|
|
|
|
if (error) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return callback(error)
|
|
|
|
}
|
2019-09-24 04:43:43 -04:00
|
|
|
if (!user) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return callback(new Errors.NotFoundError('user not found'))
|
|
|
|
}
|
2019-09-25 10:29:40 -04:00
|
|
|
const emailExists = user.emails.some(
|
|
|
|
emailData => emailData.email === email
|
|
|
|
)
|
|
|
|
if (!emailExists) {
|
|
|
|
return callback(new Errors.NotFoundError('email missing for user'))
|
|
|
|
}
|
2019-09-24 04:43:43 -04:00
|
|
|
UserUpdater.confirmEmail(userId, email, callback)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2019-09-24 04:43:43 -04:00
|
|
|
|
2020-07-27 10:34:07 -04:00
|
|
|
UserEmailsConfirmationHandler.promises = {
|
|
|
|
sendConfirmationEmail: promisify(sendConfirmationEmail)
|
|
|
|
}
|
|
|
|
|
2019-09-24 04:43:43 -04:00
|
|
|
module.exports = UserEmailsConfirmationHandler
|