From 53b78ad68b16e38d4ccbfc5e319af3ec4cc0a6af Mon Sep 17 00:00:00 2001 From: June Kelly Date: Fri, 10 Feb 2023 10:19:58 +0000 Subject: [PATCH] Merge pull request #11590 from overleaf/jk-password-reset-ux-improvements [web] Password Reset UX Improvements GitOrigin-RevId: d62575ff965e045823bfb7268db892188cf709ed --- .../PasswordReset/PasswordResetController.js | 14 +++++++++++--- .../web/app/src/Features/User/UserController.js | 10 +++++++++- services/web/app/views/user/setPassword.pug | 2 +- services/web/locales/en.json | 12 ++++++------ .../web/test/acceptance/src/PasswordResetTests.js | 2 +- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/services/web/app/src/Features/PasswordReset/PasswordResetController.js b/services/web/app/src/Features/PasswordReset/PasswordResetController.js index f1a02b9209..42f48c9d04 100644 --- a/services/web/app/src/Features/PasswordReset/PasswordResetController.js +++ b/services/web/app/src/Features/PasswordReset/PasswordResetController.js @@ -22,9 +22,17 @@ async function setNewUserPassword(req, res, next) { const err = AuthenticationManager.validatePassword(password, email) if (err) { - return res.status(400).json({ - message: { text: err.message }, - }) + if (err?.info?.code === 'contains_email') { + return res.status(400).json({ + message: { + text: req.i18n.translate('invalid_password_contains_email'), + }, + }) + } else { + return res.status(400).json({ + message: { text: err.message }, + }) + } } passwordResetToken = passwordResetToken.trim() diff --git a/services/web/app/src/Features/User/UserController.js b/services/web/app/src/Features/User/UserController.js index 072163531a..9b0fe11e9f 100644 --- a/services/web/app/src/Features/User/UserController.js +++ b/services/web/app/src/Features/User/UserController.js @@ -96,7 +96,15 @@ async function changePassword(req, res, next) { ) } catch (error) { if (error.name === 'InvalidPasswordError') { - return HttpErrorHandler.badRequest(req, res, error.message) + if (error?.info?.code === 'contains_email') { + return HttpErrorHandler.badRequest( + req, + res, + req.i18n.translate('invalid_password_contains_email') + ) + } else { + return HttpErrorHandler.badRequest(req, res, error.message) + } } else if (error.name === 'PasswordMustBeDifferentError') { return HttpErrorHandler.badRequest( req, diff --git a/services/web/app/views/user/setPassword.pug b/services/web/app/views/user/setPassword.pug index 9ff95fbad2..38f0abf1e3 100644 --- a/services/web/app/views/user/setPassword.pug +++ b/services/web/app/views/user/setPassword.pug @@ -65,7 +65,7 @@ block content ul.mb-4.ps-4 li #{translate('is_longer_than_n_characters', {n: settings.passwordStrengthOptions.length.min})} li #{translate('does_not_contain_or_significantly_match_your_email')} - li !{translate('is_not_a_common_or_obvious_password_as_defined_by_the_have_i_been_pwned_database', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com', rel: 'noopener noreferrer', target: '_blank'}}])} + li #{translate('is_not_used_on_any_other_website')} .actions button.btn.btn-primary.w-100( type='submit', diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 37755f8d2b..72583abc7e 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -344,7 +344,7 @@ "do_you_want_to_overwrite_them": "Do you want to overwrite them?", "document_history": "Document history", "documentation": "Documentation", - "does_not_contain_or_significantly_match_your_email": "Does not contain or significantly match your email", + "does_not_contain_or_significantly_match_your_email": "does not contain or significantly match your email", "doesnt_match": "Doesn’t match", "doing_this_allow_log_in_through_institution": "Doing this will allow you to log in to __appName__ through your institution and will reconfirm your institutional email address.", "doing_this_allow_log_in_through_institution_2": "Doing this will allow you to log in to <0>__appName__ through your institution and will reconfirm your institutional email address.", @@ -709,7 +709,7 @@ "importing": "Importing", "importing_and_merging_changes_in_github": "Importing and merging changes in GitHub", "in_good_company": "You’re In Good Company", - "in_order_to_have_a_secure_account_make_sure_your_password": "In order to have a secure account, make sure your password:", + "in_order_to_have_a_secure_account_make_sure_your_password": "To help keep your account secure, make sure your new password:", "in_order_to_match_institutional_metadata_2": "In order to match your institutional metadata, we’ve linked your account using <0>__email__.", "in_order_to_match_institutional_metadata_associated": "In order to match your institutional metadata, your account is associated with the email __email__.", "increased_compile_timeout": "Increased compile timeout", @@ -739,7 +739,7 @@ "invalid_filename": "Upload failed: check that the file name doesn’t contain special characters, trailing/leading whitespace or more than __nameLimit__ characters", "invalid_institutional_email": "Your institution’s SSO service returned your email address as __email__, which is at an unexpected domain that we do not recognise as belonging to it. You may be able to change your primary email address via your user profile at your institution to one at your institution’s domain. Please contact your IT department if you have any questions.", "invalid_password": "Invalid Password", - "invalid_password_contains_email": "Password can not contain email address", + "invalid_password_contains_email": "Password cannot contain parts of email address", "invalid_password_invalid_character": "Password contains an invalid character", "invalid_password_not_set": "Password is required", "invalid_password_too_long": "Maximum password length __maxLength__ exceeded", @@ -754,8 +754,8 @@ "invited_to_join": "You have been invited to join", "ip_address": "IP Address", "is_email_affiliated": "Is your email affiliated with an institution? ", - "is_longer_than_n_characters": "Is longer than __n__ characters", - "is_not_a_common_or_obvious_password_as_defined_by_the_have_i_been_pwned_database": "Is not a common or obvious password, as defined by the <0>Have I Been Pwned database", + "is_longer_than_n_characters": "is at least __n__ characters long", + "is_not_used_on_any_other_website": "is not used on any other website", "it": "Italian", "ja": "Japanese", "january": "January", @@ -1587,7 +1587,7 @@ "url_to_fetch_the_file_from": "URL to fetch the file from", "usage_metrics": "Usage metrics", "usage_metrics_info": "Metrics that show how many users are accessing the licence, how many projects are being created and worked on, and how much collaboration is happening in Overleaf.", - "use_a_different_password": "Use a different password", + "use_a_different_password": "Please use a different password", "use_your_own_machine": "Use your own machine, with your own setup", "user_already_added": "User already added", "user_deletion_error": "Sorry, something went wrong deleting your account. Please try again in a minute.", diff --git a/services/web/test/acceptance/src/PasswordResetTests.js b/services/web/test/acceptance/src/PasswordResetTests.js index b7405a60df..b0415e65de 100644 --- a/services/web/test/acceptance/src/PasswordResetTests.js +++ b/services/web/test/acceptance/src/PasswordResetTests.js @@ -200,7 +200,7 @@ describe('PasswordReset', function () { expect(response.status).to.equal(400) const body = await response.json() expect(body).to.deep.equal({ - message: { text: 'password contains part of email address' }, + message: { text: 'Password cannot contain parts of email address' }, }) })