@workos-inc/authkit-nextjs 2.10.0 → 2.11.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 CHANGED
@@ -141,9 +141,14 @@ The `onSuccess` callback receives the following data:
141
141
 
142
142
  **Note**: `authenticationMethod` is only provided during the initial authentication callback. It will not be available in subsequent requests or session refreshes.
143
143
 
144
- ### Middleware
144
+ ### Middleware / Proxy
145
145
 
146
- This library relies on [Next.js middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware) to provide session management for routes. Put the following in your `middleware.ts` file in the root of your project:
146
+ This library relies on Next.js middleware to provide session management for routes.
147
+
148
+ **For Next.js ≤15:** Create a `middleware.ts` file in the root of your project.
149
+ **For Next.js 16+:** Create a `proxy.ts` file in the root of your project.
150
+
151
+ The code remains the same; only the filename changes:
147
152
 
148
153
  ```ts
149
154
  import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
@@ -571,6 +576,8 @@ Eager auth makes tokens briefly accessible via JavaScript (30-second window) to
571
576
 
572
577
  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.
573
578
 
579
+ > **Note:** For Next.js 16+, name your file `proxy.ts` and the function `proxy` instead of `middleware`.
580
+
574
581
  ```ts
575
582
  export default async function middleware(request: NextRequest) {
576
583
  // Perform logic before or after AuthKit
@@ -689,6 +696,25 @@ export default authkitMiddleware({
689
696
  });
690
697
  ```
691
698
 
699
+ ### Validate an API key
700
+
701
+ Use the `validateApiKey` function in your application's public API endpoints to parse a [Bearer Authentication](https://swagger.io/docs/specification/v3_0/authentication/bearer-authentication/) header and validate the [API key](https://workos.com/docs/authkit/api-keys) with WorkOS.
702
+
703
+ ```ts
704
+ import { NextResponse } from 'next/server'
705
+ import { validateApiKey } from '@workos-inc/authkit-nextjs'
706
+
707
+ export async function GET() {
708
+ const { apiKey } = await validateApiKey()
709
+
710
+ if (!apiKey) {
711
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
712
+ }
713
+
714
+ return NextResponse.json({ success: true })
715
+ }
716
+ ```
717
+
692
718
  ### Advanced: Direct access to the WorkOS client
693
719
 
694
720
  For advanced use cases or functionality not covered by the helper methods, you can access the underlying WorkOS client directly:
package/dist/esm/auth.js CHANGED
@@ -8,6 +8,14 @@ import { getCookieOptions } from './cookie.js';
8
8
  import { getAuthorizationUrl } from './get-authorization-url.js';
9
9
  import { getSessionFromCookie, refreshSession, withAuth } from './session.js';
10
10
  import { getWorkOS } from './workos.js';
11
+ /**
12
+ * A wrapper around revalidateTag to provide compatibility with previous versions.
13
+ * @param tag The tag to revalidate.
14
+ */
15
+ function revalidateTagCompat(tag) {
16
+ const fn = revalidateTag;
17
+ return fn(tag, 'max');
18
+ }
11
19
  export async function getSignInUrl({ organizationId, loginHint, redirectUri, prompt, state, } = {}) {
12
20
  return getAuthorizationUrl({ organizationId, screenHint: 'sign-in', loginHint, redirectUri, prompt, state });
13
21
  }
@@ -82,7 +90,7 @@ export async function switchToOrganization(organizationId, options = {}) {
82
90
  break;
83
91
  case 'tag':
84
92
  for (const tag of revalidationTags) {
85
- revalidateTag(tag);
93
+ revalidateTagCompat(tag);
86
94
  }
87
95
  break;
88
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}
@@ -4,15 +4,17 @@ import { Button } from './button.js';
4
4
  import { MinMaxButton } from './min-max-button.js';
5
5
  import { getOrganizationAction, handleSignOutAction } from '../actions.js';
6
6
  import { useAuth } from './authkit-provider.js';
7
- export function Impersonation({ side = 'bottom', ...props }) {
8
- const { user, impersonator, organizationId, loading } = useAuth();
7
+ export function Impersonation({ side = 'bottom', returnTo, ...props }) {
8
+ const { user, impersonator, organizationId } = useAuth();
9
9
  const [organization, setOrganization] = React.useState(null);
10
10
  React.useEffect(() => {
11
- if (!organizationId)
11
+ if (!organizationId || !impersonator || !user)
12
+ return;
13
+ if (organization && organization.id === organizationId)
12
14
  return;
13
15
  getOrganizationAction(organizationId).then(setOrganization);
14
- }, [organizationId]);
15
- if (loading || !impersonator || !user)
16
+ }, [organizationId, impersonator, user]);
17
+ if (!impersonator || !user)
16
18
  return null;
17
19
  return (React.createElement("div", { ...props, "data-workos-impersonation-root": "", style: {
18
20
  'position': 'fixed',
@@ -53,7 +55,7 @@ export function Impersonation({ side = 'bottom', ...props }) {
53
55
  } },
54
56
  React.createElement("form", { onSubmit: async (event) => {
55
57
  event.preventDefault();
56
- await handleSignOutAction();
58
+ await handleSignOutAction({ returnTo });
57
59
  }, style: {
58
60
  display: 'flex',
59
61
  alignItems: 'baseline',
@@ -1 +1 @@
1
- {"version":3,"file":"impersonation.js","sourceRoot":"","sources":["../../../src/components/impersonation.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAMhD,MAAM,UAAU,aAAa,CAAC,EAAE,IAAI,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAsB;IAC7E,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAElE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAsB,IAAI,CAAC,CAAC;IAElF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,cAAc;YAAE,OAAO;QAC5B,qBAAqB,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,IAAI,OAAO,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEnD,OAAO,CACL,gCACM,KAAK,oCACsB,EAAE,EACjC,KAAK,EAAE;YACL,UAAU,EAAE,OAAO;YACnB,OAAO,EAAE,CAAC;YACV,eAAe,EAAE,MAAM;YACvB,QAAQ,EAAE,IAAI;YAEd,2DAA2D;YAC3D,gBAAgB,EAAE,GAAG;YACrB,QAAQ,EAAE,4DAA4D;YACtE,UAAU,EAAE,uDAAuD;YACnE,QAAQ,EAAE,4CAA4C;YACtD,SAAS,EAAE,mDAAmD;YAC9D,SAAS,EAAE,+CAA+C;YAE1D,GAAG,KAAK,CAAC,KAAK;SACf;QAED,6BACE,KAAK,EAAE;gBACL,iBAAiB,EAAE,yFAAyF;gBAC5G,UAAU,EAAE,UAAU;gBACtB,OAAO,EAAE,iCAAiC;gBAC1C,cAAc,EAAE,gCAAgC;gBAChD,WAAW,EAAE;;;MAGjB;gBACI,YAAY,EAAE,yCAAyC;aACxD,GACD;QAEF,6BACE,KAAK,EAAE;gBACL,OAAO,EAAE,MAAM;gBACf,cAAc,EAAE,QAAQ;gBAExB,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,CAAC;gBACR,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;gBAC7C,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAEnD,UAAU,EACR,wIAAwI;gBAC1I,QAAQ,EAAE,gCAAgC;gBAC1C,UAAU,EAAE,KAAK;aAClB;YAED,8BACE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;oBACxB,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,MAAM,mBAAmB,EAAE,CAAC;gBAC9B,CAAC,EACD,KAAK,EAAE;oBACL,OAAO,EAAE,MAAM;oBACf,UAAU,EAAE,UAAU;oBACtB,WAAW,EAAE,aAAa;oBAC1B,YAAY,EAAE,aAAa;oBAE3B,QAAQ,EAAE,UAAU;oBACpB,UAAU,EAAE,uBAAuB;oBACnC,WAAW,EAAE,uBAAuB;oBAEpC,aAAa,EAAE,MAAM;oBACrB,eAAe,EAAE,eAAe;oBAChC,WAAW,EAAE,OAAO;oBACpB,WAAW,EAAE,cAAc;oBAC3B,eAAe,EAAE,cAAc;oBAC/B,gBAAgB,EAAE,cAAc;oBAEhC,UAAU,EAAE,yCAAyC;oBACrD,SAAS,EAAE,iEAAiE;oBAC5E,OAAO,EAAE,+BAA+B;oBACxC,MAAM,EAAE,+BAA+B;oBAEvC,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI;wBACpB,UAAU,EAAE,CAAC;wBACb,aAAa,EAAE,aAAa;wBAC5B,cAAc,EAAE,CAAC;wBACjB,iBAAiB,EAAE,cAAc;wBACjC,sBAAsB,EAAE,aAAa;wBACrC,uBAAuB,EAAE,aAAa;qBACvC,CAAC;oBAEF,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI;wBACvB,UAAU,EAAE,aAAa;wBACzB,aAAa,EAAE,CAAC;wBAChB,cAAc,EAAE,cAAc;wBAC9B,iBAAiB,EAAE,CAAC;wBACpB,mBAAmB,EAAE,aAAa;wBAClC,oBAAoB,EAAE,aAAa;qBACpC,CAAC;iBACH;gBAED,2BAAG,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE;;oBACxE,+BAAI,IAAI,CAAC,KAAK,CAAK;oBAAC,GAAG;oBAC5C,YAAY,KAAK,IAAI,IAAI,CACxB;;wBACa,+BAAI,YAAY,CAAC,IAAI,CAAK;wCACpC,CACJ,CACC;gBACJ,oBAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE,WAAW,EAAE,aAAa,EAAE,WAEvF;gBACT,oBAAC,YAAY,IAAC,cAAc,EAAC,GAAG,IAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAgB,CACvE;YAEP,6BACE,KAAK,EAAE;oBACL,OAAO,EAAE,aAAa;oBAEtB,QAAQ,EAAE,OAAO;oBACjB,KAAK,EAAE,aAAa;oBAEpB,aAAa,EAAE,MAAM;oBACrB,eAAe,EAAE,eAAe;oBAChC,MAAM,EAAE,iCAAiC;oBACzC,YAAY,EAAE,aAAa;oBAE3B,UAAU,EAAE,yCAAyC;oBACrD,SAAS,EAAE,gEAAgE;oBAC3E,OAAO,EAAE,qBAAqB;oBAC9B,MAAM,EAAE,qBAAqB;oBAE7B,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;oBAC7C,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;iBACpD;gBAED,oBAAC,YAAY,IAAC,cAAc,EAAC,GAAG,IAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAgB,CACxE,CACF,CACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"impersonation.js","sourceRoot":"","sources":["../../../src/components/impersonation.tsx"],"names":[],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -2,7 +2,8 @@ import { getSignInUrl, getSignUpUrl, signOut, switchToOrganization } from './aut
2
2
  import { handleAuth } from './authkit-callback-route.js';
3
3
  import { authkit, authkitMiddleware } from './middleware.js';
4
4
  import { getTokenClaims, refreshSession, saveSession, withAuth } from './session.js';
5
+ import { validateApiKey } from './validate-api-key.js';
5
6
  import { getWorkOS } from './workos.js';
6
7
  export * from './interfaces.js';
7
- export { authkit, authkitMiddleware, getSignInUrl, getSignUpUrl, getWorkOS, handleAuth, refreshSession, saveSession, signOut, switchToOrganization, withAuth, getTokenClaims, };
8
+ export { authkit, authkitMiddleware, getSignInUrl, getSignUpUrl, getWorkOS, handleAuth, refreshSession, saveSession, signOut, switchToOrganization, withAuth, getTokenClaims, validateApiKey, };
8
9
  //# sourceMappingURL=index.js.map
@@ -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,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,QAAQ,EACR,cAAc,GACf,CAAC"}
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,QAAQ,EACR,cAAc,EACd,cAAc,GACf,CAAC"}
@@ -37,6 +37,7 @@ export async function generateSession(overrides = {}) {
37
37
  lastSignInAt: '2024-01-01T00:00:00Z',
38
38
  externalId: null,
39
39
  metadata: {},
40
+ locale: null,
40
41
  ...overrides,
41
42
  };
42
43
  const accessToken = await generateTestToken({
@@ -1 +1 @@
1
- {"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/test-helpers.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,KAAK;IACnE,MAAM,cAAc,GAAG;QACrB,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,WAAW,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;QAC7C,YAAY,EAAE,CAAC,YAAY,CAAC;QAC5B,aAAa,EAAE,CAAC,4BAA4B,CAAC;KAC9C,CAAC;IAEF,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;IAExD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAgC,CAAC,CAAC;IAEtF,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;SAC3C,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,WAAW,EAAE;SACb,SAAS,CAAC,oBAAoB,CAAC;SAC/B,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;SACxC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAA2B,EAAE;IACjE,MAAM,QAAQ,GAAG;QACf,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,kBAAkB;QACzB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,SAAS,EAAE,MAAM;QACjB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,sBAAsB;QACjC,SAAS,EAAE,sBAAsB;QACjC,YAAY,EAAE,sBAAsB;QACpC,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,EAAE;QACZ,GAAG,SAAS;KACE,CAAC;IAEjB,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC;QAC1C,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CACrC;QACE,WAAW;QACX,YAAY,EAAE,mBAAmB;QACjC,IAAI,EAAE,QAAQ;KACf,EACD;QACE,QAAQ,EAAE,sBAAgC;KAC3C,CACF,CAAC;IAEF,MAAM,UAAU,GAAG,kBAAkB,IAAI,aAAa,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/test-helpers.ts"],"names":[],"mappings":"AAAA,uBAAuB;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,KAAK;IACnE,MAAM,cAAc,GAAG;QACrB,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,WAAW,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;QAC7C,YAAY,EAAE,CAAC,YAAY,CAAC;QAC5B,aAAa,EAAE,CAAC,4BAA4B,CAAC;KAC9C,CAAC;IAEF,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;IAExD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAgC,CAAC,CAAC;IAEtF,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;SAC3C,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,WAAW,EAAE;SACb,SAAS,CAAC,oBAAoB,CAAC;SAC/B,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;SACxC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAA2B,EAAE;IACjE,MAAM,QAAQ,GAAG;QACf,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,kBAAkB;QACzB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,SAAS,EAAE,MAAM;QACjB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,sBAAsB;QACjC,SAAS,EAAE,sBAAsB;QACjC,YAAY,EAAE,sBAAsB;QACpC,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,IAAI;QACZ,GAAG,SAAS;KACE,CAAC;IAEjB,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC;QAC1C,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CACrC;QACE,WAAW;QACX,YAAY,EAAE,mBAAmB;QACjC,IAAI,EAAE,QAAQ;KACf,EACD;QACE,QAAQ,EAAE,sBAAgC;KAC3C,CACF,CAAC;IAEF,MAAM,UAAU,GAAG,kBAAkB,IAAI,aAAa,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAChD,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  interface ImpersonationProps extends React.ComponentPropsWithoutRef<'div'> {
3
3
  side?: 'top' | 'bottom';
4
+ returnTo?: string;
4
5
  }
5
- export declare function Impersonation({ side, ...props }: ImpersonationProps): React.JSX.Element | null;
6
+ export declare function Impersonation({ side, returnTo, ...props }: ImpersonationProps): React.JSX.Element | null;
6
7
  export {};
@@ -2,6 +2,7 @@ import { getSignInUrl, getSignUpUrl, signOut, switchToOrganization } from './aut
2
2
  import { handleAuth } from './authkit-callback-route.js';
3
3
  import { authkit, authkitMiddleware } from './middleware.js';
4
4
  import { getTokenClaims, refreshSession, saveSession, withAuth } from './session.js';
5
+ import { validateApiKey } from './validate-api-key.js';
5
6
  import { getWorkOS } from './workos.js';
6
7
  export * from './interfaces.js';
7
- export { authkit, authkitMiddleware, getSignInUrl, getSignUpUrl, getWorkOS, handleAuth, refreshSession, saveSession, signOut, switchToOrganization, withAuth, getTokenClaims, };
8
+ export { authkit, authkitMiddleware, getSignInUrl, getSignUpUrl, getWorkOS, handleAuth, refreshSession, saveSession, signOut, switchToOrganization, withAuth, getTokenClaims, validateApiKey, };
@@ -0,0 +1 @@
1
+ export declare function validateApiKey(): Promise<import("@workos-inc/node/lib/api-keys/interfaces/validate-api-key.interface.js").ValidateApiKeyResponse>;
@@ -1,5 +1,5 @@
1
1
  import { WorkOS } from '@workos-inc/node';
2
- export declare const VERSION = "2.10.0";
2
+ export declare const VERSION = "2.11.0";
3
3
  /**
4
4
  * Create a WorkOS instance with the provided API key and options.
5
5
  * If an instance already exists, it returns the existing instance.
@@ -0,0 +1,17 @@
1
+ 'use server';
2
+ import { getWorkOS } from './workos.js';
3
+ import { headers } from 'next/headers';
4
+ export async function validateApiKey() {
5
+ var _a;
6
+ const headersList = await headers();
7
+ const authorizationHeader = headersList.get('authorization');
8
+ if (!authorizationHeader) {
9
+ return { apiKey: null };
10
+ }
11
+ const value = (_a = authorizationHeader.match(/Bearer\s+(.*)/i)) === null || _a === void 0 ? void 0 : _a[1];
12
+ if (!value) {
13
+ return { apiKey: null };
14
+ }
15
+ return getWorkOS().apiKeys.validateApiKey({ value });
16
+ }
17
+ //# sourceMappingURL=validate-api-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-api-key.js","sourceRoot":"","sources":["../../src/validate-api-key.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,cAAc;;IAClC,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IACpC,MAAM,mBAAmB,GAAG,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7D,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,KAAK,GAAG,MAAA,mBAAmB,CAAC,KAAK,CAAC,gBAAgB,CAAC,0CAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,SAAS,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AACvD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { WorkOS } from '@workos-inc/node';
2
2
  import { WORKOS_API_HOSTNAME, WORKOS_API_KEY, WORKOS_API_HTTPS, WORKOS_API_PORT } from './env-variables.js';
3
3
  import { lazy } from './utils.js';
4
- export const VERSION = '2.10.0';
4
+ export const VERSION = '2.11.0';
5
5
  const options = {
6
6
  apiHostname: WORKOS_API_HOSTNAME,
7
7
  https: WORKOS_API_HTTPS ? WORKOS_API_HTTPS === 'true' : true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workos-inc/authkit-nextjs",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "Authentication and session helpers for using WorkOS & AuthKit with Next.js",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -35,13 +35,13 @@
35
35
  "type-check": "tsc --project tsconfig.json --noEmit"
36
36
  },
37
37
  "dependencies": {
38
- "@workos-inc/node": "^7.67.0",
38
+ "@workos-inc/node": "^7.72.0",
39
39
  "iron-session": "^8.0.1",
40
40
  "jose": "^5.2.3",
41
41
  "path-to-regexp": "^6.2.2"
42
42
  },
43
43
  "peerDependencies": {
44
- "next": "^13.5.9 || ^14.2.26 || ^15.2.3",
44
+ "next": "^13.5.9 || ^14.2.26 || ^15.2.3 || ^16",
45
45
  "react": "^18.0 || ^19.0.0",
46
46
  "react-dom": "^18.0 || ^19.0.0"
47
47
  },
@@ -57,7 +57,7 @@
57
57
  "eslint-plugin-require-extensions": "^0.1.3",
58
58
  "jest": "^29.7.0",
59
59
  "jest-environment-jsdom": "^29.7.0",
60
- "next": "^15.0.1",
60
+ "next": "^16.0.1",
61
61
  "prettier": "^3.3.3",
62
62
  "ts-jest": "^29.2.5",
63
63
  "ts-node": "^10.9.2",
package/src/auth.ts CHANGED
@@ -10,6 +10,16 @@ import { getAuthorizationUrl } from './get-authorization-url.js';
10
10
  import type { AccessToken, SwitchToOrganizationOptions, UserInfo } from './interfaces.js';
11
11
  import { getSessionFromCookie, refreshSession, withAuth } from './session.js';
12
12
  import { getWorkOS } from './workos.js';
13
+
14
+ /**
15
+ * A wrapper around revalidateTag to provide compatibility with previous versions.
16
+ * @param tag The tag to revalidate.
17
+ */
18
+ function revalidateTagCompat(tag: string): void {
19
+ const fn = revalidateTag as (tag: string, profile: string) => void;
20
+ return fn(tag, 'max');
21
+ }
22
+
13
23
  export async function getSignInUrl({
14
24
  organizationId,
15
25
  loginHint,
@@ -111,7 +121,7 @@ export async function switchToOrganization(
111
121
  break;
112
122
  case 'tag':
113
123
  for (const tag of revalidationTags) {
114
- revalidateTag(tag);
124
+ revalidateTagCompat(tag);
115
125
  }
116
126
  break;
117
127
  }
@@ -36,6 +36,7 @@ describe('authkit-callback-route', () => {
36
36
  lastSignInAt: '2024-01-01T00:00:00Z',
37
37
  externalId: null,
38
38
  metadata: {},
39
+ locale: null,
39
40
  },
40
41
  oauthTokens: {
41
42
  accessToken: 'access123',
@@ -27,19 +27,6 @@ describe('Impersonation', () => {
27
27
  impersonator: null,
28
28
  user: { id: '123', email: 'user@example.com' },
29
29
  organizationId: null,
30
- loading: false,
31
- });
32
-
33
- const { container } = render(<Impersonation />);
34
- expect(container).toBeEmptyDOMElement();
35
- });
36
-
37
- it('should return null if loading', () => {
38
- (useAuth as jest.Mock).mockReturnValue({
39
- impersonator: { email: 'admin@example.com' },
40
- user: { id: '123', email: 'user@example.com' },
41
- organizationId: null,
42
- loading: true,
43
30
  });
44
31
 
45
32
  const { container } = render(<Impersonation />);
@@ -51,7 +38,6 @@ describe('Impersonation', () => {
51
38
  impersonator: { email: 'admin@example.com' },
52
39
  user: { id: '123', email: 'user@example.com' },
53
40
  organizationId: null,
54
- loading: false,
55
41
  });
56
42
 
57
43
  const { container } = render(<Impersonation />);
@@ -63,7 +49,6 @@ describe('Impersonation', () => {
63
49
  impersonator: { email: 'admin@example.com' },
64
50
  user: { id: '123', email: 'user@example.com' },
65
51
  organizationId: 'org_123',
66
- loading: false,
67
52
  });
68
53
 
69
54
  (getOrganizationAction as jest.Mock).mockResolvedValue({
@@ -83,7 +68,6 @@ describe('Impersonation', () => {
83
68
  impersonator: { email: 'admin@example.com' },
84
69
  user: { id: '123', email: 'user@example.com' },
85
70
  organizationId: null,
86
- loading: false,
87
71
  });
88
72
 
89
73
  const { container } = render(<Impersonation />);
@@ -96,7 +80,6 @@ describe('Impersonation', () => {
96
80
  impersonator: { email: 'admin@example.com' },
97
81
  user: { id: '123', email: 'user@example.com' },
98
82
  organizationId: null,
99
- loading: false,
100
83
  });
101
84
 
102
85
  const { container } = render(<Impersonation side="top" />);
@@ -109,7 +92,6 @@ describe('Impersonation', () => {
109
92
  impersonator: { email: 'admin@example.com' },
110
93
  user: { id: '123', email: 'user@example.com' },
111
94
  organizationId: null,
112
- loading: false,
113
95
  });
114
96
 
115
97
  const customStyle = { backgroundColor: 'red' };
@@ -123,12 +105,146 @@ describe('Impersonation', () => {
123
105
  impersonator: { email: 'admin@example.com' },
124
106
  user: { id: '123', email: 'user@example.com' },
125
107
  organizationId: null,
126
- loading: false,
127
108
  });
128
109
 
129
110
  render(<Impersonation />);
130
111
  const stopButton = await screen.findByText('Stop');
131
112
  stopButton.click();
132
- expect(handleSignOutAction).toHaveBeenCalled();
113
+ expect(handleSignOutAction).toHaveBeenCalledWith({});
114
+ });
115
+
116
+ it('should pass returnTo prop to handleSignOutAction when provided', async () => {
117
+ (useAuth as jest.Mock).mockReturnValue({
118
+ impersonator: { email: 'admin@example.com' },
119
+ user: { id: '123', email: 'user@example.com' },
120
+ organizationId: null,
121
+ loading: false,
122
+ });
123
+
124
+ const returnTo = '/dashboard';
125
+ render(<Impersonation returnTo={returnTo} />);
126
+ const stopButton = await screen.findByText('Stop');
127
+ stopButton.click();
128
+ expect(handleSignOutAction).toHaveBeenCalledWith({ returnTo });
129
+ });
130
+
131
+ it('should not call getOrganizationAction when organizationId is not provided', () => {
132
+ (useAuth as jest.Mock).mockReturnValue({
133
+ impersonator: { email: 'admin@example.com' },
134
+ user: { id: '123', email: 'user@example.com' },
135
+ organizationId: null,
136
+ });
137
+
138
+ render(<Impersonation />);
139
+ expect(getOrganizationAction).not.toHaveBeenCalled();
140
+ });
141
+
142
+ it('should not call getOrganizationAction when impersonator is not present', () => {
143
+ (useAuth as jest.Mock).mockReturnValue({
144
+ impersonator: null,
145
+ user: { id: '123', email: 'user@example.com' },
146
+ organizationId: 'org_123',
147
+ });
148
+
149
+ render(<Impersonation />);
150
+ expect(getOrganizationAction).not.toHaveBeenCalled();
151
+ });
152
+
153
+ it('should not call getOrganizationAction when user is not present', () => {
154
+ (useAuth as jest.Mock).mockReturnValue({
155
+ impersonator: { email: 'admin@example.com' },
156
+ user: null,
157
+ organizationId: 'org_123',
158
+ });
159
+
160
+ render(<Impersonation />);
161
+ expect(getOrganizationAction).not.toHaveBeenCalled();
162
+ });
163
+
164
+ it('should not call getOrganizationAction again when organization is already loaded with same ID', async () => {
165
+ const mockOrg = {
166
+ id: 'org_123',
167
+ name: 'Test Org',
168
+ };
169
+
170
+ (getOrganizationAction as jest.Mock).mockResolvedValue(mockOrg);
171
+
172
+ const { rerender } = await act(async () => {
173
+ (useAuth as jest.Mock).mockReturnValue({
174
+ impersonator: { email: 'admin@example.com' },
175
+ user: { id: '123', email: 'user@example.com' },
176
+ organizationId: 'org_123',
177
+ });
178
+
179
+ return render(<Impersonation />);
180
+ });
181
+
182
+ // Wait for the initial call to complete
183
+ await act(async () => {
184
+ await new Promise((resolve) => setTimeout(resolve, 0));
185
+ });
186
+
187
+ expect(getOrganizationAction).toHaveBeenCalledTimes(1);
188
+
189
+ // Rerender with the same organizationId
190
+ await act(async () => {
191
+ (useAuth as jest.Mock).mockReturnValue({
192
+ impersonator: { email: 'admin@example.com' },
193
+ user: { id: '123', email: 'user@example.com' },
194
+ organizationId: 'org_123',
195
+ });
196
+
197
+ rerender(<Impersonation />);
198
+ });
199
+
200
+ // Should still be called only once
201
+ expect(getOrganizationAction).toHaveBeenCalledTimes(1);
202
+ });
203
+
204
+ it('should call getOrganizationAction again when organizationId changes', async () => {
205
+ const mockOrg1 = {
206
+ id: 'org_123',
207
+ name: 'Test Org 1',
208
+ };
209
+
210
+ const mockOrg2 = {
211
+ id: 'org_456',
212
+ name: 'Test Org 2',
213
+ };
214
+
215
+ (getOrganizationAction as jest.Mock).mockResolvedValueOnce(mockOrg1).mockResolvedValueOnce(mockOrg2);
216
+
217
+ const { rerender } = await act(async () => {
218
+ (useAuth as jest.Mock).mockReturnValue({
219
+ impersonator: { email: 'admin@example.com' },
220
+ user: { id: '123', email: 'user@example.com' },
221
+ organizationId: 'org_123',
222
+ });
223
+
224
+ return render(<Impersonation />);
225
+ });
226
+
227
+ // Wait for the initial call to complete
228
+ await act(async () => {
229
+ await new Promise((resolve) => setTimeout(resolve, 0));
230
+ });
231
+
232
+ expect(getOrganizationAction).toHaveBeenCalledTimes(1);
233
+ expect(getOrganizationAction).toHaveBeenCalledWith('org_123');
234
+
235
+ // Rerender with a different organizationId
236
+ await act(async () => {
237
+ (useAuth as jest.Mock).mockReturnValue({
238
+ impersonator: { email: 'admin@example.com' },
239
+ user: { id: '123', email: 'user@example.com' },
240
+ organizationId: 'org_456',
241
+ });
242
+
243
+ rerender(<Impersonation />);
244
+ });
245
+
246
+ // Should be called again with the new ID
247
+ expect(getOrganizationAction).toHaveBeenCalledTimes(2);
248
+ expect(getOrganizationAction).toHaveBeenCalledWith('org_456');
133
249
  });
134
250
  });
@@ -9,19 +9,21 @@ import { useAuth } from './authkit-provider.js';
9
9
 
10
10
  interface ImpersonationProps extends React.ComponentPropsWithoutRef<'div'> {
11
11
  side?: 'top' | 'bottom';
12
+ returnTo?: string;
12
13
  }
13
14
 
14
- export function Impersonation({ side = 'bottom', ...props }: ImpersonationProps) {
15
- const { user, impersonator, organizationId, loading } = useAuth();
15
+ export function Impersonation({ side = 'bottom', returnTo, ...props }: ImpersonationProps) {
16
+ const { user, impersonator, organizationId } = useAuth();
16
17
 
17
18
  const [organization, setOrganization] = React.useState<Organization | null>(null);
18
19
 
19
20
  React.useEffect(() => {
20
- if (!organizationId) return;
21
+ if (!organizationId || !impersonator || !user) return;
22
+ if (organization && organization.id === organizationId) return;
21
23
  getOrganizationAction(organizationId).then(setOrganization);
22
- }, [organizationId]);
24
+ }, [organizationId, impersonator, user]);
23
25
 
24
- if (loading || !impersonator || !user) return null;
26
+ if (!impersonator || !user) return null;
25
27
 
26
28
  return (
27
29
  <div
@@ -78,7 +80,7 @@ export function Impersonation({ side = 'bottom', ...props }: ImpersonationProps)
78
80
  <form
79
81
  onSubmit={async (event) => {
80
82
  event.preventDefault();
81
- await handleSignOutAction();
83
+ await handleSignOutAction({ returnTo });
82
84
  }}
83
85
  style={{
84
86
  display: 'flex',
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ import { getSignInUrl, getSignUpUrl, signOut, switchToOrganization } from './aut
2
2
  import { handleAuth } from './authkit-callback-route.js';
3
3
  import { authkit, authkitMiddleware } from './middleware.js';
4
4
  import { getTokenClaims, refreshSession, saveSession, withAuth } from './session.js';
5
+ import { validateApiKey } from './validate-api-key.js';
5
6
  import { getWorkOS } from './workos.js';
6
7
 
7
8
  export * from './interfaces.js';
@@ -19,4 +20,5 @@ export {
19
20
  switchToOrganization,
20
21
  withAuth,
21
22
  getTokenClaims,
23
+ validateApiKey,
22
24
  };
@@ -45,6 +45,7 @@ export async function generateSession(overrides: Partial<User> = {}) {
45
45
  lastSignInAt: '2024-01-01T00:00:00Z',
46
46
  externalId: null,
47
47
  metadata: {},
48
+ locale: null,
48
49
  ...overrides,
49
50
  } satisfies User;
50
51
 
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect, beforeEach, jest } from '@jest/globals';
2
+
3
+ import { validateApiKey } from './validate-api-key.js';
4
+ import { getWorkOS } from './workos.js';
5
+
6
+ // These are mocked in jest.setup.ts
7
+ import { headers } from 'next/headers';
8
+
9
+ const workos = getWorkOS();
10
+
11
+ describe('validate-api-key.ts', () => {
12
+ beforeEach(async () => {
13
+ // Clear all mocks between tests
14
+ jest.clearAllMocks();
15
+
16
+ const nextHeaders = await headers();
17
+ // @ts-expect-error - _reset is part of the mock
18
+ nextHeaders._reset();
19
+ });
20
+
21
+ describe('validateApiKey', () => {
22
+ it('should return valid API key when Bearer token is present and valid', async () => {
23
+ const mockApiKeyResponse = {
24
+ apiKey: {
25
+ id: 'api_key_123',
26
+ object: 'api_key' as const,
27
+ name: 'Test API Key',
28
+ obfuscatedValue: 'sk_…7890',
29
+ createdAt: '2024-01-01T00:00:00Z',
30
+ updatedAt: '2024-01-01T00:00:00Z',
31
+ lastUsedAt: '2024-01-01T00:00:00Z',
32
+ permissions: [],
33
+ owner: { type: 'organization' as const, id: 'org_123' },
34
+ },
35
+ };
36
+
37
+ jest.spyOn(workos.apiKeys, 'validateApiKey').mockResolvedValue(mockApiKeyResponse);
38
+
39
+ const nextHeaders = await headers();
40
+ nextHeaders.set('authorization', 'Bearer sk_test_1234567890');
41
+
42
+ const result = await validateApiKey();
43
+
44
+ expect(workos.apiKeys.validateApiKey).toHaveBeenCalledWith({
45
+ value: 'sk_test_1234567890',
46
+ });
47
+ expect(result).toEqual(mockApiKeyResponse);
48
+ });
49
+
50
+ it('should return { apiKey: null } when no authorization header is present', async () => {
51
+ // Don't set any authorization header
52
+ const result = await validateApiKey();
53
+
54
+ expect(workos.apiKeys.validateApiKey).not.toHaveBeenCalled();
55
+ expect(result).toEqual({ apiKey: null });
56
+ });
57
+
58
+ it('should return { apiKey: null } when authorization header is empty', async () => {
59
+ const nextHeaders = await headers();
60
+ nextHeaders.set('authorization', '');
61
+
62
+ const result = await validateApiKey();
63
+
64
+ expect(workos.apiKeys.validateApiKey).not.toHaveBeenCalled();
65
+ expect(result).toEqual({ apiKey: null });
66
+ });
67
+
68
+ it('should return { apiKey: null } when authorization header does not start with Bearer', async () => {
69
+ const nextHeaders = await headers();
70
+ nextHeaders.set('authorization', 'Basic dXNlcjpwYXNz');
71
+
72
+ const result = await validateApiKey();
73
+
74
+ expect(workos.apiKeys.validateApiKey).not.toHaveBeenCalled();
75
+ expect(result).toEqual({ apiKey: null });
76
+ });
77
+
78
+ it('should return { apiKey: null } when Bearer token is missing', async () => {
79
+ const nextHeaders = await headers();
80
+ nextHeaders.set('authorization', 'Bearer');
81
+
82
+ const result = await validateApiKey();
83
+
84
+ expect(workos.apiKeys.validateApiKey).not.toHaveBeenCalled();
85
+ expect(result).toEqual({ apiKey: null });
86
+ });
87
+
88
+ it('should return { apiKey: null } when Bearer token is only whitespace', async () => {
89
+ const nextHeaders = await headers();
90
+ nextHeaders.set('authorization', 'Bearer ');
91
+
92
+ const result = await validateApiKey();
93
+
94
+ expect(workos.apiKeys.validateApiKey).not.toHaveBeenCalled();
95
+ expect(result).toEqual({ apiKey: null });
96
+ });
97
+
98
+ it('should return { apiKey: null } when WorkOS validation fails', async () => {
99
+ const mockResponse = { apiKey: null };
100
+ jest.spyOn(workos.apiKeys, 'validateApiKey').mockResolvedValue(mockResponse);
101
+
102
+ const nextHeaders = await headers();
103
+ nextHeaders.set('authorization', 'Bearer invalid_key');
104
+
105
+ const result = await validateApiKey();
106
+
107
+ expect(workos.apiKeys.validateApiKey).toHaveBeenCalledWith({
108
+ value: 'invalid_key',
109
+ });
110
+ expect(result).toEqual({ apiKey: null });
111
+ });
112
+ });
113
+ });
@@ -0,0 +1,19 @@
1
+ 'use server';
2
+
3
+ import { getWorkOS } from './workos.js';
4
+ import { headers } from 'next/headers';
5
+
6
+ export async function validateApiKey() {
7
+ const headersList = await headers();
8
+ const authorizationHeader = headersList.get('authorization');
9
+ if (!authorizationHeader) {
10
+ return { apiKey: null };
11
+ }
12
+
13
+ const value = authorizationHeader.match(/Bearer\s+(.*)/i)?.[1];
14
+ if (!value) {
15
+ return { apiKey: null };
16
+ }
17
+
18
+ return getWorkOS().apiKeys.validateApiKey({ value });
19
+ }
package/src/workos.ts CHANGED
@@ -2,7 +2,7 @@ import { WorkOS } from '@workos-inc/node';
2
2
  import { WORKOS_API_HOSTNAME, WORKOS_API_KEY, WORKOS_API_HTTPS, WORKOS_API_PORT } from './env-variables.js';
3
3
  import { lazy } from './utils.js';
4
4
 
5
- export const VERSION = '2.10.0';
5
+ export const VERSION = '2.11.0';
6
6
 
7
7
  const options = {
8
8
  apiHostname: WORKOS_API_HOSTNAME,