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:
Jakob Ackermann
2021-09-24 08:03:23 +00:00
committed by Copybot
parent 7455393208
commit d3009db5b6
4 changed files with 118 additions and 42 deletions
@@ -12,7 +12,11 @@ async function setNewUserPassword(req, res, next) {
let user let user
let { passwordResetToken, password } = req.body let { passwordResetToken, password } = req.body
if (!passwordResetToken || !password) { if (!passwordResetToken || !password) {
return res.sendStatus(400) return res.status(400).json({
message: {
key: 'invalid-password',
},
})
} }
passwordResetToken = passwordResetToken.trim() passwordResetToken = passwordResetToken.trim()
delete req.session.resetToken delete req.session.resetToken
@@ -31,8 +35,18 @@ async function setNewUserPassword(req, res, next) {
auditLog auditLog
) )
const { found, reset, userId } = result const { found, reset, userId } = result
if (!found) return res.sendStatus(404) if (!found) {
if (!reset) return res.sendStatus(500) 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( await UserSessionsManager.promises.revokeAllUserSessions(
{ _id: userId }, { _id: userId },
[] []
@@ -44,11 +58,21 @@ async function setNewUserPassword(req, res, next) {
user = await UserGetter.promises.getUser(userId) user = await UserGetter.promises.getUser(userId)
} catch (error) { } catch (error) {
if (error.name === 'NotFoundError') { if (error.name === 'NotFoundError') {
return res.sendStatus(404) return res.status(404).json({
message: {
key: 'token-expired',
},
})
} else if (error.name === 'InvalidPasswordError') { } else if (error.name === 'InvalidPasswordError') {
return res.sendStatus(400) return res.status(400).json({
message: {
key: 'invalid-password',
},
})
} else { } else {
return res.sendStatus(500) return res.status(500).json({
message: req.i18n.translate('error_performing_request'),
})
} }
} }
+41 -28
View File
@@ -1,7 +1,4 @@
extends ../layout extends ../layout-marketing
block append meta
meta(name="ol-passwordStrengthOptions" data-type="json" content=settings.passwordStrengthOptions)
block content block content
main.content.content-alt#main-content main.content.content-alt#main-content
@@ -12,52 +9,68 @@ block content
.page-header .page-header
h1 #{translate("reset_your_password")} h1 #{translate("reset_your_password")}
form( form(
async-form="password-reset", data-ol-async-form,
name="passwordResetForm", name="passwordResetForm",
action="/user/password/set", action="/user/password/set",
method="POST", method="POST",
ng-cloak
) )
input(type="hidden", name="_csrf", value=csrfToken) div(data-ol-not-sent)
.alert.alert-success(ng-show="passwordResetForm.response.success") 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")}. | #{translate("password_has_been_reset")}.
br br
a(href='/login') #{translate("login_here")} 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 .form-group
input.form-control#passwordField( input.form-control#passwordField(
type='password', type='password',
name='password', name='password',
placeholder='new password', placeholder='new password',
required,
autocomplete="new-password", autocomplete="new-password",
ng-model="password",
autofocus, 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( input(
type="hidden", type="hidden",
name="passwordResetToken", name="passwordResetToken",
value=passwordResetToken value=passwordResetToken
ng-non-bindable
) )
.actions .actions
button.btn.btn-primary( button.btn.btn-primary(
type='submit', type='submit',
ng-disabled="passwordResetForm.$invalid" data-ol-disabled-inflight
) #{translate("set_new_password")} 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')}…
+1
View File
@@ -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>", "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", "latex_guides": "LaTeX guides",
"reset_password": "Reset Password", "reset_password": "Reset Password",
"request_new_password_reset_email": "Request a new password reset email",
"set_password": "Set Password", "set_password": "Set Password",
"updating_site": "Updating Site", "updating_site": "Updating Site",
"bonus_please_recommend_us": "Bonus - Please recommend us", "bonus_please_recommend_us": "Bonus - Please recommend us",
@@ -22,7 +22,9 @@ describe('PasswordResetController', function () {
password: this.password, password: this.password,
}, },
i18n: { i18n: {
translate() {}, translate() {
return '.'
},
}, },
session: {}, session: {},
query: {}, query: {},
@@ -174,8 +176,12 @@ describe('PasswordResetController', function () {
reset: false, reset: false,
userId: this.user_id, userId: this.user_id,
}) })
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(404) code.should.equal(404)
return this.res
}
this.res.json = data => {
data.message.key.should.equal('token-expired')
done() done()
} }
this.PasswordResetController.setNewUserPassword(this.req, this.res) this.PasswordResetController.setNewUserPassword(this.req, this.res)
@@ -187,8 +193,12 @@ describe('PasswordResetController', function () {
reset: false, reset: false,
userId: this.user_id, userId: this.user_id,
}) })
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(500) code.should.equal(500)
return this.res
}
this.res.json = data => {
expect(data.message).to.exist
done() done()
} }
this.PasswordResetController.setNewUserPassword(this.req, this.res) 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) { it('should return 400 (Bad Request) if there is no password', function (done) {
this.req.body.password = '' this.req.body.password = ''
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(400) 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( this.PasswordResetHandler.promises.setNewUserPassword.called.should.equal(
false false
) )
@@ -208,8 +222,12 @@ describe('PasswordResetController', function () {
it('should return 400 (Bad Request) if there is no passwordResetToken', function (done) { it('should return 400 (Bad Request) if there is no passwordResetToken', function (done) {
this.req.body.passwordResetToken = '' this.req.body.passwordResetToken = ''
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(400) 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( this.PasswordResetHandler.promises.setNewUserPassword.called.should.equal(
false false
) )
@@ -223,8 +241,12 @@ describe('PasswordResetController', function () {
const err = new Error('bad') const err = new Error('bad')
err.name = 'InvalidPasswordError' err.name = 'InvalidPasswordError'
this.PasswordResetHandler.promises.setNewUserPassword.rejects(err) this.PasswordResetHandler.promises.setNewUserPassword.rejects(err)
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(400) 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( this.PasswordResetHandler.promises.setNewUserPassword.called.should.equal(
true true
) )
@@ -265,8 +287,12 @@ describe('PasswordResetController', function () {
const anError = new Error('oops') const anError = new Error('oops')
anError.name = 'NotFoundError' anError.name = 'NotFoundError'
this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError) this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(404) code.should.equal(404)
return this.res
}
this.res.json = data => {
data.message.key.should.equal('token-expired')
done() done()
} }
this.PasswordResetController.setNewUserPassword(this.req, this.res) this.PasswordResetController.setNewUserPassword(this.req, this.res)
@@ -275,8 +301,12 @@ describe('PasswordResetController', function () {
const anError = new Error('oops') const anError = new Error('oops')
anError.name = 'InvalidPasswordError' anError.name = 'InvalidPasswordError'
this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError) this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
this.res.sendStatus = code => { this.res.status = code => {
code.should.equal(400) code.should.equal(400)
return this.res
}
this.res.json = data => {
data.message.key.should.equal('invalid-password')
done() done()
} }
this.PasswordResetController.setNewUserPassword(this.req, this.res) this.PasswordResetController.setNewUserPassword(this.req, this.res)
@@ -284,6 +314,14 @@ describe('PasswordResetController', function () {
it('should return 500 for other errors', function (done) { it('should return 500 for other errors', function (done) {
const anError = new Error('oops') const anError = new Error('oops')
this.PasswordResetHandler.promises.setNewUserPassword.rejects(anError) 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 => { this.res.sendStatus = code => {
code.should.equal(500) code.should.equal(500)
done() done()