Files
overleaf-cep/services/web/app/src/Features/PasswordReset/PasswordResetRouter.js
T
June Kelly 3288f87dbe [web] Password set/reset: reject current password (redux) (#8956)
* [web] set-password: reject same as current password

* [web] Add 'peek' operation on tokens

This allows us to improve the UX of the reset-password form,
by not invalidating the token in the case where the new
password will be rejected by validation logic.

We give up to three attempts before invalidating the token.

* [web] Add hide-on-error feature to async forms

This allows us to hide the form elements when certain
named error conditions occur.

* [web] reset-password: handle same-password rejection

We also change the implementation to use the new
peekValueFromToken API, and to expire the token explicitely
after it has been used to set the new password.

* [web] Validate OneTimeToken when loading password reset form

* [web] Rate limit GET: /user/password/set

Now that we are peeking at OneTimeToken when accessing this page,
we add rate to the GET request, matching that of the POST request.

* [web] Tidy up pug layout and mongo query for token peeking

Co-authored-by: Mathias Jakobsen <mathias.jakobsen@overleaf.com>
GitOrigin-RevId: 835205cc7c7ebe1209ee8e5b693efeb939a3056a
2022-09-28 08:06:54 +00:00

73 lines
2.0 KiB
JavaScript

const PasswordResetController = require('./PasswordResetController')
const AuthenticationController = require('../Authentication/AuthenticationController')
const CaptchaMiddleware = require('../../Features/Captcha/CaptchaMiddleware')
const RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
const { Joi, validate } = require('../../infrastructure/Validation')
module.exports = {
apply(webRouter) {
const rateLimit = RateLimiterMiddleware.rateLimit({
endpointName: 'password_reset_rate_limit',
ipOnly: true,
maxRequests: 6,
timeInterval: 60,
})
webRouter.get(
'/user/password/reset',
validate({
query: { error: Joi.string() },
}),
PasswordResetController.renderRequestResetForm
)
webRouter.post(
'/user/password/reset',
validate({
body: Joi.object({
email: Joi.string().required(),
}),
}),
rateLimit,
CaptchaMiddleware.validateCaptcha('passwordReset'),
PasswordResetController.requestReset
)
AuthenticationController.addEndpointToLoginWhitelist('/user/password/reset')
webRouter.get(
'/user/password/set',
validate({
query: {
email: Joi.string().required(),
passwordResetToken: Joi.string(),
},
}),
rateLimit,
PasswordResetController.renderSetPasswordForm
)
webRouter.post(
'/user/password/set',
validate({
body: Joi.object({
password: Joi.string().required(),
passwordResetToken: Joi.string().required(),
}),
}),
rateLimit,
PasswordResetController.setNewUserPassword
)
AuthenticationController.addEndpointToLoginWhitelist('/user/password/set')
webRouter.post(
'/user/reconfirm',
validate({
body: Joi.object({
email: Joi.string().required(),
}),
}),
rateLimit,
CaptchaMiddleware.validateCaptcha('passwordReset'),
PasswordResetController.requestReset
)
},
}