Skip to content

Conversation

@bratsos
Copy link
Member

@bratsos bratsos commented Sep 1, 2025

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Improved resilience during origin outages: automatic token retry using the last-active token and handshake redirects that include session info when available.
  • Tests

    • Added coverage for origin-outage fallback, expired-token retry behavior, token creation with search parameters, and handshake URL/session handling.
  • Public API

    • Added a MissingExpiredToken error type, exposed a session query constant, and updated token creation to accept explicit search parameters.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Sep 1, 2025

🦋 Changeset detected

Latest commit: 8b2a3dc

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

This PR includes changesets to release 13 packages
Name Type
@clerk/clerk-js Minor
@clerk/backend Minor
@clerk/chrome-extension Patch
@clerk/expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing 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

@vercel
Copy link

vercel bot commented Sep 1, 2025

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

Project Deployment Review Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Dec 19, 2025 6:38pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 1, 2025

📝 Walkthrough

Walkthrough

Adds a new MissingExpiredTokenError class and exports it; changes Token.create to accept a search/search-parameters object and always pass body and search to fetch; updates Session to use lastActiveToken and retry with expired_token on 422 missing_expired_token errors; adds Session: '__session' query constant; updates HandshakeService to append the Session query parameter when authenticateContext.sessionToken exists; adds tests and a changeset.

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main feature being added: support for origin outage mode functionality across backend and clerk-js packages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

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

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 83ba391 and 8b2a3dc.

📒 Files selected for processing (1)
  • packages/shared/src/errors/missingExpiredTokenError.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

