@workos-inc/authkit-nextjs 0.4.2 → 0.5.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 +47 -8
- package/dist/cjs/auth.d.ts +2 -1
- package/dist/cjs/auth.js +6 -2
- package/dist/cjs/auth.js.map +1 -1
- package/dist/cjs/cookie.js +4 -1
- package/dist/cjs/cookie.js.map +1 -1
- package/dist/cjs/get-authorization-url.d.ts +2 -1
- package/dist/cjs/get-authorization-url.js +3 -1
- package/dist/cjs/get-authorization-url.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interfaces.d.ts +12 -0
- package/dist/cjs/middleware.d.ts +2 -5
- package/dist/cjs/middleware.js +2 -2
- package/dist/cjs/middleware.js.map +1 -1
- package/dist/cjs/session.d.ts +2 -2
- package/dist/cjs/session.js +28 -2
- package/dist/cjs/session.js.map +1 -1
- package/package.json +4 -5
- package/src/auth.ts +6 -2
- package/src/cookie.ts +6 -1
- package/src/get-authorization-url.ts +5 -1
- package/src/index.ts +2 -1
- package/src/interfaces.ts +15 -0
- package/src/middleware.ts +6 -6
- package/src/session.ts +37 -4
package/README.md
CHANGED
|
@@ -65,8 +65,8 @@ import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
|
65
65
|
export default authkitMiddleware();
|
|
66
66
|
|
|
67
67
|
// Match against pages that require auth
|
|
68
|
-
// Leave this out if you want auth on every
|
|
69
|
-
export const config = { matcher: ['/admin'] };
|
|
68
|
+
// Leave this out if you want auth on every resource (including images, css etc.)
|
|
69
|
+
export const config = { matcher: ['/', '/admin'] };
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
## Usage
|
|
@@ -77,16 +77,28 @@ For pages where you want to display a signed-in and signed-out view, use `getUse
|
|
|
77
77
|
|
|
78
78
|
```jsx
|
|
79
79
|
import Link from 'next/link';
|
|
80
|
-
import { getSignInUrl, getUser, signOut } from '@workos-inc/authkit-nextjs';
|
|
80
|
+
import { getSignInUrl, getSignUpUrl, getUser, signOut } from '@workos-inc/authkit-nextjs';
|
|
81
81
|
|
|
82
82
|
export default async function HomePage() {
|
|
83
83
|
// Retrieves the user from the session or returns `null` if no user is signed in
|
|
84
84
|
const { user } = await getUser();
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
if (!user) {
|
|
87
|
+
// Get the URL to redirect the user to AuthKit to sign in
|
|
88
|
+
const signInUrl = await getSignInUrl();
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
// Get the URL to redirect the user to AuthKit to sign up
|
|
91
|
+
const signUpUrl = await getSignUpUrl();
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<>
|
|
95
|
+
<Link href={signInUrl}>Log in</Link>
|
|
96
|
+
<Link href={signUpUrl}>Sign Up</Link>
|
|
97
|
+
</>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return (
|
|
90
102
|
<form
|
|
91
103
|
action={async () => {
|
|
92
104
|
'use server';
|
|
@@ -96,8 +108,6 @@ export default async function HomePage() {
|
|
|
96
108
|
<p>Welcome back {user?.firstName && `, ${user?.firstName}`}</p>
|
|
97
109
|
<button type="submit">Sign out</button>
|
|
98
110
|
</form>
|
|
99
|
-
) : (
|
|
100
|
-
<Link href={signInUrl}>Sign in</Link>
|
|
101
111
|
);
|
|
102
112
|
}
|
|
103
113
|
```
|
|
@@ -112,6 +122,29 @@ const { user } = await getUser({ ensureSignedIn: true });
|
|
|
112
122
|
|
|
113
123
|
Enabling `ensureSignedIn` will redirect users to AuthKit if they attempt to access the page without being authenticated.
|
|
114
124
|
|
|
125
|
+
### Middleware auth
|
|
126
|
+
|
|
127
|
+
The default behavior of this library is to request authentication via the `getUser` method on a per-page basis. There are some use cases where you don't want to call `getUser` (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 middleware auth instead:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
131
|
+
|
|
132
|
+
export default authkitMiddleware({
|
|
133
|
+
middlewareAuth: {
|
|
134
|
+
enabled: true,
|
|
135
|
+
unauthenticatedPaths: ['/', '/about'],
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Match against pages that require auth
|
|
140
|
+
// Leave this out if you want auth on every resource (including images, css etc.)
|
|
141
|
+
export const config = { matcher: ['/', '/admin/:path*', '/about'] };
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
In the above example the `/admin` page will require a user to be signed in, whereas `/` and `/about` can be accessed without signing in.
|
|
145
|
+
|
|
146
|
+
`unauthenticatedPaths` uses the same glob logic as the [Next.js matcher](https://nextjs.org/docs/pages/building-your-application/routing/middleware#matcher).
|
|
147
|
+
|
|
115
148
|
### Signing out
|
|
116
149
|
|
|
117
150
|
Use the `signOut` method to sign out the current logged in user and redirect to your app's homepage. The homepage redirect is set in your WorkOS dashboard settings under "Redirect".
|
|
@@ -143,3 +176,9 @@ import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
|
|
|
143
176
|
|
|
144
177
|
export default authkitMiddleware({ debug: true });
|
|
145
178
|
```
|
|
179
|
+
|
|
180
|
+
### Troubleshooting
|
|
181
|
+
|
|
182
|
+
#### NEXT_REDIRECT error when using try/catch blocks
|
|
183
|
+
|
|
184
|
+
Wrapping a `getUser({ ensureSignedIn: true })` call in a try/catch block will cause a `NEXT_REDIRECT` error. This is because `getUser` 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).
|
package/dist/cjs/auth.d.ts
CHANGED
package/dist/cjs/auth.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.signOut = exports.getSignInUrl = void 0;
|
|
3
|
+
exports.signOut = exports.getSignUpUrl = exports.getSignInUrl = void 0;
|
|
4
4
|
const get_authorization_url_js_1 = require("./get-authorization-url.js");
|
|
5
5
|
const headers_1 = require("next/headers");
|
|
6
6
|
const cookie_js_1 = require("./cookie.js");
|
|
7
7
|
const session_js_1 = require("./session.js");
|
|
8
8
|
async function getSignInUrl() {
|
|
9
|
-
return (0, get_authorization_url_js_1.getAuthorizationUrl)();
|
|
9
|
+
return (0, get_authorization_url_js_1.getAuthorizationUrl)({ screenHint: 'sign-in' });
|
|
10
10
|
}
|
|
11
11
|
exports.getSignInUrl = getSignInUrl;
|
|
12
|
+
async function getSignUpUrl() {
|
|
13
|
+
return (0, get_authorization_url_js_1.getAuthorizationUrl)({ screenHint: 'sign-up' });
|
|
14
|
+
}
|
|
15
|
+
exports.getSignUpUrl = getSignUpUrl;
|
|
12
16
|
async function signOut() {
|
|
13
17
|
(0, headers_1.cookies)().delete(cookie_js_1.cookieName);
|
|
14
18
|
await (0, session_js_1.terminateSession)();
|
package/dist/cjs/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":";;;AAAA,yEAAiE;AACjE,0CAAuC;AACvC,2CAAyC;AACzC,6CAAgD;AAEhD,KAAK,UAAU,YAAY;IACzB,OAAO,IAAA,8CAAmB,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":";;;AAAA,yEAAiE;AACjE,0CAAuC;AACvC,2CAAyC;AACzC,6CAAgD;AAEhD,KAAK,UAAU,YAAY;IACzB,OAAO,IAAA,8CAAmB,EAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;AACxD,CAAC;AAWQ,oCAAY;AATrB,KAAK,UAAU,YAAY;IACzB,OAAO,IAAA,8CAAmB,EAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;AACxD,CAAC;AAOsB,oCAAY;AALnC,KAAK,UAAU,OAAO;IACpB,IAAA,iBAAO,GAAE,CAAC,MAAM,CAAC,sBAAU,CAAC,CAAC;IAC7B,MAAM,IAAA,6BAAgB,GAAE,CAAC;AAC3B,CAAC;AAEoC,0BAAO"}
|
package/dist/cjs/cookie.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.cookieOptions = exports.cookieName = void 0;
|
|
4
|
+
const env_variables_js_1 = require("./env-variables.js");
|
|
5
|
+
const redirectUrl = new URL(env_variables_js_1.WORKOS_REDIRECT_URI);
|
|
6
|
+
const isSecureProtocol = redirectUrl.protocol === 'https:';
|
|
4
7
|
const cookieName = 'wos-session';
|
|
5
8
|
exports.cookieName = cookieName;
|
|
6
9
|
const cookieOptions = {
|
|
7
10
|
path: '/',
|
|
8
11
|
httpOnly: true,
|
|
9
|
-
secure:
|
|
12
|
+
secure: isSecureProtocol,
|
|
10
13
|
sameSite: 'lax',
|
|
11
14
|
};
|
|
12
15
|
exports.cookieOptions = cookieOptions;
|
package/dist/cjs/cookie.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie.js","sourceRoot":"","sources":["../../src/cookie.ts"],"names":[],"mappings":";;;AAAA,MAAM,UAAU,GAAG,aAAa,CAAC;AAQxB,gCAAU;AAPnB,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,GAAG;IACT,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"cookie.js","sourceRoot":"","sources":["../../src/cookie.ts"],"names":[],"mappings":";;;AAAA,yDAAyD;AAEzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,sCAAmB,CAAC,CAAC;AACjD,MAAM,gBAAgB,GAAG,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAE3D,MAAM,UAAU,GAAG,aAAa,CAAC;AAQxB,gCAAU;AAPnB,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,GAAG;IACT,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,gBAAgB;IACxB,QAAQ,EAAE,KAAc;CACzB,CAAC;AAEmB,sCAAa"}
|
|
@@ -3,12 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getAuthorizationUrl = void 0;
|
|
4
4
|
const workos_js_1 = require("./workos.js");
|
|
5
5
|
const env_variables_js_1 = require("./env-variables.js");
|
|
6
|
-
async function getAuthorizationUrl(
|
|
6
|
+
async function getAuthorizationUrl(options = {}) {
|
|
7
|
+
const { returnPathname, screenHint } = options;
|
|
7
8
|
return workos_js_1.workos.userManagement.getAuthorizationUrl({
|
|
8
9
|
provider: 'authkit',
|
|
9
10
|
clientId: env_variables_js_1.WORKOS_CLIENT_ID,
|
|
10
11
|
redirectUri: env_variables_js_1.WORKOS_REDIRECT_URI,
|
|
11
12
|
state: returnPathname ? btoa(JSON.stringify({ returnPathname })) : undefined,
|
|
13
|
+
screenHint,
|
|
12
14
|
});
|
|
13
15
|
}
|
|
14
16
|
exports.getAuthorizationUrl = getAuthorizationUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-authorization-url.js","sourceRoot":"","sources":["../../src/get-authorization-url.ts"],"names":[],"mappings":";;;AAAA,2CAAqC;AACrC,yDAA2E;
|
|
1
|
+
{"version":3,"file":"get-authorization-url.js","sourceRoot":"","sources":["../../src/get-authorization-url.ts"],"names":[],"mappings":";;;AAAA,2CAAqC;AACrC,yDAA2E;AAG3E,KAAK,UAAU,mBAAmB,CAAC,UAA6B,EAAE;IAChE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/C,OAAO,kBAAM,CAAC,cAAc,CAAC,mBAAmB,CAAC;QAC/C,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,mCAAgB;QAC1B,WAAW,EAAE,sCAAmB;QAChC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC5E,UAAU;KACX,CAAC,CAAC;AACL,CAAC;AAEQ,kDAAmB"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { handleAuth } from './authkit-callback-route.js';
|
|
2
2
|
import { authkitMiddleware } from './middleware.js';
|
|
3
3
|
import { getUser } from './session.js';
|
|
4
|
-
import { getSignInUrl, signOut } from './auth.js';
|
|
4
|
+
import { getSignInUrl, getSignUpUrl, signOut } from './auth.js';
|
|
5
5
|
import { Impersonation } from './impersonation.js';
|
|
6
|
-
export { handleAuth, authkitMiddleware, getSignInUrl, getUser, signOut, Impersonation, };
|
|
6
|
+
export { handleAuth, authkitMiddleware, getSignInUrl, getSignUpUrl, getUser, signOut, Impersonation, };
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Impersonation = exports.signOut = exports.getUser = exports.getSignInUrl = exports.authkitMiddleware = exports.handleAuth = void 0;
|
|
3
|
+
exports.Impersonation = exports.signOut = exports.getUser = exports.getSignUpUrl = exports.getSignInUrl = exports.authkitMiddleware = exports.handleAuth = void 0;
|
|
4
4
|
const authkit_callback_route_js_1 = require("./authkit-callback-route.js");
|
|
5
5
|
Object.defineProperty(exports, "handleAuth", { enumerable: true, get: function () { return authkit_callback_route_js_1.handleAuth; } });
|
|
6
6
|
const middleware_js_1 = require("./middleware.js");
|
|
@@ -9,6 +9,7 @@ const session_js_1 = require("./session.js");
|
|
|
9
9
|
Object.defineProperty(exports, "getUser", { enumerable: true, get: function () { return session_js_1.getUser; } });
|
|
10
10
|
const auth_js_1 = require("./auth.js");
|
|
11
11
|
Object.defineProperty(exports, "getSignInUrl", { enumerable: true, get: function () { return auth_js_1.getSignInUrl; } });
|
|
12
|
+
Object.defineProperty(exports, "getSignUpUrl", { enumerable: true, get: function () { return auth_js_1.getSignUpUrl; } });
|
|
12
13
|
Object.defineProperty(exports, "signOut", { enumerable: true, get: function () { return auth_js_1.signOut; } });
|
|
13
14
|
const impersonation_js_1 = require("./impersonation.js");
|
|
14
15
|
Object.defineProperty(exports, "Impersonation", { enumerable: true, get: function () { return impersonation_js_1.Impersonation; } });
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,2EAAyD;AAOvD,2FAPO,sCAAU,OAOP;AANZ,mDAAoD;AAQlD,kGARO,iCAAiB,OAQP;AAPnB,6CAAuC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,2EAAyD;AAOvD,2FAPO,sCAAU,OAOP;AANZ,mDAAoD;AAQlD,kGARO,iCAAiB,OAQP;AAPnB,6CAAuC;AAWrC,wFAXO,oBAAO,OAWP;AAVT,uCAAgE;AAQ9D,6FARO,sBAAY,OAQP;AACZ,6FATqB,sBAAY,OASrB;AAEZ,wFAXmC,iBAAO,OAWnC;AAVT,yDAAmD;AAYjD,8FAZO,gCAAa,OAYP"}
|
package/dist/cjs/interfaces.d.ts
CHANGED
|
@@ -31,3 +31,15 @@ export interface AccessToken {
|
|
|
31
31
|
org_id?: string;
|
|
32
32
|
role?: string;
|
|
33
33
|
}
|
|
34
|
+
export interface GetAuthURLOptions {
|
|
35
|
+
screenHint?: 'sign-up' | 'sign-in';
|
|
36
|
+
returnPathname?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface AuthkitMiddlewareAuth {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
unauthenticatedPaths: string[];
|
|
41
|
+
}
|
|
42
|
+
export interface AuthkitMiddlewareOptions {
|
|
43
|
+
debug?: boolean;
|
|
44
|
+
middlewareAuth?: AuthkitMiddlewareAuth;
|
|
45
|
+
}
|
package/dist/cjs/middleware.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
import { NextMiddleware } from 'next/server';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
export declare function authkitMiddleware({ debug }?: AuthkitMiddlewareOptions): NextMiddleware;
|
|
6
|
-
export {};
|
|
2
|
+
import { AuthkitMiddlewareOptions } from './interfaces.js';
|
|
3
|
+
export declare function authkitMiddleware({ debug, middlewareAuth, }?: AuthkitMiddlewareOptions): NextMiddleware;
|
package/dist/cjs/middleware.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.authkitMiddleware = void 0;
|
|
4
4
|
const session_js_1 = require("./session.js");
|
|
5
|
-
function authkitMiddleware({ debug = false } = {}) {
|
|
5
|
+
function authkitMiddleware({ debug = false, middlewareAuth = { enabled: false, unauthenticatedPaths: [] }, } = {}) {
|
|
6
6
|
return function (request) {
|
|
7
|
-
return (0, session_js_1.updateSession)(request, debug);
|
|
7
|
+
return (0, session_js_1.updateSession)(request, debug, middlewareAuth);
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
10
|
exports.authkitMiddleware = authkitMiddleware;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":";;;AACA,6CAA6C;
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":";;;AACA,6CAA6C;AAG7C,SAAgB,iBAAiB,CAAC,EAChC,KAAK,GAAG,KAAK,EACb,cAAc,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,EAAE,MACjC,EAAE;IAC9B,OAAO,UAAU,OAAO;QACtB,OAAO,IAAA,0BAAa,EAAC,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC;AAPD,8CAOC"}
|
package/dist/cjs/session.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
import { NoUserInfo, Session, UserInfo } from './interfaces.js';
|
|
2
|
+
import { AuthkitMiddlewareAuth, NoUserInfo, Session, UserInfo } from './interfaces.js';
|
|
3
3
|
declare function encryptSession(session: Session): Promise<string>;
|
|
4
|
-
declare function updateSession(request: NextRequest, debug: boolean): Promise<NextResponse<unknown>>;
|
|
4
|
+
declare function updateSession(request: NextRequest, debug: boolean, middlewareAuth: AuthkitMiddlewareAuth): Promise<NextResponse<unknown>>;
|
|
5
5
|
declare function getUser(options?: {
|
|
6
6
|
ensureSignedIn: false;
|
|
7
7
|
}): Promise<UserInfo | NoUserInfo>;
|
package/dist/cjs/session.js
CHANGED
|
@@ -10,6 +10,7 @@ const cookie_js_1 = require("./cookie.js");
|
|
|
10
10
|
const workos_js_1 = require("./workos.js");
|
|
11
11
|
const env_variables_js_1 = require("./env-variables.js");
|
|
12
12
|
const get_authorization_url_js_1 = require("./get-authorization-url.js");
|
|
13
|
+
const path_to_regexp_1 = require("path-to-regexp");
|
|
13
14
|
const sessionHeaderName = 'x-workos-session';
|
|
14
15
|
const middlewareHeaderName = 'x-workos-middleware';
|
|
15
16
|
const JWKS = (0, jose_1.createRemoteJWKSet)(new URL(workos_js_1.workos.userManagement.getJwksUrl(env_variables_js_1.WORKOS_CLIENT_ID)));
|
|
@@ -17,7 +18,7 @@ async function encryptSession(session) {
|
|
|
17
18
|
return (0, iron_session_1.sealData)(session, { password: env_variables_js_1.WORKOS_COOKIE_PASSWORD });
|
|
18
19
|
}
|
|
19
20
|
exports.encryptSession = encryptSession;
|
|
20
|
-
async function updateSession(request, debug) {
|
|
21
|
+
async function updateSession(request, debug, middlewareAuth) {
|
|
21
22
|
const session = await getSessionFromCookie();
|
|
22
23
|
const newRequestHeaders = new Headers(request.headers);
|
|
23
24
|
// We store the current request url in a custom header, so we can always have access to it
|
|
@@ -27,6 +28,16 @@ async function updateSession(request, debug) {
|
|
|
27
28
|
// Record that the request was routed through the middleware so we can check later for DX purposes
|
|
28
29
|
newRequestHeaders.set(middlewareHeaderName, 'true');
|
|
29
30
|
newRequestHeaders.delete(sessionHeaderName);
|
|
31
|
+
const matchedPaths = middlewareAuth.unauthenticatedPaths.filter((pathGlob) => {
|
|
32
|
+
const pathRegex = getMiddlewareAuthPathRegex(pathGlob);
|
|
33
|
+
return pathRegex.exec(request.nextUrl.pathname);
|
|
34
|
+
});
|
|
35
|
+
// If the user is logged out and this path isn't on the allowlist for logged out paths, redirect to AuthKit.
|
|
36
|
+
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session) {
|
|
37
|
+
if (debug)
|
|
38
|
+
console.log('Unauthenticated user on protected route, redirecting to AuthKit');
|
|
39
|
+
return server_1.NextResponse.redirect(await (0, get_authorization_url_js_1.getAuthorizationUrl)({ returnPathname: new URL(request.url).pathname }));
|
|
40
|
+
}
|
|
30
41
|
// If no session, just continue
|
|
31
42
|
if (!session) {
|
|
32
43
|
return server_1.NextResponse.next({
|
|
@@ -78,6 +89,21 @@ async function updateSession(request, debug) {
|
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
exports.updateSession = updateSession;
|
|
92
|
+
function getMiddlewareAuthPathRegex(pathGlob) {
|
|
93
|
+
let regex;
|
|
94
|
+
try {
|
|
95
|
+
// Redirect URI is only used to construct the URL
|
|
96
|
+
const url = new URL(pathGlob, env_variables_js_1.WORKOS_REDIRECT_URI);
|
|
97
|
+
const path = `${url.pathname}${url.hash || ''}`;
|
|
98
|
+
const tokens = (0, path_to_regexp_1.parse)(path);
|
|
99
|
+
regex = (0, path_to_regexp_1.tokensToRegexp)(tokens).source;
|
|
100
|
+
return new RegExp(regex);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
104
|
+
throw new Error(`Error parsing routes for middleware auth. Reason: ${message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
81
107
|
async function getUser({ ensureSignedIn = false } = {}) {
|
|
82
108
|
const hasMiddleware = Boolean((0, headers_1.headers)().get(middlewareHeaderName));
|
|
83
109
|
if (!hasMiddleware) {
|
|
@@ -88,7 +114,7 @@ async function getUser({ ensureSignedIn = false } = {}) {
|
|
|
88
114
|
if (ensureSignedIn) {
|
|
89
115
|
const url = (0, headers_1.headers)().get('x-url');
|
|
90
116
|
const returnPathname = url ? new URL(url).pathname : undefined;
|
|
91
|
-
(0, navigation_1.redirect)(await (0, get_authorization_url_js_1.getAuthorizationUrl)(returnPathname));
|
|
117
|
+
(0, navigation_1.redirect)(await (0, get_authorization_url_js_1.getAuthorizationUrl)({ returnPathname }));
|
|
92
118
|
}
|
|
93
119
|
return { user: null };
|
|
94
120
|
}
|
package/dist/cjs/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":";;;AAAA,gDAA2C;AAC3C,0CAAgD;AAChD,wCAAwD;AACxD,+BAAgE;AAChE,+CAAoD;AACpD,2CAAwD;AACxD,2CAAqC;AACrC,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workos-inc/authkit-nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Authentication and session helpers for using WorkOS & AuthKit with Next.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "commonjs",
|
|
@@ -16,16 +16,15 @@
|
|
|
16
16
|
"clean": "rm -rf dist",
|
|
17
17
|
"prebuild": "npm run clean",
|
|
18
18
|
"build": "tsc --project tsconfig-cjs.json",
|
|
19
|
-
"preversion": "npm run build",
|
|
20
|
-
"postversion": "git push --follow-tags",
|
|
21
19
|
"prepublishOnly": "npm run lint",
|
|
22
20
|
"lint": "eslint \"src/**/*.ts*\"",
|
|
23
21
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
24
22
|
},
|
|
25
23
|
"dependencies": {
|
|
26
|
-
"@workos-inc/node": "^6.
|
|
24
|
+
"@workos-inc/node": "^6.8.0",
|
|
27
25
|
"iron-session": "^8.0.1",
|
|
28
|
-
"jose": "^5.2.3"
|
|
26
|
+
"jose": "^5.2.3",
|
|
27
|
+
"path-to-regexp": "^6.2.2"
|
|
29
28
|
},
|
|
30
29
|
"peerDependencies": {
|
|
31
30
|
"next": "^13.5.4 || ^14.0.3",
|
package/src/auth.ts
CHANGED
|
@@ -4,7 +4,11 @@ import { cookieName } from './cookie.js';
|
|
|
4
4
|
import { terminateSession } from './session.js';
|
|
5
5
|
|
|
6
6
|
async function getSignInUrl() {
|
|
7
|
-
return getAuthorizationUrl();
|
|
7
|
+
return getAuthorizationUrl({ screenHint: 'sign-in' });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function getSignUpUrl() {
|
|
11
|
+
return getAuthorizationUrl({ screenHint: 'sign-up' });
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
async function signOut() {
|
|
@@ -12,4 +16,4 @@ async function signOut() {
|
|
|
12
16
|
await terminateSession();
|
|
13
17
|
}
|
|
14
18
|
|
|
15
|
-
export { getSignInUrl, signOut };
|
|
19
|
+
export { getSignInUrl, getSignUpUrl, signOut };
|
package/src/cookie.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { WORKOS_REDIRECT_URI } from './env-variables.js';
|
|
2
|
+
|
|
3
|
+
const redirectUrl = new URL(WORKOS_REDIRECT_URI);
|
|
4
|
+
const isSecureProtocol = redirectUrl.protocol === 'https:';
|
|
5
|
+
|
|
1
6
|
const cookieName = 'wos-session';
|
|
2
7
|
const cookieOptions = {
|
|
3
8
|
path: '/',
|
|
4
9
|
httpOnly: true,
|
|
5
|
-
secure:
|
|
10
|
+
secure: isSecureProtocol,
|
|
6
11
|
sameSite: 'lax' as const,
|
|
7
12
|
};
|
|
8
13
|
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { workos } from './workos.js';
|
|
2
2
|
import { WORKOS_CLIENT_ID, WORKOS_REDIRECT_URI } from './env-variables.js';
|
|
3
|
+
import { GetAuthURLOptions } from './interfaces.js';
|
|
4
|
+
|
|
5
|
+
async function getAuthorizationUrl(options: GetAuthURLOptions = {}) {
|
|
6
|
+
const { returnPathname, screenHint } = options;
|
|
3
7
|
|
|
4
|
-
async function getAuthorizationUrl(returnPathname?: string) {
|
|
5
8
|
return workos.userManagement.getAuthorizationUrl({
|
|
6
9
|
provider: 'authkit',
|
|
7
10
|
clientId: WORKOS_CLIENT_ID,
|
|
8
11
|
redirectUri: WORKOS_REDIRECT_URI,
|
|
9
12
|
state: returnPathname ? btoa(JSON.stringify({ returnPathname })) : undefined,
|
|
13
|
+
screenHint,
|
|
10
14
|
});
|
|
11
15
|
}
|
|
12
16
|
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { handleAuth } from './authkit-callback-route.js';
|
|
2
2
|
import { authkitMiddleware } from './middleware.js';
|
|
3
3
|
import { getUser } from './session.js';
|
|
4
|
-
import { getSignInUrl, signOut } from './auth.js';
|
|
4
|
+
import { getSignInUrl, getSignUpUrl, signOut } from './auth.js';
|
|
5
5
|
import { Impersonation } from './impersonation.js';
|
|
6
6
|
|
|
7
7
|
export {
|
|
@@ -10,6 +10,7 @@ export {
|
|
|
10
10
|
authkitMiddleware,
|
|
11
11
|
//
|
|
12
12
|
getSignInUrl,
|
|
13
|
+
getSignUpUrl,
|
|
13
14
|
getUser,
|
|
14
15
|
signOut,
|
|
15
16
|
//
|
package/src/interfaces.ts
CHANGED
|
@@ -35,3 +35,18 @@ export interface AccessToken {
|
|
|
35
35
|
org_id?: string;
|
|
36
36
|
role?: string;
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
export interface GetAuthURLOptions {
|
|
40
|
+
screenHint?: 'sign-up' | 'sign-in';
|
|
41
|
+
returnPathname?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface AuthkitMiddlewareAuth {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
unauthenticatedPaths: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface AuthkitMiddlewareOptions {
|
|
50
|
+
debug?: boolean;
|
|
51
|
+
middlewareAuth?: AuthkitMiddlewareAuth;
|
|
52
|
+
}
|
package/src/middleware.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { NextMiddleware } from 'next/server';
|
|
2
2
|
import { updateSession } from './session.js';
|
|
3
|
+
import { AuthkitMiddlewareOptions } from './interfaces.js';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
debug
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function authkitMiddleware({ debug = false }: AuthkitMiddlewareOptions = {}): NextMiddleware {
|
|
5
|
+
export function authkitMiddleware({
|
|
6
|
+
debug = false,
|
|
7
|
+
middlewareAuth = { enabled: false, unauthenticatedPaths: [] },
|
|
8
|
+
}: AuthkitMiddlewareOptions = {}): NextMiddleware {
|
|
9
9
|
return function (request) {
|
|
10
|
-
return updateSession(request, debug);
|
|
10
|
+
return updateSession(request, debug, middlewareAuth);
|
|
11
11
|
};
|
|
12
12
|
}
|
package/src/session.ts
CHANGED
|
@@ -5,9 +5,11 @@ import { jwtVerify, createRemoteJWKSet, decodeJwt } from 'jose';
|
|
|
5
5
|
import { sealData, unsealData } from 'iron-session';
|
|
6
6
|
import { cookieName, cookieOptions } from './cookie.js';
|
|
7
7
|
import { workos } from './workos.js';
|
|
8
|
-
import { WORKOS_CLIENT_ID, WORKOS_COOKIE_PASSWORD } from './env-variables.js';
|
|
8
|
+
import { WORKOS_CLIENT_ID, WORKOS_COOKIE_PASSWORD, WORKOS_REDIRECT_URI } from './env-variables.js';
|
|
9
9
|
import { getAuthorizationUrl } from './get-authorization-url.js';
|
|
10
|
-
import { AccessToken, NoUserInfo, Session, UserInfo } from './interfaces.js';
|
|
10
|
+
import { AccessToken, AuthkitMiddlewareAuth, NoUserInfo, Session, UserInfo } from './interfaces.js';
|
|
11
|
+
|
|
12
|
+
import { parse, tokensToRegexp } from 'path-to-regexp';
|
|
11
13
|
|
|
12
14
|
const sessionHeaderName = 'x-workos-session';
|
|
13
15
|
const middlewareHeaderName = 'x-workos-middleware';
|
|
@@ -18,7 +20,7 @@ async function encryptSession(session: Session) {
|
|
|
18
20
|
return sealData(session, { password: WORKOS_COOKIE_PASSWORD });
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
async function updateSession(request: NextRequest, debug: boolean) {
|
|
23
|
+
async function updateSession(request: NextRequest, debug: boolean, middlewareAuth: AuthkitMiddlewareAuth) {
|
|
22
24
|
const session = await getSessionFromCookie();
|
|
23
25
|
const newRequestHeaders = new Headers(request.headers);
|
|
24
26
|
|
|
@@ -32,6 +34,18 @@ async function updateSession(request: NextRequest, debug: boolean) {
|
|
|
32
34
|
|
|
33
35
|
newRequestHeaders.delete(sessionHeaderName);
|
|
34
36
|
|
|
37
|
+
const matchedPaths: string[] = middlewareAuth.unauthenticatedPaths.filter((pathGlob) => {
|
|
38
|
+
const pathRegex = getMiddlewareAuthPathRegex(pathGlob);
|
|
39
|
+
|
|
40
|
+
return pathRegex.exec(request.nextUrl.pathname);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// If the user is logged out and this path isn't on the allowlist for logged out paths, redirect to AuthKit.
|
|
44
|
+
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session) {
|
|
45
|
+
if (debug) console.log('Unauthenticated user on protected route, redirecting to AuthKit');
|
|
46
|
+
return NextResponse.redirect(await getAuthorizationUrl({ returnPathname: new URL(request.url).pathname }));
|
|
47
|
+
}
|
|
48
|
+
|
|
35
49
|
// If no session, just continue
|
|
36
50
|
if (!session) {
|
|
37
51
|
return NextResponse.next({
|
|
@@ -87,6 +101,25 @@ async function updateSession(request: NextRequest, debug: boolean) {
|
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
|
|
104
|
+
function getMiddlewareAuthPathRegex(pathGlob: string) {
|
|
105
|
+
let regex: string;
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// Redirect URI is only used to construct the URL
|
|
109
|
+
const url = new URL(pathGlob, WORKOS_REDIRECT_URI);
|
|
110
|
+
const path = `${url.pathname!}${url.hash || ''}`;
|
|
111
|
+
|
|
112
|
+
const tokens = parse(path);
|
|
113
|
+
regex = tokensToRegexp(tokens).source;
|
|
114
|
+
|
|
115
|
+
return new RegExp(regex);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
118
|
+
|
|
119
|
+
throw new Error(`Error parsing routes for middleware auth. Reason: ${message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
90
123
|
async function getUser(options?: { ensureSignedIn: false }): Promise<UserInfo | NoUserInfo>;
|
|
91
124
|
|
|
92
125
|
async function getUser(options: { ensureSignedIn: true }): Promise<UserInfo>;
|
|
@@ -105,7 +138,7 @@ async function getUser({ ensureSignedIn = false } = {}) {
|
|
|
105
138
|
if (ensureSignedIn) {
|
|
106
139
|
const url = headers().get('x-url');
|
|
107
140
|
const returnPathname = url ? new URL(url).pathname : undefined;
|
|
108
|
-
redirect(await getAuthorizationUrl(returnPathname));
|
|
141
|
+
redirect(await getAuthorizationUrl({ returnPathname }));
|
|
109
142
|
}
|
|
110
143
|
return { user: null };
|
|
111
144
|
}
|