Skip to content

Commit 86cc68e

Browse files
[fern-replay] Applied customizations
Patches applied (5): - 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) Patches with unresolved conflicts (11): - 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) Run `fern-replay resolve` to apply these customizations.
1 parent a69df6c commit 86cc68e

9 files changed

Lines changed: 3397 additions & 6 deletions

‎.fern/replay.lock‎

Lines changed: 1912 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎.shiprc‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"files": {
3+
".version": [],
4+
"src/management/version.ts": []
5+
}
6+
}

‎AUTH_MIGRATION_GUIDE.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Authentication Migration Guide
2+
3+
This guide lives in the [`auth-migration/`](./auth-migration/) directory.
4+
5+
**→ 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).
6+
7+
The directory contains:
8+
9+
- [`auth-migration/index.md`](./auth-migration/index.md): the main guide covering OIDC token grants and the four cross-cutting breaking changes.
10+
- [`auth-migration/authentication-flows.md`](./auth-migration/authentication-flows.md): database, passwordless, backchannel (CIBA), token exchange, and `UserInfoClient`.
11+
- [`auth-migration/server-side-sessions.md`](./auth-migration/server-side-sessions.md): the `@auth0/auth0-server-js` session layer.
12+
- [`auth-migration/troubleshooting.md`](./auth-migration/troubleshooting.md): FAQ and gotchas.
13+
14+
> **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`.
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# Migrating the other authentication flows
2+
3+
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.
4+
5+
> **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`).
6+
7+
Migrate one flow at a time. Only the flows your app actually uses need attention; skip the rest.
8+
9+
- [Database connections](#database-connections)
10+
- [Passwordless](#passwordless)
11+
- [Backchannel authentication (CIBA)](#backchannel-authentication-ciba)
12+
- [Token exchange (RFC 8693)](#token-exchange-rfc-8693)
13+
- [UserInfoClient](#userinfoclient)
14+
- [Quick lookup table](#quick-lookup-table)
15+
16+
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`).
17+
18+
## Database connections
19+
20+
Database connection operations move to the `authClient.database` sub-client. Names and required parameters stay the same; only casing and return shape change.
21+
22+
### `database.signUp` → `authClient.database.signUp`
23+
24+
```ts
25+
// before
26+
const resp = await auth0.database.signUp({
27+
email,
28+
password,
29+
connection: "Username-Password-Authentication",
30+
given_name: "Ada",
31+
family_name: "Lovelace",
32+
user_metadata: { plan: "free" },
33+
});
34+
const userId = resp.data.id;
35+
// after
36+
const result = await authClient.database.signUp({
37+
email,
38+
password,
39+
connection: "Username-Password-Authentication",
40+
givenName: "Ada",
41+
familyName: "Lovelace",
42+
userMetadata: { plan: "free" },
43+
});
44+
const userId = result.id;
45+
```
46+
47+
> 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.
48+
49+
### `database.changePassword` → `authClient.database.changePassword`
50+
51+
node-auth0 returned a `TextApiResponse` (read via `.data`); the new SDK returns the plain `string` directly.
52+
53+
```ts
54+
// before
55+
const resp = await auth0.database.changePassword({ email, connection: "Username-Password-Authentication" });
56+
const message = resp.data; // plain-text confirmation
57+
// after
58+
const message = await authClient.database.changePassword({ email, connection: "Username-Password-Authentication" });
59+
```
60+
61+
> `changePassword` requires `connection` plus at least one of `email` or `username`: either identifier is accepted, not `email` alone.
62+
63+
## Passwordless
64+
65+
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`.
66+
67+
### `passwordless.sendEmail` → `authClient.passwordless.sendEmail`
68+
69+
```ts
70+
// before
71+
await auth0.passwordless.sendEmail({ email, send: "code" });
72+
// after
73+
await authClient.passwordless.sendEmail({ email, send: "code" });
74+
```
75+
76+
> 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.
77+
78+
### `passwordless.sendSMS` → `authClient.passwordless.sendSms`
79+
80+
Note the casing change: `sendSMS` → `sendSms`, and `phone_number` → `phoneNumber`.
81+
82+
```ts
83+
// before
84+
await auth0.passwordless.sendSMS({ phone_number: "+15551234567" });
85+
// after
86+
await authClient.passwordless.sendSms({ phoneNumber: "+15551234567" });
87+
```
88+
89+
### `passwordless.loginWithEmail` → `getTokenByPasswordlessEmail`
90+
91+
Redeeming the one-time password is now a grant method on `AuthClient`, not on the passwordless sub-client.
92+
93+
```ts
94+
// before
95+
const resp = await auth0.passwordless.loginWithEmail({ email, code, audience, scope });
96+
const token = resp.data.access_token;
97+
// after
98+
const tokens = await authClient.getTokenByPasswordlessEmail({ email, code, audience, scope });
99+
const token = tokens.accessToken;
100+
```
101+
102+
### `passwordless.loginWithSMS` → `getTokenByPasswordlessSms`
103+
104+
```ts
105+
// before
106+
const resp = await auth0.passwordless.loginWithSMS({ phone_number, code });
107+
// after
108+
const tokens = await authClient.getTokenByPasswordlessSms({ phoneNumber, code });
109+
```
110+
111+
> 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).
112+
113+
## Backchannel authentication (CIBA)
114+
115+
CIBA is Client-Initiated Backchannel Authentication.
116+
117+
### `backchannel.authorize` → `initiateBackchannelAuthentication`
118+
119+
```ts
120+
// before
121+
const resp = await auth0.backchannel.authorize({
122+
binding_message: "ABC123",
123+
scope: "openid",
124+
userId: "auth0|123",
125+
});
126+
const authReqId = resp.auth_req_id;
127+
// after
128+
const { authReqId, expiresIn, interval } = await authClient.initiateBackchannelAuthentication({
129+
bindingMessage: "ABC123",
130+
loginHint: { sub: "auth0|123" }, // login_hint is an object with `sub`, not a bare string
131+
authorizationParams: { scope: "openid" }, // scope goes here, NOT as a top-level key
132+
});
133+
```
134+
135+
### `backchannel.backchannelGrant` → `backchannelAuthenticationGrant`
136+
137+
```ts
138+
// before
139+
const resp = await auth0.backchannel.backchannelGrant({ auth_req_id: authReqId });
140+
// after
141+
const tokens = await authClient.backchannelAuthenticationGrant({ authReqId });
142+
```
143+
144+
> 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.
145+
>
146+
> Session apps: for CIBA that also establishes a session, see [Migrating session apps](./server-side-sessions.md).
147+
148+
## Token exchange (RFC 8693)
149+
150+
```ts
151+
// before
152+
const resp = await auth0.tokenExchange.exchangeToken({
153+
subject_token_type: "urn:example:custom",
154+
subject_token: token,
155+
audience: "https://api.example.com",
156+
scope: "read",
157+
});
158+
// after
159+
const tokens = await authClient.exchangeToken({
160+
subjectTokenType: "urn:example:custom",
161+
subjectToken: token,
162+
audience: "https://api.example.com",
163+
scope: "read",
164+
});
165+
```
166+
167+
> `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`.
168+
>
169+
> Session apps: `@auth0/auth0-server-js` exposes `loginWithCustomTokenExchange` (exchange, then establish a session) and `customTokenExchange` (exchange, then return tokens with no session).
170+
171+
## UserInfoClient
172+
173+
The standalone `UserInfoClient` from node-auth0 does not exist in the new SDK. Choose the replacement based on what the app needs:
174+
175+
| Your intent | Replacement |
176+
| --- | --- |
177+
| 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.** |
178+
| Wanted a live `/userinfo` response for an arbitrary access token | `await authClient.getUserInfo({ accessToken })`, a direct method on `AuthClient`. |
179+
| Wanted the profile in a server-rendered app with a session | `await serverClient.getUser()` returns the stored user claims from the session. |
180+
181+
**Before (node-auth0):**
182+
183+
```ts
184+
import { UserInfoClient } from "auth0";
185+
const userInfo = new UserInfoClient({ domain });
186+
const resp = await userInfo.getUserInfo(accessToken);
187+
const profile = resp.data; // { sub, name, email, ... }
188+
```
189+
190+
**After (preferred): use the claims you already have:**
191+
192+
```ts
193+
const tokens = await authClient.getTokenByCode(callbackUrl, {});
194+
const profile = tokens.claims; // { sub, name, email, ... } decoded from the id_token
195+
```
196+
197+
**After (direct method):** for when you only have an access token:
198+
199+
```ts
200+
// Takes an options object: { accessToken, expectedSubject? }
201+
const profile = await authClient.getUserInfo({ accessToken });
202+
```
203+
204+
> Prefer reading `claims` over any `/userinfo` call: it avoids a network round-trip and the claims are already validated by the SDK.
205+
206+
## Quick lookup table
207+
208+
The complete node-auth0 → new SDK map, including the OIDC methods covered in the main guide.
209+
210+
| node-auth0 | new SDK equivalent | Layer |
211+
| --- | --- | --- |
212+
| `oauth.authorizationCodeGrant` | `authClient.getTokenByCode(url, opts)` | auth-js |
213+
| `oauth.authorizationCodeGrantWithPKCE` | `authClient.getTokenByCode(url, { codeVerifier })` | auth-js |
214+
| `oauth.refreshTokenGrant` | `authClient.getTokenByRefreshToken({ refreshToken })` | auth-js |
215+
| `oauth.passwordGrant` | `authClient.getTokenByPassword({ ... })` | auth-js |
216+
| `oauth.clientCredentialsGrant` | `authClient.getTokenByClientCredentials({ audience })` | auth-js |
217+
| `oauth.revokeRefreshToken` | `authClient.revokeToken({ token })` / `serverClient.revokeRefreshToken()` | auth-js / server-js |
218+
| `oauth.tokenForConnection` | `authClient.exchangeToken({ connection, ... })` | auth-js |
219+
| `oauth.pushedAuthorization` | `authClient.buildAuthorizationUrl({ pushedAuthorizationRequests: true })` | auth-js |
220+
| `database.signUp` | `authClient.database.signUp({ ... })` | auth-js |
221+
| `database.changePassword` | `authClient.database.changePassword({ ... })` | auth-js |
222+
| `passwordless.sendEmail` | `authClient.passwordless.sendEmail({ ... })` | auth-js |
223+
| `passwordless.sendSMS` | `authClient.passwordless.sendSms({ phoneNumber })` | auth-js |
224+
| `passwordless.loginWithEmail` | `authClient.getTokenByPasswordlessEmail({ ... })` | auth-js |
225+
| `passwordless.loginWithSMS` | `authClient.getTokenByPasswordlessSms({ ... })` | auth-js |
226+
| `backchannel.authorize` | `authClient.initiateBackchannelAuthentication({ ... })` | auth-js |
227+
| `backchannel.backchannelGrant` | `authClient.backchannelAuthenticationGrant({ authReqId })` | auth-js |
228+
| `tokenExchange.exchangeToken` | `authClient.exchangeToken({ subjectTokenType, subjectToken, audience })` | auth-js |
229+
| `UserInfoClient.getUserInfo` | `TokenResponse.claims` (preferred) / `authClient.getUserInfo({ accessToken })` / `serverClient.getUser()` | auth-js / server-js |
230+
| (no equivalent): build `/authorize` URL | `authClient.buildAuthorizationUrl({ ... })` | auth-js |
231+
| (no equivalent): build `/v2/logout` URL | `authClient.buildLogoutUrl({ returnTo })` | auth-js |
232+
| `ManagementClient.*` | **not migrated, stays on `auth0`** | n/a |
233+
234+
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.

0 commit comments

Comments
 (0)