Skip to content

WIP - Worktree fxa 13072#20353

Draft
dschom wants to merge 68 commits intomainfrom
worktree-FXA-13072
Draft

WIP - Worktree fxa 13072#20353
dschom wants to merge 68 commits intomainfrom
worktree-FXA-13072

Conversation

@dschom
Copy link
Copy Markdown
Contributor

@dschom dschom commented Apr 10, 2026

Because

This pull request

Issue that this pull request solves

Closes: (issue number)

Checklist

Put an x in the boxes that apply

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).
  • I have manually reviewed all AI generated code.

How to review (Optional)

  • Key files/areas to focus on:
  • Suggested review order:
  • Risky or complex parts:

Screenshots (Optional)

Please attach the screenshots of the changes made in case of change in user interface.

Other information (Optional)

Any other information that is important to this pull request.

dependabot bot and others added 30 commits April 8, 2026 15:58
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.2 to 1.4.0.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](digitalbazaar/forge@v1.3.2...v1.4.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.4.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Because:
 - The `account.recovery_codes_set` event name is not in the db
 - And that causes the recording of the event to fail

This Commit:
 - Adds the missing event name to the db
 - Fixes type issue so these are caught sooner

Closes: FXA-13351
Because:
 - We currently use a list of exact matching emails to allow bypassing verification emails

This Commit:
 - Adds a regex variable option to make bypassing a bit more flexible
 - Leaves old variable in place so we don't break existing functionality until code is live and webservices-infra is updated
 - Adds tests
… code

Because:
* We want to drive more users to install the Firefox mobile app

This commit:
* Updates the ff-logo SVG as it was out of date
* Adds a new QR code image and displays it in the lower-right hand corner for desktop users in a web integration flow, on authentication pages
* Adds a new Glean view event for the promo
* Updates stories and adds tests

closes FXA-13279
Because:
* We want to log granted scope info when access tokens are created

This commit:
* Adds a new 'scopes' option for the oauth token created Glean event

closes FXA-13288
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.12 to 1.1.13.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](juliangruber/brace-expansion@v1.1.12...v1.1.13)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Because:

- Passwordless OTP accounts were not receiving the Welcome to
  product_name email due to a legacy check in stripe-webhooks that
  checked if the account was a passwordless email/password stub account.

This commit:

- Removes the legacy check for passwordless email/password stub
  accounts, since these types of accounts are no longer supported.

Closes #PAY-3592
…risk

Remove the mysql-patcher npm dependency and vendor the library as a
modernized async/await ESM module into lib/mysql-patcher.js. Replaces
async, bluebird, clone, glob, and xtend with native equivalents. Adds
project.json with nx test-unit, test-integration, and lint targets.
Adds eslint config extending root, prettier formatting, and jest config.
Includes 15 unit tests and 7 integration tests.

Rewrites check-db-patcher.sh to poll PM2 logs directly instead of
using pgrep, fixing the race condition where the patcher finishes
before the script can find the process. Strips ANSI escape codes
from log output for clean patch summary display.
…et cancelled_for_customer_at

Because:

* When upgrading a subscription that has previously been set to cancel but has not cancelled yet, the metadata field cancelled_for_customer_at is not unset even though we uncancel the subscription as part of the upgrade process.

This commit:

* Removes cancelled_for_customer_at on subscription upgrade.

Closes #[PAY-3586](https://mozilla-hub.atlassian.net/browse/PAY-3586)
Because:

* Customers need to be alerted before their free trial ends

This commit:

* Adds in the new reminder logic and new email for the FreeTrialEnding email

Closes #PAY-3549
Because:
* Claude Code workflows lacked Jira description skills and proactive skill suggestions
* .claude folder was hidden in VS Code due to files.exclude entry
* CLAUDE.md was missing scope discipline and commit format guidance

This commit:
* Adds fxa-jira-feature-description and fxa-jira-bug-description skills
* Adds scope discipline rule to CLAUDE.md
* Adds git commit message format reference to CLAUDE.md
* Adds available skills table to CLAUDE.md with proactive suggestion instruction
* Removes .claude from VS Code files.exclude so skills are visible
…x for non-US customers

Because:

* In the subscription renewal reminder emails, European customers are being shown the prices as “€(base amount) + €(tax amount) tax”. This is a pattern that should only be shown to US customers.

This commit:

* Uses Stripe's total_tax_amounts[].inclusive to determine whether to show the customer a single total or a breakdown of base amount + tax.

Closes #[PAY-3601](https://mozilla-hub.atlassian.net/browse/PAY-3601)
Because:

* we need passkey management API endpoints

This commit:

* creates passkey management API endpoints

Closes FXA-13070
…n-in page

