@workos-inc/authkit-nextjs 2.17.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -11
- package/dist/esm/actions.js +35 -4
- package/dist/esm/actions.js.map +1 -1
- package/dist/esm/auth.js +13 -22
- package/dist/esm/auth.js.map +1 -1
- package/dist/esm/authkit-callback-route.js +71 -95
- package/dist/esm/authkit-callback-route.js.map +1 -1
- package/dist/esm/components/authkit-provider.js +31 -13
- package/dist/esm/components/authkit-provider.js.map +1 -1
- package/dist/esm/components/impersonation.js +9 -9
- package/dist/esm/components/impersonation.js.map +1 -1
- package/dist/esm/components/min-max-button.js +1 -1
- package/dist/esm/components/min-max-button.js.map +1 -1
- package/dist/esm/components/tokenStore.js +28 -19
- package/dist/esm/components/tokenStore.js.map +1 -1
- package/dist/esm/components/useAccessToken.js +1 -1
- package/dist/esm/components/useAccessToken.js.map +1 -1
- package/dist/esm/components/useTokenClaims.js +1 -1
- package/dist/esm/components/useTokenClaims.js.map +1 -1
- package/dist/esm/cookie.js +16 -5
- package/dist/esm/cookie.js.map +1 -1
- package/dist/esm/env-variables.js +5 -7
- package/dist/esm/env-variables.js.map +1 -1
- package/dist/esm/errors.js +7 -4
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/get-authorization-url.js +23 -27
- package/dist/esm/get-authorization-url.js.map +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interfaces.js +7 -1
- package/dist/esm/interfaces.js.map +1 -1
- package/dist/esm/middleware-helpers.js +8 -5
- package/dist/esm/middleware-helpers.js.map +1 -1
- package/dist/esm/middleware.js +3 -1
- package/dist/esm/middleware.js.map +1 -1
- package/dist/esm/pkce.js +17 -22
- package/dist/esm/pkce.js.map +1 -1
- package/dist/esm/session.js +19 -23
- package/dist/esm/session.js.map +1 -1
- package/dist/esm/types/actions.d.ts +34 -5
- package/dist/esm/types/auth.d.ts +6 -16
- package/dist/esm/types/cookie.d.ts +8 -0
- package/dist/esm/types/env-variables.d.ts +1 -2
- package/dist/esm/types/get-authorization-url.d.ts +1 -1
- package/dist/esm/types/index.d.ts +3 -3
- package/dist/esm/types/interfaces.d.ts +9 -1
- package/dist/esm/types/jwt.d.ts +9 -9
- package/dist/esm/types/middleware-helpers.d.ts +3 -1
- package/dist/esm/types/middleware.d.ts +3 -1
- package/dist/esm/types/pkce.d.ts +6 -5
- package/dist/esm/utils.js +2 -2
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/validate-api-key.js +1 -2
- package/dist/esm/validate-api-key.js.map +1 -1
- package/package.json +12 -13
- package/src/actions.spec.ts +81 -6
- package/src/actions.ts +44 -5
- package/src/auth.spec.ts +3 -2
- package/src/auth.ts +12 -43
- package/src/authkit-callback-route.spec.ts +210 -60
- package/src/authkit-callback-route.ts +94 -107
- package/src/components/authkit-provider.spec.tsx +89 -6
- package/src/components/authkit-provider.tsx +20 -1
- package/src/components/impersonation.spec.tsx +1 -0
- package/src/components/impersonation.tsx +29 -24
- package/src/components/tokenStore.spec.ts +35 -20
- package/src/components/tokenStore.ts +11 -3
- package/src/components/useAccessToken.spec.tsx +15 -12
- package/src/components/useTokenClaims.spec.tsx +1 -0
- package/src/cookie.ts +29 -0
- package/src/env-variables.ts +0 -2
- package/src/get-authorization-url.spec.ts +18 -40
- package/src/get-authorization-url.ts +34 -40
- package/src/index.ts +3 -1
- package/src/interfaces.ts +11 -1
- package/src/jwt.ts +9 -9
- package/src/middleware-helpers.spec.ts +7 -0
- package/src/middleware-helpers.ts +7 -3
- package/src/middleware.spec.ts +25 -0
- package/src/middleware.ts +4 -1
- package/src/pkce.spec.ts +125 -0
- package/src/pkce.ts +19 -19
- package/src/session.spec.ts +18 -22
- package/src/session.ts +10 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workos-inc/authkit-nextjs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Authentication and session helpers for using WorkOS & AuthKit with Next.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"@workos-inc/node": "^8.9.0",
|
|
27
27
|
"iron-session": "^8.0.4",
|
|
28
28
|
"jose": "^5.10.0",
|
|
29
|
-
"path-to-regexp": "^6.3.0"
|
|
29
|
+
"path-to-regexp": "^6.3.0",
|
|
30
|
+
"valibot": "^1.2.0"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
33
|
"next": "^13.5.9 || ^14.2.26 || ^15.2.3 || ^16",
|
|
@@ -40,14 +41,12 @@
|
|
|
40
41
|
"@types/react": "18.2.67",
|
|
41
42
|
"@types/react-dom": "18.2.22",
|
|
42
43
|
"@vitest/coverage-v8": "^3.2.4",
|
|
43
|
-
"eslint": "^8.57.1",
|
|
44
|
-
"eslint-config-prettier": "^9.1.2",
|
|
45
|
-
"eslint-plugin-require-extensions": "^0.1.3",
|
|
46
44
|
"jsdom": "^26.1.0",
|
|
47
|
-
"next": "^16.1
|
|
48
|
-
"
|
|
45
|
+
"next": "^16.2.1",
|
|
46
|
+
"oxfmt": "^0.42.0",
|
|
47
|
+
"oxlint": "^1.57.0",
|
|
49
48
|
"tslib": "^2.8.1",
|
|
50
|
-
"typescript": "
|
|
49
|
+
"typescript": "6.0.2",
|
|
51
50
|
"typescript-eslint": "^7.18.0",
|
|
52
51
|
"vitest": "^3.2.4"
|
|
53
52
|
},
|
|
@@ -63,13 +62,13 @@
|
|
|
63
62
|
"scripts": {
|
|
64
63
|
"clean": "rm -rf dist",
|
|
65
64
|
"prebuild": "pnpm run clean",
|
|
66
|
-
"build": "tsc --project tsconfig.json",
|
|
67
|
-
"lint": "eslint \"src/**/*.ts*\"",
|
|
65
|
+
"build": "tsc --project tsconfig.app.json",
|
|
68
66
|
"test": "vitest run",
|
|
69
67
|
"test:watch": "vitest",
|
|
70
68
|
"test:coverage": "vitest run --coverage",
|
|
71
|
-
"
|
|
72
|
-
"format": "
|
|
73
|
-
"
|
|
69
|
+
"lint": "oxlint",
|
|
70
|
+
"format": "oxfmt .",
|
|
71
|
+
"format:check": "oxfmt --check .",
|
|
72
|
+
"typecheck": "tsc --project tsconfig.app.json --noEmit && tsc --project tsconfig.test.json --noEmit"
|
|
74
73
|
}
|
|
75
74
|
}
|
package/src/actions.spec.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { signOut, switchToOrganization } from './auth.js';
|
|
12
12
|
import { getWorkOS } from '../src/workos.js';
|
|
13
13
|
import { withAuth, refreshSession } from '../src/session.js';
|
|
14
|
+
import { getAuthorizationUrl } from '../src/get-authorization-url.js';
|
|
14
15
|
|
|
15
16
|
vi.mock('../src/auth.js', () => ({
|
|
16
17
|
signOut: vi.fn().mockResolvedValue(true),
|
|
@@ -30,11 +31,31 @@ vi.mock('../src/workos.js', () => ({
|
|
|
30
31
|
|
|
31
32
|
vi.mock('../src/session.js', () => ({
|
|
32
33
|
withAuth: vi.fn().mockResolvedValue({ user: 'testUser', accessToken: 'access_token' }),
|
|
33
|
-
refreshSession: vi.fn().mockResolvedValue({
|
|
34
|
+
refreshSession: vi.fn().mockResolvedValue({ user: 'testUser', accessToken: 'refreshed_token' }),
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
vi.mock('../src/get-authorization-url.js', () => ({
|
|
38
|
+
getAuthorizationUrl: vi.fn().mockResolvedValue('https://api.workos.com/authorize?...'),
|
|
34
39
|
}));
|
|
35
40
|
|
|
36
41
|
describe('actions', () => {
|
|
37
42
|
const workos = getWorkOS();
|
|
43
|
+
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
vi.clearAllMocks();
|
|
46
|
+
// Restore default mock implementations
|
|
47
|
+
vi.mocked(withAuth).mockResolvedValue({
|
|
48
|
+
user: 'testUser' as never,
|
|
49
|
+
sessionId: 'session_123',
|
|
50
|
+
accessToken: 'access_token',
|
|
51
|
+
});
|
|
52
|
+
vi.mocked(refreshSession).mockResolvedValue({
|
|
53
|
+
user: 'testUser' as never,
|
|
54
|
+
sessionId: 'session_123',
|
|
55
|
+
accessToken: 'refreshed_token',
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
38
59
|
describe('checkSessionAction', () => {
|
|
39
60
|
it('should return true for authenticated users', async () => {
|
|
40
61
|
const result = await checkSessionAction();
|
|
@@ -62,16 +83,52 @@ describe('actions', () => {
|
|
|
62
83
|
it('should return auth details', async () => {
|
|
63
84
|
const result = await getAuthAction();
|
|
64
85
|
expect(withAuth).toHaveBeenCalled();
|
|
65
|
-
expect(result).toEqual({ user: 'testUser' });
|
|
86
|
+
expect(result).toEqual({ user: 'testUser', sessionId: 'session_123' });
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should not pass ensureSignedIn to withAuth', async () => {
|
|
90
|
+
await getAuthAction({ ensureSignedIn: true });
|
|
91
|
+
expect(withAuth).toHaveBeenCalledWith();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should return signInUrl when ensureSignedIn is true and no user', async () => {
|
|
95
|
+
vi.mocked(withAuth).mockResolvedValueOnce({ user: null });
|
|
96
|
+
const result = await getAuthAction({ ensureSignedIn: true });
|
|
97
|
+
expect(getAuthorizationUrl).toHaveBeenCalledWith({ screenHint: 'sign-in' });
|
|
98
|
+
expect(result).toEqual({ user: null, signInUrl: 'https://api.workos.com/authorize?...' });
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should not return signInUrl when ensureSignedIn is true and user exists', async () => {
|
|
102
|
+
const result = await getAuthAction({ ensureSignedIn: true });
|
|
103
|
+
expect(getAuthorizationUrl).not.toHaveBeenCalled();
|
|
104
|
+
expect(result).toEqual({ user: 'testUser', sessionId: 'session_123' });
|
|
66
105
|
});
|
|
67
106
|
});
|
|
68
107
|
|
|
69
108
|
describe('refreshAuthAction', () => {
|
|
70
109
|
it('should refresh session', async () => {
|
|
71
|
-
const params = { ensureSignedIn:
|
|
110
|
+
const params = { ensureSignedIn: false, organizationId: 'org_123' };
|
|
72
111
|
const result = await refreshAuthAction(params);
|
|
73
|
-
expect(refreshSession).toHaveBeenCalledWith(
|
|
74
|
-
expect(result).toEqual({
|
|
112
|
+
expect(refreshSession).toHaveBeenCalledWith({ organizationId: 'org_123' });
|
|
113
|
+
expect(result).toEqual({ user: 'testUser', sessionId: 'session_123' });
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should not pass ensureSignedIn to refreshSession', async () => {
|
|
117
|
+
await refreshAuthAction({ ensureSignedIn: true, organizationId: 'org_123' });
|
|
118
|
+
expect(refreshSession).toHaveBeenCalledWith({ organizationId: 'org_123' });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should return signInUrl when ensureSignedIn is true and no user', async () => {
|
|
122
|
+
vi.mocked(refreshSession).mockResolvedValueOnce({ user: null });
|
|
123
|
+
const result = await refreshAuthAction({ ensureSignedIn: true });
|
|
124
|
+
expect(getAuthorizationUrl).toHaveBeenCalledWith({ screenHint: 'sign-in' });
|
|
125
|
+
expect(result).toEqual({ user: null, signInUrl: 'https://api.workos.com/authorize?...' });
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should not return signInUrl when ensureSignedIn is true and user exists', async () => {
|
|
129
|
+
const result = await refreshAuthAction({ ensureSignedIn: true });
|
|
130
|
+
expect(getAuthorizationUrl).not.toHaveBeenCalled();
|
|
131
|
+
expect(result).toEqual({ user: 'testUser', sessionId: 'session_123' });
|
|
75
132
|
});
|
|
76
133
|
});
|
|
77
134
|
|
|
@@ -96,7 +153,25 @@ describe('actions', () => {
|
|
|
96
153
|
it('should refresh access token', async () => {
|
|
97
154
|
const result = await refreshAccessTokenAction();
|
|
98
155
|
expect(refreshSession).toHaveBeenCalled();
|
|
99
|
-
expect(result).toEqual('refreshed_token');
|
|
156
|
+
expect(result).toEqual({ accessToken: 'refreshed_token' });
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should catch errors and return a generic error instead of throwing', async () => {
|
|
160
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
161
|
+
vi.mocked(refreshSession).mockRejectedValueOnce(new Error('Rate limit exceeded'));
|
|
162
|
+
const result = await refreshAccessTokenAction();
|
|
163
|
+
expect(result).toEqual({ accessToken: undefined, error: 'Failed to refresh access token' });
|
|
164
|
+
expect(warnSpy).toHaveBeenCalledWith('Failed to refresh access token:', 'Rate limit exceeded');
|
|
165
|
+
warnSpy.mockRestore();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should handle non-Error objects in catch', async () => {
|
|
169
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
170
|
+
vi.mocked(refreshSession).mockRejectedValueOnce('string error');
|
|
171
|
+
const result = await refreshAccessTokenAction();
|
|
172
|
+
expect(result).toEqual({ accessToken: undefined, error: 'Failed to refresh access token' });
|
|
173
|
+
expect(warnSpy).toHaveBeenCalledWith('Failed to refresh access token:', 'string error');
|
|
174
|
+
warnSpy.mockRestore();
|
|
100
175
|
});
|
|
101
176
|
});
|
|
102
177
|
});
|
package/src/actions.ts
CHANGED
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
import { signOut, switchToOrganization } from './auth.js';
|
|
4
4
|
import { NoUserInfo, UserInfo, SwitchToOrganizationOptions } from './interfaces.js';
|
|
5
5
|
import { refreshSession, withAuth } from './session.js';
|
|
6
|
+
import { getAuthorizationUrl } from './get-authorization-url.js';
|
|
6
7
|
import { getWorkOS } from './workos.js';
|
|
7
8
|
|
|
9
|
+
export interface RefreshAccessTokenActionResult {
|
|
10
|
+
accessToken: string | undefined;
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
/**
|
|
9
15
|
* This function is used to sanitize the auth object.
|
|
10
16
|
* Remove the accessToken from the auth object as it is not needed on the client side.
|
|
@@ -35,7 +41,19 @@ export const getOrganizationAction = async (organizationId: string) => {
|
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
export const getAuthAction = async (options?: { ensureSignedIn?: boolean }) => {
|
|
38
|
-
|
|
44
|
+
// Never pass ensureSignedIn to withAuth from a server action, because withAuth
|
|
45
|
+
// would call redirect() to an external URL, which causes CORS errors when
|
|
46
|
+
// invoked via a client-side fetch. Instead, return the sign-in URL so the
|
|
47
|
+
// client can redirect via window.location.href.
|
|
48
|
+
const auth = await withAuth();
|
|
49
|
+
const sanitized = sanitize(auth);
|
|
50
|
+
|
|
51
|
+
if (options?.ensureSignedIn && !auth.user) {
|
|
52
|
+
const signInUrl = await getAuthorizationUrl({ screenHint: 'sign-in' });
|
|
53
|
+
return { ...sanitized, signInUrl };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return sanitized;
|
|
39
57
|
};
|
|
40
58
|
|
|
41
59
|
export const refreshAuthAction = async ({
|
|
@@ -45,7 +63,17 @@ export const refreshAuthAction = async ({
|
|
|
45
63
|
ensureSignedIn?: boolean;
|
|
46
64
|
organizationId?: string;
|
|
47
65
|
}) => {
|
|
48
|
-
|
|
66
|
+
// Never pass ensureSignedIn to refreshSession from a server action for the
|
|
67
|
+
// same CORS reason as getAuthAction above.
|
|
68
|
+
const auth = await refreshSession({ organizationId });
|
|
69
|
+
const sanitized = sanitize(auth);
|
|
70
|
+
|
|
71
|
+
if (ensureSignedIn && !auth.user) {
|
|
72
|
+
const signInUrl = await getAuthorizationUrl({ screenHint: 'sign-in' });
|
|
73
|
+
return { ...sanitized, signInUrl };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return sanitized;
|
|
49
77
|
};
|
|
50
78
|
|
|
51
79
|
export const switchToOrganizationAction = async (organizationId: string, options?: SwitchToOrganizationOptions) => {
|
|
@@ -64,8 +92,19 @@ export async function getAccessTokenAction() {
|
|
|
64
92
|
/**
|
|
65
93
|
* This action is used to refresh the access token from the auth object.
|
|
66
94
|
* It is used to fetch the access token from the server.
|
|
95
|
+
*
|
|
96
|
+
* Errors are caught and returned as data rather than thrown, to prevent
|
|
97
|
+
* Next.js from returning 500 responses for server action failures.
|
|
67
98
|
*/
|
|
68
|
-
export async function refreshAccessTokenAction() {
|
|
69
|
-
|
|
70
|
-
|
|
99
|
+
export async function refreshAccessTokenAction(): Promise<RefreshAccessTokenActionResult> {
|
|
100
|
+
try {
|
|
101
|
+
const auth = await refreshSession();
|
|
102
|
+
return { accessToken: auth.accessToken };
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.warn('Failed to refresh access token:', error instanceof Error ? error.message : String(error));
|
|
105
|
+
return {
|
|
106
|
+
accessToken: undefined,
|
|
107
|
+
error: 'Failed to refresh access token',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
71
110
|
}
|
package/src/auth.spec.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { redirect } from 'next/navigation';
|
|
|
9
9
|
import { generateSession, generateTestToken } from './test-helpers.js';
|
|
10
10
|
import { sealData } from 'iron-session';
|
|
11
11
|
import { getWorkOS } from './workos.js';
|
|
12
|
+
import { getStateFromPKCECookieValue } from './pkce.js';
|
|
12
13
|
|
|
13
14
|
const workos = getWorkOS();
|
|
14
15
|
|
|
@@ -87,7 +88,7 @@ describe('auth.ts', () => {
|
|
|
87
88
|
const parsedUrl = new URL(url);
|
|
88
89
|
const state = parsedUrl.searchParams.get('state');
|
|
89
90
|
expect(state).toBeDefined();
|
|
90
|
-
const decoded =
|
|
91
|
+
const decoded = await getStateFromPKCECookieValue(state!);
|
|
91
92
|
expect(decoded.returnPathname).toBe('/dashboard');
|
|
92
93
|
});
|
|
93
94
|
});
|
|
@@ -123,7 +124,7 @@ describe('auth.ts', () => {
|
|
|
123
124
|
const parsedUrl = new URL(url);
|
|
124
125
|
const state = parsedUrl.searchParams.get('state');
|
|
125
126
|
expect(state).toBeDefined();
|
|
126
|
-
const decoded =
|
|
127
|
+
const decoded = await getStateFromPKCECookieValue(state!);
|
|
127
128
|
expect(decoded.returnPathname).toBe('/welcome');
|
|
128
129
|
});
|
|
129
130
|
});
|
package/src/auth.ts
CHANGED
|
@@ -22,60 +22,29 @@ function revalidateTagCompat(tag: string): void {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async function getAuthURLAndSetPKCECookie(options: GetAuthURLOptions): Promise<string> {
|
|
25
|
-
const { url,
|
|
26
|
-
await setPKCECookie(
|
|
25
|
+
const { url, sealedState } = await getAuthorizationUrl(options);
|
|
26
|
+
await setPKCECookie(sealedState);
|
|
27
|
+
|
|
27
28
|
return url;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
organizationId,
|
|
32
|
-
loginHint,
|
|
33
|
-
redirectUri,
|
|
34
|
-
prompt,
|
|
35
|
-
state,
|
|
36
|
-
returnTo,
|
|
37
|
-
}: {
|
|
38
|
-
organizationId?: string;
|
|
39
|
-
loginHint?: string;
|
|
40
|
-
redirectUri?: string;
|
|
41
|
-
prompt?: 'consent';
|
|
42
|
-
state?: string;
|
|
31
|
+
type GetSignUrlOptions = Omit<GetAuthURLOptions, 'screenHint' | 'returnPathname'> & {
|
|
43
32
|
returnTo?: string;
|
|
44
|
-
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export async function getSignInUrl(authUrlOptions: GetSignUrlOptions = {}) {
|
|
45
36
|
return getAuthURLAndSetPKCECookie({
|
|
46
|
-
|
|
37
|
+
...authUrlOptions,
|
|
38
|
+
returnPathname: authUrlOptions.returnTo,
|
|
47
39
|
screenHint: 'sign-in',
|
|
48
|
-
loginHint,
|
|
49
|
-
redirectUri,
|
|
50
|
-
prompt,
|
|
51
|
-
state,
|
|
52
|
-
returnPathname: returnTo,
|
|
53
40
|
});
|
|
54
41
|
}
|
|
55
42
|
|
|
56
|
-
export async function getSignUpUrl({
|
|
57
|
-
organizationId,
|
|
58
|
-
loginHint,
|
|
59
|
-
redirectUri,
|
|
60
|
-
prompt,
|
|
61
|
-
state,
|
|
62
|
-
returnTo,
|
|
63
|
-
}: {
|
|
64
|
-
organizationId?: string;
|
|
65
|
-
loginHint?: string;
|
|
66
|
-
redirectUri?: string;
|
|
67
|
-
prompt?: 'consent';
|
|
68
|
-
state?: string;
|
|
69
|
-
returnTo?: string;
|
|
70
|
-
} = {}) {
|
|
43
|
+
export async function getSignUpUrl(authUrlOptions: GetSignUrlOptions = {}) {
|
|
71
44
|
return getAuthURLAndSetPKCECookie({
|
|
72
|
-
|
|
45
|
+
...authUrlOptions,
|
|
46
|
+
returnPathname: authUrlOptions.returnTo,
|
|
73
47
|
screenHint: 'sign-up',
|
|
74
|
-
loginHint,
|
|
75
|
-
redirectUri,
|
|
76
|
-
prompt,
|
|
77
|
-
state,
|
|
78
|
-
returnPathname: returnTo,
|
|
79
48
|
});
|
|
80
49
|
}
|
|
81
50
|
|