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
This commit is contained in:
Rebeka Dekany
2025-07-14 08:05:56 +00:00
committed by Copybot
parent 35f5588be4
commit e35f79bf32
16 changed files with 218 additions and 621 deletions
@@ -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,
})
@@ -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) {
@@ -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 = {
@@ -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
+55 -63
View File
@@ -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
@@ -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' }}])}
@@ -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' }}])}
@@ -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
+50 -51
View File
@@ -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
@@ -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')}…
+73 -77
View File
@@ -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')}…
@@ -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;
}
@@ -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';
+1 -5
View File
@@ -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 youd 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 youve entered is on a <0>public list of compromised passwords</0>. Please try logging in from a device youve previously used or <1>reset your password</1>",
"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.",
@@ -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
})
@@ -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'),
},
},
},
})
})