For passwordless Sync accounts on mobile (Firefox iOS), the cached
signin page was stuck after clicking "Sign in" because performNavigation
was false and no webchannel messages were sent. Allow in-webview
navigation to the set-password page for these accounts.
Because:

* Non-transparent CMS header in split layout covers card content

This commit:

* only set header positioning to absolute when header background is set
* adds a small top margin to the card to ensure a gap between the card and the header

Closes FXA-13319
Because:
 - We want to better understand what downstream consumers are of
   amplitude
 - And we need to understand what duplicate logging might not exist

This Commit:
 - Adds a guard clause to the amplitude logging to return early if
   disabled
 - Adds tests to make sure it works

Closes: FXA-13374
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.8.10 to 0.8.12.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](xmldom/xmldom@0.8.10...0.8.12)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-version: 0.8.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Because:

- Firefox non-sync RPs are redirect to Settings and are not signed
  into the browser, but not sync.

This commit:

- Updates OTP signup for Firefox non-sync RPs so that users are signed
  into the browser and redirected to the approrpiate page.

Closes #FXA-13114
vbudhram and others added 30 commits April 8, 2026 15:58
Because:
- The Engage event on the passwordless OTP screen fired immediately on
  page load due to autoFocus triggering the onFocus handler, before the
  View event and without any user interaction
- There was no tracking for when users click "Use a different account"
  on the OTP code page
- The statsd passwordless.sendCode.success metric did not distinguish
  signup from signin

This commit:
- Adds onChangeCb prop to FormVerifyCode so callers can hook into input
  changes without hijacking setClearMessages
- Uses onChangeCb for the Glean OTP engage metric, fixing the autoFocus
  timing issue
- Emits change email event when user clicks "Use a different account"
  on the OTP page
- Adds isNewAccount tag to passwordless.sendCode.success statsd metric

Closes: FXA-13393
Because:

* v7 was deprecated and unmaintained

This commit:

* Upgrades to v8 for all packages

