Skip to content

fix(js): Coalesce concurrent first/second factor preparations#9225

Open
tmilewski wants to merge 14 commits into
mainfrom
tom/fix-concurrent-second-factor-prepare
Open

fix(js): Coalesce concurrent first/second factor preparations#9225
tmilewski wants to merge 14 commits into
mainfrom
tom/fix-concurrent-second-factor-prepare

Conversation

@tmilewski

@tmilewski tmilewski commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

  • Coalesce identical concurrent first- and second-factor preparation requests during sign-in, sign-up, and user-profile verification
  • Keep requests for different factors and authentication attempts independent

Why

Concurrent consumers could prepare the same verification factor more than once, sending duplicate one-time codes and invalidating the code the user received first.

Testing

  • Added Vitest coverage for identical and distinct preparations, retries, future APIs, cross-attempt isolation, sign-up and profile verification, and stalled-request expiry
  • Verified the Clerk JS test suite, declaration build, and lint checks

@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jul 23, 2026 7:36pm
swingset Ready Ready Preview, Comment Jul 23, 2026 7:36pm

Request Review

@changeset-bot

changeset-bot Bot commented Jul 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 30e121c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@clerk/clerk-js Patch
@clerk/chrome-extension Patch
@clerk/electron Patch
@clerk/expo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9225

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9225

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9225

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9225

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9225

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9225

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9225

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9225

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9225

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9225

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9225

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9225

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9225

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9225

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9225

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9225

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9225

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9225

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9225

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9225

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9225

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9225

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9225

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9225

commit: 30e121c

@tmilewski tmilewski changed the title Coalesce concurrent sign-in factor preparations fix(js): Coalesce concurrent sign-in factor preparations Jul 23, 2026
@tmilewski tmilewski self-assigned this Jul 23, 2026
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-07-23T19:37:44.465Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 1
🔴 Breaking changes 0
🟡 Non-breaking changes 1
🟢 Additions 0

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/backend

Current version: 3.12.0
Recommended bump: MINOR → 3.13.0

Subpath ./proxy

🟡 Non-breaking Changes (1)

Modified: FrontendApiProxyOptions.fapiUrl
- fapiUrl?: string;

Static analyzer: Removed property FrontendApiProxyOptions.fapiUrl

🤖 AI review (reclassified as non-breaking) (85%): The removed property fapiUrl was optional (fapiUrl?: string), so no existing well-typed consumer was required to provide it; removing it only prevents consumers from passing it, which would have been silently ignored anyway (excess property checks aside, but as an interface input field removal it means callers that did pass it will now get a compile error). Wait — callers who explicitly set fapiUrl on an object of type FrontendApiProxyOptions will get a type error after removal.


Report generated by Break Check

Last ran on 30e121c.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

BaseResource now supports optional coalescing for concurrent POST mutations, including deterministic request keys, pending-request TTL handling, abort controllers, and AbortSignal forwarding. Verification preparation calls across sign-in, sign-up, email, phone, and web3 flows enable this behavior. Tests cover shared requests, differing inputs, cleanup after completion or failure, TTL expiry, and signal propagation. A patch Changesets entry was added.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: coalescing concurrent factor-preparation requests.
Description check ✅ Passed The description matches the implemented changes and testing coverage described in the PR.

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

@tmilewski tmilewski changed the title fix(js): Coalesce concurrent sign-in factor preparations fix(js): Coalesce concurrent first/second factor preparations Jul 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/clerk-js/src/core/resources/__tests__/Web3Wallet.test.ts (1)

37-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the untyped deferred response.

Use the concrete response shape so this fixture catches invalid mock payloads.

Proposed fix
-    const deferred = createDeferredPromise<any>();
+    const deferred = createDeferredPromise<{ response: Web3WalletJSON }>();

As per coding guidelines, “Avoid any type - prefer unknown when type is uncertain.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/clerk-js/src/core/resources/__tests__/Web3Wallet.test.ts` at line
37, Replace the any type in the createDeferredPromise fixture within Web3Wallet
tests with the concrete response type expected by the tested wallet resource.
Ensure the deferred promise and its resolved mock payload are type-checked
against that response shape, rather than using unknown or another untyped
fallback.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/clerk-js/src/core/resources/__tests__/Web3Wallet.test.ts`:
- Line 37: Replace the any type in the createDeferredPromise fixture within
Web3Wallet tests with the concrete response type expected by the tested wallet
resource. Ensure the deferred promise and its resolved mock payload are
type-checked against that response shape, rather than using unknown or another
untyped fallback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 7c614ce2-8737-427f-a57b-1c6decd84a9b

📥 Commits

Reviewing files that changed from the base of the PR and between 59bf726 and 30e121c.

📒 Files selected for processing (4)
  • packages/clerk-js/src/core/resources/Base.ts
  • packages/clerk-js/src/core/resources/__tests__/EmailAddress.test.ts
  • packages/clerk-js/src/core/resources/__tests__/SignIn.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Web3Wallet.test.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
  • clerk/clerk-ios (auto-detected)
  • clerk/cli (auto-detected)
  • clerk/clerk-android (auto-detected)
💤 Files with no reviewable changes (1)
  • packages/clerk-js/src/core/resources/Base.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/clerk-js/src/core/resources/tests/SignIn.test.ts

@tmilewski
tmilewski requested a review from a team July 23, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant