@workos-inc/authkit-nextjs 0.17.2 → 1.0.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 +102 -25
- package/dist/esm/actions.js +11 -0
- package/dist/esm/actions.js.map +1 -1
- package/dist/esm/components/authkit-provider.js +128 -0
- package/dist/esm/components/authkit-provider.js.map +1 -0
- package/dist/esm/components/button.js.map +1 -0
- package/dist/esm/{impersonation.js → components/impersonation.js} +12 -7
- package/dist/esm/components/impersonation.js.map +1 -0
- package/dist/esm/components/index.js +4 -0
- package/dist/esm/components/index.js.map +1 -0
- package/dist/esm/components/min-max-button.js.map +1 -0
- package/dist/esm/cookie.js +15 -12
- package/dist/esm/cookie.js.map +1 -1
- package/dist/esm/env-variables.js +5 -2
- package/dist/esm/env-variables.js.map +1 -1
- package/dist/esm/index.js +4 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/middleware.js +5 -2
- package/dist/esm/middleware.js.map +1 -1
- package/dist/esm/session.js +117 -93
- package/dist/esm/session.js.map +1 -1
- package/dist/esm/types/actions.d.ts +6 -0
- package/dist/esm/types/components/authkit-provider.d.ts +33 -0
- package/dist/esm/types/{impersonation.d.ts → components/impersonation.d.ts} +1 -1
- package/dist/esm/types/components/index.d.ts +3 -0
- package/dist/esm/types/cookie.d.ts +4 -0
- package/dist/esm/types/env-variables.d.ts +2 -2
- package/dist/esm/types/index.d.ts +3 -5
- package/dist/esm/types/interfaces.d.ts +11 -0
- package/dist/esm/types/middleware.d.ts +3 -2
- package/dist/esm/types/session.d.ts +5 -28
- package/dist/esm/types/utils.d.ts +1 -1
- package/dist/esm/types/workos.d.ts +1 -1
- package/dist/esm/utils.js +5 -3
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/workos.js +1 -1
- package/dist/esm/workos.js.map +1 -1
- package/package.json +11 -1
- package/src/actions.ts +20 -0
- package/src/components/authkit-provider.tsx +169 -0
- package/src/{impersonation.tsx → components/impersonation.tsx} +14 -7
- package/src/components/index.ts +4 -0
- package/src/cookie.ts +33 -12
- package/src/env-variables.ts +7 -2
- package/src/index.ts +3 -8
- package/src/interfaces.ts +13 -0
- package/src/middleware.ts +8 -4
- package/src/session.ts +159 -110
- package/src/utils.ts +6 -3
- package/src/workos.ts +1 -1
- package/dist/esm/authkit-provider.js +0 -52
- package/dist/esm/authkit-provider.js.map +0 -1
- package/dist/esm/button.js.map +0 -1
- package/dist/esm/impersonation.js.map +0 -1
- package/dist/esm/min-max-button.js.map +0 -1
- package/dist/esm/types/authkit-provider.d.ts +0 -11
- package/src/authkit-provider.tsx +0 -66
- /package/dist/esm/{button.js → components/button.js} +0 -0
- /package/dist/esm/{min-max-button.js → components/min-max-button.js} +0 -0
- /package/dist/esm/types/{button.d.ts → components/button.d.ts} +0 -0
- /package/dist/esm/types/{min-max-button.d.ts → components/min-max-button.d.ts} +0 -0
- /package/src/{button.tsx → components/button.tsx} +0 -0
- /package/src/{min-max-button.tsx → components/min-max-button.tsx} +0 -0
package/src/session.ts
CHANGED
|
@@ -9,14 +9,22 @@ import { getCookieOptions } from './cookie.js';
|
|
|
9
9
|
import { workos } from './workos.js';
|
|
10
10
|
import { WORKOS_CLIENT_ID, WORKOS_COOKIE_PASSWORD, WORKOS_COOKIE_NAME, WORKOS_REDIRECT_URI } from './env-variables.js';
|
|
11
11
|
import { getAuthorizationUrl } from './get-authorization-url.js';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
AccessToken,
|
|
14
|
+
AuthkitMiddlewareAuth,
|
|
15
|
+
AuthkitOptions,
|
|
16
|
+
AuthkitResponse,
|
|
17
|
+
CookieOptions,
|
|
18
|
+
NoUserInfo,
|
|
19
|
+
Session,
|
|
20
|
+
UserInfo,
|
|
21
|
+
} from './interfaces.js';
|
|
13
22
|
|
|
14
23
|
import { parse, tokensToRegexp } from 'path-to-regexp';
|
|
15
24
|
import { redirectWithFallback } from './utils.js';
|
|
16
25
|
|
|
17
26
|
const sessionHeaderName = 'x-workos-session';
|
|
18
27
|
const middlewareHeaderName = 'x-workos-middleware';
|
|
19
|
-
const redirectUriHeaderName = 'x-redirect-uri';
|
|
20
28
|
const signUpPathsHeaderName = 'x-sign-up-paths';
|
|
21
29
|
|
|
22
30
|
const JWKS = createRemoteJWKSet(new URL(workos.userManagement.getJwksUrl(WORKOS_CLIENT_ID)));
|
|
@@ -28,7 +36,7 @@ async function encryptSession(session: Session) {
|
|
|
28
36
|
});
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
async function
|
|
39
|
+
async function updateSessionMiddleware(
|
|
32
40
|
request: NextRequest,
|
|
33
41
|
debug: boolean,
|
|
34
42
|
middlewareAuth: AuthkitMiddlewareAuth,
|
|
@@ -45,34 +53,14 @@ async function updateSession(
|
|
|
45
53
|
);
|
|
46
54
|
}
|
|
47
55
|
|
|
48
|
-
const session = await getSessionFromCookie();
|
|
49
|
-
const newRequestHeaders = new Headers(request.headers);
|
|
50
|
-
|
|
51
|
-
// We store the current request url in a custom header, so we can always have access to it
|
|
52
|
-
// This is because on hard navigations we don't have access to `next-url` but need to get the current
|
|
53
|
-
// `pathname` to be able to return the users where they came from before sign-in
|
|
54
|
-
newRequestHeaders.set('x-url', request.url);
|
|
55
|
-
|
|
56
|
-
// Record that the request was routed through the middleware so we can check later for DX purposes
|
|
57
|
-
newRequestHeaders.set(middlewareHeaderName, 'true');
|
|
58
|
-
|
|
59
|
-
// Record the sign up paths so we can use it later
|
|
60
|
-
if (signUpPaths.length > 0) {
|
|
61
|
-
newRequestHeaders.set(signUpPathsHeaderName, signUpPaths.join(','));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
56
|
let url;
|
|
65
57
|
|
|
66
|
-
// If the redirect URI is set, store it in the headers so we can use it later
|
|
67
58
|
if (redirectUri) {
|
|
68
|
-
newRequestHeaders.set(redirectUriHeaderName, redirectUri);
|
|
69
59
|
url = new URL(redirectUri);
|
|
70
60
|
} else {
|
|
71
61
|
url = new URL(WORKOS_REDIRECT_URI);
|
|
72
62
|
}
|
|
73
63
|
|
|
74
|
-
newRequestHeaders.delete(sessionHeaderName);
|
|
75
|
-
|
|
76
64
|
if (
|
|
77
65
|
middlewareAuth.enabled &&
|
|
78
66
|
url.pathname === request.nextUrl.pathname &&
|
|
@@ -94,54 +82,111 @@ async function updateSession(
|
|
|
94
82
|
return pathRegex.exec(request.nextUrl.pathname);
|
|
95
83
|
});
|
|
96
84
|
|
|
85
|
+
const { session, headers, authorizationUrl } = await updateSession(request, {
|
|
86
|
+
debug,
|
|
87
|
+
redirectUri,
|
|
88
|
+
screenHint: getScreenHint(signUpPaths, request.nextUrl.pathname),
|
|
89
|
+
});
|
|
90
|
+
|
|
97
91
|
// If the user is logged out and this path isn't on the allowlist for logged out paths, redirect to AuthKit.
|
|
98
|
-
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session) {
|
|
99
|
-
if (debug)
|
|
92
|
+
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session.user) {
|
|
93
|
+
if (debug) {
|
|
94
|
+
console.log(`Unauthenticated user on protected route ${request.url}, redirecting to AuthKit`);
|
|
95
|
+
}
|
|
100
96
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
redirectUri: redirectUri,
|
|
104
|
-
screenHint: getScreenHint(signUpPaths, request.nextUrl.pathname),
|
|
105
|
-
});
|
|
97
|
+
return redirectWithFallback(authorizationUrl as string, headers);
|
|
98
|
+
}
|
|
106
99
|
|
|
107
|
-
|
|
100
|
+
// Record the sign up paths so we can use them later
|
|
101
|
+
if (signUpPaths.length > 0) {
|
|
102
|
+
headers.set(signUpPathsHeaderName, signUpPaths.join(','));
|
|
108
103
|
}
|
|
109
104
|
|
|
110
|
-
|
|
105
|
+
return NextResponse.next({
|
|
106
|
+
headers,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function updateSession(
|
|
111
|
+
request: NextRequest,
|
|
112
|
+
options: AuthkitOptions = { debug: false },
|
|
113
|
+
): Promise<AuthkitResponse> {
|
|
114
|
+
const session = await getSessionFromCookie(request);
|
|
115
|
+
|
|
116
|
+
const newRequestHeaders = new Headers(request.headers);
|
|
117
|
+
|
|
118
|
+
// Record that the request was routed through the middleware so we can check later for DX purposes
|
|
119
|
+
newRequestHeaders.set(middlewareHeaderName, 'true');
|
|
120
|
+
|
|
121
|
+
// We store the current request url in a custom header, so we can always have access to it
|
|
122
|
+
// This is because on hard navigations we don't have access to `next-url` but need to get the current
|
|
123
|
+
// `pathname` to be able to return the users where they came from before sign-in
|
|
124
|
+
newRequestHeaders.set('x-url', request.url);
|
|
125
|
+
|
|
126
|
+
newRequestHeaders.delete(sessionHeaderName);
|
|
127
|
+
|
|
111
128
|
if (!session) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
129
|
+
if (options.debug) {
|
|
130
|
+
console.log('No session found from cookie');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
session: { user: null },
|
|
135
|
+
headers: newRequestHeaders,
|
|
136
|
+
authorizationUrl: await getAuthorizationUrl({
|
|
137
|
+
returnPathname: getReturnPathname(request.url),
|
|
138
|
+
redirectUri: options.redirectUri || WORKOS_REDIRECT_URI,
|
|
139
|
+
screenHint: options.screenHint,
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
115
142
|
}
|
|
116
143
|
|
|
117
144
|
const hasValidSession = await verifyAccessToken(session.accessToken);
|
|
118
|
-
const cookieName = WORKOS_COOKIE_NAME || 'wos-session';
|
|
119
145
|
|
|
120
|
-
const
|
|
146
|
+
const cookieName = WORKOS_COOKIE_NAME || 'wos-session';
|
|
121
147
|
|
|
122
148
|
if (hasValidSession) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
149
|
+
newRequestHeaders.set(sessionHeaderName, request.cookies.get(cookieName)!.value);
|
|
150
|
+
|
|
151
|
+
const {
|
|
152
|
+
sid: sessionId,
|
|
153
|
+
org_id: organizationId,
|
|
154
|
+
role,
|
|
155
|
+
permissions,
|
|
156
|
+
entitlements,
|
|
157
|
+
} = decodeJwt<AccessToken>(session.accessToken);
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
session: {
|
|
161
|
+
sessionId,
|
|
162
|
+
user: session.user,
|
|
163
|
+
organizationId,
|
|
164
|
+
role,
|
|
165
|
+
permissions,
|
|
166
|
+
entitlements,
|
|
167
|
+
impersonator: session.impersonator,
|
|
168
|
+
accessToken: session.accessToken,
|
|
169
|
+
},
|
|
170
|
+
headers: newRequestHeaders,
|
|
171
|
+
};
|
|
129
172
|
}
|
|
130
173
|
|
|
131
|
-
|
|
132
|
-
|
|
174
|
+
if (options.debug) {
|
|
175
|
+
console.log(`Session invalid. Refreshing access token that ends in ${session.accessToken.slice(-10)}`);
|
|
176
|
+
}
|
|
133
177
|
|
|
134
|
-
|
|
178
|
+
try {
|
|
179
|
+
const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(session.accessToken);
|
|
135
180
|
|
|
136
|
-
// If the session is invalid (i.e. the access token has expired) attempt to re-authenticate with the refresh token
|
|
137
181
|
const { accessToken, refreshToken, user, impersonator } = await workos.userManagement.authenticateWithRefreshToken({
|
|
138
182
|
clientId: WORKOS_CLIENT_ID,
|
|
139
183
|
refreshToken: session.refreshToken,
|
|
140
|
-
organizationId,
|
|
184
|
+
organizationId: organizationIdFromAccessToken,
|
|
141
185
|
});
|
|
142
186
|
|
|
143
|
-
if (debug)
|
|
144
|
-
|
|
187
|
+
if (options.debug) {
|
|
188
|
+
console.log('Session successfully refreshed');
|
|
189
|
+
}
|
|
145
190
|
// Encrypt session with new access and refresh tokens
|
|
146
191
|
const encryptedSession = await encryptSession({
|
|
147
192
|
accessToken,
|
|
@@ -150,25 +195,47 @@ async function updateSession(
|
|
|
150
195
|
impersonator,
|
|
151
196
|
});
|
|
152
197
|
|
|
198
|
+
newRequestHeaders.append('Set-Cookie', `${cookieName}=${encryptedSession}; ${getCookieOptions(request.url, true)}`);
|
|
153
199
|
newRequestHeaders.set(sessionHeaderName, encryptedSession);
|
|
154
200
|
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
201
|
+
const {
|
|
202
|
+
sid: sessionId,
|
|
203
|
+
org_id: organizationId,
|
|
204
|
+
role,
|
|
205
|
+
permissions,
|
|
206
|
+
entitlements,
|
|
207
|
+
} = decodeJwt<AccessToken>(accessToken);
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
session: {
|
|
211
|
+
sessionId,
|
|
212
|
+
user,
|
|
213
|
+
organizationId,
|
|
214
|
+
role,
|
|
215
|
+
permissions,
|
|
216
|
+
entitlements,
|
|
217
|
+
impersonator,
|
|
218
|
+
accessToken,
|
|
219
|
+
},
|
|
220
|
+
headers: newRequestHeaders,
|
|
221
|
+
};
|
|
161
222
|
} catch (e) {
|
|
162
|
-
if (debug)
|
|
223
|
+
if (options.debug) {
|
|
224
|
+
console.log('Failed to refresh. Deleting cookie.', e);
|
|
225
|
+
}
|
|
163
226
|
|
|
164
|
-
|
|
165
|
-
|
|
227
|
+
// When we need to delete a cookie, return it as a header as you can't delete cookies from edge middleware
|
|
228
|
+
const deleteCookie = `${cookieName}=; Expires=${new Date(0).toUTCString()}; ${getCookieOptions(request.url, true, true)}`;
|
|
229
|
+
newRequestHeaders.append('Set-Cookie', deleteCookie);
|
|
166
230
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
231
|
+
return {
|
|
232
|
+
session: { user: null },
|
|
233
|
+
headers: newRequestHeaders,
|
|
234
|
+
authorizationUrl: await getAuthorizationUrl({
|
|
235
|
+
returnPathname: getReturnPathname(request.url),
|
|
236
|
+
}),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
172
239
|
}
|
|
173
240
|
|
|
174
241
|
async function refreshSession(options: {
|
|
@@ -194,12 +261,21 @@ async function refreshSession({
|
|
|
194
261
|
|
|
195
262
|
const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(session.accessToken);
|
|
196
263
|
|
|
197
|
-
|
|
198
|
-
clientId: WORKOS_CLIENT_ID,
|
|
199
|
-
refreshToken: session.refreshToken,
|
|
200
|
-
organizationId: nextOrganizationId ?? organizationIdFromAccessToken,
|
|
201
|
-
});
|
|
264
|
+
let refreshResult;
|
|
202
265
|
|
|
266
|
+
try {
|
|
267
|
+
refreshResult = await workos.userManagement.authenticateWithRefreshToken({
|
|
268
|
+
clientId: WORKOS_CLIENT_ID,
|
|
269
|
+
refreshToken: session.refreshToken,
|
|
270
|
+
organizationId: nextOrganizationId ?? organizationIdFromAccessToken,
|
|
271
|
+
});
|
|
272
|
+
} catch (error) {
|
|
273
|
+
throw new Error(`Failed to refresh session: ${error instanceof Error ? error.message : String(error)}`, {
|
|
274
|
+
cause: error,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const { accessToken, refreshToken, user, impersonator } = refreshResult;
|
|
203
279
|
// Encrypt session with new access and refresh tokens
|
|
204
280
|
const encryptedSession = await encryptSession({
|
|
205
281
|
accessToken,
|
|
@@ -214,7 +290,7 @@ async function refreshSession({
|
|
|
214
290
|
const url = headersList.get('x-url');
|
|
215
291
|
|
|
216
292
|
const nextCookies = await cookies();
|
|
217
|
-
nextCookies.set(cookieName, encryptedSession, getCookieOptions(url));
|
|
293
|
+
nextCookies.set(cookieName, encryptedSession, getCookieOptions(url) as CookieOptions);
|
|
218
294
|
|
|
219
295
|
const {
|
|
220
296
|
sid: sessionId,
|
|
@@ -273,9 +349,8 @@ async function redirectToSignIn() {
|
|
|
273
349
|
}
|
|
274
350
|
|
|
275
351
|
async function withAuth(options?: { ensureSignedIn: false }): Promise<UserInfo | NoUserInfo>;
|
|
276
|
-
// @ts-expect-error - TS complains about the overload signature when we have more than 2 optional properties
|
|
277
352
|
async function withAuth(options: { ensureSignedIn: true }): Promise<UserInfo>;
|
|
278
|
-
async function withAuth({ ensureSignedIn = false } = {}) {
|
|
353
|
+
async function withAuth({ ensureSignedIn = false } = {}): Promise<UserInfo | NoUserInfo> {
|
|
279
354
|
const session = await getSessionFromHeader();
|
|
280
355
|
|
|
281
356
|
if (!session) {
|
|
@@ -323,50 +398,24 @@ async function verifyAccessToken(accessToken: string) {
|
|
|
323
398
|
}
|
|
324
399
|
}
|
|
325
400
|
|
|
326
|
-
async function getSessionFromCookie(
|
|
401
|
+
async function getSessionFromCookie(request?: NextRequest) {
|
|
327
402
|
const cookieName = WORKOS_COOKIE_NAME || 'wos-session';
|
|
328
|
-
|
|
329
|
-
|
|
403
|
+
let cookie;
|
|
404
|
+
|
|
405
|
+
if (request) {
|
|
406
|
+
cookie = request.cookies.get(cookieName);
|
|
407
|
+
} else {
|
|
408
|
+
const nextCookies = await cookies();
|
|
409
|
+
cookie = nextCookies.get(cookieName);
|
|
410
|
+
}
|
|
330
411
|
|
|
331
412
|
if (cookie) {
|
|
332
|
-
return unsealData<Session>(cookie.value
|
|
413
|
+
return unsealData<Session>(cookie.value, {
|
|
333
414
|
password: WORKOS_COOKIE_PASSWORD,
|
|
334
415
|
});
|
|
335
416
|
}
|
|
336
417
|
}
|
|
337
418
|
|
|
338
|
-
/**
|
|
339
|
-
* Retrieves the session from the cookie. Meant for use in the middleware, for client side use `withAuth` instead.
|
|
340
|
-
*
|
|
341
|
-
* @returns UserInfo | NoUserInfo
|
|
342
|
-
*/
|
|
343
|
-
async function getSession(response?: NextResponse) {
|
|
344
|
-
const session = await getSessionFromCookie(response);
|
|
345
|
-
|
|
346
|
-
if (!session) return { user: null };
|
|
347
|
-
|
|
348
|
-
if (await verifyAccessToken(session.accessToken)) {
|
|
349
|
-
const {
|
|
350
|
-
sid: sessionId,
|
|
351
|
-
org_id: organizationId,
|
|
352
|
-
role,
|
|
353
|
-
permissions,
|
|
354
|
-
entitlements,
|
|
355
|
-
} = decodeJwt<AccessToken>(session.accessToken);
|
|
356
|
-
|
|
357
|
-
return {
|
|
358
|
-
sessionId,
|
|
359
|
-
user: session.user,
|
|
360
|
-
organizationId,
|
|
361
|
-
role,
|
|
362
|
-
permissions,
|
|
363
|
-
entitlements,
|
|
364
|
-
impersonator: session.impersonator,
|
|
365
|
-
accessToken: session.accessToken,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
419
|
async function getSessionFromHeader(): Promise<Session | undefined> {
|
|
371
420
|
const headersList = await headers();
|
|
372
421
|
const hasMiddleware = Boolean(headersList.get(middlewareHeaderName));
|
|
@@ -374,7 +423,7 @@ async function getSessionFromHeader(): Promise<Session | undefined> {
|
|
|
374
423
|
if (!hasMiddleware) {
|
|
375
424
|
const url = headersList.get('x-url');
|
|
376
425
|
throw new Error(
|
|
377
|
-
`You are calling 'withAuth' on ${url} that isn’t covered by the AuthKit middleware. Make sure it is running on all paths you are calling 'withAuth' from by updating your middleware config in 'middleware.(js|ts)'.`,
|
|
426
|
+
`You are calling 'withAuth' on ${url ?? 'a route'} that isn’t covered by the AuthKit middleware. Make sure it is running on all paths you are calling 'withAuth' from by updating your middleware config in 'middleware.(js|ts)'.`,
|
|
378
427
|
);
|
|
379
428
|
}
|
|
380
429
|
|
|
@@ -401,4 +450,4 @@ function getScreenHint(signUpPaths: string[] | undefined, pathname: string) {
|
|
|
401
450
|
return screenHintPaths.length > 0 ? 'sign-up' : 'sign-in';
|
|
402
451
|
}
|
|
403
452
|
|
|
404
|
-
export { encryptSession, withAuth, refreshSession, terminateSession,
|
|
453
|
+
export { encryptSession, withAuth, refreshSession, terminateSession, updateSessionMiddleware, updateSession };
|
package/src/utils.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server';
|
|
2
2
|
|
|
3
|
-
export function redirectWithFallback(redirectUri: string) {
|
|
3
|
+
export function redirectWithFallback(redirectUri: string, headers?: Headers) {
|
|
4
|
+
const newHeaders = headers ? new Headers(headers) : new Headers();
|
|
5
|
+
newHeaders.set('Location', redirectUri);
|
|
6
|
+
|
|
4
7
|
// Fall back to standard Response if NextResponse is not available.
|
|
5
8
|
// This is to support Next.js 13.
|
|
6
9
|
return NextResponse?.redirect
|
|
7
|
-
? NextResponse.redirect(redirectUri)
|
|
8
|
-
: new Response(null, { status: 307, headers:
|
|
10
|
+
? NextResponse.redirect(redirectUri, { headers })
|
|
11
|
+
: new Response(null, { status: 307, headers: newHeaders });
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
export function errorResponseWithFallback(errorBody: { error: { message: string; description: string } }) {
|
package/src/workos.ts
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
|
|
|
4
|
-
export const VERSION = '0.
|
|
4
|
+
export const VERSION = '1.0.1';
|
|
5
5
|
|
|
6
6
|
const options = {
|
|
7
7
|
apiHostname: WORKOS_API_HOSTNAME,
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { checkSessionAction } from './actions.js';
|
|
4
|
-
export const AuthKitProvider = ({ children, onSessionExpired }) => {
|
|
5
|
-
React.useEffect(() => {
|
|
6
|
-
// Return early if the session expired checks are disabled.
|
|
7
|
-
if (onSessionExpired === false) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
let visibilityChangedCalled = false;
|
|
11
|
-
const handleVisibilityChange = async () => {
|
|
12
|
-
if (visibilityChangedCalled) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
// In the case where we're using middleware auth mode, a user that has signed out in a different tab
|
|
16
|
-
// will run into an issue if they attempt to hit a server action in the original tab.
|
|
17
|
-
// This will force a refresh of the page in that case, which will redirect them to the sign-in page.
|
|
18
|
-
if (document.visibilityState === 'visible') {
|
|
19
|
-
visibilityChangedCalled = true;
|
|
20
|
-
try {
|
|
21
|
-
const hasSession = await checkSessionAction();
|
|
22
|
-
if (!hasSession) {
|
|
23
|
-
throw new Error('Session expired');
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
// 'Failed to fetch' is the error we are looking for if the action fails
|
|
28
|
-
// If any other error happens, for other reasons, we should not reload the page
|
|
29
|
-
if (error instanceof Error && error.message.includes('Failed to fetch')) {
|
|
30
|
-
if (onSessionExpired) {
|
|
31
|
-
onSessionExpired();
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
window.location.reload();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
finally {
|
|
39
|
-
visibilityChangedCalled = false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
window.addEventListener('visibilitychange', handleVisibilityChange);
|
|
44
|
-
window.addEventListener('focus', handleVisibilityChange);
|
|
45
|
-
return () => {
|
|
46
|
-
window.removeEventListener('focus', handleVisibilityChange);
|
|
47
|
-
window.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
48
|
-
};
|
|
49
|
-
}, [onSessionExpired]);
|
|
50
|
-
return React.createElement(React.Fragment, null, children);
|
|
51
|
-
};
|
|
52
|
-
//# sourceMappingURL=authkit-provider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authkit-provider.js","sourceRoot":"","sources":["../../src/authkit-provider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAWlD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAwB,EAAE,EAAE;IACtF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,2DAA2D;QAC3D,IAAI,gBAAgB,KAAK,KAAK,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,uBAAuB,GAAG,KAAK,CAAC;QAEpC,MAAM,sBAAsB,GAAG,KAAK,IAAI,EAAE;YACxC,IAAI,uBAAuB,EAAE,CAAC;gBAC5B,OAAO;YACT,CAAC;YAED,oGAAoG;YACpG,qFAAqF;YACrF,oGAAoG;YACpG,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBAC3C,uBAAuB,GAAG,IAAI,CAAC;gBAE/B,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,kBAAkB,EAAE,CAAC;oBAC9C,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;oBACrC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,wEAAwE;oBACxE,+EAA+E;oBAC/E,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;wBACxE,IAAI,gBAAgB,EAAE,CAAC;4BACrB,gBAAgB,EAAE,CAAC;wBACrB,CAAC;6BAAM,CAAC;4BACN,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;wBAC3B,CAAC;oBACH,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACT,uBAAuB,GAAG,KAAK,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;QACpE,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;QAEzD,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;YAC5D,MAAM,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;QACzE,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,OAAO,0CAAG,QAAQ,CAAI,CAAC;AACzB,CAAC,CAAC"}
|
package/dist/esm/button.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAA8D,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACnH,OAAO,CACL,gCACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,QAAQ,KACT,KAAK,EACT,KAAK,EAAE;YACL,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,SAAS;YAElB,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,SAAS;YACnB,YAAY,EAAE,6CAA6C;YAC3D,MAAM,EAAE,MAAM;YACd,eAAe,EAAE,aAAa;YAC9B,KAAK,EAAE,OAAO;YAEd,GAAG,KAAK,CAAC,KAAK;SACf,GACD,CACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"impersonation.js","sourceRoot":"","sources":["../../src/impersonation.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"min-max-button.js","sourceRoot":"","sources":["../../src/min-max-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAqB;IAC1E,OAAO,CACL,oBAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE;YACZ,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,kCAAkC,CAAuB,CAAC;YAC9F,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;QAC5D,CAAC,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAEtC,QAAQ,CACF,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
interface AuthKitProviderProps {
|
|
3
|
-
children: React.ReactNode;
|
|
4
|
-
/**
|
|
5
|
-
* Customize what happens when a session is expired. By default,the entire page will be reloaded.
|
|
6
|
-
* You can also pass this as `false` to disable the expired session checks.
|
|
7
|
-
*/
|
|
8
|
-
onSessionExpired?: false | (() => void);
|
|
9
|
-
}
|
|
10
|
-
export declare const AuthKitProvider: ({ children, onSessionExpired }: AuthKitProviderProps) => React.JSX.Element;
|
|
11
|
-
export {};
|
package/src/authkit-provider.tsx
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { checkSessionAction } from './actions.js';
|
|
5
|
-
|
|
6
|
-
interface AuthKitProviderProps {
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
/**
|
|
9
|
-
* Customize what happens when a session is expired. By default,the entire page will be reloaded.
|
|
10
|
-
* You can also pass this as `false` to disable the expired session checks.
|
|
11
|
-
*/
|
|
12
|
-
onSessionExpired?: false | (() => void);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const AuthKitProvider = ({ children, onSessionExpired }: AuthKitProviderProps) => {
|
|
16
|
-
React.useEffect(() => {
|
|
17
|
-
// Return early if the session expired checks are disabled.
|
|
18
|
-
if (onSessionExpired === false) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let visibilityChangedCalled = false;
|
|
23
|
-
|
|
24
|
-
const handleVisibilityChange = async () => {
|
|
25
|
-
if (visibilityChangedCalled) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// In the case where we're using middleware auth mode, a user that has signed out in a different tab
|
|
30
|
-
// will run into an issue if they attempt to hit a server action in the original tab.
|
|
31
|
-
// This will force a refresh of the page in that case, which will redirect them to the sign-in page.
|
|
32
|
-
if (document.visibilityState === 'visible') {
|
|
33
|
-
visibilityChangedCalled = true;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const hasSession = await checkSessionAction();
|
|
37
|
-
if (!hasSession) {
|
|
38
|
-
throw new Error('Session expired');
|
|
39
|
-
}
|
|
40
|
-
} catch (error) {
|
|
41
|
-
// 'Failed to fetch' is the error we are looking for if the action fails
|
|
42
|
-
// If any other error happens, for other reasons, we should not reload the page
|
|
43
|
-
if (error instanceof Error && error.message.includes('Failed to fetch')) {
|
|
44
|
-
if (onSessionExpired) {
|
|
45
|
-
onSessionExpired();
|
|
46
|
-
} else {
|
|
47
|
-
window.location.reload();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
} finally {
|
|
51
|
-
visibilityChangedCalled = false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
window.addEventListener('visibilitychange', handleVisibilityChange);
|
|
57
|
-
window.addEventListener('focus', handleVisibilityChange);
|
|
58
|
-
|
|
59
|
-
return () => {
|
|
60
|
-
window.removeEventListener('focus', handleVisibilityChange);
|
|
61
|
-
window.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
62
|
-
};
|
|
63
|
-
}, [onSessionExpired]);
|
|
64
|
-
|
|
65
|
-
return <>{children}</>;
|
|
66
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|