From 0b22cd44e668d3cde3fe1597d5f1c9292d30c120 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 28 Oct 2026 08:46:51 +0000 Subject: [PATCH 1/3] [fern-generated] Update SDK Generated by Fern CLI Version: unknown Generators: - fernapi/fern-typescript-sdk: 3.107.6 --- .shiprc | 6 - AUTH_MIGRATION_GUIDE.md | 14 - auth-migration/authentication-flows.md | 234 ------ auth-migration/index.md | 732 ------------------ auth-migration/server-side-sessions.md | 163 ---- auth-migration/troubleshooting.md | 32 - package.json | 2 +- reference.md | 207 +++++ src/management/api/requests/requests.ts | 9 +- .../resources/segments/client/Client.ts | 6 +- .../api/resources/users/client/Client.ts | 252 ++++++ src/management/api/types/types.ts | 84 +- .../tests/unit/stream/Stream.test.ts | 2 +- .../bruteForceProtection.test.ts | 4 +- src/management/tests/wire/clients.test.ts | 4 + .../wire/experimentation/segments.test.ts | 1 + .../tests/wire/resourceServers.test.ts | 5 + src/management/tests/wire/users.test.ts | 305 ++++++++ src/management/version.ts | 2 +- v6_MIGRATION_GUIDE.md | 158 ---- v7_MIGRATION_GUIDE.md | 146 ---- yarn.lock | 268 +++---- 22 files changed, 1005 insertions(+), 1631 deletions(-) delete mode 100644 .shiprc delete mode 100644 AUTH_MIGRATION_GUIDE.md delete mode 100644 auth-migration/authentication-flows.md delete mode 100644 auth-migration/index.md delete mode 100644 auth-migration/server-side-sessions.md delete mode 100644 auth-migration/troubleshooting.md delete mode 100644 v6_MIGRATION_GUIDE.md delete mode 100644 v7_MIGRATION_GUIDE.md diff --git a/.shiprc b/.shiprc deleted file mode 100644 index d1791e98e5..0000000000 --- a/.shiprc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "files": { - ".version": [], - "src/management/version.ts": [] - } -} diff --git a/AUTH_MIGRATION_GUIDE.md b/AUTH_MIGRATION_GUIDE.md deleted file mode 100644 index 64626f8067..0000000000 --- a/AUTH_MIGRATION_GUIDE.md +++ /dev/null @@ -1,14 +0,0 @@ -# Authentication Migration Guide - -This guide lives in the [`auth-migration/`](./auth-migration/) directory. - -**→ Start here: [`auth-migration/index.md`](./auth-migration/index.md)**: migrate your authentication code off the `auth0` package to [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js) (stateless token grants) or [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js) (server-managed sessions). - -The directory contains: - -- [`auth-migration/index.md`](./auth-migration/index.md): the main guide covering OIDC token grants and the four cross-cutting breaking changes. -- [`auth-migration/authentication-flows.md`](./auth-migration/authentication-flows.md): database, passwordless, backchannel (CIBA), token exchange, and `UserInfoClient`. -- [`auth-migration/server-side-sessions.md`](./auth-migration/server-side-sessions.md): the `@auth0/auth0-server-js` session layer. -- [`auth-migration/troubleshooting.md`](./auth-migration/troubleshooting.md): FAQ and gotchas. - -> **Migrating with an AI agent?** Point it at the Auth0 migration skill: the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`. diff --git a/auth-migration/authentication-flows.md b/auth-migration/authentication-flows.md deleted file mode 100644 index 6f7bace2a1..0000000000 --- a/auth-migration/authentication-flows.md +++ /dev/null @@ -1,234 +0,0 @@ -# Migrating the other authentication flows - -This is the incremental part of the [Authentication Migration Guide](./index.md). Start with the guide's [OIDC token grants](./index.md#oidc-token-grants) and cross-cutting breaking changes before you touch anything here. Everything below builds on those changes, so apply them to every rewrite on this page too. - -> **Migrating with an AI agent?** Point it at the Auth0 migration skill (the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`). - -Migrate one flow at a time. Only the flows your app actually uses need attention; skip the rest. - -- [Database connections](#database-connections) -- [Passwordless](#passwordless) -- [Backchannel authentication (CIBA)](#backchannel-authentication-ciba) -- [Token exchange (RFC 8693)](#token-exchange-rfc-8693) -- [UserInfoClient](#userinfoclient) -- [Quick lookup table](#quick-lookup-table) - -Unless a row routes explicitly to `@auth0/auth0-server-js`, the replacement lives on the `@auth0/auth0-auth-js` `AuthClient` (or a sub-client: `authClient.database`, `authClient.passwordless`, `authClient.mfa`, `authClient.passkey`). - -## Database connections - -Database connection operations move to the `authClient.database` sub-client. Names and required parameters stay the same; only casing and return shape change. - -### `database.signUp` → `authClient.database.signUp` - -```ts -// before -const resp = await auth0.database.signUp({ - email, - password, - connection: "Username-Password-Authentication", - given_name: "Ada", - family_name: "Lovelace", - user_metadata: { plan: "free" }, -}); -const userId = resp.data.id; -// after -const result = await authClient.database.signUp({ - email, - password, - connection: "Username-Password-Authentication", - givenName: "Ada", - familyName: "Lovelace", - userMetadata: { plan: "free" }, -}); -const userId = result.id; -``` - -> ID normalization is preserved: node-auth0 mapped the server's `_id | user_id | id` onto a single `id`. The new SDK does the same, so `result.id` is always present. Do not add your own `_id` fallback. - -### `database.changePassword` → `authClient.database.changePassword` - -node-auth0 returned a `TextApiResponse` (read via `.data`); the new SDK returns the plain `string` directly. - -```ts -// before -const resp = await auth0.database.changePassword({ email, connection: "Username-Password-Authentication" }); -const message = resp.data; // plain-text confirmation -// after -const message = await authClient.database.changePassword({ email, connection: "Username-Password-Authentication" }); -``` - -> `changePassword` requires `connection` plus at least one of `email` or `username`: either identifier is accepted, not `email` alone. - -## Passwordless - -node-auth0 lumped "start" (send the code or link) and "login" (redeem the code) onto one sub-client. The new SDK splits them: starting stays on `authClient.passwordless`; redeeming a code becomes a top-level grant method on `AuthClient`. - -### `passwordless.sendEmail` → `authClient.passwordless.sendEmail` - -```ts -// before -await auth0.passwordless.sendEmail({ email, send: "code" }); -// after -await authClient.passwordless.sendEmail({ email, send: "code" }); -``` - -> Default changed: node-auth0 defaulted `send` to `'link'` (magic link). The new SDK defaults `send` to `'code'` (one-time password). If you relied on the implicit default to send magic links, set `send: 'link'` explicitly. - -### `passwordless.sendSMS` → `authClient.passwordless.sendSms` - -Note the casing change: `sendSMS` → `sendSms`, and `phone_number` → `phoneNumber`. - -```ts -// before -await auth0.passwordless.sendSMS({ phone_number: "+15551234567" }); -// after -await authClient.passwordless.sendSms({ phoneNumber: "+15551234567" }); -``` - -### `passwordless.loginWithEmail` → `getTokenByPasswordlessEmail` - -Redeeming the one-time password is now a grant method on `AuthClient`, not on the passwordless sub-client. - -```ts -// before -const resp = await auth0.passwordless.loginWithEmail({ email, code, audience, scope }); -const token = resp.data.access_token; -// after -const tokens = await authClient.getTokenByPasswordlessEmail({ email, code, audience, scope }); -const token = tokens.accessToken; -``` - -### `passwordless.loginWithSMS` → `getTokenByPasswordlessSms` - -```ts -// before -const resp = await auth0.passwordless.loginWithSMS({ phone_number, code }); -// after -const tokens = await authClient.getTokenByPasswordlessSms({ phoneNumber, code }); -``` - -> Session apps: `@auth0/auth0-server-js` exposes `startPasswordless` / `completePasswordless` / `completePasswordlessMagicLink`, which both send the code and establish a session. Use those instead of the two-step auth-js flow when the SDK owns the session. See [Migrating session apps](./server-side-sessions.md). - -## Backchannel authentication (CIBA) - -CIBA is Client-Initiated Backchannel Authentication. - -### `backchannel.authorize` → `initiateBackchannelAuthentication` - -```ts -// before -const resp = await auth0.backchannel.authorize({ - binding_message: "ABC123", - scope: "openid", - userId: "auth0|123", -}); -const authReqId = resp.auth_req_id; -// after -const { authReqId, expiresIn, interval } = await authClient.initiateBackchannelAuthentication({ - bindingMessage: "ABC123", - loginHint: { sub: "auth0|123" }, // login_hint is an object with `sub`, not a bare string - authorizationParams: { scope: "openid" }, // scope goes here, NOT as a top-level key -}); -``` - -### `backchannel.backchannelGrant` → `backchannelAuthenticationGrant` - -```ts -// before -const resp = await auth0.backchannel.backchannelGrant({ auth_req_id: authReqId }); -// after -const tokens = await authClient.backchannelAuthenticationGrant({ authReqId }); -``` - -> One-shot convenience: `authClient.backchannelAuthentication({ ... })` initiates and polls to completion, returning a `TokenResponse`. Use it if your code did the initiate-then-poll loop by hand. -> -> Session apps: for CIBA that also establishes a session, see [Migrating session apps](./server-side-sessions.md). - -## Token exchange (RFC 8693) - -```ts -// before -const resp = await auth0.tokenExchange.exchangeToken({ - subject_token_type: "urn:example:custom", - subject_token: token, - audience: "https://api.example.com", - scope: "read", -}); -// after -const tokens = await authClient.exchangeToken({ - subjectTokenType: "urn:example:custom", - subjectToken: token, - audience: "https://api.example.com", - scope: "read", -}); -``` - -> `exchangeToken` is overloaded: a custom-exchange profile shape (`subjectTokenType` + `subjectToken` + `audience`) and a Token Vault shape (`connection` present). Presence of `connection` routes to the vault path. The custom-exchange profile is the RFC 8693 replacement for `tokenExchange.exchangeToken`. -> -> Session apps: `@auth0/auth0-server-js` exposes `loginWithCustomTokenExchange` (exchange, then establish a session) and `customTokenExchange` (exchange, then return tokens with no session). - -## UserInfoClient - -The standalone `UserInfoClient` from node-auth0 does not exist in the new SDK. Choose the replacement based on what the app needs: - -| Your intent | Replacement | -| --- | --- | -| Wanted user profile claims right after login | Read `TokenResponse.claims` from the grant result; the SDK already decodes the ID token. No extra `/userinfo` round-trip needed. **Preferred.** | -| Wanted a live `/userinfo` response for an arbitrary access token | `await authClient.getUserInfo({ accessToken })`, a direct method on `AuthClient`. | -| Wanted the profile in a server-rendered app with a session | `await serverClient.getUser()` returns the stored user claims from the session. | - -**Before (node-auth0):** - -```ts -import { UserInfoClient } from "auth0"; -const userInfo = new UserInfoClient({ domain }); -const resp = await userInfo.getUserInfo(accessToken); -const profile = resp.data; // { sub, name, email, ... } -``` - -**After (preferred): use the claims you already have:** - -```ts -const tokens = await authClient.getTokenByCode(callbackUrl, {}); -const profile = tokens.claims; // { sub, name, email, ... } decoded from the id_token -``` - -**After (direct method):** for when you only have an access token: - -```ts -// Takes an options object: { accessToken, expectedSubject? } -const profile = await authClient.getUserInfo({ accessToken }); -``` - -> Prefer reading `claims` over any `/userinfo` call: it avoids a network round-trip and the claims are already validated by the SDK. - -## Quick lookup table - -The complete node-auth0 → new SDK map, including the OIDC methods covered in the main guide. - -| node-auth0 | new SDK equivalent | Layer | -| --- | --- | --- | -| `oauth.authorizationCodeGrant` | `authClient.getTokenByCode(url, opts)` | auth-js | -| `oauth.authorizationCodeGrantWithPKCE` | `authClient.getTokenByCode(url, { codeVerifier })` | auth-js | -| `oauth.refreshTokenGrant` | `authClient.getTokenByRefreshToken({ refreshToken })` | auth-js | -| `oauth.passwordGrant` | `authClient.getTokenByPassword({ ... })` | auth-js | -| `oauth.clientCredentialsGrant` | `authClient.getTokenByClientCredentials({ audience })` | auth-js | -| `oauth.revokeRefreshToken` | `authClient.revokeToken({ token })` / `serverClient.revokeRefreshToken()` | auth-js / server-js | -| `oauth.tokenForConnection` | `authClient.exchangeToken({ connection, ... })` | auth-js | -| `oauth.pushedAuthorization` | `authClient.buildAuthorizationUrl({ pushedAuthorizationRequests: true })` | auth-js | -| `database.signUp` | `authClient.database.signUp({ ... })` | auth-js | -| `database.changePassword` | `authClient.database.changePassword({ ... })` | auth-js | -| `passwordless.sendEmail` | `authClient.passwordless.sendEmail({ ... })` | auth-js | -| `passwordless.sendSMS` | `authClient.passwordless.sendSms({ phoneNumber })` | auth-js | -| `passwordless.loginWithEmail` | `authClient.getTokenByPasswordlessEmail({ ... })` | auth-js | -| `passwordless.loginWithSMS` | `authClient.getTokenByPasswordlessSms({ ... })` | auth-js | -| `backchannel.authorize` | `authClient.initiateBackchannelAuthentication({ ... })` | auth-js | -| `backchannel.backchannelGrant` | `authClient.backchannelAuthenticationGrant({ authReqId })` | auth-js | -| `tokenExchange.exchangeToken` | `authClient.exchangeToken({ subjectTokenType, subjectToken, audience })` | auth-js | -| `UserInfoClient.getUserInfo` | `TokenResponse.claims` (preferred) / `authClient.getUserInfo({ accessToken })` / `serverClient.getUser()` | auth-js / server-js | -| (no equivalent): build `/authorize` URL | `authClient.buildAuthorizationUrl({ ... })` | auth-js | -| (no equivalent): build `/v2/logout` URL | `authClient.buildLogoutUrl({ returnTo })` | auth-js | -| `ManagementClient.*` | **not migrated, stays on `auth0`** | n/a | - -When you finish a flow, return to the [verification checklist](./index.md#verification-checklist) and confirm the four cross-cutting changes for every call site you touched. diff --git a/auth-migration/index.md b/auth-migration/index.md deleted file mode 100644 index 85a11c45c7..0000000000 --- a/auth-migration/index.md +++ /dev/null @@ -1,732 +0,0 @@ -# Authentication Migration Guide - -A guide to migrating your authentication code off the `auth0` package (node-auth0) to the modern Auth0 server SDKs: [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js) for stateless token grants, and [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js) for server-managed sessions. - -> **Migrating with an AI agent?** Point it at the Auth0 migration skill first. The skill lives in [`auth0/agent-skills`](https://github.com/auth0/agent-skills) as the `auth0` skill (migration intent: `migrate-node-auth0`). It encodes the target-SDK routing, the four cross-cutting breaking changes, the method-by-method mapping, and a build-until-green verify loop. - -## Contents - -- [How to use this guide](#how-to-use-this-guide) -- [Overview](#overview) - - [Who this is for](#who-this-is-for) - - [Scope](#scope) -- [Choosing your target SDK](#choosing-your-target-sdk) -- [Prerequisites](#prerequisites) -- [Installation and constructor mapping](#installation-and-constructor-mapping) -- [OIDC token grants](#oidc-token-grants) - - [Optional: migrate only OIDC while staying on v6](#optional-migrate-only-oidc-while-staying-on-v6) -- [Cross-cutting breaking changes](#cross-cutting-breaking-changes) - - [1. Return shape](#1-return-shape) - - [2. Casing](#2-casing) - - [3. Token expiry](#3-token-expiry) - - [4. Error model](#4-error-model) -- [Verification checklist](#verification-checklist) -- [Continue the migration](#continue-the-migration) - - [Other authentication flows](#other-authentication-flows) - - [Server-side sessions](#server-side-sessions) - - [Troubleshooting](#troubleshooting) - -## How to use this guide - -This is a reference, not a linear read. You do not have to work through it top to bottom; migrate only the flows your app actually uses, in whatever order suits you. Most apps finish after the [OIDC token grants](#oidc-token-grants) section. - -The work falls into three phases: - -| Phase | What you do | Where | -| --- | --- | --- | -| **Before**: orient and set up | Pick your target SDK, check prerequisites, install the package, map constructor options. | [Choosing your target SDK](#choosing-your-target-sdk), [Prerequisites](#prerequisites), [Installation and constructor mapping](#installation-and-constructor-mapping) | -| **During**: rewrite call sites | Rewrite the OIDC token grants (in this file), then the other flows and the session layer as needed. Apply the four cross-cutting breaking changes to every call site. | [OIDC token grants](#oidc-token-grants), [Cross-cutting breaking changes](#cross-cutting-breaking-changes), [`authentication-flows.md`](./authentication-flows.md), [`server-side-sessions.md`](./server-side-sessions.md) | -| **After**: verify | Run the build-until-green checklist; confirm no residue and that `ManagementClient` code is untouched. | [Verification checklist](#verification-checklist) | - -Suggested order: start with the OIDC grants and cross-cutting changes (the whole job for most apps), then the [other flows](./authentication-flows.md) you actually use, then [session apps](./server-side-sessions.md) if you want the SDK to own sessions. Stuck? See [`troubleshooting.md`](./troubleshooting.md). - -## Overview - -node-auth0's `AuthenticationClient` is a stateless HTTP client. Every method is a single call to an Auth0 Authentication API endpoint that returns a response object. It has no notion of a logged-in user, no session, no cookie, no token store, and no automatic refresh. Anything stateful in a node-auth0 app (persisting tokens, deciding when to refresh, tracking the login across requests) was written by you *around* node-auth0. - -The modern stack splits those two concerns into two packages: - -- `@auth0/auth0-auth-js` is the stateless token layer. It is the direct successor to `AuthenticationClient`: the same "one method equals one API call equals one result" model, with modern ergonomics (camelCase, typed errors, direct return values, per-request options). -- `@auth0/auth0-server-js` is a stateful session layer built on top of auth0-auth-js. It owns the login redirect flow, a pluggable state/transaction store, cookie handling, automatic token refresh, and logout. It is the successor to the *session code you hand-rolled*, not to `AuthenticationClient` itself. - -### Who this is for - -You are running a Node.js backend that imports the `auth0` package and calls `AuthenticationClient` (or `UserInfoClient`) to perform token grants, database signup, passwordless, CIBA, token exchange, or userinfo lookups. You want to move that code to the current first-party server SDKs. This is a surgical rewrite of the authentication layer: routes, controllers, business logic, data access, and framework wiring stay as they are. You touch the smallest possible surface: the files that import and call node-auth0's Authentication API. - -### Scope - -In scope: - -- `AuthenticationClient` and its sub-clients: `.oauth`, `.database`, `.passwordless`, `.backchannel`, `.tokenExchange` -- `UserInfoClient` -- The auth error types (`AuthApiError`) and token-validation types (`IDTokenValidateOptions`, `IdTokenValidatorError`) - -Out of scope, do not touch: - -- `ManagementClient` (Management API v2). It is not being migrated and stays on the `auth0` package. -- Application routes, view/controller logic, database code, and any non-auth use of the `auth0` package. - -> If a file uses `ManagementClient`, leave that code alone. Only rewrite the `AuthenticationClient` / `UserInfoClient` parts. - -## Choosing your target SDK - -The routing question is: do you want to keep owning your session, or hand that responsibility to the SDK? - -### Decision table - -| If your code… | Migrate to | Why | -| --- | --- | --- | -| Only performs token grants / DB signup / passwordless / userinfo and manages its own session (or is a machine-to-machine service backend) | `@auth0/auth0-auth-js` | Direct, near 1:1 replacement for `AuthenticationClient`. Same stateless model. | -| Wants the SDK to own the login redirect flow, session storage, cookies, token refresh, and logout (a server-rendered web app) | `@auth0/auth0-server-js` | Adds a session layer node-auth0 never had. This is a rewrite of the session handling, not a method-for-method port. | - -**Default recommendation:** start with `@auth0/auth0-auth-js` for a faithful parity migration. Choose `@auth0/auth0-server-js` only when you currently hand-roll session/cookie/refresh logic around node-auth0 and would benefit from the SDK owning it. - -### Signals - -Signals that point to auth0-auth-js: - -- Predominant use is `clientCredentialsGrant` (machine-to-machine). There is no user, so there is no session to own. -- The app already has a session framework it is happy with and only calls node-auth0 for token grants. -- The app is an API, worker, or CLI, not a browser-facing web server. -- You want the smallest, most mechanical, lowest-risk migration. - -Signals that point to auth0-server-js: - -- The app performs a browser redirect login and reads `req.session.user` (or equivalent) on later requests. -- You wrote refresh-on-expiry logic, a token cache, or logout-with-revocation by hand. -- You use `express-openid-connect` today and want a first-party, framework-agnostic replacement. -- You are on a server framework (Express, Fastify, Hono, Next.js) and want the SDK to manage cookies. - -### Mixing both - -A single app can use both: auth0-server-js for the user-facing login/session, and auth0-auth-js directly for a separate machine-to-machine `clientCredentialsGrant` to call another API. `ServerClient` even exposes the underlying `AuthClient` via `serverClient.authClient` for occasional low-level needs. Do not force everything onto one package. - -## Prerequisites - -### Node.js version - -Both target SDKs need Node.js 20 LTS or newer. Verify the project's runtime before installing. - -### SDK versions - -- `@auth0/auth0-auth-js` >= `1.13.0` -- `@auth0/auth0-server-js` >= `1.13.0` - -Both are published on npm; install the current `latest`. `1.13.0` is the floor for the full API surface used in this guide (`getUserInfo`, per-request `RequestOptions`, and `fullResponse`). - -## Installation and constructor mapping - -Add the target package: - -```bash -# auth-js target (stateless token grants) -npm install @auth0/auth0-auth-js - -# server-js target (server-managed sessions), pulls in auth0-auth-js transitively -npm install @auth0/auth0-server-js -``` - -Keep the `auth0` package installed if the app still uses `ManagementClient`. - -### Imports - -```ts -// before -import { AuthenticationClient, UserInfoClient, AuthApiError } from "auth0"; - -// after: auth-js target -import { AuthClient, TokenByCodeError, isMfaRequiredError } from "@auth0/auth0-auth-js"; - -// after: server-js target -import { ServerClient } from "@auth0/auth0-server-js"; -``` - -> Keep the `auth0` import if the file also uses `ManagementClient`. It is correct for a file to import both `auth0` (for `ManagementClient`) and `@auth0/auth0-auth-js` (for authentication). Only remove the `auth0` import from files where it was used *solely* for `AuthenticationClient` / `UserInfoClient`. - -### AuthClient options - -The constructor options mostly carry over with camelCase names. A few are renamed or dropped. - -**Before (node-auth0):** - -```ts -new AuthenticationClient({ - domain: "tenant.us.auth0.com", - clientId: "...", - clientSecret: "...", // OR clientAssertionSigningKey - clientAssertionSigningKey: "...", - clientAssertionSigningAlg: "RS256", - idTokenSigningAlg: "RS256", // for manual id_token validation - clockTolerance: 60, // seconds, for validation - useMTLS: false, - telemetry: true, - headers: { "X-Custom": "..." }, // sent on every request - timeoutDuration: 10000, // ms - retry: { - /* ... */ - }, - agent: undiciDispatcher, - fetch: customFetch, - middleware: [ - /* ... */ - ], -}); -``` - -**After (auth0-auth-js):** - -```ts -import { AuthClient } from "@auth0/auth0-auth-js"; - -new AuthClient({ - domain: "tenant.us.auth0.com", // same (no scheme) - clientId: "...", // same - clientSecret: "...", // same - clientAssertionSigningKey: "...", // same (string | CryptoKey) - clientAssertionSigningAlg: "RS256", // same - authorizationParams: { - // NEW: default scope/audience/redirect_uri for URL builders - scope: "openid profile email", - audience: "https://api.example.com", - redirect_uri: "https://app.example.com/callback", - }, - useMtls: false, // RENAMED from useMTLS (lowercase tls) - customFetch: fetch, // RENAMED from fetch - telemetry: { - /* ... */ - }, // structured TelemetryConfig - discoveryCache: { ttl, maxEntries }, // NEW: OIDC discovery / JWKS cache -}); -``` - -Option-by-option: - -| node-auth0 | auth0-auth-js | Notes | -| --- | --- | --- | -| `domain` | `domain` | Unchanged. No `https://` scheme. | -| `clientId` | `clientId` | Unchanged. | -| `clientSecret` | `clientSecret` | Unchanged. | -| `clientAssertionSigningKey` | `clientAssertionSigningKey` | Unchanged. Now also accepts a `CryptoKey`. | -| `clientAssertionSigningAlg` | `clientAssertionSigningAlg` | Unchanged. | -| `useMTLS` | `useMtls` | Renamed (casing). | -| `fetch` | `customFetch` | Renamed. | -| `telemetry: boolean` | `telemetry: TelemetryConfig` | Now a structured object. | -| `headers` (global) | per-request `RequestOptions.headers` | Moved to per-request options; set per call site rather than globally. | -| `timeoutDuration` | per-request `RequestOptions.signal` | Use an `AbortSignal.timeout(ms)` on the call. | -| `retry` | configure via `customFetch` | Wrap your fetch with retry if needed. | -| `agent` | configure via `customFetch` | Set the dispatcher inside your custom fetch. | -| `middleware` | `customFetch` | Compose behavior in the fetch wrapper. | -| `idTokenSigningAlg` | (internal) | ID-token validation is internal; read `TokenResponse.claims`. | -| `clockTolerance` | (internal) | Handled internally during validation. | - -### ServerClient options - -`ServerClient` wraps an `AuthClient` and adds the session machinery. It shares the auth options and adds required stores. This constructor and the stores it needs are covered in [`server-side-sessions.md`](./server-side-sessions.md); reach for it only when you route to server-js. - -### Global config to per-request options - -node-auth0's global constructor options for `headers`, `timeoutDuration`, `agent`, `retry`, and `middleware` have no direct constructor equivalents in auth0-auth-js. Instead, the new SDK's methods accept a trailing `RequestOptions` parameter: - -```ts -import type { RequestOptions } from "@auth0/auth0-server-js"; // or '@auth0/auth0-auth-js' - -const tokens = await authClient.getTokenByClientCredentials( - { audience: "https://api.example.com" }, - { - headers: { "X-Custom": "value" }, - signal: AbortSignal.timeout(5000), // timeout in ms - } satisfies RequestOptions, -); -``` - -`@auth0/auth0-server-js` re-exports `RequestOptions`, `ApiResponse`, and `FullResponseOption` from `@auth0/auth0-auth-js`, so you can import any of them from either package. - -Arity rule: MFA methods (`authClient.mfa.*`) take `requestOptions` as the 2nd argument; store-first methods (session-owning methods on `serverClient`) take it as the 3rd argument after the store context; cache hits ignore it entirely. - -Common patterns: - -- Global headers: apply via `RequestOptions.headers` on each call that needs it, or wrap `customFetch` once to inject it everywhere. -- Timeout: replace `timeoutDuration: 10000` with `signal: AbortSignal.timeout(10000)` on the call. -- Agent (Node.js dispatcher): wrap `customFetch` to inject the agent into the underlying HTTP transport. -- Retry / middleware: compose behavior in a `customFetch` wrapper passed either at construction or per request. - -## OIDC token grants - -This is the core of the migration and, for most apps, the whole of it. These are the `AuthenticationClient.oauth.*` grants that drive OpenID Connect login and machine-to-machine token acquisition. All of them move onto the `AuthClient` instance directly (not a sub-client). - -Before you touch any method, internalize the four [cross-cutting breaking changes](#cross-cutting-breaking-changes); they apply to *every* rewrite here and on the incremental pages. - -Naming conventions used throughout: - -| node-auth0 | new SDKs | -| --- | --- | -| Params and response fields use the snake_case wire shape: `client_id`, `refresh_token`, `access_token`, `expires_in`, `phone_number` | camelCase: `clientId`, `refreshToken`, `accessToken`, `expiresAt`, `phoneNumber` | -| Methods take a `bodyParameters` object (+ optional `initOverrides`) | Methods take a single `options` object (+ optional trailing `RequestOptions` for per-request `signal`, `headers`, `customFetch`) | -| Every method returns a `JSONApiResponse` / `VoidApiResponse` / `TextApiResponse` wrapper | Methods return the domain object directly (`TokenResponse`, `SignUpResult`, `string`, `void`) | - -### `oauth.authorizationCodeGrant` → `getTokenByCode` - -The single most important semantic change in the whole migration. In node-auth0 you pass the raw authorization `code` (and `redirect_uri`) that you extracted from the callback query string yourself. In auth0-auth-js you pass the entire callback `URL`; the SDK extracts `code` and enforces PKCE, and `redirect_uri` comes from the `AuthClient` config / `authorizationParams`. The stateless `AuthClient` does **not** validate OAuth `state` — that is your responsibility (or use `@auth0/auth0-server-js` `completeInteractiveLogin`, which owns a transaction store and validates `state` for you). - -**Before (node-auth0):** - -```ts -import { AuthenticationClient } from "auth0"; - -const auth0 = new AuthenticationClient({ domain, clientId, clientSecret }); - -// You parsed `code` out of the callback URL yourself. -const resp = await auth0.oauth.authorizationCodeGrant({ - code, - redirect_uri: "https://app.example.com/callback", -}); -const accessToken = resp.data.access_token; -const expiresIn = resp.data.expires_in; // relative seconds -const reqId = resp.headers.get("x-request-id"); // metadata on success -``` - -**After (auth0-auth-js):** - -```ts -import { AuthClient } from "@auth0/auth0-auth-js"; - -const authClient = new AuthClient({ domain, clientId, clientSecret }); - -// `url` is a URL object for the full incoming request URL, -// e.g. new URL(req.url, `https://${req.headers.host}`) -const tokens = await authClient.getTokenByCode(url, { - // options; e.g. codeVerifier (PKCE) or organization -}); -const accessToken = tokens.accessToken; -const expiresAt = tokens.expiresAt; // absolute Unix seconds -``` - -> If your code manually parses `req.query.code`, that parsing is now the SDK's job. Delete it and hand the SDK the full URL. The SDK reads `code` from the URL and validates the PKCE verifier; it does **not** validate OAuth `state`. **Keep your existing `state` check** (compare the `state` query parameter against what you stored before the redirect) — or migrate to `@auth0/auth0-server-js` `completeInteractiveLogin`, which handles `state` validation automatically. (`getTokenByCode` options are `codeVerifier` and `organization`.) If the node-auth0 code read `resp.headers.get(...)` on success, see [Reading HTTP response metadata](#reading-http-response-metadata-fullresponse). Error-path metadata remains accessible on the typed error. - -> **Warning:** Do not delete your `state`/CSRF check when migrating to `AuthClient.getTokenByCode`. The stateless client does not validate `state`. Removing the check silently disables CSRF protection on the authorization-code flow. - -### `oauth.authorizationCodeGrantWithPKCE` → `getTokenByCode` (with verifier) - -PKCE (Proof Key for Code Exchange) is folded into the same method; supply the code verifier via options. Typically the verifier was produced earlier by `buildAuthorizationUrl` (below), which returns a `codeVerifier` for you to persist. - -```ts -// before -const resp = await auth0.oauth.authorizationCodeGrantWithPKCE({ - code, - code_verifier: verifier, - redirect_uri: "https://app.example.com/callback", -}); - -// after -const tokens = await authClient.getTokenByCode(url, { - codeVerifier: verifier, -}); -``` - -> If you build the authorization URL yourself today, prefer switching to `authClient.buildAuthorizationUrl()` (below) so the SDK generates and returns the `codeVerifier`, then persist it and pass it back to `getTokenByCode`. - -### `oauth.refreshTokenGrant` → `getTokenByRefreshToken` - -```ts -// before -const resp = await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); -// after -const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); -``` - -### `oauth.passwordGrant` → `getTokenByPassword` - -```ts -// before -const resp = await auth0.oauth.passwordGrant({ - username, - password, - realm: "Username-Password-Authentication", - audience, - scope, -}); -// after -const tokens = await authClient.getTokenByPassword({ - username, - password, - realm: "Username-Password-Authentication", - audience, - scope, -}); -``` - -### `oauth.clientCredentialsGrant` → `getTokenByClientCredentials` - -The canonical machine-to-machine grant. This is the most common reason to stay on auth0-auth-js rather than adopt server-js: there is no user session involved. - -```ts -// before -const resp = await auth0.oauth.clientCredentialsGrant({ audience: "https://api.example.com" }); -const token = resp.data.access_token; -// after -const tokens = await authClient.getTokenByClientCredentials({ audience: "https://api.example.com" }); -const token = tokens.accessToken; -``` - -### `oauth.revokeRefreshToken` → `revokeToken` - -Renamed, and simplified return (was `VoidApiResponse`, now `void`). - -```ts -// before -await auth0.oauth.revokeRefreshToken({ token: rt }); -// after -await authClient.revokeToken({ token: rt }); -``` - -> **Session apps:** if you are migrating to server-js and this revoke was part of logout, use `serverClient.revokeRefreshToken()` instead of the low-level `revokeToken`. By default it reads the refresh token from the session; you can also pass an explicit `{ token }` in its options. - -### Build the authorization and logout URLs - -node-auth0 left `/authorize` URL construction to the caller (or to `express-openid-connect`). The new SDK gives you `buildAuthorizationUrl()` and `buildLogoutUrl()`. When migrating a redirect login, replace hand-built `/authorize` and `/v2/logout` URLs with these: - -```ts -const { authorizationUrl, codeVerifier } = await authClient.buildAuthorizationUrl({ - authorizationParams: { redirect_uri, scope: "openid profile email", audience }, -}); -// ... later, on logout: -const logoutUrl = await authClient.buildLogoutUrl({ returnTo: "https://app.example.com" }); -``` - -> Pushed Authorization Requests (PAR): there is no standalone PAR method. Pass `pushedAuthorizationRequests: true` to `buildAuthorizationUrl`: the SDK performs the PAR POST and returns an authorization URL that references the resulting `request_uri`. Requires the tenant to expose a `pushed_authorization_request_endpoint`; the SDK throws if PAR is requested but unsupported. This replaces node-auth0's `oauth.pushedAuthorization`. - -Once the OIDC grants are rewritten and the [cross-cutting breaking changes](#cross-cutting-breaking-changes) are applied, run the [verification checklist](#verification-checklist). If your app also uses database, passwordless, CIBA, token exchange, or `UserInfoClient`, continue with [`authentication-flows.md`](./authentication-flows.md). If you want the SDK to own sessions, see [`server-side-sessions.md`](./server-side-sessions.md). - -### Optional: migrate only OIDC while staying on v6 - -You do not have to migrate everything at once, and you do not have to wait for v7. node-auth0 v6 still ships `AuthenticationClient` alongside `ManagementClient`, so you can move your OIDC login and token grant code off `AuthenticationClient` to `@auth0/auth0-auth-js` now, incrementally, while the rest of the app keeps using `auth0` v6 unchanged. - -A common and fully supported end state: - -- OIDC / token grant code: migrated to `@auth0/auth0-auth-js` (the grants covered in this section). -- Other auth flows you have not gotten to yet: still on `AuthenticationClient` from `auth0` v6. -- Management API: still on `ManagementClient` from `auth0` (never migrates). - -The OIDC grants above are a complete, shippable step on their own; finishing them is a valid stopping point even if you migrate nothing else. Move on to [`authentication-flows.md`](./authentication-flows.md) and [`server-side-sessions.md`](./server-side-sessions.md) later, at your own pace. When you eventually upgrade to v7 (which removes the Authentication API from the main entrypoint; see the [v7 Migration Guide](../v7_MIGRATION_GUIDE.md)), the OIDC work is already done. - -## Cross-cutting breaking changes - -Every call-site rewrite in this guide and on the incremental pages is subject to four changes that cut across all methods. They cause the overwhelming majority of migration defects, and three of the four are *silent*: the code compiles and often runs, but produces wrong behavior at runtime. Apply each one deliberately. - -1. [Return shape: `JSONApiResponse` → domain object](#1-return-shape) -2. [Casing: snake_case wire shape → camelCase](#2-casing) -3. [Token expiry: `expires_in` (relative) → `expiresAt` (absolute)](#3-token-expiry), most dangerous -4. [Error model: `AuthApiError` → typed per-operation errors](#4-error-model) - -### 1. Return shape - -node-auth0 wraps most Authentication API results in a response envelope: - -- `JSONApiResponse`: has `.data` (the payload), `.status` (number), `.statusText`, `.headers` (a `Headers` object). -- `VoidApiResponse`: same envelope, `.data` is `undefined` (used by `sendEmail`, `revokeRefreshToken`, …). -- `TextApiResponse`: `.data` is a `string` (used by `database.changePassword`). - -Exception: `backchannel.authorize`, `backchannel.backchannelGrant`, and `tokenExchange.exchangeToken` return domain objects directly (no `.data` wrapper) in node-auth0. - -The new SDKs drop the envelope and return the domain object directly: - -- Token grants return a `TokenResponse` instance. -- `database.signUp` returns a `SignUpResult` object. -- `database.changePassword` returns a `string`. -- `sendEmail` / `sendSms` / `revokeToken` return `void`. - -HTTP metadata (status code, response headers such as `x-request-id`, `retry-after`, rate-limit headers) is available through the typed error objects on failure paths. On success paths, metadata is available via the opt-in `fullResponse` envelope (see [Reading HTTP response metadata](#reading-http-response-metadata-fullresponse)). It is no longer on the bare success value by default. - -The rewrite: delete `.data` indirection on every success path: - -```ts -// before -const resp = await auth0.oauth.clientCredentialsGrant({ audience }); -const token = resp.data.access_token; -const status = resp.status; - -// after -const tokens = await authClient.getTokenByClientCredentials({ audience }); -const token = tokens.accessToken; -``` - -```ts -// before: changePassword returned TextApiResponse -const resp = await auth0.database.changePassword({ email, connection }); -console.log(resp.data); - -// after: returns the string directly -const message = await authClient.database.changePassword({ email, connection }); -console.log(message); -``` - -> `changePassword` requires `connection` plus at least one of `email` or `username`: either identifier is accepted, not `email` alone. - -#### Reading HTTP response metadata (fullResponse) - -When your node-auth0 code reads HTTP response metadata (status, headers) on a success path, migrate to the opt-in envelope rather than dropping the read. This is most common when you track rate limits, log request IDs, or check retry-after headers for dashboard telemetry. - -```ts -// before (node-auth0): metadata on the success envelope -const resp = await auth0.oauth.clientCredentialsGrant({ audience }); -const remaining = resp.headers.get("x-ratelimit-remaining"); -const token = resp.data.access_token; - -// after: opt in to the envelope, read the native Response -const { data, response } = await authClient.getTokenByClientCredentials({ audience, fullResponse: true }); -const remaining = response.headers.get("x-ratelimit-remaining"); -const token = data.accessToken; -``` - -The same opt-in covers the non-token Authentication API methods that node-auth0 wrapped in a `JSONApiResponse` / `TextApiResponse` / `VoidApiResponse`: - -| Method | Bare return | `fullResponse: true` return | -| --- | --- | --- | -| `database.signUp` | `SignUpResult` | `ApiResponse` | -| `database.changePassword` | `string` | `ApiResponse` | -| `passwordless.sendEmail` | `void` | `ApiResponse` (`data` is `undefined`) | -| `passwordless.sendSms` | `void` | `ApiResponse` (`data` is `undefined`) | - -```ts -// before (node-auth0): read the request id off the signup envelope -const resp = await auth0.database.signUp({ email, password, connection }); -const reqId = resp.headers.get("x-request-id"); - -// after: opt in to the envelope -const { data, response } = await authClient.database.signUp({ email, password, connection, fullResponse: true }); -const reqId = response.headers.get("x-request-id"); - -// void-returning methods expose the Response with an undefined `data` -const { response: sendResp } = await authClient.passwordless.sendEmail({ email, fullResponse: true }); -const rateLimit = sendResp.headers.get("x-ratelimit-remaining"); -``` - -Caveats: - -- Pass `fullResponse: true` as a literal, not a variable. Using spread (`{ ...opts, fullResponse: true }`) widens `true` to `boolean`, causing TypeScript overload resolution to fall back to the bare return type. Fix: pass `{ ...opts, fullResponse: true as const }` or include `fullResponse` as an inline literal in the options object. -- Performance: `@auth0/auth0-auth-js` does not cache tokens: every `AuthClient` grant method performs a live token-endpoint round-trip regardless of `fullResponse`, so the flag adds no extra network cost at this layer. (Token caching and reuse live in `@auth0/auth0-server-js`'s session store, not in the auth-js `AuthClient`.) The only in-memory cache in auth-js is for OIDC discovery / JWKS metadata, which is unrelated to `fullResponse`. -- Reserved headers: a caller `Authorization` header is ignored and the telemetry `Auth0-Client` header always wins; `RequestOptions.headers` cannot override them. -- Per-request `customFetch` replaces the base transport for that call but does not inherit mutual TLS (mTLS). If you rely on mTLS, the supplied fetch must itself be mTLS-capable. - -Default to the bare return type. Reach for `fullResponse` only where you actually consumed response metadata on success: rate-limit dashboards, request-id logging for support investigations, or retry-after handling. `MissingCapturedResponseError` is an internal-bug sentinel; you do not normally catch it. - -Gotchas: - -- **Void methods.** Code that did `const r = await auth0.passwordless.sendEmail(...)` and then checked `r.status === 200` must drop that check: by default the method returns `void` and throws on failure. Rely on the thrown error instead (see [Error model](#4-error-model)). -- **Header reads.** Any code reading `resp.headers.get('x-ratelimit-remaining')` on a success path needs the opt-in `fullResponse` envelope. Error paths still surface metadata on the typed error. Search your code for `.headers` on response values. -- **Do not hand-roll a compatibility shim.** Resist reintroducing a custom `{ data, status }` shape to minimize downstream diff. Let the domain object flow through; the SDK's opt-in `fullResponse` envelope is the sanctioned channel when you genuinely need the HTTP Response. - -### 2. Casing - -node-auth0's public API exposes the snake_case wire shape verbatim, on both inputs and outputs. The new SDKs use camelCase for the public API and only translate to snake_case at the HTTP boundary internally. - -Input parameters, field map: - -| node-auth0 (snake_case) | new SDK (camelCase) | -| --- | --- | -| `client_id` | `clientId` | -| `client_secret` | `clientSecret` | -| `refresh_token` | `refreshToken` | -| `redirect_uri` | (via `authorizationParams.redirect_uri` on config / builder) | -| `code_verifier` | `codeVerifier` | -| `phone_number` | `phoneNumber` | -| `auth_req_id` | `authReqId` | -| `binding_message` | `bindingMessage` | -| `subject_token` / `subject_token_type` | `subjectToken` / `subjectTokenType` | -| `given_name` / `family_name` | `givenName` / `familyName` | -| `user_metadata` | `userMetadata` | -| `login_hint` | `loginHint` | - -Output fields, `TokenResponse` field map: - -| node-auth0 `TokenSet` (snake_case) | new SDK `TokenResponse` (camelCase) | -| --- | --- | -| `access_token` | `accessToken` | -| `refresh_token` | `refreshToken` | -| `id_token` | `idToken` | -| `token_type` | `tokenType` | -| `expires_in` (relative) | `expiresAt` (absolute, see [Token expiry](#3-token-expiry)) | -| `scope` | `scope` | -| (none): had to decode id_token yourself | `claims` (already-decoded ID token claims) | -| `authorization_details` | `authorizationDetails` | - -Rename fields on both the arguments you pass in and the fields you read out: - -```ts -// before -const resp = await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); -const newRt = resp.data.refresh_token; -const idToken = resp.data.id_token; - -// after -const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); -const newRt = tokens.refreshToken; -const idToken = tokens.idToken; -``` - -> **Gotcha: keys that look renamed but are your data.** `user_metadata` → `userMetadata` is a rename of the *SDK's* parameter. The object *inside* it (e.g. `{ plan: 'free' }`) is passed through untouched. Do not rename your own metadata keys. The same applies to `authorization_details`. - -### 3. Token expiry - -**This is the highest-risk change in the migration. It is silent, it compiles, and it corrupts session lifetimes.** - -- node-auth0 `TokenSet.expires_in` = the token's lifetime in seconds relative to now (e.g. `86400` for a 24-hour token). This is the raw OAuth `expires_in` from the wire. -- new SDK `TokenResponse.expiresAt` = an absolute Unix timestamp in seconds (e.g. `1786000000`) computed by the SDK as roughly `now + expires_in`. - -Existing node-auth0 code almost always converts the relative value to an absolute deadline itself: - -```ts -// before: very common node-auth0 pattern -const resp = await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); -const expiresAtMs = Date.now() + resp.data.expires_in * 1000; // stored deadline -``` - -If you mechanically rename `expires_in` → `expiresAt` and leave the arithmetic, you get: - -```ts -// WRONG: double-counts "now" -const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); -const expiresAtMs = Date.now() + tokens.expiresAt * 1000; // ~ now + (now + lifetime) → far future -``` - -The stored deadline lands decades in the future, so the token is treated as valid long after it has actually expired. The app does not refresh it, so production 401s follow. - -The rewrite: `expiresAt` is *already* the deadline. Do not add `Date.now()`: - -```ts -// after: correct -const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); -const expiresAtMs = tokens.expiresAt * 1000; // absolute; convert s → ms only if you store ms -``` - -If downstream code genuinely needs the *relative* remaining lifetime (e.g. to set a cookie `Max-Age`), compute it from the absolute value: - -```ts -const secondsRemaining = tokens.expiresAt - Math.floor(Date.now() / 1000); -``` - -To find every instance, grep your code for these patterns and inspect each by hand: - -- `expires_in` -- `Date.now() +` near a token result -- `+ expires` / `* 1000` near a token result -- any stored field named `expiresAt`, `expires_at`, `expiry`, `tokenExpiry` fed from a grant - -Every one of these is a candidate for the double-count bug. - -> **Session apps get this for free.** If you migrate to server-js, the SDK owns expiry math inside `getAccessToken`. Delete your `Date.now() + expires_in * 1000` bookkeeping entirely. - -### 4. Error model - -node-auth0 throws a single error type for Authentication API failures: - -```ts -class AuthApiError extends Error { - name: "AuthApiError"; - error: string; // OAuth error code, e.g. 'invalid_grant' - error_description: string; - statusCode: number; - body: string; - headers: Headers; -} -``` - -The new SDKs throw typed, operation-specific error classes: `TokenByCodeError`, `TokenByRefreshTokenError`, `TokenByClientCredentialsError`, `TokenByPasswordError`, `TokenExchangeError`, `TokenRevocationError`, `PasswordlessStartError`, `PasswordlessChallengeError`, `PasswordlessDbGetTokenError`, `MfaEnrollmentError`, and so on. Each carries a structured `.cause` (the underlying OAuth2 error) rather than flat `error` / `error_description` strings. - -The rewrite: generic catch: - -```ts -// before -try { - await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); -} catch (e) { - if (e instanceof AuthApiError && e.error === "invalid_grant") { - // refresh token revoked/expired - } -} - -// after -import { TokenByRefreshTokenError } from "@auth0/auth0-auth-js"; -try { - await authClient.getTokenByRefreshToken({ refreshToken: rt }); -} catch (e) { - if (e instanceof TokenByRefreshTokenError && e.cause?.error === "invalid_grant") { - // refresh token revoked/expired - } -} -``` - -Import the specific error class for the operation you are calling. If you had one broad `catch (e instanceof AuthApiError)` around several different operations, either widen to catch each operation's error type or check the shared base behavior. Prefer the specific type per call site, since it documents which operation can fail. - -#### MFA detection: use the type guard, not the string - -Multi-factor authentication (MFA). A very common node-auth0 pattern is detecting `mfa_required` by string comparison to route the user into an MFA challenge: - -```ts -// before -try { - await auth0.oauth.passwordGrant({ username, password }); -} catch (e) { - if (e instanceof AuthApiError && e.error === "mfa_required") { - // start MFA flow using e (mfa_token is in the body) - } -} -``` - -The new SDK provides `isMfaRequiredError()`, a type guard that narrows the error and gives typed access to the MFA context (including the `mfa_token`). Use it instead of matching the string: - -```ts -// after -import { isMfaRequiredError } from "@auth0/auth0-auth-js"; -try { - await authClient.getTokenByPassword({ username, password }); -} catch (e) { - if (isMfaRequiredError(e)) { - // e is narrowed; drive the MFA challenge via authClient.mfa.* - } -} -``` - -> After detecting `mfa_required`, the MFA enroll/challenge/verify flow that node-auth0 handled ad hoc now lives on `authClient.mfa.*` (`listAuthenticators`, `enrollAuthenticator`, `challengeAuthenticator`, `verify`, and `deleteAuthenticator`). In server-js, `serverClient.mfa.verify()` also persists the resulting tokens to the session. - -#### ID-token validation types - -node-auth0 exposed `IDTokenValidateOptions` and `IdTokenValidatorError` for callers doing manual ID-token validation. The new SDK validates ID tokens internally during grants and exposes the decoded, validated result as `TokenResponse.claims`. Replace manual validation: - -- Options like `organization`, `nonce`, `maxAge` are passed to the grant call (e.g. `getTokenByCode`), and the SDK validates them and throws a typed error on mismatch, so you no longer construct a validator or catch `IdTokenValidatorError` yourself. -- Read the validated claims from `TokenResponse.claims` instead of decoding the `id_token` string. - -## Verification checklist - -The migration is not complete until every check passes in a single pass. For every node-auth0 auth call you rewrote (here or on the incremental pages), confirm all four cross-cutting changes: - -- [ ] **Return shape**: removed `.data` / `.status` / `.headers` access on the success path. -- [ ] **Casing**: renamed every snake_case field on input args and output reads to camelCase. -- [ ] **Expiry**: any code using the old `expires_in` now uses `expiresAt` as an *absolute* timestamp; no `Date.now() +` was left in front of it. -- [ ] **Errors**: `AuthApiError` catches replaced with the specific typed error (`.cause.error`); `mfa_required` string checks replaced with `isMfaRequiredError()`. - -Then run the project gates and repeat the whole loop if any step fails: - -- [ ] Grep for residue: unmigrated `from 'auth0'` auth imports, `.data.` reads on auth responses, and relative `expires_in` arithmetic. -- [ ] `tsc --noEmit`: catches structural mismatches and type errors. -- [ ] `npm test` (or the project's test command): confirms behavior is preserved. -- [ ] Run the linter if the project has one configured. -- [ ] Confirm files that use `ManagementClient` still import and call it from `auth0`; that code must be untouched. - -Do not declare the migration complete until the loop converges: all steps pass in a single iteration. - -## Continue the migration - -Once the OIDC grants and the four cross-cutting changes are in, migrate the rest at your own pace. Each area lives in its own page. - -### Other authentication flows - -Database signup, passwordless, backchannel (CIBA), token exchange, and `UserInfoClient` lookups: see [`authentication-flows.md`](./authentication-flows.md). - -### Server-side sessions - -Routing to `@auth0/auth0-server-js`, where the SDK owns the login redirect flow, session storage, cookies, token refresh, and logout: see [`server-side-sessions.md`](./server-side-sessions.md). - -### Troubleshooting - -Common questions and failure modes (tokens valid for decades, missing `resp.data`, magic-link default flip, `getUserInfo`, `mfa_required` detection, global config): see [`troubleshooting.md`](./troubleshooting.md). diff --git a/auth-migration/server-side-sessions.md b/auth-migration/server-side-sessions.md deleted file mode 100644 index d040e2986b..0000000000 --- a/auth-migration/server-side-sessions.md +++ /dev/null @@ -1,163 +0,0 @@ -# Migrating session apps to `@auth0/auth0-server-js` - -This page is part of the [Authentication Migration Guide](./index.md). Read it only when you are routing to **`@auth0/auth0-server-js`**: when you want the SDK to own the login redirect flow, session storage, cookies, token refresh, and logout, instead of hand-rolling that around node-auth0. If you only need stateless token grants, stay on the main guide and [`authentication-flows.md`](./authentication-flows.md); you do not need this page. - -> **Migrating with an AI agent?** Point it at the Auth0 migration skill (the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`). It walks the session lifecycle step by step. - -**This is a rewrite of the session handling, not a method-for-method port.** node-auth0 had no session concept, so there is nothing to translate line-for-line. Instead you *replace* your existing session code (your `express-session` wiring, your token cache, your refresh-on-expiry logic, your logout handler) with the ServerClient lifecycle. You still touch only the auth/session code; routes, views, and business logic stay put. - -- [Mental model](#mental-model) -- [Store setup](#store-setup) -- [The redirect-login lifecycle](#the-redirect-login-lifecycle) -- [Logins without a browser redirect](#logins-without-a-browser-redirect) -- [Backchannel logout](#backchannel-logout) - -## Mental model - -A ServerClient login has three durable pieces: - -1. **Transaction store**: short-lived. Holds the in-flight login: the OAuth `state` and the PKCE (Proof Key for Code Exchange) `code_verifier` between the moment you redirect the user to Auth0 and the moment they come back to your callback. Created at `startInteractiveLogin`, consumed at `completeInteractiveLogin`. -2. **State store**: long-lived. Holds the established session: the user claims plus the access / refresh / ID tokens and their absolute expiry. Read on every subsequent request via `getUser`, `getSession`, `getAccessToken`. -3. **Cookies**: how the two stores key themselves to the browser. With a *stateless* store the session data lives encrypted in the cookie itself; with a *stateful* store the cookie holds only an identifier and the data lives in your backend (Redis, database, and so on). - -node-auth0 exposed none of this; you built equivalents by hand. You are swapping your implementation for the SDK's. - -## Store setup - -`@auth0/auth0-server-js` ships store base classes and cookie-backed implementations: - -- `CookieTransactionStore`: transaction store backed entirely by a cookie. Good default. -- `StatelessStateStore`: session lives encrypted in the cookie. No server-side storage; good for serverless or horizontally-scaled deployments with small sessions. -- `StatefulStateStore`: session lives server-side; the cookie holds an id. Use for large sessions or when you need server-side revocation. -- `AbstractTransactionStore` / `AbstractStateStore`: extend these to back a store with your own storage (Redis, Postgres, and so on). These are the exported base-class names. - -All stores accept a `CookieHandler` so they can integrate with any framework's cookie API. The `storeOptions` generic (`TStoreOptions`) is how you thread per-request context (like the framework `req` / `res`) into store reads and writes; every ServerClient method takes an optional trailing `storeOptions` argument for exactly this. - -```ts -import { ServerClient, CookieTransactionStore, StatelessStateStore } from "@auth0/auth0-server-js"; - -const serverClient = new ServerClient({ - domain: process.env.AUTH0_DOMAIN!, - clientId: process.env.AUTH0_CLIENT_ID!, - clientSecret: process.env.AUTH0_CLIENT_SECRET!, - authorizationParams: { - redirect_uri: "https://app.example.com/callback", - scope: "openid profile email offline_access", // offline_access ⇒ refresh token - audience: "https://api.example.com", - }, - transactionStore: new CookieTransactionStore( - { secret: process.env.SESSION_SECRET! }, - cookieHandler, // CookieHandler implementation - ), - stateStore: new StatelessStateStore( - { secret: process.env.SESSION_SECRET! }, - cookieHandler, // CookieHandler implementation - ), -}); -``` - -## The redirect-login lifecycle - -### 1. Start login: replace the hand-built `/authorize` redirect - -Whatever you did to send the user to Auth0 (a hand-constructed `/authorize` URL, or `express-openid-connect`'s `/login`) becomes: - -```ts -// GET /login -app.get("/login", async (req, res) => { - const authorizationUrl = await serverClient.startInteractiveLogin( - { - authorizationParams: { - /* optional per-login overrides */ - }, - appState: { returnTo: req.query.returnTo || "/" }, // seed appState for round-trip - }, - { req, res }, // storeOptions: lets the transaction store write its cookie - ); - res.redirect(authorizationUrl.href); -}); -``` - -`startInteractiveLogin` generates `state` and PKCE, writes them to the transaction store, and returns the fully-formed authorization URL. - -### 2. Complete login: replace the manual code exchange - -The callback handler that used to call `oauth.authorizationCodeGrant` (or `authorizationCodeGrantWithPKCE`) and then stuff tokens into the session becomes a single call: - -```ts -// GET /callback -app.get("/callback", async (req, res) => { - const callbackUrl = new URL(req.url, `https://${req.headers.host}`); - const { appState } = await serverClient.completeInteractiveLogin(callbackUrl, { req, res }); - // Session is now established in the state store. Tokens are NOT your concern anymore. - res.redirect(appState?.returnTo ?? "/"); -}); -``` - -`completeInteractiveLogin` validates `state`, exchanges the code, validates the ID token, writes the session (user + tokens + absolute expiry) to the state store, and clears the transaction. - -### 3. Read the user or session on later requests - -Replace `req.session.user` reads: - -```ts -const user = await serverClient.getUser({ req, res }); // user claims, or undefined -const session = await serverClient.getSession({ req, res }); // full session data, or undefined -``` - -`getUser` / `getSession` return `undefined` when there is no session or it has expired (the store deletes expired sessions on read), so use that as your "not logged in" signal. - -### 4. Get an access token to call an API: refresh is automatic - -Replace your manual "is the token expired? if so refresh" block: - -```ts -const { accessToken } = await serverClient.getAccessToken({ req, res }); -// If the stored access token is expired and a refresh token exists, -// the SDK refreshes and persists the new tokens transparently. -``` - -This is where the `expires_in` → `expiresAt` hazard disappears entirely: the SDK owns expiry math. For a downstream federated connection token (Token Vault), use `serverClient.getAccessTokenForConnection({ connection }, { req, res })`. - -### 5. Logout: replace manual revoke, session clear, and `/v2/logout` redirect - -```ts -// GET /logout -app.get("/logout", async (req, res) => { - const logoutUrl = await serverClient.logout({ returnTo: "https://app.example.com" }, { req, res }); - res.redirect(logoutUrl.href); -}); -``` - -`logout` clears the session from the state store and returns the Auth0 `/v2/logout` URL. If you also revoked the refresh token on logout (via `oauth.revokeRefreshToken`), call `serverClient.revokeRefreshToken({ req, res })` before redirecting; by default it reads the refresh token from the session, so you do not handle the raw token yourself (it also accepts an explicit `{ token }` if you need to revoke a specific one). - -## Logins without a browser redirect - -Some logins do not use a browser redirect: the password grant, passwordless, CIBA, and custom token exchange. If you used node-auth0 for one of these *and* want a server-js session out of it, use the ServerClient methods that both authenticate and write the session, rather than the low-level auth-js grants: - -| Flow | ServerClient method | -| --- | --- | -| Backchannel / CIBA | `loginBackchannel({ ... }, storeOptions)` | -| Passwordless (send) | `startPasswordless({ connection, email \| phoneNumber, ... }, storeOptions)` | -| Passwordless (verify code → session) | `completePasswordless({ connection, email \| phoneNumber, verificationCode }, storeOptions)` | -| Passwordless magic link (callback → session) | `completePasswordlessMagicLink(url, storeOptions)` | -| Custom token exchange → session | `loginWithCustomTokenExchange({ ... }, storeOptions)` | -| MFA verify → session | `serverClient.mfa.verify({ ... }, storeOptions)` | - -Each of these performs the underlying grant *and* persists the resulting tokens to the state store, so the user is logged in afterward, exactly the behavior you previously wrote by hand after a node-auth0 grant. - -## Backchannel logout - -If you implemented an Auth0 back-channel logout endpoint by hand (validating the logout token, then clearing your session store), replace it with: - -```ts -// POST /backchannel-logout -app.post("/backchannel-logout", async (req, res) => { - await serverClient.handleBackchannelLogout(req.body.logout_token, { req, res }); - res.sendStatus(204); -}); -``` - -It validates the logout token and clears the corresponding session. - -When the session layer is wired, return to the [verification checklist](./index.md#verification-checklist) in the main guide. diff --git a/auth-migration/troubleshooting.md b/auth-migration/troubleshooting.md deleted file mode 100644 index 334a37a698..0000000000 --- a/auth-migration/troubleshooting.md +++ /dev/null @@ -1,32 +0,0 @@ -# Troubleshooting: FAQ and gotchas - -Common questions and failure modes when migrating off the `auth0` package's Authentication API. This page is part of the [Authentication Migration Guide](./index.md); it assumes the terms defined there. - -> **Migrating with an AI agent?** Point it at the Auth0 migration skill (the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`). - -### Do I have to migrate everything at once? -No. The OIDC / token-grant work is a complete, shippable step on its own. You can stay on `auth0` v6 and migrate only OIDC, leaving other auth flows on `AuthenticationClient` for now. See [Optional: migrate only OIDC while staying on v6](./index.md#optional-migrate-only-oidc-while-staying-on-v6). - -### Do I have to migrate the Management API too? -No. `ManagementClient` is out of scope and stays on the `auth0` package. A file importing both `auth0` (for management) and `@auth0/auth0-auth-js` (for authentication) is correct. - -### auth0-auth-js or auth0-server-js: which do I pick? -Default to auth0-auth-js for a low-risk parity migration. Pick auth0-server-js only when you want the SDK to own the login redirect flow, session storage, cookies, refresh, and logout. See [Choosing your target SDK](./index.md#choosing-your-target-sdk). - -### My tokens suddenly look valid for decades. What happened? -You almost certainly left `Date.now() +` in front of `expiresAt`. `expiresAt` is already an absolute Unix timestamp, not a relative lifetime. See [Token expiry](./index.md#3-token-expiry). - -### Where did `resp.data` go? -The new SDKs return the domain object directly. Read `tokens.accessToken`, not `resp.data.access_token`. If you truly need HTTP response metadata on a success path, opt into `fullResponse`. - -### My magic-link passwordless flow stopped sending links. -The `send` default changed from `'link'` (node-auth0) to `'code'` (new SDK). Set `send: 'link'` explicitly if you want magic links. See [Passwordless](./authentication-flows.md#passwordless). - -### Where is `getUserInfo`? -Prefer `TokenResponse.claims`; they are already decoded and validated, with no extra round-trip. For an arbitrary access token, use `authClient.getUserInfo({ accessToken })`. In a session app, use `serverClient.getUser()`. See [UserInfoClient](./authentication-flows.md#userinfoclient). - -### Can I still set a global `headers` / `timeout` / `agent` on the client? -Not on the constructor. Move them to the per-call `RequestOptions` argument (`headers`, `signal: AbortSignal.timeout(ms)`) or wrap `customFetch`. - -### How do I detect `mfa_required` now? -Use the `isMfaRequiredError()` type guard, not a string comparison. It narrows the error and exposes the `mfa_token`. Drive the challenge via `authClient.mfa.*`. See [Error model](./index.md#4-error-model). diff --git a/package.json b/package.json index 498d343959..afb1c958b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "auth0", - "version": "7.6.0", + "version": "7.6.1", "private": false, "repository": { "type": "git", diff --git a/reference.md b/reference.md index 466e9bb8fb..03c7be2f28 100644 --- a/reference.md +++ b/reference.md @@ -13285,6 +13285,211 @@ await client.users.update("id"); +
client.users.listConsentSigningKeys(id) -> Management.ListUserConsentSigningKeysResponseContent +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve all consent signing keys registered for a user. Returns an empty array when the user has no keys registered. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.users.listConsentSigningKeys("id"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `string` — The ID of the user. + +
+
+ +
+
+ +**requestOptions:** `UsersClient.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.users.getConsentSigningKey(id, kid) -> Management.ConsentSigningKey +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve a single consent signing key for a user by its key identifier (kid). Returns 404 if the key does not exist. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.users.getConsentSigningKey("id", "kid"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `string` — The ID of the user. + +
+
+ +
+
+ +**kid:** `string` — The key identifier of the consent signing key. + +
+
+ +
+
+ +**requestOptions:** `UsersClient.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.users.deleteConsentSigningKey(id, kid) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Remove a single consent signing key for a user by its key identifier (kid). The operation is idempotent and returns 204 whether or not the key existed. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.users.deleteConsentSigningKey("id", "kid"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `string` — The ID of the user. + +
+
+ +
+
+ +**kid:** `string` — The key identifier of the consent signing key. + +
+
+ +
+
+ +**requestOptions:** `UsersClient.RequestOptions` + +
+
+
+
+ +
+
+
+
client.users.regenerateRecoveryCode(id) -> Management.RegenerateUsersRecoveryCodeResponseContent
@@ -20797,6 +21002,7 @@ const pageableResponse = await client.experimentation.segments.list({ from: "from", take: 1, type: "auth0", + status: "active", }); for await (const item of pageableResponse) { console.log(item); @@ -20807,6 +21013,7 @@ let page = await client.experimentation.segments.list({ from: "from", take: 1, type: "auth0", + status: "active", }); while (page.hasNextPage()) { page = await page.getNextPage(); diff --git a/src/management/api/requests/requests.ts b/src/management/api/requests/requests.ts index cea5fa740b..693f8fb646 100644 --- a/src/management/api/requests/requests.ts +++ b/src/management/api/requests/requests.ts @@ -1669,6 +1669,7 @@ export interface CreateResourceServerRequestContent { proof_of_possession?: Management.ResourceServerProofOfPossession | null; subject_type_authorization?: Management.ResourceServerSubjectTypeAuthorization; authorization_policy?: Management.ResourceServerAuthorizationPolicy | null; + type?: Management.ResourceServerTypeEnum | null; } /** @@ -1747,6 +1748,7 @@ export interface UpdateResourceServerRequestContent { proof_of_possession?: Management.ResourceServerProofOfPossession | null; subject_type_authorization?: Management.ResourceServerSubjectTypeAuthorization; authorization_policy?: Management.ResourceServerAuthorizationPolicy | null; + type?: Management.ResourceServerTypeEnum | null; } /** @@ -2492,9 +2494,9 @@ export interface UpdateBruteForceSettingsRequestContent { /** List of trusted IP addresses that will not have attack protection enforced against them. */ allowlist?: string[]; mode?: Management.BruteForceProtectionModeEnum; + form_submission_mode?: Management.BruteForceProtectionFormSubmissionModeEnum; /** Maximum number of unsuccessful attempts. */ max_attempts?: number; - form_submission_mode?: Management.BruteForceProtectionFormSubmissionModeEnum; } /** @@ -3236,7 +3238,8 @@ export interface UpdateFeatureFlagRequestContent { * { * from: "from", * take: 1, - * type: "auth0" + * type: "auth0", + * status: "active" * } */ export interface ListSegmentsRequestParameters { @@ -3246,6 +3249,8 @@ export interface ListSegmentsRequestParameters { take?: number | null; /** Filter by type. Exact match. */ type?: Management.SegmentTypeFilterEnum | null; + /** Filter by status. Exact match. */ + status?: Management.SegmentStatusEnum | null; } /** diff --git a/src/management/api/resources/experimentation/resources/segments/client/Client.ts b/src/management/api/resources/experimentation/resources/segments/client/Client.ts index 1ed064ecc6..b361462df0 100644 --- a/src/management/api/resources/experimentation/resources/segments/client/Client.ts +++ b/src/management/api/resources/experimentation/resources/segments/client/Client.ts @@ -40,7 +40,8 @@ export class SegmentsClient { * await client.experimentation.segments.list({ * from: "from", * take: 1, - * type: "auth0" + * type: "auth0", + * status: "active" * }) */ public async list( @@ -51,11 +52,12 @@ export class SegmentsClient { async ( request: Management.ListSegmentsRequestParameters, ): Promise> => { - const { from: from_, take = 50, type: type_ } = request; + const { from: from_, take = 50, type: type_, status } = request; const _queryParams: Record = { from: from_, take, type: type_ !== undefined ? type_ : undefined, + status: status !== undefined ? status : undefined, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); let _headers: core.Fetcher.Args["headers"] = mergeHeaders( diff --git a/src/management/api/resources/users/client/Client.ts b/src/management/api/resources/users/client/Client.ts index 562c993100..1807c89bf4 100644 --- a/src/management/api/resources/users/client/Client.ts +++ b/src/management/api/resources/users/client/Client.ts @@ -801,6 +801,258 @@ export class UsersClient { return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/users/{id}"); } + /** + * Retrieve all consent signing keys registered for a user. Returns an empty array when the user has no keys registered. + * + * @param {string} id - The ID of the user. + * @param {UsersClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Management.BadRequestError} + * @throws {@link Management.UnauthorizedError} + * @throws {@link Management.ForbiddenError} + * @throws {@link Management.TooManyRequestsError} + * @throws {@link errors.ManagementError} + * @throws {@link errors.ManagementTimeoutError} + * + * @example + * await client.users.listConsentSigningKeys("id") + */ + public listConsentSigningKeys( + id: string, + requestOptions?: UsersClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__listConsentSigningKeys(id, requestOptions)); + } + + private async __listConsentSigningKeys( + id: string, + requestOptions?: UsersClient.RequestOptions, + ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.ManagementEnvironment.Default, + `users/${core.url.encodePathParam(id, errors.ManagementError)}/consent-signing-keys`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as Management.ListUserConsentSigningKeysResponseContent, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Management.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 401: + throw new Management.UnauthorizedError(_response.error.body as unknown, _response.rawResponse); + case 403: + throw new Management.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 429: + throw new Management.TooManyRequestsError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.ManagementError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/users/{id}/consent-signing-keys", + ); + } + + /** + * Retrieve a single consent signing key for a user by its key identifier (kid). Returns 404 if the key does not exist. + * + * @param {string} id - The ID of the user. + * @param {string} kid - The key identifier of the consent signing key. + * @param {UsersClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Management.BadRequestError} + * @throws {@link Management.UnauthorizedError} + * @throws {@link Management.ForbiddenError} + * @throws {@link Management.NotFoundError} + * @throws {@link Management.TooManyRequestsError} + * @throws {@link errors.ManagementError} + * @throws {@link errors.ManagementTimeoutError} + * + * @example + * await client.users.getConsentSigningKey("id", "kid") + */ + public getConsentSigningKey( + id: string, + kid: string, + requestOptions?: UsersClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getConsentSigningKey(id, kid, requestOptions)); + } + + private async __getConsentSigningKey( + id: string, + kid: string, + requestOptions?: UsersClient.RequestOptions, + ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.ManagementEnvironment.Default, + `users/${core.url.encodePathParam(id, errors.ManagementError)}/consent-signing-keys/${core.url.encodePathParam(kid, errors.ManagementError)}`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as Management.ConsentSigningKey, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Management.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 401: + throw new Management.UnauthorizedError(_response.error.body as unknown, _response.rawResponse); + case 403: + throw new Management.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Management.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 429: + throw new Management.TooManyRequestsError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.ManagementError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/users/{id}/consent-signing-keys/{kid}", + ); + } + + /** + * Remove a single consent signing key for a user by its key identifier (kid). The operation is idempotent and returns 204 whether or not the key existed. + * + * @param {string} id - The ID of the user. + * @param {string} kid - The key identifier of the consent signing key. + * @param {UsersClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Management.BadRequestError} + * @throws {@link Management.UnauthorizedError} + * @throws {@link Management.ForbiddenError} + * @throws {@link Management.TooManyRequestsError} + * @throws {@link errors.ManagementError} + * @throws {@link errors.ManagementTimeoutError} + * + * @example + * await client.users.deleteConsentSigningKey("id", "kid") + */ + public deleteConsentSigningKey( + id: string, + kid: string, + requestOptions?: UsersClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deleteConsentSigningKey(id, kid, requestOptions)); + } + + private async __deleteConsentSigningKey( + id: string, + kid: string, + requestOptions?: UsersClient.RequestOptions, + ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.ManagementEnvironment.Default, + `users/${core.url.encodePathParam(id, errors.ManagementError)}/consent-signing-keys/${core.url.encodePathParam(kid, errors.ManagementError)}`, + ), + method: "DELETE", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: undefined, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Management.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 401: + throw new Management.UnauthorizedError(_response.error.body as unknown, _response.rawResponse); + case 403: + throw new Management.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 429: + throw new Management.TooManyRequestsError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.ManagementError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "DELETE", + "/users/{id}/consent-signing-keys/{kid}", + ); + } + /** * Remove an existing multi-factor authentication (MFA) [recovery code](https://auth0.com/docs/secure/multi-factor-authentication/reset-user-mfa) and generate a new one. If a user cannot access the original device or account used for MFA enrollment, they can use a recovery code to authenticate. * diff --git a/src/management/api/types/types.ts b/src/management/api/types/types.ts index 9d82c4d1d4..c6f2ec5bab 100644 --- a/src/management/api/types/types.ts +++ b/src/management/api/types/types.ts @@ -2346,6 +2346,7 @@ export interface Client { | Management.ClientAnonymousSessionTransferNetworkBindingEnum | undefined; third_party_security_mode?: Management.ClientThirdPartySecurityModeEnum | undefined; + oidc_support?: Management.ClientOidcSupport | undefined; redirection_policy?: Management.ClientRedirectionPolicyEnum | undefined; /** The identifier of the resource server that this client is linked to. */ resource_server_identifier?: string | undefined; @@ -3287,6 +3288,17 @@ export interface ClientOidcBackchannelLogoutSettings { [key: string]: any; } +/** + * OIDC support configuration for this client. + */ +export interface ClientOidcSupport { + is_allowed?: boolean | undefined; + allow_all_scopes?: boolean | undefined; + allowed_scopes?: Management.ClientOidcSupportAllowedScopesEnum[] | undefined; + /** Accepts any additional properties */ + [key: string]: any; +} + export const ClientOidcSupportAllowedScopesEnum = { Profile: "profile", Email: "email", @@ -3636,6 +3648,7 @@ export interface ClientSearchResponse { | Management.ClientAnonymousSessionTransferNetworkBindingEnum | undefined; third_party_security_mode?: Management.ClientThirdPartySecurityModeEnum | undefined; + oidc_support?: Management.ClientOidcSupport | undefined; redirection_policy?: Management.ClientRedirectionPolicyEnum | undefined; /** The identifier of the resource server that this client is linked to. */ resource_server_identifier?: string | undefined; @@ -4127,6 +4140,11 @@ export type ConnectionClientIdOidc = string; */ export type ConnectionClientIdPaypal = string; +/** + * OIDC client identifier issued by the identity provider during application registration. Used to authenticate your Auth0 connection when exchanging SAML Assertions for Refresh Tokens. + */ +export type ConnectionClientIdSamlxaaRequestingApp = Management.ConnectionClientIdOidc; + /** * The OAuth 2.0 client identifier */ @@ -4212,6 +4230,11 @@ export type ConnectionClientSecretOidc = string; */ export type ConnectionClientSecretPaypal = string; +/** + * OAuth 2.0 client secret issued by the identity provider during application registration. Used to authenticate your Auth0 connection when exchanging authorization codes for tokens. May be null for public clients. + */ +export type ConnectionClientSecretSamlxaaRequestingApp = string; + /** * The OAuth 2.0 client secret */ @@ -5159,6 +5182,7 @@ export interface ConnectionOptionsAuth0 extends Management.ConnectionOptionsComm enabledDatabaseCustomization?: Management.ConnectionEnabledDatabaseCustomization | undefined; import_mode?: Management.ConnectionImportMode | undefined; mfa?: Management.ConnectionMfa | undefined; + otp_settings?: Management.ConnectionOtpSettings | undefined; passkey_options?: (Management.ConnectionPasskeyOptions | null) | undefined; passwordPolicy?: (Management.ConnectionPasswordPolicyEnum | null) | undefined; password_complexity_options?: (Management.ConnectionPasswordComplexityOptions | null) | undefined; @@ -6123,6 +6147,8 @@ export type ConnectionOptionsProtocolEnumTwitter = */ export interface ConnectionOptionsSaml extends Management.ConnectionOptionsCommonSaml, Management.ConnectionOptionsCommon { + client_id?: Management.ConnectionClientIdSamlxaaRequestingApp | undefined; + client_secret?: Management.ConnectionClientSecretSamlxaaRequestingApp | undefined; debug?: Management.ConnectionDebugSaml | undefined; deflate?: Management.ConnectionOptionsDeflateSaml | undefined; destinationUrl?: Management.ConnectionDestinationUrlSaml | undefined; @@ -6446,6 +6472,24 @@ export interface ConnectionOptionsYandex extends Management.ConnectionOptionsOAu [key: string]: any; } +/** + * OTP settings for a delivery channel. + */ +export interface ConnectionOtpChannelSettings { + /** Number of digits in the generated one-time password. */ + otp_length?: number | undefined; + /** Number of seconds before the one-time password expires. */ + otp_expiry?: number | undefined; +} + +/** + * One-time password settings, configurable per delivery channel. + */ +export interface ConnectionOtpSettings { + email?: Management.ConnectionOtpChannelSettings | undefined; + phone?: Management.ConnectionOtpChannelSettings | undefined; +} + /** * Passkey authentication enablement */ @@ -6845,6 +6889,7 @@ export interface ConnectionPropertiesOptions { /** Stores encrypted string only configurations for connections */ configuration?: (Record | null) | undefined; customScripts?: Management.ConnectionCustomScripts | undefined; + otp_settings?: Management.ConnectionOtpSettings | undefined; authentication_methods?: (Management.ConnectionAuthenticationMethods | null) | undefined; passkey_options?: (Management.ConnectionPasskeyOptions | null) | undefined; passwordPolicy?: (Management.ConnectionPasswordPolicyEnum | null) | undefined; @@ -7625,6 +7670,7 @@ export namespace ConnectionResponseContentPlanningCenter { export interface ConnectionResponseContentSaml extends Management.ConnectionPurposes, Management.ConnectionResponseCommon { strategy: ConnectionResponseContentSaml.Strategy; + cross_app_access_requesting_app?: Management.CrossAppAccessRequestingApp | undefined; cross_app_access_resource_app?: (Management.ConnectionCrossAppAccessResourceApp | null) | undefined; options?: Management.ConnectionOptionsSaml | undefined; provisioning_ticket_url?: Management.ConnectionProvisioningTicketUrl | undefined; @@ -8620,6 +8666,17 @@ export interface ConnectionsOidcMetadata { [key: string]: any; } +export interface ConsentSigningKey { + /** The key identifier of the consent signing key. */ + kid: string; + /** A human-readable label for the device holding the corresponding private key. */ + device_identifier: string; + /** The ISO 8601 timestamp at which the key was registered. */ + created_at: string; + /** The ISO 8601 timestamp at which the key expires and can no longer be used to verify consent decisions. */ + expires_at: string; +} + /** * Content Security Policy configuration with multi-policy support. */ @@ -8880,6 +8937,7 @@ export interface CreateClientResponseContent { | Management.ClientAnonymousSessionTransferNetworkBindingEnum | undefined; third_party_security_mode?: Management.ClientThirdPartySecurityModeEnum | undefined; + oidc_support?: Management.ClientOidcSupport | undefined; redirection_policy?: Management.ClientRedirectionPolicyEnum | undefined; /** The identifier of the resource server that this client is linked to. */ resource_server_identifier?: string | undefined; @@ -9496,6 +9554,7 @@ export namespace CreateConnectionRequestContentPlanningCenter { */ export interface CreateConnectionRequestContentSaml extends Management.CreateConnectionCommon { strategy: CreateConnectionRequestContentSaml.Strategy; + cross_app_access_requesting_app?: Management.CrossAppAccessRequestingApp | undefined; cross_app_access_resource_app?: (Management.ConnectionCrossAppAccessResourceApp | null) | undefined; options?: Management.ConnectionOptionsSaml | undefined; show_as_button?: Management.ConnectionShowAsButton | undefined; @@ -10913,6 +10972,7 @@ export interface CreateResourceServerResponseContent { authorization_policy?: (Management.ResourceServerAuthorizationPolicy | null) | undefined; /** The client ID of the client that this resource server is linked to */ client_id?: string | undefined; + type?: (Management.ResourceServerTypeEnum | null) | undefined; } export interface CreateRoleResponseContent { @@ -32770,9 +32830,9 @@ export interface GetBruteForceSettingsResponseContent { /** List of trusted IP addresses that will not have attack protection enforced against them. */ allowlist?: string[] | undefined; mode?: Management.BruteForceProtectionModeEnum | undefined; + form_submission_mode?: Management.BruteForceProtectionFormSubmissionModeEnum | undefined; /** Maximum number of unsuccessful attempts. */ max_attempts?: number | undefined; - form_submission_mode?: Management.BruteForceProtectionFormSubmissionModeEnum | undefined; } export interface GetClientCredentialResponseContent { @@ -32922,6 +32982,7 @@ export interface GetClientResponseContent { | Management.ClientAnonymousSessionTransferNetworkBindingEnum | undefined; third_party_security_mode?: Management.ClientThirdPartySecurityModeEnum | undefined; + oidc_support?: Management.ClientOidcSupport | undefined; redirection_policy?: Management.ClientRedirectionPolicyEnum | undefined; /** The identifier of the resource server that this client is linked to. */ resource_server_identifier?: string | undefined; @@ -33819,6 +33880,7 @@ export interface GetResourceServerResponseContent { authorization_policy?: (Management.ResourceServerAuthorizationPolicy | null) | undefined; /** The client ID of the client that this resource server is linked to */ client_id?: string | undefined; + type?: (Management.ResourceServerTypeEnum | null) | undefined; } export interface GetRiskAssessmentsSettingsNewDeviceResponseContent { @@ -35150,6 +35212,8 @@ export interface ListUserConnectedAccountsResponseContent { next?: string | undefined; } +export type ListUserConsentSigningKeysResponseContent = Management.ConsentSigningKey[]; + export interface ListUserEffectivePermissionRoleSourcesResponseContent { /** Roles with the specified permission assigned to the user, both directly and via groups. */ roles: Management.UserEffectivePermissionRoleSourceResponseContent[]; @@ -37060,6 +37124,7 @@ export interface ResourceServer { authorization_policy?: (Management.ResourceServerAuthorizationPolicy | null) | undefined; /** The client ID of the client that this resource server is linked to */ client_id?: string | undefined; + type?: (Management.ResourceServerTypeEnum | null) | undefined; } /** @@ -37176,6 +37241,7 @@ export interface ResourceServerSearchResponse { authorization_policy?: (Management.ResourceServerAuthorizationPolicy | null) | undefined; /** The client ID of the client that this resource server is linked to */ client_id?: string | undefined; + type?: (Management.ResourceServerTypeEnum | null) | undefined; } /** Field name to sort results by in ascending order only. Defaults to insertion order (oldest first) if not provided. */ @@ -37299,6 +37365,12 @@ export interface ResourceServerTokenEncryptionKey { pem: string; } +/** The type of the resource server. */ +export const ResourceServerTypeEnum = { + UniversalCommerceProtocolServer: "universal_commerce_protocol_server", +} as const; +export type ResourceServerTypeEnum = (typeof ResourceServerTypeEnum)[keyof typeof ResourceServerTypeEnum]; + /** * PEM-encoded certificate */ @@ -37513,6 +37585,7 @@ export interface RotateClientSecretResponseContent { | Management.ClientAnonymousSessionTransferNetworkBindingEnum | undefined; third_party_security_mode?: Management.ClientThirdPartySecurityModeEnum | undefined; + oidc_support?: Management.ClientOidcSupport | undefined; redirection_policy?: Management.ClientRedirectionPolicyEnum | undefined; /** The identifier of the resource server that this client is linked to. */ resource_server_identifier?: string | undefined; @@ -37874,6 +37947,7 @@ export interface SegmentStartsWithExpression { starts_with: string[]; } +/** Filter by status. Exact match. */ export const SegmentStatusEnum = { Active: "active", Archived: "archived", @@ -38811,7 +38885,7 @@ export interface TenantSettingsFlags { revoke_refresh_token_grant?: boolean | undefined; /** Enables beta access to log streaming changes */ dashboard_log_streams_next?: boolean | undefined; - /** Enables new insights activity page view */ + /** Deprecated. This flag has no effect and is retained only for backward compatibility */ dashboard_insights_view?: boolean | undefined; /** Disables SAML fields map fix for bad mappings with repeated attributes */ disable_fields_map_fix?: boolean | undefined; @@ -39340,9 +39414,9 @@ export interface UpdateBruteForceSettingsResponseContent { /** List of trusted IP addresses that will not have attack protection enforced against them. */ allowlist?: string[] | undefined; mode?: Management.BruteForceProtectionModeEnum | undefined; + form_submission_mode?: Management.BruteForceProtectionFormSubmissionModeEnum | undefined; /** Maximum number of unsuccessful attempts. */ max_attempts?: number | undefined; - form_submission_mode?: Management.BruteForceProtectionFormSubmissionModeEnum | undefined; } export interface UpdateClientGrantResponseContent { @@ -39469,6 +39543,7 @@ export interface UpdateClientResponseContent { | Management.ClientAnonymousSessionTransferNetworkBindingEnum | undefined; third_party_security_mode?: Management.ClientThirdPartySecurityModeEnum | undefined; + oidc_support?: Management.ClientOidcSupport | undefined; redirection_policy?: Management.ClientRedirectionPolicyEnum | undefined; /** The identifier of the resource server that this client is linked to. */ resource_server_identifier?: string | undefined; @@ -39505,6 +39580,7 @@ export interface UpdateConnectionOptions { /** Stores encrypted string only configurations for connections */ configuration?: (Record | null) | undefined; customScripts?: Management.ConnectionCustomScripts | undefined; + otp_settings?: Management.ConnectionOtpSettings | undefined; authentication_methods?: (Management.ConnectionAuthenticationMethods | null) | undefined; passkey_options?: (Management.ConnectionPasskeyOptions | null) | undefined; passwordPolicy?: (Management.ConnectionPasswordPolicyEnum | null) | undefined; @@ -39837,6 +39913,7 @@ export interface UpdateConnectionRequestContentPlanningCenter extends Management */ export interface UpdateConnectionRequestContentSaml extends Management.ConnectionCommon { options?: Management.ConnectionOptionsSaml | undefined; + cross_app_access_requesting_app?: Management.CrossAppAccessRequestingApp | undefined; cross_app_access_resource_app?: (Management.ConnectionCrossAppAccessResourceApp | null) | undefined; show_as_button?: Management.ConnectionShowAsButton | undefined; } @@ -40470,6 +40547,7 @@ export interface UpdateResourceServerResponseContent { authorization_policy?: (Management.ResourceServerAuthorizationPolicy | null) | undefined; /** The client ID of the client that this resource server is linked to */ client_id?: string | undefined; + type?: (Management.ResourceServerTypeEnum | null) | undefined; } export interface UpdateRiskAssessmentsSettingsNewDeviceResponseContent { diff --git a/src/management/tests/unit/stream/Stream.test.ts b/src/management/tests/unit/stream/Stream.test.ts index be92ae5906..670b6f192c 100644 --- a/src/management/tests/unit/stream/Stream.test.ts +++ b/src/management/tests/unit/stream/Stream.test.ts @@ -1544,7 +1544,7 @@ describe("Stream", () => { describe("SSE stream reconnection - null reconnect body", () => { it("should treat null reconnect body as a failed attempt", async () => { let reconnectCallCount = 0; - const reconnect = async (_lastEventId: string): Promise => { + const reconnect = async (_lastEventId: string) => { reconnectCallCount++; // @ts-expect-error Intentionally returning null to test null-body handling return null; diff --git a/src/management/tests/wire/attackProtection/bruteForceProtection.test.ts b/src/management/tests/wire/attackProtection/bruteForceProtection.test.ts index 70c73aca36..7375a872ba 100644 --- a/src/management/tests/wire/attackProtection/bruteForceProtection.test.ts +++ b/src/management/tests/wire/attackProtection/bruteForceProtection.test.ts @@ -14,8 +14,8 @@ describe("BruteForceProtectionClient", () => { shields: ["block"], allowlist: ["allowlist"], mode: "count_per_identifier_and_ip", - max_attempts: 1, form_submission_mode: "auto", + max_attempts: 1, }; server @@ -96,8 +96,8 @@ describe("BruteForceProtectionClient", () => { shields: ["block"], allowlist: ["allowlist"], mode: "count_per_identifier_and_ip", - max_attempts: 1, form_submission_mode: "auto", + max_attempts: 1, }; server diff --git a/src/management/tests/wire/clients.test.ts b/src/management/tests/wire/clients.test.ts index 1e61e35a83..d1250c2ad0 100644 --- a/src/management/tests/wire/clients.test.ts +++ b/src/management/tests/wire/clients.test.ts @@ -385,6 +385,7 @@ describe("ClientsClient", () => { anonymous_sessions: { active: true }, enforce_anon_session_transfer_network_binding: "ip", third_party_security_mode: "strict", + oidc_support: { is_allowed: true, allow_all_scopes: true, allowed_scopes: ["profile"] }, redirection_policy: "allow_always", resource_server_identifier: "resource_server_identifier", async_approval_notification_channels: ["guardian-push"], @@ -1274,6 +1275,7 @@ describe("ClientsClient", () => { anonymous_sessions: { active: true }, enforce_anon_session_transfer_network_binding: "ip", third_party_security_mode: "strict", + oidc_support: { is_allowed: true, allow_all_scopes: true, allowed_scopes: ["profile"] }, redirection_policy: "allow_always", resource_server_identifier: "resource_server_identifier", async_approval_notification_channels: ["guardian-push"], @@ -1637,6 +1639,7 @@ describe("ClientsClient", () => { anonymous_sessions: { active: true }, enforce_anon_session_transfer_network_binding: "ip", third_party_security_mode: "strict", + oidc_support: { is_allowed: true, allow_all_scopes: true, allowed_scopes: ["profile"] }, redirection_policy: "allow_always", resource_server_identifier: "resource_server_identifier", async_approval_notification_channels: ["guardian-push"], @@ -1977,6 +1980,7 @@ describe("ClientsClient", () => { anonymous_sessions: { active: true }, enforce_anon_session_transfer_network_binding: "ip", third_party_security_mode: "strict", + oidc_support: { is_allowed: true, allow_all_scopes: true, allowed_scopes: ["profile"] }, redirection_policy: "allow_always", resource_server_identifier: "resource_server_identifier", async_approval_notification_channels: ["guardian-push"], diff --git a/src/management/tests/wire/experimentation/segments.test.ts b/src/management/tests/wire/experimentation/segments.test.ts index 5648e6cf7c..514a7f1864 100644 --- a/src/management/tests/wire/experimentation/segments.test.ts +++ b/src/management/tests/wire/experimentation/segments.test.ts @@ -38,6 +38,7 @@ describe("SegmentsClient", () => { from: "from", take: 1, type: "auth0", + status: "active", }); expect(expected.segments).toEqual(page.data); diff --git a/src/management/tests/wire/resourceServers.test.ts b/src/management/tests/wire/resourceServers.test.ts index ae93ec2113..cca902ed73 100644 --- a/src/management/tests/wire/resourceServers.test.ts +++ b/src/management/tests/wire/resourceServers.test.ts @@ -40,6 +40,7 @@ describe("ResourceServersClient", () => { proof_of_possession: { mechanism: "mtls", required: true }, authorization_policy: { policy_id: "policy_id" }, client_id: "client_id", + type: "universal_commerce_protocol_server", }, ], }; @@ -156,6 +157,7 @@ describe("ResourceServersClient", () => { }, authorization_policy: { policy_id: "policy_id" }, client_id: "client_id", + type: "universal_commerce_protocol_server", }; server @@ -314,6 +316,7 @@ describe("ResourceServersClient", () => { proof_of_possession: { mechanism: "mtls", required: true }, authorization_policy: { policy_id: "policy_id" }, client_id: "client_id", + type: "universal_commerce_protocol_server", }, ], next: "next", @@ -514,6 +517,7 @@ describe("ResourceServersClient", () => { }, authorization_policy: { policy_id: "policy_id" }, client_id: "client_id", + type: "universal_commerce_protocol_server", }; server @@ -748,6 +752,7 @@ describe("ResourceServersClient", () => { }, authorization_policy: { policy_id: "policy_id" }, client_id: "client_id", + type: "universal_commerce_protocol_server", }; server diff --git a/src/management/tests/wire/users.test.ts b/src/management/tests/wire/users.test.ts index 9e8329342c..d9b6f962a3 100644 --- a/src/management/tests/wire/users.test.ts +++ b/src/management/tests/wire/users.test.ts @@ -732,6 +732,311 @@ describe("UsersClient", () => { }).rejects.toThrow(Management.TooManyRequestsError); }); + test("listConsentSigningKeys (1)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + kid: "kid", + device_identifier: "device_identifier", + created_at: "2024-01-15T09:30:00Z", + expires_at: "2024-01-15T09:30:00Z", + }, + ]; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.users.listConsentSigningKeys("id"); + expect(response).toEqual(rawResponseBody); + }); + + test("listConsentSigningKeys (2)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.listConsentSigningKeys("id"); + }).rejects.toThrow(Management.BadRequestError); + }); + + test("listConsentSigningKeys (3)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys") + .respondWith() + .statusCode(401) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.listConsentSigningKeys("id"); + }).rejects.toThrow(Management.UnauthorizedError); + }); + + test("listConsentSigningKeys (4)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.listConsentSigningKeys("id"); + }).rejects.toThrow(Management.ForbiddenError); + }); + + test("listConsentSigningKeys (5)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys") + .respondWith() + .statusCode(429) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.listConsentSigningKeys("id"); + }).rejects.toThrow(Management.TooManyRequestsError); + }); + + test("getConsentSigningKey (1)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + kid: "kid", + device_identifier: "device_identifier", + created_at: "2024-01-15T09:30:00Z", + expires_at: "2024-01-15T09:30:00Z", + }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.users.getConsentSigningKey("id", "kid"); + expect(response).toEqual(rawResponseBody); + }); + + test("getConsentSigningKey (2)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.getConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.BadRequestError); + }); + + test("getConsentSigningKey (3)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(401) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.getConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.UnauthorizedError); + }); + + test("getConsentSigningKey (4)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.getConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.ForbiddenError); + }); + + test("getConsentSigningKey (5)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.getConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.NotFoundError); + }); + + test("getConsentSigningKey (6)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(429) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.getConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.TooManyRequestsError); + }); + + test("deleteConsentSigningKey (1)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + server.mockEndpoint().delete("/users/id/consent-signing-keys/kid").respondWith().statusCode(200).build(); + + const response = await client.users.deleteConsentSigningKey("id", "kid"); + expect(response).toEqual(undefined); + }); + + test("deleteConsentSigningKey (2)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.deleteConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.BadRequestError); + }); + + test("deleteConsentSigningKey (3)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(401) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.deleteConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.UnauthorizedError); + }); + + test("deleteConsentSigningKey (4)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.deleteConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.ForbiddenError); + }); + + test("deleteConsentSigningKey (5)", async () => { + const server = mockServerPool.createServer(); + const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/users/id/consent-signing-keys/kid") + .respondWith() + .statusCode(429) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.users.deleteConsentSigningKey("id", "kid"); + }).rejects.toThrow(Management.TooManyRequestsError); + }); + test("regenerateRecoveryCode (1)", async () => { const server = mockServerPool.createServer(); const client = new ManagementClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); diff --git a/src/management/version.ts b/src/management/version.ts index c012080661..67057a4309 100644 --- a/src/management/version.ts +++ b/src/management/version.ts @@ -1 +1 @@ -export const SDK_VERSION = "7.6.0"; +export const SDK_VERSION = "7.6.1"; diff --git a/v6_MIGRATION_GUIDE.md b/v6_MIGRATION_GUIDE.md deleted file mode 100644 index d1eb6bd699..0000000000 --- a/v6_MIGRATION_GUIDE.md +++ /dev/null @@ -1,158 +0,0 @@ -# V6 Migration Guide - -A guide to migrating the Auth0 Node.js SDK from `5.x` to `6.x`. - -- [Overall changes](#overall-changes) -- [Breaking changes](#breaking-changes) - - [ConnectionAttributeIdentifier replaced with identifier-specific types](#connectionattributeidentifier-replaced-with-identifier-specific-types) - - [PhoneProviderProtectionBackoffStrategyEnum value change](#phoneproviderprotectionbackoffstrategyenum-value-change) - - [users.federatedConnectionsTokensets removed](#usersfederatedconnectionstokensets-removed) - - [federated_connections_access_tokens removed from connection options](#federated_connections_access_tokens-removed-from-connection-options) - -## Overall changes - -V6 addresses type correctness for database connection attribute identifiers, aligns the phone provider backoff strategy enum with the updated API, and removes the federated connections tokensets user sub-client. There are no changes to the Authentication API — any code written for the Authentication API in `5.x` will continue to work in `6.x`. - -## Breaking changes - -### ConnectionAttributeIdentifier replaced with identifier-specific types - -In v5, all three attribute identifiers (email, phone number, and username) shared a single `ConnectionAttributeIdentifier` type for their `identifier` field. This was incorrect — each identifier type supports different values for `default_method`. - -In v6, `ConnectionAttributeIdentifier` has been removed and replaced with three separate types: - -| Attribute | Old type | New type | `default_method` values | -| -------------- | ------------------------------- | ----------------------------- | ----------------------------- | -| `email` | `ConnectionAttributeIdentifier` | `EmailAttributeIdentifier` | `"password"` \| `"email_otp"` | -| `phone_number` | `ConnectionAttributeIdentifier` | `PhoneAttributeIdentifier` | `"password"` \| `"phone_otp"` | -| `username` | `ConnectionAttributeIdentifier` | `UsernameAttributeIdentifier` | _(no `default_method`)_ | - -**Before (v5):** - -```ts -import { Management } from "auth0"; - -const identifier: Management.ConnectionAttributeIdentifier = { - active: true, - default_method: "email_otp", -}; -``` - -**After (v6):** - -```ts -import { Management } from "auth0"; - -// For email attribute -const emailIdentifier: Management.EmailAttributeIdentifier = { - active: true, - default_method: "email_otp", -}; - -// For phone_number attribute -const phoneIdentifier: Management.PhoneAttributeIdentifier = { - active: true, - default_method: "phone_otp", -}; - -// For username attribute (no default_method) -const usernameIdentifier: Management.UsernameAttributeIdentifier = { - active: true, -}; -``` - -If you were using `ConnectionAttributeIdentifier` as a type annotation in your own code, update it to the appropriate identifier-specific type based on which attribute it applies to. - ---- - -### PhoneProviderProtectionBackoffStrategyEnum value change - -The `PhoneProviderProtectionBackoffStrategyEnum` enum has been updated to reflect a change in the Auth0 API. The `None` variant has been renamed to `Default`, and its string value has changed from `"none"` to `"default"`. - -**Before (v5):** - -```ts -import { Management } from "auth0"; - -const strategy = Management.PhoneProviderProtectionBackoffStrategyEnum.None; // "none" -``` - -**After (v6):** - -```ts -import { Management } from "auth0"; - -const strategy = Management.PhoneProviderProtectionBackoffStrategyEnum.Default; // "default" -``` - -If you were passing this value directly as a string `"none"`, update it to `"default"` to match the updated API. - ---- - -### users.federatedConnectionsTokensets removed - -The `client.users.federatedConnectionsTokensets` sub-client has been removed. This includes the `list()` and `delete()` methods. - -**Before (v5):** - -```ts -// List active federated connection tokensets for a user -const tokensets = await client.users.federatedConnectionsTokensets.list("user_id"); - -// Delete a tokenset -await client.users.federatedConnectionsTokensets.delete("user_id", "tokenset_id"); -``` - -**After (v6):** - -These methods are no longer available. Remove any calls to `client.users.federatedConnectionsTokensets` from your code. - ---- - -### federated_connections_access_tokens removed from connection options - -The `federated_connections_access_tokens` field has been removed from all connection option types, including create and update. This affects OIDC, Azure AD, Google Apps, and other connection strategies. Remove it from any create or update payloads. - -**Before (v5):** - -```ts -// On create -await client.connections.create({ - strategy: "oidc", - name: "my-connection", - options: { - federated_connections_access_tokens: { ... }, - // other options - }, -}); - -// On update -await client.connections.update("connection_id", { - options: { - federated_connections_access_tokens: { ... }, - // other options - }, -}); -``` - -**After (v6):** - -```ts -// On create -await client.connections.create({ - strategy: "oidc", - name: "my-connection", - options: { - // remove federated_connections_access_tokens - // other options - }, -}); - -// On update -await client.connections.update("connection_id", { - options: { - // remove federated_connections_access_tokens - // other options - }, -}); -``` diff --git a/v7_MIGRATION_GUIDE.md b/v7_MIGRATION_GUIDE.md deleted file mode 100644 index d1dba04a5c..0000000000 --- a/v7_MIGRATION_GUIDE.md +++ /dev/null @@ -1,146 +0,0 @@ -# V7 Migration Guide - -A guide to migrating the Auth0 Node.js SDK from `6.x` to `7.x`. - -> **Migrating with an AI agent?** Point it at the Auth0 migration skill first. The skill lives in [`auth0/agent-skills`](https://github.com/auth0/agent-skills) as the `auth0` skill (migration intent: `migrate-node-auth0`). It encodes the authentication-layer rewrite rules and a verify loop. - -- [Overall changes](#overall-changes) -- [Breaking changes](#breaking-changes) - - [Authentication API removed from the main entrypoint](#authentication-api-removed-from-the-main-entrypoint) - - [Removed exports](#removed-exports) - - [ManagementClient mTLS requires an explicit `fetch`](#managementclient-mtls-requires-an-explicit-fetch) - - [mTLS works with both client secret and client assertion](#mtls-works-with-both-client-secret-and-client-assertion) - - [`domain` must be a bare hostname](#domain-must-be-a-bare-hostname) - - [Token acquisition failures throw `ManagementError`](#token-acquisition-failures-throw-managementerror) - - [`uuid` dependency removed](#uuid-dependency-removed) -- [Migrating authentication code](#migrating-authentication-code) -- [Staying on the legacy entrypoint](#staying-on-the-legacy-entrypoint) - -## Overall changes - -V7 makes `node-auth0` a **Management-API-only SDK**. The Authentication API layer (`AuthenticationClient`, its sub-clients, and `UserInfoClient`) has been removed from the main entrypoint. `ManagementClient` continues to work exactly as before; it now acquires its internal token directly via the client credentials grant rather than through the removed authentication layer. - -If your code only uses `ManagementClient`, the upgrade is small: address the Management-side breaking changes below (mTLS, domain validation, error type) and you are done. If your code uses `AuthenticationClient` or `UserInfoClient`, that code must move to a dedicated package; see [Migrating authentication code](#migrating-authentication-code). - -## Breaking changes - -### Authentication API removed from the main entrypoint - -`AuthenticationClient` and `UserInfoClient` are no longer exported from the `auth0` main entrypoint. The stateless authentication layer now lives in [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js), and the server-managed session layer lives in [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js). - -**Before (v6):** - -```ts -import { AuthenticationClient, UserInfoClient } from "auth0"; - -const auth = new AuthenticationClient({ domain, clientId, clientSecret }); -const tokens = await auth.oauth.clientCredentialsGrant({ audience }); -``` - -**After (v7):** - -```ts -import { AuthClient } from "@auth0/auth0-auth-js"; - -const auth = new AuthClient({ domain, clientId, clientSecret }); -const tokens = await auth.getTokenByClientCredentials({ audience }); -``` - -The complete method-by-method mapping, the four cross-cutting behavior changes (return shape, casing, token expiry, error model), and the session-app wiring are documented in the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). This guide does not repeat that detail. - -If you need the old clients unchanged as a stopgap, they still ship from the [legacy entrypoint](#staying-on-the-legacy-entrypoint). - -### Removed exports - -The following symbols were exported from the main entrypoint in v6 and are removed in v7. Each moves to `@auth0/auth0-auth-js`, or remains available from the `auth0/legacy` entrypoint at its v4.x shape. - -| Removed export (v6) | Replacement in v7 | -| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | -| `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | -| `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | -| `AuthenticationClientOptions` | `AuthClientOptions` from `@auth0/auth0-auth-js` | -| `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | -| `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | -| `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | -| `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | -| `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | -| `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | -| `ResponseError` | Management API calls throw `ManagementError` | -| `FetchError` | Management API calls throw `ManagementError` | -| `JSONApiResponse` | Responses return the data directly (no wrapper) | - -`ManagementClient`, the `Management` namespace, and `ManagementError` are unchanged and still exported. - -### ManagementClient mTLS requires an explicit `fetch` - -A `ManagementClient` constructed with `useMTLS: true` must now supply an explicit `fetch` option carrying the client certificate. The client throws at construction if `useMTLS` is set without a `fetch`. Previously a missing fetch surfaced as silent `401`s at request time; failing at construction makes the misconfiguration obvious. - -The token endpoint automatically uses the `mtls.{domain}` host when `useMTLS` is enabled. - -```ts -// v7: throws at construction if `fetch` is omitted -const mgmt = new ManagementClient({ - domain, - clientId, - clientSecret, - useMTLS: true, - fetch: mtlsCapableFetch, // now required -}); -``` - -### mTLS works with both client secret and client assertion - -`useMTLS` works with both `clientSecret` and `clientAssertionSigningKey`. mTLS (RFC 8705) is a transport-layer concern: the TLS client certificate yields a certificate-bound token regardless of which client authentication method is used. An explicit `fetch` option is always required when `useMTLS` is set. - -### `domain` must be a bare hostname - -`domain` must be a bare host such as `tenant.us.auth0.com`. A value that is empty, or that contains a scheme, a path, a query string, a fragment, credentials (`@`), or whitespace, now throws at construction instead of producing malformed request URLs later. The check applies to every authentication mode (`token`, `clientSecret`, and `clientAssertionSigningKey`), and to `createManagementAuth` and `TokenProvider` as well as `ManagementClient`. - -```ts -// throws in v7 -new ManagementClient({ domain: "https://tenant.us.auth0.com/", ... }); -// correct -new ManagementClient({ domain: "tenant.us.auth0.com", ... }); -``` - -### Token acquisition failures throw `ManagementError` - -When the internal client-credentials token request fails, the client now throws a `ManagementError` (previously a plain `Error`). The error carries `statusCode` and a parsed `body` with the OAuth error details. A request that exceeds the 10-second timeout throws `ManagementError` with status `408`. - -```ts -import { ManagementError } from "auth0"; - -try { - await mgmt.users.getAll(); -} catch (e) { - if (e instanceof ManagementError) { - console.error(e.statusCode, e.body); - } -} -``` - -### `uuid` dependency removed - -The `uuid` package is no longer a dependency. If your project imported `uuid` transitively through `auth0`, add it to your own `dependencies`. - -## Migrating authentication code - -If your app calls `AuthenticationClient` or `UserInfoClient`, follow the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). Start with [`auth-migration/index.md`](https://github.com/auth0/node-auth0/blob/master/auth-migration/index.md) for the OIDC token grants section; the incremental flow, session, and troubleshooting pages live in the same [`auth-migration/`](https://github.com/auth0/node-auth0/tree/master/auth-migration) directory. It covers: - -- Choosing between `@auth0/auth0-auth-js` (stateless token grants) and `@auth0/auth0-server-js` (server-managed sessions). -- The complete method-by-method API mapping for `.oauth`, `.database`, `.passwordless`, `.backchannel`, `.tokenExchange`, and `UserInfoClient`. -- The four cross-cutting behavior changes: return shape (envelope dropped), casing (snake_case → camelCase), token expiry (`expires_in` relative → `expiresAt` absolute, a silent high-risk change), and the typed error model with `isMfaRequiredError()`. -- Wiring the `auth0-server-js` session lifecycle when you want the SDK to own login, cookies, refresh, and logout. - -The Management API is explicitly out of scope in that guide: a file that keeps using `ManagementClient` from `auth0` while importing `@auth0/auth0-auth-js` for authentication is correct and expected. - -## Staying on the legacy entrypoint - -If you cannot migrate the authentication code immediately, the `auth0/legacy` entrypoint still ships `AuthenticationClient` and `UserInfoClient` at their v4.x configuration format and method signatures. This is a stopgap, not a destination; the legacy shapes differ from the current API and will not receive new features. - -```ts -import { AuthenticationClient } from "auth0/legacy"; -``` - -Plan the move to `@auth0/auth0-auth-js` / `@auth0/auth0-server-js` rather than treating the legacy entrypoint as permanent. diff --git a/yarn.lock b/yarn.lock index 91c7ee2157..fe497711fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -86,10 +86,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz#c0a0766f1a13617d8a17407d7ab8f9d486225ea4" integrity sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw== -"@babel/helper-string-parser@^7.29.7": - version "7.29.7" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz#7f0871d99824d23137d60f86fcf6130fd5a1b51f" - integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw== +"@babel/helper-string-parser@^7.29.11": + version "7.29.11" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.11.tgz#59d76b6193f61e0303b40991cabbedfadcbd5b63" + integrity sha512-snZbO7MEDOof+hvNa97EjEY7qD7h2kwvQr5AJC3ZhQudKW5dnej6k3kP9NQV88hJwaS8vDqRLFo9rivLEhle2g== "@babel/helper-validator-identifier@^7.29.7": version "7.29.7" @@ -110,11 +110,11 @@ "@babel/types" "^7.29.8" "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.29.7", "@babel/parser@^7.29.8", "@babel/parser@^7.29.9": - version "7.29.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.9.tgz#e7ee0a24f752c5296c6455855ccb72662e67ea96" - integrity sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA== + version "7.29.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.11.tgz#afa959e9d16c40d4d95012553cab363fc86cbcb7" + integrity sha512-OZ6+oaK7GMyg3IfCpj8JOmn8n+w2rJbDT0LLfVDTLb1ZFeKDh3AiNELgCMUw175IJHSkLl74hG0M0VLsvx+gag== dependencies: - "@babel/types" "^7.29.8" + "@babel/types" "^7.29.11" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -257,12 +257,12 @@ "@babel/types" "^7.29.8" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.29.7", "@babel/types@^7.29.8", "@babel/types@^7.3.3": - version "7.29.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.8.tgz#1229eef31d85156d70fa3f4cd859376d0eaf6863" - integrity sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.29.11", "@babel/types@^7.29.7", "@babel/types@^7.29.8", "@babel/types@^7.3.3": + version "7.29.11" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.11.tgz#774cffe8cac2ca494f1334e4052002c96bf628fc" + integrity sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ== dependencies: - "@babel/helper-string-parser" "^7.29.7" + "@babel/helper-string-parser" "^7.29.11" "@babel/helper-validator-identifier" "^7.29.7" "@bcoe/v8-coverage@^0.2.3": @@ -771,9 +771,9 @@ "@types/hast" "^3.0.4" "@shikijs/vscode-textmate@^10.0.2": - version "10.0.2" - resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224" - integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg== + version "10.1.0" + resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.1.0.tgz#de59840c1d9903b5f5732dbc7852437003d35f11" + integrity sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ== "@sinclair/typebox@^0.27.8": version "0.27.12" @@ -944,99 +944,99 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^8.38.0": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.2.tgz#fdaac18e9fe84b78652ae4befd2693bdd815fe04" - integrity sha512-K72/pvT7qpm8q3k8G5u93NCSN1RcLxX5h7Gw0bQpbMXviBHeY6Nx1WEwmk9wP+eKTSQ8ecxvcgt/ZX/rB938xQ== + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.1.tgz#95e29de63ce7ed793eb1c6efd9f8b802ce808262" + integrity sha512-5CokTWXpmbylfFabsbvHC0CAw3XLaGnoa+nFJX5FR592h/LoZsENUE6p/rg5xvkKrFEXz6pYmgI29AgXc2N3BQ== dependencies: "@eslint-community/regexpp" "^4.12.2" - "@typescript-eslint/scope-manager" "8.71.2" - "@typescript-eslint/type-utils" "8.71.2" - "@typescript-eslint/utils" "8.71.2" - "@typescript-eslint/visitor-keys" "8.71.2" + "@typescript-eslint/scope-manager" "8.72.1" + "@typescript-eslint/type-utils" "8.72.1" + "@typescript-eslint/utils" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" ignore "^7.0.5" natural-compare "^1.4.0" ts-api-utils "^2.5.0" "@typescript-eslint/parser@^8.38.0": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.71.2.tgz#f12dc1d3b26432144319d384273b9c4b6f5c1e99" - integrity sha512-aTtmZjp/x3gsGHkDs04/1I8kNogBJkpQaeGaN0PfiG43NzDEmW2n+OP5im9wfsvyX0yP1UZWBrAGtDBfH9jEVw== - dependencies: - "@typescript-eslint/scope-manager" "8.71.2" - "@typescript-eslint/types" "8.71.2" - "@typescript-eslint/typescript-estree" "8.71.2" - "@typescript-eslint/visitor-keys" "8.71.2" + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.72.1.tgz#7370b68dadc3819b9aac68ea340bd8b43ee62379" + integrity sha512-ZGwZP4OCfyA0AQTpEAMWz+rtX01DRhQWW5hB0ucKDEIX5U7jdmPSaMx94rQfaPAQzIYz2BimOgKOJtjfpRFQ9g== + dependencies: + "@typescript-eslint/scope-manager" "8.72.1" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" debug "^4.4.3" -"@typescript-eslint/project-service@8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.71.2.tgz#b0f89f4eec94bbdde598b8d27a446553172ada84" - integrity sha512-Pd68GsLVh5ZXlcEccFPdhSOvtHZ/2WU0XsA8zmXOS3F158lVlcTLhfQ6qvtL1RzbMie0Kp8xtbVwAg4nejKPHw== +"@typescript-eslint/project-service@8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.72.1.tgz#1d09902a9c23f6cfab779e5acc78a45abf540add" + integrity sha512-fAuVMkwdO/huI8nyo/WKnNKf6Gag93S56Rh3Ts5mGcavwSdaN8tRg1gCeIGX8PF+nzp1BjGfO4gHhGzW1J6jTg== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.71.2" - "@typescript-eslint/types" "^8.71.2" + "@typescript-eslint/tsconfig-utils" "^8.72.1" + "@typescript-eslint/types" "^8.72.1" debug "^4.4.3" -"@typescript-eslint/scope-manager@8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.71.2.tgz#ddb35569150c9aab76d1324d7f6c1a1b68ac60d9" - integrity sha512-YF4wgg5iUX5Obywoac27B56FhozMNFhdJSbh11H5GBAwmBtfyRhmgTQqW9tRNNmHDvsZ2CX6UGzoz+YfYn2Leg== +"@typescript-eslint/scope-manager@8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.72.1.tgz#a0fb4dfe5aa2b0149b7a2d1fd00d947992b13067" + integrity sha512-lC/t6eMCZZQAAKZEYGL6RDVSuFehpdmMT6h+nJIjIa6oylN/PwDgDVtEIbB7O9xFfZYtZAYLoLlDNWKJhtF+uQ== dependencies: - "@typescript-eslint/types" "8.71.2" - "@typescript-eslint/visitor-keys" "8.71.2" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" -"@typescript-eslint/tsconfig-utils@8.71.2", "@typescript-eslint/tsconfig-utils@^8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.2.tgz#0f12d2abbc8aca1a7cf2d0898a7c81b950622f61" - integrity sha512-jz49TAWokm/7yWD9/o837nYax9DyALxIPOImdImvVzo6canBCZYzin8zJyqNR5k1j9K1DE0bVvr0XYB+99uAdg== +"@typescript-eslint/tsconfig-utils@8.72.1", "@typescript-eslint/tsconfig-utils@^8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.1.tgz#07394c85095ee38455e76bc221ba23650af73e44" + integrity sha512-e4D5R5vpeAEPBxT2BAzsFQL3sbwyeeeo5+aczgNSRK1V734jE7pTqaGFU+fXapWEQwnZbpFaTn32+Z8DwS6OTg== -"@typescript-eslint/type-utils@8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.71.2.tgz#b7a615036ed59898ed1628ed74fe0b129ba0032f" - integrity sha512-cC8UaalCViJkb3rH/xLIvidEwoFRtMZMUqDjjJMGEKaTFwYRHYBcoczlEGHuvkHEO8svRDrgZ0yQgOArFmwang== +"@typescript-eslint/type-utils@8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.72.1.tgz#f1f592f63bd9726de21191aae3ccf64a813914b8" + integrity sha512-iY2wlmyrXJmx4yxUGP3aYCFF3cA/6ShddOKmLU2dx7LnEykbAM8WThlxZEfd1NddqceF6eJmZUayxx9oKIYNlg== dependencies: - "@typescript-eslint/types" "8.71.2" - "@typescript-eslint/typescript-estree" "8.71.2" - "@typescript-eslint/utils" "8.71.2" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" + "@typescript-eslint/utils" "8.72.1" debug "^4.4.3" ts-api-utils "^2.5.0" -"@typescript-eslint/types@8.71.2", "@typescript-eslint/types@^8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.71.2.tgz#c2629dcd4056c71b02cf172d109a59a757c2cce9" - integrity sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw== +"@typescript-eslint/types@8.72.1", "@typescript-eslint/types@^8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.72.1.tgz#067d8f738c294611e33a1425ae43ac9b9c2f24e3" + integrity sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw== -"@typescript-eslint/typescript-estree@8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.2.tgz#7ef01d376f6c1da20e173c3483f446127c88c24a" - integrity sha512-DgNOEsl4pdYzwSL+N/Cl33tX1Hlw3FvId73LnKXfq7jnrF2viOEn7X+P7RBkkSWCVm92gnWd28GIC5vJuLREeA== +"@typescript-eslint/typescript-estree@8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.1.tgz#e93b9cc3a56bf12f5fed857bb8f4963cce7924ee" + integrity sha512-DAlUoUV93hIvrtIQLwCbmZQYVZwOMhiHJrOVUUIWicFZaIYjTRqlY3I/NZevfkLmSqkNHRu2qYDcq9lrn16oOQ== dependencies: - "@typescript-eslint/project-service" "8.71.2" - "@typescript-eslint/tsconfig-utils" "8.71.2" - "@typescript-eslint/types" "8.71.2" - "@typescript-eslint/visitor-keys" "8.71.2" + "@typescript-eslint/project-service" "8.72.1" + "@typescript-eslint/tsconfig-utils" "8.72.1" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" debug "^4.4.3" minimatch "^10.2.2" semver "^7.7.3" tinyglobby "^0.2.15" ts-api-utils "^2.5.0" -"@typescript-eslint/utils@8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.71.2.tgz#7c01b239b7cea1310f1793bbb5a02b5f8b74a6b9" - integrity sha512-RyKa1G1M9rKHDhrk+HJtiF1MvLD5Ux2JW3TSkzw+02pRALdpJb+QzG1Y5em+LvCgzGwgg8H7mBRFKljNz7ImPw== +"@typescript-eslint/utils@8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.72.1.tgz#f210c1bf4a25aa1306df80c702ed30bbbc9b4d3d" + integrity sha512-5v5liypurJBFHCBNqh/RjsymAD+VWcE0djuGY/BUqp5fC3Qn+luWDEksjuTtWjPn6i5zQlUtkZCRG/CYG0yCkA== dependencies: "@eslint-community/eslint-utils" "^4.9.1" - "@typescript-eslint/scope-manager" "8.71.2" - "@typescript-eslint/types" "8.71.2" - "@typescript-eslint/typescript-estree" "8.71.2" + "@typescript-eslint/scope-manager" "8.72.1" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" -"@typescript-eslint/visitor-keys@8.71.2": - version "8.71.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.2.tgz#3a71f8e833aa812670a31107236b9077f4e08fe0" - integrity sha512-zozlN0UA32bSG2zkKAgQyRYSbEISVoyU6vvkKYo2aSny74D8Jh4e+POkJ6Lk0dlezZi5x7TtD+88Xb06IB8nhg== +"@typescript-eslint/visitor-keys@8.72.1": + version "8.72.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.1.tgz#c7aec9883b44ef795f1b8200df81d9d44d355de7" + integrity sha512-SB8xqipSzZHUePCCLNeYxqnxq83X61/qzNhjQGbTfjxGZIeOEP7tBgWYX05Tcd6CgE02WdTJnh5b8kMZJ/+bnQ== dependencies: - "@typescript-eslint/types" "8.71.2" + "@typescript-eslint/types" "8.72.1" eslint-visitor-keys "^5.0.0" "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": @@ -1389,10 +1389,10 @@ balanced-match@^4.0.2: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== -baseline-browser-mapping@^2.11.26: - version "2.11.29" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.29.tgz#dbed0ed2c17943aa4427863c91300865d9d8ca23" - integrity sha512-YeesxhUmR4h5y5V8KF8iBCqJb8YFrBJ++XBTeGcWIaQOYXGN19JM0FoiOjAhwuDoln8owMgXcWBmgHtYSkky2w== +baseline-browser-mapping@^2.11.33: + version "2.11.34" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.34.tgz#d97a3dc0edb2f139758f7f2b1ae89552f391b35f" + integrity sha512-Aqr8mA1kIvyJ3UY5YAY7ib8LSo1DmDMbMnVqGPtsKW1LxaFQFwn9Eb3yvq2fUKJsRvaXjnAV7R5osqETapzNiA== brace-expansion@^1.1.7: version "1.1.21" @@ -1417,15 +1417,15 @@ braces@^3.0.3: fill-range "^7.1.1" browserslist@^4.24.0, browserslist@^4.28.1: - version "4.29.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.29.3.tgz#9c8dafe96ab1c8e40e21c1274bdfa05aaee46476" - integrity sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA== + version "4.29.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.29.5.tgz#e835ff9a00f683305b33f02828c908b397410d4a" + integrity sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ== dependencies: - baseline-browser-mapping "^2.11.26" - caniuse-lite "^1.0.30001813" - electron-to-chromium "^1.5.439" - node-releases "^2.0.57" - update-browserslist-db "^1.3.3" + baseline-browser-mapping "^2.11.33" + caniuse-lite "^1.0.30001819" + electron-to-chromium "^1.5.464" + node-releases "^2.0.60" + update-browserslist-db "^1.3.4" bs-logger@^0.2.6: version "0.2.6" @@ -1469,10 +1469,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001813: - version "1.0.30001816" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001816.tgz#80567cffb179fd8a1702816bc80de8efc9784021" - integrity sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw== +caniuse-lite@^1.0.30001819: + version "1.0.30001819" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001819.tgz#4a0f8d7552a15909ce8a0c1dc2ccad9c8c0fab9d" + integrity sha512-LFUqIIAwpzsIuevnKnsR9qnStBcgzPShTX61lBwN9uFkkf8o8zLiebEjbW8AYtZiF+1YKDWfdt/pWDtMuG8Xwg== chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" @@ -1696,10 +1696,10 @@ dunder-proto@^1.0.1: es-errors "^1.3.0" gopd "^1.2.0" -electron-to-chromium@^1.5.439: - version "1.5.458" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.458.tgz#fdc608c8ee26eeb4fa20b3447378c6c83a806a76" - integrity sha512-/hIH2gRSmxrf4/X4Nw/t/Wc8PVS22l8/3HnWjWTWsTOM5dsnMUPZF/+u+yr3LqweNuTBJE1rq6qAQzKkZVwMfA== +electron-to-chromium@^1.5.464: + version "1.5.467" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.467.tgz#7a3db88a95f09304a47ca0d838a1504fa048664a" + integrity sha512-Nw9X371rtZmYcBSnEijnCDONILjs93biCZO34juC7MBOmK8E+GFnyD4T/WvyrlJkppul7oxg6TwvtKst9SODTw== emittery@^0.13.1: version "0.13.1" @@ -1980,9 +1980,9 @@ fast-levenshtein@^2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-uri@^3.0.1: - version "3.1.8" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.8.tgz#f7db8d942e20eead3cfe93b0beeb4eb0169e938b" - integrity sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg== + version "3.1.9" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.9.tgz#f1deba822b1d6ac79da2f860e872a63470cff203" + integrity sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ== fb-watchman@^2.0.0: version "2.0.4" @@ -2246,9 +2246,9 @@ ignore@^5.2.0: integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== ignore@^7.0.5: - version "7.0.12" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.12.tgz#36048ce2e8d8e0f97fd87863a1cb595ea0a5c69f" - integrity sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg== + version "7.0.14" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.14.tgz#a52b081dfb4d77e947e04d5f9e320b16f1873959" + integrity sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ== import-fresh@^3.2.1: version "3.3.1" @@ -3095,13 +3095,13 @@ minimist@^1.2.8: integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minimizer-webpack-plugin@^5.13.0: - version "5.13.0" - resolved "https://registry.yarnpkg.com/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.13.0.tgz#3624cd9556b0645aceed66f5e7466586d0635ebe" - integrity sha512-OO1NF2zHj6sf4CNv2AsUWYcS8WEwkVKQDXxxKzlOxx1Xl+WlqYtVC+oNlGNwGkLAOnpj277BSHypWwRtd9w4JQ== + version "5.13.1" + resolved "https://registry.yarnpkg.com/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.13.1.tgz#664cdfbab756e1b93ae17eb7ff70f1a5620584d7" + integrity sha512-1mhAfvachWYYOm8tpmany5NLuvP+F2wxZWBSX8DC0uFS2wJpM9q3rWgN9wBooAH9d5V12wX0BjyJe4fMjHMarQ== dependencies: "@jridgewell/trace-mapping" "^0.3.31" jest-worker "^27.4.5" - schema-utils "^4.3.3" + schema-utils "^4.6.0" terser "^5.51.0" mri@^1.1.0: @@ -3168,10 +3168,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.57: - version "2.0.59" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.59.tgz#172a7e253e3cca1ae00e8015a82b54e7fcc68fd3" - integrity sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA== +node-releases@^2.0.60: + version "2.0.60" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.60.tgz#e3104c3ceb4530578f546bcfda551a4a2de06939" + integrity sha512-OmO8+GM1JUZqXET720VrJCwkjUCXmCMQm0Z3UDDRbfNLHS4NEAvY60j5jiFv0tkKw2PNNlqOLhahVmwJIOLDIQ== normalize-path@^3.0.0: version "3.0.0" @@ -3507,10 +3507,10 @@ saxes@^6.0.0: dependencies: xmlchars "^2.2.0" -schema-utils@^4.3.3, schema-utils@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.5.0.tgz#aaf8d588bd2b19511175175a5222baef648c009c" - integrity sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA== +schema-utils@^4.6.0, schema-utils@^4.8.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.8.1.tgz#d005632a0ca18522d903d82e1dcccbddcd57e7bb" + integrity sha512-x39pYlJPyH7Uge5QO64B9XGP9zLDc9WNmiQZc+CE3IzZPvMu3lHOuAMGpYNoPixEL7MSWlGhYTg5UlLSL8G6iw== dependencies: "@types/json-schema" "^7.0.15" ajv "^8.20.0" @@ -3760,17 +3760,17 @@ tinyglobby@^0.2.15: fdir "^6.5.0" picomatch "^4.0.4" -tldts-core@^7.4.18: - version "7.4.18" - resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-7.4.18.tgz#d3318300405ff83803c9cd92f81d0fe33f83d696" - integrity sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g== +tldts-core@^7.4.19: + version "7.4.19" + resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-7.4.19.tgz#c8ace80f2c98729f4fd0779fcae0a940cd1f8085" + integrity sha512-goNXV6Ho9TIOfpJZanTd6CKG5DyYgYAL+k+22T0SLh8l6+KHIfBUPFuePuSZv05UttIaaLmI9tb7TmGIdK5AkQ== tldts@^7.0.5: - version "7.4.18" - resolved "https://registry.yarnpkg.com/tldts/-/tldts-7.4.18.tgz#3564dbc59de25c7a2a051f7a4715f6da6ba653d5" - integrity sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg== + version "7.4.19" + resolved "https://registry.yarnpkg.com/tldts/-/tldts-7.4.19.tgz#3c8bd0d5c5476627f7454db13b0548975fe1a9ad" + integrity sha512-48dH6aSpQnpbzDUc4vIQZ1VjB8tkK+e8c1yx05/SZK+rkssgjEOlxDd/yU8/a4vGYQ9vRgJr9dwMq9TJ0b3X2Q== dependencies: - tldts-core "^7.4.18" + tldts-core "^7.4.19" tmpl@1.0.5: version "1.0.5" @@ -3915,7 +3915,7 @@ universalify@^0.2.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== -update-browserslist-db@^1.3.3: +update-browserslist-db@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz#e8bd4596f6900805f9f12c5a5200c83c59c38faf" integrity sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A== @@ -3966,10 +3966,10 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -watchpack@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.6.1.tgz#fda5ef91ab74cdba7e9105e0bd2b03268b6818aa" - integrity sha512-8mk/LnXpQAiM2xKZhTkxikwly5GhL2Z+DWiLTkMa/E1Nfv9zURhHgiFyWvM4BWqW+LjIgL2AIS7JntEUx6v3vQ== +watchpack@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.6.3.tgz#880d8c437c425104b2da58bee6bd8fbc33bf78d3" + integrity sha512-s3NZy0QpTY9qGqzc0wtz4qI28z3+5qKbbAec4MV4G9N3CfgZ9wgvQRr0cl2jh/tqkWG1NWHkmVMHZpCamev5Wg== dependencies: graceful-fs "^4.1.2" @@ -3984,9 +3984,9 @@ webpack-sources@^3.6.0: integrity sha512-EIMmPVvNI0CYXyRPp34F2Qk7W37/BZVZIofS6LAUnrNjCVahS+hO4mxwFJDjQjODTGZDtVzLYoN2+1dYkhk9qA== webpack@^5.105.4: - version "5.112.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.112.0.tgz#e8710dcc0329ef076bd3b5c3bd6cf78e971c009a" - integrity sha512-NIBpsRuCll036haDDt/CfcTDfsWNR9Z782nMRMI9D377BsGcYzZDTNU5TyzhCJzPIcihAxMBaMAhq2WSaDrH8Q== + version "5.112.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.112.2.tgz#6548b28310dc57d971aadb31a582c8aadb9ec880" + integrity sha512-B2tp1LI9D8GVpPDqprdt12ukTkXXahj9MzqSWJq4faSPgOUM7CdZaGAB6HrL/8E6UwbBpdj4vzWDbKoFnVoU6g== dependencies: "@types/estree" "^1.0.8" "@types/json-schema" "^7.0.15" @@ -4001,9 +4001,9 @@ webpack@^5.105.4: graceful-fs "^4.2.11" mime-db "^1.54.0" minimizer-webpack-plugin "^5.13.0" - schema-utils "^4.5.0" + schema-utils "^4.8.1" tapable "^2.3.0" - watchpack "^2.6.1" + watchpack "^2.6.3" webpack-sources "^3.6.0" whatwg-encoding@^2.0.0: From be0df4820377e50fbeda54a9c4e47c7b65626d69 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 28 Oct 2026 08:46:51 +0000 Subject: [PATCH 2/3] [fern-replay] Applied customizations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patches applied (6): - patch-066ff9e0: docs: add v6 migration guide for breaking changes in v6.0.0 (#1368) - patch-d8faf7a2: docs: update v6 migration guide with federatedConnectionsTokensets and federated_connections_access_tokens breaking changes (#1370) - patch-0f7baa6f: fix: auto-stamp SDK_VERSION from package.json during build (#1382) - patch-b942f5d6: docs: add Authentication API migration guide (auth0-auth-js / auth0-server-js) (#1395) - patch-842d2f51: docs: add v7 migration guide (v6 → v7) (#1396) - patch-456afefc: feat: enhance domain validation for ManagementClient and related components Patches with unresolved conflicts (12): - patch-490e5634: feat(management): add sub-package exports and management auth helper (#1373) - patch-74170bb0: Release v6.1.0 (#1381) - patch-4fcb39a4: Release v6.2.0 (#1389) - patch-f9d64134: Release v6.3.0 (#1393) - patch-4d450aa4: Release v6.4.0 (#1401) - patch-d4614ec0: Release v7.0.0 (#1402) - patch-e1e90b89: Release v7.1.0 (#1405) - patch-567042f4: Release v7.2.0 (#1409) - patch-de9f20d2: Release v7.3.0 (#1415) - patch-7750e996: Release v7.4.0 (#1424) - patch-f9566e21: Release v7.5.0 (#1427) - patch-185ac064: Release v7.6.0 (#1430) Run `fern-replay resolve` to apply these customizations. Patches absorbed by generator (2): - patch-54876943: docs: update v7 migration guide with export changes and replacements - patch-4e648106: test: refactor domain validation tests to use parameterized cases and add port handling The generator now produces these customizations natively. --- .fern/replay.lock | 2284 +++++++++++++++++++++++- .shiprc | 6 + AUTH_MIGRATION_GUIDE.md | 14 + auth-migration/authentication-flows.md | 234 +++ auth-migration/index.md | 732 ++++++++ auth-migration/server-side-sessions.md | 163 ++ auth-migration/troubleshooting.md | 32 + v6_MIGRATION_GUIDE.md | 158 ++ v7_MIGRATION_GUIDE.md | 146 ++ 9 files changed, 3729 insertions(+), 40 deletions(-) create mode 100644 .shiprc create mode 100644 AUTH_MIGRATION_GUIDE.md create mode 100644 auth-migration/authentication-flows.md create mode 100644 auth-migration/index.md create mode 100644 auth-migration/server-side-sessions.md create mode 100644 auth-migration/troubleshooting.md create mode 100644 v6_MIGRATION_GUIDE.md create mode 100644 v7_MIGRATION_GUIDE.md diff --git a/.fern/replay.lock b/.fern/replay.lock index 111a822fa1..f694fd4747 100644 --- a/.fern/replay.lock +++ b/.fern/replay.lock @@ -72,14 +72,20 @@ generations: cli_version: unknown generator_versions: fernapi/fern-typescript-sdk: 3.107.1 -current_generation: 4f367ef3d7e2a5746f847006bc4e646c8b5b27cf + - commit_sha: bf8d20b878899a53ca83287309f3bb649ca46f72 + tree_hash: bf1825f88843d105d5d308391afb518ea4ffdc64 + timestamp: 2026-10-28T08:46:28.526Z + cli_version: unknown + generator_versions: + fernapi/fern-typescript-sdk: 3.107.6 +current_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 patches: - id: patch-066ff9e0 content_hash: sha256:5b87ec9a63fc57aba4840d0d335d472c621e838fc1d61515b30660df39d0dbc2 original_commit: 066ff9e02c45f4abf46791a3f070c762f7ecd924 original_message: "docs: add v6 migration guide for breaking changes in v6.0.0 (#1368)" original_author: Ankita Tripathi <51994119+ankita10119@users.noreply.github.com> - base_generation: 4f367ef3d7e2a5746f847006bc4e646c8b5b27cf + base_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 files: - v6_MIGRATION_GUIDE.md patch_content: | @@ -413,7 +419,7 @@ patches: original_commit: d8faf7a21efbed3bd75a0f36ff0d190bb9dd986b original_message: "docs: update v6 migration guide with federatedConnectionsTokensets and federated_connections_access_tokens breaking changes (#1370)" original_author: Ankita Tripathi <51994119+ankita10119@users.noreply.github.com> - base_generation: 4f367ef3d7e2a5746f847006bc4e646c8b5b27cf + base_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 files: - v6_MIGRATION_GUIDE.md patch_content: | @@ -8255,7 +8261,7 @@ patches: original_commit: 0f7baa6fa58a2944cd9e39abbfd8caf7be8d7e8c original_message: "fix: auto-stamp SDK_VERSION from package.json during build (#1382)" original_author: Ankita Tripathi <51994119+ankita10119@users.noreply.github.com> - base_generation: 4f367ef3d7e2a5746f847006bc4e646c8b5b27cf + base_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 files: - .shiprc patch_content: | @@ -13732,7 +13738,7 @@ patches: original_commit: b942f5d6b1b5f3e565f3315f12421c58ae005bec original_message: "docs: add Authentication API migration guide (auth0-auth-js / auth0-server-js) (#1395)" original_author: tusharpandey13 - base_generation: 4f367ef3d7e2a5746f847006bc4e646c8b5b27cf + base_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 files: - AUTH_MIGRATION_GUIDE.md - auth-migration/authentication-flows.md @@ -16128,17 +16134,17 @@ patches: Use the `isMfaRequiredError()` type guard, not a string comparison. It narrows the error and exposes the `mfa_token`. Drive the challenge via `authClient.mfa.*`. See [Error model](./index.md#4-error-model). user_owned: true - id: patch-842d2f51 - content_hash: sha256:fd135e124d79e79126e3cfafdb56c2d8ebd0edcc27deec1e8255a5aa8175d685 + content_hash: sha256:33d7dca791ca40e3343d9b1046b1c20a04e0add593e3d5ee2941220a39f42f88 original_commit: 842d2f5189493b78e420c17c968c80bc239e143a original_message: "docs: add v7 migration guide (v6 → v7) (#1396)" original_author: tusharpandey13 - base_generation: 4f367ef3d7e2a5746f847006bc4e646c8b5b27cf + base_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 files: - v7_MIGRATION_GUIDE.md patch_content: | diff --git a/v7_MIGRATION_GUIDE.md b/v7_MIGRATION_GUIDE.md new file mode 100644 - index 0000000000..95d366b1e8 + index 0000000000..d1dba04a5c --- /dev/null +++ b/v7_MIGRATION_GUIDE.md @@ -0,0 +1,146 @@ @@ -16198,21 +16204,21 @@ patches: + +The following symbols were exported from the main entrypoint in v6 and are removed in v7. Each moves to `@auth0/auth0-auth-js`, or remains available from the `auth0/legacy` entrypoint at its v4.x shape. + - +| Removed export (v6) | Replacement in v7 | - +| ---------------------------- | ------------------------------------------------------------------------------------- | - +| `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | - +| `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | - +| `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | - +| `AuthenticationClientOptions`| `AuthClientOptions` from `@auth0/auth0-auth-js` | - +| `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | - +| `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | - +| `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | - +| `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | - +| `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | - +| `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | - +| `ResponseError` | Management API calls throw `ManagementError` | - +| `FetchError` | Management API calls throw `ManagementError` | - +| `JSONApiResponse` | Responses return the data directly (no wrapper) | + +| Removed export (v6) | Replacement in v7 | + +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | + +| `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | + +| `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | + +| `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | + +| `AuthenticationClientOptions` | `AuthClientOptions` from `@auth0/auth0-auth-js` | + +| `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | + +| `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | + +| `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | + +| `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | + +| `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + +| `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + +| `ResponseError` | Management API calls throw `ManagementError` | + +| `FetchError` | Management API calls throw `ManagementError` | + +| `JSONApiResponse` | Responses return the data directly (no wrapper) | + +`ManagementClient`, the `Management` namespace, and `ManagementError` are unchanged and still exported. + @@ -16239,7 +16245,7 @@ patches: + +### `domain` must be a bare hostname + - +`domain` must be a bare host such as `tenant.us.auth0.com`. A value containing a scheme, slashes, or a query string now throws at construction instead of producing malformed request URLs later. + +`domain` must be a bare host such as `tenant.us.auth0.com`. A value that is empty, or that contains a scheme, a path, a query string, a fragment, credentials (`@`), or whitespace, now throws at construction instead of producing malformed request URLs later. The check applies to every authentication mode (`token`, `clientSecret`, and `clientAssertionSigningKey`), and to `createManagementAuth` and `TokenProvider` as well as `ManagementClient`. + +```ts +// throws in v7 @@ -16346,21 +16352,21 @@ patches: The following symbols were exported from the main entrypoint in v6 and are removed in v7. Each moves to `@auth0/auth0-auth-js`, or remains available from the `auth0/legacy` entrypoint at its v4.x shape. - | Removed export (v6) | Replacement in v7 | - | ---------------------------- | ------------------------------------------------------------------------------------- | - | `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | - | `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | - | `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | - | `AuthenticationClientOptions`| `AuthClientOptions` from `@auth0/auth0-auth-js` | - | `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | - | `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | - | `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | - | `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | - | `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | - | `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | - | `ResponseError` | Management API calls throw `ManagementError` | - | `FetchError` | Management API calls throw `ManagementError` | - | `JSONApiResponse` | Responses return the data directly (no wrapper) | + | Removed export (v6) | Replacement in v7 | + | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | + | `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | + | `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | + | `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | + | `AuthenticationClientOptions` | `AuthClientOptions` from `@auth0/auth0-auth-js` | + | `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | + | `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | + | `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | + | `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | + | `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + | `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + | `ResponseError` | Management API calls throw `ManagementError` | + | `FetchError` | Management API calls throw `ManagementError` | + | `JSONApiResponse` | Responses return the data directly (no wrapper) | `ManagementClient`, the `Management` namespace, and `ManagementError` are unchanged and still exported. @@ -16387,7 +16393,7 @@ patches: ### `domain` must be a bare hostname - `domain` must be a bare host such as `tenant.us.auth0.com`. A value containing a scheme, slashes, or a query string now throws at construction instead of producing malformed request URLs later. + `domain` must be a bare host such as `tenant.us.auth0.com`. A value that is empty, or that contains a scheme, a path, a query string, a fragment, credentials (`@`), or whitespace, now throws at construction instead of producing malformed request URLs later. The check applies to every authentication mode (`token`, `clientSecret`, and `clientAssertionSigningKey`), and to `createManagementAuth` and `TokenProvider` as well as `ManagementClient`. ```ts // throws in v7 @@ -27638,3 +27644,2201 @@ patches: src/management/version.ts: | export const SDK_VERSION = "7.5.0"; status: unresolved + - id: patch-456afefc + content_hash: sha256:33d7dca791ca40e3343d9b1046b1c20a04e0add593e3d5ee2941220a39f42f88 + original_commit: 456afefce9a6ae6305f65307b3a19e7b2a801199 + original_message: "feat: enhance domain validation for ManagementClient and related components" + original_author: Amit Singh + base_generation: bf8d20b878899a53ca83287309f3bb649ca46f72 + files: + - v7_MIGRATION_GUIDE.md + patch_content: | + diff --git a/v7_MIGRATION_GUIDE.md b/v7_MIGRATION_GUIDE.md + new file mode 100644 + index 0000000000..d1dba04a5c + --- /dev/null + +++ b/v7_MIGRATION_GUIDE.md + @@ -0,0 +1,146 @@ + +# V7 Migration Guide + + + +A guide to migrating the Auth0 Node.js SDK from `6.x` to `7.x`. + + + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill first. The skill lives in [`auth0/agent-skills`](https://github.com/auth0/agent-skills) as the `auth0` skill (migration intent: `migrate-node-auth0`). It encodes the authentication-layer rewrite rules and a verify loop. + + + +- [Overall changes](#overall-changes) + +- [Breaking changes](#breaking-changes) + + - [Authentication API removed from the main entrypoint](#authentication-api-removed-from-the-main-entrypoint) + + - [Removed exports](#removed-exports) + + - [ManagementClient mTLS requires an explicit `fetch`](#managementclient-mtls-requires-an-explicit-fetch) + + - [mTLS works with both client secret and client assertion](#mtls-works-with-both-client-secret-and-client-assertion) + + - [`domain` must be a bare hostname](#domain-must-be-a-bare-hostname) + + - [Token acquisition failures throw `ManagementError`](#token-acquisition-failures-throw-managementerror) + + - [`uuid` dependency removed](#uuid-dependency-removed) + +- [Migrating authentication code](#migrating-authentication-code) + +- [Staying on the legacy entrypoint](#staying-on-the-legacy-entrypoint) + + + +## Overall changes + + + +V7 makes `node-auth0` a **Management-API-only SDK**. The Authentication API layer (`AuthenticationClient`, its sub-clients, and `UserInfoClient`) has been removed from the main entrypoint. `ManagementClient` continues to work exactly as before; it now acquires its internal token directly via the client credentials grant rather than through the removed authentication layer. + + + +If your code only uses `ManagementClient`, the upgrade is small: address the Management-side breaking changes below (mTLS, domain validation, error type) and you are done. If your code uses `AuthenticationClient` or `UserInfoClient`, that code must move to a dedicated package; see [Migrating authentication code](#migrating-authentication-code). + + + +## Breaking changes + + + +### Authentication API removed from the main entrypoint + + + +`AuthenticationClient` and `UserInfoClient` are no longer exported from the `auth0` main entrypoint. The stateless authentication layer now lives in [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js), and the server-managed session layer lives in [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js). + + + +**Before (v6):** + + + +```ts + +import { AuthenticationClient, UserInfoClient } from "auth0"; + + + +const auth = new AuthenticationClient({ domain, clientId, clientSecret }); + +const tokens = await auth.oauth.clientCredentialsGrant({ audience }); + +``` + + + +**After (v7):** + + + +```ts + +import { AuthClient } from "@auth0/auth0-auth-js"; + + + +const auth = new AuthClient({ domain, clientId, clientSecret }); + +const tokens = await auth.getTokenByClientCredentials({ audience }); + +``` + + + +The complete method-by-method mapping, the four cross-cutting behavior changes (return shape, casing, token expiry, error model), and the session-app wiring are documented in the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). This guide does not repeat that detail. + + + +If you need the old clients unchanged as a stopgap, they still ship from the [legacy entrypoint](#staying-on-the-legacy-entrypoint). + + + +### Removed exports + + + +The following symbols were exported from the main entrypoint in v6 and are removed in v7. Each moves to `@auth0/auth0-auth-js`, or remains available from the `auth0/legacy` entrypoint at its v4.x shape. + + + +| Removed export (v6) | Replacement in v7 | + +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | + +| `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | + +| `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | + +| `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | + +| `AuthenticationClientOptions` | `AuthClientOptions` from `@auth0/auth0-auth-js` | + +| `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | + +| `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | + +| `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | + +| `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | + +| `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + +| `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + +| `ResponseError` | Management API calls throw `ManagementError` | + +| `FetchError` | Management API calls throw `ManagementError` | + +| `JSONApiResponse` | Responses return the data directly (no wrapper) | + + + +`ManagementClient`, the `Management` namespace, and `ManagementError` are unchanged and still exported. + + + +### ManagementClient mTLS requires an explicit `fetch` + + + +A `ManagementClient` constructed with `useMTLS: true` must now supply an explicit `fetch` option carrying the client certificate. The client throws at construction if `useMTLS` is set without a `fetch`. Previously a missing fetch surfaced as silent `401`s at request time; failing at construction makes the misconfiguration obvious. + + + +The token endpoint automatically uses the `mtls.{domain}` host when `useMTLS` is enabled. + + + +```ts + +// v7: throws at construction if `fetch` is omitted + +const mgmt = new ManagementClient({ + + domain, + + clientId, + + clientSecret, + + useMTLS: true, + + fetch: mtlsCapableFetch, // now required + +}); + +``` + + + +### mTLS works with both client secret and client assertion + + + +`useMTLS` works with both `clientSecret` and `clientAssertionSigningKey`. mTLS (RFC 8705) is a transport-layer concern: the TLS client certificate yields a certificate-bound token regardless of which client authentication method is used. An explicit `fetch` option is always required when `useMTLS` is set. + + + +### `domain` must be a bare hostname + + + +`domain` must be a bare host such as `tenant.us.auth0.com`. A value that is empty, or that contains a scheme, a path, a query string, a fragment, credentials (`@`), or whitespace, now throws at construction instead of producing malformed request URLs later. The check applies to every authentication mode (`token`, `clientSecret`, and `clientAssertionSigningKey`), and to `createManagementAuth` and `TokenProvider` as well as `ManagementClient`. + + + +```ts + +// throws in v7 + +new ManagementClient({ domain: "https://tenant.us.auth0.com/", ... }); + +// correct + +new ManagementClient({ domain: "tenant.us.auth0.com", ... }); + +``` + + + +### Token acquisition failures throw `ManagementError` + + + +When the internal client-credentials token request fails, the client now throws a `ManagementError` (previously a plain `Error`). The error carries `statusCode` and a parsed `body` with the OAuth error details. A request that exceeds the 10-second timeout throws `ManagementError` with status `408`. + + + +```ts + +import { ManagementError } from "auth0"; + + + +try { + + await mgmt.users.getAll(); + +} catch (e) { + + if (e instanceof ManagementError) { + + console.error(e.statusCode, e.body); + + } + +} + +``` + + + +### `uuid` dependency removed + + + +The `uuid` package is no longer a dependency. If your project imported `uuid` transitively through `auth0`, add it to your own `dependencies`. + + + +## Migrating authentication code + + + +If your app calls `AuthenticationClient` or `UserInfoClient`, follow the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). Start with [`auth-migration/index.md`](https://github.com/auth0/node-auth0/blob/master/auth-migration/index.md) for the OIDC token grants section; the incremental flow, session, and troubleshooting pages live in the same [`auth-migration/`](https://github.com/auth0/node-auth0/tree/master/auth-migration) directory. It covers: + + + +- Choosing between `@auth0/auth0-auth-js` (stateless token grants) and `@auth0/auth0-server-js` (server-managed sessions). + +- The complete method-by-method API mapping for `.oauth`, `.database`, `.passwordless`, `.backchannel`, `.tokenExchange`, and `UserInfoClient`. + +- The four cross-cutting behavior changes: return shape (envelope dropped), casing (snake_case → camelCase), token expiry (`expires_in` relative → `expiresAt` absolute, a silent high-risk change), and the typed error model with `isMfaRequiredError()`. + +- Wiring the `auth0-server-js` session lifecycle when you want the SDK to own login, cookies, refresh, and logout. + + + +The Management API is explicitly out of scope in that guide: a file that keeps using `ManagementClient` from `auth0` while importing `@auth0/auth0-auth-js` for authentication is correct and expected. + + + +## Staying on the legacy entrypoint + + + +If you cannot migrate the authentication code immediately, the `auth0/legacy` entrypoint still ships `AuthenticationClient` and `UserInfoClient` at their v4.x configuration format and method signatures. This is a stopgap, not a destination; the legacy shapes differ from the current API and will not receive new features. + + + +```ts + +import { AuthenticationClient } from "auth0/legacy"; + +``` + + + +Plan the move to `@auth0/auth0-auth-js` / `@auth0/auth0-server-js` rather than treating the legacy entrypoint as permanent. + theirs_snapshot: + v7_MIGRATION_GUIDE.md: | + # V7 Migration Guide + + A guide to migrating the Auth0 Node.js SDK from `6.x` to `7.x`. + + > **Migrating with an AI agent?** Point it at the Auth0 migration skill first. The skill lives in [`auth0/agent-skills`](https://github.com/auth0/agent-skills) as the `auth0` skill (migration intent: `migrate-node-auth0`). It encodes the authentication-layer rewrite rules and a verify loop. + + - [Overall changes](#overall-changes) + - [Breaking changes](#breaking-changes) + - [Authentication API removed from the main entrypoint](#authentication-api-removed-from-the-main-entrypoint) + - [Removed exports](#removed-exports) + - [ManagementClient mTLS requires an explicit `fetch`](#managementclient-mtls-requires-an-explicit-fetch) + - [mTLS works with both client secret and client assertion](#mtls-works-with-both-client-secret-and-client-assertion) + - [`domain` must be a bare hostname](#domain-must-be-a-bare-hostname) + - [Token acquisition failures throw `ManagementError`](#token-acquisition-failures-throw-managementerror) + - [`uuid` dependency removed](#uuid-dependency-removed) + - [Migrating authentication code](#migrating-authentication-code) + - [Staying on the legacy entrypoint](#staying-on-the-legacy-entrypoint) + + ## Overall changes + + V7 makes `node-auth0` a **Management-API-only SDK**. The Authentication API layer (`AuthenticationClient`, its sub-clients, and `UserInfoClient`) has been removed from the main entrypoint. `ManagementClient` continues to work exactly as before; it now acquires its internal token directly via the client credentials grant rather than through the removed authentication layer. + + If your code only uses `ManagementClient`, the upgrade is small: address the Management-side breaking changes below (mTLS, domain validation, error type) and you are done. If your code uses `AuthenticationClient` or `UserInfoClient`, that code must move to a dedicated package; see [Migrating authentication code](#migrating-authentication-code). + + ## Breaking changes + + ### Authentication API removed from the main entrypoint + + `AuthenticationClient` and `UserInfoClient` are no longer exported from the `auth0` main entrypoint. The stateless authentication layer now lives in [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js), and the server-managed session layer lives in [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js). + + **Before (v6):** + + ```ts + import { AuthenticationClient, UserInfoClient } from "auth0"; + + const auth = new AuthenticationClient({ domain, clientId, clientSecret }); + const tokens = await auth.oauth.clientCredentialsGrant({ audience }); + ``` + + **After (v7):** + + ```ts + import { AuthClient } from "@auth0/auth0-auth-js"; + + const auth = new AuthClient({ domain, clientId, clientSecret }); + const tokens = await auth.getTokenByClientCredentials({ audience }); + ``` + + The complete method-by-method mapping, the four cross-cutting behavior changes (return shape, casing, token expiry, error model), and the session-app wiring are documented in the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). This guide does not repeat that detail. + + If you need the old clients unchanged as a stopgap, they still ship from the [legacy entrypoint](#staying-on-the-legacy-entrypoint). + + ### Removed exports + + The following symbols were exported from the main entrypoint in v6 and are removed in v7. Each moves to `@auth0/auth0-auth-js`, or remains available from the `auth0/legacy` entrypoint at its v4.x shape. + + | Removed export (v6) | Replacement in v7 | + | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | + | `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | + | `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | + | `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | + | `AuthenticationClientOptions` | `AuthClientOptions` from `@auth0/auth0-auth-js` | + | `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | + | `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | + | `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | + | `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | + | `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + | `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | + | `ResponseError` | Management API calls throw `ManagementError` | + | `FetchError` | Management API calls throw `ManagementError` | + | `JSONApiResponse` | Responses return the data directly (no wrapper) | + + `ManagementClient`, the `Management` namespace, and `ManagementError` are unchanged and still exported. + + ### ManagementClient mTLS requires an explicit `fetch` + + A `ManagementClient` constructed with `useMTLS: true` must now supply an explicit `fetch` option carrying the client certificate. The client throws at construction if `useMTLS` is set without a `fetch`. Previously a missing fetch surfaced as silent `401`s at request time; failing at construction makes the misconfiguration obvious. + + The token endpoint automatically uses the `mtls.{domain}` host when `useMTLS` is enabled. + + ```ts + // v7: throws at construction if `fetch` is omitted + const mgmt = new ManagementClient({ + domain, + clientId, + clientSecret, + useMTLS: true, + fetch: mtlsCapableFetch, // now required + }); + ``` + + ### mTLS works with both client secret and client assertion + + `useMTLS` works with both `clientSecret` and `clientAssertionSigningKey`. mTLS (RFC 8705) is a transport-layer concern: the TLS client certificate yields a certificate-bound token regardless of which client authentication method is used. An explicit `fetch` option is always required when `useMTLS` is set. + + ### `domain` must be a bare hostname + + `domain` must be a bare host such as `tenant.us.auth0.com`. A value that is empty, or that contains a scheme, a path, a query string, a fragment, credentials (`@`), or whitespace, now throws at construction instead of producing malformed request URLs later. The check applies to every authentication mode (`token`, `clientSecret`, and `clientAssertionSigningKey`), and to `createManagementAuth` and `TokenProvider` as well as `ManagementClient`. + + ```ts + // throws in v7 + new ManagementClient({ domain: "https://tenant.us.auth0.com/", ... }); + // correct + new ManagementClient({ domain: "tenant.us.auth0.com", ... }); + ``` + + ### Token acquisition failures throw `ManagementError` + + When the internal client-credentials token request fails, the client now throws a `ManagementError` (previously a plain `Error`). The error carries `statusCode` and a parsed `body` with the OAuth error details. A request that exceeds the 10-second timeout throws `ManagementError` with status `408`. + + ```ts + import { ManagementError } from "auth0"; + + try { + await mgmt.users.getAll(); + } catch (e) { + if (e instanceof ManagementError) { + console.error(e.statusCode, e.body); + } + } + ``` + + ### `uuid` dependency removed + + The `uuid` package is no longer a dependency. If your project imported `uuid` transitively through `auth0`, add it to your own `dependencies`. + + ## Migrating authentication code + + If your app calls `AuthenticationClient` or `UserInfoClient`, follow the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). Start with [`auth-migration/index.md`](https://github.com/auth0/node-auth0/blob/master/auth-migration/index.md) for the OIDC token grants section; the incremental flow, session, and troubleshooting pages live in the same [`auth-migration/`](https://github.com/auth0/node-auth0/tree/master/auth-migration) directory. It covers: + + - Choosing between `@auth0/auth0-auth-js` (stateless token grants) and `@auth0/auth0-server-js` (server-managed sessions). + - The complete method-by-method API mapping for `.oauth`, `.database`, `.passwordless`, `.backchannel`, `.tokenExchange`, and `UserInfoClient`. + - The four cross-cutting behavior changes: return shape (envelope dropped), casing (snake_case → camelCase), token expiry (`expires_in` relative → `expiresAt` absolute, a silent high-risk change), and the typed error model with `isMfaRequiredError()`. + - Wiring the `auth0-server-js` session lifecycle when you want the SDK to own login, cookies, refresh, and logout. + + The Management API is explicitly out of scope in that guide: a file that keeps using `ManagementClient` from `auth0` while importing `@auth0/auth0-auth-js` for authentication is correct and expected. + + ## Staying on the legacy entrypoint + + If you cannot migrate the authentication code immediately, the `auth0/legacy` entrypoint still ships `AuthenticationClient` and `UserInfoClient` at their v4.x configuration format and method signatures. This is a stopgap, not a destination; the legacy shapes differ from the current API and will not receive new features. + + ```ts + import { AuthenticationClient } from "auth0/legacy"; + ``` + + Plan the move to `@auth0/auth0-auth-js` / `@auth0/auth0-server-js` rather than treating the legacy entrypoint as permanent. + - id: patch-185ac064 + content_hash: sha256:eae25ca4d648887ccd0dbf85d55f52be8e3112bf613809c6b74c1e61499f424f + original_commit: 185ac0645e47f85eba6a6369f820b304bce27d4c + original_message: Release v7.6.0 (#1430) + original_author: Ankita Tripathi <51994119+ankita10119@users.noreply.github.com> + base_generation: ffcd9e2df9f9842b185ec5d5df53c84a898eaf49 + files: + - package.json + - src/management/version.ts + patch_content: | + diff --git a/package.json b/package.json + index e9d0ebdf6a..498d343959 100644 + --- a/package.json + +++ b/package.json + @@ -1,6 +1,6 @@ + { + "name": "auth0", + - "version": "7.5.0", + + "version": "7.6.0", + "private": false, + "repository": { + "type": "git", + diff --git a/src/management/version.ts b/src/management/version.ts + index 6a5cc9fe4a..c012080661 100644 + --- a/src/management/version.ts + +++ b/src/management/version.ts + @@ -1 +1 @@ + -export const SDK_VERSION = "7.5.0"; + +export const SDK_VERSION = "7.6.0"; + theirs_snapshot: + package.json: | + { + "name": "auth0", + "version": "7.6.0", + "private": false, + "repository": { + "type": "git", + "url": "git+https://github.com/auth0/node-auth0.git" + }, + "license": "MIT", + "type": "commonjs", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.mjs", + "types": "./dist/cjs/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + }, + "default": "./dist/cjs/index.js" + }, + "./actions": { + "import": { + "types": "./dist/esm/management/api/resources/actions/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/exports.js" + }, + "./agents": { + "import": { + "types": "./dist/esm/management/api/resources/agents/exports.d.mts", + "default": "./dist/esm/management/api/resources/agents/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/agents/exports.d.ts", + "default": "./dist/cjs/management/api/resources/agents/exports.js" + }, + "default": "./dist/cjs/management/api/resources/agents/exports.js" + }, + "./branding": { + "import": { + "types": "./dist/esm/management/api/resources/branding/exports.d.mts", + "default": "./dist/esm/management/api/resources/branding/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/branding/exports.d.ts", + "default": "./dist/cjs/management/api/resources/branding/exports.js" + }, + "default": "./dist/cjs/management/api/resources/branding/exports.js" + }, + "./clientGrants": { + "import": { + "types": "./dist/esm/management/api/resources/clientGrants/exports.d.mts", + "default": "./dist/esm/management/api/resources/clientGrants/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/clientGrants/exports.d.ts", + "default": "./dist/cjs/management/api/resources/clientGrants/exports.js" + }, + "default": "./dist/cjs/management/api/resources/clientGrants/exports.js" + }, + "./clientProfiles": { + "import": { + "types": "./dist/esm/management/api/resources/clientProfiles/exports.d.mts", + "default": "./dist/esm/management/api/resources/clientProfiles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/clientProfiles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/clientProfiles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/clientProfiles/exports.js" + }, + "./clients": { + "import": { + "types": "./dist/esm/management/api/resources/clients/exports.d.mts", + "default": "./dist/esm/management/api/resources/clients/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/clients/exports.d.ts", + "default": "./dist/cjs/management/api/resources/clients/exports.js" + }, + "default": "./dist/cjs/management/api/resources/clients/exports.js" + }, + "./connectionProfiles": { + "import": { + "types": "./dist/esm/management/api/resources/connectionProfiles/exports.d.mts", + "default": "./dist/esm/management/api/resources/connectionProfiles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connectionProfiles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connectionProfiles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connectionProfiles/exports.js" + }, + "./connections": { + "import": { + "types": "./dist/esm/management/api/resources/connections/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/exports.js" + }, + "./customDomains": { + "import": { + "types": "./dist/esm/management/api/resources/customDomains/exports.d.mts", + "default": "./dist/esm/management/api/resources/customDomains/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/customDomains/exports.d.ts", + "default": "./dist/cjs/management/api/resources/customDomains/exports.js" + }, + "default": "./dist/cjs/management/api/resources/customDomains/exports.js" + }, + "./deviceCredentials": { + "import": { + "types": "./dist/esm/management/api/resources/deviceCredentials/exports.d.mts", + "default": "./dist/esm/management/api/resources/deviceCredentials/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/deviceCredentials/exports.d.ts", + "default": "./dist/cjs/management/api/resources/deviceCredentials/exports.js" + }, + "default": "./dist/cjs/management/api/resources/deviceCredentials/exports.js" + }, + "./emailTemplates": { + "import": { + "types": "./dist/esm/management/api/resources/emailTemplates/exports.d.mts", + "default": "./dist/esm/management/api/resources/emailTemplates/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/emailTemplates/exports.d.ts", + "default": "./dist/cjs/management/api/resources/emailTemplates/exports.js" + }, + "default": "./dist/cjs/management/api/resources/emailTemplates/exports.js" + }, + "./eventStreams": { + "import": { + "types": "./dist/esm/management/api/resources/eventStreams/exports.d.mts", + "default": "./dist/esm/management/api/resources/eventStreams/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/eventStreams/exports.d.ts", + "default": "./dist/cjs/management/api/resources/eventStreams/exports.js" + }, + "default": "./dist/cjs/management/api/resources/eventStreams/exports.js" + }, + "./events": { + "import": { + "types": "./dist/esm/management/api/resources/events/exports.d.mts", + "default": "./dist/esm/management/api/resources/events/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/events/exports.d.ts", + "default": "./dist/cjs/management/api/resources/events/exports.js" + }, + "default": "./dist/cjs/management/api/resources/events/exports.js" + }, + "./flows": { + "import": { + "types": "./dist/esm/management/api/resources/flows/exports.d.mts", + "default": "./dist/esm/management/api/resources/flows/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/flows/exports.d.ts", + "default": "./dist/cjs/management/api/resources/flows/exports.js" + }, + "default": "./dist/cjs/management/api/resources/flows/exports.js" + }, + "./forms": { + "import": { + "types": "./dist/esm/management/api/resources/forms/exports.d.mts", + "default": "./dist/esm/management/api/resources/forms/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/forms/exports.d.ts", + "default": "./dist/cjs/management/api/resources/forms/exports.js" + }, + "default": "./dist/cjs/management/api/resources/forms/exports.js" + }, + "./userGrants": { + "import": { + "types": "./dist/esm/management/api/resources/userGrants/exports.d.mts", + "default": "./dist/esm/management/api/resources/userGrants/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/userGrants/exports.d.ts", + "default": "./dist/cjs/management/api/resources/userGrants/exports.js" + }, + "default": "./dist/cjs/management/api/resources/userGrants/exports.js" + }, + "./groups": { + "import": { + "types": "./dist/esm/management/api/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/groups/exports.js" + }, + "./guardian": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/exports.js" + }, + "./hooks": { + "import": { + "types": "./dist/esm/management/api/resources/hooks/exports.d.mts", + "default": "./dist/esm/management/api/resources/hooks/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/hooks/exports.d.ts", + "default": "./dist/cjs/management/api/resources/hooks/exports.js" + }, + "default": "./dist/cjs/management/api/resources/hooks/exports.js" + }, + "./jobs": { + "import": { + "types": "./dist/esm/management/api/resources/jobs/exports.d.mts", + "default": "./dist/esm/management/api/resources/jobs/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/jobs/exports.d.ts", + "default": "./dist/cjs/management/api/resources/jobs/exports.js" + }, + "default": "./dist/cjs/management/api/resources/jobs/exports.js" + }, + "./logStreams": { + "import": { + "types": "./dist/esm/management/api/resources/logStreams/exports.d.mts", + "default": "./dist/esm/management/api/resources/logStreams/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/logStreams/exports.d.ts", + "default": "./dist/cjs/management/api/resources/logStreams/exports.js" + }, + "default": "./dist/cjs/management/api/resources/logStreams/exports.js" + }, + "./logs": { + "import": { + "types": "./dist/esm/management/api/resources/logs/exports.d.mts", + "default": "./dist/esm/management/api/resources/logs/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/logs/exports.d.ts", + "default": "./dist/cjs/management/api/resources/logs/exports.js" + }, + "default": "./dist/cjs/management/api/resources/logs/exports.js" + }, + "./networkAcls": { + "import": { + "types": "./dist/esm/management/api/resources/networkAcls/exports.d.mts", + "default": "./dist/esm/management/api/resources/networkAcls/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/networkAcls/exports.d.ts", + "default": "./dist/cjs/management/api/resources/networkAcls/exports.js" + }, + "default": "./dist/cjs/management/api/resources/networkAcls/exports.js" + }, + "./organizations": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/exports.js" + }, + "./prompts": { + "import": { + "types": "./dist/esm/management/api/resources/prompts/exports.d.mts", + "default": "./dist/esm/management/api/resources/prompts/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/prompts/exports.d.ts", + "default": "./dist/cjs/management/api/resources/prompts/exports.js" + }, + "default": "./dist/cjs/management/api/resources/prompts/exports.js" + }, + "./rateLimitPolicies": { + "import": { + "types": "./dist/esm/management/api/resources/rateLimitPolicies/exports.d.mts", + "default": "./dist/esm/management/api/resources/rateLimitPolicies/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/rateLimitPolicies/exports.d.ts", + "default": "./dist/cjs/management/api/resources/rateLimitPolicies/exports.js" + }, + "default": "./dist/cjs/management/api/resources/rateLimitPolicies/exports.js" + }, + "./refreshTokens": { + "import": { + "types": "./dist/esm/management/api/resources/refreshTokens/exports.d.mts", + "default": "./dist/esm/management/api/resources/refreshTokens/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/refreshTokens/exports.d.ts", + "default": "./dist/cjs/management/api/resources/refreshTokens/exports.js" + }, + "default": "./dist/cjs/management/api/resources/refreshTokens/exports.js" + }, + "./resourceServers": { + "import": { + "types": "./dist/esm/management/api/resources/resourceServers/exports.d.mts", + "default": "./dist/esm/management/api/resources/resourceServers/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/resourceServers/exports.d.ts", + "default": "./dist/cjs/management/api/resources/resourceServers/exports.js" + }, + "default": "./dist/cjs/management/api/resources/resourceServers/exports.js" + }, + "./roles": { + "import": { + "types": "./dist/esm/management/api/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/roles/exports.js" + }, + "./rules": { + "import": { + "types": "./dist/esm/management/api/resources/rules/exports.d.mts", + "default": "./dist/esm/management/api/resources/rules/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/rules/exports.d.ts", + "default": "./dist/cjs/management/api/resources/rules/exports.js" + }, + "default": "./dist/cjs/management/api/resources/rules/exports.js" + }, + "./rulesConfigs": { + "import": { + "types": "./dist/esm/management/api/resources/rulesConfigs/exports.d.mts", + "default": "./dist/esm/management/api/resources/rulesConfigs/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/rulesConfigs/exports.d.ts", + "default": "./dist/cjs/management/api/resources/rulesConfigs/exports.js" + }, + "default": "./dist/cjs/management/api/resources/rulesConfigs/exports.js" + }, + "./selfServiceProfiles": { + "import": { + "types": "./dist/esm/management/api/resources/selfServiceProfiles/exports.d.mts", + "default": "./dist/esm/management/api/resources/selfServiceProfiles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/selfServiceProfiles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/selfServiceProfiles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/selfServiceProfiles/exports.js" + }, + "./sessions": { + "import": { + "types": "./dist/esm/management/api/resources/sessions/exports.d.mts", + "default": "./dist/esm/management/api/resources/sessions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/sessions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/sessions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/sessions/exports.js" + }, + "./stats": { + "import": { + "types": "./dist/esm/management/api/resources/stats/exports.d.mts", + "default": "./dist/esm/management/api/resources/stats/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/stats/exports.d.ts", + "default": "./dist/cjs/management/api/resources/stats/exports.js" + }, + "default": "./dist/cjs/management/api/resources/stats/exports.js" + }, + "./supplementalSignals": { + "import": { + "types": "./dist/esm/management/api/resources/supplementalSignals/exports.d.mts", + "default": "./dist/esm/management/api/resources/supplementalSignals/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/supplementalSignals/exports.d.ts", + "default": "./dist/cjs/management/api/resources/supplementalSignals/exports.js" + }, + "default": "./dist/cjs/management/api/resources/supplementalSignals/exports.js" + }, + "./tickets": { + "import": { + "types": "./dist/esm/management/api/resources/tickets/exports.d.mts", + "default": "./dist/esm/management/api/resources/tickets/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/tickets/exports.d.ts", + "default": "./dist/cjs/management/api/resources/tickets/exports.js" + }, + "default": "./dist/cjs/management/api/resources/tickets/exports.js" + }, + "./tokenExchangeProfiles": { + "import": { + "types": "./dist/esm/management/api/resources/tokenExchangeProfiles/exports.d.mts", + "default": "./dist/esm/management/api/resources/tokenExchangeProfiles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/tokenExchangeProfiles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/tokenExchangeProfiles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/tokenExchangeProfiles/exports.js" + }, + "./userAttributeProfiles": { + "import": { + "types": "./dist/esm/management/api/resources/userAttributeProfiles/exports.d.mts", + "default": "./dist/esm/management/api/resources/userAttributeProfiles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/userAttributeProfiles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/userAttributeProfiles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/userAttributeProfiles/exports.js" + }, + "./userBlocks": { + "import": { + "types": "./dist/esm/management/api/resources/userBlocks/exports.d.mts", + "default": "./dist/esm/management/api/resources/userBlocks/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/userBlocks/exports.d.ts", + "default": "./dist/cjs/management/api/resources/userBlocks/exports.js" + }, + "default": "./dist/cjs/management/api/resources/userBlocks/exports.js" + }, + "./users": { + "import": { + "types": "./dist/esm/management/api/resources/users/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/exports.js" + }, + "./actions/versions": { + "import": { + "types": "./dist/esm/management/api/resources/actions/resources/versions/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/resources/versions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/resources/versions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/resources/versions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/resources/versions/exports.js" + }, + "./actions/executions": { + "import": { + "types": "./dist/esm/management/api/resources/actions/resources/executions/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/resources/executions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/resources/executions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/resources/executions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/resources/executions/exports.js" + }, + "./actions/modules": { + "import": { + "types": "./dist/esm/management/api/resources/actions/resources/modules/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/resources/modules/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/resources/modules/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/resources/modules/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/resources/modules/exports.js" + }, + "./actions/triggers": { + "import": { + "types": "./dist/esm/management/api/resources/actions/resources/triggers/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/resources/triggers/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/resources/triggers/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/resources/triggers/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/resources/triggers/exports.js" + }, + "./actions/modules/versions": { + "import": { + "types": "./dist/esm/management/api/resources/actions/resources/modules/resources/versions/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/resources/modules/resources/versions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/resources/modules/resources/versions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/resources/modules/resources/versions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/resources/modules/resources/versions/exports.js" + }, + "./actions/triggers/bindings": { + "import": { + "types": "./dist/esm/management/api/resources/actions/resources/triggers/resources/bindings/exports.d.mts", + "default": "./dist/esm/management/api/resources/actions/resources/triggers/resources/bindings/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/actions/resources/triggers/resources/bindings/exports.d.ts", + "default": "./dist/cjs/management/api/resources/actions/resources/triggers/resources/bindings/exports.js" + }, + "default": "./dist/cjs/management/api/resources/actions/resources/triggers/resources/bindings/exports.js" + }, + "./anomaly": { + "import": { + "types": "./dist/esm/management/api/resources/anomaly/exports.d.mts", + "default": "./dist/esm/management/api/resources/anomaly/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/anomaly/exports.d.ts", + "default": "./dist/cjs/management/api/resources/anomaly/exports.js" + }, + "default": "./dist/cjs/management/api/resources/anomaly/exports.js" + }, + "./anomaly/blocks": { + "import": { + "types": "./dist/esm/management/api/resources/anomaly/resources/blocks/exports.d.mts", + "default": "./dist/esm/management/api/resources/anomaly/resources/blocks/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/anomaly/resources/blocks/exports.d.ts", + "default": "./dist/cjs/management/api/resources/anomaly/resources/blocks/exports.js" + }, + "default": "./dist/cjs/management/api/resources/anomaly/resources/blocks/exports.js" + }, + "./attackProtection": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/exports.js" + }, + "./attackProtection/botDetection": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/resources/botDetection/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/resources/botDetection/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/resources/botDetection/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/resources/botDetection/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/resources/botDetection/exports.js" + }, + "./attackProtection/breachedPasswordDetection": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/resources/breachedPasswordDetection/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/resources/breachedPasswordDetection/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/resources/breachedPasswordDetection/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/resources/breachedPasswordDetection/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/resources/breachedPasswordDetection/exports.js" + }, + "./attackProtection/bruteForceProtection": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/resources/bruteForceProtection/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/resources/bruteForceProtection/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/resources/bruteForceProtection/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/resources/bruteForceProtection/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/resources/bruteForceProtection/exports.js" + }, + "./attackProtection/captcha": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/resources/captcha/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/resources/captcha/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/resources/captcha/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/resources/captcha/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/resources/captcha/exports.js" + }, + "./attackProtection/phoneProviderProtection": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/resources/phoneProviderProtection/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/resources/phoneProviderProtection/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/resources/phoneProviderProtection/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/resources/phoneProviderProtection/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/resources/phoneProviderProtection/exports.js" + }, + "./attackProtection/suspiciousIpThrottling": { + "import": { + "types": "./dist/esm/management/api/resources/attackProtection/resources/suspiciousIpThrottling/exports.d.mts", + "default": "./dist/esm/management/api/resources/attackProtection/resources/suspiciousIpThrottling/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/attackProtection/resources/suspiciousIpThrottling/exports.d.ts", + "default": "./dist/cjs/management/api/resources/attackProtection/resources/suspiciousIpThrottling/exports.js" + }, + "default": "./dist/cjs/management/api/resources/attackProtection/resources/suspiciousIpThrottling/exports.js" + }, + "./branding/templates": { + "import": { + "types": "./dist/esm/management/api/resources/branding/resources/templates/exports.d.mts", + "default": "./dist/esm/management/api/resources/branding/resources/templates/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/branding/resources/templates/exports.d.ts", + "default": "./dist/cjs/management/api/resources/branding/resources/templates/exports.js" + }, + "default": "./dist/cjs/management/api/resources/branding/resources/templates/exports.js" + }, + "./branding/themes": { + "import": { + "types": "./dist/esm/management/api/resources/branding/resources/themes/exports.d.mts", + "default": "./dist/esm/management/api/resources/branding/resources/themes/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/branding/resources/themes/exports.d.ts", + "default": "./dist/cjs/management/api/resources/branding/resources/themes/exports.js" + }, + "default": "./dist/cjs/management/api/resources/branding/resources/themes/exports.js" + }, + "./branding/phone": { + "import": { + "types": "./dist/esm/management/api/resources/branding/resources/phone/exports.d.mts", + "default": "./dist/esm/management/api/resources/branding/resources/phone/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/branding/resources/phone/exports.d.ts", + "default": "./dist/cjs/management/api/resources/branding/resources/phone/exports.js" + }, + "default": "./dist/cjs/management/api/resources/branding/resources/phone/exports.js" + }, + "./branding/phone/providers": { + "import": { + "types": "./dist/esm/management/api/resources/branding/resources/phone/resources/providers/exports.d.mts", + "default": "./dist/esm/management/api/resources/branding/resources/phone/resources/providers/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/branding/resources/phone/resources/providers/exports.d.ts", + "default": "./dist/cjs/management/api/resources/branding/resources/phone/resources/providers/exports.js" + }, + "default": "./dist/cjs/management/api/resources/branding/resources/phone/resources/providers/exports.js" + }, + "./branding/phone/templates": { + "import": { + "types": "./dist/esm/management/api/resources/branding/resources/phone/resources/templates/exports.d.mts", + "default": "./dist/esm/management/api/resources/branding/resources/phone/resources/templates/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/branding/resources/phone/resources/templates/exports.d.ts", + "default": "./dist/cjs/management/api/resources/branding/resources/phone/resources/templates/exports.js" + }, + "default": "./dist/cjs/management/api/resources/branding/resources/phone/resources/templates/exports.js" + }, + "./clientGrants/organizations": { + "import": { + "types": "./dist/esm/management/api/resources/clientGrants/resources/organizations/exports.d.mts", + "default": "./dist/esm/management/api/resources/clientGrants/resources/organizations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/clientGrants/resources/organizations/exports.d.ts", + "default": "./dist/cjs/management/api/resources/clientGrants/resources/organizations/exports.js" + }, + "default": "./dist/cjs/management/api/resources/clientGrants/resources/organizations/exports.js" + }, + "./clients/credentials": { + "import": { + "types": "./dist/esm/management/api/resources/clients/resources/credentials/exports.d.mts", + "default": "./dist/esm/management/api/resources/clients/resources/credentials/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/clients/resources/credentials/exports.d.ts", + "default": "./dist/cjs/management/api/resources/clients/resources/credentials/exports.js" + }, + "default": "./dist/cjs/management/api/resources/clients/resources/credentials/exports.js" + }, + "./clients/connections": { + "import": { + "types": "./dist/esm/management/api/resources/clients/resources/connections/exports.d.mts", + "default": "./dist/esm/management/api/resources/clients/resources/connections/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/clients/resources/connections/exports.d.ts", + "default": "./dist/cjs/management/api/resources/clients/resources/connections/exports.js" + }, + "default": "./dist/cjs/management/api/resources/clients/resources/connections/exports.js" + }, + "./connections/directoryProvisioning": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/directoryProvisioning/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/directoryProvisioning/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/directoryProvisioning/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/directoryProvisioning/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/directoryProvisioning/exports.js" + }, + "./connections/scimConfiguration": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/scimConfiguration/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/scimConfiguration/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/scimConfiguration/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/scimConfiguration/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/scimConfiguration/exports.js" + }, + "./connections/clients": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/clients/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/clients/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/clients/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/clients/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/clients/exports.js" + }, + "./connections/keys": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/keys/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/keys/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/keys/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/keys/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/keys/exports.js" + }, + "./connections/users": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/users/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/users/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/users/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/users/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/users/exports.js" + }, + "./connections/directoryProvisioning/synchronizations": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/directoryProvisioning/resources/synchronizations/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/directoryProvisioning/resources/synchronizations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/directoryProvisioning/resources/synchronizations/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/directoryProvisioning/resources/synchronizations/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/directoryProvisioning/resources/synchronizations/exports.js" + }, + "./connections/scimConfiguration/tokens": { + "import": { + "types": "./dist/esm/management/api/resources/connections/resources/scimConfiguration/resources/tokens/exports.d.mts", + "default": "./dist/esm/management/api/resources/connections/resources/scimConfiguration/resources/tokens/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/connections/resources/scimConfiguration/resources/tokens/exports.d.ts", + "default": "./dist/cjs/management/api/resources/connections/resources/scimConfiguration/resources/tokens/exports.js" + }, + "default": "./dist/cjs/management/api/resources/connections/resources/scimConfiguration/resources/tokens/exports.js" + }, + "./emails": { + "import": { + "types": "./dist/esm/management/api/resources/emails/exports.d.mts", + "default": "./dist/esm/management/api/resources/emails/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/emails/exports.d.ts", + "default": "./dist/cjs/management/api/resources/emails/exports.js" + }, + "default": "./dist/cjs/management/api/resources/emails/exports.js" + }, + "./emails/provider": { + "import": { + "types": "./dist/esm/management/api/resources/emails/resources/provider/exports.d.mts", + "default": "./dist/esm/management/api/resources/emails/resources/provider/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/emails/resources/provider/exports.d.ts", + "default": "./dist/cjs/management/api/resources/emails/resources/provider/exports.js" + }, + "default": "./dist/cjs/management/api/resources/emails/resources/provider/exports.js" + }, + "./eventStreams/deliveries": { + "import": { + "types": "./dist/esm/management/api/resources/eventStreams/resources/deliveries/exports.d.mts", + "default": "./dist/esm/management/api/resources/eventStreams/resources/deliveries/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/eventStreams/resources/deliveries/exports.d.ts", + "default": "./dist/cjs/management/api/resources/eventStreams/resources/deliveries/exports.js" + }, + "default": "./dist/cjs/management/api/resources/eventStreams/resources/deliveries/exports.js" + }, + "./eventStreams/redeliveries": { + "import": { + "types": "./dist/esm/management/api/resources/eventStreams/resources/redeliveries/exports.d.mts", + "default": "./dist/esm/management/api/resources/eventStreams/resources/redeliveries/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/eventStreams/resources/redeliveries/exports.d.ts", + "default": "./dist/cjs/management/api/resources/eventStreams/resources/redeliveries/exports.js" + }, + "default": "./dist/cjs/management/api/resources/eventStreams/resources/redeliveries/exports.js" + }, + "./experimentation": { + "import": { + "types": "./dist/esm/management/api/resources/experimentation/exports.d.mts", + "default": "./dist/esm/management/api/resources/experimentation/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/experimentation/exports.d.ts", + "default": "./dist/cjs/management/api/resources/experimentation/exports.js" + }, + "default": "./dist/cjs/management/api/resources/experimentation/exports.js" + }, + "./experimentation/experiments": { + "import": { + "types": "./dist/esm/management/api/resources/experimentation/resources/experiments/exports.d.mts", + "default": "./dist/esm/management/api/resources/experimentation/resources/experiments/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/experimentation/resources/experiments/exports.d.ts", + "default": "./dist/cjs/management/api/resources/experimentation/resources/experiments/exports.js" + }, + "default": "./dist/cjs/management/api/resources/experimentation/resources/experiments/exports.js" + }, + "./experimentation/featureFlags": { + "import": { + "types": "./dist/esm/management/api/resources/experimentation/resources/featureFlags/exports.d.mts", + "default": "./dist/esm/management/api/resources/experimentation/resources/featureFlags/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/experimentation/resources/featureFlags/exports.d.ts", + "default": "./dist/cjs/management/api/resources/experimentation/resources/featureFlags/exports.js" + }, + "default": "./dist/cjs/management/api/resources/experimentation/resources/featureFlags/exports.js" + }, + "./experimentation/segments": { + "import": { + "types": "./dist/esm/management/api/resources/experimentation/resources/segments/exports.d.mts", + "default": "./dist/esm/management/api/resources/experimentation/resources/segments/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/experimentation/resources/segments/exports.d.ts", + "default": "./dist/cjs/management/api/resources/experimentation/resources/segments/exports.js" + }, + "default": "./dist/cjs/management/api/resources/experimentation/resources/segments/exports.js" + }, + "./experimentation/featureFlags/variations": { + "import": { + "types": "./dist/esm/management/api/resources/experimentation/resources/featureFlags/resources/variations/exports.d.mts", + "default": "./dist/esm/management/api/resources/experimentation/resources/featureFlags/resources/variations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/experimentation/resources/featureFlags/resources/variations/exports.d.ts", + "default": "./dist/cjs/management/api/resources/experimentation/resources/featureFlags/resources/variations/exports.js" + }, + "default": "./dist/cjs/management/api/resources/experimentation/resources/featureFlags/resources/variations/exports.js" + }, + "./flows/executions": { + "import": { + "types": "./dist/esm/management/api/resources/flows/resources/executions/exports.d.mts", + "default": "./dist/esm/management/api/resources/flows/resources/executions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/flows/resources/executions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/flows/resources/executions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/flows/resources/executions/exports.js" + }, + "./flows/vault": { + "import": { + "types": "./dist/esm/management/api/resources/flows/resources/vault/exports.d.mts", + "default": "./dist/esm/management/api/resources/flows/resources/vault/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/flows/resources/vault/exports.d.ts", + "default": "./dist/cjs/management/api/resources/flows/resources/vault/exports.js" + }, + "default": "./dist/cjs/management/api/resources/flows/resources/vault/exports.js" + }, + "./flows/vault/connections": { + "import": { + "types": "./dist/esm/management/api/resources/flows/resources/vault/resources/connections/exports.d.mts", + "default": "./dist/esm/management/api/resources/flows/resources/vault/resources/connections/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/flows/resources/vault/resources/connections/exports.d.ts", + "default": "./dist/cjs/management/api/resources/flows/resources/vault/resources/connections/exports.js" + }, + "default": "./dist/cjs/management/api/resources/flows/resources/vault/resources/connections/exports.js" + }, + "./groups/members": { + "import": { + "types": "./dist/esm/management/api/resources/groups/resources/members/exports.d.mts", + "default": "./dist/esm/management/api/resources/groups/resources/members/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/groups/resources/members/exports.d.ts", + "default": "./dist/cjs/management/api/resources/groups/resources/members/exports.js" + }, + "default": "./dist/cjs/management/api/resources/groups/resources/members/exports.js" + }, + "./groups/roles": { + "import": { + "types": "./dist/esm/management/api/resources/groups/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/groups/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/groups/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/groups/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/groups/resources/roles/exports.js" + }, + "./guardian/enrollments": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/enrollments/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/enrollments/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/enrollments/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/enrollments/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/enrollments/exports.js" + }, + "./guardian/factors": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/exports.js" + }, + "./guardian/policies": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/policies/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/policies/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/policies/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/policies/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/policies/exports.js" + }, + "./guardian/factors/email": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/resources/email/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/resources/email/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/email/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/email/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/email/exports.js" + }, + "./guardian/factors/phone": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/resources/phone/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/resources/phone/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/phone/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/phone/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/phone/exports.js" + }, + "./guardian/factors/pushNotification": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/resources/pushNotification/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/resources/pushNotification/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/pushNotification/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/pushNotification/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/pushNotification/exports.js" + }, + "./guardian/factors/sms": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/resources/sms/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/resources/sms/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/sms/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/sms/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/sms/exports.js" + }, + "./guardian/factors/duo": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/resources/duo/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/resources/duo/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/duo/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/duo/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/duo/exports.js" + }, + "./guardian/factors/duo/settings": { + "import": { + "types": "./dist/esm/management/api/resources/guardian/resources/factors/resources/duo/resources/settings/exports.d.mts", + "default": "./dist/esm/management/api/resources/guardian/resources/factors/resources/duo/resources/settings/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/duo/resources/settings/exports.d.ts", + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/duo/resources/settings/exports.js" + }, + "default": "./dist/cjs/management/api/resources/guardian/resources/factors/resources/duo/resources/settings/exports.js" + }, + "./hooks/secrets": { + "import": { + "types": "./dist/esm/management/api/resources/hooks/resources/secrets/exports.d.mts", + "default": "./dist/esm/management/api/resources/hooks/resources/secrets/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/hooks/resources/secrets/exports.d.ts", + "default": "./dist/cjs/management/api/resources/hooks/resources/secrets/exports.js" + }, + "default": "./dist/cjs/management/api/resources/hooks/resources/secrets/exports.js" + }, + "./jobs/usersExports": { + "import": { + "types": "./dist/esm/management/api/resources/jobs/resources/usersExports/exports.d.mts", + "default": "./dist/esm/management/api/resources/jobs/resources/usersExports/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/jobs/resources/usersExports/exports.d.ts", + "default": "./dist/cjs/management/api/resources/jobs/resources/usersExports/exports.js" + }, + "default": "./dist/cjs/management/api/resources/jobs/resources/usersExports/exports.js" + }, + "./jobs/usersImports": { + "import": { + "types": "./dist/esm/management/api/resources/jobs/resources/usersImports/exports.d.mts", + "default": "./dist/esm/management/api/resources/jobs/resources/usersImports/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/jobs/resources/usersImports/exports.d.ts", + "default": "./dist/cjs/management/api/resources/jobs/resources/usersImports/exports.js" + }, + "default": "./dist/cjs/management/api/resources/jobs/resources/usersImports/exports.js" + }, + "./jobs/verificationEmail": { + "import": { + "types": "./dist/esm/management/api/resources/jobs/resources/verificationEmail/exports.d.mts", + "default": "./dist/esm/management/api/resources/jobs/resources/verificationEmail/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/jobs/resources/verificationEmail/exports.d.ts", + "default": "./dist/cjs/management/api/resources/jobs/resources/verificationEmail/exports.js" + }, + "default": "./dist/cjs/management/api/resources/jobs/resources/verificationEmail/exports.js" + }, + "./jobs/errors": { + "import": { + "types": "./dist/esm/management/api/resources/jobs/resources/errors/exports.d.mts", + "default": "./dist/esm/management/api/resources/jobs/resources/errors/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/jobs/resources/errors/exports.d.ts", + "default": "./dist/cjs/management/api/resources/jobs/resources/errors/exports.js" + }, + "default": "./dist/cjs/management/api/resources/jobs/resources/errors/exports.js" + }, + "./keys": { + "import": { + "types": "./dist/esm/management/api/resources/keys/exports.d.mts", + "default": "./dist/esm/management/api/resources/keys/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/keys/exports.d.ts", + "default": "./dist/cjs/management/api/resources/keys/exports.js" + }, + "default": "./dist/cjs/management/api/resources/keys/exports.js" + }, + "./keys/customSigning": { + "import": { + "types": "./dist/esm/management/api/resources/keys/resources/customSigning/exports.d.mts", + "default": "./dist/esm/management/api/resources/keys/resources/customSigning/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/keys/resources/customSigning/exports.d.ts", + "default": "./dist/cjs/management/api/resources/keys/resources/customSigning/exports.js" + }, + "default": "./dist/cjs/management/api/resources/keys/resources/customSigning/exports.js" + }, + "./keys/encryption": { + "import": { + "types": "./dist/esm/management/api/resources/keys/resources/encryption/exports.d.mts", + "default": "./dist/esm/management/api/resources/keys/resources/encryption/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/keys/resources/encryption/exports.d.ts", + "default": "./dist/cjs/management/api/resources/keys/resources/encryption/exports.js" + }, + "default": "./dist/cjs/management/api/resources/keys/resources/encryption/exports.js" + }, + "./keys/networkAcls": { + "import": { + "types": "./dist/esm/management/api/resources/keys/resources/networkAcls/exports.d.mts", + "default": "./dist/esm/management/api/resources/keys/resources/networkAcls/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/keys/resources/networkAcls/exports.d.ts", + "default": "./dist/cjs/management/api/resources/keys/resources/networkAcls/exports.js" + }, + "default": "./dist/cjs/management/api/resources/keys/resources/networkAcls/exports.js" + }, + "./keys/signing": { + "import": { + "types": "./dist/esm/management/api/resources/keys/resources/signing/exports.d.mts", + "default": "./dist/esm/management/api/resources/keys/resources/signing/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/keys/resources/signing/exports.d.ts", + "default": "./dist/cjs/management/api/resources/keys/resources/signing/exports.js" + }, + "default": "./dist/cjs/management/api/resources/keys/resources/signing/exports.js" + }, + "./organizations/clientGrants": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/clientGrants/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/clientGrants/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/clientGrants/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/clientGrants/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/clientGrants/exports.js" + }, + "./organizations/clients": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/clients/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/clients/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/clients/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/clients/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/clients/exports.js" + }, + "./organizations/connections": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/connections/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/connections/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/connections/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/connections/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/connections/exports.js" + }, + "./organizations/discoveryDomains": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/discoveryDomains/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/discoveryDomains/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/discoveryDomains/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/discoveryDomains/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/discoveryDomains/exports.js" + }, + "./organizations/enabledConnections": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/enabledConnections/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/enabledConnections/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/enabledConnections/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/enabledConnections/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/enabledConnections/exports.js" + }, + "./organizations/invitations": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/invitations/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/invitations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/invitations/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/invitations/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/invitations/exports.js" + }, + "./organizations/members": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/members/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/members/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/members/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/members/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/members/exports.js" + }, + "./organizations/groups": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/groups/exports.js" + }, + "./organizations/groups/roles": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/groups/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/groups/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/groups/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/groups/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/groups/resources/roles/exports.js" + }, + "./organizations/members/effectiveRoles": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/members/resources/effectiveRoles/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/members/resources/effectiveRoles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/exports.js" + }, + "./organizations/members/roles": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/members/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/members/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/members/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/roles/exports.js" + }, + "./organizations/members/effectiveRoles/sources": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/exports.js" + }, + "./organizations/members/effectiveRoles/sources/groups": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/members/resources/effectiveRoles/resources/sources/resources/groups/exports.js" + }, + "./organizations/roles": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/roles/exports.js" + }, + "./organizations/roles/members": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/roles/resources/members/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/roles/resources/members/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/roles/resources/members/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/roles/resources/members/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/roles/resources/members/exports.js" + }, + "./organizations/roles/groups": { + "import": { + "types": "./dist/esm/management/api/resources/organizations/resources/roles/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/organizations/resources/roles/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/organizations/resources/roles/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/organizations/resources/roles/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/organizations/resources/roles/resources/groups/exports.js" + }, + "./prompts/rendering": { + "import": { + "types": "./dist/esm/management/api/resources/prompts/resources/rendering/exports.d.mts", + "default": "./dist/esm/management/api/resources/prompts/resources/rendering/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/prompts/resources/rendering/exports.d.ts", + "default": "./dist/cjs/management/api/resources/prompts/resources/rendering/exports.js" + }, + "default": "./dist/cjs/management/api/resources/prompts/resources/rendering/exports.js" + }, + "./prompts/customText": { + "import": { + "types": "./dist/esm/management/api/resources/prompts/resources/customText/exports.d.mts", + "default": "./dist/esm/management/api/resources/prompts/resources/customText/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/prompts/resources/customText/exports.d.ts", + "default": "./dist/cjs/management/api/resources/prompts/resources/customText/exports.js" + }, + "default": "./dist/cjs/management/api/resources/prompts/resources/customText/exports.js" + }, + "./prompts/partials": { + "import": { + "types": "./dist/esm/management/api/resources/prompts/resources/partials/exports.d.mts", + "default": "./dist/esm/management/api/resources/prompts/resources/partials/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/prompts/resources/partials/exports.d.ts", + "default": "./dist/cjs/management/api/resources/prompts/resources/partials/exports.js" + }, + "default": "./dist/cjs/management/api/resources/prompts/resources/partials/exports.js" + }, + "./riskAssessments": { + "import": { + "types": "./dist/esm/management/api/resources/riskAssessments/exports.d.mts", + "default": "./dist/esm/management/api/resources/riskAssessments/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/riskAssessments/exports.d.ts", + "default": "./dist/cjs/management/api/resources/riskAssessments/exports.js" + }, + "default": "./dist/cjs/management/api/resources/riskAssessments/exports.js" + }, + "./riskAssessments/settings": { + "import": { + "types": "./dist/esm/management/api/resources/riskAssessments/resources/settings/exports.d.mts", + "default": "./dist/esm/management/api/resources/riskAssessments/resources/settings/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/riskAssessments/resources/settings/exports.d.ts", + "default": "./dist/cjs/management/api/resources/riskAssessments/resources/settings/exports.js" + }, + "default": "./dist/cjs/management/api/resources/riskAssessments/resources/settings/exports.js" + }, + "./riskAssessments/settings/newDevice": { + "import": { + "types": "./dist/esm/management/api/resources/riskAssessments/resources/settings/resources/newDevice/exports.d.mts", + "default": "./dist/esm/management/api/resources/riskAssessments/resources/settings/resources/newDevice/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/riskAssessments/resources/settings/resources/newDevice/exports.d.ts", + "default": "./dist/cjs/management/api/resources/riskAssessments/resources/settings/resources/newDevice/exports.js" + }, + "default": "./dist/cjs/management/api/resources/riskAssessments/resources/settings/resources/newDevice/exports.js" + }, + "./roles/groups": { + "import": { + "types": "./dist/esm/management/api/resources/roles/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/roles/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/roles/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/roles/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/roles/resources/groups/exports.js" + }, + "./roles/permissions": { + "import": { + "types": "./dist/esm/management/api/resources/roles/resources/permissions/exports.d.mts", + "default": "./dist/esm/management/api/resources/roles/resources/permissions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/roles/resources/permissions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/roles/resources/permissions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/roles/resources/permissions/exports.js" + }, + "./roles/users": { + "import": { + "types": "./dist/esm/management/api/resources/roles/resources/users/exports.d.mts", + "default": "./dist/esm/management/api/resources/roles/resources/users/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/roles/resources/users/exports.d.ts", + "default": "./dist/cjs/management/api/resources/roles/resources/users/exports.js" + }, + "default": "./dist/cjs/management/api/resources/roles/resources/users/exports.js" + }, + "./selfServiceProfiles/customText": { + "import": { + "types": "./dist/esm/management/api/resources/selfServiceProfiles/resources/customText/exports.d.mts", + "default": "./dist/esm/management/api/resources/selfServiceProfiles/resources/customText/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/selfServiceProfiles/resources/customText/exports.d.ts", + "default": "./dist/cjs/management/api/resources/selfServiceProfiles/resources/customText/exports.js" + }, + "default": "./dist/cjs/management/api/resources/selfServiceProfiles/resources/customText/exports.js" + }, + "./selfServiceProfiles/ssoTicket": { + "import": { + "types": "./dist/esm/management/api/resources/selfServiceProfiles/resources/ssoTicket/exports.d.mts", + "default": "./dist/esm/management/api/resources/selfServiceProfiles/resources/ssoTicket/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/selfServiceProfiles/resources/ssoTicket/exports.d.ts", + "default": "./dist/cjs/management/api/resources/selfServiceProfiles/resources/ssoTicket/exports.js" + }, + "default": "./dist/cjs/management/api/resources/selfServiceProfiles/resources/ssoTicket/exports.js" + }, + "./tenants": { + "import": { + "types": "./dist/esm/management/api/resources/tenants/exports.d.mts", + "default": "./dist/esm/management/api/resources/tenants/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/tenants/exports.d.ts", + "default": "./dist/cjs/management/api/resources/tenants/exports.js" + }, + "default": "./dist/cjs/management/api/resources/tenants/exports.js" + }, + "./tenants/settings": { + "import": { + "types": "./dist/esm/management/api/resources/tenants/resources/settings/exports.d.mts", + "default": "./dist/esm/management/api/resources/tenants/resources/settings/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/tenants/resources/settings/exports.d.ts", + "default": "./dist/cjs/management/api/resources/tenants/resources/settings/exports.js" + }, + "default": "./dist/cjs/management/api/resources/tenants/resources/settings/exports.js" + }, + "./users/authenticationMethods": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/authenticationMethods/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/authenticationMethods/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/authenticationMethods/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/authenticationMethods/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/authenticationMethods/exports.js" + }, + "./users/authenticators": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/authenticators/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/authenticators/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/authenticators/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/authenticators/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/authenticators/exports.js" + }, + "./users/connectedAccounts": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/connectedAccounts/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/connectedAccounts/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/connectedAccounts/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/connectedAccounts/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/connectedAccounts/exports.js" + }, + "./users/effectivePermissions": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/effectivePermissions/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/effectivePermissions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/exports.js" + }, + "./users/effectiveRoles": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/effectiveRoles/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/effectiveRoles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/exports.js" + }, + "./users/enrollments": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/enrollments/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/enrollments/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/enrollments/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/enrollments/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/enrollments/exports.js" + }, + "./users/groups": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/groups/exports.js" + }, + "./users/identities": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/identities/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/identities/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/identities/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/identities/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/identities/exports.js" + }, + "./users/logs": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/logs/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/logs/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/logs/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/logs/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/logs/exports.js" + }, + "./users/multifactor": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/multifactor/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/multifactor/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/multifactor/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/multifactor/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/multifactor/exports.js" + }, + "./users/organizations": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/organizations/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/organizations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/organizations/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/organizations/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/organizations/exports.js" + }, + "./users/permissions": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/permissions/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/permissions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/permissions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/permissions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/permissions/exports.js" + }, + "./users/riskAssessments": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/riskAssessments/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/riskAssessments/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/riskAssessments/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/riskAssessments/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/riskAssessments/exports.js" + }, + "./users/roles": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/roles/exports.js" + }, + "./users/refreshToken": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/refreshToken/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/refreshToken/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/refreshToken/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/refreshToken/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/refreshToken/exports.js" + }, + "./users/sessions": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/sessions/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/sessions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/sessions/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/sessions/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/sessions/exports.js" + }, + "./users/effectivePermissions/sources": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/effectivePermissions/resources/sources/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/effectivePermissions/resources/sources/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/resources/sources/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/resources/sources/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/resources/sources/exports.js" + }, + "./users/effectivePermissions/sources/roles": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/effectivePermissions/resources/sources/resources/roles/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/effectivePermissions/resources/sources/resources/roles/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/resources/sources/resources/roles/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/resources/sources/resources/roles/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/effectivePermissions/resources/sources/resources/roles/exports.js" + }, + "./users/effectiveRoles/sources": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/effectiveRoles/resources/sources/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/effectiveRoles/resources/sources/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/resources/sources/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/resources/sources/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/resources/sources/exports.js" + }, + "./users/effectiveRoles/sources/groups": { + "import": { + "types": "./dist/esm/management/api/resources/users/resources/effectiveRoles/resources/sources/resources/groups/exports.d.mts", + "default": "./dist/esm/management/api/resources/users/resources/effectiveRoles/resources/sources/resources/groups/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/resources/sources/resources/groups/exports.d.ts", + "default": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/resources/sources/resources/groups/exports.js" + }, + "default": "./dist/cjs/management/api/resources/users/resources/effectiveRoles/resources/sources/resources/groups/exports.js" + }, + "./verifiableCredentials": { + "import": { + "types": "./dist/esm/management/api/resources/verifiableCredentials/exports.d.mts", + "default": "./dist/esm/management/api/resources/verifiableCredentials/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/verifiableCredentials/exports.d.ts", + "default": "./dist/cjs/management/api/resources/verifiableCredentials/exports.js" + }, + "default": "./dist/cjs/management/api/resources/verifiableCredentials/exports.js" + }, + "./verifiableCredentials/verification": { + "import": { + "types": "./dist/esm/management/api/resources/verifiableCredentials/resources/verification/exports.d.mts", + "default": "./dist/esm/management/api/resources/verifiableCredentials/resources/verification/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/verifiableCredentials/resources/verification/exports.d.ts", + "default": "./dist/cjs/management/api/resources/verifiableCredentials/resources/verification/exports.js" + }, + "default": "./dist/cjs/management/api/resources/verifiableCredentials/resources/verification/exports.js" + }, + "./verifiableCredentials/verification/templates": { + "import": { + "types": "./dist/esm/management/api/resources/verifiableCredentials/resources/verification/resources/templates/exports.d.mts", + "default": "./dist/esm/management/api/resources/verifiableCredentials/resources/verification/resources/templates/exports.mjs" + }, + "require": { + "types": "./dist/cjs/management/api/resources/verifiableCredentials/resources/verification/resources/templates/exports.d.ts", + "default": "./dist/cjs/management/api/resources/verifiableCredentials/resources/verification/resources/templates/exports.js" + }, + "default": "./dist/cjs/management/api/resources/verifiableCredentials/resources/verification/resources/templates/exports.js" + }, + "./package.json": "./package.json", + "./legacy": { + "types": "./legacy/exports/index.d.ts", + "import": { + "types": "./legacy/exports/index.d.mts", + "default": "./legacy/exports/index.mjs" + }, + "require": { + "types": "./legacy/exports/index.d.ts", + "default": "./legacy/exports/index.js" + } + }, + "./management": { + "import": { + "types": "./dist/esm/management/index.d.mts", + "default": "./dist/esm/management/index.mjs" + }, + "require": { + "types": "./dist/cjs/management/index.d.ts", + "default": "./dist/cjs/management/index.js" + }, + "default": "./dist/cjs/management/index.js" + } + }, + "files": [ + "legacy", + "package.json", + "dist", + "reference.md", + "README.md", + "LICENSE" + ], + "scripts": { + "format": "prettier . --write --ignore-unknown", + "format:check": "prettier . --check --ignore-unknown", + "lint": "eslint . --ext .js,.ts,.tsx", + "lint:fix": "eslint . --ext .js,.ts,.tsx --fix", + "check": "yarn format:check", + "check:fix": "yarn format", + "build": "yarn build:cjs && yarn build:esm", + "build:cjs": "tsc --project ./tsconfig.cjs.json", + "build:esm": "tsc --project ./tsconfig.esm.json && node scripts/rename-to-esm-files.js dist/esm", + "test": "jest --config jest.config.mjs", + "test:unit": "jest --selectProjects unit", + "test:wire": "jest --selectProjects wire", + "prepare": "husky", + "lint:check": "eslint . --ext .js,.ts,.tsx", + "lint:package": "publint --pack npm", + "test:coverage": "jest --config jest.config.mjs --coverage", + "test:coverage:unit": "jest --selectProjects unit --coverage", + "test:coverage:browser": "jest --selectProjects browser --coverage", + "test:coverage:wire": "jest --selectProjects wire --coverage", + "docs": "typedoc", + "docs:clean": "rm -rf docs", + "docs:build": "yarn docs:clean && yarn docs", + "precommit": "lint-staged", + "validate": "yarn lint:check && yarn format --check && yarn build && yarn test && yarn lint:package" + }, + "dependencies": { + "uuid": "^11.1.1", + "jose": "^5.0.0", + "auth0-legacy": "npm:auth0@^4.37.1" + }, + "devDependencies": { + "webpack": "^5.105.4", + "ts-loader": "^9.5.4", + "jest": "^29.7.0", + "@jest/globals": "^29.7.0", + "@types/jest": "^29.5.14", + "ts-jest": "^29.3.4", + "jest-environment-jsdom": "^29.7.0", + "msw": "2.11.2", + "@types/node": "^20.0.0", + "typescript": "~5.9.3", + "prettier": "3.8.1", + "typedoc": "^0.28.7", + "typedoc-plugin-missing-exports": "^4.0.0", + "nock": "^14.0.6", + "undici": "^7.12.0", + "@eslint/js": "^9.32.0", + "@typescript-eslint/eslint-plugin": "^8.38.0", + "@typescript-eslint/parser": "^8.38.0", + "eslint": "^9.32.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.3", + "husky": "^9.1.7", + "lint-staged": "^16.1.4", + "publint": "^0.3.12" + }, + "browser": { + "fs": false, + "os": false, + "path": false, + "stream": false, + "crypto": false + }, + "packageManager": "yarn@1.22.22", + "engines": { + "node": "^20.19.0 || ^22.12.0 || ^24.0.0 || ^26.0.0" + }, + "sideEffects": false, + "bugs": { + "url": "https://github.com/auth0/node-auth0/issues" + }, + "homepage": "https://github.com/auth0/node-auth0", + "keywords": [ + "auth0", + "authentication", + "login", + "auth", + "jwt", + "management api", + "json web token" + ], + "description": "Auth0 Node.js SDK for the Management API v2.", + "lint-staged": { + "*.{js,ts,tsx}": [ + "eslint --fix", + "prettier --write" + ], + "*.{json,md,yml,yaml}": [ + "prettier --write" + ] + } + } + src/management/version.ts: | + export const SDK_VERSION = "7.6.0"; + status: unresolved diff --git a/.shiprc b/.shiprc new file mode 100644 index 0000000000..d1791e98e5 --- /dev/null +++ b/.shiprc @@ -0,0 +1,6 @@ +{ + "files": { + ".version": [], + "src/management/version.ts": [] + } +} diff --git a/AUTH_MIGRATION_GUIDE.md b/AUTH_MIGRATION_GUIDE.md new file mode 100644 index 0000000000..64626f8067 --- /dev/null +++ b/AUTH_MIGRATION_GUIDE.md @@ -0,0 +1,14 @@ +# Authentication Migration Guide + +This guide lives in the [`auth-migration/`](./auth-migration/) directory. + +**→ Start here: [`auth-migration/index.md`](./auth-migration/index.md)**: migrate your authentication code off the `auth0` package to [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js) (stateless token grants) or [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js) (server-managed sessions). + +The directory contains: + +- [`auth-migration/index.md`](./auth-migration/index.md): the main guide covering OIDC token grants and the four cross-cutting breaking changes. +- [`auth-migration/authentication-flows.md`](./auth-migration/authentication-flows.md): database, passwordless, backchannel (CIBA), token exchange, and `UserInfoClient`. +- [`auth-migration/server-side-sessions.md`](./auth-migration/server-side-sessions.md): the `@auth0/auth0-server-js` session layer. +- [`auth-migration/troubleshooting.md`](./auth-migration/troubleshooting.md): FAQ and gotchas. + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill: the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`. diff --git a/auth-migration/authentication-flows.md b/auth-migration/authentication-flows.md new file mode 100644 index 0000000000..6f7bace2a1 --- /dev/null +++ b/auth-migration/authentication-flows.md @@ -0,0 +1,234 @@ +# Migrating the other authentication flows + +This is the incremental part of the [Authentication Migration Guide](./index.md). Start with the guide's [OIDC token grants](./index.md#oidc-token-grants) and cross-cutting breaking changes before you touch anything here. Everything below builds on those changes, so apply them to every rewrite on this page too. + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill (the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`). + +Migrate one flow at a time. Only the flows your app actually uses need attention; skip the rest. + +- [Database connections](#database-connections) +- [Passwordless](#passwordless) +- [Backchannel authentication (CIBA)](#backchannel-authentication-ciba) +- [Token exchange (RFC 8693)](#token-exchange-rfc-8693) +- [UserInfoClient](#userinfoclient) +- [Quick lookup table](#quick-lookup-table) + +Unless a row routes explicitly to `@auth0/auth0-server-js`, the replacement lives on the `@auth0/auth0-auth-js` `AuthClient` (or a sub-client: `authClient.database`, `authClient.passwordless`, `authClient.mfa`, `authClient.passkey`). + +## Database connections + +Database connection operations move to the `authClient.database` sub-client. Names and required parameters stay the same; only casing and return shape change. + +### `database.signUp` → `authClient.database.signUp` + +```ts +// before +const resp = await auth0.database.signUp({ + email, + password, + connection: "Username-Password-Authentication", + given_name: "Ada", + family_name: "Lovelace", + user_metadata: { plan: "free" }, +}); +const userId = resp.data.id; +// after +const result = await authClient.database.signUp({ + email, + password, + connection: "Username-Password-Authentication", + givenName: "Ada", + familyName: "Lovelace", + userMetadata: { plan: "free" }, +}); +const userId = result.id; +``` + +> ID normalization is preserved: node-auth0 mapped the server's `_id | user_id | id` onto a single `id`. The new SDK does the same, so `result.id` is always present. Do not add your own `_id` fallback. + +### `database.changePassword` → `authClient.database.changePassword` + +node-auth0 returned a `TextApiResponse` (read via `.data`); the new SDK returns the plain `string` directly. + +```ts +// before +const resp = await auth0.database.changePassword({ email, connection: "Username-Password-Authentication" }); +const message = resp.data; // plain-text confirmation +// after +const message = await authClient.database.changePassword({ email, connection: "Username-Password-Authentication" }); +``` + +> `changePassword` requires `connection` plus at least one of `email` or `username`: either identifier is accepted, not `email` alone. + +## Passwordless + +node-auth0 lumped "start" (send the code or link) and "login" (redeem the code) onto one sub-client. The new SDK splits them: starting stays on `authClient.passwordless`; redeeming a code becomes a top-level grant method on `AuthClient`. + +### `passwordless.sendEmail` → `authClient.passwordless.sendEmail` + +```ts +// before +await auth0.passwordless.sendEmail({ email, send: "code" }); +// after +await authClient.passwordless.sendEmail({ email, send: "code" }); +``` + +> Default changed: node-auth0 defaulted `send` to `'link'` (magic link). The new SDK defaults `send` to `'code'` (one-time password). If you relied on the implicit default to send magic links, set `send: 'link'` explicitly. + +### `passwordless.sendSMS` → `authClient.passwordless.sendSms` + +Note the casing change: `sendSMS` → `sendSms`, and `phone_number` → `phoneNumber`. + +```ts +// before +await auth0.passwordless.sendSMS({ phone_number: "+15551234567" }); +// after +await authClient.passwordless.sendSms({ phoneNumber: "+15551234567" }); +``` + +### `passwordless.loginWithEmail` → `getTokenByPasswordlessEmail` + +Redeeming the one-time password is now a grant method on `AuthClient`, not on the passwordless sub-client. + +```ts +// before +const resp = await auth0.passwordless.loginWithEmail({ email, code, audience, scope }); +const token = resp.data.access_token; +// after +const tokens = await authClient.getTokenByPasswordlessEmail({ email, code, audience, scope }); +const token = tokens.accessToken; +``` + +### `passwordless.loginWithSMS` → `getTokenByPasswordlessSms` + +```ts +// before +const resp = await auth0.passwordless.loginWithSMS({ phone_number, code }); +// after +const tokens = await authClient.getTokenByPasswordlessSms({ phoneNumber, code }); +``` + +> Session apps: `@auth0/auth0-server-js` exposes `startPasswordless` / `completePasswordless` / `completePasswordlessMagicLink`, which both send the code and establish a session. Use those instead of the two-step auth-js flow when the SDK owns the session. See [Migrating session apps](./server-side-sessions.md). + +## Backchannel authentication (CIBA) + +CIBA is Client-Initiated Backchannel Authentication. + +### `backchannel.authorize` → `initiateBackchannelAuthentication` + +```ts +// before +const resp = await auth0.backchannel.authorize({ + binding_message: "ABC123", + scope: "openid", + userId: "auth0|123", +}); +const authReqId = resp.auth_req_id; +// after +const { authReqId, expiresIn, interval } = await authClient.initiateBackchannelAuthentication({ + bindingMessage: "ABC123", + loginHint: { sub: "auth0|123" }, // login_hint is an object with `sub`, not a bare string + authorizationParams: { scope: "openid" }, // scope goes here, NOT as a top-level key +}); +``` + +### `backchannel.backchannelGrant` → `backchannelAuthenticationGrant` + +```ts +// before +const resp = await auth0.backchannel.backchannelGrant({ auth_req_id: authReqId }); +// after +const tokens = await authClient.backchannelAuthenticationGrant({ authReqId }); +``` + +> One-shot convenience: `authClient.backchannelAuthentication({ ... })` initiates and polls to completion, returning a `TokenResponse`. Use it if your code did the initiate-then-poll loop by hand. +> +> Session apps: for CIBA that also establishes a session, see [Migrating session apps](./server-side-sessions.md). + +## Token exchange (RFC 8693) + +```ts +// before +const resp = await auth0.tokenExchange.exchangeToken({ + subject_token_type: "urn:example:custom", + subject_token: token, + audience: "https://api.example.com", + scope: "read", +}); +// after +const tokens = await authClient.exchangeToken({ + subjectTokenType: "urn:example:custom", + subjectToken: token, + audience: "https://api.example.com", + scope: "read", +}); +``` + +> `exchangeToken` is overloaded: a custom-exchange profile shape (`subjectTokenType` + `subjectToken` + `audience`) and a Token Vault shape (`connection` present). Presence of `connection` routes to the vault path. The custom-exchange profile is the RFC 8693 replacement for `tokenExchange.exchangeToken`. +> +> Session apps: `@auth0/auth0-server-js` exposes `loginWithCustomTokenExchange` (exchange, then establish a session) and `customTokenExchange` (exchange, then return tokens with no session). + +## UserInfoClient + +The standalone `UserInfoClient` from node-auth0 does not exist in the new SDK. Choose the replacement based on what the app needs: + +| Your intent | Replacement | +| --- | --- | +| Wanted user profile claims right after login | Read `TokenResponse.claims` from the grant result; the SDK already decodes the ID token. No extra `/userinfo` round-trip needed. **Preferred.** | +| Wanted a live `/userinfo` response for an arbitrary access token | `await authClient.getUserInfo({ accessToken })`, a direct method on `AuthClient`. | +| Wanted the profile in a server-rendered app with a session | `await serverClient.getUser()` returns the stored user claims from the session. | + +**Before (node-auth0):** + +```ts +import { UserInfoClient } from "auth0"; +const userInfo = new UserInfoClient({ domain }); +const resp = await userInfo.getUserInfo(accessToken); +const profile = resp.data; // { sub, name, email, ... } +``` + +**After (preferred): use the claims you already have:** + +```ts +const tokens = await authClient.getTokenByCode(callbackUrl, {}); +const profile = tokens.claims; // { sub, name, email, ... } decoded from the id_token +``` + +**After (direct method):** for when you only have an access token: + +```ts +// Takes an options object: { accessToken, expectedSubject? } +const profile = await authClient.getUserInfo({ accessToken }); +``` + +> Prefer reading `claims` over any `/userinfo` call: it avoids a network round-trip and the claims are already validated by the SDK. + +## Quick lookup table + +The complete node-auth0 → new SDK map, including the OIDC methods covered in the main guide. + +| node-auth0 | new SDK equivalent | Layer | +| --- | --- | --- | +| `oauth.authorizationCodeGrant` | `authClient.getTokenByCode(url, opts)` | auth-js | +| `oauth.authorizationCodeGrantWithPKCE` | `authClient.getTokenByCode(url, { codeVerifier })` | auth-js | +| `oauth.refreshTokenGrant` | `authClient.getTokenByRefreshToken({ refreshToken })` | auth-js | +| `oauth.passwordGrant` | `authClient.getTokenByPassword({ ... })` | auth-js | +| `oauth.clientCredentialsGrant` | `authClient.getTokenByClientCredentials({ audience })` | auth-js | +| `oauth.revokeRefreshToken` | `authClient.revokeToken({ token })` / `serverClient.revokeRefreshToken()` | auth-js / server-js | +| `oauth.tokenForConnection` | `authClient.exchangeToken({ connection, ... })` | auth-js | +| `oauth.pushedAuthorization` | `authClient.buildAuthorizationUrl({ pushedAuthorizationRequests: true })` | auth-js | +| `database.signUp` | `authClient.database.signUp({ ... })` | auth-js | +| `database.changePassword` | `authClient.database.changePassword({ ... })` | auth-js | +| `passwordless.sendEmail` | `authClient.passwordless.sendEmail({ ... })` | auth-js | +| `passwordless.sendSMS` | `authClient.passwordless.sendSms({ phoneNumber })` | auth-js | +| `passwordless.loginWithEmail` | `authClient.getTokenByPasswordlessEmail({ ... })` | auth-js | +| `passwordless.loginWithSMS` | `authClient.getTokenByPasswordlessSms({ ... })` | auth-js | +| `backchannel.authorize` | `authClient.initiateBackchannelAuthentication({ ... })` | auth-js | +| `backchannel.backchannelGrant` | `authClient.backchannelAuthenticationGrant({ authReqId })` | auth-js | +| `tokenExchange.exchangeToken` | `authClient.exchangeToken({ subjectTokenType, subjectToken, audience })` | auth-js | +| `UserInfoClient.getUserInfo` | `TokenResponse.claims` (preferred) / `authClient.getUserInfo({ accessToken })` / `serverClient.getUser()` | auth-js / server-js | +| (no equivalent): build `/authorize` URL | `authClient.buildAuthorizationUrl({ ... })` | auth-js | +| (no equivalent): build `/v2/logout` URL | `authClient.buildLogoutUrl({ returnTo })` | auth-js | +| `ManagementClient.*` | **not migrated, stays on `auth0`** | n/a | + +When you finish a flow, return to the [verification checklist](./index.md#verification-checklist) and confirm the four cross-cutting changes for every call site you touched. diff --git a/auth-migration/index.md b/auth-migration/index.md new file mode 100644 index 0000000000..85a11c45c7 --- /dev/null +++ b/auth-migration/index.md @@ -0,0 +1,732 @@ +# Authentication Migration Guide + +A guide to migrating your authentication code off the `auth0` package (node-auth0) to the modern Auth0 server SDKs: [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js) for stateless token grants, and [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js) for server-managed sessions. + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill first. The skill lives in [`auth0/agent-skills`](https://github.com/auth0/agent-skills) as the `auth0` skill (migration intent: `migrate-node-auth0`). It encodes the target-SDK routing, the four cross-cutting breaking changes, the method-by-method mapping, and a build-until-green verify loop. + +## Contents + +- [How to use this guide](#how-to-use-this-guide) +- [Overview](#overview) + - [Who this is for](#who-this-is-for) + - [Scope](#scope) +- [Choosing your target SDK](#choosing-your-target-sdk) +- [Prerequisites](#prerequisites) +- [Installation and constructor mapping](#installation-and-constructor-mapping) +- [OIDC token grants](#oidc-token-grants) + - [Optional: migrate only OIDC while staying on v6](#optional-migrate-only-oidc-while-staying-on-v6) +- [Cross-cutting breaking changes](#cross-cutting-breaking-changes) + - [1. Return shape](#1-return-shape) + - [2. Casing](#2-casing) + - [3. Token expiry](#3-token-expiry) + - [4. Error model](#4-error-model) +- [Verification checklist](#verification-checklist) +- [Continue the migration](#continue-the-migration) + - [Other authentication flows](#other-authentication-flows) + - [Server-side sessions](#server-side-sessions) + - [Troubleshooting](#troubleshooting) + +## How to use this guide + +This is a reference, not a linear read. You do not have to work through it top to bottom; migrate only the flows your app actually uses, in whatever order suits you. Most apps finish after the [OIDC token grants](#oidc-token-grants) section. + +The work falls into three phases: + +| Phase | What you do | Where | +| --- | --- | --- | +| **Before**: orient and set up | Pick your target SDK, check prerequisites, install the package, map constructor options. | [Choosing your target SDK](#choosing-your-target-sdk), [Prerequisites](#prerequisites), [Installation and constructor mapping](#installation-and-constructor-mapping) | +| **During**: rewrite call sites | Rewrite the OIDC token grants (in this file), then the other flows and the session layer as needed. Apply the four cross-cutting breaking changes to every call site. | [OIDC token grants](#oidc-token-grants), [Cross-cutting breaking changes](#cross-cutting-breaking-changes), [`authentication-flows.md`](./authentication-flows.md), [`server-side-sessions.md`](./server-side-sessions.md) | +| **After**: verify | Run the build-until-green checklist; confirm no residue and that `ManagementClient` code is untouched. | [Verification checklist](#verification-checklist) | + +Suggested order: start with the OIDC grants and cross-cutting changes (the whole job for most apps), then the [other flows](./authentication-flows.md) you actually use, then [session apps](./server-side-sessions.md) if you want the SDK to own sessions. Stuck? See [`troubleshooting.md`](./troubleshooting.md). + +## Overview + +node-auth0's `AuthenticationClient` is a stateless HTTP client. Every method is a single call to an Auth0 Authentication API endpoint that returns a response object. It has no notion of a logged-in user, no session, no cookie, no token store, and no automatic refresh. Anything stateful in a node-auth0 app (persisting tokens, deciding when to refresh, tracking the login across requests) was written by you *around* node-auth0. + +The modern stack splits those two concerns into two packages: + +- `@auth0/auth0-auth-js` is the stateless token layer. It is the direct successor to `AuthenticationClient`: the same "one method equals one API call equals one result" model, with modern ergonomics (camelCase, typed errors, direct return values, per-request options). +- `@auth0/auth0-server-js` is a stateful session layer built on top of auth0-auth-js. It owns the login redirect flow, a pluggable state/transaction store, cookie handling, automatic token refresh, and logout. It is the successor to the *session code you hand-rolled*, not to `AuthenticationClient` itself. + +### Who this is for + +You are running a Node.js backend that imports the `auth0` package and calls `AuthenticationClient` (or `UserInfoClient`) to perform token grants, database signup, passwordless, CIBA, token exchange, or userinfo lookups. You want to move that code to the current first-party server SDKs. This is a surgical rewrite of the authentication layer: routes, controllers, business logic, data access, and framework wiring stay as they are. You touch the smallest possible surface: the files that import and call node-auth0's Authentication API. + +### Scope + +In scope: + +- `AuthenticationClient` and its sub-clients: `.oauth`, `.database`, `.passwordless`, `.backchannel`, `.tokenExchange` +- `UserInfoClient` +- The auth error types (`AuthApiError`) and token-validation types (`IDTokenValidateOptions`, `IdTokenValidatorError`) + +Out of scope, do not touch: + +- `ManagementClient` (Management API v2). It is not being migrated and stays on the `auth0` package. +- Application routes, view/controller logic, database code, and any non-auth use of the `auth0` package. + +> If a file uses `ManagementClient`, leave that code alone. Only rewrite the `AuthenticationClient` / `UserInfoClient` parts. + +## Choosing your target SDK + +The routing question is: do you want to keep owning your session, or hand that responsibility to the SDK? + +### Decision table + +| If your code… | Migrate to | Why | +| --- | --- | --- | +| Only performs token grants / DB signup / passwordless / userinfo and manages its own session (or is a machine-to-machine service backend) | `@auth0/auth0-auth-js` | Direct, near 1:1 replacement for `AuthenticationClient`. Same stateless model. | +| Wants the SDK to own the login redirect flow, session storage, cookies, token refresh, and logout (a server-rendered web app) | `@auth0/auth0-server-js` | Adds a session layer node-auth0 never had. This is a rewrite of the session handling, not a method-for-method port. | + +**Default recommendation:** start with `@auth0/auth0-auth-js` for a faithful parity migration. Choose `@auth0/auth0-server-js` only when you currently hand-roll session/cookie/refresh logic around node-auth0 and would benefit from the SDK owning it. + +### Signals + +Signals that point to auth0-auth-js: + +- Predominant use is `clientCredentialsGrant` (machine-to-machine). There is no user, so there is no session to own. +- The app already has a session framework it is happy with and only calls node-auth0 for token grants. +- The app is an API, worker, or CLI, not a browser-facing web server. +- You want the smallest, most mechanical, lowest-risk migration. + +Signals that point to auth0-server-js: + +- The app performs a browser redirect login and reads `req.session.user` (or equivalent) on later requests. +- You wrote refresh-on-expiry logic, a token cache, or logout-with-revocation by hand. +- You use `express-openid-connect` today and want a first-party, framework-agnostic replacement. +- You are on a server framework (Express, Fastify, Hono, Next.js) and want the SDK to manage cookies. + +### Mixing both + +A single app can use both: auth0-server-js for the user-facing login/session, and auth0-auth-js directly for a separate machine-to-machine `clientCredentialsGrant` to call another API. `ServerClient` even exposes the underlying `AuthClient` via `serverClient.authClient` for occasional low-level needs. Do not force everything onto one package. + +## Prerequisites + +### Node.js version + +Both target SDKs need Node.js 20 LTS or newer. Verify the project's runtime before installing. + +### SDK versions + +- `@auth0/auth0-auth-js` >= `1.13.0` +- `@auth0/auth0-server-js` >= `1.13.0` + +Both are published on npm; install the current `latest`. `1.13.0` is the floor for the full API surface used in this guide (`getUserInfo`, per-request `RequestOptions`, and `fullResponse`). + +## Installation and constructor mapping + +Add the target package: + +```bash +# auth-js target (stateless token grants) +npm install @auth0/auth0-auth-js + +# server-js target (server-managed sessions), pulls in auth0-auth-js transitively +npm install @auth0/auth0-server-js +``` + +Keep the `auth0` package installed if the app still uses `ManagementClient`. + +### Imports + +```ts +// before +import { AuthenticationClient, UserInfoClient, AuthApiError } from "auth0"; + +// after: auth-js target +import { AuthClient, TokenByCodeError, isMfaRequiredError } from "@auth0/auth0-auth-js"; + +// after: server-js target +import { ServerClient } from "@auth0/auth0-server-js"; +``` + +> Keep the `auth0` import if the file also uses `ManagementClient`. It is correct for a file to import both `auth0` (for `ManagementClient`) and `@auth0/auth0-auth-js` (for authentication). Only remove the `auth0` import from files where it was used *solely* for `AuthenticationClient` / `UserInfoClient`. + +### AuthClient options + +The constructor options mostly carry over with camelCase names. A few are renamed or dropped. + +**Before (node-auth0):** + +```ts +new AuthenticationClient({ + domain: "tenant.us.auth0.com", + clientId: "...", + clientSecret: "...", // OR clientAssertionSigningKey + clientAssertionSigningKey: "...", + clientAssertionSigningAlg: "RS256", + idTokenSigningAlg: "RS256", // for manual id_token validation + clockTolerance: 60, // seconds, for validation + useMTLS: false, + telemetry: true, + headers: { "X-Custom": "..." }, // sent on every request + timeoutDuration: 10000, // ms + retry: { + /* ... */ + }, + agent: undiciDispatcher, + fetch: customFetch, + middleware: [ + /* ... */ + ], +}); +``` + +**After (auth0-auth-js):** + +```ts +import { AuthClient } from "@auth0/auth0-auth-js"; + +new AuthClient({ + domain: "tenant.us.auth0.com", // same (no scheme) + clientId: "...", // same + clientSecret: "...", // same + clientAssertionSigningKey: "...", // same (string | CryptoKey) + clientAssertionSigningAlg: "RS256", // same + authorizationParams: { + // NEW: default scope/audience/redirect_uri for URL builders + scope: "openid profile email", + audience: "https://api.example.com", + redirect_uri: "https://app.example.com/callback", + }, + useMtls: false, // RENAMED from useMTLS (lowercase tls) + customFetch: fetch, // RENAMED from fetch + telemetry: { + /* ... */ + }, // structured TelemetryConfig + discoveryCache: { ttl, maxEntries }, // NEW: OIDC discovery / JWKS cache +}); +``` + +Option-by-option: + +| node-auth0 | auth0-auth-js | Notes | +| --- | --- | --- | +| `domain` | `domain` | Unchanged. No `https://` scheme. | +| `clientId` | `clientId` | Unchanged. | +| `clientSecret` | `clientSecret` | Unchanged. | +| `clientAssertionSigningKey` | `clientAssertionSigningKey` | Unchanged. Now also accepts a `CryptoKey`. | +| `clientAssertionSigningAlg` | `clientAssertionSigningAlg` | Unchanged. | +| `useMTLS` | `useMtls` | Renamed (casing). | +| `fetch` | `customFetch` | Renamed. | +| `telemetry: boolean` | `telemetry: TelemetryConfig` | Now a structured object. | +| `headers` (global) | per-request `RequestOptions.headers` | Moved to per-request options; set per call site rather than globally. | +| `timeoutDuration` | per-request `RequestOptions.signal` | Use an `AbortSignal.timeout(ms)` on the call. | +| `retry` | configure via `customFetch` | Wrap your fetch with retry if needed. | +| `agent` | configure via `customFetch` | Set the dispatcher inside your custom fetch. | +| `middleware` | `customFetch` | Compose behavior in the fetch wrapper. | +| `idTokenSigningAlg` | (internal) | ID-token validation is internal; read `TokenResponse.claims`. | +| `clockTolerance` | (internal) | Handled internally during validation. | + +### ServerClient options + +`ServerClient` wraps an `AuthClient` and adds the session machinery. It shares the auth options and adds required stores. This constructor and the stores it needs are covered in [`server-side-sessions.md`](./server-side-sessions.md); reach for it only when you route to server-js. + +### Global config to per-request options + +node-auth0's global constructor options for `headers`, `timeoutDuration`, `agent`, `retry`, and `middleware` have no direct constructor equivalents in auth0-auth-js. Instead, the new SDK's methods accept a trailing `RequestOptions` parameter: + +```ts +import type { RequestOptions } from "@auth0/auth0-server-js"; // or '@auth0/auth0-auth-js' + +const tokens = await authClient.getTokenByClientCredentials( + { audience: "https://api.example.com" }, + { + headers: { "X-Custom": "value" }, + signal: AbortSignal.timeout(5000), // timeout in ms + } satisfies RequestOptions, +); +``` + +`@auth0/auth0-server-js` re-exports `RequestOptions`, `ApiResponse`, and `FullResponseOption` from `@auth0/auth0-auth-js`, so you can import any of them from either package. + +Arity rule: MFA methods (`authClient.mfa.*`) take `requestOptions` as the 2nd argument; store-first methods (session-owning methods on `serverClient`) take it as the 3rd argument after the store context; cache hits ignore it entirely. + +Common patterns: + +- Global headers: apply via `RequestOptions.headers` on each call that needs it, or wrap `customFetch` once to inject it everywhere. +- Timeout: replace `timeoutDuration: 10000` with `signal: AbortSignal.timeout(10000)` on the call. +- Agent (Node.js dispatcher): wrap `customFetch` to inject the agent into the underlying HTTP transport. +- Retry / middleware: compose behavior in a `customFetch` wrapper passed either at construction or per request. + +## OIDC token grants + +This is the core of the migration and, for most apps, the whole of it. These are the `AuthenticationClient.oauth.*` grants that drive OpenID Connect login and machine-to-machine token acquisition. All of them move onto the `AuthClient` instance directly (not a sub-client). + +Before you touch any method, internalize the four [cross-cutting breaking changes](#cross-cutting-breaking-changes); they apply to *every* rewrite here and on the incremental pages. + +Naming conventions used throughout: + +| node-auth0 | new SDKs | +| --- | --- | +| Params and response fields use the snake_case wire shape: `client_id`, `refresh_token`, `access_token`, `expires_in`, `phone_number` | camelCase: `clientId`, `refreshToken`, `accessToken`, `expiresAt`, `phoneNumber` | +| Methods take a `bodyParameters` object (+ optional `initOverrides`) | Methods take a single `options` object (+ optional trailing `RequestOptions` for per-request `signal`, `headers`, `customFetch`) | +| Every method returns a `JSONApiResponse` / `VoidApiResponse` / `TextApiResponse` wrapper | Methods return the domain object directly (`TokenResponse`, `SignUpResult`, `string`, `void`) | + +### `oauth.authorizationCodeGrant` → `getTokenByCode` + +The single most important semantic change in the whole migration. In node-auth0 you pass the raw authorization `code` (and `redirect_uri`) that you extracted from the callback query string yourself. In auth0-auth-js you pass the entire callback `URL`; the SDK extracts `code` and enforces PKCE, and `redirect_uri` comes from the `AuthClient` config / `authorizationParams`. The stateless `AuthClient` does **not** validate OAuth `state` — that is your responsibility (or use `@auth0/auth0-server-js` `completeInteractiveLogin`, which owns a transaction store and validates `state` for you). + +**Before (node-auth0):** + +```ts +import { AuthenticationClient } from "auth0"; + +const auth0 = new AuthenticationClient({ domain, clientId, clientSecret }); + +// You parsed `code` out of the callback URL yourself. +const resp = await auth0.oauth.authorizationCodeGrant({ + code, + redirect_uri: "https://app.example.com/callback", +}); +const accessToken = resp.data.access_token; +const expiresIn = resp.data.expires_in; // relative seconds +const reqId = resp.headers.get("x-request-id"); // metadata on success +``` + +**After (auth0-auth-js):** + +```ts +import { AuthClient } from "@auth0/auth0-auth-js"; + +const authClient = new AuthClient({ domain, clientId, clientSecret }); + +// `url` is a URL object for the full incoming request URL, +// e.g. new URL(req.url, `https://${req.headers.host}`) +const tokens = await authClient.getTokenByCode(url, { + // options; e.g. codeVerifier (PKCE) or organization +}); +const accessToken = tokens.accessToken; +const expiresAt = tokens.expiresAt; // absolute Unix seconds +``` + +> If your code manually parses `req.query.code`, that parsing is now the SDK's job. Delete it and hand the SDK the full URL. The SDK reads `code` from the URL and validates the PKCE verifier; it does **not** validate OAuth `state`. **Keep your existing `state` check** (compare the `state` query parameter against what you stored before the redirect) — or migrate to `@auth0/auth0-server-js` `completeInteractiveLogin`, which handles `state` validation automatically. (`getTokenByCode` options are `codeVerifier` and `organization`.) If the node-auth0 code read `resp.headers.get(...)` on success, see [Reading HTTP response metadata](#reading-http-response-metadata-fullresponse). Error-path metadata remains accessible on the typed error. + +> **Warning:** Do not delete your `state`/CSRF check when migrating to `AuthClient.getTokenByCode`. The stateless client does not validate `state`. Removing the check silently disables CSRF protection on the authorization-code flow. + +### `oauth.authorizationCodeGrantWithPKCE` → `getTokenByCode` (with verifier) + +PKCE (Proof Key for Code Exchange) is folded into the same method; supply the code verifier via options. Typically the verifier was produced earlier by `buildAuthorizationUrl` (below), which returns a `codeVerifier` for you to persist. + +```ts +// before +const resp = await auth0.oauth.authorizationCodeGrantWithPKCE({ + code, + code_verifier: verifier, + redirect_uri: "https://app.example.com/callback", +}); + +// after +const tokens = await authClient.getTokenByCode(url, { + codeVerifier: verifier, +}); +``` + +> If you build the authorization URL yourself today, prefer switching to `authClient.buildAuthorizationUrl()` (below) so the SDK generates and returns the `codeVerifier`, then persist it and pass it back to `getTokenByCode`. + +### `oauth.refreshTokenGrant` → `getTokenByRefreshToken` + +```ts +// before +const resp = await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); +// after +const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); +``` + +### `oauth.passwordGrant` → `getTokenByPassword` + +```ts +// before +const resp = await auth0.oauth.passwordGrant({ + username, + password, + realm: "Username-Password-Authentication", + audience, + scope, +}); +// after +const tokens = await authClient.getTokenByPassword({ + username, + password, + realm: "Username-Password-Authentication", + audience, + scope, +}); +``` + +### `oauth.clientCredentialsGrant` → `getTokenByClientCredentials` + +The canonical machine-to-machine grant. This is the most common reason to stay on auth0-auth-js rather than adopt server-js: there is no user session involved. + +```ts +// before +const resp = await auth0.oauth.clientCredentialsGrant({ audience: "https://api.example.com" }); +const token = resp.data.access_token; +// after +const tokens = await authClient.getTokenByClientCredentials({ audience: "https://api.example.com" }); +const token = tokens.accessToken; +``` + +### `oauth.revokeRefreshToken` → `revokeToken` + +Renamed, and simplified return (was `VoidApiResponse`, now `void`). + +```ts +// before +await auth0.oauth.revokeRefreshToken({ token: rt }); +// after +await authClient.revokeToken({ token: rt }); +``` + +> **Session apps:** if you are migrating to server-js and this revoke was part of logout, use `serverClient.revokeRefreshToken()` instead of the low-level `revokeToken`. By default it reads the refresh token from the session; you can also pass an explicit `{ token }` in its options. + +### Build the authorization and logout URLs + +node-auth0 left `/authorize` URL construction to the caller (or to `express-openid-connect`). The new SDK gives you `buildAuthorizationUrl()` and `buildLogoutUrl()`. When migrating a redirect login, replace hand-built `/authorize` and `/v2/logout` URLs with these: + +```ts +const { authorizationUrl, codeVerifier } = await authClient.buildAuthorizationUrl({ + authorizationParams: { redirect_uri, scope: "openid profile email", audience }, +}); +// ... later, on logout: +const logoutUrl = await authClient.buildLogoutUrl({ returnTo: "https://app.example.com" }); +``` + +> Pushed Authorization Requests (PAR): there is no standalone PAR method. Pass `pushedAuthorizationRequests: true` to `buildAuthorizationUrl`: the SDK performs the PAR POST and returns an authorization URL that references the resulting `request_uri`. Requires the tenant to expose a `pushed_authorization_request_endpoint`; the SDK throws if PAR is requested but unsupported. This replaces node-auth0's `oauth.pushedAuthorization`. + +Once the OIDC grants are rewritten and the [cross-cutting breaking changes](#cross-cutting-breaking-changes) are applied, run the [verification checklist](#verification-checklist). If your app also uses database, passwordless, CIBA, token exchange, or `UserInfoClient`, continue with [`authentication-flows.md`](./authentication-flows.md). If you want the SDK to own sessions, see [`server-side-sessions.md`](./server-side-sessions.md). + +### Optional: migrate only OIDC while staying on v6 + +You do not have to migrate everything at once, and you do not have to wait for v7. node-auth0 v6 still ships `AuthenticationClient` alongside `ManagementClient`, so you can move your OIDC login and token grant code off `AuthenticationClient` to `@auth0/auth0-auth-js` now, incrementally, while the rest of the app keeps using `auth0` v6 unchanged. + +A common and fully supported end state: + +- OIDC / token grant code: migrated to `@auth0/auth0-auth-js` (the grants covered in this section). +- Other auth flows you have not gotten to yet: still on `AuthenticationClient` from `auth0` v6. +- Management API: still on `ManagementClient` from `auth0` (never migrates). + +The OIDC grants above are a complete, shippable step on their own; finishing them is a valid stopping point even if you migrate nothing else. Move on to [`authentication-flows.md`](./authentication-flows.md) and [`server-side-sessions.md`](./server-side-sessions.md) later, at your own pace. When you eventually upgrade to v7 (which removes the Authentication API from the main entrypoint; see the [v7 Migration Guide](../v7_MIGRATION_GUIDE.md)), the OIDC work is already done. + +## Cross-cutting breaking changes + +Every call-site rewrite in this guide and on the incremental pages is subject to four changes that cut across all methods. They cause the overwhelming majority of migration defects, and three of the four are *silent*: the code compiles and often runs, but produces wrong behavior at runtime. Apply each one deliberately. + +1. [Return shape: `JSONApiResponse` → domain object](#1-return-shape) +2. [Casing: snake_case wire shape → camelCase](#2-casing) +3. [Token expiry: `expires_in` (relative) → `expiresAt` (absolute)](#3-token-expiry), most dangerous +4. [Error model: `AuthApiError` → typed per-operation errors](#4-error-model) + +### 1. Return shape + +node-auth0 wraps most Authentication API results in a response envelope: + +- `JSONApiResponse`: has `.data` (the payload), `.status` (number), `.statusText`, `.headers` (a `Headers` object). +- `VoidApiResponse`: same envelope, `.data` is `undefined` (used by `sendEmail`, `revokeRefreshToken`, …). +- `TextApiResponse`: `.data` is a `string` (used by `database.changePassword`). + +Exception: `backchannel.authorize`, `backchannel.backchannelGrant`, and `tokenExchange.exchangeToken` return domain objects directly (no `.data` wrapper) in node-auth0. + +The new SDKs drop the envelope and return the domain object directly: + +- Token grants return a `TokenResponse` instance. +- `database.signUp` returns a `SignUpResult` object. +- `database.changePassword` returns a `string`. +- `sendEmail` / `sendSms` / `revokeToken` return `void`. + +HTTP metadata (status code, response headers such as `x-request-id`, `retry-after`, rate-limit headers) is available through the typed error objects on failure paths. On success paths, metadata is available via the opt-in `fullResponse` envelope (see [Reading HTTP response metadata](#reading-http-response-metadata-fullresponse)). It is no longer on the bare success value by default. + +The rewrite: delete `.data` indirection on every success path: + +```ts +// before +const resp = await auth0.oauth.clientCredentialsGrant({ audience }); +const token = resp.data.access_token; +const status = resp.status; + +// after +const tokens = await authClient.getTokenByClientCredentials({ audience }); +const token = tokens.accessToken; +``` + +```ts +// before: changePassword returned TextApiResponse +const resp = await auth0.database.changePassword({ email, connection }); +console.log(resp.data); + +// after: returns the string directly +const message = await authClient.database.changePassword({ email, connection }); +console.log(message); +``` + +> `changePassword` requires `connection` plus at least one of `email` or `username`: either identifier is accepted, not `email` alone. + +#### Reading HTTP response metadata (fullResponse) + +When your node-auth0 code reads HTTP response metadata (status, headers) on a success path, migrate to the opt-in envelope rather than dropping the read. This is most common when you track rate limits, log request IDs, or check retry-after headers for dashboard telemetry. + +```ts +// before (node-auth0): metadata on the success envelope +const resp = await auth0.oauth.clientCredentialsGrant({ audience }); +const remaining = resp.headers.get("x-ratelimit-remaining"); +const token = resp.data.access_token; + +// after: opt in to the envelope, read the native Response +const { data, response } = await authClient.getTokenByClientCredentials({ audience, fullResponse: true }); +const remaining = response.headers.get("x-ratelimit-remaining"); +const token = data.accessToken; +``` + +The same opt-in covers the non-token Authentication API methods that node-auth0 wrapped in a `JSONApiResponse` / `TextApiResponse` / `VoidApiResponse`: + +| Method | Bare return | `fullResponse: true` return | +| --- | --- | --- | +| `database.signUp` | `SignUpResult` | `ApiResponse` | +| `database.changePassword` | `string` | `ApiResponse` | +| `passwordless.sendEmail` | `void` | `ApiResponse` (`data` is `undefined`) | +| `passwordless.sendSms` | `void` | `ApiResponse` (`data` is `undefined`) | + +```ts +// before (node-auth0): read the request id off the signup envelope +const resp = await auth0.database.signUp({ email, password, connection }); +const reqId = resp.headers.get("x-request-id"); + +// after: opt in to the envelope +const { data, response } = await authClient.database.signUp({ email, password, connection, fullResponse: true }); +const reqId = response.headers.get("x-request-id"); + +// void-returning methods expose the Response with an undefined `data` +const { response: sendResp } = await authClient.passwordless.sendEmail({ email, fullResponse: true }); +const rateLimit = sendResp.headers.get("x-ratelimit-remaining"); +``` + +Caveats: + +- Pass `fullResponse: true` as a literal, not a variable. Using spread (`{ ...opts, fullResponse: true }`) widens `true` to `boolean`, causing TypeScript overload resolution to fall back to the bare return type. Fix: pass `{ ...opts, fullResponse: true as const }` or include `fullResponse` as an inline literal in the options object. +- Performance: `@auth0/auth0-auth-js` does not cache tokens: every `AuthClient` grant method performs a live token-endpoint round-trip regardless of `fullResponse`, so the flag adds no extra network cost at this layer. (Token caching and reuse live in `@auth0/auth0-server-js`'s session store, not in the auth-js `AuthClient`.) The only in-memory cache in auth-js is for OIDC discovery / JWKS metadata, which is unrelated to `fullResponse`. +- Reserved headers: a caller `Authorization` header is ignored and the telemetry `Auth0-Client` header always wins; `RequestOptions.headers` cannot override them. +- Per-request `customFetch` replaces the base transport for that call but does not inherit mutual TLS (mTLS). If you rely on mTLS, the supplied fetch must itself be mTLS-capable. + +Default to the bare return type. Reach for `fullResponse` only where you actually consumed response metadata on success: rate-limit dashboards, request-id logging for support investigations, or retry-after handling. `MissingCapturedResponseError` is an internal-bug sentinel; you do not normally catch it. + +Gotchas: + +- **Void methods.** Code that did `const r = await auth0.passwordless.sendEmail(...)` and then checked `r.status === 200` must drop that check: by default the method returns `void` and throws on failure. Rely on the thrown error instead (see [Error model](#4-error-model)). +- **Header reads.** Any code reading `resp.headers.get('x-ratelimit-remaining')` on a success path needs the opt-in `fullResponse` envelope. Error paths still surface metadata on the typed error. Search your code for `.headers` on response values. +- **Do not hand-roll a compatibility shim.** Resist reintroducing a custom `{ data, status }` shape to minimize downstream diff. Let the domain object flow through; the SDK's opt-in `fullResponse` envelope is the sanctioned channel when you genuinely need the HTTP Response. + +### 2. Casing + +node-auth0's public API exposes the snake_case wire shape verbatim, on both inputs and outputs. The new SDKs use camelCase for the public API and only translate to snake_case at the HTTP boundary internally. + +Input parameters, field map: + +| node-auth0 (snake_case) | new SDK (camelCase) | +| --- | --- | +| `client_id` | `clientId` | +| `client_secret` | `clientSecret` | +| `refresh_token` | `refreshToken` | +| `redirect_uri` | (via `authorizationParams.redirect_uri` on config / builder) | +| `code_verifier` | `codeVerifier` | +| `phone_number` | `phoneNumber` | +| `auth_req_id` | `authReqId` | +| `binding_message` | `bindingMessage` | +| `subject_token` / `subject_token_type` | `subjectToken` / `subjectTokenType` | +| `given_name` / `family_name` | `givenName` / `familyName` | +| `user_metadata` | `userMetadata` | +| `login_hint` | `loginHint` | + +Output fields, `TokenResponse` field map: + +| node-auth0 `TokenSet` (snake_case) | new SDK `TokenResponse` (camelCase) | +| --- | --- | +| `access_token` | `accessToken` | +| `refresh_token` | `refreshToken` | +| `id_token` | `idToken` | +| `token_type` | `tokenType` | +| `expires_in` (relative) | `expiresAt` (absolute, see [Token expiry](#3-token-expiry)) | +| `scope` | `scope` | +| (none): had to decode id_token yourself | `claims` (already-decoded ID token claims) | +| `authorization_details` | `authorizationDetails` | + +Rename fields on both the arguments you pass in and the fields you read out: + +```ts +// before +const resp = await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); +const newRt = resp.data.refresh_token; +const idToken = resp.data.id_token; + +// after +const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); +const newRt = tokens.refreshToken; +const idToken = tokens.idToken; +``` + +> **Gotcha: keys that look renamed but are your data.** `user_metadata` → `userMetadata` is a rename of the *SDK's* parameter. The object *inside* it (e.g. `{ plan: 'free' }`) is passed through untouched. Do not rename your own metadata keys. The same applies to `authorization_details`. + +### 3. Token expiry + +**This is the highest-risk change in the migration. It is silent, it compiles, and it corrupts session lifetimes.** + +- node-auth0 `TokenSet.expires_in` = the token's lifetime in seconds relative to now (e.g. `86400` for a 24-hour token). This is the raw OAuth `expires_in` from the wire. +- new SDK `TokenResponse.expiresAt` = an absolute Unix timestamp in seconds (e.g. `1786000000`) computed by the SDK as roughly `now + expires_in`. + +Existing node-auth0 code almost always converts the relative value to an absolute deadline itself: + +```ts +// before: very common node-auth0 pattern +const resp = await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); +const expiresAtMs = Date.now() + resp.data.expires_in * 1000; // stored deadline +``` + +If you mechanically rename `expires_in` → `expiresAt` and leave the arithmetic, you get: + +```ts +// WRONG: double-counts "now" +const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); +const expiresAtMs = Date.now() + tokens.expiresAt * 1000; // ~ now + (now + lifetime) → far future +``` + +The stored deadline lands decades in the future, so the token is treated as valid long after it has actually expired. The app does not refresh it, so production 401s follow. + +The rewrite: `expiresAt` is *already* the deadline. Do not add `Date.now()`: + +```ts +// after: correct +const tokens = await authClient.getTokenByRefreshToken({ refreshToken: rt }); +const expiresAtMs = tokens.expiresAt * 1000; // absolute; convert s → ms only if you store ms +``` + +If downstream code genuinely needs the *relative* remaining lifetime (e.g. to set a cookie `Max-Age`), compute it from the absolute value: + +```ts +const secondsRemaining = tokens.expiresAt - Math.floor(Date.now() / 1000); +``` + +To find every instance, grep your code for these patterns and inspect each by hand: + +- `expires_in` +- `Date.now() +` near a token result +- `+ expires` / `* 1000` near a token result +- any stored field named `expiresAt`, `expires_at`, `expiry`, `tokenExpiry` fed from a grant + +Every one of these is a candidate for the double-count bug. + +> **Session apps get this for free.** If you migrate to server-js, the SDK owns expiry math inside `getAccessToken`. Delete your `Date.now() + expires_in * 1000` bookkeeping entirely. + +### 4. Error model + +node-auth0 throws a single error type for Authentication API failures: + +```ts +class AuthApiError extends Error { + name: "AuthApiError"; + error: string; // OAuth error code, e.g. 'invalid_grant' + error_description: string; + statusCode: number; + body: string; + headers: Headers; +} +``` + +The new SDKs throw typed, operation-specific error classes: `TokenByCodeError`, `TokenByRefreshTokenError`, `TokenByClientCredentialsError`, `TokenByPasswordError`, `TokenExchangeError`, `TokenRevocationError`, `PasswordlessStartError`, `PasswordlessChallengeError`, `PasswordlessDbGetTokenError`, `MfaEnrollmentError`, and so on. Each carries a structured `.cause` (the underlying OAuth2 error) rather than flat `error` / `error_description` strings. + +The rewrite: generic catch: + +```ts +// before +try { + await auth0.oauth.refreshTokenGrant({ refresh_token: rt }); +} catch (e) { + if (e instanceof AuthApiError && e.error === "invalid_grant") { + // refresh token revoked/expired + } +} + +// after +import { TokenByRefreshTokenError } from "@auth0/auth0-auth-js"; +try { + await authClient.getTokenByRefreshToken({ refreshToken: rt }); +} catch (e) { + if (e instanceof TokenByRefreshTokenError && e.cause?.error === "invalid_grant") { + // refresh token revoked/expired + } +} +``` + +Import the specific error class for the operation you are calling. If you had one broad `catch (e instanceof AuthApiError)` around several different operations, either widen to catch each operation's error type or check the shared base behavior. Prefer the specific type per call site, since it documents which operation can fail. + +#### MFA detection: use the type guard, not the string + +Multi-factor authentication (MFA). A very common node-auth0 pattern is detecting `mfa_required` by string comparison to route the user into an MFA challenge: + +```ts +// before +try { + await auth0.oauth.passwordGrant({ username, password }); +} catch (e) { + if (e instanceof AuthApiError && e.error === "mfa_required") { + // start MFA flow using e (mfa_token is in the body) + } +} +``` + +The new SDK provides `isMfaRequiredError()`, a type guard that narrows the error and gives typed access to the MFA context (including the `mfa_token`). Use it instead of matching the string: + +```ts +// after +import { isMfaRequiredError } from "@auth0/auth0-auth-js"; +try { + await authClient.getTokenByPassword({ username, password }); +} catch (e) { + if (isMfaRequiredError(e)) { + // e is narrowed; drive the MFA challenge via authClient.mfa.* + } +} +``` + +> After detecting `mfa_required`, the MFA enroll/challenge/verify flow that node-auth0 handled ad hoc now lives on `authClient.mfa.*` (`listAuthenticators`, `enrollAuthenticator`, `challengeAuthenticator`, `verify`, and `deleteAuthenticator`). In server-js, `serverClient.mfa.verify()` also persists the resulting tokens to the session. + +#### ID-token validation types + +node-auth0 exposed `IDTokenValidateOptions` and `IdTokenValidatorError` for callers doing manual ID-token validation. The new SDK validates ID tokens internally during grants and exposes the decoded, validated result as `TokenResponse.claims`. Replace manual validation: + +- Options like `organization`, `nonce`, `maxAge` are passed to the grant call (e.g. `getTokenByCode`), and the SDK validates them and throws a typed error on mismatch, so you no longer construct a validator or catch `IdTokenValidatorError` yourself. +- Read the validated claims from `TokenResponse.claims` instead of decoding the `id_token` string. + +## Verification checklist + +The migration is not complete until every check passes in a single pass. For every node-auth0 auth call you rewrote (here or on the incremental pages), confirm all four cross-cutting changes: + +- [ ] **Return shape**: removed `.data` / `.status` / `.headers` access on the success path. +- [ ] **Casing**: renamed every snake_case field on input args and output reads to camelCase. +- [ ] **Expiry**: any code using the old `expires_in` now uses `expiresAt` as an *absolute* timestamp; no `Date.now() +` was left in front of it. +- [ ] **Errors**: `AuthApiError` catches replaced with the specific typed error (`.cause.error`); `mfa_required` string checks replaced with `isMfaRequiredError()`. + +Then run the project gates and repeat the whole loop if any step fails: + +- [ ] Grep for residue: unmigrated `from 'auth0'` auth imports, `.data.` reads on auth responses, and relative `expires_in` arithmetic. +- [ ] `tsc --noEmit`: catches structural mismatches and type errors. +- [ ] `npm test` (or the project's test command): confirms behavior is preserved. +- [ ] Run the linter if the project has one configured. +- [ ] Confirm files that use `ManagementClient` still import and call it from `auth0`; that code must be untouched. + +Do not declare the migration complete until the loop converges: all steps pass in a single iteration. + +## Continue the migration + +Once the OIDC grants and the four cross-cutting changes are in, migrate the rest at your own pace. Each area lives in its own page. + +### Other authentication flows + +Database signup, passwordless, backchannel (CIBA), token exchange, and `UserInfoClient` lookups: see [`authentication-flows.md`](./authentication-flows.md). + +### Server-side sessions + +Routing to `@auth0/auth0-server-js`, where the SDK owns the login redirect flow, session storage, cookies, token refresh, and logout: see [`server-side-sessions.md`](./server-side-sessions.md). + +### Troubleshooting + +Common questions and failure modes (tokens valid for decades, missing `resp.data`, magic-link default flip, `getUserInfo`, `mfa_required` detection, global config): see [`troubleshooting.md`](./troubleshooting.md). diff --git a/auth-migration/server-side-sessions.md b/auth-migration/server-side-sessions.md new file mode 100644 index 0000000000..d040e2986b --- /dev/null +++ b/auth-migration/server-side-sessions.md @@ -0,0 +1,163 @@ +# Migrating session apps to `@auth0/auth0-server-js` + +This page is part of the [Authentication Migration Guide](./index.md). Read it only when you are routing to **`@auth0/auth0-server-js`**: when you want the SDK to own the login redirect flow, session storage, cookies, token refresh, and logout, instead of hand-rolling that around node-auth0. If you only need stateless token grants, stay on the main guide and [`authentication-flows.md`](./authentication-flows.md); you do not need this page. + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill (the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`). It walks the session lifecycle step by step. + +**This is a rewrite of the session handling, not a method-for-method port.** node-auth0 had no session concept, so there is nothing to translate line-for-line. Instead you *replace* your existing session code (your `express-session` wiring, your token cache, your refresh-on-expiry logic, your logout handler) with the ServerClient lifecycle. You still touch only the auth/session code; routes, views, and business logic stay put. + +- [Mental model](#mental-model) +- [Store setup](#store-setup) +- [The redirect-login lifecycle](#the-redirect-login-lifecycle) +- [Logins without a browser redirect](#logins-without-a-browser-redirect) +- [Backchannel logout](#backchannel-logout) + +## Mental model + +A ServerClient login has three durable pieces: + +1. **Transaction store**: short-lived. Holds the in-flight login: the OAuth `state` and the PKCE (Proof Key for Code Exchange) `code_verifier` between the moment you redirect the user to Auth0 and the moment they come back to your callback. Created at `startInteractiveLogin`, consumed at `completeInteractiveLogin`. +2. **State store**: long-lived. Holds the established session: the user claims plus the access / refresh / ID tokens and their absolute expiry. Read on every subsequent request via `getUser`, `getSession`, `getAccessToken`. +3. **Cookies**: how the two stores key themselves to the browser. With a *stateless* store the session data lives encrypted in the cookie itself; with a *stateful* store the cookie holds only an identifier and the data lives in your backend (Redis, database, and so on). + +node-auth0 exposed none of this; you built equivalents by hand. You are swapping your implementation for the SDK's. + +## Store setup + +`@auth0/auth0-server-js` ships store base classes and cookie-backed implementations: + +- `CookieTransactionStore`: transaction store backed entirely by a cookie. Good default. +- `StatelessStateStore`: session lives encrypted in the cookie. No server-side storage; good for serverless or horizontally-scaled deployments with small sessions. +- `StatefulStateStore`: session lives server-side; the cookie holds an id. Use for large sessions or when you need server-side revocation. +- `AbstractTransactionStore` / `AbstractStateStore`: extend these to back a store with your own storage (Redis, Postgres, and so on). These are the exported base-class names. + +All stores accept a `CookieHandler` so they can integrate with any framework's cookie API. The `storeOptions` generic (`TStoreOptions`) is how you thread per-request context (like the framework `req` / `res`) into store reads and writes; every ServerClient method takes an optional trailing `storeOptions` argument for exactly this. + +```ts +import { ServerClient, CookieTransactionStore, StatelessStateStore } from "@auth0/auth0-server-js"; + +const serverClient = new ServerClient({ + domain: process.env.AUTH0_DOMAIN!, + clientId: process.env.AUTH0_CLIENT_ID!, + clientSecret: process.env.AUTH0_CLIENT_SECRET!, + authorizationParams: { + redirect_uri: "https://app.example.com/callback", + scope: "openid profile email offline_access", // offline_access ⇒ refresh token + audience: "https://api.example.com", + }, + transactionStore: new CookieTransactionStore( + { secret: process.env.SESSION_SECRET! }, + cookieHandler, // CookieHandler implementation + ), + stateStore: new StatelessStateStore( + { secret: process.env.SESSION_SECRET! }, + cookieHandler, // CookieHandler implementation + ), +}); +``` + +## The redirect-login lifecycle + +### 1. Start login: replace the hand-built `/authorize` redirect + +Whatever you did to send the user to Auth0 (a hand-constructed `/authorize` URL, or `express-openid-connect`'s `/login`) becomes: + +```ts +// GET /login +app.get("/login", async (req, res) => { + const authorizationUrl = await serverClient.startInteractiveLogin( + { + authorizationParams: { + /* optional per-login overrides */ + }, + appState: { returnTo: req.query.returnTo || "/" }, // seed appState for round-trip + }, + { req, res }, // storeOptions: lets the transaction store write its cookie + ); + res.redirect(authorizationUrl.href); +}); +``` + +`startInteractiveLogin` generates `state` and PKCE, writes them to the transaction store, and returns the fully-formed authorization URL. + +### 2. Complete login: replace the manual code exchange + +The callback handler that used to call `oauth.authorizationCodeGrant` (or `authorizationCodeGrantWithPKCE`) and then stuff tokens into the session becomes a single call: + +```ts +// GET /callback +app.get("/callback", async (req, res) => { + const callbackUrl = new URL(req.url, `https://${req.headers.host}`); + const { appState } = await serverClient.completeInteractiveLogin(callbackUrl, { req, res }); + // Session is now established in the state store. Tokens are NOT your concern anymore. + res.redirect(appState?.returnTo ?? "/"); +}); +``` + +`completeInteractiveLogin` validates `state`, exchanges the code, validates the ID token, writes the session (user + tokens + absolute expiry) to the state store, and clears the transaction. + +### 3. Read the user or session on later requests + +Replace `req.session.user` reads: + +```ts +const user = await serverClient.getUser({ req, res }); // user claims, or undefined +const session = await serverClient.getSession({ req, res }); // full session data, or undefined +``` + +`getUser` / `getSession` return `undefined` when there is no session or it has expired (the store deletes expired sessions on read), so use that as your "not logged in" signal. + +### 4. Get an access token to call an API: refresh is automatic + +Replace your manual "is the token expired? if so refresh" block: + +```ts +const { accessToken } = await serverClient.getAccessToken({ req, res }); +// If the stored access token is expired and a refresh token exists, +// the SDK refreshes and persists the new tokens transparently. +``` + +This is where the `expires_in` → `expiresAt` hazard disappears entirely: the SDK owns expiry math. For a downstream federated connection token (Token Vault), use `serverClient.getAccessTokenForConnection({ connection }, { req, res })`. + +### 5. Logout: replace manual revoke, session clear, and `/v2/logout` redirect + +```ts +// GET /logout +app.get("/logout", async (req, res) => { + const logoutUrl = await serverClient.logout({ returnTo: "https://app.example.com" }, { req, res }); + res.redirect(logoutUrl.href); +}); +``` + +`logout` clears the session from the state store and returns the Auth0 `/v2/logout` URL. If you also revoked the refresh token on logout (via `oauth.revokeRefreshToken`), call `serverClient.revokeRefreshToken({ req, res })` before redirecting; by default it reads the refresh token from the session, so you do not handle the raw token yourself (it also accepts an explicit `{ token }` if you need to revoke a specific one). + +## Logins without a browser redirect + +Some logins do not use a browser redirect: the password grant, passwordless, CIBA, and custom token exchange. If you used node-auth0 for one of these *and* want a server-js session out of it, use the ServerClient methods that both authenticate and write the session, rather than the low-level auth-js grants: + +| Flow | ServerClient method | +| --- | --- | +| Backchannel / CIBA | `loginBackchannel({ ... }, storeOptions)` | +| Passwordless (send) | `startPasswordless({ connection, email \| phoneNumber, ... }, storeOptions)` | +| Passwordless (verify code → session) | `completePasswordless({ connection, email \| phoneNumber, verificationCode }, storeOptions)` | +| Passwordless magic link (callback → session) | `completePasswordlessMagicLink(url, storeOptions)` | +| Custom token exchange → session | `loginWithCustomTokenExchange({ ... }, storeOptions)` | +| MFA verify → session | `serverClient.mfa.verify({ ... }, storeOptions)` | + +Each of these performs the underlying grant *and* persists the resulting tokens to the state store, so the user is logged in afterward, exactly the behavior you previously wrote by hand after a node-auth0 grant. + +## Backchannel logout + +If you implemented an Auth0 back-channel logout endpoint by hand (validating the logout token, then clearing your session store), replace it with: + +```ts +// POST /backchannel-logout +app.post("/backchannel-logout", async (req, res) => { + await serverClient.handleBackchannelLogout(req.body.logout_token, { req, res }); + res.sendStatus(204); +}); +``` + +It validates the logout token and clears the corresponding session. + +When the session layer is wired, return to the [verification checklist](./index.md#verification-checklist) in the main guide. diff --git a/auth-migration/troubleshooting.md b/auth-migration/troubleshooting.md new file mode 100644 index 0000000000..334a37a698 --- /dev/null +++ b/auth-migration/troubleshooting.md @@ -0,0 +1,32 @@ +# Troubleshooting: FAQ and gotchas + +Common questions and failure modes when migrating off the `auth0` package's Authentication API. This page is part of the [Authentication Migration Guide](./index.md); it assumes the terms defined there. + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill (the `auth0` skill in [`auth0/agent-skills`](https://github.com/auth0/agent-skills), migration intent `migrate-node-auth0`). + +### Do I have to migrate everything at once? +No. The OIDC / token-grant work is a complete, shippable step on its own. You can stay on `auth0` v6 and migrate only OIDC, leaving other auth flows on `AuthenticationClient` for now. See [Optional: migrate only OIDC while staying on v6](./index.md#optional-migrate-only-oidc-while-staying-on-v6). + +### Do I have to migrate the Management API too? +No. `ManagementClient` is out of scope and stays on the `auth0` package. A file importing both `auth0` (for management) and `@auth0/auth0-auth-js` (for authentication) is correct. + +### auth0-auth-js or auth0-server-js: which do I pick? +Default to auth0-auth-js for a low-risk parity migration. Pick auth0-server-js only when you want the SDK to own the login redirect flow, session storage, cookies, refresh, and logout. See [Choosing your target SDK](./index.md#choosing-your-target-sdk). + +### My tokens suddenly look valid for decades. What happened? +You almost certainly left `Date.now() +` in front of `expiresAt`. `expiresAt` is already an absolute Unix timestamp, not a relative lifetime. See [Token expiry](./index.md#3-token-expiry). + +### Where did `resp.data` go? +The new SDKs return the domain object directly. Read `tokens.accessToken`, not `resp.data.access_token`. If you truly need HTTP response metadata on a success path, opt into `fullResponse`. + +### My magic-link passwordless flow stopped sending links. +The `send` default changed from `'link'` (node-auth0) to `'code'` (new SDK). Set `send: 'link'` explicitly if you want magic links. See [Passwordless](./authentication-flows.md#passwordless). + +### Where is `getUserInfo`? +Prefer `TokenResponse.claims`; they are already decoded and validated, with no extra round-trip. For an arbitrary access token, use `authClient.getUserInfo({ accessToken })`. In a session app, use `serverClient.getUser()`. See [UserInfoClient](./authentication-flows.md#userinfoclient). + +### Can I still set a global `headers` / `timeout` / `agent` on the client? +Not on the constructor. Move them to the per-call `RequestOptions` argument (`headers`, `signal: AbortSignal.timeout(ms)`) or wrap `customFetch`. + +### How do I detect `mfa_required` now? +Use the `isMfaRequiredError()` type guard, not a string comparison. It narrows the error and exposes the `mfa_token`. Drive the challenge via `authClient.mfa.*`. See [Error model](./index.md#4-error-model). diff --git a/v6_MIGRATION_GUIDE.md b/v6_MIGRATION_GUIDE.md new file mode 100644 index 0000000000..d1eb6bd699 --- /dev/null +++ b/v6_MIGRATION_GUIDE.md @@ -0,0 +1,158 @@ +# V6 Migration Guide + +A guide to migrating the Auth0 Node.js SDK from `5.x` to `6.x`. + +- [Overall changes](#overall-changes) +- [Breaking changes](#breaking-changes) + - [ConnectionAttributeIdentifier replaced with identifier-specific types](#connectionattributeidentifier-replaced-with-identifier-specific-types) + - [PhoneProviderProtectionBackoffStrategyEnum value change](#phoneproviderprotectionbackoffstrategyenum-value-change) + - [users.federatedConnectionsTokensets removed](#usersfederatedconnectionstokensets-removed) + - [federated_connections_access_tokens removed from connection options](#federated_connections_access_tokens-removed-from-connection-options) + +## Overall changes + +V6 addresses type correctness for database connection attribute identifiers, aligns the phone provider backoff strategy enum with the updated API, and removes the federated connections tokensets user sub-client. There are no changes to the Authentication API — any code written for the Authentication API in `5.x` will continue to work in `6.x`. + +## Breaking changes + +### ConnectionAttributeIdentifier replaced with identifier-specific types + +In v5, all three attribute identifiers (email, phone number, and username) shared a single `ConnectionAttributeIdentifier` type for their `identifier` field. This was incorrect — each identifier type supports different values for `default_method`. + +In v6, `ConnectionAttributeIdentifier` has been removed and replaced with three separate types: + +| Attribute | Old type | New type | `default_method` values | +| -------------- | ------------------------------- | ----------------------------- | ----------------------------- | +| `email` | `ConnectionAttributeIdentifier` | `EmailAttributeIdentifier` | `"password"` \| `"email_otp"` | +| `phone_number` | `ConnectionAttributeIdentifier` | `PhoneAttributeIdentifier` | `"password"` \| `"phone_otp"` | +| `username` | `ConnectionAttributeIdentifier` | `UsernameAttributeIdentifier` | _(no `default_method`)_ | + +**Before (v5):** + +```ts +import { Management } from "auth0"; + +const identifier: Management.ConnectionAttributeIdentifier = { + active: true, + default_method: "email_otp", +}; +``` + +**After (v6):** + +```ts +import { Management } from "auth0"; + +// For email attribute +const emailIdentifier: Management.EmailAttributeIdentifier = { + active: true, + default_method: "email_otp", +}; + +// For phone_number attribute +const phoneIdentifier: Management.PhoneAttributeIdentifier = { + active: true, + default_method: "phone_otp", +}; + +// For username attribute (no default_method) +const usernameIdentifier: Management.UsernameAttributeIdentifier = { + active: true, +}; +``` + +If you were using `ConnectionAttributeIdentifier` as a type annotation in your own code, update it to the appropriate identifier-specific type based on which attribute it applies to. + +--- + +### PhoneProviderProtectionBackoffStrategyEnum value change + +The `PhoneProviderProtectionBackoffStrategyEnum` enum has been updated to reflect a change in the Auth0 API. The `None` variant has been renamed to `Default`, and its string value has changed from `"none"` to `"default"`. + +**Before (v5):** + +```ts +import { Management } from "auth0"; + +const strategy = Management.PhoneProviderProtectionBackoffStrategyEnum.None; // "none" +``` + +**After (v6):** + +```ts +import { Management } from "auth0"; + +const strategy = Management.PhoneProviderProtectionBackoffStrategyEnum.Default; // "default" +``` + +If you were passing this value directly as a string `"none"`, update it to `"default"` to match the updated API. + +--- + +### users.federatedConnectionsTokensets removed + +The `client.users.federatedConnectionsTokensets` sub-client has been removed. This includes the `list()` and `delete()` methods. + +**Before (v5):** + +```ts +// List active federated connection tokensets for a user +const tokensets = await client.users.federatedConnectionsTokensets.list("user_id"); + +// Delete a tokenset +await client.users.federatedConnectionsTokensets.delete("user_id", "tokenset_id"); +``` + +**After (v6):** + +These methods are no longer available. Remove any calls to `client.users.federatedConnectionsTokensets` from your code. + +--- + +### federated_connections_access_tokens removed from connection options + +The `federated_connections_access_tokens` field has been removed from all connection option types, including create and update. This affects OIDC, Azure AD, Google Apps, and other connection strategies. Remove it from any create or update payloads. + +**Before (v5):** + +```ts +// On create +await client.connections.create({ + strategy: "oidc", + name: "my-connection", + options: { + federated_connections_access_tokens: { ... }, + // other options + }, +}); + +// On update +await client.connections.update("connection_id", { + options: { + federated_connections_access_tokens: { ... }, + // other options + }, +}); +``` + +**After (v6):** + +```ts +// On create +await client.connections.create({ + strategy: "oidc", + name: "my-connection", + options: { + // remove federated_connections_access_tokens + // other options + }, +}); + +// On update +await client.connections.update("connection_id", { + options: { + // remove federated_connections_access_tokens + // other options + }, +}); +``` diff --git a/v7_MIGRATION_GUIDE.md b/v7_MIGRATION_GUIDE.md new file mode 100644 index 0000000000..d1dba04a5c --- /dev/null +++ b/v7_MIGRATION_GUIDE.md @@ -0,0 +1,146 @@ +# V7 Migration Guide + +A guide to migrating the Auth0 Node.js SDK from `6.x` to `7.x`. + +> **Migrating with an AI agent?** Point it at the Auth0 migration skill first. The skill lives in [`auth0/agent-skills`](https://github.com/auth0/agent-skills) as the `auth0` skill (migration intent: `migrate-node-auth0`). It encodes the authentication-layer rewrite rules and a verify loop. + +- [Overall changes](#overall-changes) +- [Breaking changes](#breaking-changes) + - [Authentication API removed from the main entrypoint](#authentication-api-removed-from-the-main-entrypoint) + - [Removed exports](#removed-exports) + - [ManagementClient mTLS requires an explicit `fetch`](#managementclient-mtls-requires-an-explicit-fetch) + - [mTLS works with both client secret and client assertion](#mtls-works-with-both-client-secret-and-client-assertion) + - [`domain` must be a bare hostname](#domain-must-be-a-bare-hostname) + - [Token acquisition failures throw `ManagementError`](#token-acquisition-failures-throw-managementerror) + - [`uuid` dependency removed](#uuid-dependency-removed) +- [Migrating authentication code](#migrating-authentication-code) +- [Staying on the legacy entrypoint](#staying-on-the-legacy-entrypoint) + +## Overall changes + +V7 makes `node-auth0` a **Management-API-only SDK**. The Authentication API layer (`AuthenticationClient`, its sub-clients, and `UserInfoClient`) has been removed from the main entrypoint. `ManagementClient` continues to work exactly as before; it now acquires its internal token directly via the client credentials grant rather than through the removed authentication layer. + +If your code only uses `ManagementClient`, the upgrade is small: address the Management-side breaking changes below (mTLS, domain validation, error type) and you are done. If your code uses `AuthenticationClient` or `UserInfoClient`, that code must move to a dedicated package; see [Migrating authentication code](#migrating-authentication-code). + +## Breaking changes + +### Authentication API removed from the main entrypoint + +`AuthenticationClient` and `UserInfoClient` are no longer exported from the `auth0` main entrypoint. The stateless authentication layer now lives in [`@auth0/auth0-auth-js`](https://github.com/auth0/auth0-auth-js), and the server-managed session layer lives in [`@auth0/auth0-server-js`](https://github.com/auth0/auth0-auth-js/tree/main/packages/auth0-server-js). + +**Before (v6):** + +```ts +import { AuthenticationClient, UserInfoClient } from "auth0"; + +const auth = new AuthenticationClient({ domain, clientId, clientSecret }); +const tokens = await auth.oauth.clientCredentialsGrant({ audience }); +``` + +**After (v7):** + +```ts +import { AuthClient } from "@auth0/auth0-auth-js"; + +const auth = new AuthClient({ domain, clientId, clientSecret }); +const tokens = await auth.getTokenByClientCredentials({ audience }); +``` + +The complete method-by-method mapping, the four cross-cutting behavior changes (return shape, casing, token expiry, error model), and the session-app wiring are documented in the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). This guide does not repeat that detail. + +If you need the old clients unchanged as a stopgap, they still ship from the [legacy entrypoint](#staying-on-the-legacy-entrypoint). + +### Removed exports + +The following symbols were exported from the main entrypoint in v6 and are removed in v7. Each moves to `@auth0/auth0-auth-js`, or remains available from the `auth0/legacy` entrypoint at its v4.x shape. + +| Removed export (v6) | Replacement in v7 | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `AuthenticationClient` | `AuthClient` from `@auth0/auth0-auth-js` | +| `UserInfoClient` | `AuthClient.getUserInfo()` from `@auth0/auth0-auth-js`, or read `TokenResponse.claims` | +| `AuthApiError` | Per-operation typed errors from `@auth0/auth0-auth-js` (`TokenByCodeError`, `TokenByRefreshTokenError`, …); use their `.cause` | +| `AuthenticationClientOptions` | `AuthClientOptions` from `@auth0/auth0-auth-js` | +| `IDTokenValidateOptions` | Validation is internal to the grant call; pass `organization` / `nonce` / `maxAge` to the grant and read `TokenResponse.claims` | +| `IdTokenValidatorError` | Thrown internally by the grant as a typed error on claim mismatch | +| `TokenSet` | `TokenResponse` from `@auth0/auth0-auth-js` (camelCase fields; `expiresAt` is absolute) | +| `SUBJECT_TOKEN_TYPES` | Pass the token-type URN string directly to `exchangeToken` in `@auth0/auth0-auth-js` | +| `UserInfoResponse` | Return type of `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | +| `UserInfoError` | Typed error from `AuthClient.getUserInfo()` in `@auth0/auth0-auth-js` | +| `ResponseError` | Management API calls throw `ManagementError` | +| `FetchError` | Management API calls throw `ManagementError` | +| `JSONApiResponse` | Responses return the data directly (no wrapper) | + +`ManagementClient`, the `Management` namespace, and `ManagementError` are unchanged and still exported. + +### ManagementClient mTLS requires an explicit `fetch` + +A `ManagementClient` constructed with `useMTLS: true` must now supply an explicit `fetch` option carrying the client certificate. The client throws at construction if `useMTLS` is set without a `fetch`. Previously a missing fetch surfaced as silent `401`s at request time; failing at construction makes the misconfiguration obvious. + +The token endpoint automatically uses the `mtls.{domain}` host when `useMTLS` is enabled. + +```ts +// v7: throws at construction if `fetch` is omitted +const mgmt = new ManagementClient({ + domain, + clientId, + clientSecret, + useMTLS: true, + fetch: mtlsCapableFetch, // now required +}); +``` + +### mTLS works with both client secret and client assertion + +`useMTLS` works with both `clientSecret` and `clientAssertionSigningKey`. mTLS (RFC 8705) is a transport-layer concern: the TLS client certificate yields a certificate-bound token regardless of which client authentication method is used. An explicit `fetch` option is always required when `useMTLS` is set. + +### `domain` must be a bare hostname + +`domain` must be a bare host such as `tenant.us.auth0.com`. A value that is empty, or that contains a scheme, a path, a query string, a fragment, credentials (`@`), or whitespace, now throws at construction instead of producing malformed request URLs later. The check applies to every authentication mode (`token`, `clientSecret`, and `clientAssertionSigningKey`), and to `createManagementAuth` and `TokenProvider` as well as `ManagementClient`. + +```ts +// throws in v7 +new ManagementClient({ domain: "https://tenant.us.auth0.com/", ... }); +// correct +new ManagementClient({ domain: "tenant.us.auth0.com", ... }); +``` + +### Token acquisition failures throw `ManagementError` + +When the internal client-credentials token request fails, the client now throws a `ManagementError` (previously a plain `Error`). The error carries `statusCode` and a parsed `body` with the OAuth error details. A request that exceeds the 10-second timeout throws `ManagementError` with status `408`. + +```ts +import { ManagementError } from "auth0"; + +try { + await mgmt.users.getAll(); +} catch (e) { + if (e instanceof ManagementError) { + console.error(e.statusCode, e.body); + } +} +``` + +### `uuid` dependency removed + +The `uuid` package is no longer a dependency. If your project imported `uuid` transitively through `auth0`, add it to your own `dependencies`. + +## Migrating authentication code + +If your app calls `AuthenticationClient` or `UserInfoClient`, follow the dedicated [Authentication Migration Guide](https://github.com/auth0/node-auth0/tree/master/auth-migration). Start with [`auth-migration/index.md`](https://github.com/auth0/node-auth0/blob/master/auth-migration/index.md) for the OIDC token grants section; the incremental flow, session, and troubleshooting pages live in the same [`auth-migration/`](https://github.com/auth0/node-auth0/tree/master/auth-migration) directory. It covers: + +- Choosing between `@auth0/auth0-auth-js` (stateless token grants) and `@auth0/auth0-server-js` (server-managed sessions). +- The complete method-by-method API mapping for `.oauth`, `.database`, `.passwordless`, `.backchannel`, `.tokenExchange`, and `UserInfoClient`. +- The four cross-cutting behavior changes: return shape (envelope dropped), casing (snake_case → camelCase), token expiry (`expires_in` relative → `expiresAt` absolute, a silent high-risk change), and the typed error model with `isMfaRequiredError()`. +- Wiring the `auth0-server-js` session lifecycle when you want the SDK to own login, cookies, refresh, and logout. + +The Management API is explicitly out of scope in that guide: a file that keeps using `ManagementClient` from `auth0` while importing `@auth0/auth0-auth-js` for authentication is correct and expected. + +## Staying on the legacy entrypoint + +If you cannot migrate the authentication code immediately, the `auth0/legacy` entrypoint still ships `AuthenticationClient` and `UserInfoClient` at their v4.x configuration format and method signatures. This is a stopgap, not a destination; the legacy shapes differ from the current API and will not receive new features. + +```ts +import { AuthenticationClient } from "auth0/legacy"; +``` + +Plan the move to `@auth0/auth0-auth-js` / `@auth0/auth0-server-js` rather than treating the legacy entrypoint as permanent. From f1f07135f4dc291fdb2157eb48681d715cb591cb Mon Sep 17 00:00:00 2001 From: "ankitatripathi.mp@gmail.com" Date: Wed, 28 Oct 2026 16:46:27 +0530 Subject: [PATCH 3/3] test: restore return type on Stream null-reconnect stub --- src/management/tests/unit/stream/Stream.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/management/tests/unit/stream/Stream.test.ts b/src/management/tests/unit/stream/Stream.test.ts index 670b6f192c..be92ae5906 100644 --- a/src/management/tests/unit/stream/Stream.test.ts +++ b/src/management/tests/unit/stream/Stream.test.ts @@ -1544,7 +1544,7 @@ describe("Stream", () => { describe("SSE stream reconnection - null reconnect body", () => { it("should treat null reconnect body as a failed attempt", async () => { let reconnectCallCount = 0; - const reconnect = async (_lastEventId: string) => { + const reconnect = async (_lastEventId: string): Promise => { reconnectCallCount++; // @ts-expect-error Intentionally returning null to test null-body handling return null;