Closes #FXA-8765
Bumps [bn.js](https://github.com/indutny/bn.js) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/indutny/bn.js/releases)
- [Changelog](https://github.com/indutny/bn.js/blob/master/CHANGELOG.md)
- [Commits](indutny/bn.js@v5.2.2...v5.2.3)

---
updated-dependencies:
- dependency-name: bn.js
  dependency-version: 5.2.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [yauzl](https://github.com/thejoshwolfe/yauzl) from 3.2.0 to 3.3.0.
- [Commits](thejoshwolfe/yauzl@3.2.0...3.3.0)

---
updated-dependencies:
- dependency-name: yauzl
  dependency-version: 3.3.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Because:

- Passwordless OTP tests were not correctly configured to run in
  production due to hard coded relier client id.

This commit:

- Update Passwordless OTP tests to use target.relierClientID instead of
  hard coded value.

Closes #FXA-13401
Because:
 - We want to record event latency in event-broker
 - And we previously using changeTime, which is not correct

This Commit:
 - Uses timestamp on the message event to correctly record the event
   lattency

Closes: FXA-13395
…ndored lib

Migrate fxa-settings and fxa-content-server off the stale npm package
(v0.0.4, last published 2018) to the in-repo @fxa/vendored/common-password-list.
Adds webpack aliases for content-server and Jest moduleNameMapper for
fxa-settings, and removes the npm dependency.
Because:

* we need to use these endpoints in settings

This commit:

* add these methods to auth-client
* adds more fields in the response of /passkey/registration/finish

Closes FXA-13071
Because:

* Account.refresh makes unnecessary calls to the backend in the 'account' case, when /account and /attached_client should provide all info needed

This commit:

* removes unnecesssary calls

Closes FXA-13384
Because:

* getStripeSubscriptions (in admin server) loads subscriptions for an account, fetches each subscription's latest_invoice from the Stripe API, and when Stripe returns "No such invoice", the code returns and stops processing the rest of the subscriptions for that account, leading to missing subscriptions in the admin panel.

This commit:

* Continues instead of returning to skip the subscription with missing things and keep processing the rest.
* Displays the subscription, just without invoice information.

Closes # [PAY-3457](https://mozilla-hub.atlassian.net/browse/PAY-3457)
Because:

* Latest Firebase docker image adds cache

This commit:

* Gitignore cache files

Closes #
Because:
* Telegraf's statsd input plugin only accepts non-negative values for
  histograms
* The delta from otplib's checkDelta can be negative (e.g. -1 when the
  user enters a code from the previous time window)
* The previous guard `if (type && delta)` skipped recording when
  delta === 0, silently dropping the most common exact-match case

This commit:
* Offsets delta by the configured window size so values are always
  non-negative (with window=1: -1→0, 0→1, 1→2)
* Fixes the falsy check to use `delta !== undefined && delta !== null`
  so delta=0 is recorded
* Guards against undefined otpOptions with optional chaining

Fixes #13356
Because:

- Some customers are experiencing CSP errors related to connect-src
  missing some values.

This commit:

- Adds auth-server and profile-server env vars to connect-src csp.
- Adds logic for Security Policy Reporting to Sentry

Closes #PAY-3483
Because:

* Allow testing registration separately from authentication

This commit:

* Adds registrationEnabled and authenticationEnabled flags and uses the existing flag as a master switch

Closes #FXA-13398
Bumps [yaml](https://github.com/eemeli/yaml) from 1.10.2 to 1.10.3.
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](eemeli/yaml@v1.10.2...v1.10.3)

---
updated-dependencies:
- dependency-name: yaml
  dependency-version: 1.10.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…t page

Because:

* We need to add a Free Trials section to the Sub Manage page so that a customer can see what free trials they have.

This commit:

* Adds a new Free Trial section and component, to be rendered on the Subscription Management page, akin to “Payment details” and “Active subscriptions”, that is only rendered if a user has an active trialing subscription.
* If the free trial is active, includes details about their upcoming billing cycle, and the option to cancel their free trial
* If the free trial could not be converted due to a failed payment method, includes invoice details, and the option to update their payment info
* Implements UI for both Desktop and Mobile views

Closes #[PAY-3547](https://mozilla-hub.atlassian.net/browse/PAY-3547)
Because:

* sometimes a cleanup job gets cancelled due to concurrency settings

This commit:

* turns storybook cleanup into a daily cronjob that searches through all PRs stored and cleanup closed ones
Because:

* FxA has several webhooks that SubPlat can make use of

This commit:

* Adds a FxaWebhookService class
* Adds routes to the payments-api service to receive webhooks
* Adds validations to only handle valid webhook requests

Closes #PAY-3464
Remove Mocha test runner and migrate all remaining integration tests to
Jest. Split the single CI integration job into separate integration and
scripts jobs. Clean up dead code, migration comments, and stale frozen-file
rules for deleted Mocha tests.
Because:
 - There is a chance that a build will generate a ftl hash that matches another

This Commit:
 - Adds a hashFunction to the grunt step for generating the files using the CIRCLE_WORKFLOW_ID to ensure a unique hash from each build

Closes: FXA-13363
Because:
 - There's a bug where a user can be signed out after changing password

This Commit:
 - Fixes the issue by providing the proper sessionVerified property in
   the API response for the client to cache

Closes: FXA-13355
Because:

* When a user upgrades a subscription, we update their subscription in Stripe. By default, a user's free trial remains attached to the subscription after its update.
* A user can use this to obtain a free trial on an upgraded subscription, regardless of that subscription's free trial eligibility

This commit:

* Cancels a free trial when the user upgrades their subscription by setting the trial's end time to "now"
* Adds in warning messaging to the upgrade page alerting the user to the fact that they will be billed the full amount

Closes #PAY-3602
…pair

Because:
* The send tab flow will use the service=sync flow, but with Send Tab specific entrypoints. For this flow, we want to always take users to the /pair page (choice screen)

This commit:
* Skips the inline_recovery_key_flow for Sync signins with the Send Tab entrypoint, uses existing success message
* Skips the sync_signup_confirmed screen for Sync signups with the Send Tab entrypoint, updates the success message
* Skips the sync_signup_confirmed screen for passwordless users signing up for Sync with the Send Tab entrypoint, updates the success message

closes FXA-13397
… OTP verify

Because:
* 6-digit OTP codes are vulnerable to distributed brute-force without
  email-scoped limits
* We need production data on per-email verification volume before
  switching from report to block mode

This commit:
* Add passwordlessVerifyOtp email-scoped rule (10 per 10min, report)
* Add passwordlessVerifyOtpPerDay email-scoped rule (20 per 24h, report)

Closes #FXA-13331
…gql:allowlist build steps

Remove unused GraphQL decorators, shared GQL utilities, allowlist
generation config, and gql:allowlist calls from build/start scripts.
Because:

* buildPasskeyConfig validated rpId and allowedOrigins unconditionally, causing auth-server to crash at startup on any environment where passkeys is disabled but the required fields are left at their Convict defaults (empty string / empty array)

This commit:

* Adds @ValidateIf((o) => o.enabled) to rpId and allowedOrigins in PasskeyConfig so those constraints are skipped when the feature is off
* Wraps the buildPasskeyConfig call in key_server.js with try/catch so that misconfigured-but-enabled passkeys logs via log.error (structured mozlog) before exiting, instead of falling through to console.error
* Adds a test asserting that disabled passkeys with empty defaults no longer throws

Closes #FXA-13378
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.