* Replace token-link email with 6-digit code on SSO registration
Unverified SSO emails previously received a long-lived token link
(90-day TTL) via UserEmailsConfirmationHandler. This replaces that
flow with the same 6-digit code verification used for password
registration, redirecting through /registration/confirm-email.
- SSOManager.registerSSO now always confirms email (caller must
verify first); removes sendConfirmationEmail / _finishRegistration
- SSOController._signUp sends confirmation code and stores
pendingSSORegistration in session when IdP email_verified is false
- New SSOConfirmEmailHandler completes registration after code check
via completeSSOEmailConfirmation module hook
- OnboardingController confirm-email handlers accept
pendingSSORegistration alongside pendingUserRegistration
confirmEmailFromToken (POST /user/emails/confirm) removal is deferred
to a follow-up PR to avoid breaking in-flight 90-day tokens.
Closes#28607
* Fix unverified-email edge cases; Add ORCID e2e tests;
* Rename `confirmEmail` parameter to `emailVerifiedByIdP` in _signUp function
* Remove `sendConfirmationEmail`
* Mock getUserByAnyEmail in tests
* Extract _finishSSORegistration helper to deduplicate the register →
set session flags → allocate referral → finishSaasLogin → finishLogin
sequence shared by both the direct and deferred (code-confirmed) paths.
* Stop duplicating session data in pendingSSORegistration
analyticsId, splitTests, and referal_* are already in the session at
confirmation time — no need to copy them into pendingSSORegistration.
Re-fetch splitTests fresh on completion instead.
* Simplify the code
* Remove dead confirmEmail template
No callers remain after sendConfirmationEmail was deleted. The token-link
flow (confirmEmailFromToken) only validates tokens, never sends email.
* Remove dead reconfirmEmail template
* Address comments from Copilot
* Clear stale pending registration when starting a new flow
* Add unit tests for completeSSOEmailConfirmation
* Add `verificationMethod` param
* Fix camelcase issues
* Extract _createSSOUser and _registerAndFinish helpers to deduplicate registration logic
* Remove obscure "registration_error"
* Prevent FormTextIcon from shrinking
* Enable "email_already_registered_sso" error
* Misc. improvements to confirm-email-form.tsx
* Remove `UserEmailsConfirmationHandler` mock
Co-authored-by: Olzhas Askar <olzhas.askar@overleaf.com>
* Add info on sso_email.pug page
---------
Co-authored-by: Olzhas Askar <olzhas.askar@overleaf.com>
GitOrigin-RevId: d0196ebc6d81ff61bcd27726d0b899b743d08d64
- Add a Typst language (stream highlighting + completions) for .typ, and
Quarto completions (code chunks, callouts, cross-refs) for .qmd/markdown.
- Project dashboard: new Format column (Quarto/Typst/LaTeX) from the cheap
project compiler field, surfaced through the projects list API.
- Compiler dropdown: grey out engines that don't match the root file's
extension (.qmd->Quarto, .typ->Typst, .tex->LaTeX engines).
- Replace the Overleaf fill loader with an animated Verso logo: the four
quadrant circles drift on their own orbits while colour warms up with load
progress; reused on the token-access screen too.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Instance name: stamp the nav title with the build number at deploy time
("Verso V0.<run> alpha") via a sed placeholder fed by GITHUB_RUN_NUMBER,
instead of the static "Verso V1.0 Alpha".
- Title typeface: self-host the EB Garamond latin subset (same one embedded in
the logo SVGs) and apply it to .navbar-title so the instance name matches the
Verso wordmark.
- Sidebar wordmark: let the logo fill the full sidebar column width (drop the
160px cap).
- Project filters: switch the ds-nav active state (filter selection + theme
toggle) from the green tokens to the blue scale, matching the rail.
- Present button: rename the presentation toolbar action from "Preview" to
"Present" / "Présenter" and add a tooltip explaining it publishes the
presentation and opens it in a new tab. New keys present /
present_publishes_and_opens_in_new_tab in en, fr and extracted-translations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Editor rail: the active item used the Overleaf green accent. Switch
--ide-rail-link-active-color/background to the blue scale (--blue-10/70,
--bg-info-03) to match the Verso palette.
- Footers: remove the default "Fork on GitHub!" right_footer item (redundant
with the "Built on Overleaf" link); right_footer now defaults to [].
- Login: move the hero wordmark into a full-width centered block and bump it to
max-width 480px so it's no longer constrained by the form column.
- Projects dashboard: restore the instance name in the top-left navbar (set
OVERLEAF_NAV_TITLE="Verso V1.0 Alpha") instead of the wordmark logo, and move
the full Verso wordmark to the sidebar's lower section (where the old
"Digital Science" mark sat). Revert HeaderLogoOrTitle to its title-first
behaviour now that the dashboard no longer passes a logo.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three follow-ups after the visual-identity deploy:
- Footer: restore the React <Footer> on the projects dashboard (both
ProjectListDsNav and the legacy DefaultNavbarAndFooter). Removing it earlier
was an overcorrection — it now renders the Verso/AGPL thin footer rather than
the old "Powered by Overleaf" line. Other pages already kept the pug footer.
- Navbar brand: HeaderLogoOrTitle previously hid the logo whenever a nav title
was set, so on the dashboard only the "Verso" instance-name text showed and
the wired-up Verso logo never appeared. Make a configured logo (custom logo
or the Verso brand logo) take precedence over the title text; fall back to the
title only when no logo is provided (unchanged for other navbars).
- Login: enlarge the hero wordmark (max-width 260px -> 380px, full column width).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [web] Fix footer For Students link to activate student toggle
The footer link only set itm_referrer plus a #student-annual hash. The
plans page reads the active plan/period from `plan` and `period` query
params (PlansHelper.getPlansPageViewOptions), so the student tab never
activated from the footer link.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* syncStudentModeFromPlanType after in handleDeprecatedHash
* Change URL update to use replaceState in the pricing page
* Revert "Change URL update to use replaceState in the pricing page"
This reverts commit eac71f193029e3f1c75e0c97261d8a5982c0d35c.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitOrigin-RevId: 69d689d0fe89fc68cefab9233739fc61da8f2ced
* Add tests on plurals
* Update `collabs_per_proj` and its pluralisations
* Update `n_user` and its pluralisations
* Update `showing_x_results` and its pluralisations
* Update `show_x_more_projects` and its pluralisations
* `bin/run web npm run extract-translations`
* Populate `_plural` keys in non-en locales
For 2-form languages (da, de, es, fi, fr, it, nl, no, pt, sv, tr), copy
the existing bare-key value into the new `_plural` sibling to prevent
i18next from falling back to English for count!=1.
Also remove orphan singular keys (`collabs_per_proj_single`,
`showing_1_result*`) left over from the previous commits.
Bare-key values remain in their original plural form pending translator
review — count=1 will still render the plural form in non-en until
translators flip those to singular. Multi-form (cs, pl, ru) and
single-form (ja, ko, zh-CN, zh-TW) locales are unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Flip non-en bare-key values to singular form
Per review, the i18next v3 plural convention uses the bare key for count=1
(singular) and `_plural` for count!=1. The non-en bare-key values were
left as the original plural form by the previous commit so the `_plural`
siblings could be copied from them; this commit flips the bare values to
the singular form per language.
Languages where singular and plural noun forms coincide (Finnish, Swedish,
Turkish) are unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Apply suggestions from code review
Co-authored-by: Olzhas Askar <olzhas.askar@gmail.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Olzhas Askar <olzhas.askar@gmail.com>
GitOrigin-RevId: 628513ca792c2dcce023247e52b7320e2741cc54
* visual updates to optional fields in manual bib entry
* omitting onClose from button auto complete props
GitOrigin-RevId: 922695e8eaec83702b482123dc4b4483fe957b78
* Add DS nav page switcher behind overleaf-library flag
- Add shared DsNavPageSwitcher component (Library/Projects nav links + logo)
- Show page switcher in projects sidebar when overleaf-library flag enabled
- Hide 'All projects' filter and sidebar New Project button behind flag
- Move New Project button to content area header when flag enabled
- Prevent full page reload when clicking active nav item
- Change Upgrade button to premium variant when flag enabled
- Add overleaf-library split test to ProjectListController
- Add library-page class to remove rounded corner on /library
- Add Cypress component tests for DsNavPageSwitcher
Closes#33092
GitOrigin-RevId: 2e348da8307bf944d481b54b3a2bcc2eb319e18e
* [web] Update paywall copy for plans-2026 AI tiers
Replace AI-related strings in upgrade/paywall UI when the
plans-2026-phase-1 flag is enabled:
- Add `higher_ai_allowance` ("Higher AI allowance") for paywall bullet
lists and body text; keep `higher_ai_limits` ("Higher AI limits") for
the subscriptions dashboard, which uses different wording per spec
- Update three locale strings to use "allowance" instead of "limits":
`access_all_premium_features_ai`, `plus_additional_collaborators_and_more`,
`upgrade_to_add_more_collaborators_and_more`
- Fix casing: `upgrade_to_review` "Upgrade to Review" → "Upgrade to review"
- Switch upgrade-benefits and onboarding prompt from `higher_ai_limits`
to `higher_ai_allowance`
- Fix subscriptions free-plan to show `higher_ai_limits` instead of
`get_unlimited_ai` under the plans2026 flag
- Fix compile-timeout button to show "Start free trial" under plans2026
instead of "Start a free trial"
- Update two Cypress assertions for the new track-changes modal title
* Update extracted translations for higher AI allowance
* Remove "start a free trial" with exclamation
* Remove "get unlimited ai" translation entries
GitOrigin-RevId: 12300d94dc81c5407a21d4682d5714d7284c31b0
[web] Tear down new-user-system-overall-theme split test and themed-project-dashboard feature flag
GitOrigin-RevId: fe947a603266166332b73a5707bb6cbc9e3d03b9
* Revert "Revert "Adding More Ai Quota Tiers (#32128)" (#32431)"
This reverts commit f0ea19b418da6096c84b42024aea643807347649.
* fix: dont block workbench from users who have access via WF
* fix: simplify workbench access rules and ensure wf premium users can use workbench
GitOrigin-RevId: 7927248eadd906d7f802d55fa5c6bc7df162b141
* feat: adding tiers for free and standard
* feat: updating feature calculation to account for more quota tiers
* feat: rename freeTrialQuota to freeQuota
* feat: add hasAiFreeTier and hasUnlimitedAi to editor, block free tier from using workbench
* fix: updating tests
* fix: updating ordering precedence for quota tiers
* feat: bump unlimited ai fair usage to 300 uses
* fix: update workbench quota usage for unlimited plans
* feat: bump features version for ai quota split
* feat: popover should only show for relevant users on workbench, and adding upgrade notification to ineligible users
GitOrigin-RevId: e3ef38797f267677cad51d7273272623027ca330
* feat: adding usage rate limiting to workbench and aligning editor context values for suggestionsLeft
* feat: prepend word token to headers of token rate limiter to prevent confusion with usage rate limiter
* Shared AI paywalls (#31948)
* feat: renaming hasPremiumSuggestion and adding token limits to editor context and project load
* feat: adding new ai features paywall component
* feat: rename getRemainingFeatureUses to token based naming for token based limiter, removed checking for feature usage on anonymous users, and removed guard on null userId since we shouldnt be calling getRemainingFeatureUses on a nonexistent user
* feat: using token rate limit headers to set token rate values in editor context
* feat: update workbench to be available without refreshing if rate limit reset occurs within session
* fix: move paywall out of inert section
* Hide new paywalls behind FF and open plans page on upgrade attempt (#32023)
* feat: hide new paywalls behind FF
* feat: update ai paywall buttons to navigate to plans page post quota plans change release
* feat: showing a fair limit notificaiton pre-quota change, and updating paywall to not fire if user has premium already (#32056)
GitOrigin-RevId: 565fb128d55543fea34c383bc4abeaa3dd148d09
* Initial working version of auto complete button component
* generalising button auto complete for use in bibtex entry form
* Adding optional fuzzy searching
* Restoring delete optional field
* Removing dropdown specific styling
* Updating item/group interface for autocomplete
* Auto complete allowing full keyboard nav functionality
* Custom class for dropdown-upward
* Adding error validation for duplicate name with standard field
* fixing type errors
* Replacing Fuse with MiniSearch
* Adding clear button and frontend tests for ol-autocomplete
* Adding fuzzysearch option to autocomplete story
* removing unused vars and noddy comment
* Fixing lint failure
* Updating fuzzy search threshold
* Using downshift natural highlight
* Required label for aria compliancy
* changing how create item is handled
* addressing review comments
* Using AutoExpandingTextArea for optional fields and hooking in validation
* Formatting
* Requiring items prop for ol-autocomplete
* Fixing type failure in test
GitOrigin-RevId: 9b8f719fbb2bdd75fc1d5a9076908559040a8a78