Skip to content

Commit cfaef3f

Browse files
authored
docs: fix state parameter type documentation to match implementation (#327)
The state parameter in getSignInUrl/getSignUpUrl is implemented as a string (matching OAuth 2.0 RFC 6749 specification), but the documentation showed examples using object literals without JSON serialization. This commit updates all documentation examples to: - Show explicit JSON.stringify() when passing state objects - Show explicit JSON.parse() when reading state in callbacks - Update the type table to reflect string | undefined instead of Record<string, any> - Add a note explaining that state is an opaque string per OAuth 2.0 spec Fixes #326
1 parent e4ed7af commit cfaef3f

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

README.md

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ export const GET = handleAuth({
100100
await saveAuthMethod(user.id, authenticationMethod);
101101
}
102102
// Access custom state data passed through the auth flow
103-
if (state?.teamId) {
104-
await addUserToTeam(user.id, state.teamId);
103+
const customData = state ? JSON.parse(state) : null;
104+
if (customData?.teamId) {
105+
await addUserToTeam(user.id, customData.teamId);
105106
}
106107
},
107108
});
@@ -128,16 +129,16 @@ export const GET = handleAuth({
128129

129130
The `onSuccess` callback receives the following data:
130131

131-
| Property | Type | Description |
132-
| ---------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------- |
133-
| `user` | `User` | The authenticated user object |
134-
| `accessToken` | `string` | JWT access token |
135-
| `refreshToken` | `string` | Refresh token for session renewal |
136-
| `impersonator` | `Impersonator \| undefined` | Present if user is being impersonated |
137-
| `oauthTokens` | `OauthTokens \| undefined` | OAuth tokens from upstream provider |
138-
| `authenticationMethod` | `string \| undefined` | How the user authenticated (e.g., 'password', 'google-oauth'). Only available during initial login |
139-
| `organizationId` | `string \| undefined` | Organization context of authentication |
140-
| `state` | `Record<string, any> \| undefined` | Custom state data passed through the authentication flow |
132+
| Property | Type | Description |
133+
| ---------------------- | --------------------------- | -------------------------------------------------------------------------------------------------- |
134+
| `user` | `User` | The authenticated user object |
135+
| `accessToken` | `string` | JWT access token |
136+
| `refreshToken` | `string` | Refresh token for session renewal |
137+
| `impersonator` | `Impersonator \| undefined` | Present if user is being impersonated |
138+
| `oauthTokens` | `OauthTokens \| undefined` | OAuth tokens from upstream provider |
139+
| `authenticationMethod` | `string \| undefined` | How the user authenticated (e.g., 'password', 'google-oauth'). Only available during initial login |
140+
| `organizationId` | `string \| undefined` | Organization context of authentication |
141+
| `state` | `string \| undefined` | Custom state string passed through the authentication flow (parse with JSON.parse if needed) |
141142

142143
**Note**: `authenticationMethod` is only provided during the initial authentication callback. It will not be available in subsequent requests or session refreshes.
143144

@@ -229,10 +230,10 @@ export default async function HomePage() {
229230

230231
// You can also pass custom state data through the auth flow
231232
const signInUrlWithState = await getSignInUrl({
232-
state: {
233+
state: JSON.stringify({
233234
teamId: 'team_123',
234235
referrer: 'homepage',
235-
},
236+
}),
236237
});
237238

238239
return (
@@ -408,41 +409,46 @@ JWT tokens are sensitive credentials and should be handled carefully:
408409
409410
### Passing Custom State Through Authentication
410411
411-
You can pass custom state data through the authentication flow using the `state` parameter. This data will be available in the `onSuccess` callback after authentication:
412+
You can pass custom state data through the authentication flow using the `state` parameter. The state parameter is a string value that gets passed through OAuth and returned in the callback. To pass complex data, serialize it as JSON:
412413
413414
```ts
414-
// When generating sign-in/sign-up URLs
415+
// When generating sign-in/sign-up URLs, serialize your data as JSON
415416
const signInUrl = await getSignInUrl({
416-
state: {
417+
state: JSON.stringify({
417418
teamId: 'team_123',
418419
feature: 'billing',
419420
referrer: 'pricing-page',
420421
timestamp: Date.now(),
421-
},
422+
}),
422423
});
423424
424425
// The state data is available in the callback handler
425426
export const GET = handleAuth({
426427
onSuccess: async ({ user, state }) => {
428+
// Parse the state string back to an object
429+
const customData = state ? JSON.parse(state) : null;
430+
427431
// Access your custom state data
428-
if (state?.teamId) {
429-
await addUserToTeam(user.id, state.teamId);
432+
if (customData?.teamId) {
433+
await addUserToTeam(user.id, customData.teamId);
430434
}
431435
432-
if (state?.feature) {
433-
await trackFeatureActivation(user.id, state.feature);
436+
if (customData?.feature) {
437+
await trackFeatureActivation(user.id, customData.feature);
434438
}
435439
436440
// Track where the user came from
437441
await analytics.track('sign_in_completed', {
438442
userId: user.id,
439-
referrer: state?.referrer,
440-
timestamp: state?.timestamp,
443+
referrer: customData?.referrer,
444+
timestamp: customData?.timestamp,
441445
});
442446
},
443447
});
444448
```
445449
450+
> **Note**: The `state` parameter is an opaque string as defined by OAuth 2.0 (RFC 6749). If you need to pass structured data, you must serialize it yourself using `JSON.stringify()` and parse it with `JSON.parse()` in the callback.
451+
446452
This is useful for:
447453
448454
- Tracking user journey and referral sources

0 commit comments

Comments
 (0)