Commit Graph
28783 Commits
Author SHA1 Message Date
Anna Claire Fields 19d97a75c6 [web] log the failing tag colour in the validation rollout (#36858)
GitOrigin-RevId: 9fa5a7bc380edf85a1b266e10c5add495744619b
2026-09-17 12:03:42 +00:00
Brian Gough 7aa941794e Merge pull request #36860 from overleaf/bg-allow-integer-in-sync-requests
Allow integer values for h and v parameters in proxySyncPdf

GitOrigin-RevId: 66f303a5940f6976dcfe27ebf90da8a9ec24e98a
2026-09-17 12:03:37 +00:00
Jakob Ackermann 9b44fd075b [monorepo] downgrade ranges ids back to strings for now (#36857)
GitOrigin-RevId: 6c85715bc85adc2f641bfd0e9f3bb6a8f2c839c2
2026-09-17 12:03:33 +00:00
Jakob AckermannandClaude Opus 5 91bf8f13ba [validation-tools] add a throw+log mode to parseReq (#36821)
REQ_VALIDATION_MODE=enforce-log rejects schema failures exactly as 'enforce'
does, but logs them first at instrumented call sites, so the visibility built
for the 'log' rollout (sanitized issues, caller trace, logFields values, per
schema/signature dedup) survives moving out of 'log' mode.

opts no longer change the outcome in this mode: logOnly does not suppress the
throw, the error is classified from the primary schema (not the fallback), and
fallbackSchema is only re-parsed to tag the log entry -- 'enforced-fallback-
passed' marks a rejection the looser pre-refinement schema would have avoided,
i.e. one the tightened schema newly introduces.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
GitOrigin-RevId: 0743322990e6c570ffbae166b4586285a18221df
2026-09-17 12:03:25 +00:00
Jakob AckermannandThomas Mees e276104da8 Relax split test import schema to allow staging export fields (#36832)
* Relax split test import schema to allow staging export fields

The staging split test export includes fields (variant.active, version.__v,
splitTest.customerIoEnabled) that aren't otherwise written by the app but
are present in Mongo exports. The strict zod schema was rejecting the
import; mark these as optional so a staging export can be imported into a
local dev environment.

* [web] allow split-test import in dev-env and CI

* [web] ensure that the zod schema for split-tests covers all fields

---------

Co-authored-by: Thomas Mees <thomas.mees@overleaf.com>
GitOrigin-RevId: eab633e8498e351a64dc9a9dad85759e80744da0
2026-09-17 12:03:21 +00:00
Thomas 0e7eff712c [web] [b2b] mark selected schemas as non-strict (#36780)
Two of the B2B request schemas flagged in #36577 reject bodies we don't
want to reject:

- POST /manage/groups/:id/settings/sso: the group settings frontend
  spreads the SSO config document it fetched from the GET route back into
  the POST body, so the request carries `_id`, `__v`, `validated`,
  `enabled` and `useSettingsUKAMF` that the handler recomputes or ignores.
- POST /manage/groups/:id/invites: an internal script sends an unsupported
  `expiresAt` alongside the email; the handler only reads `email`.

Swap z.strictObject() for z.object() on both, with a comment on each
explaining why it's deliberately non-strict.

GitOrigin-RevId: 5ff94ded579bdda07efc59d9ceb1d495964a912d
2026-09-17 12:03:15 +00:00
Jimmy Domagala-Tang 8ab6005580 feat: updating userId to nullish and explaining why for reject changes (#36803)
GitOrigin-RevId: 6f7a46893b9ab32d8f726ad6ba928eb4e0175813
2026-09-17 12:03:12 +00:00
Brian Gough 538d04ddb8 Merge pull request #36664 from overleaf/lg-wordcount-sync-resources
[clsi] sync project resources for word count

GitOrigin-RevId: fe96c936e7aba22ab94416a102dcb7e4835e1256
2026-09-17 12:03:09 +00:00
Anna Claire Fields 285bcd4315 [editor-core] accept the legacy source_project_display_name on project_file (#36837)
GitOrigin-RevId: bebbba328ecdd04ac4df06f66e6b0b1f8a41276f
2026-09-17 12:03:05 +00:00
Eric Mc Sween 6590b33321 Merge pull request #36792 from overleaf/em-zod-validation-cleanup
Stop rejecting unrecognized request fields in the Dropbox, GitHub-sync, git-bridge and reference-manager APIs

GitOrigin-RevId: 5efdee90830b2a48172f839da8e59ef938746f65
2026-09-17 12:03:02 +00:00
Eric Mc Sween c55411ee99 Merge pull request #36802 from overleaf/em-migrations-auxiliary-tags
[migrations] tag the auxiliary library migrations for saas

GitOrigin-RevId: cfe1169af24b36d6dcb352b4e0f79b250d74a1a0
2026-09-17 12:02:53 +00:00
f671c3dc59 [web] read a linked project file's source from history (#36817)
* [web] read a linked project file's source from history

Behind the `linked-file-from-history` flag, a linked `project_file` import reads
the source out of the source project's latest history snapshot rather than out of
its file tree in mongo, where docs and files are two kinds of thing.

- `ProjectFileAgent` gains `_importFromHistory` alongside the existing
  `_importFromProject`, and the flag picks between them. The snapshot only holds
  what has reached history, so the source project is flushed through
  document-updater and project-history first. A file that is editable is loaded
  eagerly, which applies the edit operations sitting on top of its blob; one that
  is not keeps its hash and is streamed. The file is promisified on the way.
- `History/HistoryOTContentManager.mjs` reads the latest chunk and rolls its
  changes into a snapshot, retrying the read. `History/HistoryBlobStore.mjs` is
  the blob store overleaf-editor-core asks for while loading a file.
- `LinkedFilesController` resolves the flag, including from the referer: the
  import endpoints have no query string of their own. Every agent takes the
  assignment so that the ones that do not read it still pass it along.
- `linked-file-from-history.spec.ts` drives the flag from the editor url, over
  three imports from another project: a file uploaded to the source project and
  then refreshed from it, an edit the source project has only made in its editor,
  and a binary file. Both sources produce the same file, so which one was read is
  asserted in the acceptance tests rather than here.

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

* [saas-e2e] add test coverage for tracked-delete in linked file source

* Apply suggestions from code review

Co-authored-by: Mathias Jakobsen <mathias.jakobsen@overleaf.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Mathias Jakobsen <mathias.jakobsen@overleaf.com>
GitOrigin-RevId: 3907d6d399e4b5315e68bf833663c06bc72f4011
2026-09-17 12:02:47 +00:00
34d57a87f9 Add contextual pointers to the AI assistant in the editor gutter (#36643)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: jessdomanska <87976015+jessdomanska@users.noreply.github.com>
GitOrigin-RevId: 0df858dae9673868f02ca32cea024fe89794b544
2026-09-17 12:02:41 +00:00
Olzhas Askar bb7dfcd588 Merge pull request #36767 from overleaf/oa-express-types
[web] Express req/res/next types

GitOrigin-RevId: 30b4822e2ee55976331d049f8109f7098914973c
2026-09-17 12:02:38 +00:00
Olzhas Askar e9206d2b95 Merge pull request #36312 from overleaf/oa-unhardcode-homepage
[web] Unhardcode homepage

GitOrigin-RevId: 7ae0b66b5db57998ad1bd1988766d45e096620f7
2026-09-17 12:02:34 +00:00
Eric Mc Sween eb98741f03 Merge pull request #36693 from overleaf/em-node-24-version-metadata
[monorepo] bring stale Node version declarations up to 24.18.1

GitOrigin-RevId: 07d08e32920f05f02b817950eed25030d3b82ce4
2026-09-17 12:02:26 +00:00
Jimmy Domagala-Tang 1c0bc6c50a [web] Gate labs experiments behind premium compiles (#36339)
* feat: gating labs experiments behind premium compile feature

* feat: move filtering to the labs module, and only propogate experiments that user can opt into on the FE

GitOrigin-RevId: 984aa0339c7dc8d61f0f6830780a599508306d5e
2026-09-17 12:02:23 +00:00
Jessica Lawshe 2c8e2781c7 Merge pull request #35038 from overleaf/th-add-v1-blocked-domain
Add 'passmail' to the list of domains blocked in v1

GitOrigin-RevId: 6c12800d03af0ad838f60a13fcf7d77d321b03c6
2026-09-17 12:02:17 +00:00
Jessica Lawshe 49a00ef0e2 Merge pull request #36310 from overleaf/jel-confirm-existing-email
[web] Check if domain captured by group when showing confirm email UI

GitOrigin-RevId: bb6add82e083497c8036739d877610a47e35ecfd
2026-09-17 12:02:03 +00:00
Jakob Ackermann f62b8525f2 [web] gracefully handle empty relativePath in uppy uploads (#36773)
GitOrigin-RevId: 640094f69cf53ba9f33a5bdc3b6d532547431d01
2026-09-17 12:01:55 +00:00
Olzhas Askar c2cd5d686c Merge pull request #36711 from overleaf/oa-prices
[web] Prices, their versions and helper functions

GitOrigin-RevId: b42f16fe3b083a4872230f2e348b247650d08df8
2026-09-17 12:01:51 +00:00
Domagoj Kriskovic a301363ece Move Library BibTeX export to a server-side endpoint (#36604)
* Move bulk bibtex download to a server-side streaming endpoint

* Wrap download fetch errors in FetchError and parse the error body

* Refactor library references download to use GET request and stream response

* Remove MAX_DOWNLOAD_IDS limit from downloadIdsSchema and related test

* fix merge conflict

GitOrigin-RevId: dee2bae8bfb982cd1b79bbd21c9f1b90e8cff1a4
2026-09-17 12:01:40 +00:00
Tom Wells f0cd4b737f Merge pull request #36725 from overleaf/tw-add-library-docs-button
Add info button with link to docs on the Library page

GitOrigin-RevId: 7e7bc10272e0b5bcb7b1f98c07f493643f2ea92d
2026-09-17 12:01:32 +00:00
Jakob Ackermann 58e2396d91 [web] remove legacy body field for rootDoc_id (#36608)
The migration finished in 2014, there are no more clients using it.

REF: 175dfae085
GitOrigin-RevId: 6fc21e93c5ef34622e9cf6259e7105f3202d66ae
2026-09-17 12:01:26 +00:00
Jakob Ackermann 640a2e1c60 [web] remove unused link=false flag from /user/oauth-unlink (#36566)
GitOrigin-RevId: 5a8af17bf339df62a6cf54d6c372bff4cbe88eb3
2026-09-17 12:01:23 +00:00
Jakob Ackermann 4e80d65efc [ranges-tracker] add legacy orderedRejections field in tracked-changes (#36565)
* [docstore] use more realistic test stubs for ranges

* [monorepo] define ranges schemas in @overleaf/ranges-tracker

* [ranges-tracker] add legacy orderedRejections field in tracked-changes

* [monorepo] resolve @overleaf/ranges-tracker subpath imports in typescript

* [real-time] validate comment thread ids and tracked change id seeds

* [ranges-tracker] require ObjectId ids and tracked change metadata in ranges

* [monorepo] require ObjectId tracked change ids on the accept routes

* [web] use ObjectId comment thread ids in the DocumentController tests

GitOrigin-RevId: 58b20dec311d85b917ef63f9efbe745a265a2de6
2026-09-17 12:01:19 +00:00
Eric Mc Sween 833e44d142 Merge pull request #36733 from overleaf/dk-fetch-utils-unset-headers
[fetch-utils] Drop headers with unset values

GitOrigin-RevId: 284b8551dfc3b15315a873a9256fbf9f35e4004b
2026-09-17 12:01:03 +00:00
ilkin-overleaf 7cfdd0f75a Merge pull request #36230 from overleaf/ii-workspaces-projects-page
Empty states for the project list views

GitOrigin-RevId: 3ce8e327bb675f3c63763e7599396020a4252025
2026-09-17 12:00:54 +00:00
Jimmy Domagala-TangandTim Gibbon baa9cf78d9 Adding 2025 and 2026 incremental compiles options (#35850)
* feat: adding 2025 and 2026 incremental compiles options

* feat: remove dmtcp from compiler list and autoselect checkpointing version with labs inclusion

* feat: updating seccomp profile for checkpointing

* feat: disable non-premium dmtcp compiles, and align checkpoint version detection between clsi and web

* feat: adding in reminder of checkpoint experiment, and using session based split test retrieval

* Increase Packer build.sh timeout from 1h15m to 1h30m as build takes approx 1h

* fix: moving checkpointing check from tag name based to hasCheckpointing flag set as part of allowed_images, and removing uneeded seccomp rule

* feat: move variant/ image selection to CLSI, and have web control only what options to set for a compile. removing uneeded extra variants from webs list of allowed images

* feat: adding compile timer as a query string as well

---------

Co-authored-by: Tim Gibbon <tim.gibbon@overleaf.com>
GitOrigin-RevId: cdbdf76a62dcd5a585925f18d64b6cb9cd6ed373
2026-09-17 12:00:46 +00:00
John Lees-Miller 35271cb33c Merge pull request #36639 from overleaf/jlm-github-sync-distinguish-404s
Distinguish GitHub's repo-lookup 404 from its commit-comparison 404

GitOrigin-RevId: 67cd1d3af1fde553fc200371f5d2ec020c7245fa
2026-09-17 12:00:40 +00:00
David 28fd2f6605 Merge pull request #36675 from overleaf/dp-dark-library-modals
Theme the bibtex import and entry edit modals for dark mode

GitOrigin-RevId: 7aaf69f418844435de3421aa9b48e797b2ba93ef
2026-09-17 12:00:37 +00:00
Antoine ClausseandClaude Opus 5 e2e05b69f1 [web] Add pro-value-framing split test copy (#36628)
* feat(web): add pro-value-framing split test copy

Serve quantified, benefit-led plan differentiators on the plans and
interstitial pages to the `enabled` variant of the `pro-value-framing`
split test, in place of the vague "increased/max AI allowance" and
"10/unlimited collaborators" framing.

The variant changes the bullet set and order as well as the strings, so
it swaps in its own short feature list rather than remapping keys: Pro
leads with "Everything in Standard, plus:", Free gains Error Assist and
"Compile simple projects". The plans page comparison table mirrors the
card wording in its AI allowance row.

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

* test(web): assert plan copy numbers against plan features

Check the quantified claims in the plan copy against the SaaS plan
features: the collaborator limits, and the "24x" compile timeout claims
as the ratio of the paid to the free compileTimeout. The "2x more AI
usage" claim is checked against the allowance tooltips, since the
allowances themselves come from AI_*_QUOTA_GRANT and are not available
in the unit test environment.

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

* Remove overly contrasted color in card

* Remove redundant `makeUISettings2026`

* Simplify valueFramingOverrides

* Fix types

* Revert changes to the table, replace `2x_more_ai_usage` to `2x_the_ai_allowance`

* Remove oververbose PlansValueFraming.test.mjs

* Revert "Remove overly contrasted color in card"

This reverts commit 8e83a0c523c4ebfe8a40a04023f1801080d0e412.

* Apply suggestions from code review

GitOrigin-RevId: 25b0736af47a3a32f4e1dd108ab0eb14c1bc13e3
2026-09-17 12:00:26 +00:00
Antoine ClausseandClaude Fable 5 0e510226fa [web] Format paused reactivation date in UTC via shared helper (#36600)
The paused branch of getFormattedRenewalDate formatted the reactivation
date in the viewer's local timezone with a hand-rolled format literal,
while the surrounding dates are UTC. Compute the reactivation date in
UTC and format it with formatPaymentDate.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
GitOrigin-RevId: 1f1679c1988c696c16c78bd11152d6a39a20c4e1
2026-09-17 12:00:22 +00:00
Eric Mc Sween 82539b5842 Merge pull request #36684 from overleaf/em-user-settings-zotero-groups
Stop carrying an _id on reference manager groups in user settings

GitOrigin-RevId: 1ac74d201a3b81b2069215e05b9c84189c42aad6
2026-09-17 12:00:19 +00:00
Tim Down a84079e600 Merge pull request #36682 from overleaf/td-migration-readme
Update migrations README following switch to Yarn

GitOrigin-RevId: 718af0c66d173ecbfaa27209a41f525c9d1a4a8a
2026-09-17 11:59:50 +00:00
Lucie GermainandClaude Sonnet 5 57e536de79 [Security Upgrade]: cypress in root workspace (drops unpatched extract-zip) (#36689)
* [security] bump cypress 15.12.0 -> 15.20.1 to drop unpatched extract-zip

extract-zip <=2.0.1 has no patched release (GHSA-jmr9-qjv8-65gv). It was a
transitive dependency of cypress, used only to unpack Cypress's own binary.
Cypress 15.20.1 replaces extract-zip with yauzl directly, so upgrading the
parent removes the vulnerable package entirely.

Also bumps the pinned cypress/included Docker base image used by
test_frontend_ct / server-ce e2e / saas-e2e.

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

* [security] fix cy.get<T> alias typing broken by cypress 15.20.1

Cypress 15.20.1 adds a dedicated Chainable.get overload for alias strings
(get<S>(alias: `@${string}`): Chainable<S>), which now takes priority over
the generic selector overload. cy.get<HTMLInputElement>('@input') therefore
resolved to Chainable<HTMLInputElement> instead of
Chainable<JQuery<HTMLInputElement>>, so .then(element => element.get(0))
no longer type-checked. Pass the JQuery-wrapped type explicitly to match
the new overload.

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
GitOrigin-RevId: f4a56a2d5948b5aaf00a07ecb384fc75abf6de53
2026-09-17 11:59:44 +00:00
Lucie GermainandClaude Sonnet 5 a8e1198da8 bump ip-address to 10.3.1 in yarn.lock (#36452)
Fixes GHSA-mwp4-54f8-5fhr (high), GHSA-4xrf-jv44-h6hh (medium),
GHSA-22jq-vg5j-6vgg (medium) in ip-address, a transitive dependency
pinned via a resolutions entry in root package.json.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
GitOrigin-RevId: 1557589d719801cbd0ed95d36a17583fdc215f90
2026-09-17 11:59:36 +00:00
Mathias Jakobsen 0dd792b146 Merge pull request #36677 from overleaf/mj-fix-tag-hsl
[web] Allow derived HSL values for tags

GitOrigin-RevId: c9617a8b289e361f3dd438c7d81d8b3c1d5cb645
2026-09-17 11:59:32 +00:00
Rebeka Dekany b5c161eeca [web] Cache Stripe prices and products in StripeClient (#36236)
* Cache Stripe prices and products in StripeClient

* Note the Stripe price cache in the price scripts and dev manual

* Add tests for the Stripe price and product cache

* Simplify the not-found guard in getProductsByIds

GitOrigin-RevId: eb2a270a3abe0e9bf53ca2ebee1f0ad02b1a4cc4
2026-09-17 11:59:29 +00:00
Jimmy Domagala-Tang 009668c224 Release TeX Live 2026.1 as the default image (#36382)
* feat: releasing 2026.1 texlive to general release and promoting to default image

* fix: update clsi image tests so their likeness calcs work locally on different archs

* feat: updating epstopdf fixture and adding note to texlive Dockerfile used for codespaces

* fix: use generated image-eps-convert instead of fixture version that drifts

GitOrigin-RevId: 13c4f6977dbf07ddd34c9a5ab3ea295cddcbe025
2026-09-17 11:59:26 +00:00
Olzhas Askar 6053781e57 Merge pull request #36496 from overleaf/oa-annual-events
[web] Subscription event segmentation

GitOrigin-RevId: fdc25ac7bc7320ed82617b7c27c12a17eb31d723
2026-09-17 11:59:20 +00:00
Andrew Rumble ba4e6ef8ed Merge pull request #35468 from overleaf/ar-fetch-utils-type-improvements
[fetch-utils] type improvements

GitOrigin-RevId: 4652054c715c4ddb19bac1f46cdf1fc3916c533d
2026-09-17 11:59:06 +00:00
Mathias Jakobsen 1f9873e391 Merge pull request #36575 from overleaf/mj-generic-modals-themes
[web] Add dark mode to ide modals

GitOrigin-RevId: cd8e95e2286df46510a377ff9a69c4ab646ceabd
2026-09-17 11:59:00 +00:00
Mathias Jakobsen 8139638d9d Merge pull request #36570 from overleaf/mj-themed-labs-modal
[web] Add dark mode support for labs modal

GitOrigin-RevId: 18f9aff407ee5324c835f915419819b00d49bfb0
2026-09-17 11:58:57 +00:00
John Lees-MillerandClaude Opus 5 1ecdd122d0 Add Stripe migration features for stage 7 testing (part 2) (#35890)
* upsert: migrate US/CA PayPal without a payment method when flagged

getPaymentMethod no longer throws for a PayPal billing agreement destined for
Stripe US/CA when the account is flagged ignore_payment_method; instead it
returns null so the customer is migrated without a default payment method
(the send_invoice paymentMethodPending flow). Unflagged accounts still throw.

* finalize: expect the plan-code remap for legacy-plan subscriptions

When a subscription carries legacy_remap=1 metadata, compare the Stripe product's planCode against the recorded target plan code instead of the raw Recurly plan code, so the intentional remap is not misread as drift (the price is preserved, so the amount comparison is unchanged). Clear the legacy_remap metadata during post-migration cleanup.

* finalize: expect the assistant add-on reprice

When a subscription carries assist_addon_repriced=1 metadata, compare the assistant item against the recorded target amount (Stripe minor units) instead of the raw Recurly amount, so the intended reprice is not misread as drift. Clear the reprice metadata during post-migration cleanup.

* create_coupons: create migration coupons by name with amount_off, currency and product scope

Create the pipeline's per-region coupon_specs_<region>.csv coupons by name (idempotent, auto-paginated), supporting amount_off + currency (fixed) or percent_off, duration, and applies_to.products, with no promotion code. Region comes from the existing --region flag. The existing name-based percent-off + promotion-code path is unchanged.

* finalize: schedule the pending change as a phase 2

For a subscription flagged pending_change_scheduled, compare drift against the current Recurly state (not the pending change), then in Step 7 release the toolkit schedule and create a fresh two-phase subscription schedule (current until renewal; pending state from renewal with proration disabled and end_behavior release), clearing the scheduling metadata once the schedule exists.

* finalize: flag address-pending migrations and push the needs_to_update_address trait

When a migrated subscription carries metadata.addressPending, append -address-pending to the finalization status and push needs_to_update_address to customer.io (alongside the existing tax-info-pending handling), so the customer can be driven to add a billing address. The flag stays on the subscription so the customer.updated webhook can enable automatic_tax and clear it once the address resolves.

* webhook: heal address-pending migrations when the tax location resolves

On customer.updated (address/tax change), for a customer whose location is no longer unrecognized_location, enable automatic_tax on their migrated subscriptions still flagged metadata.addressPending and clear the flag. Enabling automatic_tax is rejected by Stripe while the location is still invalid, so the update is a safe idempotent no-op until the address is fixed; the cancellation state is never touched.

* cron: cancel unresolved address-pending subscriptions before they renew untaxed

Backstop for the address-pending cohort: searches the address-pending subscriptions in a region and, for any about to renew (within a configurable lead window) whose customer location is still unrecognized_location, cancels it at period end so it never renews untaxed. Skips subscriptions that are already cancelling and those whose location has resolved (healed by the webhook). Dry-run unless --commit.

* upsert: set tax.validate_location=auto on customer update

Conform PAN-copied customers to the account's default tax-location validation. Uses 'auto' rather than 'immediately' (which throws for country-only addresses and would break the address-pending migration flow).

* finalize-migration: send payment method info to customer.io

Add payment_method (card/paypal/none) and needs_to_add_payment_method
traits to the stripe_migration customer.io payload so the migration
email campaign can personalise per payment method without enumerating
the full cross-join. The payment method is read from the already-fetched
customer/subscription (default_payment_method now expanded on that fetch),
so no extra Stripe request is made. Also report a -payment-method-pending
status suffix in the CSV output.

* upsert: flag customers whose address Stripe cannot resolve

After pushing the Recurly address, read customer.tax.automatic_tax; when it is 'unrecognized_location', record address_unrecognized in the output so the subscription is migrated untaxed (address-pending) instead of failing at the billing-migration toolkit. This is the authoritative, region-agnostic detector (covers US/CA country-only and broken non-US addresses, e.g. India with a postal but no state/city). Adds isCustomerAddressUnrecognized helper + unit tests.

* Close reactivation-without-valid-address loophole

* webhook: detect newly-set address/tax with !== undefined

Review follow-up: the address-pending heal guard used a truthy check, which
would miss an address newly set from empty. Harmonise with _billingChanges,
which already uses !== undefined.

* upsert: set tax.validate_location via customerParams

Review follow-up: move the tax.validate_location='auto' directive into the
assembled customerParams instead of overriding it inline at the update call,
so it also appears in the dry-run output.

* create_coupons: guard migration coupons against ambiguous discount specs

Review follow-up: throw a clear per-coupon error if a migration coupon spec
has neither or both of amount_off/percent_off, catching data-processing
issues instead of silently sending percent_off=NaN.

* Rely on presence of customer.tax

* webhook: cover the address-pending heal path in unit tests

The customer.updated fixtures carried no `tax` hash and the mocked region
client had no `stripe` property, so the one test that reached the heal branch
threw and was swallowed by the caller's error handler. The heal logic had no
real coverage as a result.

Add the missing fixture fields and tests covering the heal itself, the
still-unrecognized early return, the skip rules for unflagged and cancelled
subscriptions, the Stripe rejection path that leaves the flag set, and the
missing-tax guard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
GitOrigin-RevId: 8162e3e0f01e136d3aa560c22e98f43e36da4eb5
2026-09-17 11:58:48 +00:00
Brian Gough 446c4f3f6a Merge pull request #35899 from overleaf/bg-custom-multer-workaround
add custom multer upload handler to prevent leaked files

GitOrigin-RevId: 7b390d326b4cf81fd82c532c53e9772cb4107a29
2026-09-17 11:58:42 +00:00
Andrew Rumble 44753a2a50 Merge pull request #36606 from overleaf/ar/log-relativePath
[web] log relativePath in uploadFiles endpoint

GitOrigin-RevId: d30cace4632c6c1b70aad2c84a2a6f470ef2ffa8
2026-09-17 11:58:39 +00:00
Domagoj Kriskovic ce194c9752 Use named <a> in feedback link Trans and themed-links mixin
GitOrigin-RevId: 812beaa01376c8ce0a423ba4cf1ae25581396fbb
2026-09-17 11:58:36 +00:00
Domagoj Kriskovic d7b4ef33ed Add "New" badge to library nav link and a feedback link on the library page
GitOrigin-RevId: 6c936ca8168dd718c4eaf806f426d5c00078add8
2026-09-17 11:58:32 +00:00
Brian Gough a4b9b18109 Merge pull request #36402 from overleaf/bg-zod-move-safe-path-tests
move safe path tests from zodHelpers to web

GitOrigin-RevId: 3bb25fa108a4a0da0bed1ae60fabfdd47ed76283
2026-09-17 11:58:29 +00:00