From 3e95aa6bd0d1d0ede8a71587528a970710c02e2e Mon Sep 17 00:00:00 2001 From: Brian Marete Date: Sun, 3 Oct 2021 13:46:31 +0300 Subject: [PATCH] Fix/password reset bug (#811) * fix query for finding user in reset_password route * Add env file to api configuration * Update certs on circleci * Update config.yml * Remove CircleCI * Fix assert statement for token expiry * Notify user if password reset token has expired * Lint fixes Co-authored-by: mrlarso --- .vscode/launch.json | 2 +- .../components/authentication/password-reset.js | 16 ++++++++++++++++ frontend/translations/auth/en-us.yaml | 3 ++- frontend/translations/auth/sw-ke.yaml | 3 ++- server/routes/auth.js | 5 +++-- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 446ef4dc1..95a165e23 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -27,7 +27,7 @@ "request": "launch", "name": "API", "program": "${workspaceFolder}/server/index.js", - "runtimeVersion": "8.15.0", + "runtimeVersion": "14", "envFile": "${workspaceFolder}/.env" }, { diff --git a/frontend/app/components/authentication/password-reset.js b/frontend/app/components/authentication/password-reset.js index f617b81ab..664903a52 100644 --- a/frontend/app/components/authentication/password-reset.js +++ b/frontend/app/components/authentication/password-reset.js @@ -1,12 +1,16 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; import { tracked } from '@glimmer/tracking'; +import { inject as service } from '@ember/service'; import fetch from 'fetch'; export default class PasswordResetComponent extends Component { token = this.args.token; email = this.args.email; + @service notify; + @service intl; + @tracked isInvalid = false; @tracked showPasswordForm = true; @tracked error = { message: '' }; @@ -46,6 +50,18 @@ export default class PasswordResetComponent extends Component { ...this.error, message: 'Something went wrong. Please try again.', }; + if (response.status === 400) { + // intl service not rendering html so we pass the string to html property of notify service + this.notify.info({ + html: this.intl.t( + 'auth.password_reset.password_reset_token_expired', + { htmlSafe: true } + ), + closeAfter: null, + }); + } + + this.loading = false; } else { this.showPasswordForm = false; } diff --git a/frontend/translations/auth/en-us.yaml b/frontend/translations/auth/en-us.yaml index 7d02af63f..77f439e4b 100644 --- a/frontend/translations/auth/en-us.yaml +++ b/frontend/translations/auth/en-us.yaml @@ -31,4 +31,5 @@ password_reset: enter_email_prompt: Enter your email address and we'll send you a link to reset your password. email_sent_p1: We have sent an email to {email}. Click on the password reset link to set your new password. email_sent_p2: If you haven’t received an email please check your spam folder or - try_again: try again \ No newline at end of file + try_again: try again + password_reset_token_expired: This password reset link is expired. Click '<'a href="/forgot_password"'>'here'' to request a new link \ No newline at end of file diff --git a/frontend/translations/auth/sw-ke.yaml b/frontend/translations/auth/sw-ke.yaml index a91ad3855..f06623f6b 100644 --- a/frontend/translations/auth/sw-ke.yaml +++ b/frontend/translations/auth/sw-ke.yaml @@ -31,4 +31,5 @@ password_reset: enter_email_prompt: Ingiza anwani yako ya barua pepe na tutakutumia kiunga cha kuweka tena nenosiri lako. email_sent_p1: Tumetuma barua pepe kwa {email}. Bonyeza kiungo cha kuweka upya nenosiri ili kuweka nenosiri lako mpya. email_sent_p2: Ikiwa haujapokea barua pepe tafadhali angalia folda yako ya barua taka au - try_again: jaribu tena \ No newline at end of file + try_again: jaribu tena + password_reset_token_expired: This password reset link is expired. Click here to request a new link \ No newline at end of file diff --git a/server/routes/auth.js b/server/routes/auth.js index 103dd5a96..c1307be2e 100644 --- a/server/routes/auth.js +++ b/server/routes/auth.js @@ -168,14 +168,15 @@ router.post('/reset_password', checkIfPasswordAreSame, async ctx => { const auth = ctx.request.body.auth; const decodedMail = Buffer.from(auth.email, 'base64').toString('ascii'); - const user = await User.query().where( + const user = await User.query().findOne( { reset_password_token: auth.token, email: decodedMail, } ); + const tokenExpiryTime = Date.parse(user.resetPasswordExpires); ctx.assert(user, 404, 'Account not found'); - ctx.assert(user.resetPasswordExpires > new Date(+new Date() + 0), 400, 'Reset password token has expired'); + ctx.assert(tokenExpiryTime > Date.now(), 400, 'Reset password token has expired'); try { const userData = await user.$query().patchAndFetch({ 'resetPasswordExpires': new Date(), 'hash': auth.hash });