All code must pass ESLint checks with the project's configuration

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*.{js,jsx,ts,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Follow established naming conventions (PascalCase for components, camelCase for variables)

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
packages/**/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

packages/**/src/**/*.{ts,tsx,js,jsx}: Maintain comprehensive JSDoc comments for public APIs
Use tree-shaking friendly exports
Validate all inputs and sanitize outputs
All public APIs must be documented with JSDoc
Use dynamic imports for optional features
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Implement proper logging with different levels

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*.ts?(x)

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details in classes
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Use mixins for shared behavior across unrelated classes in TypeScript
Use generic constraints with bounded type parameters like <T extends { id: string }>
Use utility types like Omit, Partial, and Pick for data transformation instead of manual type construction
Use discriminated unions instead of boolean flags for state management and API responses
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation at the type level
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Document functions with JSDoc comments including @param, @returns, @throws, and @example tags
Create custom error classes that extend Error for specific error types
Use the Result pattern for error handling instead of throwing exceptions
Use optional chaining (?.) and nullish coalescing (??) operators for safe property access
Let TypeScript infer obvious types to reduce verbosity
Use const assertions with as const for literal types
Use satisfies operator for type checking without widening types
Declare readonly arrays and objects for immutable data structures
Use spread operator and array spread for immutable updates instead of mutations
Use lazy loading for large types...

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use ESLint with custom configurations tailored for different package types

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*.{js,ts,jsx,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use Prettier for code formatting across all packages

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
**/*

⚙️ CodeRabbit configuration file

If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.

**/*: Only comment on issues that would block merging, ignore minor or stylistic concerns.
Restrict feedback to errors, security risks, or functionality-breaking problems.
Do not post comments on code style, formatting, or non-critical improvements.
Keep reviews short: flag only issues that make the PR unsafe to merge.
Group similar issues into a single comment instead of posting multiple notes.
Skip repetition: if a pattern repeats, mention it once at a summary level only.
Do not add general suggestions, focus strictly on merge-blocking concerns.
If there are no critical problems, respond with minimal approval (e.g., 'Looks good'). Do not add additional review.
Avoid line-by-line commentary unless it highlights a critical bug or security hole.
Highlight only issues that could cause runtime errors, data loss, or severe maintainability issues.
Ignore minor optimization opportunities, focus solely on correctness and safety.
Provide a top-level summary of critical blockers rather than detailed per-line notes.
Comment only when the issue must be resolved before merge, otherwise remain silent.
When in doubt, err on the side of fewer comments, brevity and blocking issues only.
Avoid posting any refactoring issues.

Files:

  • packages/shared/src/errors/missingExpiredTokenError.ts
🧬 Code graph analysis (1)
packages/shared/src/errors/missingExpiredTokenError.ts (1)
packages/shared/src/error.ts (3)
  • MissingExpiredTokenError (6-6)
  • ClerkAPIResponseError (4-4)
  • isClerkAPIResponseError (4-4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
packages/shared/src/errors/missingExpiredTokenError.ts (1)

1-45: Looks good.

The error class is well-structured with proper type guards and comprehensive documentation. No blocking issues found.


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

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 3a21810 to 0b098e5 Compare October 21, 2025 16:22
@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 0b098e5 to f347347 Compare October 28, 2025 21:17
@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from f347347 to 929883f Compare November 3, 2025 10:50
@bratsos bratsos marked this pull request as ready for review November 3, 2025 11:03
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/backend/src/tokens/handshake.ts (1)

152-154: Verify security implications of passing session tokens in URL query parameters.

Passing session tokens as query parameters can expose them through:

  • Browser history and autocomplete
  • Server access logs
  • Referer headers when navigating to external sites
  • Network monitoring tools
  • Proxy logs

If this is intentional for the handshake flow (e.g., for cookie-less environments or cross-origin scenarios), ensure that:

  1. The token has a very short TTL
  2. It's single-use/nonce-based
  3. The endpoint validates and immediately invalidates it
  4. Documentation warns developers about the security trade-offs

Additionally, using constants.Cookies.Session as a URL query parameter name (not a cookie) may be confusing. Consider whether a separate constant like constants.QueryParameters.Session would be clearer.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5b85ea9 and 929883f.

📒 Files selected for processing (6)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
packages/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Unit tests should use Jest or Vitest as the test runner.

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
packages/{clerk-js,elements,themes}/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Visual regression testing should be performed for UI components.

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
🧬 Code graph analysis (5)
packages/backend/src/tokens/__tests__/handshake.test.ts (1)
packages/backend/src/tokens/handshake.ts (1)
  • HandshakeService (84-360)
packages/backend/src/tokens/handshake.ts (1)
packages/backend/src/constants.ts (1)
  • constants (79-85)
packages/clerk-js/src/core/resources/Session.ts (1)
packages/clerk-js/src/core/resources/Token.ts (1)
  • Token (6-54)
packages/clerk-js/src/core/resources/__tests__/Session.test.ts (4)
packages/clerk-js/src/core/tokenCache.ts (1)
  • SessionTokenCache (407-407)
packages/clerk-js/src/core/events.ts (1)
  • eventBus (31-31)
packages/clerk-js/src/test/core-fixtures.ts (1)
  • clerkMock (249-256)
packages/clerk-js/src/core/resources/Session.ts (1)
  • Session (44-442)
packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2)
packages/clerk-js/src/test/core-fixtures.ts (1)
  • mockFetch (262-272)
packages/clerk-js/src/core/fapiClient.ts (1)
  • createFapiClient (80-299)
🔇 Additional comments (4)
packages/backend/src/tokens/__tests__/handshake.test.ts (1)

435-467: LGTM! Comprehensive test coverage for session token handling.

The tests properly verify both scenarios:

  1. Session token is included in the handshake URL when present
  2. Session token is excluded when absent (using toBeNull())

The test setup correctly creates isolated contexts and the assertions are accurate.

packages/clerk-js/src/core/resources/__tests__/Token.test.ts (1)

108-147: LGTM! Well-structured tests for the new search parameter support.

The test suite properly validates:

  1. Search parameters are correctly included in the API request URL
  2. Backward compatibility is maintained when search parameters are omitted

The assertions check both URL construction and request options, providing comprehensive coverage.

packages/clerk-js/src/core/resources/Session.ts (1)

2-2: LGTM! Well-implemented retry mechanism for origin outage mode.

The error handling logic correctly:

  1. Catches the specific error condition (422 with missing_expired_token code)
  2. Validates all preconditions before retrying (including array bounds check)
  3. Retries with the expired token passed as a search parameter
  4. Re-throws other errors without modification
  5. Maintains proper caching behavior (tokenResolver set before catch)

The implementation avoids infinite recursion since the retry uses different parameters, and the logic aligns with the comprehensive test coverage in Session.test.ts.

Also applies to: 408-419

packages/clerk-js/src/core/resources/__tests__/Session.test.ts (1)

1-1: LGTM! Comprehensive test coverage for origin outage mode fallback.

The test suite thoroughly validates the retry mechanism:

  1. Successful retry scenario: Verifies that when a 422 with missing_expired_token is returned and lastActiveToken exists, the code makes a second request with the expired token in the search parameters.

  2. Edge cases properly covered:

    • No retry when lastActiveToken is unavailable
    • No retry for non-422 HTTP errors
    • No retry when the error code differs

The test setup with spies on eventBus.emit and BaseResource._fetch is appropriate, and the assertions correctly validate both the number of fetch calls and the request shapes.

Also applies to: 1090-1235

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 929883f to 771560c Compare November 3, 2025 16:03
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 3, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@6678

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@6678

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 8b2a3dc

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

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

124-128: Consider adding body assertion for consistency.

The existing tests and the second test in this suite (lines 140-145) all assert body: '' in their expectations. For consistency, consider adding the same assertion here.

 expect(options).toMatchObject({
   method: 'POST',
+  body: '',
   credentials: 'include',
   headers: expect.any(Headers),
 });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 929883f and 771560c.

📒 Files selected for processing (6)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/tests/Session.test.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
packages/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Unit tests should use Jest or Vitest as the test runner.

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
packages/{clerk-js,elements,themes}/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Visual regression testing should be performed for UI components.

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
🧬 Code graph analysis (2)
packages/clerk-js/src/core/resources/__tests__/Token.test.ts (3)
packages/clerk-js/src/test/core-fixtures.ts (1)
  • mockFetch (262-272)
packages/clerk-js/src/core/fapiClient.ts (1)
  • createFapiClient (80-299)
packages/clerk-js/src/core/resources/Token.ts (1)
  • Token (6-54)
packages/backend/src/tokens/__tests__/handshake.test.ts (2)
packages/backend/src/tokens/handshake.ts (1)
  • HandshakeService (84-360)
packages/backend/src/constants.ts (1)
  • constants (79-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (4)
packages/backend/src/tokens/__tests__/handshake.test.ts (2)

435-450: LGTM! Well-structured test for session token passthrough.

The test correctly verifies that when a session token is present in the AuthenticateContext, it's properly appended to the handshake URL as a query parameter. Good test isolation by creating a dedicated service instance.


452-467: LGTM! Comprehensive negative test case.

This test properly verifies that when the session token is absent, the query parameter is not added to the handshake URL. Together with the previous test, this provides complete coverage for the session token passthrough feature.

packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2)

108-147: Good test coverage for the new search parameters feature.

The test suite properly covers both the new search parameters functionality and backward compatibility. The mock setup, assertions on URL construction, and request options verification are well-structured.


4-4: No issues found.

The import of mockJwt on line 4 is valid. The export exists in core-fixtures, and it is correctly used in the new test cases (lines 115 and 132) to mock API responses. Both new tests are well-structured: the first verifies search parameter inclusion in the URL, and the second ensures backward compatibility when no search parameters are provided.

@blacksmith-sh
Copy link

blacksmith-sh bot commented Nov 3, 2025

Found 23 test failures on Blacksmith runners:

Test View Logs
[chrome] › integration/tests/elements/
next-sign-in.test.ts:134:7 › Next.js Sign-In Flow @elements › long-running--elements.ne
xt.appRouter › can reset password
View Logs
[chrome] › integration/tests/elements/
otp.test.ts:196:9 › OTP @elements › long-running--elements.next.appRouter › Type: segme
nted-otp › should forward-delete char when pressing delete
View Logs
[chrome] › integration/tests/machine-auth/
api-keys.test.ts:184:7 › Next.js API key auth within routes @nextjs › should handle mul
tiple token types
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:110:9 › pricing table @billing › long-running--withBilling.astro.
node › when signed in flow › subscribes to a plan
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:110:9 › pricing table @billing › long-running--withBilling.next.a
ppRouter › when signed in flow › subscribes to a plan
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:110:9 › pricing table @billing › long-running--withBilling.vue.vi
te › when signed in flow › subscribes to a plan
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:221:7 › pricing table @billing › long-running--withBilling.astro.
node › user is prompted to add email before checkout
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:221:7 › pricing table @billing › long-running--withBilling.next.a
ppRouter › user is prompted to add email before checkout
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:250:7 › pricing table @billing › long-running--withBilling.next.a
ppRouter › starts free trial subscription for new user
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:456:9 › pricing table @billing › long-running--withBilling.vue.vi
te › in UserProfile › renders pricing table, subscribes to a plan, revalidates payment
method on complete and then downgrades to free
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:80:9 › pricing table @billing › long-running--withBilling.astro.n
ode › when signed in flow › when signed in, clicking get started button opens checkout
drawer and shows free plan as active
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:80:9 › pricing table @billing › long-running--withBilling.next.ap
pRouter › when signed in flow › when signed in, clicking get started button opens check
out drawer and shows free plan as active
View Logs
[chrome] › integration/tests/
pricing-table.test.ts:80:9 › pricing table @billing › long-running--withBilling.vue.vit
e › when signed in flow › when signed in, clicking get started button opens checkout dr
awer and shows free plan as active
View Logs
[chrome] › integration/tests/
session-tasks-multi-session.test.ts:33:9 › session tasks multi-session flow @nextjs › l
ong-running--next.appRouter.withSessionTasks › when switching sessions, navigate to tas
k
View Logs
[chrome] › integration/tests/
sign-in-flow.test.ts:101:7 › sign in flow @generic @nextjs › long-running--next.appRout
er.withEmailCodes › can reset password
View Logs
[chrome] › integration/tests/
sign-in-flow.test.ts:101:7 › sign in flow @generic @nextjs › long-running--next.appRout
er.withEmailCodes › can reset password
View Logs
[chrome] › integration/tests/
sign-in-flow.test.ts:101:7 › sign in flow @generic @nextjs › long-running--next.appRout
er.withEmailCodes › can reset password
View Logs
[chrome] › integration/tests/
sign-in-flow.test.ts:101:7 › sign in flow @generic @nextjs › long-running--next.appRout
er.withEmailCodes › can reset password
View Logs
[chrome] › integration/tests/
sign-in-flow.test.ts:101:7 › sign in flow @generic @nextjs › long-running--react.vite.w
ithEmailCodes › can reset password
View Logs
[chrome] › integration/tests/
sign-in-or-up-flow.test.ts:115:9 › sign-in-or-up flow @nextjs › long-running--next.appR
outer.withSignInOrUpFlow › sign-in › can reset password
View Logs
[chrome] › integration/tests/
sign-in-or-up-flow.test.ts:115:9 › sign-in-or-up flow @nextjs › long-running--next.appR
outer.withSignInOrUpFlow › sign-in › can reset password
View Logs
[chrome] › integration/tests/
sign-in-or-up-flow.test.ts:115:9 › sign-in-or-up flow @nextjs › long-running--next.appR
outer.withSignInOrUpFlow › sign-in › can reset password
View Logs
[setup] › integration/tests/
global.setup.ts:7:6 › start long running apps ─────────────────────
View Logs


Fix in Cursor

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 771560c to 11fb32b Compare November 3, 2025 16:27
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
packages/clerk-js/src/core/resources/Token.ts (2)

11-20: JSDoc documentation is still missing.

Despite being marked as addressed in a previous review, the create method lacks JSDoc documentation. The coding guidelines require "All public APIs must be documented with JSDoc."

Add comprehensive JSDoc comments above the method documenting:

  • The method's purpose and when to use it
  • Each parameter (path, body, search) with types and descriptions
  • The return value (Promise<TokenResource>)
  • Any errors that may be thrown

Example JSDoc structure:

/**
 * Creates a new token resource by making a POST request to the specified path.
 * 
 * @param path - The API endpoint path for token creation
 * @param body - The request body payload (default: empty object)
 * @param search - URL search/query parameters to include in the request (default: empty object)
 * @returns A promise that resolves to a TokenResource instance
 * @throws {Error} If the API request fails or returns an error
 */
static async create(path: string, body: unknown = {}, search: Record<string, string> = {}): Promise<TokenResource> {

As per coding guidelines


11-11: The body: any type violation persists.

Despite being marked as addressed in a previous review, the body parameter still uses the any type, which violates the coding guideline: "Avoid any type - prefer unknown when type is uncertain, then narrow with type guards."

Replace any with unknown or define a specific type/interface for the body parameter.

Apply this diff to replace any with unknown:

-  static async create(path: string, body: any = {}, search: Record<string, string> = {}): Promise<TokenResource> {
+  static async create(path: string, body: unknown = {}, search: Record<string, string> = {}): Promise<TokenResource> {

As per coding guidelines

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 771560c and 11fb32b.

📒 Files selected for processing (6)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/backend/src/tokens/tests/handshake.test.ts
  • packages/clerk-js/src/core/resources/tests/Session.test.ts
  • packages/clerk-js/src/core/resources/tests/Token.test.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/handshake.ts
🧬 Code graph analysis (1)
packages/backend/src/tokens/handshake.ts (1)
packages/backend/src/constants.ts (1)
  • constants (79-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build Packages
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 5f7f54b to 4a663f9 Compare November 12, 2025 11:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

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

408-419: Consider explicit type annotation for catch parameter.

The error handling logic is correct and defensive. However, explicitly typing the catch parameter would improve code clarity and align with TypeScript best practices.

Apply this diff:

-    const tokenResolver = Token.create(path, params).catch(e => {
+    const tokenResolver = Token.create(path, params).catch((e: unknown) => {
       if (
         e instanceof ClerkAPIResponseError &&
         e.status === 422 &&

As per coding guidelines

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7f54b and 4a663f9.

📒 Files selected for processing (6)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/clerk-js/src/core/resources/tests/Token.test.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
🧬 Code graph analysis (3)
packages/backend/src/tokens/__tests__/handshake.test.ts (2)
packages/backend/src/tokens/handshake.ts (1)
  • HandshakeService (84-360)
packages/backend/src/constants.ts (1)
  • constants (79-85)
packages/clerk-js/src/core/resources/Session.ts (1)
packages/clerk-js/src/core/resources/Token.ts (1)
  • Token (6-54)
packages/clerk-js/src/core/resources/__tests__/Session.test.ts (4)
packages/clerk-js/src/core/tokenCache.ts (1)
  • SessionTokenCache (407-407)
packages/clerk-js/src/core/events.ts (1)
  • eventBus (32-32)
packages/clerk-js/src/test/core-fixtures.ts (1)
  • clerkMock (249-256)
packages/clerk-js/src/core/resources/Session.ts (1)
  • Session (44-442)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build Packages
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
packages/backend/src/tokens/__tests__/handshake.test.ts (1)

435-467: LGTM! Comprehensive test coverage for sessionToken handling.

Both test cases properly validate the conditional inclusion of the session token in the handshake URL, with appropriate isolation and assertions.

packages/clerk-js/src/core/resources/__tests__/Session.test.ts (1)

1090-1235: LGTM! Excellent test coverage for origin outage mode fallback.

The test suite comprehensively validates all branches of the retry logic:

  • Successful retry path with expired_token query parameter on 422 with missing_expired_token code
  • No retry when lastActiveToken is unavailable
  • No retry for non-422 errors
  • No retry when error code differs

The test structure is clean, with proper setup/teardown, clear assertions, and good mock isolation.

@bratsos bratsos changed the title feat: Support origin outage mode feat(backend, clerk-js): Support origin outage mode Nov 12, 2025
@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 4a663f9 to 7dc1fa1 Compare November 12, 2025 11:24
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

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

1207-1234: Remove unnecessary type cast.

Line 1218 uses as unknown as SessionJSON when last_active_token is set to a valid token object. This cast is unnecessary and should be removed for type safety. The cast was needed in the test at line 1161 where last_active_token is null, but not here.

Apply this diff:

-      } as unknown as SessionJSON);
+      } as SessionJSON);

Otherwise, the test correctly validates that retry only occurs for the specific missing_expired_token error code, not other 422 errors.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4a663f9 and 7dc1fa1.

📒 Files selected for processing (7)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/bundlewatch.config.json (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/clerk-js/bundlewatch.config.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/clerk-js/src/core/resources/tests/Token.test.ts
  • packages/backend/src/tokens/tests/handshake.test.ts
  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/clerk-js/src/core/resources/Token.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
🧬 Code graph analysis (1)
packages/clerk-js/src/core/resources/__tests__/Session.test.ts (4)
packages/clerk-js/src/core/tokenCache.ts (1)
  • SessionTokenCache (407-407)
packages/clerk-js/src/core/events.ts (1)
  • eventBus (32-32)
packages/clerk-js/src/test/core-fixtures.ts (1)
  • clerkMock (249-256)
packages/clerk-js/src/core/resources/Session.ts (1)
  • Session (44-442)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (33)
  • GitHub Check: Integration Tests (nextjs, chrome, 15, RQ)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Unit Tests (22, shared, clerk-js, RQ)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Static analysis
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (5)
packages/clerk-js/src/core/resources/__tests__/Session.test.ts (5)

1-1: LGTM! Import supports the new error handling tests.

The import of ClerkAPIResponseError is correctly added to support the new origin outage mode fallback tests.


1090-1105: LGTM! Proper test suite setup and teardown.

The test suite setup correctly initializes spies on eventBus.emit and BaseResource._fetch, and the teardown ensures proper cleanup by restoring spies and clearing the clerk instance.


1107-1148: LGTM! Comprehensive test of retry logic.

This test correctly validates the origin outage mode fallback behavior: when the API returns a 422 with missing_expired_token and a lastActiveToken exists, the request is retried with the expired token as a search parameter. The assertions verify both the initial request and the retry request parameters.


1150-1179: LGTM! Validates no retry without lastActiveToken.

This test correctly verifies that when lastActiveToken is not available, the request fails without attempting a retry, even when the API returns a 422 with missing_expired_token.


1181-1205: LGTM! Validates retry is specific to 422 errors.

This test correctly verifies that the retry logic is only triggered for 422 status codes, ensuring that other error responses (like 400) are not retried even when a lastActiveToken is available.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/backend/src/constants.ts (1)

27-40: The __session query parameter does expose the actual session token—ensure the parameter is stripped from the URL after the handshake exchange completes.

The code appends the session token directly to query parameters in buildRedirectToHandshake(), which sends it to the Clerk backend. While other handshake parameters (Handshake, HandshakeHelp, DevBrowser, HandshakeNonce) are deleted from the redirect URL in development mode, the Session parameter is missing from this cleanup logic. This leaves the token exposed in browser history and potential logs until it's replaced by secure cookies. Add newUrl.searchParams.delete(constants.QueryParameters.Session); to the parameter cleanup, and verify integration tests confirm the parameter is removed after the cookie exchange.

🧹 Nitpick comments (1)
packages/backend/src/constants.ts (1)

27-40: Prefer Cookies.Session over duplicating '__session' in QueryParameters.
Keeps the “same value” guarantee true over time (and matches the comment on Line 31).

 const QueryParameters = {
   ClerkSynced: '__clerk_synced',
   SuffixedCookies: 'suffixed_cookies',
   ClerkRedirectUrl: '__clerk_redirect_url',
   // use the reference to Cookies to indicate that it's the same value
   DevBrowser: Cookies.DevBrowser,
   Handshake: Cookies.Handshake,
   HandshakeHelp: '__clerk_help',
   LegacyDevBrowser: '__dev_session',
   HandshakeReason: '__clerk_hs_reason',
   HandshakeNonce: Cookies.HandshakeNonce,
   HandshakeFormat: 'format',
-  Session: '__session',
+  Session: Cookies.Session,
 } as const;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ffe0e08 and a40d623.

📒 Files selected for processing (2)
  • packages/backend/src/constants.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/backend/src/tokens/handshake.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

All code must pass ESLint checks with the project's configuration

Files:

  • packages/backend/src/constants.ts
**/*.{js,jsx,ts,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/backend/src/constants.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/backend/src/constants.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Follow established naming conventions (PascalCase for components, camelCase for variables)

Files:

  • packages/backend/src/constants.ts
packages/**/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

packages/**/src/**/*.{ts,tsx,js,jsx}: Maintain comprehensive JSDoc comments for public APIs
Use tree-shaking friendly exports
Validate all inputs and sanitize outputs
All public APIs must be documented with JSDoc
Use dynamic imports for optional features
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Implement proper logging with different levels

Files:

  • packages/backend/src/constants.ts
**/*.ts?(x)

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

Files:

  • packages/backend/src/constants.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details in classes
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Use mixins for shared behavior across unrelated classes in TypeScript
Use generic constraints with bounded type parameters like <T extends { id: string }>
Use utility types like Omit, Partial, and Pick for data transformation instead of manual type construction
Use discriminated unions instead of boolean flags for state management and API responses
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation at the type level
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Document functions with JSDoc comments including @param, @returns, @throws, and @example tags
Create custom error classes that extend Error for specific error types
Use the Result pattern for error handling instead of throwing exceptions
Use optional chaining (?.) and nullish coalescing (??) operators for safe property access
Let TypeScript infer obvious types to reduce verbosity
Use const assertions with as const for literal types
Use satisfies operator for type checking without widening types
Declare readonly arrays and objects for immutable data structures
Use spread operator and array spread for immutable updates instead of mutations
Use lazy loading for large types...

Files:

  • packages/backend/src/constants.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use ESLint with custom configurations tailored for different package types

Files:

  • packages/backend/src/constants.ts
**/*.{js,ts,jsx,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use Prettier for code formatting across all packages

Files:

  • packages/backend/src/constants.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from a40d623 to c477def Compare December 12, 2025 12:34
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
packages/clerk-js/src/core/resources/Session.ts (1)

401-408: Fix Token.create(..., search) typing; don’t pass undefined (and decide skip-cache on retry).
This repeats a concern from earlier review: Token.create takes search: Record<string, string> = {}, so undefined is an avoidable TS footgun, and the retry currently ignores the debug=skip_cache flag.

-    const tokenResolver = Token.create(path, params, skipCache ? { debug: 'skip_cache' } : undefined).catch(e => {
+    const search: Record<string, string> = skipCache ? { debug: 'skip_cache' } : {};
+
+    const tokenResolver = Token.create(path, params, search).catch(e => {
       if (MissingExpiredTokenError.is(e) && lastActiveToken) {
-        return Token.create(path, { ...params }, { expired_token: lastActiveToken });
+        return Token.create(path, { ...params }, { ...search, expired_token: lastActiveToken });
       }
       throw e;
     });
#!/bin/bash
# Verify TS strictness expectations and ensure no other callers pass `undefined` for `search`.
rg -n "strictNullChecks|\"strict\"\s*:" -S packages/clerk-js/tsconfig*.json tsconfig*.json || true
rg -nP "Token\.create\([^)]*,\s*[^)]*,\s*undefined\s*\)" --type=ts -S packages/clerk-js/src || true
packages/clerk-js/src/core/resources/Token.ts (1)

12-18: Token.create uses any and lacks JSDoc documentation.

The body parameter violates the type safety guidelines (avoid any), and as a public API method on an exported class, it requires comprehensive JSDoc comments including parameter, return, and error documentation per the coding guidelines.

 export class Token extends BaseResource implements TokenResource {
   pathRoot = 'tokens';

   jwt?: JWT;

+  /**
+   * Create (mint) a token via FAPI.
+   *
+   * @param path - FAPI path to mint the token from.
+   * @param body - POST body payload.
+   * @param search - Query-string parameters (e.g. debug flags, expired token recovery).
+   * @returns The minted token resource.
+   * @throws ClerkAPIResponseError on non-2xx responses.
+   */
-  static async create(path: string, body: any = {}, search: Record<string, string> = {}): Promise<TokenResource> {
+  static async create(
+    path: string,
+    body: Record<string, unknown> = {},
+    search: Record<string, string> = {},
+  ): Promise<TokenResource> {
     const json = (await BaseResource._fetch<TokenJSON>({
       method: 'POST',
       path,
       body,
       search,
     })) as unknown as TokenJSON;
🧹 Nitpick comments (1)
packages/clerk-js/src/core/resources/__tests__/Session.test.ts (1)

1090-1285: Origin-outage fallback coverage is solid (retry/no-retry matrix).
Nice set of cases: retries only for 422 missing_expired_token, cookie fallback when last_active_token is missing, and no retry for other 4xx / other codes.
Optional: add a small assertion that __internal_getSessionCookie is not consulted when lastActiveToken is present (to lock in the precedence order).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a40d623 and c477def.

📒 Files selected for processing (12)
  • .changeset/chatty-tigers-see.md (1 hunks)
  • packages/backend/src/constants.ts (1 hunks)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/src/core/clerk.ts (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
  • packages/shared/src/error.ts (1 hunks)
  • packages/shared/src/errors/missingExpiredTokenError.ts (1 hunks)
  • packages/shared/src/types/clerk.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/shared/src/types/clerk.ts
  • packages/clerk-js/src/core/clerk.ts
  • packages/clerk-js/src/core/resources/tests/Token.test.ts
  • packages/shared/src/errors/missingExpiredTokenError.ts
  • .changeset/chatty-tigers-see.md
  • packages/backend/src/tokens/handshake.ts
  • packages/backend/src/constants.ts
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

All code must pass ESLint checks with the project's configuration

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.{js,jsx,ts,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Follow established naming conventions (PascalCase for components, camelCase for variables)

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
packages/**/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

packages/**/src/**/*.{ts,tsx,js,jsx}: Maintain comprehensive JSDoc comments for public APIs
Use tree-shaking friendly exports
Validate all inputs and sanitize outputs
All public APIs must be documented with JSDoc
Use dynamic imports for optional features
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Implement proper logging with different levels

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.ts?(x)

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details in classes
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Use mixins for shared behavior across unrelated classes in TypeScript
Use generic constraints with bounded type parameters like <T extends { id: string }>
Use utility types like Omit, Partial, and Pick for data transformation instead of manual type construction
Use discriminated unions instead of boolean flags for state management and API responses
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation at the type level
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Document functions with JSDoc comments including @param, @returns, @throws, and @example tags
Create custom error classes that extend Error for specific error types
Use the Result pattern for error handling instead of throwing exceptions
Use optional chaining (?.) and nullish coalescing (??) operators for safe property access
Let TypeScript infer obvious types to reduce verbosity
Use const assertions with as const for literal types
Use satisfies operator for type checking without widening types
Declare readonly arrays and objects for immutable data structures
Use spread operator and array spread for immutable updates instead of mutations
Use lazy loading for large types...

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use ESLint with custom configurations tailored for different package types

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.{js,ts,jsx,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use Prettier for code formatting across all packages

Files:

  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/shared/src/error.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{test,spec}.{ts,tsx,js,jsx}: Unit tests are required for all new functionality
Verify proper error handling and edge cases
Include tests for all new features

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/*.{test,spec,e2e}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use real Clerk instances for integration tests

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use React Testing Library for component testing

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts
🧬 Code graph analysis (2)
packages/backend/src/tokens/__tests__/handshake.test.ts (2)
packages/backend/src/tokens/handshake.ts (1)
  • HandshakeService (84-360)
packages/backend/src/constants.ts (1)
  • constants (80-86)
packages/clerk-js/src/core/resources/Session.ts (2)
packages/clerk-js/src/core/resources/Token.ts (1)
  • Token (7-55)
packages/shared/src/errors/missingExpiredTokenError.ts (1)
  • MissingExpiredTokenError (16-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (3)
packages/shared/src/error.ts (1)

6-6: Public re-export looks fine; ensure it’s intentional + documented as a public API.
Re-exporting MissingExpiredTokenError makes it part of @clerk/shared/error’s surface—please ensure the changeset/docs reflect this addition (and that it’s meant to be supported long-term).

packages/clerk-js/src/core/resources/__tests__/Session.test.ts (1)

1-1: Import change is aligned with new error handling tests.

packages/clerk-js/src/core/resources/Session.ts (1)

2-2: Import addition is correct for the new retry gate.

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from c477def to 37a7dba Compare December 16, 2025 15:40
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/clerk-js/src/core/resources/Token.ts (1)

12-12: Address the persisting any type violation.

The body parameter still uses any type, which violates the coding guideline: "Avoid any type - prefer unknown when type is uncertain, then narrow with type guards." A past review comment flagged this issue and was marked as addressed in commit 771560c, but the any type remains in the current code.

Consider applying a type-safe solution:

-  static async create(path: string, body: any = {}, search: Record<string, string> = {}): Promise<TokenResource> {
+  static async create(path: string, body: Record<string, unknown> = {}, search: Record<string, string> = {}): Promise<TokenResource> {

As per coding guidelines

packages/backend/src/tokens/__tests__/handshake.test.ts (2)

435-450: Critical: Test uses wrong constant despite being marked as fixed.

Line 449 uses constants.Cookies.Session to verify the query parameter, but the production code at packages/backend/src/tokens/handshake.ts:153 sets it using constants.QueryParameters.Session. This mismatch was flagged in a previous review and marked as addressed, but the issue persists in the current code.

Apply this fix:

-      expect(url.searchParams.get(constants.Cookies.Session)).toBe('test_session_token_123');
+      expect(url.searchParams.get(constants.QueryParameters.Session)).toBe('test_session_token_123');

452-467: Critical: Test uses wrong constant (same issue as previous test).

Line 466 has the identical issue—it uses constants.Cookies.Session instead of constants.QueryParameters.Session to check the URL query parameter.

Apply this fix:

-      expect(url.searchParams.get(constants.Cookies.Session)).toBeNull();
+      expect(url.searchParams.get(constants.QueryParameters.Session)).toBeNull();
🧹 Nitpick comments (1)
packages/backend/src/tokens/handshake.ts (1)

152-154: Consider adding a comment to document the security trade-off.

The implementation correctly uses constants.QueryParameters.Session and aligns with the origin outage mode requirements. However, as discussed in a previous review, passing session tokens in URLs is generally discouraged per RFC 6750 due to exposure risks. While this is acceptable here with short-lived tokens (~10s to expiration), adding an inline comment would help future maintainers understand this intentional trade-off.

Consider adding a comment like:

+    // Passing session token in URL for origin outage mode handshake.
+    // Token is short-lived (~10s to expiration) to minimize exposure risk.
     if (this.authenticateContext.sessionToken) {
       url.searchParams.append(constants.QueryParameters.Session, this.authenticateContext.sessionToken);
     }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c477def and 37a7dba.

📒 Files selected for processing (12)
  • .changeset/chatty-tigers-see.md (1 hunks)
  • packages/backend/src/constants.ts (1 hunks)
  • packages/backend/src/tokens/__tests__/handshake.test.ts (1 hunks)
  • packages/backend/src/tokens/handshake.ts (1 hunks)
  • packages/clerk-js/src/core/clerk.ts (1 hunks)
  • packages/clerk-js/src/core/resources/Session.ts (2 hunks)
  • packages/clerk-js/src/core/resources/Token.ts (1 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Session.test.ts (2 hunks)
  • packages/clerk-js/src/core/resources/__tests__/Token.test.ts (2 hunks)
  • packages/shared/src/error.ts (1 hunks)
  • packages/shared/src/errors/missingExpiredTokenError.ts (1 hunks)
  • packages/shared/src/types/clerk.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/clerk-js/src/core/clerk.ts
  • packages/clerk-js/src/core/resources/tests/Session.test.ts
  • packages/clerk-js/src/core/resources/Session.ts
  • packages/shared/src/errors/missingExpiredTokenError.ts
  • packages/shared/src/error.ts
  • packages/backend/src/constants.ts
  • packages/shared/src/types/clerk.ts
  • packages/clerk-js/src/core/resources/tests/Token.test.ts
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

All code must pass ESLint checks with the project's configuration

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{js,jsx,ts,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Follow established naming conventions (PascalCase for components, camelCase for variables)

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
packages/**/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

packages/**/src/**/*.{ts,tsx,js,jsx}: Maintain comprehensive JSDoc comments for public APIs
Use tree-shaking friendly exports
Validate all inputs and sanitize outputs
All public APIs must be documented with JSDoc
Use dynamic imports for optional features
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Implement proper logging with different levels

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.ts?(x)

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Implement type guards for unknown types using the pattern function isType(value: unknown): value is Type
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details in classes
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Use mixins for shared behavior across unrelated classes in TypeScript
Use generic constraints with bounded type parameters like <T extends { id: string }>
Use utility types like Omit, Partial, and Pick for data transformation instead of manual type construction
Use discriminated unions instead of boolean flags for state management and API responses
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation at the type level
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Document functions with JSDoc comments including @param, @returns, @throws, and @example tags
Create custom error classes that extend Error for specific error types
Use the Result pattern for error handling instead of throwing exceptions
Use optional chaining (?.) and nullish coalescing (??) operators for safe property access
Let TypeScript infer obvious types to reduce verbosity
Use const assertions with as const for literal types
Use satisfies operator for type checking without widening types
Declare readonly arrays and objects for immutable data structures
Use spread operator and array spread for immutable updates instead of mutations
Use lazy loading for large types...

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use ESLint with custom configurations tailored for different package types

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{js,ts,jsx,tsx,json,md,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use Prettier for code formatting across all packages

Files:

  • packages/backend/src/tokens/handshake.ts
  • packages/clerk-js/src/core/resources/Token.ts
  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{test,spec}.{ts,tsx,js,jsx}: Unit tests are required for all new functionality
Verify proper error handling and edge cases
Include tests for all new features

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.{test,spec,e2e}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use real Clerk instances for integration tests

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Use React Testing Library for component testing

Files:

  • packages/backend/src/tokens/__tests__/handshake.test.ts
🧬 Code graph analysis (1)
packages/backend/src/tokens/handshake.ts (1)
packages/backend/src/constants.ts (1)
  • constants (80-86)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16, RQ)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
.changeset/chatty-tigers-see.md (1)

1-6: LGTM! Changeset properly documents the feature addition.

The changeset correctly specifies minor version bumps for both affected packages and clearly describes the new feature.

packages/clerk-js/src/core/resources/Token.ts (1)

12-21: Signature change improves flexibility for token requests.

Replacing the skipCache boolean with a search parameters object provides more flexibility for passing query parameters, which aligns with the origin outage mode feature requirements. The updated fetch call correctly includes both body and search parameters.


// TODO: update template endpoint to accept organizationId
const params: Record<string, string | null> = template ? {} : { organizationId };
const lastActiveToken = this.lastActiveToken?.getRawString() ?? Session.clerk.__internal_getSessionCookie?.();
Copy link
Member

@brkalow brkalow Dec 17, 2025

Choose a reason for hiding this comment

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

❓ Why do we need this fallback specifically? In a multi-session scenario, it's feasible (though unlikely) that the session cookie would not match the token in memory. Is this a safe-guard or a to address a specific scenario?

If there isn't a specific scenario in mind, it would be preferable to not need to add this internal property and reference the core Clerk instance here, to avoid tight coupling

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the call-out!

Double check me on this, but I think in a real origin outage mode, v1/client API call will fail - which is what populates this.lastActiveToken if I'm not mistaken - but we may already have a token stored in the cookies.

Copy link
Member

Choose a reason for hiding this comment

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

We have a fallback in place already that reads from the session cookie:

const initClient = async () => {
return Client.getOrCreateInstance()
.fetch()
.then(res => this.updateClient(res))
.catch(async e => {
/**
* Only handle non 4xx errors, like 5xx errors and network errors.
*/
if (is4xxError(e)) {
// bubble it up
throw e;
}
++initializationDegradedCounter;
const jwtInCookie = this.#authService?.getSessionCookie();
const localClient = createClientFromJwt(jwtInCookie);
this.updateClient(localClient);
/**
* In most scenarios we want the poller to stop while we are fetching a fresh token during an outage.
* We want to avoid having the below `getToken()` retrying at the same time as the poller.
*/
this.#authService?.stopPollingForToken();
// Attempt to grab a fresh token
await this.session
?.getToken({ skipCache: true })
// If the token fetch fails, let Clerk be marked as loaded and leave it up to the poller.
.catch(() => null)
.finally(() => {
this.#authService?.startPollingForToken();
});
// Allows for Clerk to be marked as loaded with the client and session created from the JWT.
return null;
});
};

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh nice I missed that. Then we can simplify this a lot, I'll just drop this commit f076cc3

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch 2 times, most recently from ad4fdba to 33c6d84 Compare December 18, 2025 20:40
@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from 33c6d84 to fa870c2 Compare December 19, 2025 16:59
'@clerk/backend': minor
---

Adds support for origin outage mode
Copy link
Member

Choose a reason for hiding this comment

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

Let's update this to be user-focused. What does it mean for users at a high level?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure! How about this: Improves resilience by keeping users logged in when Clerk's origin is temporarily unavailable using edge-based token generation

Copy link
Member Author

Choose a reason for hiding this comment

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

@bratsos bratsos force-pushed the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch from ead5018 to 83ba391 Compare December 19, 2025 18:16
@bratsos bratsos merged commit e76d248 into main Dec 19, 2025
44 checks passed
@bratsos bratsos deleted the alexbratsos/plat-1654-add-logic-to-mint-new-session-tokens-based-on-existing-ones branch December 19, 2025 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants