From a64de04fa6682cd825e5be564c3f9ca69c794839 Mon Sep 17 00:00:00 2001 From: M Fahru Date: Mon, 27 Jan 2025 08:47:22 -0700 Subject: [PATCH] Merge pull request #22610 from overleaf/mf-migrate-setpassword-page-bs5 [web] Migrate set password page to bootstrap 5 and website-redesign styling GitOrigin-RevId: a9168b4171739cd49d0b76505800bcd171bd9572 --- .../PasswordReset/PasswordResetController.mjs | 18 +++- .../web/app/views/user/setPassword-bs5.pug | 90 +++++++++++++++++++ services/web/locales/en.json | 1 + 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 services/web/app/views/user/setPassword-bs5.pug diff --git a/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs b/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs index 3817bdf37f..40e3a06e44 100644 --- a/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs +++ b/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs @@ -145,6 +145,12 @@ async function requestReset(req, res, next) { } async function renderSetPasswordForm(req, res, next) { + const { variant } = await SplitTestHandler.promises.getAssignment( + req, + res, + 'auth-pages-bs5' + ) + if (req.query.passwordResetToken != null) { try { const result = @@ -157,6 +163,10 @@ async function renderSetPasswordForm(req, res, next) { return res.redirect('/user/password/reset?error=token_expired') } req.session.resetToken = req.query.passwordResetToken + if (variant === 'enabled') { + req.session.setPasswordBS5 = true + } + let emailQuery = '' if (typeof req.query.email === 'string') { @@ -185,7 +195,13 @@ async function renderSetPasswordForm(req, res, next) { const passwordResetToken = req.session.resetToken delete req.session.resetToken - res.render('user/setPassword', { + const template = req.session.setPasswordBS5 + ? 'user/setPassword-bs5' + : 'user/setPassword' + + delete req.session.setPasswordBS5 + + res.render(template, { title: 'set_password', email, passwordResetToken, diff --git a/services/web/app/views/user/setPassword-bs5.pug b/services/web/app/views/user/setPassword-bs5.pug new file mode 100644 index 0000000000..354f368f2b --- /dev/null +++ b/services/web/app/views/user/setPassword-bs5.pug @@ -0,0 +1,90 @@ +extends ../layout-website-redesign-bootstrap-5 + +block vars + - var suppressNavbar = true + - var suppressFooter = true + +block content + main#main-content + a.auth-aux-logo(href="/") + img(src=buildImgPath("ol-brand/overleaf-o-dark.svg") alt=settings.appName) + .auth-aux-container + form( + data-ol-async-form + name="passwordResetForm" + action="/user/password/set" + method="POST" + data-ol-hide-on-error="token-expired" + ) + div( + hidden + data-ol-sent + ) + h1.h3.mb-3.mt-0 #{translate("password_updated")} + p.mb-4 #{translate("your_password_has_been_successfully_changed")}. + a.btn.btn-primary.w-100(href='/login') #{translate("log_in_now")} + + div(data-ol-not-sent) + h1.h3.mb-3.mt-0 #{translate("reset_your_password")} + p(data-ol-hide-on-error-message="token-expired") #{translate("create_a_new_password_for_your_account")}. + +formMessages() + + +customFormMessage('password-contains-email', 'danger') + | #{translate('invalid_password_contains_email')}. + | #{translate('use_a_different_password')}. + + +customFormMessage('password-too-similar', 'danger') + | #{translate('invalid_password_too_similar')}. + | #{translate('use_a_different_password')}. + + +customFormMessage('token-expired', 'danger') + | #{translate('password_reset_token_expired')} + br + a(href="/user/password/reset") + | #{translate('request_new_password_reset_email')} + + input(type="hidden" name="_csrf" value=csrfToken) + input(type="text" hidden name="email" autocomplete="username" value=email) + + .form-group.mb-3 + label.form-label(for='passwordField', data-ol-hide-on-error-message="token-expired") #{translate("new_password_sentence_case")} + input.form-control#passwordField( + type='password' + name='password' + autocomplete="new-password" + autofocus + required + minlength=settings.passwordStrengthOptions.length.min + ) + + +customValidationMessage('invalid-password') + | #{translate('invalid_password')}. + + +customValidationMessage('password-must-be-different') + | #{translate('password_cant_be_the_same_as_current_one')}. + + +customValidationMessage('password-must-be-strong') + | !{translate('password_was_detected_on_a_public_list_of_known_compromised_passwords', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com/passwords', rel: 'noopener noreferrer', target: '_blank'}}])}. + | #{translate('use_a_different_password')}. + + input( + type="hidden" + name="passwordResetToken" + value=passwordResetToken + ) + div(data-ol-hide-on-error-message="token-expired") + div #{translate('in_order_to_have_a_secure_account_make_sure_your_password')} + ul.mb-3.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_used_on_any_other_website')} + .actions + button.btn.btn-primary.w-100( + type='submit' + 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')}… diff --git a/services/web/locales/en.json b/services/web/locales/en.json index b05644fefc..6918ede1f3 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -1323,6 +1323,7 @@ "new_font_open_dyslexic": "New font: OpenDyslexic Mono is designed to improve readability for those with dyslexia.", "new_name": "New Name", "new_password": "New Password", + "new_password_sentence_case": "New password", "new_project": "New Project", "new_snippet_project": "Untitled", "new_subscription_will_be_billed_immediately": "Your new subscription will be billed immediately to your current payment method.",