@workos-inc/authkit-nextjs 2.12.2 → 2.14.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 +138 -73
- package/dist/esm/errors.js +33 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/get-authorization-url.js +7 -2
- package/dist/esm/get-authorization-url.js.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/middleware-helpers.js +99 -0
- package/dist/esm/middleware-helpers.js.map +1 -0
- package/dist/esm/session.js +11 -35
- package/dist/esm/session.js.map +1 -1
- package/dist/esm/types/errors.d.ts +15 -0
- package/dist/esm/types/index.d.ts +3 -1
- package/dist/esm/types/middleware-helpers.d.ts +25 -0
- package/dist/esm/types/session.d.ts +1 -1
- package/dist/esm/types/validate-api-key.d.ts +1 -1
- package/dist/esm/types/workos.d.ts +1 -1
- package/dist/esm/utils.js +0 -2
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/workos.js +1 -1
- package/package.json +20 -21
- package/src/actions.spec.ts +14 -12
- package/src/auth.spec.ts +27 -29
- package/src/authkit-callback-route.spec.ts +31 -29
- package/src/components/authkit-provider.spec.tsx +67 -71
- package/src/components/button.spec.tsx +4 -6
- package/src/components/impersonation.spec.tsx +25 -25
- package/src/components/min-max-button.spec.tsx +2 -1
- package/src/components/tokenStore.spec.ts +21 -21
- package/src/components/useAccessToken.spec.tsx +73 -77
- package/src/components/useTokenClaims.spec.tsx +22 -22
- package/src/cookie.spec.ts +14 -9
- package/src/errors.spec.ts +108 -0
- package/src/errors.ts +46 -0
- package/src/get-authorization-url.spec.ts +12 -13
- package/src/get-authorization-url.ts +6 -10
- package/src/index.ts +16 -2
- package/src/middleware-helpers.spec.ts +231 -0
- package/src/middleware-helpers.ts +130 -0
- package/src/session.spec.ts +81 -73
- package/src/session.ts +16 -38
- package/src/utils.spec.ts +14 -31
- package/src/utils.ts +0 -2
- package/src/validate-api-key.spec.ts +4 -6
- package/src/workos.spec.ts +2 -2
- package/src/workos.ts +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ The AuthKit library for Next.js provides convenient helpers for authentication a
|
|
|
9
9
|
Install the package with:
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
|
|
12
|
+
pnpm i @workos-inc/authkit-nextjs
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
or
|
|
@@ -142,31 +142,41 @@ The `onSuccess` callback receives the following data:
|
|
|
142
142
|
|
|
143
143
|
**Note**: `authenticationMethod` is only provided during the initial authentication callback. It will not be available in subsequent requests or session refreshes.
|
|
144
144
|
|
|
145
|
-
###
|
|
145
|
+
### Proxy / Middleware
|
|
146
146
|
|
|
147
|
-
This library relies on Next.js middleware to provide session management for routes.
|
|
147
|
+
This library relies on Next.js proxy (called "middleware" in Next.js ≤15) to provide session management for routes.
|
|
148
148
|
|
|
149
|
-
**For Next.js ≤15:** Create a `middleware.ts` file in the root of your project.
|
|
150
149
|
**For Next.js 16+:** Create a `proxy.ts` file in the root of your project.
|
|
150
|
+
**For Next.js ≤15:** Create a `middleware.ts` file in the root of your project.
|
|
151
151
|
|
|
152
|
-
The code remains the same; only the filename
|
|
152
|
+
The code remains the same; only the filename and export name differ:
|
|
153
153
|
|
|
154
154
|
```ts
|
|
155
|
+
// proxy.ts (Next.js 16+) or middleware.ts (Next.js ≤15)
|
|
155
156
|
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
156
157
|
|
|
157
158
|
export default authkitMiddleware();
|
|
159
|
+
// For Next.js 16+, you can also use: export { default as proxy } from './proxy';
|
|
158
160
|
|
|
159
161
|
// Match against pages that require auth
|
|
160
|
-
// Leave this out if you want auth on every resource (including images, css etc.)
|
|
161
162
|
export const config = { matcher: ['/', '/admin'] };
|
|
162
163
|
```
|
|
163
164
|
|
|
164
|
-
|
|
165
|
+
> [!WARNING]
|
|
166
|
+
> Using a catch-all matcher pattern can intercept static assets (CSS, images, fonts), causing styles to break—particularly with Tailwind CSS v4. If you need a broad matcher, exclude Next.js static paths:
|
|
167
|
+
>
|
|
168
|
+
> ```ts
|
|
169
|
+
> export const config = {
|
|
170
|
+
> matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
171
|
+
> };
|
|
172
|
+
> ```
|
|
173
|
+
|
|
174
|
+
The proxy/middleware can be configured with several options.
|
|
165
175
|
|
|
166
176
|
| Option | Default | Description |
|
|
167
177
|
| ---------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
168
178
|
| `redirectUri` | `undefined` | Used in cases where you need your redirect URI to be set dynamically (e.g. Vercel preview deployments) |
|
|
169
|
-
| `middlewareAuth` | `undefined` | Used to configure middleware auth options. See [middleware auth](#middleware-auth) for more details.
|
|
179
|
+
| `middlewareAuth` | `undefined` | Used to configure proxy/middleware auth options. See [middleware auth](#middleware-auth) for more details. |
|
|
170
180
|
| `debug` | `false` | Enables debug logs. |
|
|
171
181
|
| `signUpPaths` | `[]` | Used to specify paths that should use the 'sign-up' screen hint when redirecting to AuthKit. |
|
|
172
182
|
| `eagerAuth` | `false` | Enables synchronous access token availability for third-party services. See [eager auth](#eager-auth) for more details. |
|
|
@@ -183,12 +193,123 @@ export default authkitMiddleware({
|
|
|
183
193
|
});
|
|
184
194
|
|
|
185
195
|
// Match against pages that require auth
|
|
186
|
-
// Leave this out if you want auth on every resource (including images, css etc.)
|
|
187
196
|
export const config = { matcher: ['/', '/admin'] };
|
|
188
197
|
```
|
|
189
198
|
|
|
190
199
|
Custom redirect URIs will be used over a redirect URI configured in the environment variables.
|
|
191
200
|
|
|
201
|
+
#### Composable proxy/middleware
|
|
202
|
+
|
|
203
|
+
If you need to combine AuthKit with other proxy logic (rate limiting, redirects, etc.), use the `authkit()` function with `handleAuthkitHeaders()` helper:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
// proxy.ts (Next.js 16+) or middleware.ts (Next.js ≤15)
|
|
207
|
+
import { NextRequest } from 'next/server';
|
|
208
|
+
import { authkit, handleAuthkitHeaders } from '@workos-inc/authkit-nextjs';
|
|
209
|
+
|
|
210
|
+
export default async function proxy(request: NextRequest) {
|
|
211
|
+
// For Next.js ≤15, use: export default async function middleware(request: NextRequest) {
|
|
212
|
+
// Get session, headers, and the WorkOS authorization URL for sign-in redirects
|
|
213
|
+
const { session, headers, authorizationUrl } = await authkit(request);
|
|
214
|
+
|
|
215
|
+
const { pathname } = request.nextUrl;
|
|
216
|
+
|
|
217
|
+
// Redirect unauthenticated users on protected routes
|
|
218
|
+
if (pathname.startsWith('/app') && !session.user && authorizationUrl) {
|
|
219
|
+
return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Custom redirects (relative URLs supported)
|
|
223
|
+
if (pathname === '/old-path') {
|
|
224
|
+
return handleAuthkitHeaders(request, headers, { redirect: '/new-path' });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Continue request with properly merged headers
|
|
228
|
+
return handleAuthkitHeaders(request, headers);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export const config = { matcher: ['/', '/app/:path*'] };
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
> [!IMPORTANT]
|
|
235
|
+
> Always use `handleAuthkitHeaders()` when returning a response. This helper ensures:
|
|
236
|
+
>
|
|
237
|
+
> - AuthKit headers are properly passed to your pages (so `withAuth()` works)
|
|
238
|
+
> - Internal headers (session data, URLs) are never leaked to the browser
|
|
239
|
+
> - Only safe response headers (`Set-Cookie`, `Cache-Control`, `Vary`) are forwarded
|
|
240
|
+
> - `Cache-Control: no-store` is automatically set when cookies are present
|
|
241
|
+
> - `Vary` headers are properly merged when multiple values exist
|
|
242
|
+
> - Relative redirect URLs are automatically normalized to absolute URLs
|
|
243
|
+
> - POST/PUT redirects use 303 status to prevent form resubmission
|
|
244
|
+
|
|
245
|
+
> [!NOTE]
|
|
246
|
+
> The `redirect` option should only be used with trusted values (e.g., `authorizationUrl` from `authkit()` or hardcoded paths). Never pass user-controlled input directly to `redirect` without validation, as this could enable open redirect attacks.
|
|
247
|
+
|
|
248
|
+
##### Redirect options
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
handleAuthkitHeaders(request, headers, {
|
|
252
|
+
redirect: '/login', // URL to redirect to (string or URL object)
|
|
253
|
+
redirectStatus: 307, // 302 | 303 | 307 | 308 (default: 307 for GET, 303 for POST)
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
##### Advanced: Composing with rewrites
|
|
258
|
+
|
|
259
|
+
For advanced use cases like rewrites, use the lower-level `partitionAuthkitHeaders()` and `applyResponseHeaders()`:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
// proxy.ts (Next.js 16+) or middleware.ts (Next.js ≤15)
|
|
263
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
264
|
+
import { authkit, partitionAuthkitHeaders, applyResponseHeaders } from '@workos-inc/authkit-nextjs';
|
|
265
|
+
|
|
266
|
+
export default async function proxy(request: NextRequest) {
|
|
267
|
+
// For Next.js ≤15, use: export default async function middleware(request: NextRequest) {
|
|
268
|
+
const { headers } = await authkit(request);
|
|
269
|
+
const { requestHeaders, responseHeaders } = partitionAuthkitHeaders(request, headers);
|
|
270
|
+
|
|
271
|
+
// Create your own response (rewrite, etc.)
|
|
272
|
+
const response = NextResponse.rewrite(new URL('/app/dashboard', request.url), {
|
|
273
|
+
request: { headers: requestHeaders },
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Apply AuthKit response headers (Set-Cookie, etc.)
|
|
277
|
+
applyResponseHeaders(response, responseHeaders);
|
|
278
|
+
|
|
279
|
+
return response;
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
##### Internal headers reference
|
|
284
|
+
|
|
285
|
+
AuthKit uses internal headers to pass data between proxy/middleware and server components. These are automatically handled by the helpers above, but understanding them helps with debugging.
|
|
286
|
+
|
|
287
|
+
**Request headers** (passed to server components, never sent to browser):
|
|
288
|
+
|
|
289
|
+
| Header | Purpose |
|
|
290
|
+
| --------------------- | ------------------------------------------------------------------------------------------ |
|
|
291
|
+
| `x-workos-middleware` | Flag indicating AuthKit proxy/middleware is active. Required for `withAuth()` to function. |
|
|
292
|
+
| `x-workos-session` | Encrypted session data. Contains user info, access token, and refresh token. |
|
|
293
|
+
| `x-url` | Current request URL. Used for redirect-after-login and generating sign-in URLs. |
|
|
294
|
+
| `x-redirect-uri` | OAuth callback URI. Used by `getAuthorizationUrl()` for the OAuth flow. |
|
|
295
|
+
| `x-sign-up-paths` | Paths configured to trigger sign-up instead of sign-in flow. |
|
|
296
|
+
|
|
297
|
+
> **Security:** These headers contain sensitive session data. The `handleAuthkitHeaders()` helper ensures they're forwarded to your pages (so `withAuth()` works) but never leaked to the browser. Client-injected `x-workos-*` headers are stripped and replaced with trusted values.
|
|
298
|
+
|
|
299
|
+
**Response headers** (safe to send to browser):
|
|
300
|
+
|
|
301
|
+
| Header | Purpose |
|
|
302
|
+
| -------------------- | -------------------------------------------------------------------------------------- |
|
|
303
|
+
| `Set-Cookie` | Session cookies (e.g., `wos-session`). Multiple cookies are properly appended. |
|
|
304
|
+
| `Cache-Control` | Caching directives. Auto-set to `no-store` when cookies are present. |
|
|
305
|
+
| `Vary` | Cache variation keys. Values are deduplicated when merging. |
|
|
306
|
+
| `WWW-Authenticate` | Authentication challenge for 401 responses (API auth flows). |
|
|
307
|
+
| `Proxy-Authenticate` | Authentication challenge for proxy auth. |
|
|
308
|
+
| `Link` | Pagination, preload hints, etc. |
|
|
309
|
+
| `x-middleware-cache` | Next.js proxy/middleware result caching. Set to `no-cache` to prevent stale responses. |
|
|
310
|
+
|
|
311
|
+
Only these allowlisted headers are forwarded to the browser. Any other headers from `authkit()` (including future `x-workos-*` headers) are filtered out for security.
|
|
312
|
+
|
|
192
313
|
## Usage
|
|
193
314
|
|
|
194
315
|
### Wrap your app in `AuthKitProvider`
|
|
@@ -220,7 +341,7 @@ import { withAuth } from '@workos-inc/authkit-nextjs';
|
|
|
220
341
|
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
|
221
342
|
// Fetch auth data on the server
|
|
222
343
|
const auth = await withAuth();
|
|
223
|
-
|
|
344
|
+
|
|
224
345
|
// Remove the accessToken from the auth object as it is not needed on the client side
|
|
225
346
|
const { accessToken, ...initialAuth } = auth;
|
|
226
347
|
|
|
@@ -503,16 +624,16 @@ const { session, headers } = await authkit(request, {
|
|
|
503
624
|
});
|
|
504
625
|
```
|
|
505
626
|
|
|
506
|
-
These callbacks provide a way to perform side effects when sessions are refreshed in the middleware. Common use cases include:
|
|
627
|
+
These callbacks provide a way to perform side effects when sessions are refreshed in the proxy/middleware. Common use cases include:
|
|
507
628
|
|
|
508
629
|
- Logging authentication events
|
|
509
630
|
- Updating last activity timestamps
|
|
510
631
|
- Triggering organization-specific data prefetching
|
|
511
632
|
- Recording failed refresh attempts
|
|
512
633
|
|
|
513
|
-
### Middleware auth
|
|
634
|
+
### Proxy / Middleware auth
|
|
514
635
|
|
|
515
|
-
The default behavior of this library is to request authentication via the `withAuth` method on a per-page basis. There are some use cases where you don't want to call `withAuth` (e.g. you don't need user data for your page) or if you'd prefer a "secure by default" approach where every route defined in your middleware matcher is protected unless specified otherwise. In those cases you can opt-in to use
|
|
636
|
+
The default behavior of this library is to request authentication via the `withAuth` method on a per-page basis. There are some use cases where you don't want to call `withAuth` (e.g. you don't need user data for your page) or if you'd prefer a "secure by default" approach where every route defined in your proxy/middleware matcher is protected unless specified otherwise. In those cases you can opt-in to use `middlewareAuth` instead:
|
|
516
637
|
|
|
517
638
|
```ts
|
|
518
639
|
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
@@ -539,7 +660,7 @@ The `eagerAuth` option enables synchronous access to authentication tokens on in
|
|
|
539
660
|
|
|
540
661
|
#### How it works
|
|
541
662
|
|
|
542
|
-
When `eagerAuth: true` is set, the middleware temporarily stores the access token in a short-lived cookie (30 seconds) that is:
|
|
663
|
+
When `eagerAuth: true` is set, the proxy/middleware temporarily stores the access token in a short-lived cookie (30 seconds) that is:
|
|
543
664
|
|
|
544
665
|
- Only set on initial page loads (not API or prefetch requests)
|
|
545
666
|
- Immediately consumed and deleted by the client
|
|
@@ -547,7 +668,7 @@ When `eagerAuth: true` is set, the middleware temporarily stores the access toke
|
|
|
547
668
|
|
|
548
669
|
#### Usage
|
|
549
670
|
|
|
550
|
-
Enable eager auth in your middleware configuration:
|
|
671
|
+
Enable eager auth in your proxy/middleware configuration:
|
|
551
672
|
|
|
552
673
|
```ts
|
|
553
674
|
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
@@ -601,62 +722,6 @@ Eager auth makes tokens briefly accessible via JavaScript (30-second window) to
|
|
|
601
722
|
- Most API calls where a brief loading state is acceptable
|
|
602
723
|
- When you don't need immediate token access on page load
|
|
603
724
|
|
|
604
|
-
### Composing middleware
|
|
605
|
-
|
|
606
|
-
> **Security note:** Always forward `request.headers` when returning `NextResponse.*` to mitigate SSRF issues in Next.js < 14.2.32 (14.x) or < 15.4.7 (15.x). This pattern is safe on all versions. We strongly recommend upgrading to the latest Next.js.
|
|
607
|
-
|
|
608
|
-
If you don't want to use `authkitMiddleware` and instead want to compose your own middleware, you can use the `authkit` method. In this mode you are responsible to handling what to do when there's no session on a protected route.
|
|
609
|
-
|
|
610
|
-
> **Note:** For Next.js 16+, name your file `proxy.ts` and the function `proxy` instead of `middleware`.
|
|
611
|
-
|
|
612
|
-
```ts
|
|
613
|
-
export default async function middleware(request: NextRequest) {
|
|
614
|
-
// Perform logic before or after AuthKit
|
|
615
|
-
|
|
616
|
-
// Auth object contains the session, response headers and an authorization URL in the case that the session isn't valid
|
|
617
|
-
// This method will automatically handle setting the cookie and refreshing the session
|
|
618
|
-
const {
|
|
619
|
-
session,
|
|
620
|
-
headers: authkitHeaders,
|
|
621
|
-
authorizationUrl,
|
|
622
|
-
} = await authkit(request, {
|
|
623
|
-
debug: true,
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
const { pathname } = new URL(request.url);
|
|
627
|
-
|
|
628
|
-
// Control of what to do when there's no session on a protected route is left to the developer
|
|
629
|
-
if (pathname.startsWith('/account') && !session.user) {
|
|
630
|
-
console.log('No session on protected path');
|
|
631
|
-
return NextResponse.redirect(authorizationUrl);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
// Forward the incoming request headers (mitigation) and pass AuthKit headers as request headers
|
|
635
|
-
const response = NextResponse.next({
|
|
636
|
-
request: { headers: authkitHeaders },
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
// Copy Set-Cookie and cache control headers to the response, but exclude the internal
|
|
640
|
-
// x-workos-session header which contains encrypted session data and should never appear
|
|
641
|
-
// in HTTP responses (it's only used to pass session data between middleware and page handlers)
|
|
642
|
-
for (const [key, value] of authkitHeaders) {
|
|
643
|
-
if (key.toLowerCase() === 'x-workos-session') {
|
|
644
|
-
continue; // Internal header - must not leak to response
|
|
645
|
-
}
|
|
646
|
-
if (key.toLowerCase() === 'set-cookie') {
|
|
647
|
-
response.headers.append(key, value);
|
|
648
|
-
} else {
|
|
649
|
-
response.headers.set(key, value);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
return response;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Match against the pages
|
|
657
|
-
export const config = { matcher: ['/', '/account/:path*'] };
|
|
658
|
-
```
|
|
659
|
-
|
|
660
725
|
### Signing out
|
|
661
726
|
|
|
662
727
|
Use the `signOut` method to sign out the current logged in user and redirect to your app's default Logout URI. The Logout URI is set in your WorkOS dashboard settings under "Redirect".
|
|
@@ -818,7 +883,7 @@ The library automatically sets appropriate cache headers on all authenticated re
|
|
|
818
883
|
- `Pragma: no-cache` - HTTP/1.0 compatibility
|
|
819
884
|
- `Expires: 0` - HTTP/1.0 cache expiration
|
|
820
885
|
- `Vary: Cookie` - Ensures CDNs differentiate between different users (defense-in-depth)
|
|
821
|
-
- `x-middleware-cache: no-cache` - Prevents Next.js middleware result caching
|
|
886
|
+
- `x-middleware-cache: no-cache` - Prevents Next.js proxy/middleware result caching
|
|
822
887
|
|
|
823
888
|
These headers are applied automatically when:
|
|
824
889
|
|
|
@@ -834,7 +899,7 @@ These headers are applied automatically when:
|
|
|
834
899
|
|
|
835
900
|
### Debugging
|
|
836
901
|
|
|
837
|
-
To enable debug logs, initialize the middleware with the debug flag enabled.
|
|
902
|
+
To enable debug logs, initialize the proxy/middleware with the debug flag enabled.
|
|
838
903
|
|
|
839
904
|
```js
|
|
840
905
|
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { decodeJwt } from './jwt.js';
|
|
2
|
+
export class AuthKitError extends Error {
|
|
3
|
+
constructor(message, cause, data) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'AuthKitError';
|
|
6
|
+
this.cause = cause;
|
|
7
|
+
this.data = data;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class TokenRefreshError extends AuthKitError {
|
|
11
|
+
constructor(message, cause, context) {
|
|
12
|
+
super(message, cause);
|
|
13
|
+
this.name = 'TokenRefreshError';
|
|
14
|
+
this.userId = context === null || context === void 0 ? void 0 : context.userId;
|
|
15
|
+
this.sessionId = context === null || context === void 0 ? void 0 : context.sessionId;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function getSessionErrorContext(session) {
|
|
19
|
+
if (!(session === null || session === void 0 ? void 0 : session.accessToken)) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const { payload } = decodeJwt(session.accessToken);
|
|
24
|
+
return {
|
|
25
|
+
userId: payload.sub,
|
|
26
|
+
sessionId: payload.sid,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (_a) {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,OAAO,YAAa,SAAQ,KAAK;IAGrC,YAAY,OAAe,EAAE,KAAe,EAAE,IAA8B;QAC1E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAOD,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IAIjD,YAAY,OAAe,EAAE,KAAe,EAAE,OAAkC;QAC9E,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,CAAC;IACtC,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAwB;IAC7D,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,CAAA,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACnD,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,GAAG;YACnB,SAAS,EAAE,OAAO,CAAC,GAAG;SACvB,CAAC;IACJ,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -2,8 +2,13 @@ import { getWorkOS } from './workos.js';
|
|
|
2
2
|
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
|
-
|
|
6
|
-
const { returnPathname, screenHint, organizationId,
|
|
5
|
+
var _a;
|
|
6
|
+
const { returnPathname, screenHint, organizationId, loginHint, prompt, state: customState } = options;
|
|
7
|
+
let redirectUri = options.redirectUri;
|
|
8
|
+
if (!redirectUri) {
|
|
9
|
+
const headersList = await headers();
|
|
10
|
+
redirectUri = (_a = headersList.get('x-redirect-uri')) !== null && _a !== void 0 ? _a : undefined;
|
|
11
|
+
}
|
|
7
12
|
const internalState = returnPathname
|
|
8
13
|
? btoa(JSON.stringify({ returnPathname })).replace(/\+/g, '-').replace(/\//g, '_')
|
|
9
14
|
: null;
|
|
@@ -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
|
|
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,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACtG,IAAI,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACtC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;QACpC,WAAW,GAAG,MAAA,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,mCAAI,SAAS,CAAC;IAC/D,CAAC;IAED,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/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { getSignInUrl, getSignUpUrl, signOut, switchToOrganization } from './auth.js';
|
|
2
2
|
import { handleAuth } from './authkit-callback-route.js';
|
|
3
|
+
import { AuthKitError, TokenRefreshError } from './errors.js';
|
|
3
4
|
import { authkit, authkitMiddleware } from './middleware.js';
|
|
5
|
+
export { applyResponseHeaders, handleAuthkitHeaders, partitionAuthkitHeaders, isAuthkitRequestHeader, AUTHKIT_REQUEST_HEADERS, } from './middleware-helpers.js';
|
|
4
6
|
import { getTokenClaims, refreshSession, saveSession, withAuth } from './session.js';
|
|
5
7
|
import { validateApiKey } from './validate-api-key.js';
|
|
6
8
|
import { getWorkOS } from './workos.js';
|
|
7
9
|
export * from './interfaces.js';
|
|
8
|
-
export { authkit, authkitMiddleware, getSignInUrl, getSignUpUrl, getWorkOS, handleAuth, refreshSession, saveSession, signOut, switchToOrganization,
|
|
10
|
+
export { AuthKitError, TokenRefreshError, authkit, authkitMiddleware, getSignInUrl, getSignUpUrl, getTokenClaims, getWorkOS, handleAuth, refreshSession, saveSession, signOut, switchToOrganization, validateApiKey, withAuth, };
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,UAAU,EACV,cAAc,EACd,WAAW,EACX,OAAO,EACP,oBAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,GAKxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,OAAO,EACP,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,UAAU,EACV,cAAc,EACd,WAAW,EACX,OAAO,EACP,oBAAoB,EACpB,cAAc,EACd,QAAQ,GACT,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
/** Internal AuthKit headers - forwarded to downstream requests but never sent to browser. */
|
|
3
|
+
export const AUTHKIT_REQUEST_HEADERS = [
|
|
4
|
+
'x-workos-middleware',
|
|
5
|
+
'x-url',
|
|
6
|
+
'x-redirect-uri',
|
|
7
|
+
'x-sign-up-paths',
|
|
8
|
+
'x-workos-session',
|
|
9
|
+
];
|
|
10
|
+
const ALLOWED_RESPONSE_HEADERS = [
|
|
11
|
+
'set-cookie',
|
|
12
|
+
'cache-control',
|
|
13
|
+
'vary',
|
|
14
|
+
'www-authenticate',
|
|
15
|
+
'proxy-authenticate',
|
|
16
|
+
'link',
|
|
17
|
+
'x-middleware-cache',
|
|
18
|
+
];
|
|
19
|
+
const MULTI_VALUE_HEADERS = ['set-cookie', 'www-authenticate', 'proxy-authenticate', 'link'];
|
|
20
|
+
export function isAuthkitRequestHeader(name) {
|
|
21
|
+
const lower = name.toLowerCase();
|
|
22
|
+
return AUTHKIT_REQUEST_HEADERS.includes(lower) || lower.startsWith('x-workos-');
|
|
23
|
+
}
|
|
24
|
+
function setHeader(headers, name, value) {
|
|
25
|
+
const lower = name.toLowerCase();
|
|
26
|
+
if (MULTI_VALUE_HEADERS.includes(lower)) {
|
|
27
|
+
headers.append(name, value);
|
|
28
|
+
}
|
|
29
|
+
else if (lower === 'vary') {
|
|
30
|
+
const existing = headers.get(name);
|
|
31
|
+
const merged = new Set([
|
|
32
|
+
...(existing ? existing.split(',').map((v) => v.trim()) : []),
|
|
33
|
+
...value.split(',').map((v) => v.trim()),
|
|
34
|
+
]);
|
|
35
|
+
headers.set(name, [...merged].join(', '));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
headers.set(name, value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Partitions AuthKit headers into request headers (for withAuth) and response headers (for browser).
|
|
43
|
+
*/
|
|
44
|
+
export function partitionAuthkitHeaders(request, authkitHeaders) {
|
|
45
|
+
const headers = new Headers(authkitHeaders);
|
|
46
|
+
const requestHeaders = new Headers(request.headers);
|
|
47
|
+
// Strip any client-injected authkit headers, then apply trusted ones
|
|
48
|
+
for (const name of [...requestHeaders.keys()]) {
|
|
49
|
+
if (isAuthkitRequestHeader(name)) {
|
|
50
|
+
requestHeaders.delete(name);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const headerName of AUTHKIT_REQUEST_HEADERS) {
|
|
54
|
+
const value = headers.get(headerName);
|
|
55
|
+
if (value != null) {
|
|
56
|
+
requestHeaders.set(headerName, value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Build response headers from allowlist only
|
|
60
|
+
const responseHeaders = new Headers();
|
|
61
|
+
for (const [name, value] of headers) {
|
|
62
|
+
const lower = name.toLowerCase();
|
|
63
|
+
if (!isAuthkitRequestHeader(lower) && ALLOWED_RESPONSE_HEADERS.includes(lower)) {
|
|
64
|
+
setHeader(responseHeaders, name, value);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Auto-add cache-control when setting cookies
|
|
68
|
+
if (responseHeaders.has('set-cookie') && !responseHeaders.has('cache-control')) {
|
|
69
|
+
responseHeaders.set('cache-control', 'no-store');
|
|
70
|
+
}
|
|
71
|
+
return { requestHeaders, responseHeaders };
|
|
72
|
+
}
|
|
73
|
+
export function applyResponseHeaders(response, responseHeaders) {
|
|
74
|
+
for (const [name, value] of responseHeaders) {
|
|
75
|
+
setHeader(response.headers, name, value);
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Creates a NextResponse with properly merged AuthKit headers.
|
|
81
|
+
*/
|
|
82
|
+
export function handleAuthkitHeaders(request, authkitHeaders, options = {}) {
|
|
83
|
+
const { requestHeaders, responseHeaders } = partitionAuthkitHeaders(request, authkitHeaders);
|
|
84
|
+
const { redirect, redirectStatus } = options;
|
|
85
|
+
if (redirect != null && redirect !== '') {
|
|
86
|
+
let redirectUrl;
|
|
87
|
+
try {
|
|
88
|
+
redirectUrl = redirect instanceof URL ? redirect : new URL(redirect, request.url);
|
|
89
|
+
}
|
|
90
|
+
catch (_a) {
|
|
91
|
+
throw new Error(`Invalid redirect URL: "${redirect}". Must be a valid absolute or relative URL.`);
|
|
92
|
+
}
|
|
93
|
+
const method = request.method.toUpperCase();
|
|
94
|
+
const status = redirectStatus !== null && redirectStatus !== void 0 ? redirectStatus : (method === 'GET' || method === 'HEAD' ? 307 : 303);
|
|
95
|
+
return applyResponseHeaders(NextResponse.redirect(redirectUrl, status), responseHeaders);
|
|
96
|
+
}
|
|
97
|
+
return applyResponseHeaders(NextResponse.next({ request: { headers: requestHeaders } }), responseHeaders);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=middleware-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-helpers.js","sourceRoot":"","sources":["../../src/middleware-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/session.js
CHANGED
|
@@ -3,13 +3,14 @@ import { sealData, unsealData } from 'iron-session';
|
|
|
3
3
|
import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';
|
|
4
4
|
import { cookies, headers } from 'next/headers';
|
|
5
5
|
import { redirect } from 'next/navigation';
|
|
6
|
-
import { NextResponse } from 'next/server';
|
|
7
6
|
import { getCookieOptions, getJwtCookie } from './cookie.js';
|
|
8
7
|
import { WORKOS_CLIENT_ID, WORKOS_COOKIE_NAME, WORKOS_COOKIE_PASSWORD, WORKOS_REDIRECT_URI } from './env-variables.js';
|
|
8
|
+
import { TokenRefreshError, getSessionErrorContext } from './errors.js';
|
|
9
9
|
import { getAuthorizationUrl } from './get-authorization-url.js';
|
|
10
10
|
import { getWorkOS } from './workos.js';
|
|
11
11
|
import { parse, tokensToRegexp } from 'path-to-regexp';
|
|
12
|
-
import {
|
|
12
|
+
import { handleAuthkitHeaders } from './middleware-helpers.js';
|
|
13
|
+
import { lazy, setCachePreventionHeaders } from './utils.js';
|
|
13
14
|
const sessionHeaderName = 'x-workos-session';
|
|
14
15
|
const middlewareHeaderName = 'x-workos-middleware';
|
|
15
16
|
const signUpPathsHeaderName = 'x-sign-up-paths';
|
|
@@ -100,42 +101,19 @@ async function updateSessionMiddleware(request, debug, middlewareAuth, redirectU
|
|
|
100
101
|
screenHint: getScreenHint(signUpPaths, request.nextUrl.pathname),
|
|
101
102
|
eagerAuth,
|
|
102
103
|
});
|
|
103
|
-
// If the user is logged out and this path isn't on the allowlist for logged out paths, redirect to AuthKit.
|
|
104
|
-
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session.user) {
|
|
105
|
-
if (debug) {
|
|
106
|
-
console.log(`Unauthenticated user on protected route ${request.url}, redirecting to AuthKit`);
|
|
107
|
-
}
|
|
108
|
-
return redirectWithFallback(authorizationUrl, headers);
|
|
109
|
-
}
|
|
110
104
|
// Record the sign up paths so we can use them later
|
|
111
105
|
if (signUpPaths.length > 0) {
|
|
112
106
|
headers.set(signUpPathsHeaderName, signUpPaths.join(','));
|
|
113
107
|
}
|
|
114
108
|
applyCacheSecurityHeaders(headers, request, session);
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
if (headers.has(signUpPathsHeaderName)) {
|
|
123
|
-
requestHeaders.set(signUpPathsHeaderName, headers.get(signUpPathsHeaderName));
|
|
124
|
-
}
|
|
125
|
-
// Pass session to page handlers via request header
|
|
126
|
-
// This ensures handlers see refreshed sessions immediately (before Set-Cookie reaches browser)
|
|
127
|
-
const sessionHeader = headers.get(sessionHeaderName);
|
|
128
|
-
if (sessionHeader) {
|
|
129
|
-
requestHeaders.set(sessionHeaderName, sessionHeader);
|
|
109
|
+
// If the user is logged out and this path isn't on the allowlist for logged out paths, redirect to AuthKit.
|
|
110
|
+
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session.user) {
|
|
111
|
+
if (debug) {
|
|
112
|
+
console.log(`Unauthenticated user on protected route ${request.url}, redirecting to AuthKit`);
|
|
113
|
+
}
|
|
114
|
+
return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
|
|
130
115
|
}
|
|
131
|
-
|
|
132
|
-
headers.delete(sessionHeaderName);
|
|
133
|
-
return NextResponse.next({
|
|
134
|
-
request: {
|
|
135
|
-
headers: requestHeaders,
|
|
136
|
-
},
|
|
137
|
-
headers,
|
|
138
|
-
});
|
|
116
|
+
return handleAuthkitHeaders(request, headers);
|
|
139
117
|
}
|
|
140
118
|
async function updateSession(request, options = { debug: false }) {
|
|
141
119
|
var _a, _b;
|
|
@@ -288,9 +266,7 @@ async function refreshSession({ organizationId: nextOrganizationId, ensureSigned
|
|
|
288
266
|
});
|
|
289
267
|
}
|
|
290
268
|
catch (error) {
|
|
291
|
-
throw new
|
|
292
|
-
cause: error,
|
|
293
|
-
});
|
|
269
|
+
throw new TokenRefreshError(`Failed to refresh session: ${error instanceof Error ? error.message : String(error)}`, error, getSessionErrorContext(session));
|
|
294
270
|
}
|
|
295
271
|
const headersList = await headers();
|
|
296
272
|
const url = headersList.get('x-url');
|