Skip to content

Conversation

@btiernay
Copy link
Contributor

@btiernay btiernay commented Oct 5, 2025

Summary

Enforce an explicit and unambiguous subject token choice for Token Vault exchanges by requiring exactly one of accessToken or
refreshToken. This aligns with how the backend must identify the subject token type for exchange and prevents accidental misuse.

What & Why

The Token Vault exchange methods (getTokenForConnection in auth-js and getAccessTokenForConnection in api-js) now enforce XOR
validation: callers must provide exactly one of accessToken or refreshToken, not both and not neither.

  • Prevents ambiguity: The backend requires an unambiguous subject_token_type for the exchange. Allowing both tokens would invite
    confusion or accidental mismatches.
  • Better developer experience: Clear, actionable error messages and comprehensive documentation with examples.
  • Type-level enforcement: TypeScript users get compile-time safety via discriminated unions.
  • Fail-fast: Local validation before any network request.

Changes

Scope: Enhanced types + validation + docs + tests

auth0-auth-js

  • src/auth-client.ts:
    • Enhanced constant documentation for SUBJECT_TYPE_ACCESS_TOKEN and SUBJECT_TYPE_REFRESH_TOKEN with usage guidance
    • Added XOR runtime validation in getTokenForConnection()
  • src/types.ts:
    • Introduced SubjectToken discriminated union for compile-time XOR enforcement
    • Enhanced JSDoc for TokenForConnectionOptions with comprehensive guidance
  • src/auth-client.spec.ts: Updated test to match new error message
  • EXAMPLES.md: Added note about XOR requirement

auth0-api-js

  • src/api-client.ts: Added XOR runtime validation in getAccessTokenForConnection()
  • src/types.ts:
    • Introduced SubjectToken discriminated union
    • Enhanced JSDoc for AccessTokenForConnectionOptions
  • src/api-client.spec.ts: Added new test for XOR validation
  • EXAMPLES.md: Documented refreshToken parameter and XOR requirement

Type-Level Enforcement

TypeScript users get compile-time safety:

export type SubjectToken =
  | {
      accessToken: string;
      refreshToken?: never;
    }
  | {
      refreshToken: string;
      accessToken?: never;
    };

export type TokenForConnectionOptions = SubjectToken & {
  connection: string;
  loginHint?: string;
};

Runtime Validation

JavaScript users get clear runtime errors:

  /**
   * Enforce the XOR at runtime for JavaScript callers and for robust error messages.
   * TypeScript users already get compile time feedback from the SubjectToken union.
   */
  if ((options as any).accessToken && (options as any).refreshToken) {
    throw new TokenForConnectionError(
      'Provide either accessToken or refreshToken, not both.'
    );
  }

Backwards Compatibility

  • Error class/name/code preserved: TokenForConnectionError with unchanged name and code
  • Most apps unaffected: Typical usage already passes only one token
  • Migration: Remove one of the two tokens if both are currently passed (unlikely scenario)

Tests

  • ✅ New unit tests cover both-provided case with updated error message
  • ✅ Existing tests for neither-provided case remain
  • ✅ Happy paths (access-token-only and refresh-token-only) unchanged

Documentation

  • Enhanced constant documentation explaining when to use access vs refresh tokens
  • JSDoc with discriminated union types provides IntelliSense guidance
  • README/EXAMPLES updated with clear XOR requirement notes
  • Consistent messaging across both packages

@btiernay btiernay force-pushed the feat/token-vault-xor-validation branch 7 times, most recently from 9bd1632 to 626bb76 Compare October 6, 2025 00:16
- Add XOR guard to getTokenForConnection (auth-js) and getAccessTokenForConnection (api-js)
- Preserve TokenForConnectionError class/name/code for compatibility
- Update JSDoc and documentation with explicit guidance and examples
- Add unit tests for both-provided and neither-provided cases

BREAKING CHANGE: Passing both accessToken and refreshToken to Token Vault exchange methods now fails with TokenForConnectionError. Remove one of the two tokens from the call.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@btiernay btiernay force-pushed the feat/token-vault-xor-validation branch from 626bb76 to 82aebd2 Compare October 6, 2025 00:18
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.

1 participant