@workos-inc/authkit-nextjs 2.9.0 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -14
- package/dist/esm/auth.js +4 -4
- package/dist/esm/auth.js.map +1 -1
- package/dist/esm/authkit-callback-route.js +37 -2
- package/dist/esm/authkit-callback-route.js.map +1 -1
- package/dist/esm/get-authorization-url.js +6 -2
- package/dist/esm/get-authorization-url.js.map +1 -1
- package/dist/esm/test-helpers.js +1 -0
- package/dist/esm/test-helpers.js.map +1 -1
- package/dist/esm/types/auth.d.ts +4 -2
- package/dist/esm/types/interfaces.d.ts +2 -0
- package/dist/esm/types/workos.d.ts +1 -1
- package/dist/esm/workos.js +1 -1
- package/dist/esm/workos.js.map +1 -1
- package/package.json +2 -2
- package/src/auth.ts +18 -4
- package/src/authkit-callback-route.spec.ts +69 -0
- package/src/authkit-callback-route.ts +35 -2
- package/src/get-authorization-url.ts +9 -1
- package/src/interfaces.ts +2 -0
- package/src/session.spec.ts +10 -1
- package/src/test-helpers.ts +1 -0
- package/src/workos.ts +1 -1
package/README.md
CHANGED
|
@@ -94,11 +94,15 @@ If your application needs to persist data upon a successful authentication, like
|
|
|
94
94
|
|
|
95
95
|
```ts
|
|
96
96
|
export const GET = handleAuth({
|
|
97
|
-
onSuccess: async ({ user, oauthTokens, authenticationMethod, organizationId }) => {
|
|
97
|
+
onSuccess: async ({ user, oauthTokens, authenticationMethod, organizationId, state }) => {
|
|
98
98
|
await saveTokens(oauthTokens);
|
|
99
99
|
if (authenticationMethod) {
|
|
100
100
|
await saveAuthMethod(user.id, authenticationMethod);
|
|
101
101
|
}
|
|
102
|
+
// Access custom state data passed through the auth flow
|
|
103
|
+
if (state?.teamId) {
|
|
104
|
+
await addUserToTeam(user.id, state.teamId);
|
|
105
|
+
}
|
|
102
106
|
},
|
|
103
107
|
});
|
|
104
108
|
```
|
|
@@ -124,15 +128,16 @@ export const GET = handleAuth({
|
|
|
124
128
|
|
|
125
129
|
The `onSuccess` callback receives the following data:
|
|
126
130
|
|
|
127
|
-
| Property | Type
|
|
128
|
-
| ---------------------- |
|
|
129
|
-
| `user` | `User`
|
|
130
|
-
| `accessToken` | `string`
|
|
131
|
-
| `refreshToken` | `string`
|
|
132
|
-
| `impersonator` | `Impersonator \| undefined`
|
|
133
|
-
| `oauthTokens` | `OauthTokens \| undefined`
|
|
134
|
-
| `authenticationMethod` | `string \| undefined`
|
|
135
|
-
| `organizationId` | `string \| undefined`
|
|
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 |
|
|
136
141
|
|
|
137
142
|
**Note**: `authenticationMethod` is only provided during the initial authentication callback. It will not be available in subsequent requests or session refreshes.
|
|
138
143
|
|
|
@@ -217,6 +222,14 @@ export default async function HomePage() {
|
|
|
217
222
|
// Get the URL to redirect the user to AuthKit to sign up
|
|
218
223
|
const signUpUrl = await getSignUpUrl();
|
|
219
224
|
|
|
225
|
+
// You can also pass custom state data through the auth flow
|
|
226
|
+
const signInUrlWithState = await getSignInUrl({
|
|
227
|
+
state: {
|
|
228
|
+
teamId: 'team_123',
|
|
229
|
+
referrer: 'homepage',
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
|
|
220
233
|
return (
|
|
221
234
|
<>
|
|
222
235
|
<Link href={signInUrl}>Log in</Link>
|
|
@@ -244,7 +257,7 @@ export default async function HomePage() {
|
|
|
244
257
|
For client components, use the `useAuth` hook to get the current user session.
|
|
245
258
|
|
|
246
259
|
```jsx
|
|
247
|
-
'use client'
|
|
260
|
+
'use client';
|
|
248
261
|
// Note the updated import path
|
|
249
262
|
import { useAuth } from '@workos-inc/authkit-nextjs/components';
|
|
250
263
|
|
|
@@ -260,6 +273,14 @@ export default function MyComponent() {
|
|
|
260
273
|
}
|
|
261
274
|
```
|
|
262
275
|
|
|
276
|
+
### Get the enabled flags for the logged in user
|
|
277
|
+
|
|
278
|
+
For situations where you need access to the authenticated user's currently active feature flags, use `withAuth` to retrieve the flags from the WorkOS session.
|
|
279
|
+
|
|
280
|
+
```jsx
|
|
281
|
+
const { featureFlags } = await withAuth();
|
|
282
|
+
```
|
|
283
|
+
|
|
263
284
|
### Requiring auth
|
|
264
285
|
|
|
265
286
|
For pages where a signed-in user is mandatory, you can use the `ensureSignedIn` option:
|
|
@@ -380,6 +401,50 @@ JWT tokens are sensitive credentials and should be handled carefully:
|
|
|
380
401
|
- Don't store tokens in localStorage or sessionStorage
|
|
381
402
|
- Be cautious about exposing tokens in your application state
|
|
382
403
|
|
|
404
|
+
### Passing Custom State Through Authentication
|
|
405
|
+
|
|
406
|
+
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:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
// When generating sign-in/sign-up URLs
|
|
410
|
+
const signInUrl = await getSignInUrl({
|
|
411
|
+
state: {
|
|
412
|
+
teamId: 'team_123',
|
|
413
|
+
feature: 'billing',
|
|
414
|
+
referrer: 'pricing-page',
|
|
415
|
+
timestamp: Date.now(),
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
// The state data is available in the callback handler
|
|
420
|
+
export const GET = handleAuth({
|
|
421
|
+
onSuccess: async ({ user, state }) => {
|
|
422
|
+
// Access your custom state data
|
|
423
|
+
if (state?.teamId) {
|
|
424
|
+
await addUserToTeam(user.id, state.teamId);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (state?.feature) {
|
|
428
|
+
await trackFeatureActivation(user.id, state.feature);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Track where the user came from
|
|
432
|
+
await analytics.track('sign_in_completed', {
|
|
433
|
+
userId: user.id,
|
|
434
|
+
referrer: state?.referrer,
|
|
435
|
+
timestamp: state?.timestamp,
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
This is useful for:
|
|
442
|
+
|
|
443
|
+
- Tracking user journey and referral sources
|
|
444
|
+
- Maintaining context about what the user was trying to do before authentication
|
|
445
|
+
- Implementing custom onboarding flows
|
|
446
|
+
- Analytics and attribution tracking
|
|
447
|
+
|
|
383
448
|
### Session Refresh Callbacks
|
|
384
449
|
|
|
385
450
|
When using the `authkit` function directly, you can provide callbacks to be notified when a session is refreshed:
|
|
@@ -461,10 +526,10 @@ Then access the token synchronously in your client components:
|
|
|
461
526
|
```tsx
|
|
462
527
|
'use client';
|
|
463
528
|
|
|
464
|
-
import {
|
|
529
|
+
import { useAccessToken } from '@workos-inc/authkit-nextjs/components';
|
|
465
530
|
|
|
466
531
|
function MyComponent() {
|
|
467
|
-
const { getAccessToken } =
|
|
532
|
+
const { getAccessToken } = useAccessToken();
|
|
468
533
|
|
|
469
534
|
// Token is available immediately on initial page load
|
|
470
535
|
const token = getAccessToken();
|
|
@@ -704,6 +769,6 @@ export default authkitMiddleware({ debug: true });
|
|
|
704
769
|
|
|
705
770
|
Wrapping a `withAuth({ ensureSignedIn: true })` call in a try/catch block will cause a `NEXT_REDIRECT` error. This is because `withAuth` will attempt to redirect the user to AuthKit if no session is detected and redirects in Next must be [called outside a try/catch](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#redirecting).
|
|
706
771
|
|
|
707
|
-
#### Module build failed: UnhandledSchemeError: Reading from "node:crypto" is not handled by plugins (Unhandled scheme)
|
|
772
|
+
#### Module build failed: UnhandledSchemeError: Reading from "node:crypto" is not handled by plugins (Unhandled scheme)
|
|
708
773
|
|
|
709
774
|
You may encounter this error if you attempt to import server side code from authkit-nextjs into a client component. Likely you are using `withAuth` in a client component instead of the `useAuth` hook. Either move the code to a server component or use the `useAuth` hook.
|
package/dist/esm/auth.js
CHANGED
|
@@ -8,11 +8,11 @@ import { getCookieOptions } from './cookie.js';
|
|
|
8
8
|
import { getAuthorizationUrl } from './get-authorization-url.js';
|
|
9
9
|
import { getSessionFromCookie, refreshSession, withAuth } from './session.js';
|
|
10
10
|
import { getWorkOS } from './workos.js';
|
|
11
|
-
export async function getSignInUrl({ organizationId, loginHint, redirectUri, prompt, } = {}) {
|
|
12
|
-
return getAuthorizationUrl({ organizationId, screenHint: 'sign-in', loginHint, redirectUri, prompt });
|
|
11
|
+
export async function getSignInUrl({ organizationId, loginHint, redirectUri, prompt, state, } = {}) {
|
|
12
|
+
return getAuthorizationUrl({ organizationId, screenHint: 'sign-in', loginHint, redirectUri, prompt, state });
|
|
13
13
|
}
|
|
14
|
-
export async function getSignUpUrl({ organizationId, loginHint, redirectUri, prompt, } = {}) {
|
|
15
|
-
return getAuthorizationUrl({ organizationId, screenHint: 'sign-up', loginHint, redirectUri, prompt });
|
|
14
|
+
export async function getSignUpUrl({ organizationId, loginHint, redirectUri, prompt, state, } = {}) {
|
|
15
|
+
return getAuthorizationUrl({ organizationId, screenHint: 'sign-up', loginHint, redirectUri, prompt, state });
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* Sign out the user and delete the session cookie.
|
package/dist/esm/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EACjC,cAAc,EACd,SAAS,EACT,WAAW,EACX,MAAM,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,40 @@ import { WORKOS_CLIENT_ID } from './env-variables.js';
|
|
|
2
2
|
import { saveSession } from './session.js';
|
|
3
3
|
import { errorResponseWithFallback, redirectWithFallback } from './utils.js';
|
|
4
4
|
import { getWorkOS } from './workos.js';
|
|
5
|
+
function handleState(state) {
|
|
6
|
+
let returnPathname = undefined;
|
|
7
|
+
let userState;
|
|
8
|
+
if (state === null || state === void 0 ? void 0 : state.includes('.')) {
|
|
9
|
+
const [internal, ...rest] = state.split('.');
|
|
10
|
+
userState = rest.join('.');
|
|
11
|
+
try {
|
|
12
|
+
// Reverse URL-safe base64 encoding
|
|
13
|
+
const decoded = internal.replace(/-/g, '+').replace(/_/g, '/');
|
|
14
|
+
returnPathname = JSON.parse(atob(decoded)).returnPathname;
|
|
15
|
+
}
|
|
16
|
+
catch (_a) {
|
|
17
|
+
// Malformed internal part, ignore it
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (state) {
|
|
21
|
+
try {
|
|
22
|
+
const decoded = JSON.parse(atob(state));
|
|
23
|
+
if (decoded.returnPathname) {
|
|
24
|
+
returnPathname = decoded.returnPathname;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
userState = state;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (_b) {
|
|
31
|
+
userState = state;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
returnPathname,
|
|
36
|
+
state: userState,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
5
39
|
export function handleAuth(options = {}) {
|
|
6
40
|
const { returnPathname: returnPathnameOption = '/', baseURL, onSuccess, onError } = options;
|
|
7
41
|
// Throw early if baseURL is provided but invalid
|
|
@@ -16,7 +50,7 @@ export function handleAuth(options = {}) {
|
|
|
16
50
|
return async function GET(request) {
|
|
17
51
|
const code = request.nextUrl.searchParams.get('code');
|
|
18
52
|
const state = request.nextUrl.searchParams.get('state');
|
|
19
|
-
|
|
53
|
+
const { state: customState, returnPathname: returnPathnameState } = handleState(state);
|
|
20
54
|
if (code) {
|
|
21
55
|
try {
|
|
22
56
|
// Use the code returned to us by AuthKit and authenticate the user with WorkOS
|
|
@@ -32,7 +66,7 @@ export function handleAuth(options = {}) {
|
|
|
32
66
|
url.searchParams.delete('code');
|
|
33
67
|
url.searchParams.delete('state');
|
|
34
68
|
// Redirect to the requested path and store the session
|
|
35
|
-
returnPathname =
|
|
69
|
+
const returnPathname = returnPathnameState !== null && returnPathnameState !== void 0 ? returnPathnameState : returnPathnameOption;
|
|
36
70
|
// Extract the search params if they are present
|
|
37
71
|
if (returnPathname.includes('?')) {
|
|
38
72
|
const newUrl = new URL(returnPathname, 'https://example.com');
|
|
@@ -59,6 +93,7 @@ export function handleAuth(options = {}) {
|
|
|
59
93
|
oauthTokens,
|
|
60
94
|
authenticationMethod,
|
|
61
95
|
organizationId,
|
|
96
|
+
state: customState,
|
|
62
97
|
});
|
|
63
98
|
}
|
|
64
99
|
return response;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authkit-callback-route.js","sourceRoot":"","sources":["../../src/authkit-callback-route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,UAAU,UAAU,CAAC,UAA6B,EAAE;IACxD,MAAM,EAAE,cAAc,EAAE,oBAAoB,GAAG,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5F,iDAAiD;IACjD,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,UAAU,GAAG,CAAC,OAAoB;QAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"authkit-callback-route.js","sourceRoot":"","sources":["../../src/authkit-callback-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,16 @@ import { WORKOS_CLIENT_ID, WORKOS_REDIRECT_URI } from './env-variables.js';
|
|
|
3
3
|
import { headers } from 'next/headers';
|
|
4
4
|
async function getAuthorizationUrl(options = {}) {
|
|
5
5
|
const headersList = await headers();
|
|
6
|
-
const { returnPathname, screenHint, organizationId, redirectUri = headersList.get('x-redirect-uri'), loginHint, prompt, } = options;
|
|
6
|
+
const { returnPathname, screenHint, organizationId, redirectUri = headersList.get('x-redirect-uri'), loginHint, prompt, state: customState, } = options;
|
|
7
|
+
const internalState = returnPathname
|
|
8
|
+
? btoa(JSON.stringify({ returnPathname })).replace(/\+/g, '-').replace(/\//g, '_')
|
|
9
|
+
: null;
|
|
10
|
+
const finalState = internalState && customState ? `${internalState}.${customState}` : internalState || customState || undefined;
|
|
7
11
|
return getWorkOS().userManagement.getAuthorizationUrl({
|
|
8
12
|
provider: 'authkit',
|
|
9
13
|
clientId: WORKOS_CLIENT_ID,
|
|
10
14
|
redirectUri: redirectUri !== null && redirectUri !== void 0 ? redirectUri : WORKOS_REDIRECT_URI,
|
|
11
|
-
state:
|
|
15
|
+
state: finalState,
|
|
12
16
|
screenHint,
|
|
13
17
|
organizationId,
|
|
14
18
|
loginHint,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-authorization-url.js","sourceRoot":"","sources":["../../src/get-authorization-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,KAAK,UAAU,mBAAmB,CAAC,UAA6B,EAAE;IAChE,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,MAAM,EACJ,cAAc,EACd,UAAU,EACV,cAAc,EACd,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAC/C,SAAS,EACT,MAAM,
|
|
1
|
+
{"version":3,"file":"get-authorization-url.js","sourceRoot":"","sources":["../../src/get-authorization-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,KAAK,UAAU,mBAAmB,CAAC,UAA6B,EAAE;IAChE,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,MAAM,EACJ,cAAc,EACd,UAAU,EACV,cAAc,EACd,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAC/C,SAAS,EACT,MAAM,EACN,KAAK,EAAE,WAAW,GACnB,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GAAG,cAAc;QAClC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QAClF,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,UAAU,GACd,aAAa,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,aAAa,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,aAAa,IAAI,WAAW,IAAI,SAAS,CAAC;IAE/G,OAAO,SAAS,EAAE,CAAC,cAAc,CAAC,mBAAmB,CAAC;QACpD,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,gBAAgB;QAC1B,WAAW,EAAE,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,mBAAmB;QAC/C,KAAK,EAAE,UAAU;QACjB,UAAU;QACV,cAAc;QACd,SAAS;QACT,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
package/dist/esm/test-helpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/test-helpers.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,KAAK;IACnE,MAAM,cAAc,GAAG;QACrB,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,WAAW,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;QAC7C,YAAY,EAAE,CAAC,YAAY,CAAC;QAC5B,aAAa,EAAE,CAAC,4BAA4B,CAAC;KAC9C,CAAC;IAEF,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;IAExD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAgC,CAAC,CAAC;IAEtF,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;SAC3C,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,WAAW,EAAE;SACb,SAAS,CAAC,oBAAoB,CAAC;SAC/B,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;SACxC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAA2B,EAAE;IACjE,MAAM,QAAQ,GAAG;QACf,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,kBAAkB;QACzB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,SAAS,EAAE,MAAM;QACjB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,sBAAsB;QACjC,SAAS,EAAE,sBAAsB;QACjC,YAAY,EAAE,sBAAsB;QACpC,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,EAAE;QACZ,GAAG,SAAS;KACE,CAAC;IAEjB,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC;QAC1C,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CACrC;QACE,WAAW;QACX,YAAY,EAAE,mBAAmB;QACjC,IAAI,EAAE,QAAQ;KACf,EACD;QACE,QAAQ,EAAE,sBAAgC;KAC3C,CACF,CAAC;IAEF,MAAM,UAAU,GAAG,kBAAkB,IAAI,aAAa,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAChD,CAAC"}
|
|
1
|
+
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/test-helpers.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,KAAK;IACnE,MAAM,cAAc,GAAG;QACrB,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,WAAW,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;QAC7C,YAAY,EAAE,CAAC,YAAY,CAAC;QAC5B,aAAa,EAAE,CAAC,4BAA4B,CAAC;KAC9C,CAAC;IAEF,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;IAExD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAgC,CAAC,CAAC;IAEtF,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;SAC3C,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,WAAW,EAAE;SACb,SAAS,CAAC,oBAAoB,CAAC;SAC/B,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;SACxC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAA2B,EAAE;IACjE,MAAM,QAAQ,GAAG;QACf,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,kBAAkB;QACzB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,SAAS,EAAE,MAAM;QACjB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,sBAAsB;QACjC,SAAS,EAAE,sBAAsB;QACjC,YAAY,EAAE,sBAAsB;QACpC,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,EAAE;QACZ,GAAG,SAAS;KACE,CAAC;IAEjB,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC;QAC1C,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CACrC;QACE,WAAW;QACX,YAAY,EAAE,mBAAmB;QACjC,IAAI,EAAE,QAAQ;KACf,EACD;QACE,QAAQ,EAAE,sBAAgC;KAC3C,CACF,CAAC;IAEF,MAAM,UAAU,GAAG,kBAAkB,IAAI,aAAa,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/esm/types/auth.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import type { SwitchToOrganizationOptions, UserInfo } from './interfaces.js';
|
|
2
|
-
export declare function getSignInUrl({ organizationId, loginHint, redirectUri, prompt, }?: {
|
|
2
|
+
export declare function getSignInUrl({ organizationId, loginHint, redirectUri, prompt, state, }?: {
|
|
3
3
|
organizationId?: string;
|
|
4
4
|
loginHint?: string;
|
|
5
5
|
redirectUri?: string;
|
|
6
6
|
prompt?: 'consent';
|
|
7
|
+
state?: string;
|
|
7
8
|
}): Promise<string>;
|
|
8
|
-
export declare function getSignUpUrl({ organizationId, loginHint, redirectUri, prompt, }?: {
|
|
9
|
+
export declare function getSignUpUrl({ organizationId, loginHint, redirectUri, prompt, state, }?: {
|
|
9
10
|
organizationId?: string;
|
|
10
11
|
loginHint?: string;
|
|
11
12
|
redirectUri?: string;
|
|
12
13
|
prompt?: 'consent';
|
|
14
|
+
state?: string;
|
|
13
15
|
}): Promise<string>;
|
|
14
16
|
/**
|
|
15
17
|
* Sign out the user and delete the session cookie.
|
|
@@ -13,6 +13,7 @@ export interface HandleAuthSuccessData extends Session {
|
|
|
13
13
|
oauthTokens?: OauthTokens;
|
|
14
14
|
organizationId?: string;
|
|
15
15
|
authenticationMethod?: AuthenticationResponse['authenticationMethod'];
|
|
16
|
+
state?: string | undefined;
|
|
16
17
|
}
|
|
17
18
|
export interface Impersonator {
|
|
18
19
|
email: string;
|
|
@@ -64,6 +65,7 @@ export interface GetAuthURLOptions {
|
|
|
64
65
|
redirectUri?: string;
|
|
65
66
|
loginHint?: string;
|
|
66
67
|
prompt?: 'consent';
|
|
68
|
+
state?: string;
|
|
67
69
|
}
|
|
68
70
|
export interface AuthkitMiddlewareAuth {
|
|
69
71
|
enabled: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WorkOS } from '@workos-inc/node';
|
|
2
|
-
export declare const VERSION = "2.
|
|
2
|
+
export declare const VERSION = "2.10.0";
|
|
3
3
|
/**
|
|
4
4
|
* Create a WorkOS instance with the provided API key and options.
|
|
5
5
|
* If an instance already exists, it returns the existing instance.
|
package/dist/esm/workos.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WorkOS } from '@workos-inc/node';
|
|
2
2
|
import { WORKOS_API_HOSTNAME, WORKOS_API_KEY, WORKOS_API_HTTPS, WORKOS_API_PORT } from './env-variables.js';
|
|
3
3
|
import { lazy } from './utils.js';
|
|
4
|
-
export const VERSION = '2.
|
|
4
|
+
export const VERSION = '2.10.0';
|
|
5
5
|
const options = {
|
|
6
6
|
apiHostname: WORKOS_API_HOSTNAME,
|
|
7
7
|
https: WORKOS_API_HTTPS ? WORKOS_API_HTTPS === 'true' : true,
|
package/dist/esm/workos.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workos.js","sourceRoot":"","sources":["../../src/workos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"workos.js","sourceRoot":"","sources":["../../src/workos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAEhC,MAAM,OAAO,GAAG;IACd,WAAW,EAAE,mBAAmB;IAChC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI;IAC5D,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS;IAC7D,OAAO,EAAE;QACP,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;KACjB;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workos-inc/authkit-nextjs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta.1",
|
|
4
4
|
"description": "Authentication and session helpers for using WorkOS & AuthKit with Next.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"type-check": "tsc --project tsconfig.json --noEmit"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@workos-inc/node": "^
|
|
38
|
+
"@workos-inc/node": "^8.0.0-rc.1",
|
|
39
39
|
"iron-session": "^8.0.1",
|
|
40
40
|
"jose": "^5.2.3",
|
|
41
41
|
"path-to-regexp": "^6.2.2"
|
package/src/auth.ts
CHANGED
|
@@ -15,8 +15,15 @@ export async function getSignInUrl({
|
|
|
15
15
|
loginHint,
|
|
16
16
|
redirectUri,
|
|
17
17
|
prompt,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
state,
|
|
19
|
+
}: {
|
|
20
|
+
organizationId?: string;
|
|
21
|
+
loginHint?: string;
|
|
22
|
+
redirectUri?: string;
|
|
23
|
+
prompt?: 'consent';
|
|
24
|
+
state?: string;
|
|
25
|
+
} = {}) {
|
|
26
|
+
return getAuthorizationUrl({ organizationId, screenHint: 'sign-in', loginHint, redirectUri, prompt, state });
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
export async function getSignUpUrl({
|
|
@@ -24,8 +31,15 @@ export async function getSignUpUrl({
|
|
|
24
31
|
loginHint,
|
|
25
32
|
redirectUri,
|
|
26
33
|
prompt,
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
state,
|
|
35
|
+
}: {
|
|
36
|
+
organizationId?: string;
|
|
37
|
+
loginHint?: string;
|
|
38
|
+
redirectUri?: string;
|
|
39
|
+
prompt?: 'consent';
|
|
40
|
+
state?: string;
|
|
41
|
+
} = {}) {
|
|
42
|
+
return getAuthorizationUrl({ organizationId, screenHint: 'sign-up', loginHint, redirectUri, prompt, state });
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
/**
|
|
@@ -34,6 +34,7 @@ describe('authkit-callback-route', () => {
|
|
|
34
34
|
createdAt: '2024-01-01T00:00:00Z',
|
|
35
35
|
updatedAt: '2024-01-01T00:00:00Z',
|
|
36
36
|
lastSignInAt: '2024-01-01T00:00:00Z',
|
|
37
|
+
locale: null,
|
|
37
38
|
externalId: null,
|
|
38
39
|
metadata: {},
|
|
39
40
|
},
|
|
@@ -275,5 +276,73 @@ describe('authkit-callback-route', () => {
|
|
|
275
276
|
const session = await getSessionFromCookie();
|
|
276
277
|
expect(session?.accessToken).toBe(newAccessToken);
|
|
277
278
|
});
|
|
279
|
+
|
|
280
|
+
it('should pass custom state data to onSuccess callback', async () => {
|
|
281
|
+
jest.mocked(workos.userManagement.authenticateWithCode).mockResolvedValue(mockAuthResponse);
|
|
282
|
+
|
|
283
|
+
// Create state with new format: internal.user
|
|
284
|
+
const internalState = btoa(JSON.stringify({ returnPathname: '/dashboard' }))
|
|
285
|
+
.replace(/\+/g, '-')
|
|
286
|
+
.replace(/\//g, '_');
|
|
287
|
+
const userState = 'custom-user-state-string';
|
|
288
|
+
const state = `${internalState}.${userState}`;
|
|
289
|
+
|
|
290
|
+
request.nextUrl.searchParams.set('code', 'test-code');
|
|
291
|
+
request.nextUrl.searchParams.set('state', state);
|
|
292
|
+
|
|
293
|
+
const onSuccess = jest.fn();
|
|
294
|
+
const handler = handleAuth({ onSuccess });
|
|
295
|
+
await handler(request);
|
|
296
|
+
|
|
297
|
+
// Verify onSuccess was called with the custom state string
|
|
298
|
+
expect(onSuccess).toHaveBeenCalledWith(
|
|
299
|
+
expect.objectContaining({
|
|
300
|
+
...mockAuthResponse,
|
|
301
|
+
state: 'custom-user-state-string',
|
|
302
|
+
}),
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// Verify the redirect went to the correct path
|
|
306
|
+
const response = await handler(request);
|
|
307
|
+
expect(response.headers.get('Location')).toContain('/dashboard');
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('should handle state without custom data', async () => {
|
|
311
|
+
jest.mocked(workos.userManagement.authenticateWithCode).mockResolvedValue(mockAuthResponse);
|
|
312
|
+
|
|
313
|
+
// State with only returnPathname
|
|
314
|
+
const state = btoa(JSON.stringify({ returnPathname: '/profile' }));
|
|
315
|
+
|
|
316
|
+
request.nextUrl.searchParams.set('code', 'test-code');
|
|
317
|
+
request.nextUrl.searchParams.set('state', state);
|
|
318
|
+
|
|
319
|
+
const onSuccess = jest.fn();
|
|
320
|
+
const handler = handleAuth({ onSuccess });
|
|
321
|
+
await handler(request);
|
|
322
|
+
|
|
323
|
+
// Verify onSuccess was called without state property when no custom data exists
|
|
324
|
+
expect(onSuccess).toHaveBeenCalledWith(
|
|
325
|
+
expect.objectContaining({
|
|
326
|
+
...mockAuthResponse,
|
|
327
|
+
state: undefined,
|
|
328
|
+
}),
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('should handle backward compatibility with old state format', async () => {
|
|
333
|
+
jest.mocked(workos.userManagement.authenticateWithCode).mockResolvedValue(mockAuthResponse);
|
|
334
|
+
|
|
335
|
+
// Old format: just returnPathname
|
|
336
|
+
const state = btoa(JSON.stringify({ returnPathname: '/old-path' }));
|
|
337
|
+
|
|
338
|
+
request.nextUrl.searchParams.set('code', 'test-code');
|
|
339
|
+
request.nextUrl.searchParams.set('state', state);
|
|
340
|
+
|
|
341
|
+
const handler = handleAuth();
|
|
342
|
+
const response = await handler(request);
|
|
343
|
+
|
|
344
|
+
// Should still redirect correctly
|
|
345
|
+
expect(response.headers.get('Location')).toContain('/old-path');
|
|
346
|
+
});
|
|
278
347
|
});
|
|
279
348
|
});
|
|
@@ -5,6 +5,37 @@ import { saveSession } from './session.js';
|
|
|
5
5
|
import { errorResponseWithFallback, redirectWithFallback } from './utils.js';
|
|
6
6
|
import { getWorkOS } from './workos.js';
|
|
7
7
|
|
|
8
|
+
function handleState(state: string | null) {
|
|
9
|
+
let returnPathname: string | undefined = undefined;
|
|
10
|
+
let userState: string | undefined;
|
|
11
|
+
if (state?.includes('.')) {
|
|
12
|
+
const [internal, ...rest] = state.split('.');
|
|
13
|
+
userState = rest.join('.');
|
|
14
|
+
try {
|
|
15
|
+
// Reverse URL-safe base64 encoding
|
|
16
|
+
const decoded = internal.replace(/-/g, '+').replace(/_/g, '/');
|
|
17
|
+
returnPathname = JSON.parse(atob(decoded)).returnPathname;
|
|
18
|
+
} catch {
|
|
19
|
+
// Malformed internal part, ignore it
|
|
20
|
+
}
|
|
21
|
+
} else if (state) {
|
|
22
|
+
try {
|
|
23
|
+
const decoded = JSON.parse(atob(state));
|
|
24
|
+
if (decoded.returnPathname) {
|
|
25
|
+
returnPathname = decoded.returnPathname;
|
|
26
|
+
} else {
|
|
27
|
+
userState = state;
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
userState = state;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
returnPathname,
|
|
35
|
+
state: userState,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
8
39
|
export function handleAuth(options: HandleAuthOptions = {}) {
|
|
9
40
|
const { returnPathname: returnPathnameOption = '/', baseURL, onSuccess, onError } = options;
|
|
10
41
|
|
|
@@ -20,7 +51,8 @@ export function handleAuth(options: HandleAuthOptions = {}) {
|
|
|
20
51
|
return async function GET(request: NextRequest) {
|
|
21
52
|
const code = request.nextUrl.searchParams.get('code');
|
|
22
53
|
const state = request.nextUrl.searchParams.get('state');
|
|
23
|
-
|
|
54
|
+
|
|
55
|
+
const { state: customState, returnPathname: returnPathnameState } = handleState(state);
|
|
24
56
|
|
|
25
57
|
if (code) {
|
|
26
58
|
try {
|
|
@@ -41,7 +73,7 @@ export function handleAuth(options: HandleAuthOptions = {}) {
|
|
|
41
73
|
url.searchParams.delete('state');
|
|
42
74
|
|
|
43
75
|
// Redirect to the requested path and store the session
|
|
44
|
-
returnPathname =
|
|
76
|
+
const returnPathname = returnPathnameState ?? returnPathnameOption;
|
|
45
77
|
|
|
46
78
|
// Extract the search params if they are present
|
|
47
79
|
if (returnPathname.includes('?')) {
|
|
@@ -72,6 +104,7 @@ export function handleAuth(options: HandleAuthOptions = {}) {
|
|
|
72
104
|
oauthTokens,
|
|
73
105
|
authenticationMethod,
|
|
74
106
|
organizationId,
|
|
107
|
+
state: customState,
|
|
75
108
|
});
|
|
76
109
|
}
|
|
77
110
|
|
|
@@ -12,13 +12,21 @@ async function getAuthorizationUrl(options: GetAuthURLOptions = {}) {
|
|
|
12
12
|
redirectUri = headersList.get('x-redirect-uri'),
|
|
13
13
|
loginHint,
|
|
14
14
|
prompt,
|
|
15
|
+
state: customState,
|
|
15
16
|
} = options;
|
|
16
17
|
|
|
18
|
+
const internalState = returnPathname
|
|
19
|
+
? btoa(JSON.stringify({ returnPathname })).replace(/\+/g, '-').replace(/\//g, '_')
|
|
20
|
+
: null;
|
|
21
|
+
|
|
22
|
+
const finalState =
|
|
23
|
+
internalState && customState ? `${internalState}.${customState}` : internalState || customState || undefined;
|
|
24
|
+
|
|
17
25
|
return getWorkOS().userManagement.getAuthorizationUrl({
|
|
18
26
|
provider: 'authkit',
|
|
19
27
|
clientId: WORKOS_CLIENT_ID,
|
|
20
28
|
redirectUri: redirectUri ?? WORKOS_REDIRECT_URI,
|
|
21
|
-
state:
|
|
29
|
+
state: finalState,
|
|
22
30
|
screenHint,
|
|
23
31
|
organizationId,
|
|
24
32
|
loginHint,
|
package/src/interfaces.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface HandleAuthSuccessData extends Session {
|
|
|
12
12
|
oauthTokens?: OauthTokens;
|
|
13
13
|
organizationId?: string;
|
|
14
14
|
authenticationMethod?: AuthenticationResponse['authenticationMethod'];
|
|
15
|
+
state?: string | undefined;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export interface Impersonator {
|
|
@@ -67,6 +68,7 @@ export interface GetAuthURLOptions {
|
|
|
67
68
|
redirectUri?: string;
|
|
68
69
|
loginHint?: string;
|
|
69
70
|
prompt?: 'consent';
|
|
71
|
+
state?: string;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
export interface AuthkitMiddlewareAuth {
|
package/src/session.spec.ts
CHANGED
|
@@ -42,6 +42,10 @@ describe('session.ts', () => {
|
|
|
42
42
|
profilePictureUrl: null,
|
|
43
43
|
firstName: null,
|
|
44
44
|
lastName: null,
|
|
45
|
+
lastSignInAt: null,
|
|
46
|
+
locale: null,
|
|
47
|
+
externalId: null,
|
|
48
|
+
metadata: {},
|
|
45
49
|
createdAt: '2024-01-01',
|
|
46
50
|
updatedAt: '2024-01-01',
|
|
47
51
|
} as User,
|
|
@@ -146,7 +150,12 @@ describe('session.ts', () => {
|
|
|
146
150
|
|
|
147
151
|
await withAuth({ ensureSignedIn: true });
|
|
148
152
|
|
|
149
|
-
|
|
153
|
+
// URL-safe base64 encoding
|
|
154
|
+
const pathname = encodeURIComponent(
|
|
155
|
+
btoa(JSON.stringify({ returnPathname: '/protected?test=123' }))
|
|
156
|
+
.replace(/\+/g, '-')
|
|
157
|
+
.replace(/\//g, '_'),
|
|
158
|
+
);
|
|
150
159
|
|
|
151
160
|
expect(redirect).toHaveBeenCalledWith(expect.stringContaining(pathname));
|
|
152
161
|
});
|
package/src/test-helpers.ts
CHANGED
package/src/workos.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { WorkOS } from '@workos-inc/node';
|
|
|
2
2
|
import { WORKOS_API_HOSTNAME, WORKOS_API_KEY, WORKOS_API_HTTPS, WORKOS_API_PORT } from './env-variables.js';
|
|
3
3
|
import { lazy } from './utils.js';
|
|
4
4
|
|
|
5
|
-
export const VERSION = '2.
|
|
5
|
+
export const VERSION = '2.10.0';
|
|
6
6
|
|
|
7
7
|
const options = {
|
|
8
8
|
apiHostname: WORKOS_API_HOSTNAME,
|