Skip to content

feat(auth0-fastify): add Custom Token Exchange support#78

Merged
nandan-bhat merged 3 commits into
mainfrom
feature/CTE/SDK-6333
Jun 17, 2026
Merged

feat(auth0-fastify): add Custom Token Exchange support#78
nandan-bhat merged 3 commits into
mainfrom
feature/CTE/SDK-6333

Conversation

@nandan-bhat

@nandan-bhat nandan-bhat commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Changes

Adds Custom Token Exchange (CTE) support to the Fastify plugin, building on the CTE methods released in @auth0/auth0-server-js v1.6.0.

The plugin follows the same client-only pattern it already uses for CIBA (loginBackchannel): no new mounted route. Developers call the methods on fastify.auth0Client from their own routes.

  • Re-exports LoginWithCustomTokenExchangeOptions, CustomTokenExchangeOptions, and LoginWithCustomTokenExchangeResult from auth0-server-js so consumers can import them from @auth0/auth0-fastify.
  • Bumps @auth0/auth0-server-js from ^1.4.0 to ^1.6.0 (the version that ships the CTE methods).
  • Adds an EXAMPLES section covering both methods, actor-token delegation and the act claim, the openid-scope note, and the refresh-token suppression caveat when an actor token is used.

No change to the plugin body. The methods are already reachable on the decorated client; this PR makes the types and docs first-class.

Testing

Added unit tests in index.spec.ts:

  • loginWithCustomTokenExchange writes the exchanged user to the session
  • loginWithCustomTokenExchange stores the token under the configured audience
  • customTokenExchange returns a token without creating a session
  • customTokenExchange surfaces the act claim when an actor token is used
  • customTokenExchange throws when the exchange fails

Summary by CodeRabbit

  • Documentation

    • Added a “Login using Custom Token Exchange” guide, including delegation (with/without sessions), actor-token delegation, audience and organization examples, and clarified session and refresh-token behavior.
  • Tests

    • Added coverage for session cookie updates, audience-specific token storage, actor claim persistence, correct behavior when sessions already exist, organization forwarding, and token-exchange error handling.
  • Chores

    • Updated @auth0/auth0-server-js dependency to ^1.6.1.
  • Refactor

    • Re-exported additional custom token exchange TypeScript types and related error types.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 841d6f59-3603-48e0-a5ec-b6e65fcf387a

📥 Commits

Reviewing files that changed from the base of the PR and between 48e70a1 and d076c24.

📒 Files selected for processing (2)
  • packages/auth0-fastify/package.json
  • packages/auth0-fastify/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/auth0-fastify/package.json
  • packages/auth0-fastify/src/index.ts

📝 Walkthrough

Walkthrough

Adds custom token exchange support to auth0-fastify by re-exporting five new TypeScript types and two error classes from @auth0/auth0-server-js, bumping the dependency to ^1.6.1, adding eight Vitest/MSW test cases covering both session-creating and delegation flows, and documenting all exchange patterns in EXAMPLES.md.

Changes

Custom Token Exchange Feature

Layer / File(s) Summary
Type and value re-exports and dependency bump
packages/auth0-fastify/src/index.ts, packages/auth0-fastify/package.json
Re-exports LoginWithCustomTokenExchangeOptions, CustomTokenExchangeOptions, LoginWithCustomTokenExchangeResult, TokenResponse, and ActClaim types, plus TokenExchangeError and MissingClientAuthError values from @auth0/auth0-server-js, and bumps the dependency constraint from ^1.4.0 to ^1.6.1.
Session-creating token exchange tests (loginWithCustomTokenExchange)
packages/auth0-fastify/src/index.spec.ts
Three Vitest tests verify: user subject written to the __a0_session cookie, audience-scoped tokenSets[0] entry created with accessToken, and actor-token act claim persisted into the session user via MSW override.
Delegation token exchange tests (customTokenExchange)
packages/auth0-fastify/src/index.spec.ts
Five Vitest tests verify: customTokenExchange returning accessToken without setting a session cookie, not overwriting an existing session, surfacing actor-token act claims, throwing TokenExchangeError on a 400 token endpoint response, and forwarding the organization parameter to the token endpoint.
EXAMPLES.md documentation
packages/auth0-fastify/EXAMPLES.md
Adds table-of-contents entries and a new section documenting loginWithCustomTokenExchange for session creation, customTokenExchange for delegation, actor-token delegation via actorToken/actorTokenType, the refresh-token constraint when using actor tokens, and organization-scoped exchange using the organization option.

