2019-05-29 05:21:06 -04:00
|
|
|
const settings = require('settings-sharelatex')
|
2020-08-13 09:42:28 -04:00
|
|
|
const UserAuditLogHandler = require('../User/UserAuditLogHandler')
|
2019-05-29 05:21:06 -04:00
|
|
|
const UserGetter = require('../User/UserGetter')
|
|
|
|
const OneTimeTokenHandler = require('../Security/OneTimeTokenHandler')
|
|
|
|
const EmailHandler = require('../Email/EmailHandler')
|
|
|
|
const AuthenticationManager = require('../Authentication/AuthenticationManager')
|
2020-08-13 09:42:28 -04:00
|
|
|
const { callbackify, promisify } = require('util')
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-08-13 09:42:28 -04:00
|
|
|
function generateAndEmailResetToken(email, callback) {
|
|
|
|
UserGetter.getUserByAnyEmail(email, (err, user) => {
|
|
|
|
if (err || !user) {
|
|
|
|
return callback(err, null)
|
|
|
|
}
|
|
|
|
if (user.email !== email) {
|
|
|
|
return callback(null, 'secondary')
|
|
|
|
}
|
|
|
|
const data = { user_id: user._id.toString(), email: email }
|
|
|
|
OneTimeTokenHandler.getNewToken('password', data, (err, token) => {
|
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
2019-06-14 12:31:46 -04:00
|
|
|
}
|
2020-08-13 09:42:28 -04:00
|
|
|
const emailOptions = {
|
|
|
|
to: email,
|
|
|
|
setNewPasswordUrl: `${
|
|
|
|
settings.siteUrl
|
|
|
|
}/user/password/set?passwordResetToken=${token}&email=${encodeURIComponent(
|
|
|
|
email
|
2021-04-27 03:52:58 -04:00
|
|
|
)}`,
|
2019-06-14 12:31:46 -04:00
|
|
|
}
|
2020-08-13 09:42:28 -04:00
|
|
|
EmailHandler.sendEmail('passwordResetRequested', emailOptions, err => {
|
2019-06-14 12:31:46 -04:00
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
2020-08-13 09:42:28 -04:00
|
|
|
callback(null, 'primary')
|
2019-06-14 12:31:46 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
2020-08-13 09:42:28 -04:00
|
|
|
})
|
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-08-13 09:42:28 -04:00
|
|
|
function getUserForPasswordResetToken(token, callback) {
|
|
|
|
OneTimeTokenHandler.getValueFromTokenAndExpire(
|
|
|
|
'password',
|
|
|
|
token,
|
|
|
|
(err, data) => {
|
|
|
|
if (err != null) {
|
|
|
|
if (err.name === 'NotFoundError') {
|
|
|
|
return callback(null, null)
|
|
|
|
} else {
|
|
|
|
return callback(err)
|
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
}
|
2020-08-13 09:42:28 -04:00
|
|
|
if (data == null || data.email == null) {
|
|
|
|
return callback(null, null)
|
2019-06-14 12:31:46 -04:00
|
|
|
}
|
2020-08-13 09:42:28 -04:00
|
|
|
UserGetter.getUserByMainEmail(
|
|
|
|
data.email,
|
2020-10-22 04:11:43 -04:00
|
|
|
{ _id: 1, 'overleaf.id': 1, email: 1 },
|
2020-08-13 09:42:28 -04:00
|
|
|
(err, user) => {
|
|
|
|
if (err != null) {
|
|
|
|
callback(err)
|
|
|
|
} else if (user == null) {
|
|
|
|
callback(null, null)
|
|
|
|
} else if (
|
|
|
|
data.user_id != null &&
|
|
|
|
data.user_id === user._id.toString()
|
|
|
|
) {
|
|
|
|
callback(null, user)
|
|
|
|
} else if (
|
|
|
|
data.v1_user_id != null &&
|
|
|
|
user.overleaf != null &&
|
|
|
|
data.v1_user_id === user.overleaf.id
|
|
|
|
) {
|
|
|
|
callback(null, user)
|
|
|
|
} else {
|
|
|
|
callback(null, null)
|
2019-06-14 12:31:46 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2020-08-13 09:42:28 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
2019-07-16 05:10:18 -04:00
|
|
|
|
2020-08-13 09:42:28 -04:00
|
|
|
async function setNewUserPassword(token, password, auditLog) {
|
|
|
|
const user = await PasswordResetHandler.promises.getUserForPasswordResetToken(
|
|
|
|
token
|
|
|
|
)
|
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
return {
|
|
|
|
found: false,
|
|
|
|
reset: false,
|
2021-04-27 03:52:58 -04:00
|
|
|
userId: null,
|
2020-08-13 09:42:28 -04:00
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2020-08-13 09:42:28 -04:00
|
|
|
|
2020-10-22 04:11:43 -04:00
|
|
|
const reset = await AuthenticationManager.promises.setUserPassword(
|
|
|
|
user,
|
|
|
|
password
|
|
|
|
)
|
|
|
|
|
2020-08-13 09:42:28 -04:00
|
|
|
await UserAuditLogHandler.promises.addEntry(
|
|
|
|
user._id,
|
|
|
|
'reset-password',
|
|
|
|
auditLog.initiatorId,
|
|
|
|
auditLog.ip
|
|
|
|
)
|
|
|
|
|
|
|
|
return { found: true, reset, userId: user._id }
|
|
|
|
}
|
|
|
|
|
|
|
|
const PasswordResetHandler = {
|
|
|
|
generateAndEmailResetToken,
|
|
|
|
|
|
|
|
setNewUserPassword: callbackify(setNewUserPassword),
|
|
|
|
|
2021-04-27 03:52:58 -04:00
|
|
|
getUserForPasswordResetToken,
|
2020-08-13 09:42:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
PasswordResetHandler.promises = {
|
|
|
|
getUserForPasswordResetToken: promisify(
|
|
|
|
PasswordResetHandler.getUserForPasswordResetToken
|
|
|
|
),
|
2021-04-27 03:52:58 -04:00
|
|
|
setNewUserPassword,
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
|
|
|
|
module.exports = PasswordResetHandler
|