2019-05-29 05:21:06 -04:00
|
|
|
const settings = require('settings-sharelatex')
|
|
|
|
const UserGetter = require('../User/UserGetter')
|
|
|
|
const OneTimeTokenHandler = require('../Security/OneTimeTokenHandler')
|
|
|
|
const EmailHandler = require('../Email/EmailHandler')
|
|
|
|
const AuthenticationManager = require('../Authentication/AuthenticationManager')
|
|
|
|
const logger = require('logger-sharelatex')
|
|
|
|
const V1Api = require('../V1/V1Api')
|
|
|
|
|
2019-07-04 08:40:12 -04:00
|
|
|
const PasswordResetHandler = {
|
2019-05-29 05:21:06 -04:00
|
|
|
generateAndEmailResetToken(email, callback) {
|
2019-07-04 08:40:12 -04:00
|
|
|
PasswordResetHandler._getPasswordResetData(email, function(
|
2019-05-29 05:21:06 -04:00
|
|
|
error,
|
|
|
|
exists,
|
|
|
|
data
|
|
|
|
) {
|
|
|
|
if (error != null) {
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(error)
|
2019-05-29 05:21:06 -04:00
|
|
|
} else if (exists) {
|
2019-07-04 08:40:12 -04:00
|
|
|
OneTimeTokenHandler.getNewToken('password', data, function(err, token) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
|
|
|
const emailOptions = {
|
|
|
|
to: email,
|
|
|
|
setNewPasswordUrl: `${
|
|
|
|
settings.siteUrl
|
|
|
|
}/user/password/set?passwordResetToken=${token}&email=${encodeURIComponent(
|
|
|
|
email
|
|
|
|
)}`
|
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
EmailHandler.sendEmail(
|
2019-05-29 05:21:06 -04:00
|
|
|
'passwordResetRequested',
|
|
|
|
emailOptions,
|
|
|
|
function(error) {
|
|
|
|
if (error != null) {
|
|
|
|
return callback(error)
|
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(null, 'primary')
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
} else {
|
2019-07-04 08:40:12 -04:00
|
|
|
UserGetter.getUserByAnyEmail(email, function(err, user) {
|
|
|
|
if (err != null) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
if (!user) {
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(null, null)
|
|
|
|
} else if (user.overleaf == null || user.overleaf.id == null) {
|
|
|
|
callback(null, 'sharelatex')
|
2019-05-29 05:21:06 -04:00
|
|
|
} else {
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(null, 'secondary')
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
setNewUserPassword(token, password, callback) {
|
2019-07-16 05:10:18 -04:00
|
|
|
PasswordResetHandler.getUserForPasswordResetToken(
|
|
|
|
token,
|
|
|
|
(err, user, version) => {
|
|
|
|
if (err != null) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
|
|
|
if (user == null) {
|
|
|
|
return callback(null, false, null)
|
|
|
|
}
|
|
|
|
AuthenticationManager.setUserPassword(
|
|
|
|
user._id,
|
|
|
|
password,
|
|
|
|
(err, reset) => {
|
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
|
|
|
callback(null, reset, user._id)
|
|
|
|
}
|
|
|
|
)
|
2019-07-04 08:40:12 -04:00
|
|
|
}
|
2019-07-16 05:10:18 -04:00
|
|
|
)
|
|
|
|
},
|
|
|
|
|
|
|
|
getUserForPasswordResetToken(token, callback) {
|
|
|
|
OneTimeTokenHandler.getValueFromTokenAndExpire(
|
|
|
|
'password',
|
|
|
|
token,
|
|
|
|
(err, data) => {
|
|
|
|
if (err != null) {
|
|
|
|
if (err.name === 'NotFoundError') {
|
|
|
|
return callback(null, null)
|
|
|
|
} else {
|
2019-07-04 08:40:12 -04:00
|
|
|
return callback(err)
|
|
|
|
}
|
2019-07-16 05:10:18 -04:00
|
|
|
}
|
|
|
|
if (data == null || data.email == null) {
|
|
|
|
return callback(null, null)
|
|
|
|
}
|
|
|
|
UserGetter.getUserByMainEmail(
|
|
|
|
data.email,
|
|
|
|
{ _id: 1, 'overleaf.id': 1 },
|
|
|
|
(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, 'v2')
|
|
|
|
} else if (
|
|
|
|
data.v1_user_id != null &&
|
|
|
|
user.overleaf != null &&
|
|
|
|
data.v1_user_id === user.overleaf.id
|
|
|
|
) {
|
|
|
|
callback(null, user, 'v1')
|
|
|
|
} else {
|
|
|
|
callback(null, null)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
}
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-07-16 05:10:18 -04:00
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_getPasswordResetData(email, callback) {
|
|
|
|
if (settings.overleaf != null) {
|
|
|
|
// Overleaf v2
|
2019-07-04 08:40:12 -04:00
|
|
|
V1Api.request(
|
2019-05-29 05:21:06 -04:00
|
|
|
{
|
|
|
|
url: '/api/v1/sharelatex/user_emails',
|
|
|
|
qs: {
|
|
|
|
email
|
|
|
|
},
|
|
|
|
expectedStatusCodes: [404]
|
|
|
|
},
|
|
|
|
function(error, response, body) {
|
|
|
|
if (error != null) {
|
|
|
|
return callback(error)
|
|
|
|
}
|
|
|
|
if (response.statusCode === 404) {
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(null, false)
|
2019-05-29 05:21:06 -04:00
|
|
|
} else {
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(null, true, { v1_user_id: body.user_id, email: email })
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
// ShareLaTeX
|
2019-07-04 08:40:12 -04:00
|
|
|
UserGetter.getUserByMainEmail(email, function(err, user) {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
|
|
|
if (user == null || user.holdingAccount || user.overleaf != null) {
|
|
|
|
logger.err({ email }, 'user could not be found for password reset')
|
|
|
|
return callback(null, false)
|
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
callback(null, true, { user_id: user._id, email: email })
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-04 08:40:12 -04:00
|
|
|
|
|
|
|
module.exports = PasswordResetHandler
|