Sequence Diagram

sequenceDiagram
  participant Test as Vitest Test
  participant Fastify as Fastify Route
  participant Auth0Client as auth0Client
  participant MSW as MSW Token Endpoint

  rect rgba(100, 200, 100, 0.5)
    Note over Fastify,Auth0Client: Session-creating flow
    Test->>Fastify: POST /login-custom-token-exchange
    Fastify->>Auth0Client: loginWithCustomTokenExchange({subjectToken}, {request, reply})
    Auth0Client->>MSW: POST /oauth/token (subjectToken)
    MSW-->>Auth0Client: accessToken, idToken [, act claim]
    Auth0Client-->>Fastify: __a0_session cookie set (user.sub, tokenSets)
    Fastify-->>Test: HTTP response + Set-Cookie
  end

  rect rgba(100, 150, 200, 0.5)
    Note over Fastify,Auth0Client: Delegation flow (no session)
    Test->>Fastify: POST /custom-token-exchange
    Fastify->>Auth0Client: customTokenExchange({subjectToken}, [actorToken])
    Auth0Client->>MSW: POST /oauth/token (subjectToken, [actor tokens])
    MSW-->>Auth0Client: accessToken [or TokenExchangeError on 400]
    Auth0Client-->>Fastify: accessToken result (no session cookie)
    Fastify-->>Test: HTTP response (no Set-Cookie)
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐇 Hop hop, a token to trade,
A session is born or a delegation made!
The actor steps in with its claim so bright,
While MSW mocks in the dead of night.
New types re-exported, the docs shine anew —
This bunny approves of the exchange breakthrough! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding Custom Token Exchange support to the auth0-fastify package, which aligns with the core objective of the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/CTE/SDK-6333

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@packages/auth0-fastify/EXAMPLES.md`:
- Around line 212-216: Remove the blank line that appears between the two
blockquote callouts in the EXAMPLES.md file. The blank line exists between the
[!NOTE] blockquote about the openid scope and the [!IMPORTANT] blockquote about
store options, which violates the MD028 rule. Delete this empty line so the two
blockquotes are directly consecutive without any separation between them.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7bf7519-d0eb-491e-a775-3b5d4e1161a6

📥 Commits

Reviewing files that changed from the base of the PR and between eef783f and 2099791.

📒 Files selected for processing (4)
  • packages/auth0-fastify/EXAMPLES.md
  • packages/auth0-fastify/package.json
  • packages/auth0-fastify/src/index.spec.ts
  • packages/auth0-fastify/src/index.ts

Comment thread packages/auth0-fastify/EXAMPLES.md Outdated
expect(session.tokenSets[0]?.accessToken).toBe(accessToken);
});

test('customTokenExchange returns a token without creating a session', async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: worth adding a test where customTokenExchange does not overwrite an existing session
There is a session and after calling customTokenExchange it remains intact.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 48e70a1

Comment on lines +19 to +23
export type {
LoginWithCustomTokenExchangeOptions,
CustomTokenExchangeOptions,
LoginWithCustomTokenExchangeResult,
} from '@auth0/auth0-server-js';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggest also re-exporting TokenResponse and ActClaim from @auth0/auth0-server-js here.
customTokenExchange() returns a TokenResponse which carries act?: ActClaim for delegation flows. Without these exports, a developer who writes a typed helper function or service layer cannot name these types from @auth0/auth0-fastify

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 48e70a1

Piyush-85
Piyush-85 previously approved these changes Jun 17, 2026

@cschetan77 cschetan77 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

@nandan-bhat nandan-bhat merged commit f27d174 into main Jun 17, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants