99 Commits
Author SHA1 Message Date
Lucie GermainandClaude Opus 5 9cf4fa8bf5 [web] gracefully handle failed oauth token exchange for reference managers (#36377)
* [web] gracefully handle failed oauth token exchange for reference managers

Mendeley/ReadCube redirect back to /:ref_provider/oauth/token-exchange with
`error` and `error_description` instead of `code` when a user declines consent.
completeAuth forwarded the whole query string on to third-party-references,
whose strict zod schema (d8c1679bb08) accepts only oauth_token, oauth_verifier
and code, so the exchange failed and the user got a 500.

The same forwarding also sent `state` on every callback, success or failure.
`state` is web's own CSRF token and is never read by third-party-references, so
it tripped the log-only schema on every single token exchange, and would have
broken linking outright under REQ_VALIDATION_MODE=enforce.

Forward only the credentials the exchange needs, and show a translated
notification in the Reference managers section rather than erroring. Validate
ref_provider against the known providers so the provider name can be
interpolated into the message without reflecting a URL segment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* [web] fix providerName argument and validate before deriving refProvider

Address Copilot review on #36377:

- The token-exchange failure handler passed `false` positionally into the
  `providerName` slot of _redirectWithLinkingError, so a failed exchange would
  have rendered "your false account". Pass providerName and an explicit false.
- _getRefProviderBackendKey(req) ran before parseReq, so refProvider was derived
  from raw, unvalidated req.params. Parse first and derive from the validated
  params via _toRefProviderBackendKey; _getRefProviderBackendKey now delegates
  to it so the other handlers are unchanged.

The completeAuth tests kept their assertions inside ctx.res.callback without
awaiting the controller, so the callback fired after the test had already
returned and the assertions were never enforced — which is why the suite was
green with the providerName bug in it. Await the controller and assert inline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* [web] add logOnly to the completeAuth schema and guard the provider lookup

logOnly returns the raw input on a schema failure, so ref_provider can be an
arbitrary URL segment. Check it against the display-name table rather than
trusting the schema: unknown providers 404 in both validation modes, and
providerName is guaranteed non-null for the rest of the handler.

Also covers the schema half under REQ_VALIDATION_MODE=enforce, so dropping
ref_provider from completeAuthSchema fails a test rather than passing unnoticed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
GitOrigin-RevId: b98eb5414fe8b672f44aab8c3690f7637d434cd2
2026-09-17 11:51:27 +00:00
Liam O'BrienandClaude Sonnet 4.6 77970c98c9 Fix GitHub Sync unlink robustness and detect expired credentials (#35147)
* github-sync: only swallow permanent revocation failures during unlink

404 (token gone) and 422 (token issued under a mismatched client_id,
the confirmed cause of #35108) are treated as safe to proceed past;
any other revocation error now aborts the unlink instead of silently
deleting the local credential row, so a token that might still be
live isn't orphaned by a transient GitHub failure.

* web: surface genuine github-sync unlink failures instead of a 500

When GithubSyncApiHandler.unlink rejects for a reason other than the
permanent 404/422 cases now handled by github-sync, show an error
notification on the settings page instead of crashing the request,
mirroring the existing projectSyncSuccessMessage session-flash pattern.

* github-sync: detect expired credentials in user status check

getStatus now validates a stored token against GitHub (GET /user)
before reporting it as linked. A GithubInvalidCredentialsError (401)
now surfaces as expired: true alongside enabled: true, distinguishing
a dead token from a genuinely working link. Any other validation
failure fails open and reports enabled: true as before.

* web: propagate github-sync expired status through to the client

Thread the new expired field from github-sync's status endpoint
through GithubSyncController.getUserStatus and the settings-page
injectUserSettings middleware, and extend the corresponding
TypeScript types on both the app and frontend side.

* web: show a re-link path on the settings widget when github credentials expire

The widget now checks expired status: it shows an error indicator
with a "connection expired" message and renders the Link action
instead of a dead-end Unlink button, since relinking upserts a fresh
token regardless of the stale row.

* web: keep unlink available for expired github credentials

Some users just want to remove an expired connection rather than
relink it. Keep Unlink as the primary action regardless of expired
status, and surface the relink path as an inline link next to the
expired message instead of replacing the primary action.

* web: correct the github unlink confirmation warning

Unlinking never touches a project's githubSyncProjectStates row,
regardless of whether the credential was healthy or expired -
verified by tracing unlinkAccount/deleteUser and confirming no other
code path deletes project sync state on account unlink. Sync pauses
until relink, but no project loses its GitHub connection, so the
warning text was simply wrong; corrected rather than adding a
separate expired-specific message.

* web: add Storybook story for expired github-sync credentials

Covers the new expired state alongside the existing NoFeature,
Unlinked, Linked and Error stories for the settings widget.

* simplify: collapse duplicated branches and extract session-flash helper

- Merge the near-identical 404/422 checks in _revokeToken into one
  status-set check.
- Use optional chaining instead of null-guard ternaries in
  GithubSyncMiddleware.
- Extract popSessionValue() in UserPagesController to de-duplicate the
  read-then-delete session flash-message pattern, now used 3 times.

* review-self: close test coverage gaps found in self-review

- AuthenticationController: cover 401/403 revocation responses and a
  plain network error with no .response, alongside existing 404/422/500.
- GithubSyncController: assert projectSyncErrorMessage stays unset on
  the unlink success path.
- UserPagesController: cover projectSyncErrorMessage set-then-cleared
  and absent-stays-undefined cases.
- Add GithubSyncMiddleware.test.mjs (previously untested): not-logged-in,
  successful status fetch, and callback-error branches.
- Cypress: cover cancelling the unlink confirmation modal while expired.
- Storybook: add ErrorWhileUnlinked story for the disabled-Link +
  error-indicator combination.

* review-self: fix audit-log ordering, cache getStatus validation safely

- GithubSyncApiHandler: write the link-github/unlink-github audit log
  entry only after the corresponding github-sync API call succeeds,
  instead of before (resolves the discrepancy tracked in issue 3354).
- UserController/UserManager: cache getStatus's live token-validation
  result for 5 minutes to cut down on redundant GitHub API calls,
  with an optimistic-lock write (matched against the encrypted token
  that was actually validated) so a relink can never be overwritten by
  a stale in-flight validation of the old token.
- github-integration-linking-widget: dedupe the relink href against
  the linkPath already passed to IntegrationLinkingWidget.

* web: surface expired github credentials proactively in the sync modal

The modal previously only showed the reauthorize prompt after a real
GitHub API call failed with 401 mid-action. It now also checks the
expired field already returned by the status endpoint and shows the
same prompt immediately on open, before ever rendering the export
form against a token known to be dead. Extracted the existing
reauthorize markup into GithubCredentialsExpired so both call sites
share it.

* github-sync: avoid double-fetching the credential doc in getStatus

getStatus called UserManager.getUser, then getAuthToken which
internally fetched the same document again. Add getAuthTokenFromUser
to decrypt from an already-fetched doc and use it in getStatus,
removing the redundant Mongo query and the now-unreachable
GithubUserNotLinkedError handling (the user doc's existence was
already confirmed by the first fetch).

* github-sync: make expired-token handling reactive, drop proactive getStatus validation

Reverts getStatus in the github-sync service to a pure DB check — no live
GitHub API call, no 5-minute cache, no token_expired/token_validated_at
fields. The expired state is already surfaced reactively: the unmerged-commits
fetch on modal open returns 401 when the token is dead (handled by the existing
case 401 branch), and ExportToGithub handles 401 from the orgs call. The
proactive check added complexity (caching, optimistic-lock writes) without a
meaningful UX gain over the reactive paths.

Removes the expired indicator from the settings widget and the proactive
GithubCredentialsExpired screen from the modal's pre-flight check. The
github_sync_expired locale key is removed as it is no longer referenced.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* github-sync: show reauthorize prompt when push/pull fails with expired credentials

When a merge (push or pull) returns 401, GithubSyncMergeAction now renders
GithubCredentialsExpired with the Reauthorize button instead of the raw
"GithubInvalidCredentialsError" string that was previously falling through
to the default error branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* github-sync: wrap all async controller handlers with expressify

Without expressify, an unhandled throw from an async route handler
(e.g. a token decryption failure in the github-sync service producing a
non-4xx error that _reportError re-throws) becomes an unhandled rejection.
Express never sends a response and the modal is left stuck on loading.
expressify catches the error and passes it to next(), so Express's error
handler sends a 500 and the frontend can surface it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* removing redundant tests

* removing getAuthTokenFromUser function

* removing redundant key

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
GitOrigin-RevId: 0d9a314bf70bea9e6037593f2a6f8b8d1f2c6e71
2026-09-17 11:22:04 +00:00
Jimmy Domagala-Tang 8e5c207f6b Remove Writefull.enabled (#31476)
* feat: migrate from aiErrorAssist naming for disabling AI features to aiFeatures.enabled to avoid confusion

feat: keep aiErrorAssistant as setting on user object until migration is run

* feat: migrate writefull.enabled unset to instead use promotionSet false

* feat: remove wf.enabled in favor for aiFeatures.enabled for display, and writefull.promotionSet for determining if we should autoload or autocreate

GitOrigin-RevId: 2b7a5b8a430a804f6c9804cc926cb5c057e34df5
2026-02-20 09:06:08 +00:00
Alf Eaton b843603bb1 Use data-type="number" for numeric meta values (#26775)
GitOrigin-RevId: 844f56383457ee7f2043af553b7dd5ae1b33f8a9
2025-07-10 08:07:04 +00:00
Rebeka Dekany c40ab3234d Prettier for PUG templates (#26170)
* Setup prettier

* Ignore these pug templates by prettier

* Fix typo

* Fix prettier error

* Add prettier-ignore for quoting of event-segmentation attribute

* Manual tab indentation

* Interpolate

* Remove unbuffered if conditional

* Inline event-segmentation objects and remove prettier-ignore rule

* Fix spacing before interpolation

* Source format

* Source format

GitOrigin-RevId: c30e037f5caf8f91efc1bd9e75f81ae533b5a506
2025-06-24 08:05:06 +00:00
Miguel Serrano 04fa5366ce Merge pull request #26070 from overleaf/msm-disable-dropbox
[web] Disable Dropbox Capability

GitOrigin-RevId: 5f91d2918bf3b88e52f4d27c828a4715f9b88629
2025-06-20 08:05:20 +00:00
Mathias Jakobsen fe68930e9a Merge pull request #24733 from overleaf/mj-labs-without-features
[web] Move labs experiments from features to own property

GitOrigin-RevId: 22dee79758e5fa65fc31d9b8d4b155443cd585e7
2025-04-17 08:05:28 +00:00
Tim Down 9ea0f2ec29 Merge pull request #24606 from overleaf/td-bs5-make-default
Make Bootstrap 5 the default everywhere

GitOrigin-RevId: 024614d6f4f370fd9c9623a6f35c64e43d2a70c4
2025-04-08 08:07:29 +00:00
Rebeka Dekany 789db0d822 Remove bootstrap-5 feature flag from the Account Settings page (#23693)
GitOrigin-RevId: 0fc29f2cb904f9133fd26ad119909edba1518cbf
2025-02-24 09:04:54 +00:00
Tim Down 39a499b25a Merge pull request #21622 from overleaf/td-settings-link-colour
Enable redesign for account settings page and use application link colour

GitOrigin-RevId: dad039810256bda47061799ef56a9c87a663ab3d
2024-11-15 09:04:49 +00:00
Liangjun Song 3f1edfc1c9 Merge pull request #19954 from overleaf/ls-access-token-gradual-rollout-cleanup
Update git bridge modal for pw auth deprecation

GitOrigin-RevId: 2e764922bf350ddcba29bf9f3baa220ed1f48e40
2024-08-26 08:05:15 +00:00
Tim Down d5643d53b3 Merge pull request #18996 from overleaf/td-bs5-nav-react
Main navigation React component

GitOrigin-RevId: c99a4b4a2f6fd02618689f829681118b2b64aa8d
2024-08-22 08:05:03 +00:00
Tim Down 956aad7e43 Merge pull request #18764 from overleaf/td-bs5-dashboard-feature-flag
Create new feature flag for BS5 project dashboard page

GitOrigin-RevId: a523bd7df94c411805ac2f5234135bc7a56d25bb
2024-06-25 11:12:35 +00:00
Tim Down 3b2e60ece7 Merge pull request #18558 from overleaf/td-bs5-query-string-override
Add a mechanism to hide incomplete Bootstrap 5 pages by default

GitOrigin-RevId: 07cc998bf3a0bed9df2f43d1c04c62d167c9b893
2024-05-30 08:04:15 +00:00
Tim Down a345eb42c2 Merge pull request #17712 from overleaf/td-bs5-feature-flag
Add feature flag check and per-page opt-in for Bootstrap 5

GitOrigin-RevId: 111474c19f0202efc4e701eef597c7653f8e8b61
2024-04-12 08:05:10 +00:00
Jessica Lawshe d65bba566c Merge pull request #17315 from overleaf/ab-accounts-settings-sso-status
[web] Show Group SSO linking status on the account settings page

GitOrigin-RevId: ae45e1bd7a90a672c5fb023e7f3e603a00e364e5
2024-03-12 09:03:43 +00:00
Miguel Serrano 992cb49802 Merge pull request #17241 from overleaf/msm-fix-sp-git-settings
[web] Prevent render of Sync section in SP when git is disabled

GitOrigin-RevId: 5bfd1baadaff21db72d84a11d3f926431739dae4
2024-02-22 09:05:06 +00:00
Rebeka Dekany 61c380c89d Merge pull request #16371 from overleaf/rd-skip-link-dashboard
[web] Accessibility - Add 'main-content' ID to main element for skip link destination

GitOrigin-RevId: f6a7bf4cc12ab2428478562a9edda245dce7c2fb
2024-01-05 09:03:49 +00:00
Alf Eaton 749aef1c6f Add optional personal access tokens for git bridge (#15209)
GitOrigin-RevId: 50d4c0e11728e014e81172c062a3b22fefa6286c
2023-10-20 08:03:27 +00:00
M Fahru a3e30c0a39 Merge pull request #14178 from overleaf/mf-admin-email-managed-group-alert
Add managed group admin email inside managed group alert on the subscription page & team invite page warning

GitOrigin-RevId: 00929008170ef9302ddcbbf10aefd76f95e189a8
2023-08-10 08:05:04 +00:00
Brian Gough 558992d947 Merge pull request #13916 from overleaf/bg-managed-users-hide-leave-group-action
managed users hide leave group action

GitOrigin-RevId: 160e31e6935cd3737356714020e057f8c1acc5b8
2023-07-21 08:04:36 +00:00
Davinder Singh 9e8e124113 Merge pull request #13591 from overleaf/ab-account-enrollment
[web] Managed users - account enrollment

GitOrigin-RevId: 6fc9ef8c44394eb92d3afd2022433b0b6d508503
2023-07-17 10:59:02 +00:00
Miguel Serrano 51223315e4 Merge pull request #13164 from overleaf/msm-email-limit
[web] limit user email addresses to 10

GitOrigin-RevId: 038214cc921d86a407391e6c82fa9cd16a7f9646
2023-05-29 08:04:04 +00:00
Miguel Serrano 27c2d1c16e [web] Personal Access Token Settings UI (#13040)
* [web] Personal Access Token Settings UI

* [web] Add Personal Access Token Settings UI to settings page

* [web] Added `personal-access-token-settings` unit tests

GitOrigin-RevId: 353b2f1a2b57c3292554f129be6cbb4f8f8382f8
2023-05-17 09:28:01 +00:00
Miguel Serrano c2dce961b9 Merge pull request #12901 from overleaf/msm-oauth-token-flags
[web] Feature flags for Personal Access Tokens

GitOrigin-RevId: cb359b7c41d8875ebae7d78a8839528bc4adc04c
2023-05-08 08:04:55 +00:00
Mathias Jakobsen 6169ba55e5 Merge pull request #9389 from overleaf/mj-angular-settings-cleanup
[web] Angular settings removal

GitOrigin-RevId: a7efdf31d488aa782e0ad400f05169645e1731d0
2022-08-30 08:03:52 +00:00
Miguel Serrano d91fada6fe Merge pull request #7913 from overleaf/msm-remove-beta-server-pro
[Settings] Remove beta section from Server Pro

GitOrigin-RevId: b85b1c675e3f45c6a8f5c77bb51ba9b86ee1b764
2022-05-12 10:40:47 +00:00
ilkin-overleaf d50271c1e9 Merge pull request #7225 from overleaf/ta-leave-modal
[DeleteAccount] Create Modal with Form

GitOrigin-RevId: 611f08c7253f59d91c6937b79c80a386b9d21ccd
2022-04-11 08:03:36 +00:00
Jakob Ackermann 333f334419 Merge pull request #7256 from overleaf/msm-upgrade-account-tracking
Event Tracking for account upgrade

GitOrigin-RevId: 865524a0c9c79d051953340a7ea744c88dbe1295
2022-04-05 12:21:29 +00:00
Timon Engelke b9db578e0b Fix user settings template 2021-11-30 18:05:00 +01:00
Jessica Lawshe bb882c697c Merge pull request #4288 from overleaf/jel-skip-to-content
Add "Skip to content" to improve accessibility

GitOrigin-RevId: 43368a65057656bdea10b6be3c598d68bd8e2d40
2021-07-28 02:06:54 +00:00
Miguel Serrano 37a50e295a [ServerPro] Removed SaaS views in admin panel and user settings (#4263)
* Removed SaaS views from SP admin panel and user settings

* Hiding must reconfirm for server pro and restored site admin

* Removed empty 'security' section

GitOrigin-RevId: 9ad8e2b7510cf957ccf3f968a53fa88d3174a64b
2021-07-01 12:30:21 +00:00
Eric Mc Sween 5587de9cf5 Merge pull request #3833 from overleaf/em-meta-tags
Pass values to JS through meta tags

GitOrigin-RevId: f663a1b7fef4544b560574d21f59fdabaf617830
2021-04-01 02:05:44 +00:00
Alf Eaton a5637651b5 Add Content-Security-Policy header (#3783)
* Add Content-Security-Policy header
* Add nonce attribute to script tags
* Use source-map for webpack devtool
* Add ng-csp attribute when CSP is enabled
* Allow overriding CSP settings with environment variables
* Hook into render and allow routes to disable the CSP header

GitOrigin-RevId: a873736a3514198165f1b2f1e18d002b65f20d30
2021-03-26 03:04:55 +00:00
Jakob Ackermann f353728bda Merge pull request #3755 from overleaf/jpa-xss-2
[views] mitigate Angular XSS via email/new_email

GitOrigin-RevId: 3d127c283ba9f97c5b0e6c53a9d77f7f597058bb
2021-03-18 03:04:50 +00:00
Thomas 2d8167fa0a Merge pull request #3675 from overleaf/tm-main-landmarks-a11y
Add main landmark roles to multiple templates

GitOrigin-RevId: 80ae851fae015b21a3210d71d04287c0c9a3024d
2021-03-05 03:05:00 +00:00
Jessica Lawshe ddb6163b65 Merge pull request #3623 from overleaf/jel-ui-reconfirm-settings
Add reconfirm UI to settings

GitOrigin-RevId: cf9c4648cab07784782e24d752154089dc32196a
2021-02-23 03:04:17 +00:00
Shane Kilkelly e9f7a17093 Merge pull request #3234 from overleaf/sk-fix-password-validation-email
Overhaul password validation

GitOrigin-RevId: a591c4e192e30a0ac053eab6f80627543a8a92fe
2020-10-23 02:04:39 +00:00
nate stemen 8ba78bd559 Merge pull request #2848 from overleaf/ns-account-deletion-v1-references
remove references to v1 projects on account deletion

GitOrigin-RevId: 1e886d6b693f98ee81efc704d2a3688de43981ef
2020-05-22 03:24:48 +00:00
Miguel Serrano e2bf647b81 Merge pull request #2763 from overleaf/ta-dot-dot-dot
Replace Triple-Dots with Ellipsis in Pug Files

GitOrigin-RevId: 408cea0772d8751acd8939e199e49e2cf9685b8f
2020-04-23 03:29:02 +00:00
Eric Mc Sween e80870f453 Merge pull request #2629 from overleaf/cmg-updateon-typo
Fix typo in user settings

GitOrigin-RevId: 066ee8047d807e9ac077eb687a93f12d9db6bf55
2020-02-28 04:18:21 +00:00
Jessica Lawshe 5c918bed94 Adding an institution email that must be linked
GitOrigin-RevId: 9ba42a07fb386275cf6d81a7d4b91a7f974faf15
2019-10-08 13:29:17 +00:00
Eric Mc Sween 039b5eaba0 Merge pull request #2167 from overleaf/jel-saml-account-settings-layout
Account settings layout for institution SSO

GitOrigin-RevId: d9c9e5eeb3b4a215456b0f5294139c1b8d4968c3
2019-09-30 13:36:41 +00:00
Eric Mc Sween 869fcf7952 Merge pull request #2089 from overleaf/em-mailchimp-unsubscribe
Handle error on Mailchimp unsubscribe when deleting users

GitOrigin-RevId: 8923480e6d50de45003fd7741610f995753a412b
2019-09-03 15:25:01 +00:00
Simon Detheridge 4cf480a448 Merge pull request #1965 from overleaf/jel-remove-v1-login
Remove login to v1 via v2

GitOrigin-RevId: e5ba86786d14c5a2be87aff6b38cfd807b5cd053
2019-07-22 15:31:24 +00:00
Ersun Warncke d624c29b6f remove v1 deps for password change/reset
GitOrigin-RevId: be25f19ae589c50bfde0b170860127fa8d6f63b7
2019-07-17 15:09:24 +00:00
Jessica Lawshe 6e09af6fbe Merge pull request #1971 from overleaf/jel-settings-add-aria-label
Update label to match input ID

GitOrigin-RevId: 849c9d49d861cf3b5645496b5e4eed1dc6d7392a
2019-07-11 17:07:51 +00:00
Jessica Lawshe ed6891e66d Merge pull request #1961 from overleaf/jel-remove-force-import-feature-check
Remove checks for `force-import-to-v2`

GitOrigin-RevId: f94e8b0fb2f7f4416759583d5ca02babec345120
2019-07-11 15:35:36 +00:00
Jessica Lawshe d4a8f38736 Merge pull request #1942 from overleaf/jel-user-settings-form-msg
Move user settings form message next to submit button and add ID attributes

GitOrigin-RevId: 3d87242e5a7211f9fa58b07f38a278fb94019046
2019-07-11 15:35:31 +00:00
Timothée Alby e029616ed4 Merge pull request #1914 from overleaf/jel-no-pw-message
Check for password on delete modal

GitOrigin-RevId: a2ec40b9c73e92490a9dfd0377b10f9d1831f56f
2019-07-01 14:06:42 +00:00