mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #5124 from overleaf/jk-de-ng-set-password-page
[web] de-ng set password form GitOrigin-RevId: d8ebf9f794454d5772e13ab783892d2bba6eed87
This commit is contained in:
parent
9e5dae3443
commit
891947770c
4 changed files with 118 additions and 42 deletions
|
@ -12,7 +12,11 @@ async function setNewUserPassword(req, res, next) {
|
|||
let user
|
||||
let { passwordResetToken, password } = req.body
|
||||
if (!passwordResetToken || !password) {
|
||||
return res.sendStatus(400)
|
||||
return res.status(400).json({
|
||||
message: {
|
||||
key: 'invalid-password',
|
||||
},
|
||||
})
|
||||
}
|
||||
passwordResetToken = passwordResetToken.trim()
|
||||
delete req.session.resetToken
|
||||
|
@ -31,8 +35,18 @@ async function setNewUserPassword(req, res, next) {
|
|||
auditLog
|
||||
)
|
||||
const { found, reset, userId } = result
|
||||
if (!found) return res.sendStatus(404)
|
||||
if (!reset) return res.sendStatus(500)
|
||||
if (!found) {
|
||||
return res.status(404).json({
|
||||
message: {
|
||||
key: 'token-expired',
|
||||
},
|
||||
})
|
||||
}
|
||||
if (!reset) {
|
||||
return res.status(500).json({
|
||||
message: req.i18n.translate('error_performing_request'),
|
||||
})
|
||||
}
|
||||
await UserSessionsManager.promises.revokeAllUserSessions(
|
||||
{ _id: userId },
|
||||
[]
|
||||
|
@ -44,11 +58,21 @@ async function setNewUserPassword(req, res, next) {
|
|||
user = await UserGetter.promises.getUser(userId)
|
||||
} catch (error) {
|
||||
if (error.name === 'NotFoundError') {
|
||||
return res.sendStatus(404)
|
||||
return res.status(404).json({
|
||||
message: {
|
||||
key: 'token-expired',
|
||||
},
|
||||
})
|
||||
} else if (error.name === 'InvalidPasswordError') {
|
||||
return res.sendStatus(400)
|
||||
return res.status(400).json({
|
||||
message: {
|
||||
key: 'invalid-password',
|
||||
},
|
||||
})
|
||||
} else {
|
||||
return res.sendStatus(500)
|
||||
return res.status(500).json({
|
||||
message: req.i18n.translate('error_performing_request'),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
extends ../layout
|
||||
|
||||
block append meta
|
||||
meta(name="ol-passwordStrengthOptions" data-type="json" content=settings.passwordStrengthOptions)
|
||||
extends ../layout-marketing
|
||||
|
||||
block content
|
||||
main.content.content-alt#main-content
|
||||
|
@ -12,52 +9,68 @@ block content
|
|||
.page-header
|
||||
h1 #{translate("reset_your_password")}
|
||||
form(
|
||||
async-form="password-reset",
|
||||
data-ol-async-form,
|
||||
name="passwordResetForm",
|
||||
action="/user/password/set",
|
||||
method="POST",
|
||||
ng-cloak
|
||||
)
|
||||
input(type="hidden", name="_csrf", value=csrfToken)
|
||||
.alert.alert-success(ng-show="passwordResetForm.response.success")
|
||||
div(data-ol-not-sent)
|
||||
div(data-ol-form-messages)
|
||||
|
||||
div.alert.alert-danger(
|
||||
hidden
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
data-ol-custom-form-message='token-expired'
|
||||
)
|
||||
| #{translate('password_reset_token_expired')}
|
||||
br
|
||||
a(href="/user/password/reset")
|
||||
| #{translate('request_new_password_reset_email')}
|
||||
|
||||
div.alert.alert-danger(
|
||||
hidden
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
data-ol-custom-form-message='invalid-password'
|
||||
)
|
||||
| #{translate('invalid_password')}
|
||||
|
||||
div.alert.alert-success(
|
||||
hidden
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
data-ol-sent
|
||||
)
|
||||
| #{translate("password_has_been_reset")}.
|
||||
br
|
||||
a(href='/login') #{translate("login_here")}
|
||||
div(ng-show="passwordResetForm.response.error == true")
|
||||
div(ng-switch="passwordResetForm.response.status")
|
||||
.alert.alert-danger(ng-switch-when="404")
|
||||
| #{translate('password_reset_token_expired')}
|
||||
br
|
||||
a(href="/user/password/reset")
|
||||
| Request a new password reset email
|
||||
.alert.alert-danger(ng-switch-when="400")
|
||||
| #{translate('invalid_password')}
|
||||
.alert.alert-danger(ng-switch-when="429")
|
||||
| #{translate('rate_limit_hit_wait')}
|
||||
.alert.alert-danger(ng-switch-default)
|
||||
| #{translate('error_performing_request')}
|
||||
|
||||
input(type="hidden", name="_csrf", value=csrfToken)
|
||||
|
||||
.form-group
|
||||
input.form-control#passwordField(
|
||||
type='password',
|
||||
name='password',
|
||||
placeholder='new password',
|
||||
required,
|
||||
autocomplete="new-password",
|
||||
ng-model="password",
|
||||
autofocus,
|
||||
complex-password
|
||||
required,
|
||||
minlength=settings.passwordStrengthOptions.length.min,
|
||||
maxlength=settings.passwordStrengthOptions.length.max
|
||||
)
|
||||
span.small.text-primary(ng-show="passwordResetForm.password.$error.complexPassword", ng-bind-html="complexPasswordErrorMessage")
|
||||
input(
|
||||
type="hidden",
|
||||
name="passwordResetToken",
|
||||
value=passwordResetToken
|
||||
ng-non-bindable
|
||||
)
|
||||
.actions
|
||||
button.btn.btn-primary(
|
||||
type='submit',
|
||||
ng-disabled="passwordResetForm.$invalid"
|
||||
) #{translate("set_new_password")}
|
||||
data-ol-disabled-inflight
|
||||
aria-label=translate('set_new_password')
|
||||
)
|
||||
span(data-ol-inflight="idle")
|
||||
| #{translate('set_new_password')}
|
||||
span(hidden data-ol-inflight="pending")
|
||||
| #{translate('set_new_password')}…
|
||||
|
|
|
@ -1113,6 +1113,7 @@
|
|||
"support_lots_of_features": "We support almost all LaTeX features, including inserting images, bibliographies, equations, and much more! Read about all the exciting things you can do with __appName__ in our <0>__help_guides_link__</0>",
|
||||
"latex_guides": "LaTeX guides",
|
||||
"reset_password": "Reset Password",
|
||||
"request_new_password_reset_email": "Request a new password reset email",
|
||||
"set_password": "Set Password",
|
||||
"updating_site": "Updating Site",
|
||||
"bonus_please_recommend_us": "Bonus - Please recommend us",
|
||||
|
|
|
@ -22,7 +22,9 @@ describe('PasswordResetController', function () {
|
|||
password: this.password,
|
||||
},
|
||||
i18n: {
|
||||
translate() {},
|
||||
translate() {
|
||||
return '.'
|
||||
},
|
||||
},
|
||||
session: {},
|
||||
query: {},
|
||||
|
@ -174,8 +176,12 @@ describe('PasswordResetController', function () {
|
|||
reset: false,
|
||||
userId: this.user_id,
|
||||
})
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(404)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
data.message.key.should.equal('token-expired')
|
||||
done()
|
||||
}
|
||||
this.PasswordResetController.setNewUserPassword(this.req, this.res)
|
||||
|
@ -187,8 +193,12 @@ describe('PasswordResetController', function () {
|
|||
reset: false,
|
||||
userId: this.user_id,
|
||||
})
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(500)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
expect(data.message).to.exist
|
||||
done()
|
||||
}
|
||||
this.PasswordResetController.setNewUserPassword(this.req, this.res)
|
||||
|
@ -196,8 +206,12 @@ describe('PasswordResetController', function () {
|
|||
|
||||
it('should return 400 (Bad Request) if there is no password', function (done) {
|
||||
this.req.body.password = ''
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(400)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
data.message.key.should.equal('invalid-password')
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.called.should.equal(
|
||||
false
|
||||
)
|
||||
|
@ -208,8 +222,12 @@ describe('PasswordResetController', function () {
|
|||
|
||||
it('should return 400 (Bad Request) if there is no passwordResetToken', function (done) {
|
||||
this.req.body.passwordResetToken = ''
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(400)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
data.message.key.should.equal('invalid-password')
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.called.should.equal(
|
||||
false
|
||||
)
|
||||
|
@ -223,8 +241,12 @@ describe('PasswordResetController', function () {
|
|||
const err = new Error('bad')
|
||||
err.name = 'InvalidPasswordError'
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.rejects(err)
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(400)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
data.message.key.should.equal('invalid-password')
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.called.should.equal(
|
||||
true
|
||||
)
|
||||
|
@ -265,8 +287,12 @@ describe('PasswordResetController', function () {
|
|||
const anError = new Error('oops')
|
||||
anError.name = 'NotFoundError'
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(404)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
data.message.key.should.equal('token-expired')
|
||||
done()
|
||||
}
|
||||
this.PasswordResetController.setNewUserPassword(this.req, this.res)
|
||||
|
@ -275,8 +301,12 @@ describe('PasswordResetController', function () {
|
|||
const anError = new Error('oops')
|
||||
anError.name = 'InvalidPasswordError'
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
|
||||
this.res.sendStatus = code => {
|
||||
this.res.status = code => {
|
||||
code.should.equal(400)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
data.message.key.should.equal('invalid-password')
|
||||
done()
|
||||
}
|
||||
this.PasswordResetController.setNewUserPassword(this.req, this.res)
|
||||
|
@ -284,6 +314,14 @@ describe('PasswordResetController', function () {
|
|||
it('should return 500 for other errors', function (done) {
|
||||
const anError = new Error('oops')
|
||||
this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
|
||||
this.res.status = code => {
|
||||
code.should.equal(500)
|
||||
return this.res
|
||||
}
|
||||
this.res.json = data => {
|
||||
expect(data.message).to.exist
|
||||
done()
|
||||
}
|
||||
this.res.sendStatus = code => {
|
||||
code.should.equal(500)
|
||||
done()
|
||||
|
|
Loading…
Reference in a new issue