From e35f79bf32399939c9b95b55a0ca04e7eac978b5 Mon Sep 17 00:00:00 2001 From: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> Date: Fri, 11 Jul 2025 13:49:48 +0200 Subject: [PATCH] Tear down bs5-auth-pages feature flag (#27035) * Remove auth-pages-bs5 test assignment setPassword * Remove auth-pages-bs5 test assignment passwordReset * Remove auth-pages-bs5 test assignment primaryEmailCheck * Remove auth-pages-bs5 test assignment reconfirm * Remove - bootstrap5PageStatus = 'enabled' * Remove primary-email-check.less * Fix spacing * Remove unused translations * Removed unused SplitTestHandler * Update password_reset_sentence_case to password_reset GitOrigin-RevId: d5a5c9a1576f325186aa103c4b7ad8fb819b790a --- .../PasswordReset/PasswordResetController.mjs | 29 +--- .../src/Features/User/UserEmailsController.js | 13 +- .../src/Features/User/UserPagesController.mjs | 11 +- .../web/app/views/user/passwordReset-bs5.pug | 81 ---------- services/web/app/views/user/passwordReset.pug | 118 +++++++------- .../app/views/user/primaryEmailCheck-bs5.pug | 42 ----- .../web/app/views/user/primaryEmailCheck.pug | 71 ++++----- services/web/app/views/user/reconfirm-bs5.pug | 73 --------- services/web/app/views/user/reconfirm.pug | 101 ++++++------ .../web/app/views/user/setPassword-bs5.pug | 87 ---------- services/web/app/views/user/setPassword.pug | 150 +++++++++--------- .../stylesheets/app/primary-email-check.less | 39 ----- .../web/frontend/stylesheets/main-style.less | 1 - services/web/locales/en.json | 6 +- .../PasswordResetController.test.mjs | 12 -- .../src/User/UserEmailsControllerTests.js | 5 - 16 files changed, 218 insertions(+), 621 deletions(-) delete mode 100644 services/web/app/views/user/passwordReset-bs5.pug delete mode 100644 services/web/app/views/user/primaryEmailCheck-bs5.pug delete mode 100644 services/web/app/views/user/reconfirm-bs5.pug delete mode 100644 services/web/app/views/user/setPassword-bs5.pug delete mode 100644 services/web/frontend/stylesheets/app/primary-email-check.less diff --git a/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs b/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs index 771782c302..2963c56653 100644 --- a/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs +++ b/services/web/app/src/Features/PasswordReset/PasswordResetController.mjs @@ -8,7 +8,6 @@ import UserSessionsManager from '../User/UserSessionsManager.js' import OError from '@overleaf/o-error' import EmailsHelper from '../Helpers/EmailHelper.js' import { expressify } from '@overleaf/promise-utils' -import SplitTestHandler from '../SplitTests/SplitTestHandler.js' async function setNewUserPassword(req, res, next) { let user @@ -149,12 +148,6 @@ async function requestReset(req, res, next) { } async function renderSetPasswordForm(req, res, next) { - const { variant } = await SplitTestHandler.promises.getAssignment( - req, - res, - 'bs5-auth-pages' - ) - if (req.query.passwordResetToken != null) { try { const result = @@ -167,10 +160,6 @@ 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') { @@ -199,13 +188,7 @@ async function renderSetPasswordForm(req, res, next) { const passwordResetToken = req.session.resetToken delete req.session.resetToken - const template = req.session.setPasswordBS5 - ? 'user/setPassword-bs5' - : 'user/setPassword' - - delete req.session.setPasswordBS5 - - res.render(template, { + res.render('user/setPassword', { title: 'set_password', email, passwordResetToken, @@ -218,16 +201,8 @@ async function renderRequestResetForm(req, res) { if (errorQuery === 'token_expired') { error = 'password_reset_token_expired' } - const { variant } = await SplitTestHandler.promises.getAssignment( - req, - res, - 'bs5-auth-pages' - ) - const template = - variant === 'enabled' ? 'user/passwordReset-bs5' : 'user/passwordReset' - - res.render(template, { + res.render('user/passwordReset', { title: 'reset_password', error, }) diff --git a/services/web/app/src/Features/User/UserEmailsController.js b/services/web/app/src/Features/User/UserEmailsController.js index 8a7c2bbeb4..e4ad7423af 100644 --- a/services/web/app/src/Features/User/UserEmailsController.js +++ b/services/web/app/src/Features/User/UserEmailsController.js @@ -20,7 +20,6 @@ const { RateLimiter } = require('../../infrastructure/RateLimiter') const Features = require('../../infrastructure/Features') const tsscmp = require('tsscmp') const Modules = require('../../infrastructure/Modules') -const SplitTestHandler = require('../SplitTests/SplitTestHandler') const AUDIT_LOG_TOKEN_PREFIX_LENGTH = 10 @@ -527,18 +526,8 @@ async function primaryEmailCheckPage(req, res) { userId, 'primary-email-check-page-displayed' ) - const { variant } = await SplitTestHandler.promises.getAssignment( - req, - res, - 'bs5-auth-pages' - ) - const template = - variant === 'enabled' - ? 'user/primaryEmailCheck-bs5' - : 'user/primaryEmailCheck' - - res.render(template) + res.render('user/primaryEmailCheck') } async function primaryEmailCheck(req, res) { diff --git a/services/web/app/src/Features/User/UserPagesController.mjs b/services/web/app/src/Features/User/UserPagesController.mjs index d353ca88e3..8b5263c37d 100644 --- a/services/web/app/src/Features/User/UserPagesController.mjs +++ b/services/web/app/src/Features/User/UserPagesController.mjs @@ -10,7 +10,6 @@ import SubscriptionLocator from '../Subscription/SubscriptionLocator.js' import _ from 'lodash' import { expressify } from '@overleaf/promise-utils' import Features from '../../infrastructure/Features.js' -import SplitTestHandler from '../SplitTests/SplitTestHandler.js' import Modules from '../../infrastructure/Modules.js' async function settingsPage(req, res) { @@ -193,16 +192,8 @@ async function reconfirmAccountPage(req, res) { const pageData = { reconfirm_email: req.session.reconfirm_email, } - const { variant } = await SplitTestHandler.promises.getAssignment( - req, - res, - 'bs5-auth-pages' - ) - const template = - variant === 'enabled' ? 'user/reconfirm-bs5' : 'user/reconfirm' - - res.render(template, pageData) + res.render('user/reconfirm', pageData) } const UserPagesController = { diff --git a/services/web/app/views/user/passwordReset-bs5.pug b/services/web/app/views/user/passwordReset-bs5.pug deleted file mode 100644 index f69553b849..0000000000 --- a/services/web/app/views/user/passwordReset-bs5.pug +++ /dev/null @@ -1,81 +0,0 @@ -extends ../layout-website-redesign -include ../_mixins/recaptcha -include ../_mixins/notification - -block vars - - var suppressNavbar = true - - var suppressFooter = true - - isWebsiteRedesign = true - -block content - - var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset) - - if showCaptcha - script( - type='text/javascript' - nonce=scriptNonce - src='https://www.recaptcha.net/recaptcha/api.js?render=explicit' - ) - div( - id='recaptcha' - class='g-recaptcha' - data-sitekey=settings.recaptcha.siteKey - data-size='invisible' - data-badge='inline' - ) - - main#main-content(data-ol-captcha-retry-trigger-area='') - a.auth-aux-logo(href='/') - img(src=buildImgPath('ol-brand/overleaf-o-dark.svg') alt=settings.appName) - .auth-aux-container - form( - name='passwordResetForm' - captcha-action-name=showCaptcha ? 'passwordReset' : false - data-ol-async-form - action='/user/password/reset' - method='POST' - captcha=showCaptcha ? '' : false - ) - if error === 'password_reset_token_expired' - h1.h3.mb-3.mt-0 #{translate("sorry_your_token_expired")} - p #{translate('please_request_a_new_password_reset_email_and_follow_the_link')}. - else - h1.h3.mb-3.mt-0(data-ol-not-sent) #{translate("password_reset_sentence_case")} - h1.h3.mb-3.mt-0(hidden data-ol-sent) #{translate("check_your_email")} - p.mb-3.pb-3(data-ol-not-sent) #{translate("enter_your_email_address_below_and_we_will_send_you_a_link_to_reset_your_password")}. - - div(data-ol-not-sent) - +formMessagesNewStyle - if error && error !== 'password_reset_token_expired' - +notification({ariaLive: 'assertive', type: 'error', className: 'mb-3', content: translate(error)}) - - div(data-ol-custom-form-message='no-password-allowed-due-to-sso' hidden) - +notification({ariaLive: 'polite', type: 'error', className: 'mb-3', content: translate('you_cant_reset_password_due_to_sso', {}, [{name: 'a', attrs: {href: '/sso-login'}}])}) - input(name='_csrf' type='hidden' value=csrfToken) - .form-group.mb-3 - label.form-label(for='email') #{translate("email")} - input#email.form-control( - name='email' - aria-label='email' - type='email' - required - autocomplete='username' - autofocus - ) - .actions - button.btn.btn-primary.w-100.mb-3( - type='submit' - data-ol-disabled-inflight - aria-label=translate('reset_password_sentence_case') - ) - span(data-ol-inflight='idle') - | #{translate("reset_password_sentence_case")} - span(hidden data-ol-inflight='pending') - | #{translate("requesting_password_reset")}… - a.btn.btn-ghost.w-100.mb-3(href='/login') #{translate("back_to_log_in")} - div(hidden data-ol-sent) - p.mb-4 #{translate('password_reset_email_sent')} - a.btn.btn-primary.w-100.mb-3(href='/login') #{translate('back_to_log_in')} - - if showCaptcha - +recaptchaConditions diff --git a/services/web/app/views/user/passwordReset.pug b/services/web/app/views/user/passwordReset.pug index e3396a5cc0..f498baff23 100644 --- a/services/web/app/views/user/passwordReset.pug +++ b/services/web/app/views/user/passwordReset.pug @@ -1,9 +1,11 @@ -extends ../layout-marketing +extends ../layout-website-redesign include ../_mixins/recaptcha -include ../_mixins/material_symbol +include ../_mixins/notification block vars - - bootstrap5PageStatus = 'disabled' + - var suppressNavbar = true + - var suppressFooter = true + - isWebsiteRedesign = true block content - var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset) @@ -22,68 +24,58 @@ block content data-badge='inline' ) - main#main-content.content.content-alt(data-ol-captcha-retry-trigger-area='') - .container-custom-sm.mx-auto - .card - form( - name='passwordResetForm' - captcha-action-name=showCaptcha ? 'passwordReset' : false - data-ol-async-form - action='/user/password/reset' - method='POST' - captcha=showCaptcha ? '' : false - ) - if error === 'password_reset_token_expired' - h3.mt-0.mb-2 #{translate("sorry_your_token_expired")} - p #{translate('please_request_a_new_password_reset_email_and_follow_the_link')}. - else - h3.mt-0.mb-2(data-ol-not-sent) #{translate("password_reset")} - h3.mt-0.mb-2(hidden data-ol-sent) #{translate("check_your_email")} - p(data-ol-not-sent) #{translate("enter_your_email_address_below_and_we_will_send_you_a_link_to_reset_your_password")}. + main#main-content(data-ol-captcha-retry-trigger-area='') + a.auth-aux-logo(href='/') + img(src=buildImgPath('ol-brand/overleaf-o-dark.svg') alt=settings.appName) + .auth-aux-container + form( + name='passwordResetForm' + captcha-action-name=showCaptcha ? 'passwordReset' : false + data-ol-async-form + action='/user/password/reset' + method='POST' + captcha=showCaptcha ? '' : false + ) + if error === 'password_reset_token_expired' + h1.h3.mb-3.mt-0 #{translate("sorry_your_token_expired")} + p #{translate('please_request_a_new_password_reset_email_and_follow_the_link')}. + else + h1.h3.mb-3.mt-0(data-ol-not-sent) #{translate("password_reset")} + h1.h3.mb-3.mt-0(hidden data-ol-sent) #{translate("check_your_email")} + p.mb-3.pb-3(data-ol-not-sent) #{translate("enter_your_email_address_below_and_we_will_send_you_a_link_to_reset_your_password")}. - div(data-ol-not-sent) - +formMessages - if error && error !== 'password_reset_token_expired' - .alert.alert-danger.mb-2(role='alert' aria-live='assertive') - | #{translate(error)} + div(data-ol-not-sent) + +formMessagesNewStyle + if error && error !== 'password_reset_token_expired' + +notification({ariaLive: 'assertive', type: 'error', className: 'mb-3', content: translate(error)}) - div(data-ol-custom-form-message='no-password-allowed-due-to-sso' hidden) - .notification.notification-type-error( - aria-live='polite' - style='margin-bottom: 10px' - ) - .notification-icon - +material-symbol-rounded('error') - .notification-content-and-cta - .notification-content - p - | !{translate("you_cant_reset_password_due_to_sso", {}, [{name: 'a', attrs: {href: '/sso-login'}}])} - - input(name='_csrf' type='hidden' value=csrfToken) - .form-group.mb-3 - label(for='email') #{translate("email")} - input#email.form-control( - name='email' - aria-label='email' - type='email' - placeholder=translate('enter_your_email_address') - required - autocomplete='username' - autofocus - ) - .actions - button.btn.btn-primary.w-100( - type='submit' - data-ol-disabled-inflight - aria-label=translate('request_password_reset_to_reconfirm') - ) - span(data-ol-inflight='idle') - | #{translate("request_password_reset")} - span(hidden data-ol-inflight='pending') - | #{translate("requesting_password_reset")}… - div(hidden data-ol-sent) - p.mb-4 #{translate('password_reset_email_sent')} - a(href='/login') #{translate('back_to_log_in')} + div(data-ol-custom-form-message='no-password-allowed-due-to-sso' hidden) + +notification({ariaLive: 'polite', type: 'error', className: 'mb-3', content: translate('you_cant_reset_password_due_to_sso', {}, [{name: 'a', attrs: {href: '/sso-login'}}])}) + input(name='_csrf' type='hidden' value=csrfToken) + .form-group.mb-3 + label.form-label(for='email') #{translate("email")} + input#email.form-control( + name='email' + aria-label='email' + type='email' + required + autocomplete='username' + autofocus + ) + .actions + button.btn.btn-primary.w-100.mb-3( + type='submit' + data-ol-disabled-inflight + aria-label=translate('reset_password_sentence_case') + ) + span(data-ol-inflight='idle') + | #{translate("reset_password_sentence_case")} + span(hidden data-ol-inflight='pending') + | #{translate("requesting_password_reset")}… + a.btn.btn-ghost.w-100.mb-3(href='/login') #{translate("back_to_log_in")} + div(hidden data-ol-sent) + p.mb-4 #{translate('password_reset_email_sent')} + a.btn.btn-primary.w-100.mb-3(href='/login') #{translate('back_to_log_in')} if showCaptcha +recaptchaConditions diff --git a/services/web/app/views/user/primaryEmailCheck-bs5.pug b/services/web/app/views/user/primaryEmailCheck-bs5.pug deleted file mode 100644 index f45f15d0ca..0000000000 --- a/services/web/app/views/user/primaryEmailCheck-bs5.pug +++ /dev/null @@ -1,42 +0,0 @@ -extends ../layout-website-redesign - -block vars - - bootstrap5PageStatus = 'enabled' - - isWebsiteRedesign = true - -block content - main#main-content - .auth-aux-container - img.w-50.d-block( - src=buildImgPath('ol-brand/overleaf.svg') - alt=settings.appName - ) - h1.h3.mb-3 #{translate("keep_your_account_safe")} - div(data-ol-multi-submit) - p.small.mb-4 - | !{translate("primary_email_check_question", { email: getUserEmail() }, ["strong"])} - form( - data-ol-async-form - action='/user/emails/primary-email-check' - method='POST' - ) - input(name='_csrf' type='hidden' value=csrfToken) - +formMessagesNewStyle - - button.btn.btn-primary.w-100.mb-3(type='submit' data-ol-disabled-inflight) - span(data-ol-inflight='idle') #{translate("yes_that_is_correct")} - span(hidden data-ol-inflight='pending') #{translate("confirming")}… - - a.btn.btn-secondary.w-100.mb-4( - href='/user/settings#add-email' - data-ol-slow-link - event-tracking='primary-email-check-change-email' - event-tracking-mb='true' - event-tracking-trigger='click' - ) - span(data-ol-inflight='idle') #{translate("no_update_email")} - span(hidden data-ol-inflight='pending') #{translate("redirecting")}… - p.small.mb-2 - | #{translate("keep_your_email_updated")} - p.small - | !{translate("learn_more_about_emails", {}, [{name: 'a', attrs: {href: '/learn/how-to/Keeping_your_account_secure', 'event-tracking': 'primary-email-check-learn-more', 'event-tracking-mb': 'true', 'event-tracking-trigger': 'click' }}])} diff --git a/services/web/app/views/user/primaryEmailCheck.pug b/services/web/app/views/user/primaryEmailCheck.pug index 8a0f1e6e94..cd3f0399a0 100644 --- a/services/web/app/views/user/primaryEmailCheck.pug +++ b/services/web/app/views/user/primaryEmailCheck.pug @@ -1,42 +1,41 @@ -extends ../layout-marketing +extends ../layout-website-redesign block vars - - bootstrap5PageStatus = 'disabled' + - isWebsiteRedesign = true block content - main.content.content-alt#main-content - .login-register-container.primary-email-check-container - .card.primary-email-check-card - img.primary-email-check-logo(src=buildImgPath("ol-brand/overleaf.svg") alt=settings.appName) - h3.primary-email-check-header #{translate("keep_your_account_safe")} - .login-register-form.primary-email-check-form(data-ol-multi-submit) - p.small - | !{translate("primary_email_check_question", { email: getUserEmail() }, ["strong"])} - form( - data-ol-async-form - action="/user/emails/primary-email-check" - method="POST" - ) - input(name='_csrf', type='hidden', value=csrfToken) - +formMessages() + main#main-content + .auth-aux-container + img.w-50.d-block( + src=buildImgPath('ol-brand/overleaf.svg') + alt=settings.appName + ) + h1.h3.mb-3 #{translate("keep_your_account_safe")} + div(data-ol-multi-submit) + p.small.mb-4 + | !{translate("primary_email_check_question", { email: getUserEmail() }, ["strong"])} + form( + data-ol-async-form + action='/user/emails/primary-email-check' + method='POST' + ) + input(name='_csrf' type='hidden' value=csrfToken) + +formMessagesNewStyle - button.btn-primary.btn.btn-block.btn-primary-email-check-button.primary-email-confirm-button( - type='submit' - data-ol-disabled-inflight - ) - span(data-ol-inflight="idle") #{translate("yes_that_is_correct")} - span(hidden data-ol-inflight="pending") #{translate("confirming")}… + button.btn.btn-primary.w-100.mb-3(type='submit' data-ol-disabled-inflight) + span(data-ol-inflight='idle') #{translate("yes_that_is_correct")} + span(hidden data-ol-inflight='pending') #{translate("confirming")}… - a.btn-secondary.btn.btn-block.btn-primary-email-check-button.primary-email-change-button( - href="/user/settings#add-email" - data-ol-slow-link - event-tracking="primary-email-check-change-email" - event-tracking-mb="true" - event-tracking-trigger="click" - ) - span(data-ol-inflight="idle") #{translate("no_update_email")} - span(hidden data-ol-inflight="pending") #{translate("redirecting")}… - p.small - | #{translate("keep_your_email_updated")} - p.small - | !{translate("learn_more_about_emails", {}, [{name: 'a', attrs: {href: '/learn/how-to/Keeping_your_account_secure', 'event-tracking': 'primary-email-check-learn-more', 'event-tracking-mb': 'true', 'event-tracking-trigger': 'click' }}])} + a.btn.btn-secondary.w-100.mb-4( + href='/user/settings#add-email' + data-ol-slow-link + event-tracking='primary-email-check-change-email' + event-tracking-mb='true' + event-tracking-trigger='click' + ) + span(data-ol-inflight='idle') #{translate("no_update_email")} + span(hidden data-ol-inflight='pending') #{translate("redirecting")}… + p.small.mb-2 + | #{translate("keep_your_email_updated")} + p.small + | !{translate("learn_more_about_emails", {}, [{name: 'a', attrs: {href: '/learn/how-to/Keeping_your_account_secure', 'event-tracking': 'primary-email-check-learn-more', 'event-tracking-mb': 'true', 'event-tracking-trigger': 'click' }}])} diff --git a/services/web/app/views/user/reconfirm-bs5.pug b/services/web/app/views/user/reconfirm-bs5.pug deleted file mode 100644 index e8e640d10c..0000000000 --- a/services/web/app/views/user/reconfirm-bs5.pug +++ /dev/null @@ -1,73 +0,0 @@ -extends ../layout-website-redesign -include ../_mixins/recaptcha - -block vars - - isWebsiteRedesign = true - -block content - - var email = reconfirm_email ? reconfirm_email : '' - - var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset) - - if showCaptcha - script( - type='text/javascript' - nonce=scriptNonce - src='https://www.recaptcha.net/recaptcha/api.js?render=explicit' - ) - div( - id='recaptcha' - class='g-recaptcha' - data-sitekey=settings.recaptcha.siteKey - data-size='invisible' - data-badge='inline' - ) - - main#main-content(data-ol-captcha-retry-trigger-area='') - .container.auth-aux-container(style='max-width: 420px') - form( - name='reconfirmAccountForm' - captcha-action-name=showCaptcha ? 'passwordReset' : false - data-ol-async-form - action='/user/reconfirm' - method='POST' - aria-label=translate('request_reconfirmation_email') - captcha=showCaptcha ? '' : false - ) - h1.h5.mb-3 #{translate("reconfirm_account")} - p #{translate('reconfirm_explained')} - | - a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail} - | . - - div(data-ol-not-sent) - +formMessagesNewStyle - - input(name='_csrf' type='hidden' value=csrfToken) - .form-group.mb-3 - label.form-label(for='email') #{translate("please_enter_email")} - input.form-control( - name='email' - aria-label='email' - type='email' - placeholder='email@example.com' - required - autofocus - value=email - ) - .actions - button.btn.btn-primary.w-100( - style='white-space: normal' - type='submit' - data-ol-disabled-inflight - aria-label=translate('request_password_reset_to_reconfirm') - ) - span(data-ol-inflight='idle') - | #{translate('request_password_reset_to_reconfirm')} - span(hidden data-ol-inflight='pending') - | #{translate('request_password_reset_to_reconfirm')}… - div(hidden data-ol-sent) - .alert.alert-success(role='alert' aria-live='polite') - span #{translate('password_reset_email_sent')} - - if showCaptcha - +recaptchaConditions diff --git a/services/web/app/views/user/reconfirm.pug b/services/web/app/views/user/reconfirm.pug index 8cfe2ec218..876c28edaf 100644 --- a/services/web/app/views/user/reconfirm.pug +++ b/services/web/app/views/user/reconfirm.pug @@ -1,8 +1,8 @@ -extends ../layout-marketing +extends ../layout-website-redesign include ../_mixins/recaptcha block vars - - bootstrap5PageStatus = 'disabled' + - isWebsiteRedesign = true block content - var email = reconfirm_email ? reconfirm_email : '' @@ -22,53 +22,52 @@ block content data-badge='inline' ) - main#main-content.content.content-alt(data-ol-captcha-retry-trigger-area='') - .container - .row - .col-sm-12.col-md-6.col-md-offset-3 - .card - h1.card-header #{translate("reconfirm_account")} - p #{translate('reconfirm_explained')}  - a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail} - | . - form( - name='reconfirmAccountForm' - captcha-action-name=showCaptcha ? 'passwordReset' : false - data-ol-async-form - action='/user/reconfirm' - method='POST' - aria-label=translate('request_reconfirmation_email') - captcha=showCaptcha ? '' : false - ) - div(data-ol-not-sent) - +formMessages + main#main-content(data-ol-captcha-retry-trigger-area='') + .container.auth-aux-container(style='max-width: 420px') + form( + name='reconfirmAccountForm' + captcha-action-name=showCaptcha ? 'passwordReset' : false + data-ol-async-form + action='/user/reconfirm' + method='POST' + aria-label=translate('request_reconfirmation_email') + captcha=showCaptcha ? '' : false + ) + h1.h5.mb-3 #{translate("reconfirm_account")} + p #{translate('reconfirm_explained')} + |   + a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail} + | . - input(name='_csrf' type='hidden' value=csrfToken) - .form-group - label(for='email') #{translate("please_enter_email")} - input.form-control( - name='email' - aria-label='email' - type='email' - placeholder='email@example.com' - required - autofocus - value=email - ) - .actions - button.btn.btn-primary( - type='submit' - data-ol-disabled-inflight - aria-label=translate('request_password_reset_to_reconfirm') - ) - span(data-ol-inflight='idle') - | #{translate('request_password_reset_to_reconfirm')} - span(hidden data-ol-inflight='pending') - | #{translate('request_password_reset_to_reconfirm')}… - div(hidden data-ol-sent) - .alert.alert-success(role='alert' aria-live='polite') - span #{translate('password_reset_email_sent')} - .row - .col-sm-12.col-md-6.col-md-offset-3 - if showCaptcha - +recaptchaConditions + div(data-ol-not-sent) + +formMessagesNewStyle + + input(name='_csrf' type='hidden' value=csrfToken) + .form-group.mb-3 + label.form-label(for='email') #{translate("please_enter_email")} + input.form-control( + name='email' + aria-label='email' + type='email' + placeholder='email@example.com' + required + autofocus + value=email + ) + .actions + button.btn.btn-primary.w-100( + style='white-space: normal' + type='submit' + data-ol-disabled-inflight + aria-label=translate('request_password_reset_to_reconfirm') + ) + span(data-ol-inflight='idle') + | #{translate('request_password_reset_to_reconfirm')} + span(hidden data-ol-inflight='pending') + | #{translate('request_password_reset_to_reconfirm')}… + div(hidden data-ol-sent) + .alert.alert-success(role='alert' aria-live='polite') + span #{translate('password_reset_email_sent')} + + if showCaptcha + +recaptchaConditions diff --git a/services/web/app/views/user/setPassword-bs5.pug b/services/web/app/views/user/setPassword-bs5.pug deleted file mode 100644 index 5081d22409..0000000000 --- a/services/web/app/views/user/setPassword-bs5.pug +++ /dev/null @@ -1,87 +0,0 @@ -extends ../layout-website-redesign - -block vars - - var suppressNavbar = true - - var suppressFooter = true - - isWebsiteRedesign = 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( - name='passwordResetForm' - data-ol-async-form - 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")}. - +formMessagesNewStyle - - +customFormMessageNewStyle('password-contains-email', 'danger') - | #{translate('invalid_password_contains_email')}. - | #{translate('use_a_different_password')}. - - +customFormMessageNewStyle('password-too-similar', 'danger') - | #{translate('invalid_password_too_similar')}. - | #{translate('use_a_different_password')}. - - +customFormMessageNewStyle('token-expired', 'danger') - | #{translate('password_reset_token_expired')} - br - a(href='/user/password/reset') - | #{translate('request_new_password_reset_email')} - - input(name='_csrf' type='hidden' value=csrfToken) - input(name='email' type='text' hidden autocomplete='username' value=email) - - .form-group.mb-3 - label.form-label( - for='passwordField' - data-ol-hide-on-error-message='token-expired' - ) #{translate("new_password")} - input#passwordField.form-control.auth-aux-new-password( - name='password' - type='password' - autocomplete='new-password' - autofocus - required - minlength=settings.passwordStrengthOptions.length.min - ) - - +customValidationMessageNewStyle('invalid-password') - | #{translate('invalid_password')}. - - +customValidationMessageNewStyle('password-must-be-different') - | #{translate('password_cant_be_the_same_as_current_one')}. - - +customValidationMessageNewStyle('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(name='passwordResetToken' type='hidden' 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/app/views/user/setPassword.pug b/services/web/app/views/user/setPassword.pug index 653bc52045..5081d22409 100644 --- a/services/web/app/views/user/setPassword.pug +++ b/services/web/app/views/user/setPassword.pug @@ -1,91 +1,87 @@ -extends ../layout-marketing +extends ../layout-website-redesign block vars - - bootstrap5PageStatus = 'disabled' + - var suppressNavbar = true + - var suppressFooter = true + - isWebsiteRedesign = true block content - main#main-content.content.content-alt - .container-custom-sm.mx-auto - .card - form( - name='passwordResetForm' - data-ol-async-form - action='/user/password/set' - method='POST' - data-ol-hide-on-error='token-expired' - ) - div(hidden data-ol-sent) - h3.mt-0.mb-2 #{translate("password_updated")} - p.mb-4 #{translate("your_password_has_been_successfully_changed")}. - a(href='/login') #{translate("log_in_now")} + main#main-content + a.auth-aux-logo(href='/') + img(src=buildImgPath('ol-brand/overleaf-o-dark.svg') alt=settings.appName) + .auth-aux-container + form( + name='passwordResetForm' + data-ol-async-form + 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) - h3.mt-0.mb-2 #{translate("reset_your_password")} - p(data-ol-hide-on-error-message='token-expired') #{translate("create_a_new_password_for_your_account")}. - +formMessages + 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")}. + +formMessagesNewStyle - +customFormMessage('password-contains-email', 'danger') - | #{translate('invalid_password_contains_email')}. - | #{translate('use_a_different_password')}. + +customFormMessageNewStyle('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')}. + +customFormMessageNewStyle('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')} + +customFormMessageNewStyle('token-expired', 'danger') + | #{translate('password_reset_token_expired')} + br + a(href='/user/password/reset') + | #{translate('request_new_password_reset_email')} - input(name='_csrf' type='hidden' value=csrfToken) - input( - name='email' - type='text' - hidden - autocomplete='username' - value=email + input(name='_csrf' type='hidden' value=csrfToken) + input(name='email' type='text' hidden autocomplete='username' value=email) + + .form-group.mb-3 + label.form-label( + for='passwordField' + data-ol-hide-on-error-message='token-expired' + ) #{translate("new_password")} + input#passwordField.form-control.auth-aux-new-password( + name='password' + type='password' + autocomplete='new-password' + autofocus + required + minlength=settings.passwordStrengthOptions.length.min ) - .form-group - label( - for='passwordField' - data-ol-hide-on-error-message='token-expired' - ) #{translate("new_password")} - input#passwordField.form-control( - name='password' - type='password' - placeholder=translate('enter_your_new_password') - autocomplete='new-password' - autofocus - required - minlength=settings.passwordStrengthOptions.length.min - ) + +customValidationMessageNewStyle('invalid-password') + | #{translate('invalid_password')}. - +customValidationMessage('invalid-password') - | #{translate('invalid_password')}. + +customValidationMessageNewStyle('password-must-be-different') + | #{translate('password_cant_be_the_same_as_current_one')}. - +customValidationMessage('password-must-be-different') - | #{translate('password_cant_be_the_same_as_current_one')}. + +customValidationMessageNewStyle('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')}. - +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(name='passwordResetToken' type='hidden' 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-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_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')}… + input(name='passwordResetToken' type='hidden' 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/frontend/stylesheets/app/primary-email-check.less b/services/web/frontend/stylesheets/app/primary-email-check.less deleted file mode 100644 index 2a1a766fd4..0000000000 --- a/services/web/frontend/stylesheets/app/primary-email-check.less +++ /dev/null @@ -1,39 +0,0 @@ -.primary-email-check-container { - max-width: 400px !important; -} - -.primary-email-check-card { - padding: 24px; - display: flex; - flex-direction: column; - gap: 12px; - - .primary-email-confirm-button { - margin-top: 12px; - } - - .primary-email-change-button { - margin-bottom: 12px; - } - - p { - margin-bottom: 0; - } -} - -.primary-email-check-header { - margin-top: 12px; - margin-bottom: 0; -} - -.primary-email-check-form { - padding: 0 !important; - display: flex; - flex-direction: column; - gap: 12px; -} - -.primary-email-check-logo { - width: 130px; - margin: 0 auto; -} diff --git a/services/web/frontend/stylesheets/main-style.less b/services/web/frontend/stylesheets/main-style.less index ac72ff6d0a..1898c6be66 100644 --- a/services/web/frontend/stylesheets/main-style.less +++ b/services/web/frontend/stylesheets/main-style.less @@ -116,7 +116,6 @@ @import 'app/error-pages.less'; @import 'app/editor/history-v2.less'; @import 'app/open-in-overleaf.less'; -@import 'app/primary-email-check'; @import 'app/grammarly'; @import 'app/front-chat-widget.less'; @import 'app/ol-chat.less'; diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 35c7787e1e..7fbe27fc3c 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -688,9 +688,7 @@ "enter_the_code": "Enter the 6-digit code sent to __email__.", "enter_the_confirmation_code": "Enter the 6-digit confirmation code sent to __email__.", "enter_the_number_of_licenses_youd_like_to_add_to_see_the_cost_breakdown": "Enter the number of licenses you’d like to add to see the cost breakdown.", - "enter_your_email_address": "Enter your email address", "enter_your_email_address_below_and_we_will_send_you_a_link_to_reset_your_password": "Enter your email address below, and we will send you a link to reset your password", - "enter_your_new_password": "Enter your new password", "equation_generator": "Equation Generator", "equation_preview": "Equation preview", "error": "Error", @@ -1584,9 +1582,8 @@ "password_change_successful": "Password changed", "password_compromised_try_again_or_use_known_device_or_reset": "The password you’ve entered is on a <0>public list of compromised passwords. Please try logging in from a device you’ve previously used or <1>reset your password", "password_managed_externally": "Password settings are managed externally", - "password_reset": "Password Reset", + "password_reset": "Password reset", "password_reset_email_sent": "You have been sent an email to complete your password reset.", - "password_reset_sentence_case": "Password reset", "password_reset_token_expired": "Your password reset token has expired. Please request a new password reset email and follow the link there.", "password_too_long_please_reset": "Maximum password length exceeded. Please reset your password.", "password_updated": "Password updated", @@ -1860,7 +1857,6 @@ "republish": "Republish", "request_new_password_reset_email": "Request a new password reset email", "request_overleaf_common": "Request Overleaf Commons", - "request_password_reset": "Request password reset", "request_password_reset_to_reconfirm": "Request password reset email to reconfirm", "request_reconfirmation_email": "Request reconfirmation email", "request_sent_thank_you": "Message sent! Our team will review it and reply by email.", diff --git a/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs b/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs index 70439baa33..d225c7ff81 100644 --- a/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs +++ b/services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs @@ -59,11 +59,6 @@ describe('PasswordResetController', function () { removeReconfirmFlag: sinon.stub().resolves(), }, } - ctx.SplitTestHandler = { - promises: { - getAssignment: sinon.stub().resolves('default'), - }, - } vi.doMock('@overleaf/settings', () => ({ default: ctx.settings, @@ -112,13 +107,6 @@ describe('PasswordResetController', function () { default: ctx.UserUpdater, })) - vi.doMock( - '../../../../app/src/Features/SplitTests/SplitTestHandler', - () => ({ - default: ctx.SplitTestHandler, - }) - ) - ctx.PasswordResetController = (await import(MODULE_PATH)).default }) diff --git a/services/web/test/unit/src/User/UserEmailsControllerTests.js b/services/web/test/unit/src/User/UserEmailsControllerTests.js index ae94194084..b89df8821a 100644 --- a/services/web/test/unit/src/User/UserEmailsControllerTests.js +++ b/services/web/test/unit/src/User/UserEmailsControllerTests.js @@ -101,11 +101,6 @@ describe('UserEmailsController', function () { '../Analytics/AnalyticsManager': this.AnalyticsManager, './UserAuditLogHandler': this.UserAuditLogHandler, '../../infrastructure/RateLimiter': this.RateLimiter, - '../SplitTests/SplitTestHandler': { - promises: { - getAssignment: sinon.stub().resolves('default'), - }, - }, }, }) })