@auth0/auth0-server-js 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/state/utils.ts","../src/server-client.ts","../src/utils.ts","../src/telemetry.ts","../src/mfa/server-mfa-client.ts","../src/passkey/server-passkey-client.ts","../src/encryption/index.ts","../src/store/abstract-store.ts","../src/store/abstract-state-store.ts","../src/store/abstract-transaction-store.ts","../src/store/cookie-transaction-store.ts","../src/store/abstract-session-store.ts","../src/store/stateful-state-store.ts","../src/store/stateless-state-store.ts","../src/mfa/index.ts","../src/passkey/index.ts"],"sourcesContent":["export { ServerClient } from './server-client.js';\nexport { AbstractStateStore } from './store/abstract-state-store.js';\nexport { AbstractTransactionStore } from './store/abstract-transaction-store.js';\nexport type { TokenResponse, ActClaim } from '@auth0/auth0-auth-js';\nexport { TokenExchangeError, MissingClientAuthError } from '@auth0/auth0-auth-js';\n\nexport type { CookieHandler, CookieSerializeOptions } from './store/cookie-handler.js';\nexport { CookieTransactionStore } from './store/cookie-transaction-store.js';\n\nexport { StatefulStateStore } from './store/stateful-state-store.js';\nexport type { StatefulStateStoreOptions } from './store/stateful-state-store.js';\nexport { StatelessStateStore } from './store/stateless-state-store.js';\n\nexport * from './errors.js';\nexport * from './types.js';\nexport * from './mfa/index.js';\nexport * from './passkey/index.js';\n","/**\n * Error thrown when there is no transaction available.\n */\nexport class MissingTransactionError extends Error {\n public code: string = 'missing_transaction_error';\n\n constructor(message?: string) {\n super(message ?? 'The transaction is missing.');\n this.name = 'MissingTransactionError';\n }\n}\n\n\n/**\n * Error thrown when backchannel logout fails.\n */\nexport class BackchannelLogoutError extends Error {\n public code: string = 'backchannel_logout_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'BackchannelLogoutError';\n }\n}\n\n/**\n * Error thrown when starting the user-linking failed.\n */\nexport class StartLinkUserError extends Error {\n public code: string = 'start_link_user_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'StartLinkUserError';\n }\n}\n\n/**\n * Error thrown when a required argument is missing.\n */\nexport class MissingRequiredArgumentError extends Error {\n public code: string = 'missing_required_argument_error';\n\n constructor(argument: string) {\n super(`The argument '${argument}' is required but was not provided.`);\n this.name = 'MissingRequiredArgumentError';\n }\n}\n\n/**\n * Error thrown when a session is missing.\n */\nexport class MissingSessionError extends Error {\n public code: string = 'missing_session_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'MissingSessionError';\n }\n}\n\n/**\n * Error thrown when a configuration is invalid.\n */\nexport class InvalidConfigurationError extends Error {\n public code: string = 'invalid_configuration_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'InvalidConfigurationError';\n }\n}\n\n/**\n * Error thrown when the issuer validation fails.\n */\nexport class IssuerValidationError extends Error {\n public code: string = 'issuer_validation_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'IssuerValidationError';\n }\n}\n\n/**\n * Error thrown when the session has passed its upstream IdP-asserted\n * `session_expiry` ceiling (IPSIE SL1). The user must re-authenticate.\n */\nexport class SessionExpiredError extends Error {\n public code: string = 'session_expired';\n\n constructor(message?: string) {\n super(\n message ??\n 'The session has expired because the upstream identity provider session ceiling was reached. The user needs to re-authenticate.'\n );\n this.name = 'SessionExpiredError';\n }\n}\n","import type { AccessTokenForConnectionOptions, StateData } from '../types.js';\nimport { TokenResponse } from '@auth0/auth0-auth-js';\nimport { SessionExpiredError } from '../errors.js';\n\n/**\n * Negative leeway (in seconds) applied to the `session_expiry` ceiling to absorb\n * clock skew between the SDK and the Auth0 platform. The session is treated as\n * expired slightly BEFORE the wall-clock ceiling, never after.\n */\nexport const SESSION_EXPIRY_LEEWAY = 30;\n\n/**\n * Upper bound (exclusive) for a value to be accepted as a Unix timestamp in seconds.\n *\n * `1e10` (10,000,000,000) is the year ~2286 — far beyond any real session ceiling, yet well below\n * a millisecond timestamp for the current era (`Date.now()` is ~1.7e12). This lets us reject a\n * `session_expiry` (or `iat`) that was mistakenly provided in milliseconds: such a value would\n * otherwise look like a valid far-future seconds timestamp and silently disable the ceiling.\n * Since `session_expiry` can be set by a customer Post-Login Action, a milliseconds mix-up is a\n * realistic input, not just a platform glitch. The threshold matches the cross-SDK convention.\n */\nconst MAX_PLAUSIBLE_UNIX_SECONDS = 1e10;\n\n/**\n * Returns whether a value is a plausible Unix timestamp in seconds: a positive integer below the\n * milliseconds range. Used to reject values mistakenly expressed in milliseconds.\n */\nfunction isPlausibleUnixSeconds(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0 && value < MAX_PLAUSIBLE_UNIX_SECONDS;\n}\n\n/**\n * Reads the IPSIE `session_expiry` claim (absolute Unix seconds) from ID token claims.\n *\n * Fail-open by design: returns `undefined` (meaning \"no ceiling\") unless the value is a plausible\n * Unix-seconds timestamp (positive integer below the milliseconds range). A missing or malformed\n * claim MUST NEVER be treated as an already-expired session — a platform glitch must not lock out\n * every enterprise user. A value in milliseconds is rejected rather than accepted as a far-future\n * ceiling (which would silently disable enforcement).\n *\n * @param claims The decoded ID token claims, or undefined.\n * @returns The ceiling in Unix seconds, or undefined when absent/invalid.\n */\nexport function extractSessionExpiry(claims: TokenResponse['claims'] | undefined): number | undefined {\n const value = claims?.session_expiry;\n return isPlausibleUnixSeconds(value) ? value : undefined;\n}\n\n/**\n * Returns whether the `session_expiry` ceiling has been reached, applying the negative leeway.\n *\n * @param sessionExpiresAt The stored ceiling in Unix seconds, or undefined for \"no ceiling\".\n * @param nowSeconds Optional current time in Unix seconds (defaults to now). Injectable for tests.\n * @returns `true` when the session must be treated as expired; `false` when there is no ceiling\n * or it has not yet been reached.\n */\nexport function isSessionExpiryReached(sessionExpiresAt: number | undefined, nowSeconds?: number): boolean {\n if (sessionExpiresAt === undefined) {\n return false;\n }\n const now = nowSeconds ?? Math.floor(Date.now() / 1000);\n return now >= sessionExpiresAt - SESSION_EXPIRY_LEEWAY;\n}\n\n/**\n * Creates an updated token set object from the token endpoint response\n * @param audience The audience for which the token was requested\n * @param response The response from the token endpoint\n * @returns Updated token set object\n */\nconst createUpdatedTokenSet = (audience: string, response: TokenResponse) => ({\n audience,\n accessToken: response.accessToken,\n scope: response.scope,\n expiresAt: response.expiresAt,\n});\n\n/**\n * Returns whether a `session_expiry` ceiling is already in the past at login — i.e. the session\n * would be born expired and MUST NOT be persisted (the caller should throw `SessionExpiredError`).\n *\n * Compares the ceiling against the ID token `iat` (issued-at), or the current time when `iat` is\n * absent, applying the same negative leeway as {@link isSessionExpiryReached}. `iat` is only\n * trusted when it is a plausible Unix-seconds value; an absent or malformed `iat` (e.g.\n * milliseconds) falls back to now, so a bad `iat` cannot itself manufacture a false lockout.\n *\n * This is enforced at the login sites (interactive login, backchannel login, MFA verify) rather\n * than inside {@link updateStateData}, so the ceiling is only ever derived from a genuine\n * authentication event — never re-derived from a refresh-token response.\n *\n * Companion to {@link isSessionExpiryReached}: that one gates *reads* of an already-stored session\n * against the current wall clock (`now`), whereas this one gates *login* against the token's `iat`,\n * so a token minted with an already-past ceiling is rejected before it is ever persisted.\n *\n * @param sessionExpiresAt The extracted ceiling in Unix seconds, or undefined for \"no ceiling\".\n * @param issuedAt The ID token `iat` claim, if present.\n * @returns `true` when the ceiling is already reached at login; `false` when there is no ceiling.\n */\nexport function isSessionExpiryInPast(sessionExpiresAt: number | undefined, issuedAt?: number): boolean {\n if (sessionExpiresAt === undefined) {\n return false;\n }\n const reference = isPlausibleUnixSeconds(issuedAt) ? issuedAt : Math.floor(Date.now() / 1000);\n return sessionExpiresAt <= reference + SESSION_EXPIRY_LEEWAY;\n}\n\n/**\n * Stamps the IPSIE `session_expiry` ceiling onto freshly-built login state.\n *\n * Call this ONLY at the login sites (interactive login, backchannel login, MFA verify) — i.e.\n * with the state produced by {@link updateStateData} from a genuine authentication response.\n * It must NOT be called on the refresh path: the ceiling is write-once per authentication and\n * preserved unchanged across refreshes (see {@link updateStateData}).\n *\n * Behavior:\n * - Extracts the ceiling from the response claims (rejecting malformed/millisecond values).\n * - Throws {@link SessionExpiredError} when the ceiling is already in the past at login, so a\n * born-expired session is never persisted.\n * - Returns the state with `sessionExpiresAt` set to the extracted value. On a re-login this\n * overwrites any preserved ceiling — including clearing it (to `undefined`) when the new login\n * is through a connection that asserts no ceiling — so the value always reflects the most\n * recent authentication event.\n *\n * @param stateData The login state to stamp (from {@link updateStateData}).\n * @param claims The decoded ID token claims from the authentication response.\n * @returns The state data with `sessionExpiresAt` reflecting this login.\n * @throws {SessionExpiredError} When the ceiling is at or before the issued-at time.\n */\nexport function applySessionExpiryAtLogin(stateData: StateData, claims: TokenResponse['claims']): StateData {\n const sessionExpiresAt = extractSessionExpiry(claims);\n\n if (isSessionExpiryInPast(sessionExpiresAt, claims?.iat)) {\n throw new SessionExpiredError(\n 'The upstream identity provider session_expiry is at or before the issued-at time; refusing to create an already-expired session.'\n );\n }\n\n return { ...stateData, sessionExpiresAt };\n}\n\n/**\n * Utility function to update the state with a new response from the token endpoint\n * @param audience The audience of the token endpoint response\n * @param stateData The existing state data to update, or undefined if no state data available.\n * @param tokenEndpointResponse The response from the token endpoint.\n * @returns Updated state data.\n */\nexport function updateStateData(\n audience: string,\n stateData: StateData | undefined,\n tokenEndpointResponse: TokenResponse,\n context?: { domain?: string }\n): StateData {\n // If we already have a session and the new token belongs to a different user (iss or sub mismatch),\n // wipe the existing state to start a fresh session. This handles the case where a user logs in\n // as a different user without explicitly logging out first.\n if (stateData && tokenEndpointResponse.claims) {\n const newSub = tokenEndpointResponse.claims.sub;\n const newIss = tokenEndpointResponse.claims.iss;\n const existingSub = stateData.user?.sub;\n const existingIss = stateData.user?.iss;\n\n const subMismatch = newSub !== undefined && existingSub !== undefined && newSub !== existingSub;\n const issMismatch = newIss !== undefined && existingIss !== undefined && newIss !== existingIss;\n\n if (subMismatch || issMismatch) {\n stateData = undefined;\n }\n }\n\n if (stateData) {\n const isNewTokenSet = !stateData.tokenSets.some(\n (tokenSet) => tokenSet.audience === audience && tokenSet.scope === tokenEndpointResponse.scope\n );\n\n const tokenSets = isNewTokenSet\n ? [...stateData.tokenSets, createUpdatedTokenSet(audience, tokenEndpointResponse)]\n : stateData.tokenSets.map((tokenSet) =>\n tokenSet.audience === audience && tokenSet.scope === tokenEndpointResponse.scope\n ? createUpdatedTokenSet(audience, tokenEndpointResponse)\n : tokenSet\n );\n\n // The `session_expiry` ceiling is intentionally NOT derived here. It is stamped once at the\n // login sites (interactive login, backchannel login, MFA verify) and preserved across every\n // refresh via the `...stateData` spread below. A refresh-token grant must never overwrite the\n // ceiling — even when a Post-Login Action stamps `session_expiry` on the refreshed ID token —\n // because that would let the session outlive the bound asserted at the original login.\n return {\n ...stateData,\n idToken: tokenEndpointResponse.idToken ?? stateData.idToken,\n refreshToken: tokenEndpointResponse.refreshToken ?? stateData.refreshToken,\n tokenSets,\n domain: context?.domain ?? stateData.domain,\n };\n } else {\n const user = tokenEndpointResponse.claims;\n return {\n user,\n idToken: tokenEndpointResponse.idToken,\n refreshToken: tokenEndpointResponse.refreshToken,\n tokenSets: [createUpdatedTokenSet(audience, tokenEndpointResponse)],\n domain: context?.domain,\n internal: {\n sid: user?.sid as string,\n createdAt: Math.floor(Date.now() / 1000),\n },\n };\n }\n}\n\nexport function updateStateDataForConnectionTokenSet(\n options: AccessTokenForConnectionOptions,\n stateData: StateData,\n tokenEndpointResponse: TokenResponse\n) {\n stateData.connectionTokenSets = stateData.connectionTokenSets || [];\n\n const isNewTokenSet = !stateData.connectionTokenSets.some(\n (tokenSet) =>\n tokenSet.connection === options.connection && (!options.loginHint || tokenSet.loginHint === options.loginHint)\n );\n\n const connectionTokenSet = {\n connection: options.connection,\n loginHint: options.loginHint,\n accessToken: tokenEndpointResponse.accessToken,\n scope: tokenEndpointResponse.scope,\n expiresAt: tokenEndpointResponse.expiresAt,\n };\n\n const connectionTokenSets = isNewTokenSet\n ? [...stateData.connectionTokenSets, connectionTokenSet]\n : stateData.connectionTokenSets.map((tokenSet) =>\n tokenSet.connection === options.connection && (!options.loginHint || tokenSet.loginHint === options.loginHint)\n ? connectionTokenSet\n : tokenSet\n );\n\n return {\n ...stateData,\n connectionTokenSets,\n };\n}\n","import {\n AccessTokenForConnectionOptions,\n ConnectionTokenSet,\n CustomTokenExchangeOptions,\n DomainResolver,\n LoginBackchannelOptions,\n LoginBackchannelResult,\n LoginWithCustomTokenExchangeOptions,\n LoginWithCustomTokenExchangeResult,\n CompletePasswordlessOptions,\n CompletePasswordlessResult,\n GetAccessTokenOptions,\n LogoutOptions,\n ServerClientOptions,\n SessionData,\n StartInteractiveLoginOptions,\n StartLinkUserOptions,\n StartPasswordlessOptions,\n StartUnlinkUserOptions,\n StateData,\n StateStore,\n TokenSet,\n TransactionData,\n TransactionStore,\n} from './types.js';\nimport {\n BackchannelLogoutError,\n InvalidConfigurationError,\n MissingRequiredArgumentError,\n MissingSessionError,\n MissingTransactionError,\n SessionExpiredError,\n} from './errors.js';\nimport {\n updateStateData,\n updateStateDataForConnectionTokenSet,\n isSessionExpiryReached,\n applySessionExpiryAtLogin,\n} from './state/utils.js';\nimport {\n TokenForConnectionError,\n AuthClient,\n AuthorizationDetails,\n PasswordlessStartError,\n PasswordlessVerifyError,\n TokenByRefreshTokenError,\n TokenByRefreshTokenOptions,\n TokenResponse,\n} from '@auth0/auth0-auth-js';\nimport { compareScopes, ensureOpenIdScope } from './utils.js';\nimport { decodeJwt } from 'jose';\nimport type { AuthClientOptions } from '@auth0/auth0-auth-js';\nimport { getTelemetryConfig } from './telemetry.js';\nimport { ServerMfaClient } from './mfa/server-mfa-client.js';\nimport { ServerPasskeyClient } from './passkey/server-passkey-client.js';\n\nconst normalizeDomain = (value: string) => {\n const trimmed = value.trim();\n const parsed = trimmed.startsWith('http') ? new URL(trimmed) : new URL(`https://${trimmed}`);\n return parsed.host.toLowerCase();\n};\n\nconst decodeIssuer = (token: string) => {\n try {\n const { iss } = decodeJwt(token);\n return typeof iss === 'string' ? iss : undefined;\n } catch {\n return undefined;\n }\n};\n\nexport class ServerClient<TStoreOptions = unknown> {\n readonly #options: ServerClientOptions<TStoreOptions>;\n readonly #transactionStore: TransactionStore<TStoreOptions>;\n readonly #transactionStoreIdentifier: string;\n readonly #stateStore: StateStore<TStoreOptions>;\n readonly #stateStoreIdentifier: string;\n readonly #authClientOptions: Omit<AuthClientOptions, 'domain'>;\n readonly #staticDomain?: string;\n readonly #authClient?: AuthClient;\n readonly #mfaClient?: ServerMfaClient<TStoreOptions>;\n readonly #passkeyClient: ServerPasskeyClient<TStoreOptions>;\n\n /**\n * The underlying `authClient` instance that can be used to interact with the Auth0 Authentication API.\n * Generally, you should prefer to use the higher-level methods exposed on the `ServerClient` instance.\n *\n * This property can only be used when `domain` is configured as a static string.\n * In resolver mode (`domain` as a function), the SDK resolves the domain per request,\n * so use `ServerClient` methods instead.\n *\n * Important: the methods exposed on the `authClient` instance do not handle any session or state management.\n */\n public get authClient(): AuthClient {\n if (!this.#authClient) {\n throw new InvalidConfigurationError('authClient is only available when using a static domain configuration.');\n }\n return this.#authClient;\n }\n\n /**\n * The MFA client for managing multi-factor authentication operations.\n *\n * Provides methods to list, enroll, and challenge MFA authenticators,\n * as well as verify MFA challenges to complete authentication.\n *\n * The `verify` method integrates with the session state store, persisting tokens\n * and user data after successful MFA verification.\n *\n * This property can only be used when `domain` is configured as a static string.\n * In resolver mode (`domain` as a function), MFA is not supported.\n */\n public get mfa(): ServerMfaClient<TStoreOptions> {\n if (!this.#mfaClient) {\n throw new InvalidConfigurationError('mfa is only available when using a static domain configuration.');\n }\n return this.#mfaClient;\n }\n\n /**\n * The passkey client for signing up and logging in users with WebAuthn credentials.\n *\n * Provides `register()` and `challenge()` to request signup/login challenges, and\n * `getToken()` to exchange the resulting credential for tokens and persist the session.\n *\n * Unlike `mfa`, this property is available in both static and resolver (multi-tenant)\n * domain modes. In resolver mode, pass the same `storeOptions` to `register()`/`challenge()`\n * and `getToken()` so the credential is exchanged against the tenant that issued it.\n */\n public get passkey(): ServerPasskeyClient<TStoreOptions> {\n return this.#passkeyClient;\n }\n\n constructor(options: ServerClientOptions<TStoreOptions>) {\n this.#options = options;\n this.#stateStoreIdentifier = this.#options.stateIdentifier || '__a0_session';\n this.#transactionStoreIdentifier = this.#options.transactionIdentifier || '__a0_tx';\n this.#transactionStore = options.transactionStore;\n this.#stateStore = options.stateStore;\n\n if (!this.#options.stateStore) {\n throw new MissingRequiredArgumentError('stateStore');\n }\n\n if (!this.#options.transactionStore) {\n throw new MissingRequiredArgumentError('transactionStore');\n }\n\n if (typeof this.#options.domain !== 'string' && typeof this.#options.domain !== 'function') {\n throw new InvalidConfigurationError('domain must be a string or resolver function');\n }\n\n this.#authClientOptions = {\n clientId: this.#options.clientId,\n clientSecret: this.#options.clientSecret,\n clientAssertionSigningKey: this.#options.clientAssertionSigningKey,\n clientAssertionSigningAlg: this.#options.clientAssertionSigningAlg,\n authorizationParams: this.#options.authorizationParams,\n discoveryCache: this.#options.discoveryCache,\n customFetch: this.#options.customFetch,\n useMtls: this.#options.useMtls,\n };\n\n if (typeof this.#options.domain === 'string') {\n const domain = normalizeDomain(this.#options.domain);\n this.#staticDomain = domain;\n this.#authClient = new AuthClient({\n domain,\n ...this.#authClientOptions,\n telemetry: getTelemetryConfig(this.#options.telemetry),\n });\n\n this.#mfaClient = new ServerMfaClient({\n authClient: this.#authClient,\n domain,\n stateStore: this.#stateStore,\n stateStoreIdentifier: this.#stateStoreIdentifier,\n defaultAudience: this.#options.authorizationParams?.audience ?? 'default',\n });\n }\n\n // The passkey client resolves the domain per call, so it is available in both\n // static and resolver (multi-tenant) modes.\n this.#passkeyClient = new ServerPasskeyClient({\n resolveDomain: (storeOptions) => this.#resolveDomain(storeOptions),\n getAuthClient: (domain) => this.#getAuthClient(domain),\n stateStore: this.#stateStore,\n stateStoreIdentifier: this.#stateStoreIdentifier,\n defaultScope: this.#options.authorizationParams?.scope,\n defaultAudience: this.#options.authorizationParams?.audience,\n });\n }\n\n async #resolveDomain(storeOptions?: TStoreOptions): Promise<string> {\n if (typeof this.#options.domain === 'function') {\n const resolved = await (this.#options.domain as DomainResolver<TStoreOptions>)(storeOptions);\n if (typeof resolved !== 'string' || resolved.trim().length === 0) {\n throw new InvalidConfigurationError('domainResolver returned no domain');\n }\n return normalizeDomain(resolved);\n }\n\n return normalizeDomain(this.#options.domain);\n }\n\n #createAuthClient(domain: string): AuthClient {\n return new AuthClient({\n domain,\n ...this.#authClientOptions,\n telemetry: getTelemetryConfig(this.#options.telemetry),\n });\n }\n\n #getAuthClient(domain: string): AuthClient {\n const normalizedDomain = normalizeDomain(domain);\n if (this.#authClient && this.#staticDomain === normalizedDomain) {\n return this.#authClient;\n }\n return this.#createAuthClient(normalizedDomain);\n }\n\n #getSessionDomain(stateData: StateData): string | undefined {\n if (stateData.domain) {\n return normalizeDomain(stateData.domain);\n }\n\n if (this.#staticDomain) {\n return this.#staticDomain;\n }\n\n // Legacy sessions may not have `domain` persisted yet; infer it from ID token claims.\n const issuerFromClaims = stateData.user?.iss;\n if (typeof issuerFromClaims === 'string' && issuerFromClaims.trim().length > 0) {\n return normalizeDomain(issuerFromClaims);\n }\n\n return;\n }\n\n #isResolverMode(): boolean {\n return typeof this.#options.domain === 'function';\n }\n\n async #isSessionForCurrentDomain(stateData: StateData, storeOptions?: TStoreOptions): Promise<boolean> {\n const sessionDomain = this.#getSessionDomain(stateData);\n if (!sessionDomain) {\n return false;\n }\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n return sessionDomain === resolvedDomain;\n }\n\n /**\n * Starts the interactive login process, and returns a URL to redirect the user-agent to to request authorization at Auth0.\n * @param options Optional options used to configure the interactive login process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {BuildAuthorizationUrlError} If there was an issue when building the Authorization URL.\n *\n * @returns A promise resolving to a URL object, representing the URL to redirect the user-agent to to request authorization at Auth0.\n */\n public async startInteractiveLogin(options?: StartInteractiveLoginOptions, storeOptions?: TStoreOptions) {\n const redirectUri = options?.authorizationParams?.redirect_uri ?? this.#options.authorizationParams?.redirect_uri;\n if (!redirectUri) {\n throw new MissingRequiredArgumentError('authorizationParams.redirect_uri');\n }\n\n const scope = ensureOpenIdScope(options?.authorizationParams?.scope ?? this.#options.authorizationParams?.scope);\n\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n const { codeVerifier, authorizationUrl } = await authClient.buildAuthorizationUrl({\n pushedAuthorizationRequests: options?.pushedAuthorizationRequests,\n authorizationParams: {\n ...options?.authorizationParams,\n redirect_uri: redirectUri,\n scope,\n },\n });\n\n const transactionState: TransactionData = {\n audience: options?.authorizationParams?.audience ?? this.#options.authorizationParams?.audience,\n codeVerifier,\n domain,\n };\n\n if (options?.appState) {\n transactionState.appState = options.appState;\n }\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n\n return authorizationUrl;\n }\n\n /**\n * Completes the interactive login process.\n * Takes an URL, extract the Authorization Code flow query parameters and requests a token.\n * @param url The URl from which the query params should be extracted to exchange for a token.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingTransactionError} When no transaction was found.\n * @throws {TokenByCodeError} If there was an issue requesting the access token.\n * @throws {SessionExpiredError} When the ID token's `session_expiry` is already in the past at login (the session is born expired); nothing is persisted.\n *\n * @returns A promise resolving to an object, containing the original appState (if present) and the authorizationDetails (when RAR was used).\n */\n public async completeInteractiveLogin<TAppState = unknown>(url: URL, storeOptions?: TStoreOptions) {\n const transactionData = await this.#transactionStore.get(this.#transactionStoreIdentifier, storeOptions);\n\n if (!transactionData) {\n throw new MissingTransactionError();\n }\n\n const domain = transactionData.domain ?? (await this.#resolveDomain(storeOptions));\n const authClient = this.#getAuthClient(domain);\n const tokenEndpointResponse = await authClient.getTokenByCode(url, {\n // TransactionData.codeVerifier is optional only to accommodate magic-link transactions.\n codeVerifier: transactionData.codeVerifier!,\n });\n\n // The transaction (and its code_verifier) is single-use and spent once the code is exchanged.\n // Delete it now — before applySessionExpiryAtLogin, which can throw the session_expiry lockout\n // — so a born-expired login does not leave the spent transaction lingering until its TTL.\n await this.#transactionStore.delete(this.#transactionStoreIdentifier, storeOptions);\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n const stateData = applySessionExpiryAtLogin(\n updateStateData(transactionData.audience ?? 'default', existingStateData, tokenEndpointResponse, {\n domain,\n }),\n tokenEndpointResponse.claims\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return { appState: transactionData.appState, authorizationDetails: tokenEndpointResponse.authorizationDetails } as {\n appState?: TAppState;\n authorizationDetails?: AuthorizationDetails[];\n };\n }\n\n /**\n * Starts the user linking process, and returns a URL to redirect the user-agent to to request authorization at Auth0.\n * @param options Options used to configure the user linking process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingSessionError} If there is no active session.\n * @throws {BuildLinkUserUrlError} If there was an issue when building the Authorization URL.\n * @throws {SessionExpiredError} When the session's `session_expiry` ceiling has been reached; the session is cleared and re-authentication is required.\n *\n * @returns A promise resolving to a URL object, representing the URL to redirect the user-agent to to request authorization at Auth0.\n */\n public async startLinkUser(options: StartLinkUserOptions, storeOptions?: TStoreOptions) {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (!stateData || !stateData.idToken) {\n throw new MissingSessionError(\n 'Unable to start the user linking process without a logged in user. Ensure to login using the SDK before starting the user linking process.'\n );\n }\n\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n throw new SessionExpiredError();\n }\n\n const domain = this.#getSessionDomain(stateData)!;\n const authClient = this.#getAuthClient(domain);\n const { linkUserUrl, codeVerifier } = await authClient.buildLinkUserUrl({\n connection: options.connection,\n connectionScope: options.connectionScope,\n idToken: stateData.idToken,\n authorizationParams: options.authorizationParams,\n });\n\n const transactionState: TransactionData = {\n audience: options?.authorizationParams?.audience ?? this.#options.authorizationParams?.audience,\n codeVerifier,\n domain,\n };\n\n if (options?.appState) {\n transactionState.appState = options.appState;\n }\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n\n return linkUserUrl;\n }\n\n /**\n * Completes the user linking process.\n * Takes an URL, extract the Authorization Code flow query parameters and requests a token.\n * @param url The URl from which the query params should be extracted to exchange for a token.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingTransactionError} When no transaction was found.\n * @throws {TokenByCodeError} If there was an issue requesting the access token.\n *\n * @returns A promise resolving to an object, containing the original appState (if present).\n */\n public async completeLinkUser<TAppState = unknown>(url: URL, storeOptions?: TStoreOptions) {\n // In order to complete the link user flow, we need to exchange the code for a token in the same\n // way as we do for the interactive login flow.\n const result = await this.completeInteractiveLogin<TAppState>(url, storeOptions);\n\n // As we currently do not support RAR when starting the user linking flow, we will ommit it from being returned as optional altogether.\n return {\n appState: result.appState,\n };\n }\n\n /**\n * Starts the user unlinking process, and returns a URL to redirect the user-agent to to initialize user unlinking at Auth0.\n * @param options Options used to configure the user unlinking process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingSessionError} If there is no active session.\n * @throws {BuildUnlinkUserUrlError} If there was an issue when building the User Unlinking URL.\n * @throws {SessionExpiredError} When the session's `session_expiry` ceiling has been reached; the session is cleared and re-authentication is required.\n *\n * @returns A promise resolving to a URL object, representing the URL to redirect the user-agent to to request authorization at Auth0.\n */\n public async startUnlinkUser(options: StartUnlinkUserOptions, storeOptions?: TStoreOptions) {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (!stateData || !stateData.idToken) {\n throw new MissingSessionError(\n 'Unable to start the user unlinking process without a logged in user. Ensure to login using the SDK before starting the user unlinking process.'\n );\n }\n\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n throw new SessionExpiredError();\n }\n\n const domain = this.#getSessionDomain(stateData)!;\n const authClient = this.#getAuthClient(domain);\n const { unlinkUserUrl, codeVerifier } = await authClient.buildUnlinkUserUrl({\n connection: options.connection,\n idToken: stateData.idToken,\n authorizationParams: options.authorizationParams,\n });\n\n const transactionState: TransactionData = {\n audience: options?.authorizationParams?.audience ?? this.#options.authorizationParams?.audience,\n codeVerifier,\n domain,\n };\n\n if (options?.appState) {\n transactionState.appState = options.appState;\n }\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n\n return unlinkUserUrl;\n }\n\n /**\n * Completes the user unlinking process.\n * Takes an URL, extract the Authorization Code flow query parameters and requests a token.\n * @param url The URl from which the query params should be extracted to exchange for a token.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingTransactionError} When no transaction was found.\n * @throws {TokenByCodeError} If there was an issue requesting the access token.\n *\n * @returns A promise resolving to an object, containing the original appState (if present).\n */\n public async completeUnlinkUser<TAppState = unknown>(url: URL, storeOptions?: TStoreOptions) {\n // In order to complete the link user flow, we need to exchange the code for a token in the same\n // way as we do for the interactive login flow.\n const result = await this.completeInteractiveLogin<TAppState>(url, storeOptions);\n\n // As we currently do not support RAR when starting the user unlinking flow, we will ommit it from being returned as optional altogether.\n return {\n appState: result.appState,\n };\n }\n\n /**\n * Logs in using Client-Initiated Backchannel Authentication.\n *\n * Using Client-Initiated Backchannel Authentication requires the feature to be enabled in the Auth0 dashboard.\n * @see https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-initiated-backchannel-authentication-flow\n * @param options Options used to configure the backchannel login process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {BackchannelAuthenticationError} If there was an issue when doing backchannel authentication.\n * @throws {SessionExpiredError} When the ID token's `session_expiry` is already in the past at login (the session is born expired); nothing is persisted.\n *\n * @returns A promise resolving to an object, containing the authorizationDetails (when RAR was used).\n */\n public async loginBackchannel(\n options: LoginBackchannelOptions,\n storeOptions?: TStoreOptions\n ): Promise<LoginBackchannelResult> {\n const scope = ensureOpenIdScope(options.authorizationParams?.scope ?? this.#options.authorizationParams?.scope);\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n const tokenEndpointResponse = await authClient.backchannelAuthentication({\n bindingMessage: options.bindingMessage,\n loginHint: options.loginHint,\n authorizationParams: {\n ...options.authorizationParams,\n scope,\n },\n });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const stateData = applySessionExpiryAtLogin(\n updateStateData(this.#options.authorizationParams?.audience ?? 'default', existingStateData, tokenEndpointResponse, {\n domain,\n }),\n tokenEndpointResponse.claims\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n\n /**\n * Starts a passwordless flow by sending a one-time code (OTP) or a magic link.\n *\n * Discriminated on `connection` (and, for email, `send`) to mirror the\n * `@auth0/nextjs-auth0` `passwordless.start()` surface:\n * - `{ connection: 'email' }` / `{ connection: 'email', send: 'code' }` — email OTP\n * - `{ connection: 'email', send: 'link', redirectUri }` — email magic link\n * - `{ connection: 'sms' }` — SMS OTP\n *\n * OTP modes are a stateless passthrough to the Authentication API (no session, no transaction);\n * complete them with {@link ServerClient#completePasswordless}.\n *\n * Magic-link mode is stateful: the SDK generates an opaque anti-forgery `state`, sends the link\n * with the OAuth parameters embedded (`redirect_uri`, `response_type=code`, `scope`, `state`),\n * and persists a transaction carrying that `state`. NO PKCE challenge is registered, so the\n * transaction holds no `codeVerifier`. Complete it with\n * {@link ServerClient#completePasswordlessMagicLink}. Requires the tenant setting\n * `allow_magiclink_verify_without_session: true` for server-side completion.\n *\n * @param options Discriminated start options.\n * @param storeOptions Optional options passed to the resolver / stores.\n *\n * @throws {PasswordlessStartError} If the request fails, or if a magic link is requested without a `redirectUri`.\n *\n * @example\n * // Email OTP\n * await serverClient.startPasswordless({ connection: 'email', email: 'user@example.com' });\n * // SMS OTP\n * await serverClient.startPasswordless({ connection: 'sms', phoneNumber: '+14155550100' });\n * // Email magic link\n * await serverClient.startPasswordless({\n * connection: 'email',\n * email: 'user@example.com',\n * send: 'link',\n * redirectUri: 'https://app.example.com/auth/callback',\n * });\n */\n public async startPasswordless(\n options: StartPasswordlessOptions,\n storeOptions?: TStoreOptions\n ): Promise<void> {\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n\n if (options.connection === 'sms') {\n await authClient.passwordless.sendSms({\n phoneNumber: options.phoneNumber,\n language: options.language,\n });\n return;\n }\n\n // Email OTP\n if (options.send !== 'link') {\n await authClient.passwordless.sendEmail({\n email: options.email,\n send: 'code',\n language: options.language,\n });\n return;\n }\n\n // Email magic link (stateful)\n if (!options.redirectUri || typeof options.redirectUri !== 'string') {\n throw new PasswordlessStartError('redirectUri is required to start a passwordless magic-link login.');\n }\n\n const state = crypto.randomUUID();\n const scope = ensureOpenIdScope(options.scope ?? this.#options.authorizationParams?.scope);\n const audience = options.audience ?? this.#options.authorizationParams?.audience;\n\n await authClient.passwordless.sendEmail({\n email: options.email,\n send: 'link',\n language: options.language,\n authParams: {\n ...options.authParams,\n redirect_uri: options.redirectUri,\n response_type: 'code',\n scope,\n ...(audience ? { audience } : {}),\n state,\n },\n });\n\n const transactionState: TransactionData = {\n audience,\n domain,\n state,\n };\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n }\n\n /**\n * Completes a passwordless OTP login and persists the resulting session.\n *\n * Discriminated on `connection` to mirror the `@auth0/nextjs-auth0` `passwordless.verify()`\n * surface. Non-redirect flow: no PKCE and no transaction store (mirrors\n * {@link ServerClient#loginBackchannel}). The `openid` scope is always ensured by this layer.\n *\n * Note: the state store is read-then-written; if your deployment performs concurrent\n * logins for the same session identifier, use a state store with atomic/serializable\n * writes to avoid last-write-wins races.\n *\n * @param options Discriminated completion options (`connection`, identifier, `verificationCode`).\n * @param storeOptions Optional options passed to the resolver / stores.\n *\n * @throws {PasswordlessVerifyError} If the code is invalid, expired, or rate-limited. When the\n * connection requires MFA, the server responds with `mfa_required`; narrow the thrown error\n * with `isMfaRequiredError(error)` to read `cause.mfa_token`.\n *\n * @returns A promise resolving to the authorizationDetails (when RAR was used).\n */\n public async completePasswordless(\n options: CompletePasswordlessOptions,\n storeOptions?: TStoreOptions\n ): Promise<CompletePasswordlessResult> {\n const scope = ensureOpenIdScope(options.authorizationParams?.scope ?? this.#options.authorizationParams?.scope);\n const audience = options.authorizationParams?.audience ?? this.#options.authorizationParams?.audience;\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n\n const tokenEndpointResponse =\n options.connection === 'sms'\n ? await authClient.getTokenByPasswordlessSms({\n phoneNumber: options.phoneNumber,\n code: options.verificationCode,\n audience,\n scope,\n })\n : await authClient.getTokenByPasswordlessEmail({\n email: options.email,\n code: options.verificationCode,\n audience,\n scope,\n });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const stateData = updateStateData(\n this.#options.authorizationParams?.audience ?? 'default',\n existingStateData,\n tokenEndpointResponse,\n { domain }\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n\n /**\n * Completes a passwordless magic-link login and persists the resulting session.\n *\n * Loads the transaction persisted by {@link ServerClient#startPasswordless} (magic-link mode), validates the\n * `state` returned on the callback URL against the stored `state` (anti-forgery binding), exchanges\n * the authorization code WITHOUT PKCE, writes the session, and deletes the transaction. The existing\n * interactive login path ({@link ServerClient#completeInteractiveLogin}) is not used.\n *\n * @param url The callback URL containing the authorization `code` and `state`.\n * @param storeOptions Optional options passed to the resolver / stores.\n *\n * @throws {MissingTransactionError} If no magic-link transaction was found.\n * @throws {PasswordlessVerifyError} If the returned `state` is missing or does not match.\n * @throws {TokenByCodeError} If the token exchange fails.\n *\n * @returns A promise resolving to the authorizationDetails (when RAR was used).\n *\n * @example\n * const result = await serverClient.completePasswordlessMagicLink(callbackUrl, storeOptions);\n */\n public async completePasswordlessMagicLink(\n url: URL,\n storeOptions?: TStoreOptions\n ): Promise<CompletePasswordlessResult> {\n const transactionData = await this.#transactionStore.get(this.#transactionStoreIdentifier, storeOptions);\n\n if (!transactionData) {\n throw new MissingTransactionError();\n }\n\n // TransactionData.state is `unknown` ([key: string]: unknown); validate the type\n // rather than assert it, so a non-string state (e.g. number from a custom store)\n // falls through to the mismatch branch instead of comparing wrongly.\n const expectedState = typeof transactionData.state === 'string' ? transactionData.state : undefined;\n const returnedState = url.searchParams.get('state');\n if (!returnedState || !expectedState || returnedState !== expectedState) {\n throw new PasswordlessVerifyError('State mismatch on magic-link callback');\n }\n\n const domain = transactionData.domain ?? (await this.#resolveDomain(storeOptions));\n const authClient = this.#getAuthClient(domain);\n\n // Belt-and-suspenders: `expectedState` is re-validated inside getTokenByMagicLinkCode\n // (openid-client's anti-forgery binding). This is intentionally redundant with the\n // manual check above — do not remove one without auditing the other.\n const tokenEndpointResponse = await authClient.getTokenByMagicLinkCode(url, { expectedState });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const stateData = updateStateData(transactionData.audience ?? 'default', existingStateData, tokenEndpointResponse, {\n domain,\n });\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n await this.#transactionStore.delete(this.#transactionStoreIdentifier, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n\n /**\n * Retrieves the user from the store, or undefined if no user found.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n * @returns The user, or undefined if no user found in the store.\n */\n public async getUser(storeOptions?: TStoreOptions) {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (!stateData) {\n return;\n }\n\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n return;\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n return;\n }\n\n return stateData.user;\n }\n\n /**\n * Retrieve the user session from the store, or undefined if no session found.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n * @returns The session or undefined if no session found in the store.\n */\n public async getSession(storeOptions?: TStoreOptions): Promise<SessionData | undefined> {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (stateData) {\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n return;\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { internal, ...sessionData } = stateData;\n return sessionData;\n }\n }\n\n // TEMPORARY: Overloads for backwards compatibility in minor version.\n // In the next major version, remove the first overload and use only the second signature.\n public async getAccessToken(storeOptions?: TStoreOptions): Promise<TokenSet>;\n public async getAccessToken(options: GetAccessTokenOptions, storeOptions?: TStoreOptions): Promise<TokenSet>;\n /**\n * Retrieves the access token from the store, or calls Auth0 when the access token is expired and a refresh token is available in the store.\n * Also updates the store when a new token was retrieved from Auth0.\n *\n * When `options.audience` and/or `options.scope` are provided, the SDK uses the session's refresh token to\n * request an access token for that audience/scope (Multi-Resource Refresh Tokens). Tokens are cached per\n * audience and scope combination.\n *\n * @param options Optional options for requesting a specific audience/scope.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {TokenByRefreshTokenError} If the refresh token was not found or there was an issue requesting the access token. When the cause is `mfa_required`, use `isMfaRequiredError(error)` to narrow the error and read `cause.mfa_token`.\n * @throws {SessionExpiredError} When the session's `session_expiry` ceiling has been reached; the session is cleared and no refresh is attempted — the user must re-authenticate.\n *\n * @returns The Token Set, containing the access token, as well as additional information.\n */\n public async getAccessToken(\n tokenOptionsOrStoreOptions?: GetAccessTokenOptions | TStoreOptions,\n storeOptions?: TStoreOptions\n ): Promise<TokenSet> {\n // TEMPORARY: Detect if first arg is GetAccessTokenOptions (has audience/scope)\n // or storeOptions (old behavior). Remove in next major version.\n const hasTokenOptions =\n // If second arg exists, first arg must be GetAccessTokenOptions\n storeOptions !== undefined ||\n // OR if first arg has audience/scope properties\n (!!tokenOptionsOrStoreOptions &&\n typeof tokenOptionsOrStoreOptions === 'object' &&\n ('audience' in tokenOptionsOrStoreOptions || 'scope' in tokenOptionsOrStoreOptions));\n\n const [resolvedOptions, resolvedStoreOptions] = hasTokenOptions\n ? [tokenOptionsOrStoreOptions as GetAccessTokenOptions, storeOptions]\n : [undefined, tokenOptionsOrStoreOptions as TStoreOptions];\n\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, resolvedStoreOptions);\n // The requested audience as sent to Auth0. `undefined` means \"no specific audience\" and is\n // intentionally not sent on the wire. `'default'` below is only a synthetic cache key.\n const requestedAudience = resolvedOptions?.audience ?? this.#options.authorizationParams?.audience;\n const audience = requestedAudience ?? 'default';\n const scope = resolvedOptions?.scope ?? this.#options.authorizationParams?.scope;\n\n const sessionDomain = stateData ? this.#getSessionDomain(stateData) : this.#staticDomain;\n if (this.#isResolverMode()) {\n if (!stateData) {\n throw new MissingSessionError('Unable to retrieve access token without a logged in user.');\n }\n if (!sessionDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n const resolvedDomain = await this.#resolveDomain(resolvedStoreOptions);\n if (sessionDomain !== resolvedDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n if (stateData && isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, resolvedStoreOptions);\n throw new SessionExpiredError();\n }\n\n const tokenSet = stateData?.tokenSets.find(\n (tokenSet) => tokenSet.audience === audience && (!scope || compareScopes(tokenSet.scope, scope))\n );\n\n if (tokenSet && tokenSet.expiresAt > Date.now() / 1000) {\n return tokenSet;\n }\n\n if (!stateData?.refreshToken) {\n throw new TokenByRefreshTokenError(\n 'The access token has expired and a refresh token was not provided. The user needs to re-authenticate.'\n );\n }\n\n const domainForSession = sessionDomain!;\n const tokenByRefreshTokenOptions: TokenByRefreshTokenOptions = {\n refreshToken: stateData.refreshToken,\n // Only forward audience/scope to Auth0 when token options were explicitly supplied, and\n // never send the synthetic 'default' cache-key audience as a real request parameter.\n ...(hasTokenOptions && {\n ...(requestedAudience && { audience: requestedAudience }),\n ...(scope && { scope }),\n }),\n };\n\n const tokenEndpointResponse =\n await this.#getAuthClient(domainForSession).getTokenByRefreshToken(tokenByRefreshTokenOptions);\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, resolvedStoreOptions);\n const updatedStateData = updateStateData(audience, existingStateData, tokenEndpointResponse, {\n domain: domainForSession,\n });\n\n await this.#stateStore.set(this.#stateStoreIdentifier, updatedStateData, false, resolvedStoreOptions);\n\n return {\n accessToken: tokenEndpointResponse.accessToken,\n scope: tokenEndpointResponse.scope,\n expiresAt: tokenEndpointResponse.expiresAt,\n audience: audience,\n };\n }\n\n /**\n * Retrieves an access token for a connection.\n *\n * This method attempts to obtain an access token for a specified connection.\n * It first checks if a refresh token exists in the store.\n * If no refresh token is found, it throws an `AccessTokenForConnectionError` indicating\n * that the refresh token was not found.\n *\n * @param options - Options for retrieving an access token for a connection.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {TokenForConnectionError} If the refresh token was not found or there was an issue requesting the access token.\n *\n * @returns The Connection Token Set, containing the access token for the connection, as well as additional information.\n */\n public async getAccessTokenForConnection(\n options: AccessTokenForConnectionOptions,\n storeOptions?: TStoreOptions\n ): Promise<ConnectionTokenSet> {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const sessionDomain = stateData ? this.#getSessionDomain(stateData) : this.#staticDomain;\n if (this.#isResolverMode()) {\n if (!stateData) {\n throw new MissingSessionError('Unable to retrieve an access token for a connection without a logged in user.');\n }\n if (!sessionDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n if (sessionDomain !== resolvedDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n // NOTE: the IPSIE `session_expiry` ceiling is intentionally NOT enforced here. Connection\n // (Token Vault) tokens are the upstream IdP's own tokens — Auth0 stores and returns them, it\n // does not mint them — so their lifetime is governed by the upstream IdP's `expires_in`, not by\n // the Auth0 app-session ceiling. Gating this path would reject a connection-token fetch that\n // should still succeed. (The ceiling IS enforced on getAccessToken/getUser/getSession and the\n // link/unlink flows, which depend on the Auth0 session itself.)\n const connectionTokenSet = stateData?.connectionTokenSets?.find(\n (tokenSet) => tokenSet.connection === options.connection\n );\n\n if (connectionTokenSet && connectionTokenSet.expiresAt > Date.now() / 1000) {\n return connectionTokenSet;\n }\n\n if (!stateData?.refreshToken) {\n throw new TokenForConnectionError(\n 'A refresh token was not found but is required to be able to retrieve an access token for a connection.'\n );\n }\n\n const domainForSession = sessionDomain!;\n const tokenEndpointResponse = await this.#getAuthClient(domainForSession).getTokenForConnection({\n connection: options.connection,\n loginHint: options.loginHint,\n refreshToken: stateData.refreshToken,\n });\n\n const updatedStateData = updateStateDataForConnectionTokenSet(\n options,\n {\n ...stateData,\n domain: stateData.domain ?? domainForSession,\n },\n tokenEndpointResponse\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, updatedStateData, false, storeOptions);\n\n return {\n accessToken: tokenEndpointResponse.accessToken,\n scope: tokenEndpointResponse.scope,\n expiresAt: tokenEndpointResponse.expiresAt,\n connection: options.connection,\n loginHint: options.loginHint,\n };\n }\n\n /**\n * Logs the user out and returns a URL to redirect the user-agent to after they log out.\n * @param options Options used to configure the logout process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n * @returns {URL}\n */\n public async logout(options: LogoutOptions, storeOptions?: TStoreOptions) {\n if (!this.#isResolverMode()) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n return this.authClient.buildLogoutUrl(options);\n }\n\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(resolvedDomain);\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n const sessionDomain = stateData ? this.#getSessionDomain(stateData) : undefined;\n\n if (!stateData) {\n // No local session, still return a logout URL for the current domain.\n return authClient.buildLogoutUrl(options);\n }\n\n if (sessionDomain && sessionDomain === resolvedDomain) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n }\n\n return authClient.buildLogoutUrl(options);\n }\n\n /**\n * Exchanges a custom token for Auth0 tokens and persists the resulting session (RFC 8693).\n *\n * Calls the token endpoint using the RFC 8693 Token Exchange grant, then stores the\n * resulting tokens in the StateStore — effectively logging the user in without an\n * interactive browser flow. Use this when the caller already holds a trusted external\n * token (e.g. a Google ID token, a legacy system token) and wants to establish an\n * Auth0 session from it.\n *\n * Requires a Token Exchange Profile configured in your Auth0 tenant.\n *\n * @param options Options for the custom token exchange, including the subject token and its type.\n * @param storeOptions Optional options passed to the StateStore.\n *\n * @throws {TokenExchangeError} If the exchange fails or the subject token is invalid.\n * @throws {MissingClientAuthError} If client credentials are not configured.\n *\n * @returns A promise resolving to an object containing `authorizationDetails` when RAR was used.\n */\n public async loginWithCustomTokenExchange(\n options: LoginWithCustomTokenExchangeOptions,\n storeOptions?: TStoreOptions\n ): Promise<LoginWithCustomTokenExchangeResult> {\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n const tokenEndpointResponse = await authClient.exchangeToken({\n ...options,\n scope: ensureOpenIdScope(options.scope),\n });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n const stateData = updateStateData(\n this.#options.authorizationParams?.audience ?? 'default',\n existingStateData,\n tokenEndpointResponse,\n { domain }\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return { authorizationDetails: tokenEndpointResponse.authorizationDetails };\n }\n\n /**\n * Exchanges a custom token for Auth0 tokens without establishing a session (RFC 8693).\n *\n * Performs the same RFC 8693 Token Exchange as `loginWithCustomTokenExchange` but\n * returns the raw token response without writing anything to the StateStore. Use this\n * for delegation or impersonation flows where you need downstream tokens but do not\n * want to create or modify the current user session.\n *\n * Requires a Token Exchange Profile configured in your Auth0 tenant.\n *\n * @param options Options for the custom token exchange, including the subject token and its type.\n * @param storeOptions Optional options passed to the StateStore (used only for domain resolution in resolver mode).\n *\n * @throws {TokenExchangeError} If the exchange fails or the subject token is invalid.\n * @throws {MissingClientAuthError} If client credentials are not configured.\n *\n * @returns A promise resolving to the token response from Auth0.\n */\n public async customTokenExchange(\n options: CustomTokenExchangeOptions,\n storeOptions?: TStoreOptions\n ): Promise<TokenResponse> {\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n return authClient.exchangeToken(options);\n }\n\n /**\n * Handles the backchannel logout process by verifying the logout token and deleting the session from the store if the logout token was considered valid.\n * @param logoutToken The logout token to verify and use to delete the session from the store.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {BackchannelLogoutError} If the logout token is missing.\n * @throws {VerifyLogoutTokenError} If the logout token is invalid.\n */\n public async handleBackchannelLogout(logoutToken: string, storeOptions?: TStoreOptions) {\n if (!logoutToken) {\n throw new BackchannelLogoutError('Missing Logout Token');\n }\n\n if (!this.#isResolverMode()) {\n const logoutTokenClaims = await this.authClient.verifyLogoutToken({ logoutToken });\n await this.#stateStore.deleteByLogoutToken(logoutTokenClaims, storeOptions);\n return;\n }\n\n const issuer = decodeIssuer(logoutToken);\n if (!issuer) {\n throw new BackchannelLogoutError('Logout token is missing an issuer');\n }\n\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n const domain = normalizeDomain(issuer);\n if (domain !== resolvedDomain) {\n throw new BackchannelLogoutError('Logout token issuer does not match the resolved domain');\n }\n\n const authClient = this.#getAuthClient(domain);\n const logoutTokenClaims = await authClient.verifyLogoutToken({ logoutToken });\n\n await this.#stateStore.deleteByLogoutToken({ ...logoutTokenClaims, iss: issuer }, storeOptions);\n }\n}\n","export const DEFAULT_SCOPES = 'openid profile email offline_access';\n\n/**\n * Ensures that the \"openid\" scope is always included in the scope string.\n *\n * @param scope - The scope provided by the user (optional)\n * @returns A scope string that includes \"openid\" if it was not already present.\n */\nexport const ensureOpenIdScope = (scope?: string) => {\n const normalizedScope = scope?.trim();\n if (!normalizedScope) {\n return DEFAULT_SCOPES;\n }\n\n const scopes = normalizedScope.split(/\\s+/);\n if (!scopes.includes('openid')) {\n scopes.unshift('openid');\n }\n\n return scopes.join(' ');\n};\n\n/**\n * Compares two sets of scopes to determine if all required scopes are present in the provided scopes.\n * @param scopes Scopes to compare\n * @param requiredScopes Scopes required to be present in the scopes\n * @returns True if all required scopes are present in the scopes, false otherwise\n */\nexport const compareScopes = (scopes: string | undefined, requiredScopes: string | undefined) => {\n // When the scopes and requiredScopes are exactly the same, return true\n // This handles cases where both are empty or undefined or both are the same string\n if (scopes === requiredScopes) {\n return true;\n }\n\n if (!scopes || !requiredScopes) {\n return false;\n }\n\n const scopesSet = new Set(scopes.trim().split(' ').filter(Boolean));\n const requiredScopesArray = requiredScopes.trim().split(' ').filter(Boolean);\n\n return requiredScopesArray.every((scope) => scopesSet.has(scope));\n};\n","import { TelemetryConfig } from '@auth0/auth0-auth-js';\n\n// These constants are injected at build time via tsup\ndeclare const __AUTH0_SERVER_JS_PACKAGE_NAME__: string;\ndeclare const __AUTH0_SERVER_JS_PACKAGE_VERSION__: string;\n\nexport function getTelemetryConfig(config?: TelemetryConfig): TelemetryConfig {\n if (config?.enabled === false) {\n return config;\n }\n\n return {\n enabled: true,\n name: config?.name ?? __AUTH0_SERVER_JS_PACKAGE_NAME__,\n version: config?.version ?? __AUTH0_SERVER_JS_PACKAGE_VERSION__,\n };\n}\n","import { updateStateData, applySessionExpiryAtLogin } from '../state/utils.js';\nimport type { ServerMfaClientOptions, MfaVerifyResponse } from './types.js';\nimport type {\n ListAuthenticatorsOptions,\n AuthenticatorResponse,\n EnrollAuthenticatorOptions,\n EnrollmentResponse,\n ChallengeOptions,\n ChallengeResponse,\n MfaVerifyOptions,\n} from '@auth0/auth0-auth-js';\n\nexport class ServerMfaClient<TStoreOptions = unknown> {\n readonly #options: ServerMfaClientOptions<TStoreOptions>;\n\n /**\n * @internal\n */\n constructor(options: ServerMfaClientOptions<TStoreOptions>) {\n this.#options = options;\n }\n\n /**\n * Lists all MFA authenticators enrolled by the user.\n *\n * @param options - Options for listing authenticators\n * @returns Promise resolving to an array of enrolled authenticators\n * @throws {MfaListAuthenticatorsError} When the request fails\n */\n async listAuthenticators(options: ListAuthenticatorsOptions): Promise<AuthenticatorResponse[]> {\n return this.#options.authClient.mfa.listAuthenticators(options);\n }\n\n /**\n * Enrolls a new MFA authenticator for the user.\n *\n * @param options - Enrollment options\n * @returns Promise resolving to enrollment response with authenticator details\n * @throws {MfaEnrollmentError} When enrollment fails\n */\n async enrollAuthenticator(options: EnrollAuthenticatorOptions): Promise<EnrollmentResponse> {\n return this.#options.authClient.mfa.enrollAuthenticator(options);\n }\n\n /**\n * Initiates an MFA challenge for user verification.\n *\n * @param options - Challenge options\n * @returns Promise resolving to challenge response with challenge details\n * @throws {MfaChallengeError} When the challenge fails\n */\n async challengeAuthenticator(options: ChallengeOptions): Promise<ChallengeResponse> {\n return this.#options.authClient.mfa.challengeAuthenticator(options);\n }\n\n /**\n * Verifies an MFA challenge and completes the authentication flow.\n *\n * Exchanges the MFA token and verification code for access, ID, and refresh tokens,\n * then saves them into the user's session automatically.\n *\n * @param options - The MFA token, factor type (otp / oob / recovery-code), and the code to verify\n * @param storeOptions - Optional options forwarded to the session store. Can be omitted when\n * using the built-in stores; required if your custom store needs extra context (e.g. a request object).\n * @returns The tokens returned by Auth0 after successful verification\n * @throws {MfaVerifyError} When verification fails (e.g. invalid token, wrong code)\n */\n async verify(options: MfaVerifyOptions, storeOptions?: TStoreOptions): Promise<MfaVerifyResponse> {\n const tokenResponse = await this.#options.authClient.mfa.verify(options);\n\n const audience = options.audience ?? this.#options.defaultAudience;\n const existingStateData = await this.#options.stateStore.get(\n this.#options.stateStoreIdentifier,\n storeOptions\n );\n\n const updatedStateData = applySessionExpiryAtLogin(\n updateStateData(audience, existingStateData, tokenResponse, {\n domain: this.#options.domain,\n }),\n tokenResponse.claims\n );\n\n await this.#options.stateStore.set(\n this.#options.stateStoreIdentifier,\n updatedStateData,\n true,\n storeOptions\n );\n\n const result: MfaVerifyResponse = {\n accessToken: tokenResponse.accessToken,\n tokenType: tokenResponse.tokenType ?? 'bearer',\n expiresAt: tokenResponse.expiresAt,\n scope: tokenResponse.scope,\n };\n\n if (tokenResponse.idToken) result.idToken = tokenResponse.idToken;\n if (tokenResponse.refreshToken) result.refreshToken = tokenResponse.refreshToken;\n if (tokenResponse.recoveryCode) result.recoveryCode = tokenResponse.recoveryCode;\n\n return result;\n }\n}\n","import { updateStateData } from '../state/utils.js';\nimport { ensureOpenIdScope } from '../utils.js';\nimport type { ServerPasskeyClientOptions } from './types.js';\nimport type {\n PasskeyRegisterOptions,\n PasskeyRegisterResponse,\n PasskeyChallengeOptions,\n PasskeyChallengeResponse,\n PasskeyGetTokenOptions,\n PasskeyGetTokenResult,\n} from '../types.js';\n\nexport class ServerPasskeyClient<TStoreOptions = unknown> {\n readonly #options: ServerPasskeyClientOptions<TStoreOptions>;\n\n /**\n * @internal\n */\n constructor(options: ServerPasskeyClientOptions<TStoreOptions>) {\n this.#options = options;\n }\n\n /**\n * Requests a passkey signup challenge for a new user.\n *\n * Returns the `authSession` and the WebAuthn credential creation options\n * (`authnParamsPublicKey`). The application must return these to the browser,\n * pass `authnParamsPublicKey` to `navigator.credentials.create()`, and then\n * call `getToken()` with the resulting credential to complete signup.\n *\n * This method does not create a session; no state is persisted.\n *\n * @param options User profile data and optional realm/organization.\n * @param storeOptions Optional options used to resolve the domain (resolver mode).\n *\n * @throws {PasskeyRegisterError} If there was an issue requesting the signup challenge.\n *\n * @returns A promise resolving to the signup challenge.\n */\n async register(options: PasskeyRegisterOptions, storeOptions?: TStoreOptions): Promise<PasskeyRegisterResponse> {\n const domain = await this.#options.resolveDomain(storeOptions);\n const authClient = this.#options.getAuthClient(domain);\n\n return authClient.passkey.register(options);\n }\n\n /**\n * Requests a passkey login challenge for an existing user.\n *\n * Returns the `authSession` and the WebAuthn credential request options\n * (`authnParamsPublicKey`). The application must return these to the browser,\n * pass `authnParamsPublicKey` to `navigator.credentials.get()`, and then\n * call `getToken()` with the resulting credential to complete login.\n *\n * This method does not create a session; no state is persisted.\n *\n * @param options Optional realm/organization configuration.\n * @param storeOptions Optional options used to resolve the domain (resolver mode).\n *\n * @throws {PasskeyChallengeError} If there was an issue requesting the login challenge.\n *\n * @returns A promise resolving to the login challenge.\n */\n async challenge(options?: PasskeyChallengeOptions, storeOptions?: TStoreOptions): Promise<PasskeyChallengeResponse> {\n const domain = await this.#options.resolveDomain(storeOptions);\n const authClient = this.#options.getAuthClient(domain);\n\n return authClient.passkey.challenge(options);\n }\n\n /**\n * Completes a passkey authentication flow (signup or login) by exchanging the\n * WebAuthn credential for tokens, and persists the resulting session.\n *\n * Call this after obtaining a credential from `navigator.credentials.create()`\n * (signup) or `navigator.credentials.get()` (login), passing the `authSession`\n * returned by `register()` / `challenge()` together with the serialized credential.\n *\n * In resolver (multi-tenant) mode, pass the same `storeOptions` you passed to\n * `register()` / `challenge()` so the token exchange resolves the same tenant\n * that issued the `authSession`; otherwise the exchange will fail.\n *\n * @param options The auth session, serialized credential, and optional realm/scope/audience/organization.\n * @param storeOptions Optional options used to pass to the State Store (and to resolve the domain in resolver mode).\n *\n * @throws {PasskeyGetTokenError} If there was an issue exchanging the credential for tokens. When the cause is `mfa_required`, use `isMfaRequiredError(error)` to narrow the error and read `cause.mfa_token`. No session is persisted in this case.\n * @throws {OrganizationValidationError} When `organization` is passed and the returned ID token's organization claim is missing or does not match. The error is thrown before the session is written, so no session is persisted in this case.\n *\n * @returns A promise resolving to an object containing the authorizationDetails (when RAR was used).\n */\n async getToken(options: PasskeyGetTokenOptions, storeOptions?: TStoreOptions): Promise<PasskeyGetTokenResult> {\n const scope = ensureOpenIdScope(options.scope ?? this.#options.defaultScope);\n const audience = options.audience ?? this.#options.defaultAudience;\n\n const domain = await this.#options.resolveDomain(storeOptions);\n const authClient = this.#options.getAuthClient(domain);\n\n const tokenEndpointResponse = await authClient.passkey.getTokenByPasskey({\n ...options,\n scope,\n audience,\n });\n\n const existingStateData = await this.#options.stateStore.get(this.#options.stateStoreIdentifier, storeOptions);\n\n const stateData = updateStateData(audience ?? 'default', existingStateData, tokenEndpointResponse, { domain });\n\n await this.#options.stateStore.set(this.#options.stateStoreIdentifier, stateData, true, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n}\n","import { EncryptJWT, jwtDecrypt, errors } from 'jose';\nimport type { JWTPayload } from 'jose';\nimport { InvalidConfigurationError } from '../errors.js';\n\nconst ENC = 'A256CBC-HS512';\nconst ALG = 'dir';\nconst DIGEST = 'SHA-256';\nconst BIT_LENGTH = 512;\nconst HKDF_INFO = 'derived cookie encryption secret';\n\nlet encoder: TextEncoder | undefined;\n\n/**\n * Type guard to determine if an error is a decryption-related error.\n * Decryption errors (JWEDecryptionFailed, JWEInvalid) indicate issues with the encryption key or data format.\n * These are distinct from claim validation errors (like expiration), which indicate a valid token with invalid claims.\n * @param e - The error thrown during decryption\n * @returns True if the error is a decryption error, false otherwise\n */\nexport function isDecryptionError(e: unknown): e is Error {\n return e instanceof errors.JWEDecryptionFailed || e instanceof errors.JWEInvalid;\n}\n\nasync function deriveEncryptionSecret(secret: string, salt: string, kid: string) {\n encoder ||= new TextEncoder();\n const key = await crypto.subtle.importKey('raw', encoder.encode(secret), 'HKDF', false, ['deriveBits']);\n\n return new Uint8Array(\n await crypto.subtle.deriveBits(\n {\n name: 'HKDF',\n hash: DIGEST,\n info: encoder.encode(HKDF_INFO),\n salt: encoder.encode(`${salt}${kid}`),\n } as HkdfParams,\n key,\n BIT_LENGTH\n )\n );\n}\n\n/**\n * Encrypts a payload using the provided secret and salt, with an expiration time.\n * @param payload The payload to encrypt.\n * @param secret The secret to use for encryption.\n * @param salt The salt to use for encryption.\n * @param expiration The expiration time for the encrypted payload.\n * @returns The encrypted payload.\n */\nasync function _encrypt(payload: JWTPayload, secret: string, salt: string, expiration: number) {\n const kid = crypto.randomUUID();\n const encryptionSecret = await deriveEncryptionSecret(secret, salt, kid);\n\n return await new EncryptJWT(payload)\n .setProtectedHeader({ enc: ENC, alg: ALG, kid: kid })\n .setExpirationTime(expiration)\n .encrypt(encryptionSecret);\n}\n\n/**\n * Encrypts a payload using the provided secret and salt, with an expiration time.\n * The secret can be a single string or an array of strings for secret rotation support.\n * When using an array of secrets, only the first one is used for encryption (all secrets are tried for decryption).\n * @param payload The payload to encrypt.\n * @param secret The secret(s) to use for encryption. Can be a single string or an array of strings for secret rotation support.\n * @param salt The salt to use for encryption.\n * @param expiration The expiration time for the encrypted payload.\n * @returns The encrypted payload.\n */\nexport async function encrypt(payload: JWTPayload, secret: string | string[], salt: string, expiration: number) {\n if (typeof secret === 'string') {\n return await _encrypt(payload, secret, salt, expiration);\n } else {\n // For encryption, we only use the newest secret, as the old secrets are only used for backward compatibility during decryption.\n const [newSecret] = secret;\n\n if (!newSecret) {\n throw new InvalidConfigurationError('At least one secret must be provided');\n }\n\n return await _encrypt(payload, newSecret, salt, expiration);\n }\n}\n\n/**\n * Decrypts an encrypted payload using the provided secret(s) and salt.\n * @param value The encrypted payload to decrypt.\n * @param secret The secret to use for decryption.\n * @param salt The salt to use for decryption.\n * @returns The decrypted payload.\n */\nexport async function _decrypt<T>(value: string, secret: string, salt: string) {\n const res = await jwtDecrypt<T>(\n value,\n async (protectedHeader) => {\n // This error shouldn't happen, as we always set a kid.\n // However, leaving this here as a safety net.\n if (!protectedHeader.kid) {\n throw new Error('Missing \"kid\" in JWE header');\n }\n\n return await deriveEncryptionSecret(secret, salt, protectedHeader.kid);\n },\n { clockTolerance: 15 }\n );\n return res.payload;\n}\n\n/**\n * Decrypts an encrypted payload using the provided secret(s) and salt.\n * The secret can be a single string or an array of strings for secret rotation support.\n * When using an array of secrets, the function will try to decrypt with each secret in order until it succeeds or exhausts all options.\n * Only decryption-related errors (JWEDecryptionFailed, JWEInvalid) will trigger fallback to old secrets.\n * Other errors (like expiration) will be thrown immediately.\n * @param value The encrypted payload to decrypt.\n * @param secret The secret(s) to use for decryption. Can be a single string or an array of strings for secret rotation support.\n * @param salt The salt to use for decryption.\n * @returns The decrypted payload.\n */\nexport async function decrypt<T>(value: string, secret: string | string[], salt: string) {\n if (typeof secret === 'string') {\n return await _decrypt<T>(value, secret, salt);\n } else {\n const [newSecret, ...oldSecrets] = secret;\n\n if (!newSecret) {\n throw new InvalidConfigurationError('At least one secret must be provided');\n }\n\n let firstError: Error | undefined;\n\n try {\n return await _decrypt<T>(value, newSecret, salt);\n } catch (err) {\n firstError = err as Error;\n\n // Only try old secrets if this is a decryption-related error\n // Other errors (like expiration) should be thrown immediately\n if (!isDecryptionError(err)) {\n throw firstError;\n }\n\n for (const oldSecret of oldSecrets) {\n try {\n return await _decrypt(value, oldSecret, salt);\n } catch (fallbackErr) {\n // Only ignore decryption errors with old secrets and continue trying with the next one\n // If it's a different type of error, throw it\n if (!isDecryptionError(fallbackErr)) {\n throw fallbackErr;\n }\n }\n }\n\n // If we've exhausted all secrets and still can't decrypt, throw the original error.\n throw firstError;\n }\n }\n}\n","import type { EncryptedStoreOptions, AbstractDataStore } from '../types.js';\nimport { encrypt, decrypt, isDecryptionError } from '../encryption/index.js';\nimport { JWTPayload } from 'jose';\n\n/**\n * Abstract class that can be used to implement an Encrypted JWT State Store, using the 'A256CBC-HS512' encryption algorithm.\n */\nexport abstract class AbstractStore<TData extends JWTPayload, TStoreOptions = unknown> implements AbstractDataStore<TData, TStoreOptions>\n{\n protected readonly options: EncryptedStoreOptions;\n\n constructor(options: EncryptedStoreOptions) {\n this.options = options;\n }\n\n abstract set(identifier: string, state: TData, removeIfExists?: boolean, options?: TStoreOptions | undefined): Promise<void>;\n abstract get(identifier: string, options?: TStoreOptions | undefined): Promise<TData | undefined>;\n abstract delete(identifier: string, options?: TStoreOptions | undefined): Promise<void>;\n\n protected async encrypt<TData extends JWTPayload>(identifier: string, stateData: TData, expiration: number) {\n return await encrypt(stateData, this.options.secret, identifier, expiration);\n }\n\n protected async decrypt<TData>(identifier: string, encryptedStateData: string) {\n try {\n return (await decrypt(encryptedStateData, this.options.secret, identifier)) as TData;\n } catch (e: unknown){\n // When the error is a decryption failure, we want to ignore it and return undefined, as this likely means the session has expired or the data is invalid.\n if (isDecryptionError(e)) {\n return;\n }\n\n throw e;\n }\n }\n}\n","import type { StateData, EncryptedStoreOptions, StateStore, LogoutTokenClaims } from '../types.js';\nimport { AbstractStore } from './abstract-store.js';\n\n/**\n * Abstract class that can be used to implement an Encrypted JWT State Store, using the 'A256CBC-HS512' encryption algorithm.\n */\nexport abstract class AbstractStateStore<TStoreOptions = unknown> extends AbstractStore<StateData, TStoreOptions> implements StateStore<TStoreOptions> {\n constructor(options: EncryptedStoreOptions) {\n super(options);\n }\n\n abstract deleteByLogoutToken(claims: LogoutTokenClaims, options?: TStoreOptions | undefined): Promise<void>;\n}","import type { EncryptedStoreOptions, TransactionData, TransactionStore } from '../types.js';\nimport { AbstractStore } from './abstract-store.js';\n\n/**\n * Abstract class that can be used to implement an Encrypted JWT Transaction Store, using the 'A256CBC-HS512' encryption algorithm.\n */\nexport abstract class AbstractTransactionStore<TStoreOptions = unknown> extends AbstractStore<TransactionData, TStoreOptions> implements TransactionStore<TStoreOptions> {\n constructor(options: EncryptedStoreOptions) {\n super(options);\n }\n}","import type { EncryptedStoreOptions, TransactionData } from './../types.js';\nimport { AbstractTransactionStore } from './abstract-transaction-store.js';\nimport type { CookieHandler, CookieSerializeOptions } from './cookie-handler.js';\n\nexport class CookieTransactionStore<TStoreOptions> extends AbstractTransactionStore<TStoreOptions> {\n readonly #cookieHandler: CookieHandler<TStoreOptions>;\n\n constructor(options: EncryptedStoreOptions, cookieHandler: CookieHandler<TStoreOptions>) {\n super(options);\n this.#cookieHandler = cookieHandler;\n }\n\n async set(\n identifier: string,\n transactionData: TransactionData,\n removeIfExists?: boolean,\n options?: TStoreOptions\n ): Promise<void> { \n const maxAge = 60 * 60;\n const cookieOpts: CookieSerializeOptions = { httpOnly: true, sameSite: 'lax', path: '/', maxAge };\n const expiration = Math.floor(Date.now() / 1000 + maxAge);\n const encryptedStateData = await this.encrypt(identifier, transactionData, expiration);\n\n this.#cookieHandler.setCookie(identifier, encryptedStateData, cookieOpts, options);\n }\n\n async get(identifier: string, options?: TStoreOptions): Promise<TransactionData | undefined> {\n const cookieValue = this.#cookieHandler.getCookie(identifier, options);\n\n if (cookieValue) {\n return await this.decrypt(identifier, cookieValue);\n }\n }\n\n async delete(identifier: string, options?: TStoreOptions | undefined): Promise<void> {\n this.#cookieHandler.deleteCookie(identifier, options);\n }\n}\n","import { AbstractStateStore } from './abstract-state-store.js';\nimport type { EncryptedStoreOptions, SessionConfiguration } from '../types.js';\n\nexport abstract class AbstractSessionStore<TStoreOptions> extends AbstractStateStore<TStoreOptions> {\n readonly #rolling: boolean;\n readonly #absoluteDuration: number;\n readonly #inactivityDuration: number;\n\n constructor(options: SessionConfiguration & EncryptedStoreOptions) {\n super(options);\n\n this.#rolling = options.rolling ?? true;\n this.#absoluteDuration = options.absoluteDuration ?? 60 * 60 * 24 * 3;\n this.#inactivityDuration = options.inactivityDuration ?? 60 * 60 * 24 * 1;\n }\n\n /**\n * calculateMaxAge calculates the max age of the session based on createdAt and the rolling and absolute durations.\n * When sessionExpiresAt is provided, caps the maxAge to not exceed the time until that ceiling.\n */\n protected calculateMaxAge(createdAt: number, sessionExpiresAt?: number) {\n const now = (Date.now() / 1000) | 0;\n\n let maxAge = this.#rolling\n ? Math.min(now + this.#inactivityDuration, createdAt + this.#absoluteDuration) - now\n : this.#absoluteDuration;\n\n if (sessionExpiresAt !== undefined) {\n maxAge = Math.min(maxAge, sessionExpiresAt - now);\n }\n\n return maxAge > 0 ? maxAge : 0;\n }\n}","import type {\n EncryptedStoreOptions,\n LogoutTokenClaims,\n SessionConfiguration,\n SessionCookieOptions,\n SessionStore,\n StateData,\n} from '../types.js';\nimport { AbstractSessionStore } from './abstract-session-store.js';\nimport type { CookieHandler, CookieSerializeOptions } from './cookie-handler.js';\n\nexport interface StatefulStateStoreOptions<TStoreOptions> extends EncryptedStoreOptions {\n store: SessionStore<TStoreOptions>;\n}\n\nconst generateId = () => {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n};\n\nexport class StatefulStateStore<TStoreOptions> extends AbstractSessionStore<TStoreOptions> {\n readonly #store: SessionStore<TStoreOptions>;\n readonly #cookieOptions: SessionCookieOptions | undefined;\n readonly #cookieHandler: CookieHandler<TStoreOptions>;\n\n constructor(\n options: StatefulStateStoreOptions<TStoreOptions> & SessionConfiguration,\n cookieHandler: CookieHandler<TStoreOptions>\n ) {\n super(options);\n\n this.#store = options.store;\n this.#cookieOptions = options.cookie;\n this.#cookieHandler = cookieHandler;\n }\n\n async set(\n identifier: string,\n stateData: StateData,\n removeIfExists?: boolean,\n options?: TStoreOptions | undefined\n ): Promise<void> {\n let sessionId = await this.getSessionId(identifier, options);\n\n // if this is a new session created by a new login we need to remove the old session\n // from the store and regenerate the session ID to prevent session fixation.\n if (sessionId && removeIfExists) {\n await this.#store.delete(sessionId);\n sessionId = generateId();\n }\n\n sessionId ??= generateId();\n\n const maxAge = this.calculateMaxAge(stateData.internal.createdAt, stateData.sessionExpiresAt);\n const cookieOpts = this.#getCookieOptions({\n maxAge,\n });\n const expiration = Date.now() / 1000 + maxAge;\n const encryptedStateData = await this.encrypt<{ id: string }>(\n identifier,\n {\n id: sessionId,\n },\n expiration\n );\n\n await this.#store.set(sessionId, stateData);\n\n this.#cookieHandler.setCookie(identifier, encryptedStateData, cookieOpts, options);\n }\n\n async get(identifier: string, options?: TStoreOptions | undefined): Promise<StateData | undefined> {\n const sessionId = await this.getSessionId(identifier, options);\n\n if (sessionId) {\n const stateData = await this.#store.get(sessionId);\n\n // If we have a session cookie, but no `stateData`, we should remove the cookie.\n if (!stateData) {\n this.#cookieHandler.deleteCookie(identifier, options, this.#getCookieOptions());\n }\n\n return stateData;\n }\n }\n\n async delete(identifier: string, options?: TStoreOptions | undefined): Promise<void> {\n const sessionId = await this.getSessionId(identifier, options);\n\n if (sessionId) {\n await this.#store.delete(sessionId);\n }\n\n this.#cookieHandler.deleteCookie(identifier, options, this.#getCookieOptions());\n }\n\n private async getSessionId(identifier: string, options?: TStoreOptions) {\n const cookieValue = this.#cookieHandler.getCookie(identifier, options);\n if (cookieValue) {\n const sessionCookie = await this.decrypt<{ id: string }>(identifier, cookieValue);\n \n if (sessionCookie) {\n return sessionCookie.id;\n }\n }\n }\n\n deleteByLogoutToken(claims: LogoutTokenClaims, options?: TStoreOptions | undefined): Promise<void> {\n return this.#store.deleteByLogoutToken(claims, options);\n }\n\n #getCookieOptions(partial?: Partial<CookieSerializeOptions>): CookieSerializeOptions {\n return {\n httpOnly: true,\n sameSite: this.#cookieOptions?.sameSite ?? 'lax',\n path: this.#cookieOptions?.path ?? '/',\n secure: this.#cookieOptions?.secure ?? true,\n ...partial,\n };\n }\n}\n","import type { EncryptedStoreOptions, SessionConfiguration, SessionCookieOptions, StateData } from '../types.js';\nimport { AbstractSessionStore } from './abstract-session-store.js';\nimport type { CookieHandler, CookieSerializeOptions } from './cookie-handler.js';\n\nexport class StatelessStateStore<TStoreOptions> extends AbstractSessionStore<TStoreOptions> {\n readonly #cookieOptions: SessionCookieOptions | undefined;\n readonly #cookieHandler: CookieHandler<TStoreOptions>;\n\n constructor(options: SessionConfiguration & EncryptedStoreOptions, cookieHandler: CookieHandler<TStoreOptions>) {\n super(options);\n\n this.#cookieOptions = options.cookie;\n this.#cookieHandler = cookieHandler;\n }\n\n async set(\n identifier: string,\n stateData: StateData,\n removeIfExists?: boolean,\n options?: TStoreOptions | undefined\n ): Promise<void> {\n const maxAge = this.calculateMaxAge(stateData.internal.createdAt, stateData.sessionExpiresAt);\n const cookieOpts = this.#getCookieOptions({\n maxAge,\n });\n const expiration = Math.floor(Date.now() / 1000 + maxAge);\n const encryptedStateData = await this.encrypt(identifier, stateData, expiration);\n\n const chunkSize = 3072;\n const chunkCount = Math.ceil(encryptedStateData.length / chunkSize);\n const chunks = [...Array(chunkCount).keys()].map((i) => ({\n value: encryptedStateData.substring(i * chunkSize, (i + 1) * chunkSize),\n name: `${identifier}.${i}`,\n }));\n\n chunks.forEach((chunk) => {\n this.#cookieHandler.setCookie(chunk.name, chunk.value, cookieOpts, options);\n });\n\n const existingCookieKeys = this.getCookieKeys(identifier, options);\n const cookieKeysToRemove = existingCookieKeys.filter((key) => !chunks.some((chunk) => chunk.name === key));\n cookieKeysToRemove.forEach((key) => {\n this.#cookieHandler.deleteCookie(key, options, cookieOpts);\n });\n }\n\n async get(identifier: string, options?: TStoreOptions | undefined): Promise<StateData | undefined> {\n const cookieKeys = this.getCookieKeys(identifier, options);\n const encryptedStateData = cookieKeys\n .map((key) => ({\n index: parseInt(key.split('.')[1] as string, 10),\n value: this.#cookieHandler.getCookie(key, options),\n }))\n .sort((a, b) => a.index - b.index)\n .map((item) => item.value)\n .join('');\n\n if (encryptedStateData) {\n return await this.decrypt(identifier, encryptedStateData);\n }\n }\n\n async delete(identifier: string, options?: TStoreOptions | undefined): Promise<void> {\n const cookieKeys = this.getCookieKeys(identifier, options);\n for (const key of cookieKeys) {\n this.#cookieHandler.deleteCookie(key, options, this.#getCookieOptions());\n }\n }\n\n deleteByLogoutToken(): Promise<void> {\n throw new Error(\n 'Backchannel logout is not available when using Stateless Storage. Use Stateful Storage by providing a `sessionStore`'\n );\n }\n\n private getCookieKeys(identifier: string, options?: TStoreOptions): string[] {\n return Object.keys(this.#cookieHandler.getCookies(options)).filter((key) => key.startsWith(identifier));\n }\n\n #getCookieOptions(partial?: Partial<CookieSerializeOptions>): CookieSerializeOptions {\n return {\n httpOnly: true,\n sameSite: this.#cookieOptions?.sameSite ?? 'lax',\n path: this.#cookieOptions?.path ?? '/',\n secure: this.#cookieOptions?.secure ?? true,\n ...partial,\n };\n }\n}\n","export { ServerMfaClient } from './server-mfa-client.js';\nexport type { MfaVerifyResponse } from './types.js';\nexport type {\n MfaFactorType,\n MfaVerifyOtpOptions,\n MfaVerifyOobOptions,\n MfaVerifyRecoveryCodeOptions,\n MfaVerifyOptions,\n} from '@auth0/auth0-auth-js';\n\n// Re-export MFA types and errors from auth0-auth-js for convenience\nexport type {\n AuthenticatorResponse,\n AuthenticatorType,\n OobChannel,\n ListAuthenticatorsOptions,\n EnrollOtpOptions,\n EnrollOobOptions,\n EnrollEmailOptions,\n EnrollAuthenticatorOptions,\n OtpEnrollmentResponse,\n OobEnrollmentResponse,\n EnrollmentResponse,\n ChallengeOptions,\n ChallengeResponse,\n MfaRequirements,\n} from '@auth0/auth0-auth-js';\n\nexport {\n MfaListAuthenticatorsError,\n MfaEnrollmentError,\n MfaChallengeError,\n MfaVerifyError,\n isMfaRequiredError,\n} from '@auth0/auth0-auth-js';\n","export { ServerPasskeyClient } from './server-passkey-client.js';\n\n// Re-export passkey error classes from auth0-auth-js for convenience, so consumers\n// can narrow thrown errors via `instanceof` without importing auth0-auth-js directly.\n// `OrganizationValidationError` is thrown by `getToken()` when an `organization` is\n// passed and the returned ID token's organization claim is missing or mismatched.\n// The passkey option/response types are re-exported from `../types.js`.\nexport {\n PasskeyRegisterError,\n PasskeyChallengeError,\n PasskeyGetTokenError,\n OrganizationValidationError,\n} from '@auth0/auth0-auth-js';\n"],"mappings":"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","names":["tokenSet","logoutTokenClaims","import_jose","import_auth0_auth_js","import_auth0_auth_js","import_auth0_auth_js"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/state/utils.ts","../src/server-client.ts","../src/utils.ts","../src/telemetry.ts","../src/mfa/server-mfa-client.ts","../src/passkey/server-passkey-client.ts","../src/encryption/index.ts","../src/store/abstract-store.ts","../src/store/abstract-state-store.ts","../src/store/abstract-transaction-store.ts","../src/store/cookie-transaction-store.ts","../src/store/abstract-session-store.ts","../src/store/stateful-state-store.ts","../src/store/stateless-state-store.ts","../src/mfa/index.ts","../src/passkey/index.ts"],"sourcesContent":["export { ServerClient } from './server-client.js';\nexport { AbstractStateStore } from './store/abstract-state-store.js';\nexport { AbstractTransactionStore } from './store/abstract-transaction-store.js';\nexport type { TokenResponse, ActClaim } from '@auth0/auth0-auth-js';\nexport { TokenExchangeError, MissingClientAuthError, OrganizationValidationError } from '@auth0/auth0-auth-js';\n\nexport type { CookieHandler, CookieSerializeOptions } from './store/cookie-handler.js';\nexport { CookieTransactionStore } from './store/cookie-transaction-store.js';\n\nexport { StatefulStateStore } from './store/stateful-state-store.js';\nexport type { StatefulStateStoreOptions } from './store/stateful-state-store.js';\nexport { StatelessStateStore } from './store/stateless-state-store.js';\n\nexport * from './errors.js';\nexport * from './types.js';\nexport * from './mfa/index.js';\nexport * from './passkey/index.js';\n","/**\n * Error thrown when there is no transaction available.\n */\nexport class MissingTransactionError extends Error {\n public code: string = 'missing_transaction_error';\n\n constructor(message?: string) {\n super(message ?? 'The transaction is missing.');\n this.name = 'MissingTransactionError';\n }\n}\n\n\n/**\n * Error thrown when backchannel logout fails.\n */\nexport class BackchannelLogoutError extends Error {\n public code: string = 'backchannel_logout_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'BackchannelLogoutError';\n }\n}\n\n/**\n * Error thrown when starting the user-linking failed.\n */\nexport class StartLinkUserError extends Error {\n public code: string = 'start_link_user_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'StartLinkUserError';\n }\n}\n\n/**\n * Error thrown when a required argument is missing.\n */\nexport class MissingRequiredArgumentError extends Error {\n public code: string = 'missing_required_argument_error';\n\n constructor(argument: string) {\n super(`The argument '${argument}' is required but was not provided.`);\n this.name = 'MissingRequiredArgumentError';\n }\n}\n\n/**\n * Error thrown when a session is missing.\n */\nexport class MissingSessionError extends Error {\n public code: string = 'missing_session_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'MissingSessionError';\n }\n}\n\n/**\n * Error thrown when a configuration is invalid.\n */\nexport class InvalidConfigurationError extends Error {\n public code: string = 'invalid_configuration_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'InvalidConfigurationError';\n }\n}\n\n/**\n * Error thrown when the issuer validation fails.\n */\nexport class IssuerValidationError extends Error {\n public code: string = 'issuer_validation_error';\n\n constructor(message: string) {\n super(message);\n this.name = 'IssuerValidationError';\n }\n}\n\n/**\n * Error thrown when the session has passed its upstream IdP-asserted\n * `session_expiry` ceiling (IPSIE SL1). The user must re-authenticate.\n */\nexport class SessionExpiredError extends Error {\n public code: string = 'session_expired';\n\n constructor(message?: string) {\n super(\n message ??\n 'The session has expired because the upstream identity provider session ceiling was reached. The user needs to re-authenticate.'\n );\n this.name = 'SessionExpiredError';\n }\n}\n","import type { AccessTokenForConnectionOptions, StateData } from '../types.js';\nimport { TokenResponse } from '@auth0/auth0-auth-js';\nimport { SessionExpiredError } from '../errors.js';\n\n/**\n * Negative leeway (in seconds) applied to the `session_expiry` ceiling to absorb\n * clock skew between the SDK and the Auth0 platform. The session is treated as\n * expired slightly BEFORE the wall-clock ceiling, never after.\n */\nexport const SESSION_EXPIRY_LEEWAY = 30;\n\n/**\n * Upper bound (exclusive) for a value to be accepted as a Unix timestamp in seconds.\n *\n * `1e10` (10,000,000,000) is the year ~2286 — far beyond any real session ceiling, yet well below\n * a millisecond timestamp for the current era (`Date.now()` is ~1.7e12). This lets us reject a\n * `session_expiry` (or `iat`) that was mistakenly provided in milliseconds: such a value would\n * otherwise look like a valid far-future seconds timestamp and silently disable the ceiling.\n * Since `session_expiry` can be set by a customer Post-Login Action, a milliseconds mix-up is a\n * realistic input, not just a platform glitch. The threshold matches the cross-SDK convention.\n */\nconst MAX_PLAUSIBLE_UNIX_SECONDS = 1e10;\n\n/**\n * Returns whether a value is a plausible Unix timestamp in seconds: a positive integer below the\n * milliseconds range. Used to reject values mistakenly expressed in milliseconds.\n */\nfunction isPlausibleUnixSeconds(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0 && value < MAX_PLAUSIBLE_UNIX_SECONDS;\n}\n\n/**\n * Reads the IPSIE `session_expiry` claim (absolute Unix seconds) from ID token claims.\n *\n * Fail-open by design: returns `undefined` (meaning \"no ceiling\") unless the value is a plausible\n * Unix-seconds timestamp (positive integer below the milliseconds range). A missing or malformed\n * claim MUST NEVER be treated as an already-expired session — a platform glitch must not lock out\n * every enterprise user. A value in milliseconds is rejected rather than accepted as a far-future\n * ceiling (which would silently disable enforcement).\n *\n * @param claims The decoded ID token claims, or undefined.\n * @returns The ceiling in Unix seconds, or undefined when absent/invalid.\n */\nexport function extractSessionExpiry(claims: TokenResponse['claims'] | undefined): number | undefined {\n const value = claims?.session_expiry;\n return isPlausibleUnixSeconds(value) ? value : undefined;\n}\n\n/**\n * Returns whether the `session_expiry` ceiling has been reached, applying the negative leeway.\n *\n * @param sessionExpiresAt The stored ceiling in Unix seconds, or undefined for \"no ceiling\".\n * @param nowSeconds Optional current time in Unix seconds (defaults to now). Injectable for tests.\n * @returns `true` when the session must be treated as expired; `false` when there is no ceiling\n * or it has not yet been reached.\n */\nexport function isSessionExpiryReached(sessionExpiresAt: number | undefined, nowSeconds?: number): boolean {\n if (sessionExpiresAt === undefined) {\n return false;\n }\n const now = nowSeconds ?? Math.floor(Date.now() / 1000);\n return now >= sessionExpiresAt - SESSION_EXPIRY_LEEWAY;\n}\n\n/**\n * Creates an updated token set object from the token endpoint response\n * @param audience The audience for which the token was requested\n * @param response The response from the token endpoint\n * @returns Updated token set object\n */\nconst createUpdatedTokenSet = (audience: string, response: TokenResponse) => ({\n audience,\n accessToken: response.accessToken,\n scope: response.scope,\n expiresAt: response.expiresAt,\n});\n\n/**\n * Returns whether a `session_expiry` ceiling is already in the past at login — i.e. the session\n * would be born expired and MUST NOT be persisted (the caller should throw `SessionExpiredError`).\n *\n * Compares the ceiling against the ID token `iat` (issued-at), or the current time when `iat` is\n * absent, applying the same negative leeway as {@link isSessionExpiryReached}. `iat` is only\n * trusted when it is a plausible Unix-seconds value; an absent or malformed `iat` (e.g.\n * milliseconds) falls back to now, so a bad `iat` cannot itself manufacture a false lockout.\n *\n * This is enforced at the login sites (interactive login, backchannel login, MFA verify) rather\n * than inside {@link updateStateData}, so the ceiling is only ever derived from a genuine\n * authentication event — never re-derived from a refresh-token response.\n *\n * Companion to {@link isSessionExpiryReached}: that one gates *reads* of an already-stored session\n * against the current wall clock (`now`), whereas this one gates *login* against the token's `iat`,\n * so a token minted with an already-past ceiling is rejected before it is ever persisted.\n *\n * @param sessionExpiresAt The extracted ceiling in Unix seconds, or undefined for \"no ceiling\".\n * @param issuedAt The ID token `iat` claim, if present.\n * @returns `true` when the ceiling is already reached at login; `false` when there is no ceiling.\n */\nexport function isSessionExpiryInPast(sessionExpiresAt: number | undefined, issuedAt?: number): boolean {\n if (sessionExpiresAt === undefined) {\n return false;\n }\n const reference = isPlausibleUnixSeconds(issuedAt) ? issuedAt : Math.floor(Date.now() / 1000);\n return sessionExpiresAt <= reference + SESSION_EXPIRY_LEEWAY;\n}\n\n/**\n * Stamps the IPSIE `session_expiry` ceiling onto freshly-built login state.\n *\n * Call this ONLY at the login sites (interactive login, backchannel login, MFA verify) — i.e.\n * with the state produced by {@link updateStateData} from a genuine authentication response.\n * It must NOT be called on the refresh path: the ceiling is write-once per authentication and\n * preserved unchanged across refreshes (see {@link updateStateData}).\n *\n * Behavior:\n * - Extracts the ceiling from the response claims (rejecting malformed/millisecond values).\n * - Throws {@link SessionExpiredError} when the ceiling is already in the past at login, so a\n * born-expired session is never persisted.\n * - Returns the state with `sessionExpiresAt` set to the extracted value. On a re-login this\n * overwrites any preserved ceiling — including clearing it (to `undefined`) when the new login\n * is through a connection that asserts no ceiling — so the value always reflects the most\n * recent authentication event.\n *\n * @param stateData The login state to stamp (from {@link updateStateData}).\n * @param claims The decoded ID token claims from the authentication response.\n * @returns The state data with `sessionExpiresAt` reflecting this login.\n * @throws {SessionExpiredError} When the ceiling is at or before the issued-at time.\n */\nexport function applySessionExpiryAtLogin(stateData: StateData, claims: TokenResponse['claims']): StateData {\n const sessionExpiresAt = extractSessionExpiry(claims);\n\n if (isSessionExpiryInPast(sessionExpiresAt, claims?.iat)) {\n throw new SessionExpiredError(\n 'The upstream identity provider session_expiry is at or before the issued-at time; refusing to create an already-expired session.'\n );\n }\n\n return { ...stateData, sessionExpiresAt };\n}\n\n/**\n * Utility function to update the state with a new response from the token endpoint\n * @param audience The audience of the token endpoint response\n * @param stateData The existing state data to update, or undefined if no state data available.\n * @param tokenEndpointResponse The response from the token endpoint.\n * @returns Updated state data.\n */\nexport function updateStateData(\n audience: string,\n stateData: StateData | undefined,\n tokenEndpointResponse: TokenResponse,\n context?: { domain?: string }\n): StateData {\n // If we already have a session and the new token belongs to a different user (iss or sub mismatch),\n // wipe the existing state to start a fresh session. This handles the case where a user logs in\n // as a different user without explicitly logging out first.\n if (stateData && tokenEndpointResponse.claims) {\n const newSub = tokenEndpointResponse.claims.sub;\n const newIss = tokenEndpointResponse.claims.iss;\n const existingSub = stateData.user?.sub;\n const existingIss = stateData.user?.iss;\n\n const subMismatch = newSub !== undefined && existingSub !== undefined && newSub !== existingSub;\n const issMismatch = newIss !== undefined && existingIss !== undefined && newIss !== existingIss;\n\n if (subMismatch || issMismatch) {\n stateData = undefined;\n }\n }\n\n if (stateData) {\n const isNewTokenSet = !stateData.tokenSets.some(\n (tokenSet) => tokenSet.audience === audience && tokenSet.scope === tokenEndpointResponse.scope\n );\n\n const tokenSets = isNewTokenSet\n ? [...stateData.tokenSets, createUpdatedTokenSet(audience, tokenEndpointResponse)]\n : stateData.tokenSets.map((tokenSet) =>\n tokenSet.audience === audience && tokenSet.scope === tokenEndpointResponse.scope\n ? createUpdatedTokenSet(audience, tokenEndpointResponse)\n : tokenSet\n );\n\n // The `session_expiry` ceiling is intentionally NOT derived here. It is stamped once at the\n // login sites (interactive login, backchannel login, MFA verify) and preserved across every\n // refresh via the `...stateData` spread below. A refresh-token grant must never overwrite the\n // ceiling — even when a Post-Login Action stamps `session_expiry` on the refreshed ID token —\n // because that would let the session outlive the bound asserted at the original login.\n return {\n ...stateData,\n idToken: tokenEndpointResponse.idToken ?? stateData.idToken,\n refreshToken: tokenEndpointResponse.refreshToken ?? stateData.refreshToken,\n tokenSets,\n domain: context?.domain ?? stateData.domain,\n };\n } else {\n const user = tokenEndpointResponse.claims;\n return {\n user,\n idToken: tokenEndpointResponse.idToken,\n refreshToken: tokenEndpointResponse.refreshToken,\n tokenSets: [createUpdatedTokenSet(audience, tokenEndpointResponse)],\n domain: context?.domain,\n internal: {\n sid: user?.sid as string,\n createdAt: Math.floor(Date.now() / 1000),\n },\n };\n }\n}\n\nexport function updateStateDataForConnectionTokenSet(\n options: AccessTokenForConnectionOptions,\n stateData: StateData,\n tokenEndpointResponse: TokenResponse\n) {\n stateData.connectionTokenSets = stateData.connectionTokenSets || [];\n\n const isNewTokenSet = !stateData.connectionTokenSets.some(\n (tokenSet) =>\n tokenSet.connection === options.connection && (!options.loginHint || tokenSet.loginHint === options.loginHint)\n );\n\n const connectionTokenSet = {\n connection: options.connection,\n loginHint: options.loginHint,\n accessToken: tokenEndpointResponse.accessToken,\n scope: tokenEndpointResponse.scope,\n expiresAt: tokenEndpointResponse.expiresAt,\n };\n\n const connectionTokenSets = isNewTokenSet\n ? [...stateData.connectionTokenSets, connectionTokenSet]\n : stateData.connectionTokenSets.map((tokenSet) =>\n tokenSet.connection === options.connection && (!options.loginHint || tokenSet.loginHint === options.loginHint)\n ? connectionTokenSet\n : tokenSet\n );\n\n return {\n ...stateData,\n connectionTokenSets,\n };\n}\n","import {\n AccessTokenForConnectionOptions,\n ConnectionTokenSet,\n CustomTokenExchangeOptions,\n DomainResolver,\n LoginBackchannelOptions,\n LoginBackchannelResult,\n LoginWithCustomTokenExchangeOptions,\n LoginWithCustomTokenExchangeResult,\n CompletePasswordlessOptions,\n CompletePasswordlessResult,\n GetAccessTokenOptions,\n LogoutOptions,\n ServerClientOptions,\n SessionData,\n StartInteractiveLoginOptions,\n StartLinkUserOptions,\n StartPasswordlessOptions,\n StartUnlinkUserOptions,\n StateData,\n StateStore,\n TokenSet,\n TransactionData,\n TransactionStore,\n} from './types.js';\nimport {\n BackchannelLogoutError,\n InvalidConfigurationError,\n MissingRequiredArgumentError,\n MissingSessionError,\n MissingTransactionError,\n SessionExpiredError,\n} from './errors.js';\nimport {\n updateStateData,\n updateStateDataForConnectionTokenSet,\n isSessionExpiryReached,\n applySessionExpiryAtLogin,\n} from './state/utils.js';\nimport {\n TokenForConnectionError,\n AuthClient,\n AuthorizationDetails,\n OrganizationValidationError,\n PasswordlessStartError,\n PasswordlessVerifyError,\n TokenByRefreshTokenError,\n TokenByRefreshTokenOptions,\n TokenResponse,\n} from '@auth0/auth0-auth-js';\nimport { compareScopes, ensureOpenIdScope } from './utils.js';\nimport { decodeJwt } from 'jose';\nimport type { AuthClientOptions } from '@auth0/auth0-auth-js';\nimport { getTelemetryConfig } from './telemetry.js';\nimport { ServerMfaClient } from './mfa/server-mfa-client.js';\nimport { ServerPasskeyClient } from './passkey/server-passkey-client.js';\n\nconst normalizeDomain = (value: string) => {\n const trimmed = value.trim();\n const parsed = trimmed.startsWith('http') ? new URL(trimmed) : new URL(`https://${trimmed}`);\n return parsed.host.toLowerCase();\n};\n\nconst decodeIssuer = (token: string) => {\n try {\n const { iss } = decodeJwt(token);\n return typeof iss === 'string' ? iss : undefined;\n } catch {\n return undefined;\n }\n};\n\nexport class ServerClient<TStoreOptions = unknown> {\n readonly #options: ServerClientOptions<TStoreOptions>;\n readonly #transactionStore: TransactionStore<TStoreOptions>;\n readonly #transactionStoreIdentifier: string;\n readonly #stateStore: StateStore<TStoreOptions>;\n readonly #stateStoreIdentifier: string;\n readonly #authClientOptions: Omit<AuthClientOptions, 'domain'>;\n readonly #staticDomain?: string;\n readonly #authClient?: AuthClient;\n readonly #mfaClient?: ServerMfaClient<TStoreOptions>;\n readonly #passkeyClient: ServerPasskeyClient<TStoreOptions>;\n\n /**\n * The underlying `authClient` instance that can be used to interact with the Auth0 Authentication API.\n * Generally, you should prefer to use the higher-level methods exposed on the `ServerClient` instance.\n *\n * This property can only be used when `domain` is configured as a static string.\n * In resolver mode (`domain` as a function), the SDK resolves the domain per request,\n * so use `ServerClient` methods instead.\n *\n * Important: the methods exposed on the `authClient` instance do not handle any session or state management.\n */\n public get authClient(): AuthClient {\n if (!this.#authClient) {\n throw new InvalidConfigurationError('authClient is only available when using a static domain configuration.');\n }\n return this.#authClient;\n }\n\n /**\n * The MFA client for managing multi-factor authentication operations.\n *\n * Provides methods to list, enroll, and challenge MFA authenticators,\n * as well as verify MFA challenges to complete authentication.\n *\n * The `verify` method integrates with the session state store, persisting tokens\n * and user data after successful MFA verification.\n *\n * This property can only be used when `domain` is configured as a static string.\n * In resolver mode (`domain` as a function), MFA is not supported.\n */\n public get mfa(): ServerMfaClient<TStoreOptions> {\n if (!this.#mfaClient) {\n throw new InvalidConfigurationError('mfa is only available when using a static domain configuration.');\n }\n return this.#mfaClient;\n }\n\n /**\n * The passkey client for signing up and logging in users with WebAuthn credentials.\n *\n * Provides `register()` and `challenge()` to request signup/login challenges, and\n * `getToken()` to exchange the resulting credential for tokens and persist the session.\n *\n * Unlike `mfa`, this property is available in both static and resolver (multi-tenant)\n * domain modes. In resolver mode, pass the same `storeOptions` to `register()`/`challenge()`\n * and `getToken()` so the credential is exchanged against the tenant that issued it.\n */\n public get passkey(): ServerPasskeyClient<TStoreOptions> {\n return this.#passkeyClient;\n }\n\n constructor(options: ServerClientOptions<TStoreOptions>) {\n this.#options = options;\n this.#stateStoreIdentifier = this.#options.stateIdentifier || '__a0_session';\n this.#transactionStoreIdentifier = this.#options.transactionIdentifier || '__a0_tx';\n this.#transactionStore = options.transactionStore;\n this.#stateStore = options.stateStore;\n\n if (!this.#options.stateStore) {\n throw new MissingRequiredArgumentError('stateStore');\n }\n\n if (!this.#options.transactionStore) {\n throw new MissingRequiredArgumentError('transactionStore');\n }\n\n if (typeof this.#options.domain !== 'string' && typeof this.#options.domain !== 'function') {\n throw new InvalidConfigurationError('domain must be a string or resolver function');\n }\n\n this.#authClientOptions = {\n clientId: this.#options.clientId,\n clientSecret: this.#options.clientSecret,\n clientAssertionSigningKey: this.#options.clientAssertionSigningKey,\n clientAssertionSigningAlg: this.#options.clientAssertionSigningAlg,\n authorizationParams: this.#options.authorizationParams,\n discoveryCache: this.#options.discoveryCache,\n customFetch: this.#options.customFetch,\n useMtls: this.#options.useMtls,\n };\n\n if (typeof this.#options.domain === 'string') {\n const domain = normalizeDomain(this.#options.domain);\n this.#staticDomain = domain;\n this.#authClient = new AuthClient({\n domain,\n ...this.#authClientOptions,\n telemetry: getTelemetryConfig(this.#options.telemetry),\n });\n\n this.#mfaClient = new ServerMfaClient({\n authClient: this.#authClient,\n domain,\n stateStore: this.#stateStore,\n stateStoreIdentifier: this.#stateStoreIdentifier,\n defaultAudience: this.#options.authorizationParams?.audience ?? 'default',\n });\n }\n\n // The passkey client resolves the domain per call, so it is available in both\n // static and resolver (multi-tenant) modes.\n this.#passkeyClient = new ServerPasskeyClient({\n resolveDomain: (storeOptions) => this.#resolveDomain(storeOptions),\n getAuthClient: (domain) => this.#getAuthClient(domain),\n stateStore: this.#stateStore,\n stateStoreIdentifier: this.#stateStoreIdentifier,\n defaultScope: this.#options.authorizationParams?.scope,\n defaultAudience: this.#options.authorizationParams?.audience,\n });\n }\n\n async #resolveDomain(storeOptions?: TStoreOptions): Promise<string> {\n if (typeof this.#options.domain === 'function') {\n const resolved = await (this.#options.domain as DomainResolver<TStoreOptions>)(storeOptions);\n if (typeof resolved !== 'string' || resolved.trim().length === 0) {\n throw new InvalidConfigurationError('domainResolver returned no domain');\n }\n return normalizeDomain(resolved);\n }\n\n return normalizeDomain(this.#options.domain);\n }\n\n #createAuthClient(domain: string): AuthClient {\n return new AuthClient({\n domain,\n ...this.#authClientOptions,\n telemetry: getTelemetryConfig(this.#options.telemetry),\n });\n }\n\n #getAuthClient(domain: string): AuthClient {\n const normalizedDomain = normalizeDomain(domain);\n if (this.#authClient && this.#staticDomain === normalizedDomain) {\n return this.#authClient;\n }\n return this.#createAuthClient(normalizedDomain);\n }\n\n #getSessionDomain(stateData: StateData): string | undefined {\n if (stateData.domain) {\n return normalizeDomain(stateData.domain);\n }\n\n if (this.#staticDomain) {\n return this.#staticDomain;\n }\n\n // Legacy sessions may not have `domain` persisted yet; infer it from ID token claims.\n const issuerFromClaims = stateData.user?.iss;\n if (typeof issuerFromClaims === 'string' && issuerFromClaims.trim().length > 0) {\n return normalizeDomain(issuerFromClaims);\n }\n\n return;\n }\n\n #isResolverMode(): boolean {\n return typeof this.#options.domain === 'function';\n }\n\n async #isSessionForCurrentDomain(stateData: StateData, storeOptions?: TStoreOptions): Promise<boolean> {\n const sessionDomain = this.#getSessionDomain(stateData);\n if (!sessionDomain) {\n return false;\n }\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n return sessionDomain === resolvedDomain;\n }\n\n /**\n * Starts the interactive login process, and returns a URL to redirect the user-agent to to request authorization at Auth0.\n *\n * When `organization` is provided (per-login option, client-level default, or via\n * `authorizationParams.organization`), it is forwarded to `/authorize` and remembered so the\n * returned ID token's organization claim can be validated in `completeInteractiveLogin`.\n *\n * @param options Optional options used to configure the interactive login process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {OrganizationValidationError} If the resolved `organization` is blank.\n * @throws {InvalidConfigurationError} If `invitation` is provided without an `organization`.\n * @throws {BuildAuthorizationUrlError} If there was an issue when building the Authorization URL.\n *\n * @returns A promise resolving to a URL object, representing the URL to redirect the user-agent to to request authorization at Auth0.\n */\n public async startInteractiveLogin(options?: StartInteractiveLoginOptions, storeOptions?: TStoreOptions) {\n const redirectUri = options?.authorizationParams?.redirect_uri ?? this.#options.authorizationParams?.redirect_uri;\n if (!redirectUri) {\n throw new MissingRequiredArgumentError('authorizationParams.redirect_uri');\n }\n\n const scope = ensureOpenIdScope(options?.authorizationParams?.scope ?? this.#options.authorizationParams?.scope);\n\n // Resolve organization in precedence order. Per-login values always win over\n // client-level values (consistent with how audience/scope/redirect_uri resolve\n // in this method): per-login option, then per-login authorizationParams, then\n // client-level option, then client-level authorizationParams. authorizationParams.organization\n // remains supported at both levels (the client-level one is merged into the\n // authorize request by the underlying AuthClient, so it must be resolved here\n // too, otherwise its claim would never be validated at callback).\n const perLoginAuthParamsOrganization =\n typeof options?.authorizationParams?.organization === 'string'\n ? options.authorizationParams.organization\n : undefined;\n const clientAuthParamsOrganization =\n typeof this.#options.authorizationParams?.organization === 'string'\n ? this.#options.authorizationParams.organization\n : undefined;\n const resolvedOrganization =\n options?.organization ??\n perLoginAuthParamsOrganization ??\n this.#options.organization ??\n clientAuthParamsOrganization;\n\n // Fail fast on a blank organization before the redirect, mirroring the\n // core's up-front check, rather than silently dropping it (and skipping\n // validation) or only surfacing the error after the round-trip to Auth0.\n if (resolvedOrganization !== undefined && !resolvedOrganization.trim()) {\n throw new OrganizationValidationError('organization must not be blank');\n }\n\n // An invitation ticket is only meaningful in the context of an organization;\n // Auth0's invitation flow requires both parameters. Fail fast rather than\n // sending an invalid authorize request. `invitation` is supported both as the\n // first-class option and via authorizationParams (which is spread into the\n // request below), so both sources are guarded.\n const hasInvitation = !!(options?.invitation || options?.authorizationParams?.invitation);\n if (hasInvitation && !resolvedOrganization) {\n throw new InvalidConfigurationError('organization is required when invitation is provided.');\n }\n\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n const { codeVerifier, authorizationUrl } = await authClient.buildAuthorizationUrl({\n pushedAuthorizationRequests: options?.pushedAuthorizationRequests,\n authorizationParams: {\n ...options?.authorizationParams,\n redirect_uri: redirectUri,\n scope,\n ...(resolvedOrganization ? { organization: resolvedOrganization } : {}),\n ...(options?.invitation ? { invitation: options.invitation } : {}),\n },\n });\n\n const transactionState: TransactionData = {\n audience: options?.authorizationParams?.audience ?? this.#options.authorizationParams?.audience,\n codeVerifier,\n domain,\n };\n\n if (resolvedOrganization) {\n transactionState.organization = resolvedOrganization;\n }\n\n if (options?.appState) {\n transactionState.appState = options.appState;\n }\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n\n return authorizationUrl;\n }\n\n /**\n * Completes the interactive login process.\n * Takes an URL, extract the Authorization Code flow query parameters and requests a token.\n * @param url The URl from which the query params should be extracted to exchange for a token.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingTransactionError} When no transaction was found.\n * @throws {TokenByCodeError} If there was an issue requesting the access token.\n * @throws {OrganizationValidationError} When an organization was requested at login and the returned ID token's organization claim is missing or does not match; nothing is persisted.\n * @throws {SessionExpiredError} When the ID token's `session_expiry` is already in the past at login (the session is born expired); nothing is persisted.\n *\n * @returns A promise resolving to an object, containing the original appState (if present) and the authorizationDetails (when RAR was used).\n */\n public async completeInteractiveLogin<TAppState = unknown>(url: URL, storeOptions?: TStoreOptions) {\n const transactionData = await this.#transactionStore.get(this.#transactionStoreIdentifier, storeOptions);\n\n if (!transactionData) {\n throw new MissingTransactionError();\n }\n\n const domain = transactionData.domain ?? (await this.#resolveDomain(storeOptions));\n const authClient = this.#getAuthClient(domain);\n const tokenEndpointResponse = await authClient.getTokenByCode(url, {\n // TransactionData.codeVerifier is optional only to accommodate magic-link transactions.\n codeVerifier: transactionData.codeVerifier!,\n organization: transactionData.organization,\n });\n\n // The transaction (and its code_verifier) is single-use and spent once the code is exchanged.\n // Delete it now — before applySessionExpiryAtLogin, which can throw the session_expiry lockout\n // — so a born-expired login does not leave the spent transaction lingering until its TTL.\n await this.#transactionStore.delete(this.#transactionStoreIdentifier, storeOptions);\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n const stateData = applySessionExpiryAtLogin(\n updateStateData(transactionData.audience ?? 'default', existingStateData, tokenEndpointResponse, {\n domain,\n }),\n tokenEndpointResponse.claims\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return { appState: transactionData.appState, authorizationDetails: tokenEndpointResponse.authorizationDetails } as {\n appState?: TAppState;\n authorizationDetails?: AuthorizationDetails[];\n };\n }\n\n /**\n * Starts the user linking process, and returns a URL to redirect the user-agent to to request authorization at Auth0.\n * @param options Options used to configure the user linking process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingSessionError} If there is no active session.\n * @throws {BuildLinkUserUrlError} If there was an issue when building the Authorization URL.\n * @throws {SessionExpiredError} When the session's `session_expiry` ceiling has been reached; the session is cleared and re-authentication is required.\n *\n * @returns A promise resolving to a URL object, representing the URL to redirect the user-agent to to request authorization at Auth0.\n */\n public async startLinkUser(options: StartLinkUserOptions, storeOptions?: TStoreOptions) {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (!stateData || !stateData.idToken) {\n throw new MissingSessionError(\n 'Unable to start the user linking process without a logged in user. Ensure to login using the SDK before starting the user linking process.'\n );\n }\n\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n throw new SessionExpiredError();\n }\n\n const domain = this.#getSessionDomain(stateData)!;\n const authClient = this.#getAuthClient(domain);\n const { linkUserUrl, codeVerifier } = await authClient.buildLinkUserUrl({\n connection: options.connection,\n connectionScope: options.connectionScope,\n idToken: stateData.idToken,\n authorizationParams: options.authorizationParams,\n });\n\n const transactionState: TransactionData = {\n audience: options?.authorizationParams?.audience ?? this.#options.authorizationParams?.audience,\n codeVerifier,\n domain,\n };\n\n if (options?.appState) {\n transactionState.appState = options.appState;\n }\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n\n return linkUserUrl;\n }\n\n /**\n * Completes the user linking process.\n * Takes an URL, extract the Authorization Code flow query parameters and requests a token.\n * @param url The URl from which the query params should be extracted to exchange for a token.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingTransactionError} When no transaction was found.\n * @throws {TokenByCodeError} If there was an issue requesting the access token.\n *\n * @returns A promise resolving to an object, containing the original appState (if present).\n */\n public async completeLinkUser<TAppState = unknown>(url: URL, storeOptions?: TStoreOptions) {\n // In order to complete the link user flow, we need to exchange the code for a token in the same\n // way as we do for the interactive login flow.\n const result = await this.completeInteractiveLogin<TAppState>(url, storeOptions);\n\n // As we currently do not support RAR when starting the user linking flow, we will ommit it from being returned as optional altogether.\n return {\n appState: result.appState,\n };\n }\n\n /**\n * Starts the user unlinking process, and returns a URL to redirect the user-agent to to initialize user unlinking at Auth0.\n * @param options Options used to configure the user unlinking process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingSessionError} If there is no active session.\n * @throws {BuildUnlinkUserUrlError} If there was an issue when building the User Unlinking URL.\n * @throws {SessionExpiredError} When the session's `session_expiry` ceiling has been reached; the session is cleared and re-authentication is required.\n *\n * @returns A promise resolving to a URL object, representing the URL to redirect the user-agent to to request authorization at Auth0.\n */\n public async startUnlinkUser(options: StartUnlinkUserOptions, storeOptions?: TStoreOptions) {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (!stateData || !stateData.idToken) {\n throw new MissingSessionError(\n 'Unable to start the user unlinking process without a logged in user. Ensure to login using the SDK before starting the user unlinking process.'\n );\n }\n\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n throw new SessionExpiredError();\n }\n\n const domain = this.#getSessionDomain(stateData)!;\n const authClient = this.#getAuthClient(domain);\n const { unlinkUserUrl, codeVerifier } = await authClient.buildUnlinkUserUrl({\n connection: options.connection,\n idToken: stateData.idToken,\n authorizationParams: options.authorizationParams,\n });\n\n const transactionState: TransactionData = {\n audience: options?.authorizationParams?.audience ?? this.#options.authorizationParams?.audience,\n codeVerifier,\n domain,\n };\n\n if (options?.appState) {\n transactionState.appState = options.appState;\n }\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n\n return unlinkUserUrl;\n }\n\n /**\n * Completes the user unlinking process.\n * Takes an URL, extract the Authorization Code flow query parameters and requests a token.\n * @param url The URl from which the query params should be extracted to exchange for a token.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {MissingTransactionError} When no transaction was found.\n * @throws {TokenByCodeError} If there was an issue requesting the access token.\n *\n * @returns A promise resolving to an object, containing the original appState (if present).\n */\n public async completeUnlinkUser<TAppState = unknown>(url: URL, storeOptions?: TStoreOptions) {\n // In order to complete the link user flow, we need to exchange the code for a token in the same\n // way as we do for the interactive login flow.\n const result = await this.completeInteractiveLogin<TAppState>(url, storeOptions);\n\n // As we currently do not support RAR when starting the user unlinking flow, we will ommit it from being returned as optional altogether.\n return {\n appState: result.appState,\n };\n }\n\n /**\n * Logs in using Client-Initiated Backchannel Authentication.\n *\n * Using Client-Initiated Backchannel Authentication requires the feature to be enabled in the Auth0 dashboard.\n * @see https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-initiated-backchannel-authentication-flow\n * @param options Options used to configure the backchannel login process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {BackchannelAuthenticationError} If there was an issue when doing backchannel authentication.\n * @throws {SessionExpiredError} When the ID token's `session_expiry` is already in the past at login (the session is born expired); nothing is persisted.\n *\n * @returns A promise resolving to an object, containing the authorizationDetails (when RAR was used).\n */\n public async loginBackchannel(\n options: LoginBackchannelOptions,\n storeOptions?: TStoreOptions\n ): Promise<LoginBackchannelResult> {\n const scope = ensureOpenIdScope(options.authorizationParams?.scope ?? this.#options.authorizationParams?.scope);\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n const tokenEndpointResponse = await authClient.backchannelAuthentication({\n bindingMessage: options.bindingMessage,\n loginHint: options.loginHint,\n authorizationParams: {\n ...options.authorizationParams,\n scope,\n },\n });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const stateData = applySessionExpiryAtLogin(\n updateStateData(this.#options.authorizationParams?.audience ?? 'default', existingStateData, tokenEndpointResponse, {\n domain,\n }),\n tokenEndpointResponse.claims\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n\n /**\n * Starts a passwordless flow by sending a one-time code (OTP) or a magic link.\n *\n * Discriminated on `connection` (and, for email, `send`) to mirror the\n * `@auth0/nextjs-auth0` `passwordless.start()` surface:\n * - `{ connection: 'email' }` / `{ connection: 'email', send: 'code' }` — email OTP\n * - `{ connection: 'email', send: 'link', redirectUri }` — email magic link\n * - `{ connection: 'sms' }` — SMS OTP\n *\n * OTP modes are a stateless passthrough to the Authentication API (no session, no transaction);\n * complete them with {@link ServerClient#completePasswordless}.\n *\n * Magic-link mode is stateful: the SDK generates an opaque anti-forgery `state`, sends the link\n * with the OAuth parameters embedded (`redirect_uri`, `response_type=code`, `scope`, `state`),\n * and persists a transaction carrying that `state`. NO PKCE challenge is registered, so the\n * transaction holds no `codeVerifier`. Complete it with\n * {@link ServerClient#completePasswordlessMagicLink}. Requires the tenant setting\n * `allow_magiclink_verify_without_session: true` for server-side completion.\n *\n * @param options Discriminated start options.\n * @param storeOptions Optional options passed to the resolver / stores.\n *\n * @throws {PasswordlessStartError} If the request fails, or if a magic link is requested without a `redirectUri`.\n *\n * @example\n * // Email OTP\n * await serverClient.startPasswordless({ connection: 'email', email: 'user@example.com' });\n * // SMS OTP\n * await serverClient.startPasswordless({ connection: 'sms', phoneNumber: '+14155550100' });\n * // Email magic link\n * await serverClient.startPasswordless({\n * connection: 'email',\n * email: 'user@example.com',\n * send: 'link',\n * redirectUri: 'https://app.example.com/auth/callback',\n * });\n */\n public async startPasswordless(\n options: StartPasswordlessOptions,\n storeOptions?: TStoreOptions\n ): Promise<void> {\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n\n if (options.connection === 'sms') {\n await authClient.passwordless.sendSms({\n phoneNumber: options.phoneNumber,\n language: options.language,\n });\n return;\n }\n\n // Email OTP\n if (options.send !== 'link') {\n await authClient.passwordless.sendEmail({\n email: options.email,\n send: 'code',\n language: options.language,\n });\n return;\n }\n\n // Email magic link (stateful)\n if (!options.redirectUri || typeof options.redirectUri !== 'string') {\n throw new PasswordlessStartError('redirectUri is required to start a passwordless magic-link login.');\n }\n\n const state = crypto.randomUUID();\n const scope = ensureOpenIdScope(options.scope ?? this.#options.authorizationParams?.scope);\n const audience = options.audience ?? this.#options.authorizationParams?.audience;\n\n await authClient.passwordless.sendEmail({\n email: options.email,\n send: 'link',\n language: options.language,\n authParams: {\n ...options.authParams,\n redirect_uri: options.redirectUri,\n response_type: 'code',\n scope,\n ...(audience ? { audience } : {}),\n state,\n },\n });\n\n const transactionState: TransactionData = {\n audience,\n domain,\n state,\n };\n\n await this.#transactionStore.set(this.#transactionStoreIdentifier, transactionState, false, storeOptions);\n }\n\n /**\n * Completes a passwordless OTP login and persists the resulting session.\n *\n * Discriminated on `connection` to mirror the `@auth0/nextjs-auth0` `passwordless.verify()`\n * surface. Non-redirect flow: no PKCE and no transaction store (mirrors\n * {@link ServerClient#loginBackchannel}). The `openid` scope is always ensured by this layer.\n *\n * Note: the state store is read-then-written; if your deployment performs concurrent\n * logins for the same session identifier, use a state store with atomic/serializable\n * writes to avoid last-write-wins races.\n *\n * @param options Discriminated completion options (`connection`, identifier, `verificationCode`).\n * @param storeOptions Optional options passed to the resolver / stores.\n *\n * @throws {PasswordlessVerifyError} If the code is invalid, expired, or rate-limited. When the\n * connection requires MFA, the server responds with `mfa_required`; narrow the thrown error\n * with `isMfaRequiredError(error)` to read `cause.mfa_token`.\n *\n * @returns A promise resolving to the authorizationDetails (when RAR was used).\n */\n public async completePasswordless(\n options: CompletePasswordlessOptions,\n storeOptions?: TStoreOptions\n ): Promise<CompletePasswordlessResult> {\n const scope = ensureOpenIdScope(options.authorizationParams?.scope ?? this.#options.authorizationParams?.scope);\n const audience = options.authorizationParams?.audience ?? this.#options.authorizationParams?.audience;\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n\n const tokenEndpointResponse =\n options.connection === 'sms'\n ? await authClient.getTokenByPasswordlessSms({\n phoneNumber: options.phoneNumber,\n code: options.verificationCode,\n audience,\n scope,\n })\n : await authClient.getTokenByPasswordlessEmail({\n email: options.email,\n code: options.verificationCode,\n audience,\n scope,\n });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const stateData = updateStateData(\n this.#options.authorizationParams?.audience ?? 'default',\n existingStateData,\n tokenEndpointResponse,\n { domain }\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n\n /**\n * Completes a passwordless magic-link login and persists the resulting session.\n *\n * Loads the transaction persisted by {@link ServerClient#startPasswordless} (magic-link mode), validates the\n * `state` returned on the callback URL against the stored `state` (anti-forgery binding), exchanges\n * the authorization code WITHOUT PKCE, writes the session, and deletes the transaction. The existing\n * interactive login path ({@link ServerClient#completeInteractiveLogin}) is not used.\n *\n * @param url The callback URL containing the authorization `code` and `state`.\n * @param storeOptions Optional options passed to the resolver / stores.\n *\n * @throws {MissingTransactionError} If no magic-link transaction was found.\n * @throws {PasswordlessVerifyError} If the returned `state` is missing or does not match.\n * @throws {TokenByCodeError} If the token exchange fails.\n *\n * @returns A promise resolving to the authorizationDetails (when RAR was used).\n *\n * @example\n * const result = await serverClient.completePasswordlessMagicLink(callbackUrl, storeOptions);\n */\n public async completePasswordlessMagicLink(\n url: URL,\n storeOptions?: TStoreOptions\n ): Promise<CompletePasswordlessResult> {\n const transactionData = await this.#transactionStore.get(this.#transactionStoreIdentifier, storeOptions);\n\n if (!transactionData) {\n throw new MissingTransactionError();\n }\n\n // TransactionData.state is `unknown` ([key: string]: unknown); validate the type\n // rather than assert it, so a non-string state (e.g. number from a custom store)\n // falls through to the mismatch branch instead of comparing wrongly.\n const expectedState = typeof transactionData.state === 'string' ? transactionData.state : undefined;\n const returnedState = url.searchParams.get('state');\n if (!returnedState || !expectedState || returnedState !== expectedState) {\n throw new PasswordlessVerifyError('State mismatch on magic-link callback');\n }\n\n const domain = transactionData.domain ?? (await this.#resolveDomain(storeOptions));\n const authClient = this.#getAuthClient(domain);\n\n // Belt-and-suspenders: `expectedState` is re-validated inside getTokenByMagicLinkCode\n // (openid-client's anti-forgery binding). This is intentionally redundant with the\n // manual check above — do not remove one without auditing the other.\n const tokenEndpointResponse = await authClient.getTokenByMagicLinkCode(url, { expectedState });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const stateData = updateStateData(transactionData.audience ?? 'default', existingStateData, tokenEndpointResponse, {\n domain,\n });\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n await this.#transactionStore.delete(this.#transactionStoreIdentifier, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n\n /**\n * Retrieves the user from the store, or undefined if no user found.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n * @returns The user, or undefined if no user found in the store.\n */\n public async getUser(storeOptions?: TStoreOptions) {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (!stateData) {\n return;\n }\n\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n return;\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n return;\n }\n\n return stateData.user;\n }\n\n /**\n * Retrieve the user session from the store, or undefined if no session found.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n * @returns The session or undefined if no session found in the store.\n */\n public async getSession(storeOptions?: TStoreOptions): Promise<SessionData | undefined> {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n if (stateData) {\n if (this.#isResolverMode()) {\n const isCurrentDomain = await this.#isSessionForCurrentDomain(stateData, storeOptions);\n if (!isCurrentDomain) {\n return;\n }\n }\n\n if (isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { internal, ...sessionData } = stateData;\n return sessionData;\n }\n }\n\n // TEMPORARY: Overloads for backwards compatibility in minor version.\n // In the next major version, remove the first overload and use only the second signature.\n public async getAccessToken(storeOptions?: TStoreOptions): Promise<TokenSet>;\n public async getAccessToken(options: GetAccessTokenOptions, storeOptions?: TStoreOptions): Promise<TokenSet>;\n /**\n * Retrieves the access token from the store, or calls Auth0 when the access token is expired and a refresh token is available in the store.\n * Also updates the store when a new token was retrieved from Auth0.\n *\n * When `options.audience` and/or `options.scope` are provided, the SDK uses the session's refresh token to\n * request an access token for that audience/scope (Multi-Resource Refresh Tokens). Tokens are cached per\n * audience and scope combination.\n *\n * @param options Optional options for requesting a specific audience/scope.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {TokenByRefreshTokenError} If the refresh token was not found or there was an issue requesting the access token. When the cause is `mfa_required`, use `isMfaRequiredError(error)` to narrow the error and read `cause.mfa_token`.\n * @throws {SessionExpiredError} When the session's `session_expiry` ceiling has been reached; the session is cleared and no refresh is attempted — the user must re-authenticate.\n *\n * @returns The Token Set, containing the access token, as well as additional information.\n */\n public async getAccessToken(\n tokenOptionsOrStoreOptions?: GetAccessTokenOptions | TStoreOptions,\n storeOptions?: TStoreOptions\n ): Promise<TokenSet> {\n // TEMPORARY: Detect if first arg is GetAccessTokenOptions (has audience/scope)\n // or storeOptions (old behavior). Remove in next major version.\n const hasTokenOptions =\n // If second arg exists, first arg must be GetAccessTokenOptions\n storeOptions !== undefined ||\n // OR if first arg has audience/scope properties\n (!!tokenOptionsOrStoreOptions &&\n typeof tokenOptionsOrStoreOptions === 'object' &&\n ('audience' in tokenOptionsOrStoreOptions || 'scope' in tokenOptionsOrStoreOptions));\n\n const [resolvedOptions, resolvedStoreOptions] = hasTokenOptions\n ? [tokenOptionsOrStoreOptions as GetAccessTokenOptions, storeOptions]\n : [undefined, tokenOptionsOrStoreOptions as TStoreOptions];\n\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, resolvedStoreOptions);\n // The requested audience as sent to Auth0. `undefined` means \"no specific audience\" and is\n // intentionally not sent on the wire. `'default'` below is only a synthetic cache key.\n const requestedAudience = resolvedOptions?.audience ?? this.#options.authorizationParams?.audience;\n const audience = requestedAudience ?? 'default';\n const scope = resolvedOptions?.scope ?? this.#options.authorizationParams?.scope;\n\n const sessionDomain = stateData ? this.#getSessionDomain(stateData) : this.#staticDomain;\n if (this.#isResolverMode()) {\n if (!stateData) {\n throw new MissingSessionError('Unable to retrieve access token without a logged in user.');\n }\n if (!sessionDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n const resolvedDomain = await this.#resolveDomain(resolvedStoreOptions);\n if (sessionDomain !== resolvedDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n if (stateData && isSessionExpiryReached(stateData.sessionExpiresAt)) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, resolvedStoreOptions);\n throw new SessionExpiredError();\n }\n\n const tokenSet = stateData?.tokenSets.find(\n (tokenSet) => tokenSet.audience === audience && (!scope || compareScopes(tokenSet.scope, scope))\n );\n\n if (tokenSet && tokenSet.expiresAt > Date.now() / 1000) {\n return tokenSet;\n }\n\n if (!stateData?.refreshToken) {\n throw new TokenByRefreshTokenError(\n 'The access token has expired and a refresh token was not provided. The user needs to re-authenticate.'\n );\n }\n\n const domainForSession = sessionDomain!;\n const tokenByRefreshTokenOptions: TokenByRefreshTokenOptions = {\n refreshToken: stateData.refreshToken,\n // Only forward audience/scope to Auth0 when token options were explicitly supplied, and\n // never send the synthetic 'default' cache-key audience as a real request parameter.\n ...(hasTokenOptions && {\n ...(requestedAudience && { audience: requestedAudience }),\n ...(scope && { scope }),\n }),\n };\n\n const tokenEndpointResponse =\n await this.#getAuthClient(domainForSession).getTokenByRefreshToken(tokenByRefreshTokenOptions);\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, resolvedStoreOptions);\n const updatedStateData = updateStateData(audience, existingStateData, tokenEndpointResponse, {\n domain: domainForSession,\n });\n\n await this.#stateStore.set(this.#stateStoreIdentifier, updatedStateData, false, resolvedStoreOptions);\n\n return {\n accessToken: tokenEndpointResponse.accessToken,\n scope: tokenEndpointResponse.scope,\n expiresAt: tokenEndpointResponse.expiresAt,\n audience: audience,\n };\n }\n\n /**\n * Retrieves an access token for a connection.\n *\n * This method attempts to obtain an access token for a specified connection.\n * It first checks if a refresh token exists in the store.\n * If no refresh token is found, it throws an `AccessTokenForConnectionError` indicating\n * that the refresh token was not found.\n *\n * @param options - Options for retrieving an access token for a connection.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {TokenForConnectionError} If the refresh token was not found or there was an issue requesting the access token.\n *\n * @returns The Connection Token Set, containing the access token for the connection, as well as additional information.\n */\n public async getAccessTokenForConnection(\n options: AccessTokenForConnectionOptions,\n storeOptions?: TStoreOptions\n ): Promise<ConnectionTokenSet> {\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n\n const sessionDomain = stateData ? this.#getSessionDomain(stateData) : this.#staticDomain;\n if (this.#isResolverMode()) {\n if (!stateData) {\n throw new MissingSessionError('Unable to retrieve an access token for a connection without a logged in user.');\n }\n if (!sessionDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n if (sessionDomain !== resolvedDomain) {\n throw new MissingSessionError('Session domain does not match the current domain.');\n }\n }\n\n // NOTE: the IPSIE `session_expiry` ceiling is intentionally NOT enforced here. Connection\n // (Token Vault) tokens are the upstream IdP's own tokens — Auth0 stores and returns them, it\n // does not mint them — so their lifetime is governed by the upstream IdP's `expires_in`, not by\n // the Auth0 app-session ceiling. Gating this path would reject a connection-token fetch that\n // should still succeed. (The ceiling IS enforced on getAccessToken/getUser/getSession and the\n // link/unlink flows, which depend on the Auth0 session itself.)\n const connectionTokenSet = stateData?.connectionTokenSets?.find(\n (tokenSet) => tokenSet.connection === options.connection\n );\n\n if (connectionTokenSet && connectionTokenSet.expiresAt > Date.now() / 1000) {\n return connectionTokenSet;\n }\n\n if (!stateData?.refreshToken) {\n throw new TokenForConnectionError(\n 'A refresh token was not found but is required to be able to retrieve an access token for a connection.'\n );\n }\n\n const domainForSession = sessionDomain!;\n const tokenEndpointResponse = await this.#getAuthClient(domainForSession).getTokenForConnection({\n connection: options.connection,\n loginHint: options.loginHint,\n refreshToken: stateData.refreshToken,\n });\n\n const updatedStateData = updateStateDataForConnectionTokenSet(\n options,\n {\n ...stateData,\n domain: stateData.domain ?? domainForSession,\n },\n tokenEndpointResponse\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, updatedStateData, false, storeOptions);\n\n return {\n accessToken: tokenEndpointResponse.accessToken,\n scope: tokenEndpointResponse.scope,\n expiresAt: tokenEndpointResponse.expiresAt,\n connection: options.connection,\n loginHint: options.loginHint,\n };\n }\n\n /**\n * Logs the user out and returns a URL to redirect the user-agent to after they log out.\n * @param options Options used to configure the logout process.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n * @returns {URL}\n */\n public async logout(options: LogoutOptions, storeOptions?: TStoreOptions) {\n if (!this.#isResolverMode()) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n return this.authClient.buildLogoutUrl(options);\n }\n\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(resolvedDomain);\n const stateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n const sessionDomain = stateData ? this.#getSessionDomain(stateData) : undefined;\n\n if (!stateData) {\n // No local session, still return a logout URL for the current domain.\n return authClient.buildLogoutUrl(options);\n }\n\n if (sessionDomain && sessionDomain === resolvedDomain) {\n await this.#stateStore.delete(this.#stateStoreIdentifier, storeOptions);\n }\n\n return authClient.buildLogoutUrl(options);\n }\n\n /**\n * Exchanges a custom token for Auth0 tokens and persists the resulting session (RFC 8693).\n *\n * Calls the token endpoint using the RFC 8693 Token Exchange grant, then stores the\n * resulting tokens in the StateStore — effectively logging the user in without an\n * interactive browser flow. Use this when the caller already holds a trusted external\n * token (e.g. a Google ID token, a legacy system token) and wants to establish an\n * Auth0 session from it.\n *\n * Requires a Token Exchange Profile configured in your Auth0 tenant.\n *\n * @param options Options for the custom token exchange, including the subject token and its type.\n * @param storeOptions Optional options passed to the StateStore.\n *\n * @throws {TokenExchangeError} If the exchange fails or the subject token is invalid.\n * @throws {MissingClientAuthError} If client credentials are not configured.\n *\n * @returns A promise resolving to an object containing `authorizationDetails` when RAR was used.\n */\n public async loginWithCustomTokenExchange(\n options: LoginWithCustomTokenExchangeOptions,\n storeOptions?: TStoreOptions\n ): Promise<LoginWithCustomTokenExchangeResult> {\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n const tokenEndpointResponse = await authClient.exchangeToken({\n ...options,\n scope: ensureOpenIdScope(options.scope),\n });\n\n const existingStateData = await this.#stateStore.get(this.#stateStoreIdentifier, storeOptions);\n const stateData = updateStateData(\n this.#options.authorizationParams?.audience ?? 'default',\n existingStateData,\n tokenEndpointResponse,\n { domain }\n );\n\n await this.#stateStore.set(this.#stateStoreIdentifier, stateData, true, storeOptions);\n\n return { authorizationDetails: tokenEndpointResponse.authorizationDetails };\n }\n\n /**\n * Exchanges a custom token for Auth0 tokens without establishing a session (RFC 8693).\n *\n * Performs the same RFC 8693 Token Exchange as `loginWithCustomTokenExchange` but\n * returns the raw token response without writing anything to the StateStore. Use this\n * for delegation or impersonation flows where you need downstream tokens but do not\n * want to create or modify the current user session.\n *\n * Requires a Token Exchange Profile configured in your Auth0 tenant.\n *\n * @param options Options for the custom token exchange, including the subject token and its type.\n * @param storeOptions Optional options passed to the StateStore (used only for domain resolution in resolver mode).\n *\n * @throws {TokenExchangeError} If the exchange fails or the subject token is invalid.\n * @throws {MissingClientAuthError} If client credentials are not configured.\n *\n * @returns A promise resolving to the token response from Auth0.\n */\n public async customTokenExchange(\n options: CustomTokenExchangeOptions,\n storeOptions?: TStoreOptions\n ): Promise<TokenResponse> {\n const domain = await this.#resolveDomain(storeOptions);\n const authClient = this.#getAuthClient(domain);\n return authClient.exchangeToken(options);\n }\n\n /**\n * Handles the backchannel logout process by verifying the logout token and deleting the session from the store if the logout token was considered valid.\n * @param logoutToken The logout token to verify and use to delete the session from the store.\n * @param storeOptions Optional options used to pass to the Transaction and State Store.\n *\n * @throws {BackchannelLogoutError} If the logout token is missing.\n * @throws {VerifyLogoutTokenError} If the logout token is invalid.\n */\n public async handleBackchannelLogout(logoutToken: string, storeOptions?: TStoreOptions) {\n if (!logoutToken) {\n throw new BackchannelLogoutError('Missing Logout Token');\n }\n\n if (!this.#isResolverMode()) {\n const logoutTokenClaims = await this.authClient.verifyLogoutToken({ logoutToken });\n await this.#stateStore.deleteByLogoutToken(logoutTokenClaims, storeOptions);\n return;\n }\n\n const issuer = decodeIssuer(logoutToken);\n if (!issuer) {\n throw new BackchannelLogoutError('Logout token is missing an issuer');\n }\n\n const resolvedDomain = await this.#resolveDomain(storeOptions);\n const domain = normalizeDomain(issuer);\n if (domain !== resolvedDomain) {\n throw new BackchannelLogoutError('Logout token issuer does not match the resolved domain');\n }\n\n const authClient = this.#getAuthClient(domain);\n const logoutTokenClaims = await authClient.verifyLogoutToken({ logoutToken });\n\n await this.#stateStore.deleteByLogoutToken({ ...logoutTokenClaims, iss: issuer }, storeOptions);\n }\n}\n","export const DEFAULT_SCOPES = 'openid profile email offline_access';\n\n/**\n * Ensures that the \"openid\" scope is always included in the scope string.\n *\n * @param scope - The scope provided by the user (optional)\n * @returns A scope string that includes \"openid\" if it was not already present.\n */\nexport const ensureOpenIdScope = (scope?: string) => {\n const normalizedScope = scope?.trim();\n if (!normalizedScope) {\n return DEFAULT_SCOPES;\n }\n\n const scopes = normalizedScope.split(/\\s+/);\n if (!scopes.includes('openid')) {\n scopes.unshift('openid');\n }\n\n return scopes.join(' ');\n};\n\n/**\n * Compares two sets of scopes to determine if all required scopes are present in the provided scopes.\n * @param scopes Scopes to compare\n * @param requiredScopes Scopes required to be present in the scopes\n * @returns True if all required scopes are present in the scopes, false otherwise\n */\nexport const compareScopes = (scopes: string | undefined, requiredScopes: string | undefined) => {\n // When the scopes and requiredScopes are exactly the same, return true\n // This handles cases where both are empty or undefined or both are the same string\n if (scopes === requiredScopes) {\n return true;\n }\n\n if (!scopes || !requiredScopes) {\n return false;\n }\n\n const scopesSet = new Set(scopes.trim().split(' ').filter(Boolean));\n const requiredScopesArray = requiredScopes.trim().split(' ').filter(Boolean);\n\n return requiredScopesArray.every((scope) => scopesSet.has(scope));\n};\n","import { TelemetryConfig } from '@auth0/auth0-auth-js';\n\n// These constants are injected at build time via tsup\ndeclare const __AUTH0_SERVER_JS_PACKAGE_NAME__: string;\ndeclare const __AUTH0_SERVER_JS_PACKAGE_VERSION__: string;\n\nexport function getTelemetryConfig(config?: TelemetryConfig): TelemetryConfig {\n if (config?.enabled === false) {\n return config;\n }\n\n return {\n enabled: true,\n name: config?.name ?? __AUTH0_SERVER_JS_PACKAGE_NAME__,\n version: config?.version ?? __AUTH0_SERVER_JS_PACKAGE_VERSION__,\n };\n}\n","import { updateStateData, applySessionExpiryAtLogin } from '../state/utils.js';\nimport type { ServerMfaClientOptions, MfaVerifyResponse } from './types.js';\nimport type {\n ListAuthenticatorsOptions,\n AuthenticatorResponse,\n EnrollAuthenticatorOptions,\n EnrollmentResponse,\n ChallengeOptions,\n ChallengeResponse,\n MfaVerifyOptions,\n} from '@auth0/auth0-auth-js';\n\nexport class ServerMfaClient<TStoreOptions = unknown> {\n readonly #options: ServerMfaClientOptions<TStoreOptions>;\n\n /**\n * @internal\n */\n constructor(options: ServerMfaClientOptions<TStoreOptions>) {\n this.#options = options;\n }\n\n /**\n * Lists all MFA authenticators enrolled by the user.\n *\n * @param options - Options for listing authenticators\n * @returns Promise resolving to an array of enrolled authenticators\n * @throws {MfaListAuthenticatorsError} When the request fails\n */\n async listAuthenticators(options: ListAuthenticatorsOptions): Promise<AuthenticatorResponse[]> {\n return this.#options.authClient.mfa.listAuthenticators(options);\n }\n\n /**\n * Enrolls a new MFA authenticator for the user.\n *\n * @param options - Enrollment options\n * @returns Promise resolving to enrollment response with authenticator details\n * @throws {MfaEnrollmentError} When enrollment fails\n */\n async enrollAuthenticator(options: EnrollAuthenticatorOptions): Promise<EnrollmentResponse> {\n return this.#options.authClient.mfa.enrollAuthenticator(options);\n }\n\n /**\n * Initiates an MFA challenge for user verification.\n *\n * @param options - Challenge options\n * @returns Promise resolving to challenge response with challenge details\n * @throws {MfaChallengeError} When the challenge fails\n */\n async challengeAuthenticator(options: ChallengeOptions): Promise<ChallengeResponse> {\n return this.#options.authClient.mfa.challengeAuthenticator(options);\n }\n\n /**\n * Verifies an MFA challenge and completes the authentication flow.\n *\n * Exchanges the MFA token and verification code for access, ID, and refresh tokens,\n * then saves them into the user's session automatically.\n *\n * @param options - The MFA token, factor type (otp / oob / recovery-code), and the code to verify\n * @param storeOptions - Optional options forwarded to the session store. Can be omitted when\n * using the built-in stores; required if your custom store needs extra context (e.g. a request object).\n * @returns The tokens returned by Auth0 after successful verification\n * @throws {MfaVerifyError} When verification fails (e.g. invalid token, wrong code)\n */\n async verify(options: MfaVerifyOptions, storeOptions?: TStoreOptions): Promise<MfaVerifyResponse> {\n const tokenResponse = await this.#options.authClient.mfa.verify(options);\n\n const audience = options.audience ?? this.#options.defaultAudience;\n const existingStateData = await this.#options.stateStore.get(\n this.#options.stateStoreIdentifier,\n storeOptions\n );\n\n const updatedStateData = applySessionExpiryAtLogin(\n updateStateData(audience, existingStateData, tokenResponse, {\n domain: this.#options.domain,\n }),\n tokenResponse.claims\n );\n\n await this.#options.stateStore.set(\n this.#options.stateStoreIdentifier,\n updatedStateData,\n true,\n storeOptions\n );\n\n const result: MfaVerifyResponse = {\n accessToken: tokenResponse.accessToken,\n tokenType: tokenResponse.tokenType ?? 'bearer',\n expiresAt: tokenResponse.expiresAt,\n scope: tokenResponse.scope,\n };\n\n if (tokenResponse.idToken) result.idToken = tokenResponse.idToken;\n if (tokenResponse.refreshToken) result.refreshToken = tokenResponse.refreshToken;\n if (tokenResponse.recoveryCode) result.recoveryCode = tokenResponse.recoveryCode;\n\n return result;\n }\n}\n","import { updateStateData } from '../state/utils.js';\nimport { ensureOpenIdScope } from '../utils.js';\nimport type { ServerPasskeyClientOptions } from './types.js';\nimport type {\n PasskeyRegisterOptions,\n PasskeyRegisterResponse,\n PasskeyChallengeOptions,\n PasskeyChallengeResponse,\n PasskeyGetTokenOptions,\n PasskeyGetTokenResult,\n} from '../types.js';\n\nexport class ServerPasskeyClient<TStoreOptions = unknown> {\n readonly #options: ServerPasskeyClientOptions<TStoreOptions>;\n\n /**\n * @internal\n */\n constructor(options: ServerPasskeyClientOptions<TStoreOptions>) {\n this.#options = options;\n }\n\n /**\n * Requests a passkey signup challenge for a new user.\n *\n * Returns the `authSession` and the WebAuthn credential creation options\n * (`authnParamsPublicKey`). The application must return these to the browser,\n * pass `authnParamsPublicKey` to `navigator.credentials.create()`, and then\n * call `getToken()` with the resulting credential to complete signup.\n *\n * This method does not create a session; no state is persisted.\n *\n * @param options User profile data and optional realm/organization.\n * @param storeOptions Optional options used to resolve the domain (resolver mode).\n *\n * @throws {PasskeyRegisterError} If there was an issue requesting the signup challenge.\n *\n * @returns A promise resolving to the signup challenge.\n */\n async register(options: PasskeyRegisterOptions, storeOptions?: TStoreOptions): Promise<PasskeyRegisterResponse> {\n const domain = await this.#options.resolveDomain(storeOptions);\n const authClient = this.#options.getAuthClient(domain);\n\n return authClient.passkey.register(options);\n }\n\n /**\n * Requests a passkey login challenge for an existing user.\n *\n * Returns the `authSession` and the WebAuthn credential request options\n * (`authnParamsPublicKey`). The application must return these to the browser,\n * pass `authnParamsPublicKey` to `navigator.credentials.get()`, and then\n * call `getToken()` with the resulting credential to complete login.\n *\n * This method does not create a session; no state is persisted.\n *\n * @param options Optional realm/organization configuration.\n * @param storeOptions Optional options used to resolve the domain (resolver mode).\n *\n * @throws {PasskeyChallengeError} If there was an issue requesting the login challenge.\n *\n * @returns A promise resolving to the login challenge.\n */\n async challenge(options?: PasskeyChallengeOptions, storeOptions?: TStoreOptions): Promise<PasskeyChallengeResponse> {\n const domain = await this.#options.resolveDomain(storeOptions);\n const authClient = this.#options.getAuthClient(domain);\n\n return authClient.passkey.challenge(options);\n }\n\n /**\n * Completes a passkey authentication flow (signup or login) by exchanging the\n * WebAuthn credential for tokens, and persists the resulting session.\n *\n * Call this after obtaining a credential from `navigator.credentials.create()`\n * (signup) or `navigator.credentials.get()` (login), passing the `authSession`\n * returned by `register()` / `challenge()` together with the serialized credential.\n *\n * In resolver (multi-tenant) mode, pass the same `storeOptions` you passed to\n * `register()` / `challenge()` so the token exchange resolves the same tenant\n * that issued the `authSession`; otherwise the exchange will fail.\n *\n * @param options The auth session, serialized credential, and optional realm/scope/audience/organization.\n * @param storeOptions Optional options used to pass to the State Store (and to resolve the domain in resolver mode).\n *\n * @throws {PasskeyGetTokenError} If there was an issue exchanging the credential for tokens. When the cause is `mfa_required`, use `isMfaRequiredError(error)` to narrow the error and read `cause.mfa_token`. No session is persisted in this case.\n * @throws {OrganizationValidationError} When `organization` is passed and the returned ID token's organization claim is missing or does not match. The error is thrown before the session is written, so no session is persisted in this case.\n *\n * @returns A promise resolving to an object containing the authorizationDetails (when RAR was used).\n */\n async getToken(options: PasskeyGetTokenOptions, storeOptions?: TStoreOptions): Promise<PasskeyGetTokenResult> {\n const scope = ensureOpenIdScope(options.scope ?? this.#options.defaultScope);\n const audience = options.audience ?? this.#options.defaultAudience;\n\n const domain = await this.#options.resolveDomain(storeOptions);\n const authClient = this.#options.getAuthClient(domain);\n\n const tokenEndpointResponse = await authClient.passkey.getTokenByPasskey({\n ...options,\n scope,\n audience,\n });\n\n const existingStateData = await this.#options.stateStore.get(this.#options.stateStoreIdentifier, storeOptions);\n\n const stateData = updateStateData(audience ?? 'default', existingStateData, tokenEndpointResponse, { domain });\n\n await this.#options.stateStore.set(this.#options.stateStoreIdentifier, stateData, true, storeOptions);\n\n return {\n authorizationDetails: tokenEndpointResponse.authorizationDetails,\n };\n }\n}\n","import { EncryptJWT, jwtDecrypt, errors } from 'jose';\nimport type { JWTPayload } from 'jose';\nimport { InvalidConfigurationError } from '../errors.js';\n\nconst ENC = 'A256CBC-HS512';\nconst ALG = 'dir';\nconst DIGEST = 'SHA-256';\nconst BIT_LENGTH = 512;\nconst HKDF_INFO = 'derived cookie encryption secret';\n\nlet encoder: TextEncoder | undefined;\n\n/**\n * Type guard to determine if an error is a decryption-related error.\n * Decryption errors (JWEDecryptionFailed, JWEInvalid) indicate issues with the encryption key or data format.\n * These are distinct from claim validation errors (like expiration), which indicate a valid token with invalid claims.\n * @param e - The error thrown during decryption\n * @returns True if the error is a decryption error, false otherwise\n */\nexport function isDecryptionError(e: unknown): e is Error {\n return e instanceof errors.JWEDecryptionFailed || e instanceof errors.JWEInvalid;\n}\n\nasync function deriveEncryptionSecret(secret: string, salt: string, kid: string) {\n encoder ||= new TextEncoder();\n const key = await crypto.subtle.importKey('raw', encoder.encode(secret), 'HKDF', false, ['deriveBits']);\n\n return new Uint8Array(\n await crypto.subtle.deriveBits(\n {\n name: 'HKDF',\n hash: DIGEST,\n info: encoder.encode(HKDF_INFO),\n salt: encoder.encode(`${salt}${kid}`),\n } as HkdfParams,\n key,\n BIT_LENGTH\n )\n );\n}\n\n/**\n * Encrypts a payload using the provided secret and salt, with an expiration time.\n * @param payload The payload to encrypt.\n * @param secret The secret to use for encryption.\n * @param salt The salt to use for encryption.\n * @param expiration The expiration time for the encrypted payload.\n * @returns The encrypted payload.\n */\nasync function _encrypt(payload: JWTPayload, secret: string, salt: string, expiration: number) {\n const kid = crypto.randomUUID();\n const encryptionSecret = await deriveEncryptionSecret(secret, salt, kid);\n\n return await new EncryptJWT(payload)\n .setProtectedHeader({ enc: ENC, alg: ALG, kid: kid })\n .setExpirationTime(expiration)\n .encrypt(encryptionSecret);\n}\n\n/**\n * Encrypts a payload using the provided secret and salt, with an expiration time.\n * The secret can be a single string or an array of strings for secret rotation support.\n * When using an array of secrets, only the first one is used for encryption (all secrets are tried for decryption).\n * @param payload The payload to encrypt.\n * @param secret The secret(s) to use for encryption. Can be a single string or an array of strings for secret rotation support.\n * @param salt The salt to use for encryption.\n * @param expiration The expiration time for the encrypted payload.\n * @returns The encrypted payload.\n */\nexport async function encrypt(payload: JWTPayload, secret: string | string[], salt: string, expiration: number) {\n if (typeof secret === 'string') {\n return await _encrypt(payload, secret, salt, expiration);\n } else {\n // For encryption, we only use the newest secret, as the old secrets are only used for backward compatibility during decryption.\n const [newSecret] = secret;\n\n if (!newSecret) {\n throw new InvalidConfigurationError('At least one secret must be provided');\n }\n\n return await _encrypt(payload, newSecret, salt, expiration);\n }\n}\n\n/**\n * Decrypts an encrypted payload using the provided secret(s) and salt.\n * @param value The encrypted payload to decrypt.\n * @param secret The secret to use for decryption.\n * @param salt The salt to use for decryption.\n * @returns The decrypted payload.\n */\nexport async function _decrypt<T>(value: string, secret: string, salt: string) {\n const res = await jwtDecrypt<T>(\n value,\n async (protectedHeader) => {\n // This error shouldn't happen, as we always set a kid.\n // However, leaving this here as a safety net.\n if (!protectedHeader.kid) {\n throw new Error('Missing \"kid\" in JWE header');\n }\n\n return await deriveEncryptionSecret(secret, salt, protectedHeader.kid);\n },\n { clockTolerance: 15 }\n );\n return res.payload;\n}\n\n/**\n * Decrypts an encrypted payload using the provided secret(s) and salt.\n * The secret can be a single string or an array of strings for secret rotation support.\n * When using an array of secrets, the function will try to decrypt with each secret in order until it succeeds or exhausts all options.\n * Only decryption-related errors (JWEDecryptionFailed, JWEInvalid) will trigger fallback to old secrets.\n * Other errors (like expiration) will be thrown immediately.\n * @param value The encrypted payload to decrypt.\n * @param secret The secret(s) to use for decryption. Can be a single string or an array of strings for secret rotation support.\n * @param salt The salt to use for decryption.\n * @returns The decrypted payload.\n */\nexport async function decrypt<T>(value: string, secret: string | string[], salt: string) {\n if (typeof secret === 'string') {\n return await _decrypt<T>(value, secret, salt);\n } else {\n const [newSecret, ...oldSecrets] = secret;\n\n if (!newSecret) {\n throw new InvalidConfigurationError('At least one secret must be provided');\n }\n\n let firstError: Error | undefined;\n\n try {\n return await _decrypt<T>(value, newSecret, salt);\n } catch (err) {\n firstError = err as Error;\n\n // Only try old secrets if this is a decryption-related error\n // Other errors (like expiration) should be thrown immediately\n if (!isDecryptionError(err)) {\n throw firstError;\n }\n\n for (const oldSecret of oldSecrets) {\n try {\n return await _decrypt(value, oldSecret, salt);\n } catch (fallbackErr) {\n // Only ignore decryption errors with old secrets and continue trying with the next one\n // If it's a different type of error, throw it\n if (!isDecryptionError(fallbackErr)) {\n throw fallbackErr;\n }\n }\n }\n\n // If we've exhausted all secrets and still can't decrypt, throw the original error.\n throw firstError;\n }\n }\n}\n","import type { EncryptedStoreOptions, AbstractDataStore } from '../types.js';\nimport { encrypt, decrypt, isDecryptionError } from '../encryption/index.js';\nimport { JWTPayload } from 'jose';\n\n/**\n * Abstract class that can be used to implement an Encrypted JWT State Store, using the 'A256CBC-HS512' encryption algorithm.\n */\nexport abstract class AbstractStore<TData extends JWTPayload, TStoreOptions = unknown> implements AbstractDataStore<TData, TStoreOptions>\n{\n protected readonly options: EncryptedStoreOptions;\n\n constructor(options: EncryptedStoreOptions) {\n this.options = options;\n }\n\n abstract set(identifier: string, state: TData, removeIfExists?: boolean, options?: TStoreOptions | undefined): Promise<void>;\n abstract get(identifier: string, options?: TStoreOptions | undefined): Promise<TData | undefined>;\n abstract delete(identifier: string, options?: TStoreOptions | undefined): Promise<void>;\n\n protected async encrypt<TData extends JWTPayload>(identifier: string, stateData: TData, expiration: number) {\n return await encrypt(stateData, this.options.secret, identifier, expiration);\n }\n\n protected async decrypt<TData>(identifier: string, encryptedStateData: string) {\n try {\n return (await decrypt(encryptedStateData, this.options.secret, identifier)) as TData;\n } catch (e: unknown){\n // When the error is a decryption failure, we want to ignore it and return undefined, as this likely means the session has expired or the data is invalid.\n if (isDecryptionError(e)) {\n return;\n }\n\n throw e;\n }\n }\n}\n","import type { StateData, EncryptedStoreOptions, StateStore, LogoutTokenClaims } from '../types.js';\nimport { AbstractStore } from './abstract-store.js';\n\n/**\n * Abstract class that can be used to implement an Encrypted JWT State Store, using the 'A256CBC-HS512' encryption algorithm.\n */\nexport abstract class AbstractStateStore<TStoreOptions = unknown> extends AbstractStore<StateData, TStoreOptions> implements StateStore<TStoreOptions> {\n constructor(options: EncryptedStoreOptions) {\n super(options);\n }\n\n abstract deleteByLogoutToken(claims: LogoutTokenClaims, options?: TStoreOptions | undefined): Promise<void>;\n}","import type { EncryptedStoreOptions, TransactionData, TransactionStore } from '../types.js';\nimport { AbstractStore } from './abstract-store.js';\n\n/**\n * Abstract class that can be used to implement an Encrypted JWT Transaction Store, using the 'A256CBC-HS512' encryption algorithm.\n */\nexport abstract class AbstractTransactionStore<TStoreOptions = unknown> extends AbstractStore<TransactionData, TStoreOptions> implements TransactionStore<TStoreOptions> {\n constructor(options: EncryptedStoreOptions) {\n super(options);\n }\n}","import type { EncryptedStoreOptions, TransactionData } from './../types.js';\nimport { AbstractTransactionStore } from './abstract-transaction-store.js';\nimport type { CookieHandler, CookieSerializeOptions } from './cookie-handler.js';\n\nexport class CookieTransactionStore<TStoreOptions> extends AbstractTransactionStore<TStoreOptions> {\n readonly #cookieHandler: CookieHandler<TStoreOptions>;\n\n constructor(options: EncryptedStoreOptions, cookieHandler: CookieHandler<TStoreOptions>) {\n super(options);\n this.#cookieHandler = cookieHandler;\n }\n\n async set(\n identifier: string,\n transactionData: TransactionData,\n removeIfExists?: boolean,\n options?: TStoreOptions\n ): Promise<void> { \n const maxAge = 60 * 60;\n const cookieOpts: CookieSerializeOptions = { httpOnly: true, sameSite: 'lax', path: '/', maxAge };\n const expiration = Math.floor(Date.now() / 1000 + maxAge);\n const encryptedStateData = await this.encrypt(identifier, transactionData, expiration);\n\n this.#cookieHandler.setCookie(identifier, encryptedStateData, cookieOpts, options);\n }\n\n async get(identifier: string, options?: TStoreOptions): Promise<TransactionData | undefined> {\n const cookieValue = this.#cookieHandler.getCookie(identifier, options);\n\n if (cookieValue) {\n return await this.decrypt(identifier, cookieValue);\n }\n }\n\n async delete(identifier: string, options?: TStoreOptions | undefined): Promise<void> {\n this.#cookieHandler.deleteCookie(identifier, options);\n }\n}\n","import { AbstractStateStore } from './abstract-state-store.js';\nimport type { EncryptedStoreOptions, SessionConfiguration } from '../types.js';\n\nexport abstract class AbstractSessionStore<TStoreOptions> extends AbstractStateStore<TStoreOptions> {\n readonly #rolling: boolean;\n readonly #absoluteDuration: number;\n readonly #inactivityDuration: number;\n\n constructor(options: SessionConfiguration & EncryptedStoreOptions) {\n super(options);\n\n this.#rolling = options.rolling ?? true;\n this.#absoluteDuration = options.absoluteDuration ?? 60 * 60 * 24 * 3;\n this.#inactivityDuration = options.inactivityDuration ?? 60 * 60 * 24 * 1;\n }\n\n /**\n * calculateMaxAge calculates the max age of the session based on createdAt and the rolling and absolute durations.\n * When sessionExpiresAt is provided, caps the maxAge to not exceed the time until that ceiling.\n */\n protected calculateMaxAge(createdAt: number, sessionExpiresAt?: number) {\n const now = (Date.now() / 1000) | 0;\n\n let maxAge = this.#rolling\n ? Math.min(now + this.#inactivityDuration, createdAt + this.#absoluteDuration) - now\n : this.#absoluteDuration;\n\n if (sessionExpiresAt !== undefined) {\n maxAge = Math.min(maxAge, sessionExpiresAt - now);\n }\n\n return maxAge > 0 ? maxAge : 0;\n }\n}","import type {\n EncryptedStoreOptions,\n LogoutTokenClaims,\n SessionConfiguration,\n SessionCookieOptions,\n SessionStore,\n StateData,\n} from '../types.js';\nimport { AbstractSessionStore } from './abstract-session-store.js';\nimport type { CookieHandler, CookieSerializeOptions } from './cookie-handler.js';\n\nexport interface StatefulStateStoreOptions<TStoreOptions> extends EncryptedStoreOptions {\n store: SessionStore<TStoreOptions>;\n}\n\nconst generateId = () => {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n};\n\nexport class StatefulStateStore<TStoreOptions> extends AbstractSessionStore<TStoreOptions> {\n readonly #store: SessionStore<TStoreOptions>;\n readonly #cookieOptions: SessionCookieOptions | undefined;\n readonly #cookieHandler: CookieHandler<TStoreOptions>;\n\n constructor(\n options: StatefulStateStoreOptions<TStoreOptions> & SessionConfiguration,\n cookieHandler: CookieHandler<TStoreOptions>\n ) {\n super(options);\n\n this.#store = options.store;\n this.#cookieOptions = options.cookie;\n this.#cookieHandler = cookieHandler;\n }\n\n async set(\n identifier: string,\n stateData: StateData,\n removeIfExists?: boolean,\n options?: TStoreOptions | undefined\n ): Promise<void> {\n let sessionId = await this.getSessionId(identifier, options);\n\n // if this is a new session created by a new login we need to remove the old session\n // from the store and regenerate the session ID to prevent session fixation.\n if (sessionId && removeIfExists) {\n await this.#store.delete(sessionId);\n sessionId = generateId();\n }\n\n sessionId ??= generateId();\n\n const maxAge = this.calculateMaxAge(stateData.internal.createdAt, stateData.sessionExpiresAt);\n const cookieOpts = this.#getCookieOptions({\n maxAge,\n });\n const expiration = Date.now() / 1000 + maxAge;\n const encryptedStateData = await this.encrypt<{ id: string }>(\n identifier,\n {\n id: sessionId,\n },\n expiration\n );\n\n await this.#store.set(sessionId, stateData);\n\n this.#cookieHandler.setCookie(identifier, encryptedStateData, cookieOpts, options);\n }\n\n async get(identifier: string, options?: TStoreOptions | undefined): Promise<StateData | undefined> {\n const sessionId = await this.getSessionId(identifier, options);\n\n if (sessionId) {\n const stateData = await this.#store.get(sessionId);\n\n // If we have a session cookie, but no `stateData`, we should remove the cookie.\n if (!stateData) {\n this.#cookieHandler.deleteCookie(identifier, options, this.#getCookieOptions());\n }\n\n return stateData;\n }\n }\n\n async delete(identifier: string, options?: TStoreOptions | undefined): Promise<void> {\n const sessionId = await this.getSessionId(identifier, options);\n\n if (sessionId) {\n await this.#store.delete(sessionId);\n }\n\n this.#cookieHandler.deleteCookie(identifier, options, this.#getCookieOptions());\n }\n\n private async getSessionId(identifier: string, options?: TStoreOptions) {\n const cookieValue = this.#cookieHandler.getCookie(identifier, options);\n if (cookieValue) {\n const sessionCookie = await this.decrypt<{ id: string }>(identifier, cookieValue);\n \n if (sessionCookie) {\n return sessionCookie.id;\n }\n }\n }\n\n deleteByLogoutToken(claims: LogoutTokenClaims, options?: TStoreOptions | undefined): Promise<void> {\n return this.#store.deleteByLogoutToken(claims, options);\n }\n\n #getCookieOptions(partial?: Partial<CookieSerializeOptions>): CookieSerializeOptions {\n return {\n httpOnly: true,\n sameSite: this.#cookieOptions?.sameSite ?? 'lax',\n path: this.#cookieOptions?.path ?? '/',\n secure: this.#cookieOptions?.secure ?? true,\n ...partial,\n };\n }\n}\n","import type { EncryptedStoreOptions, SessionConfiguration, SessionCookieOptions, StateData } from '../types.js';\nimport { AbstractSessionStore } from './abstract-session-store.js';\nimport type { CookieHandler, CookieSerializeOptions } from './cookie-handler.js';\n\nexport class StatelessStateStore<TStoreOptions> extends AbstractSessionStore<TStoreOptions> {\n readonly #cookieOptions: SessionCookieOptions | undefined;\n readonly #cookieHandler: CookieHandler<TStoreOptions>;\n\n constructor(options: SessionConfiguration & EncryptedStoreOptions, cookieHandler: CookieHandler<TStoreOptions>) {\n super(options);\n\n this.#cookieOptions = options.cookie;\n this.#cookieHandler = cookieHandler;\n }\n\n async set(\n identifier: string,\n stateData: StateData,\n removeIfExists?: boolean,\n options?: TStoreOptions | undefined\n ): Promise<void> {\n const maxAge = this.calculateMaxAge(stateData.internal.createdAt, stateData.sessionExpiresAt);\n const cookieOpts = this.#getCookieOptions({\n maxAge,\n });\n const expiration = Math.floor(Date.now() / 1000 + maxAge);\n const encryptedStateData = await this.encrypt(identifier, stateData, expiration);\n\n const chunkSize = 3072;\n const chunkCount = Math.ceil(encryptedStateData.length / chunkSize);\n const chunks = [...Array(chunkCount).keys()].map((i) => ({\n value: encryptedStateData.substring(i * chunkSize, (i + 1) * chunkSize),\n name: `${identifier}.${i}`,\n }));\n\n chunks.forEach((chunk) => {\n this.#cookieHandler.setCookie(chunk.name, chunk.value, cookieOpts, options);\n });\n\n const existingCookieKeys = this.getCookieKeys(identifier, options);\n const cookieKeysToRemove = existingCookieKeys.filter((key) => !chunks.some((chunk) => chunk.name === key));\n cookieKeysToRemove.forEach((key) => {\n this.#cookieHandler.deleteCookie(key, options, cookieOpts);\n });\n }\n\n async get(identifier: string, options?: TStoreOptions | undefined): Promise<StateData | undefined> {\n const cookieKeys = this.getCookieKeys(identifier, options);\n const encryptedStateData = cookieKeys\n .map((key) => ({\n index: parseInt(key.split('.')[1] as string, 10),\n value: this.#cookieHandler.getCookie(key, options),\n }))\n .sort((a, b) => a.index - b.index)\n .map((item) => item.value)\n .join('');\n\n if (encryptedStateData) {\n return await this.decrypt(identifier, encryptedStateData);\n }\n }\n\n async delete(identifier: string, options?: TStoreOptions | undefined): Promise<void> {\n const cookieKeys = this.getCookieKeys(identifier, options);\n for (const key of cookieKeys) {\n this.#cookieHandler.deleteCookie(key, options, this.#getCookieOptions());\n }\n }\n\n deleteByLogoutToken(): Promise<void> {\n throw new Error(\n 'Backchannel logout is not available when using Stateless Storage. Use Stateful Storage by providing a `sessionStore`'\n );\n }\n\n private getCookieKeys(identifier: string, options?: TStoreOptions): string[] {\n return Object.keys(this.#cookieHandler.getCookies(options)).filter((key) => key.startsWith(identifier));\n }\n\n #getCookieOptions(partial?: Partial<CookieSerializeOptions>): CookieSerializeOptions {\n return {\n httpOnly: true,\n sameSite: this.#cookieOptions?.sameSite ?? 'lax',\n path: this.#cookieOptions?.path ?? '/',\n secure: this.#cookieOptions?.secure ?? true,\n ...partial,\n };\n }\n}\n","export { ServerMfaClient } from './server-mfa-client.js';\nexport type { MfaVerifyResponse } from './types.js';\nexport type {\n MfaFactorType,\n MfaVerifyOtpOptions,\n MfaVerifyOobOptions,\n MfaVerifyRecoveryCodeOptions,\n MfaVerifyOptions,\n} from '@auth0/auth0-auth-js';\n\n// Re-export MFA types and errors from auth0-auth-js for convenience\nexport type {\n AuthenticatorResponse,\n AuthenticatorType,\n OobChannel,\n ListAuthenticatorsOptions,\n EnrollOtpOptions,\n EnrollOobOptions,\n EnrollEmailOptions,\n EnrollAuthenticatorOptions,\n OtpEnrollmentResponse,\n OobEnrollmentResponse,\n EnrollmentResponse,\n ChallengeOptions,\n ChallengeResponse,\n MfaRequirements,\n} from '@auth0/auth0-auth-js';\n\nexport {\n MfaListAuthenticatorsError,\n MfaEnrollmentError,\n MfaChallengeError,\n MfaVerifyError,\n isMfaRequiredError,\n} from '@auth0/auth0-auth-js';\n","export { ServerPasskeyClient } from './server-passkey-client.js';\n\n// Re-export passkey error classes from auth0-auth-js for convenience, so consumers\n// can narrow thrown errors via `instanceof` without importing auth0-auth-js directly.\n// `OrganizationValidationError` is thrown by `getToken()` when an `organization` is\n// passed and the returned ID token's organization claim is missing or mismatched.\n// The passkey option/response types are re-exported from `../types.js`.\nexport {\n PasskeyRegisterError,\n PasskeyChallengeError,\n PasskeyGetTokenError,\n OrganizationValidationError,\n} from '@auth0/auth0-auth-js';\n"],"mappings":"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","names":["tokenSet","logoutTokenClaims","import_jose","import_auth0_auth_js","import_auth0_auth_js","import_auth0_auth_js"]}