@descope/nextjs-sdk 0.0.3-alpha.1 → 0.0.4

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.
Files changed (56) hide show
  1. package/README.md +102 -7
  2. package/dist/client/dts/src/server/authMiddleware.d.ts +1 -0
  3. package/dist/client/dts/src/server/constants.d.ts +5 -1
  4. package/dist/client/dts/src/server/sdk.d.ts +1 -1
  5. package/dist/client/dts/src/server/utils.d.ts +1 -0
  6. package/dist/client/dts/src/shared/DescopeFlows.d.ts +8 -0
  7. package/dist/client/dts/src/shared/DescopeWidgets.d.ts +22 -0
  8. package/dist/client/dts/src/shared/constants.d.ts +4 -0
  9. package/dist/client/dts/src/shared/index.d.ts +1 -0
  10. package/dist/dts/src/server/authMiddleware.d.ts +1 -0
  11. package/dist/dts/src/server/constants.d.ts +5 -1
  12. package/dist/dts/src/server/sdk.d.ts +1 -1
  13. package/dist/dts/src/server/utils.d.ts +1 -0
  14. package/dist/dts/src/shared/DescopeFlows.d.ts +8 -0
  15. package/dist/dts/src/shared/DescopeWidgets.d.ts +22 -0
  16. package/dist/dts/src/shared/constants.d.ts +4 -0
  17. package/dist/dts/src/shared/index.d.ts +1 -0
  18. package/dist/index.d.ts +44 -13
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/server/dts/src/server/authMiddleware.d.ts +1 -0
  22. package/dist/server/dts/src/server/constants.d.ts +5 -1
  23. package/dist/server/dts/src/server/sdk.d.ts +1 -1
  24. package/dist/server/dts/src/server/utils.d.ts +1 -0
  25. package/dist/server/dts/src/shared/DescopeFlows.d.ts +8 -0
  26. package/dist/server/dts/src/shared/DescopeWidgets.d.ts +22 -0
  27. package/dist/server/dts/src/shared/constants.d.ts +4 -0
  28. package/dist/server/dts/src/shared/index.d.ts +1 -0
  29. package/dist/server/index.d.ts +1 -0
  30. package/dist/server/{authMiddleware.js → server/authMiddleware.js} +14 -10
  31. package/dist/server/server/authMiddleware.js.map +1 -0
  32. package/dist/server/server/constants.js +8 -0
  33. package/dist/server/server/constants.js.map +1 -0
  34. package/dist/server/{sdk.js → server/sdk.js} +4 -4
  35. package/dist/server/server/sdk.js.map +1 -0
  36. package/dist/server/{session.js → server/session.js} +4 -1
  37. package/dist/server/server/session.js.map +1 -0
  38. package/dist/server/server/utils.js +22 -0
  39. package/dist/server/server/utils.js.map +1 -0
  40. package/dist/server/{constants.js → shared/constants.js} +2 -3
  41. package/dist/server/shared/constants.js.map +1 -0
  42. package/dist/shared/AuthProvider.js +4 -1
  43. package/dist/shared/AuthProvider.js.map +1 -1
  44. package/dist/shared/DescopeFlows.js +3 -0
  45. package/dist/shared/DescopeFlows.js.map +1 -1
  46. package/dist/shared/DescopeWidgets.js +17 -0
  47. package/dist/shared/DescopeWidgets.js.map +1 -0
  48. package/dist/shared/constants.js +8 -0
  49. package/dist/shared/constants.js.map +1 -0
  50. package/package.json +5 -4
  51. package/dist/server/authMiddleware.js.map +0 -1
  52. package/dist/server/constants.js.map +0 -1
  53. package/dist/server/sdk.js.map +0 -1
  54. package/dist/server/session.js.map +0 -1
  55. /package/dist/server/{index.js → server/index.js} +0 -0
  56. /package/dist/server/{index.js.map → server/index.js.map} +0 -0
package/README.md CHANGED
@@ -30,7 +30,7 @@ For Pages router, see the [Pages Router](#pages-router) section.
30
30
  ```js
31
31
  // src/app/layout.tsx
32
32
 
33
- import { AuthProvider } from '@descope/nextjs-sdk'
33
+ import { AuthProvider } from '@descope/nextjs-sdk';
34
34
 
35
35
  export default function RootLayout({
36
36
  children
@@ -38,14 +38,12 @@ export default function RootLayout({
38
38
  children: React.ReactNode
39
39
  }) {
40
40
  return (
41
- <AuthProvider
42
- projectId="your-descope-project-id"
43
- >
41
+ <AuthProvider projectId="your-descope-project-id">
44
42
  <html lang="en">
45
43
  <body>{children}</body>
46
44
  </html>
47
45
  </AuthProvider>
48
- )
46
+ );
49
47
  }
50
48
  ```
51
49
 
@@ -57,9 +55,9 @@ You can use **default flows** or **provide flow id** directly to the Descope com
57
55
 
58
56
  ```js
59
57
  // Login page, e.g. src/app/sign-in.tsx
60
- import { Descope } from '@descope/react-sdk';
58
+ import { Descope } from '@descope/nextjs-sdk';
61
59
  // you can choose flow to run from the following without `flowId` instead
62
- // import { SignInFlow, SignUpFlow, SignUpOrInFlow } from '@descope/react-sdk'
60
+ // import { SignInFlow, SignUpFlow, SignUpOrInFlow } from '@descope/nextjs-sdk'
63
61
 
64
62
  const Page = () => {
65
63
  return (
@@ -146,6 +144,7 @@ export default authMiddleware({
146
144
 
147
145
  // The URL to redirect to if the user is not authenticated
148
146
  // Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided
147
+ // NOTE: In case it contains query parameters that exist in the original URL, they will override the original query parameters. e.g. if the original URL is /page?param1=1&param2=2 and the redirect URL is /sign-in?param1=3, the final redirect URL will be /sign-in?param1=3&param2=2
149
148
  redirectUrl?: string
150
149
 
151
150
  // An array of public routes that do not require authentication
@@ -218,6 +217,10 @@ const sdk = createSdk({
218
217
  // The Descope management key to use for management operations
219
218
  // Defaults to process.env.DESCOPE_MANAGEMENT_KEY
220
219
  managementKey: 'your-descope-management-key'
220
+
221
+ // Optional: Descope API base URL
222
+ // Defaults to process.env.DESCOPE_BASE_URL
223
+ // baseUrl: 'https://...'
221
224
  });
222
225
 
223
226
  export async function GET(req) {
@@ -237,6 +240,98 @@ export async function GET(req) {
237
240
  This section is Working in progress :-)
238
241
  In the meantime, you can see the example in the [Pages Router](/examples/pages-router/) folder.
239
242
 
243
+ ### Widgets
244
+
245
+ Widgets are components that allow you to expose management features for tenant-based implementation. In certain scenarios, your customers may require the capability to perform managerial actions independently, alleviating the necessity to contact you. Widgets serve as a feature enabling you to delegate these capabilities to your customers in a modular manner.
246
+
247
+ Important Note:
248
+
249
+ - For the user to be able to use the widget, they need to be assigned the `Tenant Admin` Role.
250
+
251
+ #### User Management
252
+
253
+ The `UserManagement` widget will let you embed a user table in your site to view and take action.
254
+
255
+ The widget lets you:
256
+
257
+ - Create a new user
258
+ - Edit an existing user
259
+ - Activate / disable an existing user
260
+ - Reset an existing user's password
261
+ - Remove an existing user's passkey
262
+ - Delete an existing user
263
+
264
+ Note:
265
+
266
+ - Custom fields also appear in the table.
267
+
268
+ ###### Usage
269
+
270
+ ```js
271
+ import { UserManagement } from '@descope/nextjs-sdk';
272
+ ...
273
+ <UserManagement
274
+ widgetId="user-management-widget"
275
+ tenant="tenant-id"
276
+ />
277
+ ```
278
+
279
+ Example:
280
+ [Manage Users](./examples/app-router/app/manage-users/page.tsx)
281
+
282
+ #### Role Management
283
+
284
+ The `RoleManagement` widget will let you embed a role table in your site to view and take action.
285
+
286
+ The widget lets you:
287
+
288
+ - Create a new role
289
+ - Change an existing role's fields
290
+ - Delete an existing role
291
+
292
+ Note:
293
+
294
+ - The `Editable` field is determined by the user's access to the role - meaning that project-level roles are not editable by tenant level users.
295
+ - You need to pre-define the permissions that the user can use, which are not editable in the widget.
296
+
297
+ ###### Usage
298
+
299
+ ```js
300
+ import { RoleManagement } from '@descope/nextjs-sdk';
301
+ ...
302
+ <RoleManagement
303
+ widgetId="role-management-widget"
304
+ tenant="tenant-id"
305
+ />
306
+ ```
307
+
308
+ Example:
309
+ [Manage Roles](./examples/app-router/app/manage-roles/page.tsx)
310
+
311
+ #### Access Key Management
312
+
313
+ The `AccessKeyManagement` widget will let you embed an access key table in your site to view and take action.
314
+
315
+ The widget lets you:
316
+
317
+ - Create a new access key
318
+ - Activate / deactivate an existing access key
319
+ - Delete an exising access key
320
+
321
+ ###### Usage
322
+
323
+ ```js
324
+ import { AccessKeyManagement } from '@descope/nextjs-sdk';
325
+ ...
326
+ <AccessKeyManagement
327
+ widgetId="access-key-management-widget"
328
+ tenant="tenant-id"
329
+ />
330
+ ```
331
+
332
+ Example:
333
+ [Manage Access Keys](./examples/app-router/app/manage-access-keys/page.tsx)
334
+
240
335
  ## Code Example
241
336
 
242
337
  You can find an example react app in the [examples folder](./examples). - [App Router](/examples/app-router/) - [Pages Router](/examples/pages-router/)
@@ -1,6 +1,7 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
  type MiddlewareOptions = {
3
3
  projectId?: string;
4
+ baseUrl?: string;
4
5
  redirectUrl?: string;
5
6
  publicRoutes?: string[];
6
7
  };
@@ -1,5 +1,9 @@
1
1
  export declare const DESCOPE_SESSION_HEADER = "x-descope-session";
2
2
  export declare const baseHeaders: {
3
3
  'x-descope-sdk-name': string;
4
- 'x-descope-sdk-version': string;
4
+ 'x-descope-sdk-version': any;
5
+ };
6
+ export declare const DEFAULT_PUBLIC_ROUTES: {
7
+ signIn: string;
8
+ signUp: string;
5
9
  };
@@ -4,5 +4,5 @@ type CreateSdkParams = Omit<Parameters<typeof descopeSdk>[0], 'projectId'> & {
4
4
  projectId?: string | undefined;
5
5
  };
6
6
  export declare const createSdk: (config?: CreateSdkParams) => Sdk;
7
- export declare const getGlobalSdk: (config?: Pick<CreateSdkParams, 'projectId'>) => Sdk;
7
+ export declare const getGlobalSdk: (config?: Pick<CreateSdkParams, 'projectId' | 'baseUrl'>) => Sdk;
8
8
  export {};
@@ -0,0 +1 @@
1
+ export declare const mergeSearchParams: (...searchParams: string[]) => string;
@@ -7,6 +7,7 @@ export declare const Descope: React.ComponentType<(({
7
7
  flowId: string;
8
8
  onSuccess?: (event: CustomEvent<any>) => void;
9
9
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
10
+ onReady?: (event: CustomEvent<any>) => void;
10
11
  logger?: import("@descope/web-component").ILogger;
11
12
  tenant?: string;
12
13
  theme?: import("@descope/web-component").ThemeOptions;
@@ -25,6 +26,7 @@ export declare const Descope: React.ComponentType<(({
25
26
  flowId: string;
26
27
  onSuccess?: (event: CustomEvent<any>) => void;
27
28
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
29
+ onReady?: (event: CustomEvent<any>) => void;
28
30
  logger?: import("@descope/web-component").ILogger;
29
31
  tenant?: string;
30
32
  theme?: import("@descope/web-component").ThemeOptions;
@@ -46,6 +48,7 @@ export declare const SignInFlow: React.ComponentType<({
46
48
  form?: Record<string, any>;
47
49
  onSuccess?: (event: CustomEvent<any>) => void;
48
50
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
51
+ onReady?: (event: CustomEvent<any>) => void;
49
52
  logger?: import("@descope/web-component").ILogger;
50
53
  tenant?: string;
51
54
  theme?: import("@descope/web-component").ThemeOptions;
@@ -63,6 +66,7 @@ export declare const SignInFlow: React.ComponentType<({
63
66
  form?: Record<string, any>;
64
67
  onSuccess?: (event: CustomEvent<any>) => void;
65
68
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
69
+ onReady?: (event: CustomEvent<any>) => void;
66
70
  logger?: import("@descope/web-component").ILogger;
67
71
  tenant?: string;
68
72
  theme?: import("@descope/web-component").ThemeOptions;
@@ -83,6 +87,7 @@ export declare const SignUpFlow: React.ComponentType<({
83
87
  form?: Record<string, any>;
84
88
  onSuccess?: (event: CustomEvent<any>) => void;
85
89
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
90
+ onReady?: (event: CustomEvent<any>) => void;
86
91
  logger?: import("@descope/web-component").ILogger;
87
92
  tenant?: string;
88
93
  theme?: import("@descope/web-component").ThemeOptions;
@@ -100,6 +105,7 @@ export declare const SignUpFlow: React.ComponentType<({
100
105
  form?: Record<string, any>;
101
106
  onSuccess?: (event: CustomEvent<any>) => void;
102
107
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
108
+ onReady?: (event: CustomEvent<any>) => void;
103
109
  logger?: import("@descope/web-component").ILogger;
104
110
  tenant?: string;
105
111
  theme?: import("@descope/web-component").ThemeOptions;
@@ -120,6 +126,7 @@ export declare const SignUpOrInFlow: React.ComponentType<({
120
126
  form?: Record<string, any>;
121
127
  onSuccess?: (event: CustomEvent<any>) => void;
122
128
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
129
+ onReady?: (event: CustomEvent<any>) => void;
123
130
  logger?: import("@descope/web-component").ILogger;
124
131
  tenant?: string;
125
132
  theme?: import("@descope/web-component").ThemeOptions;
@@ -137,6 +144,7 @@ export declare const SignUpOrInFlow: React.ComponentType<({
137
144
  form?: Record<string, any>;
138
145
  onSuccess?: (event: CustomEvent<any>) => void;
139
146
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
147
+ onReady?: (event: CustomEvent<any>) => void;
140
148
  logger?: import("@descope/web-component").ILogger;
141
149
  tenant?: string;
142
150
  theme?: import("@descope/web-component").ThemeOptions;
@@ -0,0 +1,22 @@
1
+ import { ComponentType } from 'react';
2
+ export declare const UserManagement: ComponentType<{
3
+ logger?: import("@descope/web-component").ILogger;
4
+ tenant: string;
5
+ widgetId: string;
6
+ theme?: import("@descope/web-component").ThemeOptions;
7
+ debug?: boolean;
8
+ } & import("react").RefAttributes<HTMLElement>>;
9
+ export declare const RoleManagement: ComponentType<{
10
+ logger?: import("@descope/web-component").ILogger;
11
+ tenant: string;
12
+ widgetId: string;
13
+ theme?: import("@descope/web-component").ThemeOptions;
14
+ debug?: boolean;
15
+ } & import("react").RefAttributes<HTMLElement>>;
16
+ export declare const AccessKeyManagement: ComponentType<{
17
+ logger?: import("@descope/web-component").ILogger;
18
+ tenant: string;
19
+ widgetId: string;
20
+ theme?: import("@descope/web-component").ThemeOptions;
21
+ debug?: boolean;
22
+ } & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,4 @@
1
+ export declare const baseHeaders: {
2
+ 'x-descope-sdk-name': string;
3
+ 'x-descope-sdk-version': string;
4
+ };
@@ -1,2 +1,3 @@
1
1
  export { default as AuthProvider } from './AuthProvider';
2
2
  export * from './DescopeFlows';
3
+ export * from './DescopeWidgets';
@@ -1,6 +1,7 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
  type MiddlewareOptions = {
3
3
  projectId?: string;
4
+ baseUrl?: string;
4
5
  redirectUrl?: string;
5
6
  publicRoutes?: string[];
6
7
  };
@@ -1,5 +1,9 @@
1
1
  export declare const DESCOPE_SESSION_HEADER = "x-descope-session";
2
2
  export declare const baseHeaders: {
3
3
  'x-descope-sdk-name': string;
4
- 'x-descope-sdk-version': string;
4
+ 'x-descope-sdk-version': any;
5
+ };
6
+ export declare const DEFAULT_PUBLIC_ROUTES: {
7
+ signIn: string;
8
+ signUp: string;
5
9
  };
@@ -4,5 +4,5 @@ type CreateSdkParams = Omit<Parameters<typeof descopeSdk>[0], 'projectId'> & {
4
4
  projectId?: string | undefined;
5
5
  };
6
6
  export declare const createSdk: (config?: CreateSdkParams) => Sdk;
7
- export declare const getGlobalSdk: (config?: Pick<CreateSdkParams, 'projectId'>) => Sdk;
7
+ export declare const getGlobalSdk: (config?: Pick<CreateSdkParams, 'projectId' | 'baseUrl'>) => Sdk;
8
8
  export {};
@@ -0,0 +1 @@
1
+ export declare const mergeSearchParams: (...searchParams: string[]) => string;
@@ -7,6 +7,7 @@ export declare const Descope: React.ComponentType<(({
7
7
  flowId: string;
8
8
  onSuccess?: (event: CustomEvent<any>) => void;
9
9
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
10
+ onReady?: (event: CustomEvent<any>) => void;
10
11
  logger?: import("@descope/web-component").ILogger;
11
12
  tenant?: string;
12
13
  theme?: import("@descope/web-component").ThemeOptions;
@@ -25,6 +26,7 @@ export declare const Descope: React.ComponentType<(({
25
26
  flowId: string;
26
27
  onSuccess?: (event: CustomEvent<any>) => void;
27
28
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
29
+ onReady?: (event: CustomEvent<any>) => void;
28
30
  logger?: import("@descope/web-component").ILogger;
29
31
  tenant?: string;
30
32
  theme?: import("@descope/web-component").ThemeOptions;
@@ -46,6 +48,7 @@ export declare const SignInFlow: React.ComponentType<({
46
48
  form?: Record<string, any>;
47
49
  onSuccess?: (event: CustomEvent<any>) => void;
48
50
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
51
+ onReady?: (event: CustomEvent<any>) => void;
49
52
  logger?: import("@descope/web-component").ILogger;
50
53
  tenant?: string;
51
54
  theme?: import("@descope/web-component").ThemeOptions;
@@ -63,6 +66,7 @@ export declare const SignInFlow: React.ComponentType<({
63
66
  form?: Record<string, any>;
64
67
  onSuccess?: (event: CustomEvent<any>) => void;
65
68
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
69
+ onReady?: (event: CustomEvent<any>) => void;
66
70
  logger?: import("@descope/web-component").ILogger;
67
71
  tenant?: string;
68
72
  theme?: import("@descope/web-component").ThemeOptions;
@@ -83,6 +87,7 @@ export declare const SignUpFlow: React.ComponentType<({
83
87
  form?: Record<string, any>;
84
88
  onSuccess?: (event: CustomEvent<any>) => void;
85
89
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
90
+ onReady?: (event: CustomEvent<any>) => void;
86
91
  logger?: import("@descope/web-component").ILogger;
87
92
  tenant?: string;
88
93
  theme?: import("@descope/web-component").ThemeOptions;
@@ -100,6 +105,7 @@ export declare const SignUpFlow: React.ComponentType<({
100
105
  form?: Record<string, any>;
101
106
  onSuccess?: (event: CustomEvent<any>) => void;
102
107
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
108
+ onReady?: (event: CustomEvent<any>) => void;
103
109
  logger?: import("@descope/web-component").ILogger;
104
110
  tenant?: string;
105
111
  theme?: import("@descope/web-component").ThemeOptions;
@@ -120,6 +126,7 @@ export declare const SignUpOrInFlow: React.ComponentType<({
120
126
  form?: Record<string, any>;
121
127
  onSuccess?: (event: CustomEvent<any>) => void;
122
128
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
129
+ onReady?: (event: CustomEvent<any>) => void;
123
130
  logger?: import("@descope/web-component").ILogger;
124
131
  tenant?: string;
125
132
  theme?: import("@descope/web-component").ThemeOptions;
@@ -137,6 +144,7 @@ export declare const SignUpOrInFlow: React.ComponentType<({
137
144
  form?: Record<string, any>;
138
145
  onSuccess?: (event: CustomEvent<any>) => void;
139
146
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
147
+ onReady?: (event: CustomEvent<any>) => void;
140
148
  logger?: import("@descope/web-component").ILogger;
141
149
  tenant?: string;
142
150
  theme?: import("@descope/web-component").ThemeOptions;
@@ -0,0 +1,22 @@
1
+ import { ComponentType } from 'react';
2
+ export declare const UserManagement: ComponentType<{
3
+ logger?: import("@descope/web-component").ILogger;
4
+ tenant: string;
5
+ widgetId: string;
6
+ theme?: import("@descope/web-component").ThemeOptions;
7
+ debug?: boolean;
8
+ } & import("react").RefAttributes<HTMLElement>>;
9
+ export declare const RoleManagement: ComponentType<{
10
+ logger?: import("@descope/web-component").ILogger;
11
+ tenant: string;
12
+ widgetId: string;
13
+ theme?: import("@descope/web-component").ThemeOptions;
14
+ debug?: boolean;
15
+ } & import("react").RefAttributes<HTMLElement>>;
16
+ export declare const AccessKeyManagement: ComponentType<{
17
+ logger?: import("@descope/web-component").ILogger;
18
+ tenant: string;
19
+ widgetId: string;
20
+ theme?: import("@descope/web-component").ThemeOptions;
21
+ debug?: boolean;
22
+ } & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,4 @@
1
+ export declare const baseHeaders: {
2
+ 'x-descope-sdk-name': string;
3
+ 'x-descope-sdk-version': string;
4
+ };
@@ -1,2 +1,3 @@
1
1
  export { default as AuthProvider } from './AuthProvider';
2
2
  export * from './DescopeFlows';
3
+ export * from './DescopeWidgets';
package/dist/index.d.ts CHANGED
@@ -1,17 +1,19 @@
1
- import React, { ComponentProps } from 'react';
1
+ import * as React from 'react';
2
+ import React__default, { ComponentProps, ComponentType } from 'react';
2
3
  import { AuthProvider as AuthProvider$1 } from '@descope/react-sdk';
3
4
  import * as _descope_web_component from '@descope/web-component';
4
5
 
5
- declare const AuthProvider: (props: ComponentProps<typeof AuthProvider$1>) => React.JSX.Element;
6
+ declare const AuthProvider: (props: ComponentProps<typeof AuthProvider$1>) => React__default.JSX.Element;
6
7
 
7
8
  type AdditionalProps = {
8
9
  redirectAfterSuccess?: string;
9
10
  redirectAfterError?: string;
10
11
  };
11
- declare const Descope: React.ComponentType<(({
12
+ declare const Descope: React__default.ComponentType<(({
12
13
  flowId: string;
13
14
  onSuccess?: (event: CustomEvent<any>) => void;
14
15
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
16
+ onReady?: (event: CustomEvent<any>) => void;
15
17
  logger?: _descope_web_component.ILogger;
16
18
  tenant?: string;
17
19
  theme?: _descope_web_component.ThemeOptions;
@@ -26,10 +28,11 @@ declare const Descope: React.ComponentType<(({
26
28
  }) => string;
27
29
  form?: Record<string, any>;
28
30
  client?: Record<string, any>;
29
- } & React.RefAttributes<HTMLElement>) | ({
31
+ } & React__default.RefAttributes<HTMLElement>) | ({
30
32
  flowId: string;
31
33
  onSuccess?: (event: CustomEvent<any>) => void;
32
34
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
35
+ onReady?: (event: CustomEvent<any>) => void;
33
36
  logger?: _descope_web_component.ILogger;
34
37
  tenant?: string;
35
38
  theme?: _descope_web_component.ThemeOptions;
@@ -44,13 +47,14 @@ declare const Descope: React.ComponentType<(({
44
47
  }) => string;
45
48
  form?: Record<string, any>;
46
49
  client?: Record<string, any>;
47
- } & React.RefAttributes<HTMLElement> & {
48
- children?: React.ReactNode;
50
+ } & React__default.RefAttributes<HTMLElement> & {
51
+ children?: React__default.ReactNode;
49
52
  })) & AdditionalProps>;
50
- declare const SignInFlow: React.ComponentType<({
53
+ declare const SignInFlow: React__default.ComponentType<({
51
54
  form?: Record<string, any>;
52
55
  onSuccess?: (event: CustomEvent<any>) => void;
53
56
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
57
+ onReady?: (event: CustomEvent<any>) => void;
54
58
  logger?: _descope_web_component.ILogger;
55
59
  tenant?: string;
56
60
  theme?: _descope_web_component.ThemeOptions;
@@ -68,6 +72,7 @@ declare const SignInFlow: React.ComponentType<({
68
72
  form?: Record<string, any>;
69
73
  onSuccess?: (event: CustomEvent<any>) => void;
70
74
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
75
+ onReady?: (event: CustomEvent<any>) => void;
71
76
  logger?: _descope_web_component.ILogger;
72
77
  tenant?: string;
73
78
  theme?: _descope_web_component.ThemeOptions;
@@ -82,12 +87,13 @@ declare const SignInFlow: React.ComponentType<({
82
87
  }) => string;
83
88
  client?: Record<string, any>;
84
89
  } & {
85
- children?: React.ReactNode;
90
+ children?: React__default.ReactNode;
86
91
  })) & AdditionalProps>;
87
- declare const SignUpFlow: React.ComponentType<({
92
+ declare const SignUpFlow: React__default.ComponentType<({
88
93
  form?: Record<string, any>;
89
94
  onSuccess?: (event: CustomEvent<any>) => void;
90
95
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
96
+ onReady?: (event: CustomEvent<any>) => void;
91
97
  logger?: _descope_web_component.ILogger;
92
98
  tenant?: string;
93
99
  theme?: _descope_web_component.ThemeOptions;
@@ -105,6 +111,7 @@ declare const SignUpFlow: React.ComponentType<({
105
111
  form?: Record<string, any>;
106
112
  onSuccess?: (event: CustomEvent<any>) => void;
107
113
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
114
+ onReady?: (event: CustomEvent<any>) => void;
108
115
  logger?: _descope_web_component.ILogger;
109
116
  tenant?: string;
110
117
  theme?: _descope_web_component.ThemeOptions;
@@ -119,12 +126,13 @@ declare const SignUpFlow: React.ComponentType<({
119
126
  }) => string;
120
127
  client?: Record<string, any>;
121
128
  } & {
122
- children?: React.ReactNode;
129
+ children?: React__default.ReactNode;
123
130
  })) & AdditionalProps>;
124
- declare const SignUpOrInFlow: React.ComponentType<({
131
+ declare const SignUpOrInFlow: React__default.ComponentType<({
125
132
  form?: Record<string, any>;
126
133
  onSuccess?: (event: CustomEvent<any>) => void;
127
134
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
135
+ onReady?: (event: CustomEvent<any>) => void;
128
136
  logger?: _descope_web_component.ILogger;
129
137
  tenant?: string;
130
138
  theme?: _descope_web_component.ThemeOptions;
@@ -142,6 +150,7 @@ declare const SignUpOrInFlow: React.ComponentType<({
142
150
  form?: Record<string, any>;
143
151
  onSuccess?: (event: CustomEvent<any>) => void;
144
152
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
153
+ onReady?: (event: CustomEvent<any>) => void;
145
154
  logger?: _descope_web_component.ILogger;
146
155
  tenant?: string;
147
156
  theme?: _descope_web_component.ThemeOptions;
@@ -156,7 +165,29 @@ declare const SignUpOrInFlow: React.ComponentType<({
156
165
  }) => string;
157
166
  client?: Record<string, any>;
158
167
  } & {
159
- children?: React.ReactNode;
168
+ children?: React__default.ReactNode;
160
169
  })) & AdditionalProps>;
161
170
 
162
- export { AuthProvider, Descope, SignInFlow, SignUpFlow, SignUpOrInFlow };
171
+ declare const UserManagement: ComponentType<{
172
+ logger?: _descope_web_component.ILogger;
173
+ tenant: string;
174
+ widgetId: string;
175
+ theme?: _descope_web_component.ThemeOptions;
176
+ debug?: boolean;
177
+ } & React.RefAttributes<HTMLElement>>;
178
+ declare const RoleManagement: ComponentType<{
179
+ logger?: _descope_web_component.ILogger;
180
+ tenant: string;
181
+ widgetId: string;
182
+ theme?: _descope_web_component.ThemeOptions;
183
+ debug?: boolean;
184
+ } & React.RefAttributes<HTMLElement>>;
185
+ declare const AccessKeyManagement: ComponentType<{
186
+ logger?: _descope_web_component.ILogger;
187
+ tenant: string;
188
+ widgetId: string;
189
+ theme?: _descope_web_component.ThemeOptions;
190
+ debug?: boolean;
191
+ } & React.RefAttributes<HTMLElement>>;
192
+
193
+ export { AccessKeyManagement, AuthProvider, Descope, RoleManagement, SignInFlow, SignUpFlow, SignUpOrInFlow, UserManagement };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as AuthProvider } from './shared/AuthProvider.js';
2
2
  export { Descope, SignInFlow, SignUpFlow, SignUpOrInFlow } from './shared/DescopeFlows.js';
3
+ export { AccessKeyManagement, RoleManagement, UserManagement } from './shared/DescopeWidgets.js';
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,6 +1,7 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
  type MiddlewareOptions = {
3
3
  projectId?: string;
4
+ baseUrl?: string;
4
5
  redirectUrl?: string;
5
6
  publicRoutes?: string[];
6
7
  };
@@ -1,5 +1,9 @@
1
1
  export declare const DESCOPE_SESSION_HEADER = "x-descope-session";
2
2
  export declare const baseHeaders: {
3
3
  'x-descope-sdk-name': string;
4
- 'x-descope-sdk-version': string;
4
+ 'x-descope-sdk-version': any;
5
+ };
6
+ export declare const DEFAULT_PUBLIC_ROUTES: {
7
+ signIn: string;
8
+ signUp: string;
5
9
  };
@@ -4,5 +4,5 @@ type CreateSdkParams = Omit<Parameters<typeof descopeSdk>[0], 'projectId'> & {
4
4
  projectId?: string | undefined;
5
5
  };
6
6
  export declare const createSdk: (config?: CreateSdkParams) => Sdk;
7
- export declare const getGlobalSdk: (config?: Pick<CreateSdkParams, 'projectId'>) => Sdk;
7
+ export declare const getGlobalSdk: (config?: Pick<CreateSdkParams, 'projectId' | 'baseUrl'>) => Sdk;
8
8
  export {};
@@ -0,0 +1 @@
1
+ export declare const mergeSearchParams: (...searchParams: string[]) => string;
@@ -7,6 +7,7 @@ export declare const Descope: React.ComponentType<(({
7
7
  flowId: string;
8
8
  onSuccess?: (event: CustomEvent<any>) => void;
9
9
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
10
+ onReady?: (event: CustomEvent<any>) => void;
10
11
  logger?: import("@descope/web-component").ILogger;
11
12
  tenant?: string;
12
13
  theme?: import("@descope/web-component").ThemeOptions;
@@ -25,6 +26,7 @@ export declare const Descope: React.ComponentType<(({
25
26
  flowId: string;
26
27
  onSuccess?: (event: CustomEvent<any>) => void;
27
28
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
29
+ onReady?: (event: CustomEvent<any>) => void;
28
30
  logger?: import("@descope/web-component").ILogger;
29
31
  tenant?: string;
30
32
  theme?: import("@descope/web-component").ThemeOptions;
@@ -46,6 +48,7 @@ export declare const SignInFlow: React.ComponentType<({
46
48
  form?: Record<string, any>;
47
49
  onSuccess?: (event: CustomEvent<any>) => void;
48
50
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
51
+ onReady?: (event: CustomEvent<any>) => void;
49
52
  logger?: import("@descope/web-component").ILogger;
50
53
  tenant?: string;
51
54
  theme?: import("@descope/web-component").ThemeOptions;
@@ -63,6 +66,7 @@ export declare const SignInFlow: React.ComponentType<({
63
66
  form?: Record<string, any>;
64
67
  onSuccess?: (event: CustomEvent<any>) => void;
65
68
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
69
+ onReady?: (event: CustomEvent<any>) => void;
66
70
  logger?: import("@descope/web-component").ILogger;
67
71
  tenant?: string;
68
72
  theme?: import("@descope/web-component").ThemeOptions;
@@ -83,6 +87,7 @@ export declare const SignUpFlow: React.ComponentType<({
83
87
  form?: Record<string, any>;
84
88
  onSuccess?: (event: CustomEvent<any>) => void;
85
89
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
90
+ onReady?: (event: CustomEvent<any>) => void;
86
91
  logger?: import("@descope/web-component").ILogger;
87
92
  tenant?: string;
88
93
  theme?: import("@descope/web-component").ThemeOptions;
@@ -100,6 +105,7 @@ export declare const SignUpFlow: React.ComponentType<({
100
105
  form?: Record<string, any>;
101
106
  onSuccess?: (event: CustomEvent<any>) => void;
102
107
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
108
+ onReady?: (event: CustomEvent<any>) => void;
103
109
  logger?: import("@descope/web-component").ILogger;
104
110
  tenant?: string;
105
111
  theme?: import("@descope/web-component").ThemeOptions;
@@ -120,6 +126,7 @@ export declare const SignUpOrInFlow: React.ComponentType<({
120
126
  form?: Record<string, any>;
121
127
  onSuccess?: (event: CustomEvent<any>) => void;
122
128
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
129
+ onReady?: (event: CustomEvent<any>) => void;
123
130
  logger?: import("@descope/web-component").ILogger;
124
131
  tenant?: string;
125
132
  theme?: import("@descope/web-component").ThemeOptions;
@@ -137,6 +144,7 @@ export declare const SignUpOrInFlow: React.ComponentType<({
137
144
  form?: Record<string, any>;
138
145
  onSuccess?: (event: CustomEvent<any>) => void;
139
146
  onError?: OnErrorEventHandlerNonNull & ((event: CustomEvent<any>) => void);
147
+ onReady?: (event: CustomEvent<any>) => void;
140
148
  logger?: import("@descope/web-component").ILogger;
141
149
  tenant?: string;
142
150
  theme?: import("@descope/web-component").ThemeOptions;
@@ -0,0 +1,22 @@
1
+ import { ComponentType } from 'react';
2
+ export declare const UserManagement: ComponentType<{
3
+ logger?: import("@descope/web-component").ILogger;
4
+ tenant: string;
5
+ widgetId: string;
6
+ theme?: import("@descope/web-component").ThemeOptions;
7
+ debug?: boolean;
8
+ } & import("react").RefAttributes<HTMLElement>>;
9
+ export declare const RoleManagement: ComponentType<{
10
+ logger?: import("@descope/web-component").ILogger;
11
+ tenant: string;
12
+ widgetId: string;
13
+ theme?: import("@descope/web-component").ThemeOptions;
14
+ debug?: boolean;
15
+ } & import("react").RefAttributes<HTMLElement>>;
16
+ export declare const AccessKeyManagement: ComponentType<{
17
+ logger?: import("@descope/web-component").ILogger;
18
+ tenant: string;
19
+ widgetId: string;
20
+ theme?: import("@descope/web-component").ThemeOptions;
21
+ debug?: boolean;
22
+ } & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,4 @@
1
+ export declare const baseHeaders: {
2
+ 'x-descope-sdk-name': string;
3
+ 'x-descope-sdk-version': string;
4
+ };
@@ -1,2 +1,3 @@
1
1
  export { default as AuthProvider } from './AuthProvider';
2
2
  export * from './DescopeFlows';
3
+ export * from './DescopeWidgets';
@@ -4,6 +4,7 @@ import { NextApiRequest } from 'next';
4
4
 
5
5
  type MiddlewareOptions = {
6
6
  projectId?: string;
7
+ baseUrl?: string;
7
8
  redirectUrl?: string;
8
9
  publicRoutes?: string[];
9
10
  };
@@ -1,7 +1,8 @@
1
1
  import { NextResponse } from 'next/server';
2
2
  import descopeSdk from '@descope/node-sdk';
3
- import { DESCOPE_SESSION_HEADER } from './constants.js';
3
+ import { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER } from './constants.js';
4
4
  import { getGlobalSdk } from './sdk.js';
5
+ import { mergeSearchParams } from './utils.js';
5
6
 
6
7
  /* eslint-disable no-console */
7
8
  const getSessionJwt = (req) => {
@@ -15,12 +16,8 @@ const getSessionJwt = (req) => {
15
16
  }
16
17
  return undefined;
17
18
  };
18
- const defaultPublicRoutes = {
19
- signIn: process.env.SIGN_IN_ROUTE || '/sign-in',
20
- signUp: process.env.SIGN_UP_ROUTE || '/sign-up'
21
- };
22
19
  const isPublicRoute = (req, options) => {
23
- const isDefaultPublicRoute = Object.values(defaultPublicRoutes).includes(req.nextUrl.pathname);
20
+ const isDefaultPublicRoute = Object.values(DEFAULT_PUBLIC_ROUTES).includes(req.nextUrl.pathname);
24
21
  const isPublic = options.publicRoutes?.includes(req.nextUrl.pathname);
25
22
  return isDefaultPublicRoute || isPublic;
26
23
  };
@@ -42,16 +39,23 @@ const createAuthMiddleware = (options = {}) => async (req) => {
42
39
  let session;
43
40
  try {
44
41
  session = await getGlobalSdk({
45
- projectId: options.projectId
42
+ projectId: options.projectId,
43
+ baseUrl: options.baseUrl
46
44
  }).validateJwt(jwt);
47
45
  }
48
46
  catch (err) {
49
47
  console.debug('Auth middleware, Failed to validate JWT', err);
50
48
  if (!isPublicRoute(req, options)) {
51
- const defaultRedirectUrl = options.redirectUrl || defaultPublicRoutes.signIn;
49
+ const redirectUrl = options.redirectUrl || DEFAULT_PUBLIC_ROUTES.signIn;
52
50
  const url = req.nextUrl.clone();
53
- url.pathname = defaultRedirectUrl;
54
- console.debug(`Auth middleware, Redirecting to ${url}`);
51
+ // Create a URL object for redirectUrl. 'http://example.com' is just a placeholder.
52
+ const parsedRedirectUrl = new URL(redirectUrl, 'http://example.com');
53
+ url.pathname = parsedRedirectUrl.pathname;
54
+ const searchParams = mergeSearchParams(url.search, parsedRedirectUrl.search);
55
+ if (searchParams) {
56
+ url.search = searchParams;
57
+ }
58
+ console.debug(`Auth middleware, Redirecting to ${redirectUrl}`);
55
59
  return NextResponse.redirect(url);
56
60
  }
57
61
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.js","sources":["../../../src/server/authMiddleware.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport { NextRequest, NextResponse } from 'next/server';\nimport descopeSdk from '@descope/node-sdk';\nimport type { AuthenticationInfo } from '@descope/node-sdk';\nimport { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER } from './constants';\nimport { getGlobalSdk } from './sdk';\nimport { mergeSearchParams } from './utils';\n\ntype MiddlewareOptions = {\n\t// The Descope project ID to use for authentication\n\t// Defaults to process.env.DESCOPE_PROJECT_ID\n\tprojectId?: string;\n\n\t// The base URL to use for authentication\n\t// Defaults to process.env.DESCOPE_BASE_URL\n\tbaseUrl?: string;\n\n\t// The URL to redirect to if the user is not authenticated\n\t// Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided\n\t// NOTE: In case it contains query parameters that exist in the original URL, they will override the original query parameters. e.g. if the original URL is /page?param1=1&param2=2 and the redirect URL is /sign-in?param1=3, the final redirect URL will be /sign-in?param1=3&param2=2\n\tredirectUrl?: string;\n\n\t// An array of public routes that do not require authentication\n\t// In addition to the default public routes:\n\t// - process.env.SIGN_IN_ROUTE or /sign-in if not provided\n\t// - process.env.SIGN_UP_ROUTE or /sign-up if not provided\n\tpublicRoutes?: string[];\n};\n\nconst getSessionJwt = (req: NextRequest): string | undefined => {\n\tlet jwt = req.headers?.get('Authorization')?.split(' ')[1];\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\n\tjwt = req.cookies?.get(descopeSdk.SessionTokenCookieName)?.value;\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\treturn undefined;\n};\n\nconst isPublicRoute = (req: NextRequest, options: MiddlewareOptions) => {\n\tconst isDefaultPublicRoute = Object.values(DEFAULT_PUBLIC_ROUTES).includes(\n\t\treq.nextUrl.pathname\n\t);\n\tconst isPublic = options.publicRoutes?.includes(req.nextUrl.pathname);\n\n\treturn isDefaultPublicRoute || isPublic;\n};\n\nconst addSessionToHeadersIfExists = (\n\theaders: Headers,\n\tsession: AuthenticationInfo | undefined\n): Headers => {\n\tif (session) {\n\t\tconst requestHeaders = new Headers(headers);\n\t\trequestHeaders.set(\n\t\t\tDESCOPE_SESSION_HEADER,\n\t\t\tBuffer.from(JSON.stringify(session)).toString('base64')\n\t\t);\n\t\treturn requestHeaders;\n\t}\n\treturn headers;\n};\n\n// returns a Middleware that checks if the user is authenticated\n// if the user is not authenticated, it redirects to the redirectUrl\n// if the user is authenticated, it adds the session to the headers\nconst createAuthMiddleware =\n\t(options: MiddlewareOptions = {}) =>\n\tasync (req: NextRequest) => {\n\t\tconsole.debug('Auth middleware starts');\n\n\t\tconst jwt = getSessionJwt(req);\n\n\t\t// check if the user is authenticated\n\t\tlet session: AuthenticationInfo | undefined;\n\t\ttry {\n\t\t\tsession = await getGlobalSdk({\n\t\t\t\tprojectId: options.projectId,\n\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t}).validateJwt(jwt);\n\t\t} catch (err) {\n\t\t\tconsole.debug('Auth middleware, Failed to validate JWT', err);\n\t\t\tif (!isPublicRoute(req, options)) {\n\t\t\t\tconst redirectUrl = options.redirectUrl || DEFAULT_PUBLIC_ROUTES.signIn;\n\t\t\t\tconst url = req.nextUrl.clone();\n\t\t\t\t// Create a URL object for redirectUrl. 'http://example.com' is just a placeholder.\n\t\t\t\tconst parsedRedirectUrl = new URL(redirectUrl, 'http://example.com');\n\t\t\t\turl.pathname = parsedRedirectUrl.pathname;\n\n\t\t\t\tconst searchParams = mergeSearchParams(\n\t\t\t\t\turl.search,\n\t\t\t\t\tparsedRedirectUrl.search\n\t\t\t\t);\n\t\t\t\tif (searchParams) {\n\t\t\t\t\turl.search = searchParams;\n\t\t\t\t}\n\t\t\t\tconsole.debug(`Auth middleware, Redirecting to ${redirectUrl}`);\n\t\t\t\treturn NextResponse.redirect(url);\n\t\t\t}\n\t\t}\n\n\t\tconsole.debug('Auth middleware finishes');\n\t\t// add the session to the request, if it exists\n\t\tconst headers = addSessionToHeadersIfExists(req.headers, session);\n\t\treturn NextResponse.next({\n\t\t\trequest: {\n\t\t\t\theaders\n\t\t\t}\n\t\t});\n\t};\n\nexport default createAuthMiddleware;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ const DESCOPE_SESSION_HEADER = 'x-descope-session';
2
+ const DEFAULT_PUBLIC_ROUTES = {
3
+ signIn: process.env.SIGN_IN_ROUTE || '/sign-in',
4
+ signUp: process.env.SIGN_UP_ROUTE || '/sign-up'
5
+ };
6
+
7
+ export { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER };
8
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../src/server/constants.ts"],"sourcesContent":["export const DESCOPE_SESSION_HEADER = 'x-descope-session';\n\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n\nexport const DEFAULT_PUBLIC_ROUTES = {\n\tsignIn: process.env.SIGN_IN_ROUTE || '/sign-in',\n\tsignUp: process.env.SIGN_UP_ROUTE || '/sign-up'\n};\n"],"names":[],"mappings":"AAAO,MAAM,sBAAsB,GAAG,oBAAoB;AAO7C,MAAA,qBAAqB,GAAG;AACpC,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;AAC/C,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;;;;;"}
@@ -1,12 +1,12 @@
1
1
  import descopeSdk from '@descope/node-sdk';
2
- import { baseHeaders } from './constants.js';
2
+ import { baseHeaders } from '../shared/constants.js';
3
3
 
4
4
  let globalSdk;
5
5
  const createSdk = (config) => descopeSdk({
6
6
  ...config,
7
- projectId: config.projectId || process.env.DESCOPE_PROJECT_ID,
8
- managementKey: config.managementKey || process.env.DESCOPE_MANAGEMENT_KEY,
9
- baseUrl: config.baseUrl || process.env.DESCOPE_BASE_URL,
7
+ projectId: config?.projectId || process.env.DESCOPE_PROJECT_ID,
8
+ managementKey: config?.managementKey || process.env.DESCOPE_MANAGEMENT_KEY,
9
+ baseUrl: config?.baseUrl || process.env.DESCOPE_BASE_URL,
10
10
  baseHeaders: {
11
11
  ...config?.baseHeaders,
12
12
  ...baseHeaders
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import descopeSdk from '@descope/node-sdk';\nimport { baseHeaders } from '../shared/constants';\n\ntype Sdk = ReturnType<typeof descopeSdk>;\ntype CreateSdkParams = Omit<Parameters<typeof descopeSdk>[0], 'projectId'> & {\n\tprojectId?: string | undefined;\n};\n\nlet globalSdk: Sdk;\n\nexport const createSdk = (config?: CreateSdkParams): Sdk =>\n\tdescopeSdk({\n\t\t...config,\n\t\tprojectId: config?.projectId || process.env.DESCOPE_PROJECT_ID,\n\t\tmanagementKey: config?.managementKey || process.env.DESCOPE_MANAGEMENT_KEY,\n\t\tbaseUrl: config?.baseUrl || process.env.DESCOPE_BASE_URL,\n\t\tbaseHeaders: {\n\t\t\t...config?.baseHeaders,\n\t\t\t...baseHeaders\n\t\t}\n\t});\n\nexport const getGlobalSdk = (\n\tconfig?: Pick<CreateSdkParams, 'projectId' | 'baseUrl'>\n): Sdk => {\n\tif (!globalSdk) {\n\t\tif (!config?.projectId && !process.env.DESCOPE_PROJECT_ID) {\n\t\t\tthrow new Error('Descope project ID is required to create the SDK');\n\t\t}\n\t\tglobalSdk = createSdk(config);\n\t}\n\n\treturn globalSdk;\n};\n"],"names":[],"mappings":";;;AAQA,IAAI,SAAc,CAAC;AAEN,MAAA,SAAS,GAAG,CAAC,MAAwB,KACjD,UAAU,CAAC;AACV,IAAA,GAAG,MAAM;IACT,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;IAC9D,aAAa,EAAE,MAAM,EAAE,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB;IAC1E,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;AACxD,IAAA,WAAW,EAAE;QACZ,GAAG,MAAM,EAAE,WAAW;AACtB,QAAA,GAAG,WAAW;AACd,KAAA;AACD,CAAA,EAAE;AAES,MAAA,YAAY,GAAG,CAC3B,MAAuD,KAC/C;IACR,IAAI,CAAC,SAAS,EAAE;QACf,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE;AAC1D,YAAA,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;AACpE,SAAA;AACD,QAAA,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAC9B,KAAA;AAED,IAAA,OAAO,SAAS,CAAC;AAClB;;;;"}
@@ -15,7 +15,10 @@ const extractSession = (descopeSession) => {
15
15
  };
16
16
  // returns the session token if it exists in the headers
17
17
  // This function require middleware
18
- const session = () => extractSession(headers()?.get(DESCOPE_SESSION_HEADER));
18
+ const session = () => {
19
+ const sessionHeader = headers()?.get(DESCOPE_SESSION_HEADER);
20
+ return extractSession(sessionHeader);
21
+ };
19
22
  // returns the session token if it exists in the request headers
20
23
  // This function require middleware
21
24
  const getSession = (req) => extractSession(req.headers[DESCOPE_SESSION_HEADER.toLowerCase()]);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sources":["../../../src/server/session.ts"],"sourcesContent":["import { AuthenticationInfo } from '@descope/node-sdk';\nimport { NextApiRequest } from 'next';\nimport { headers } from 'next/headers';\nimport { DESCOPE_SESSION_HEADER } from './constants';\n\nconst extractSession = (\n\tdescopeSession?: string\n): AuthenticationInfo | undefined => {\n\tif (!descopeSession) {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\tconst authInfo = JSON.parse(\n\t\t\tBuffer.from(descopeSession, 'base64').toString()\n\t\t) as AuthenticationInfo;\n\t\treturn authInfo;\n\t} catch (err) {\n\t\treturn undefined;\n\t}\n};\n// returns the session token if it exists in the headers\n// This function require middleware\nexport const session = (): AuthenticationInfo | undefined => {\n\tconst sessionHeader = headers()?.get(DESCOPE_SESSION_HEADER);\n\treturn extractSession(sessionHeader);\n};\n\n// returns the session token if it exists in the request headers\n// This function require middleware\nexport const getSession = (\n\treq: NextApiRequest\n): AuthenticationInfo | undefined =>\n\textractSession(req.headers[DESCOPE_SESSION_HEADER.toLowerCase()] as string);\n"],"names":[],"mappings":";;;AAKA,MAAM,cAAc,GAAG,CACtB,cAAuB,KACY;IACnC,IAAI,CAAC,cAAc,EAAE;AACpB,QAAA,OAAO,SAAS,CAAC;AACjB,KAAA;IACD,IAAI;AACH,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAC1B,CAAC;AACxB,QAAA,OAAO,QAAQ,CAAC;AAChB,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACb,QAAA,OAAO,SAAS,CAAC;AACjB,KAAA;AACF,CAAC,CAAC;AACF;AACA;AACO,MAAM,OAAO,GAAG,MAAqC;IAC3D,MAAM,aAAa,GAAG,OAAO,EAAE,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAC7D,IAAA,OAAO,cAAc,CAAC,aAAa,CAAC,CAAC;AACtC,EAAE;AAEF;AACA;MACa,UAAU,GAAG,CACzB,GAAmB,KAEnB,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,WAAW,EAAE,CAAW;;;;"}
@@ -0,0 +1,22 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ /*
3
+ Merges multiple search params into one.
4
+ It will override according to the order of the search params
5
+ Examples:
6
+ - mergeSearchParams('?a=1', '?b=2') => 'a=1&b=2'
7
+ - mergeSearchParams('?a=1', '?a=2') => 'a=2'
8
+ - mergeSearchParams('?a=1', '?a=2', '?b=3') => 'a=2&b=3'
9
+ */
10
+ const mergeSearchParams = (...searchParams) => {
11
+ const res = searchParams.reduce((acc, curr) => {
12
+ const currParams = new URLSearchParams(curr);
13
+ currParams.forEach((value, key) => {
14
+ acc.set(key, value);
15
+ });
16
+ return acc;
17
+ }, new URLSearchParams());
18
+ return res.toString();
19
+ };
20
+
21
+ export { mergeSearchParams };
22
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\n\n/*\nMerges multiple search params into one.\nIt will override according to the order of the search params\nExamples:\n - mergeSearchParams('?a=1', '?b=2') => 'a=1&b=2'\n - mergeSearchParams('?a=1', '?a=2') => 'a=2'\n - mergeSearchParams('?a=1', '?a=2', '?b=3') => 'a=2&b=3'\n*/\nexport const mergeSearchParams = (...searchParams: string[]): string => {\n\tconst res = searchParams.reduce((acc, curr) => {\n\t\tconst currParams = new URLSearchParams(curr);\n\t\tcurrParams.forEach((value, key) => {\n\t\t\tacc.set(key, value);\n\t\t});\n\t\treturn acc;\n\t}, new URLSearchParams());\n\n\treturn res.toString();\n};\n"],"names":[],"mappings":"AAAA;AAEA;;;;;;;AAOE;MACW,iBAAiB,GAAG,CAAC,GAAG,YAAsB,KAAY;IACtE,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAI;AAC7C,QAAA,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QAC7C,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,KAAI;AACjC,YAAA,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACrB,SAAC,CAAC,CAAC;AACH,QAAA,OAAO,GAAG,CAAC;AACZ,KAAC,EAAE,IAAI,eAAe,EAAE,CAAC,CAAC;AAE1B,IAAA,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACvB;;;;"}
@@ -1,9 +1,8 @@
1
- const DESCOPE_SESSION_HEADER = 'x-descope-session';
2
1
  // eslint-disable-next-line import/prefer-default-export
3
2
  const baseHeaders = {
4
3
  'x-descope-sdk-name': 'nextjs',
5
- 'x-descope-sdk-version': "0.0.3-alpha.1"
4
+ 'x-descope-sdk-version': "0.0.4"
6
5
  };
7
6
 
8
- export { DESCOPE_SESSION_HEADER, baseHeaders };
7
+ export { baseHeaders };
9
8
  //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../src/shared/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":"AAGA;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,OAAa;;;;;"}
@@ -1,7 +1,10 @@
1
1
  "use client";
2
2
  import React from 'react';
3
- import { AuthProvider as AuthProvider$1 } from '@descope/react-sdk';
3
+ import { baseHeaders, AuthProvider as AuthProvider$1 } from '@descope/react-sdk';
4
+ import { baseHeaders as baseHeaders$1 } from './constants.js';
4
5
 
6
+ // Override baseHeaders
7
+ Object.assign(baseHeaders, baseHeaders$1);
5
8
  const AuthProvider = (props) => (
6
9
  // by default we use sessionTokenViaCookie, so middleware will work out of the box
7
10
  React.createElement(AuthProvider$1, { sessionTokenViaCookie: true, ...props }));
@@ -1 +1 @@
1
- {"version":3,"file":"AuthProvider.js","sources":["../../src/shared/AuthProvider.tsx"],"sourcesContent":["'use client';\n\nimport React, { ComponentProps } from 'react';\n\nimport { AuthProvider as AuthProviderComp } from '@descope/react-sdk';\n\nconst AuthProvider = (props: ComponentProps<typeof AuthProviderComp>) => (\n\t// by default we use sessionTokenViaCookie, so middleware will work out of the box\n\t<AuthProviderComp sessionTokenViaCookie {...props} />\n);\n\nexport default AuthProvider;\n"],"names":[],"mappings":";;;;AAMA;AACC;AACA;;"}
1
+ {"version":3,"file":"AuthProvider.js","sources":["../../src/shared/AuthProvider.tsx"],"sourcesContent":["'use client';\n\nimport React, { ComponentProps } from 'react';\nimport {\n\tAuthProvider as AuthProviderComp,\n\tbaseHeaders\n} from '@descope/react-sdk';\nimport { baseHeaders as nextBaseHeaders } from './constants';\n\n// Override baseHeaders\nObject.assign(baseHeaders, nextBaseHeaders);\n\nconst AuthProvider = (props: ComponentProps<typeof AuthProviderComp>) => (\n\t// by default we use sessionTokenViaCookie, so middleware will work out of the box\n\t<AuthProviderComp sessionTokenViaCookie {...props} />\n);\n\nexport default AuthProvider;\n"],"names":[],"mappings":";;;;;AASA;AACA;AAEA;AACC;AACA;;"}
@@ -2,12 +2,15 @@
2
2
  import React from 'react';
3
3
  import dynamic from 'next/dynamic';
4
4
  import { useRouter } from 'next/navigation';
5
+ import { baseHeaders } from './constants.js';
5
6
 
6
7
  // Generalized function to dynamically import components from @descope/react-sdk
7
8
  // Dynamic is needed because the Descope components has a side effect us
8
9
  // and NextJS will load the page on the server even if it is a client side only page
9
10
  const dynamicDescopeComponent = (componentName) => dynamic(async () => {
10
11
  const DescopeComponents = await import('@descope/react-sdk');
12
+ // Override baseHeaders
13
+ Object.assign(DescopeComponents.baseHeaders, baseHeaders);
11
14
  const Component = DescopeComponents[componentName];
12
15
  return ({ redirectAfterSuccess = '', redirectAfterError = '', ...props }) => {
13
16
  const router = useRouter();
@@ -1 +1 @@
1
- {"version":3,"file":"DescopeFlows.js","sources":["../../src/shared/DescopeFlows.tsx"],"sourcesContent":["'use client';\n\nimport React, { ComponentType, ComponentProps } from 'react';\nimport dynamic from 'next/dynamic';\nimport { useRouter } from 'next/navigation';\nimport {\n\tDescope as DescopeWC,\n\tSignInFlow as SignInFlowWC,\n\tSignUpFlow as SignUpFlowWC,\n\tSignUpOrInFlow as SignUpOrInFlowWC\n} from '@descope/react-sdk';\n\ntype DescopeWCProps = ComponentProps<typeof DescopeWC>;\ntype SignInFlowProps = ComponentProps<typeof SignInFlowWC>;\ntype SignUpFlowProps = ComponentProps<typeof SignUpFlowWC>;\ntype SignUpOrInFlowProps = ComponentProps<typeof SignUpOrInFlowWC>;\n\ntype AdditionalProps = {\n\tredirectAfterSuccess?: string;\n\tredirectAfterError?: string;\n};\n\ntype DynamicComponentProps = {\n\tonSuccess?: (...args: any[]) => void;\n\tonError?: (...args: any[]) => void;\n};\n\n// Generalized function to dynamically import components from @descope/react-sdk\n// Dynamic is needed because the Descope components has a side effect us\n// and NextJS will load the page on the server even if it is a client side only page\nconst dynamicDescopeComponent = <\n\tT extends ComponentType<DynamicComponentProps>\n>(\n\tcomponentName: string\n) =>\n\tdynamic<ComponentProps<T> & AdditionalProps>(\n\t\tasync () => {\n\t\t\tconst DescopeComponents = await import('@descope/react-sdk');\n\t\t\tconst Component = DescopeComponents[componentName];\n\t\t\treturn ({\n\t\t\t\tredirectAfterSuccess = '',\n\t\t\t\tredirectAfterError = '',\n\t\t\t\t...props\n\t\t\t}: ComponentProps<T> & AdditionalProps) => {\n\t\t\t\tconst router = useRouter();\n\t\t\t\tconst modifiedProps = { ...props };\n\n\t\t\t\tif (redirectAfterSuccess) {\n\t\t\t\t\tmodifiedProps.onSuccess = (...args) => {\n\t\t\t\t\t\tif (props.onSuccess) {\n\t\t\t\t\t\t\tprops.onSuccess(...args);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trouter.push(redirectAfterSuccess);\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (redirectAfterError) {\n\t\t\t\t\tmodifiedProps.onError = (...args) => {\n\t\t\t\t\t\tif (props.onError) {\n\t\t\t\t\t\t\tprops.onError(...args);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trouter.push(redirectAfterError);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn <Component {...modifiedProps} />;\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\tssr: false\n\t\t}\n\t);\n\nexport const Descope =\n\tdynamicDescopeComponent<React.ComponentType<DescopeWCProps>>('Descope');\nexport const SignInFlow =\n\tdynamicDescopeComponent<React.ComponentType<SignInFlowProps>>('SignInFlow');\nexport const SignUpFlow =\n\tdynamicDescopeComponent<React.ComponentType<SignUpFlowProps>>('SignUpFlow');\nexport const SignUpOrInFlow =\n\tdynamicDescopeComponent<React.ComponentType<SignUpOrInFlowProps>>(\n\t\t'SignUpOrInFlow'\n\t);\n"],"names":[],"mappings":";;;;;AA2BA;AACA;AACA;AACA;AAOG;AACA;AACA;AAKC;AACA;AAEA;AACC;;AAEE;AACA;AACD;AACD;AACA;AAED;AACC;;AAEE;AACA;AACD;AACD;AACA;AACD;AACD;AACD;AAEC;AACA;;;;;;"}
1
+ {"version":3,"file":"DescopeFlows.js","sources":["../../src/shared/DescopeFlows.tsx"],"sourcesContent":["'use client';\n\nimport React, { ComponentType, ComponentProps } from 'react';\nimport dynamic from 'next/dynamic';\nimport { useRouter } from 'next/navigation';\nimport {\n\tDescope as DescopeWC,\n\tSignInFlow as SignInFlowWC,\n\tSignUpFlow as SignUpFlowWC,\n\tSignUpOrInFlow as SignUpOrInFlowWC\n} from '@descope/react-sdk';\nimport { baseHeaders as nextBaseHeaders } from './constants';\n\ntype DescopeWCProps = ComponentProps<typeof DescopeWC>;\ntype SignInFlowProps = ComponentProps<typeof SignInFlowWC>;\ntype SignUpFlowProps = ComponentProps<typeof SignUpFlowWC>;\ntype SignUpOrInFlowProps = ComponentProps<typeof SignUpOrInFlowWC>;\n\ntype AdditionalProps = {\n\tredirectAfterSuccess?: string;\n\tredirectAfterError?: string;\n};\n\ntype DynamicComponentProps = {\n\tonSuccess?: (...args: any[]) => void;\n\tonError?: (...args: any[]) => void;\n};\n\n// Generalized function to dynamically import components from @descope/react-sdk\n// Dynamic is needed because the Descope components has a side effect us\n// and NextJS will load the page on the server even if it is a client side only page\nconst dynamicDescopeComponent = <\n\tT extends ComponentType<DynamicComponentProps>\n>(\n\tcomponentName: string\n) =>\n\tdynamic<ComponentProps<T> & AdditionalProps>(\n\t\tasync () => {\n\t\t\tconst DescopeComponents = await import('@descope/react-sdk');\n\n\t\t\t// Override baseHeaders\n\t\t\tObject.assign(DescopeComponents.baseHeaders, nextBaseHeaders);\n\n\t\t\tconst Component = DescopeComponents[componentName];\n\t\t\treturn ({\n\t\t\t\tredirectAfterSuccess = '',\n\t\t\t\tredirectAfterError = '',\n\t\t\t\t...props\n\t\t\t}: ComponentProps<T> & AdditionalProps) => {\n\t\t\t\tconst router = useRouter();\n\t\t\t\tconst modifiedProps = { ...props };\n\n\t\t\t\tif (redirectAfterSuccess) {\n\t\t\t\t\tmodifiedProps.onSuccess = (...args) => {\n\t\t\t\t\t\tif (props.onSuccess) {\n\t\t\t\t\t\t\tprops.onSuccess(...args);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trouter.push(redirectAfterSuccess);\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (redirectAfterError) {\n\t\t\t\t\tmodifiedProps.onError = (...args) => {\n\t\t\t\t\t\tif (props.onError) {\n\t\t\t\t\t\t\tprops.onError(...args);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trouter.push(redirectAfterError);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn <Component {...modifiedProps} />;\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\tssr: false\n\t\t}\n\t);\n\nexport const Descope =\n\tdynamicDescopeComponent<React.ComponentType<DescopeWCProps>>('Descope');\nexport const SignInFlow =\n\tdynamicDescopeComponent<React.ComponentType<SignInFlowProps>>('SignInFlow');\nexport const SignUpFlow =\n\tdynamicDescopeComponent<React.ComponentType<SignUpFlowProps>>('SignUpFlow');\nexport const SignUpOrInFlow =\n\tdynamicDescopeComponent<React.ComponentType<SignUpOrInFlowProps>>(\n\t\t'SignUpOrInFlow'\n\t);\n"],"names":[],"mappings":";;;;;;AA4BA;AACA;AACA;AACA;AAOG;;;AAKA;AACA;AAKC;AACA;AAEA;AACC;;AAEE;AACA;AACD;AACD;AACA;AAED;AACC;;AAEE;AACA;AACD;AACD;AACA;AACD;AACD;AACD;AAEC;AACA;;;;;;"}
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import dynamic from 'next/dynamic';
3
+ import { UserManagement as UserManagement$1, RoleManagement as RoleManagement$1, AccessKeyManagement as AccessKeyManagement$1 } from '@descope/react-sdk';
4
+
5
+ // a helper function to dynamically load the components
6
+ // This function prevents Next.js from trying to server-side render these components
7
+ // Update the helper function to use generics for preserving component prop types
8
+ const dynamicWidgetComponent = (Component) => dynamic(() => Promise.resolve(Component), {
9
+ ssr: false // Disable server-side rendering for this component
10
+ });
11
+ // Use the helper function to create dynamically loaded components
12
+ const UserManagement = dynamicWidgetComponent(UserManagement$1);
13
+ const RoleManagement = dynamicWidgetComponent(RoleManagement$1);
14
+ const AccessKeyManagement = dynamicWidgetComponent(AccessKeyManagement$1);
15
+
16
+ export { AccessKeyManagement, RoleManagement, UserManagement };
17
+ //# sourceMappingURL=DescopeWidgets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DescopeWidgets.js","sources":["../../src/shared/DescopeWidgets.tsx"],"sourcesContent":["'use client';\n\nimport { ComponentType } from 'react';\nimport dynamic from 'next/dynamic';\nimport {\n\tUserManagement as UserManagementWC,\n\tRoleManagement as RoleManagementWC,\n\tAccessKeyManagement as AccessKeyManagementWC\n} from '@descope/react-sdk';\n\n// a helper function to dynamically load the components\n// This function prevents Next.js from trying to server-side render these components\n// Update the helper function to use generics for preserving component prop types\nconst dynamicWidgetComponent = <P extends {}>(Component: ComponentType<P>) =>\n\tdynamic<P>(() => Promise.resolve(Component), {\n\t\tssr: false // Disable server-side rendering for this component\n\t});\n\n// Use the helper function to create dynamically loaded components\nexport const UserManagement = dynamicWidgetComponent(UserManagementWC);\nexport const RoleManagement = dynamicWidgetComponent(RoleManagementWC);\nexport const AccessKeyManagement = dynamicWidgetComponent(\n\tAccessKeyManagementWC\n);\n"],"names":[],"mappings":";;;;AAUA;AACA;AACA;AACA;;AAGE;AAEF;;;;;"}
@@ -0,0 +1,8 @@
1
+ // eslint-disable-next-line import/prefer-default-export
2
+ const baseHeaders = {
3
+ 'x-descope-sdk-name': 'nextjs',
4
+ 'x-descope-sdk-version': "0.0.4"
5
+ };
6
+
7
+ export { baseHeaders };
8
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../src/shared/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":"AAGA;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,OAAa;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope/nextjs-sdk",
3
- "version": "0.0.3-alpha.1",
3
+ "version": "0.0.4",
4
4
  "description": "Descope NextJS SDK",
5
5
  "author": "Descope Team <info@descope.com>",
6
6
  "homepage": "https://github.com/descope/nextjs-sdk",
@@ -59,7 +59,7 @@
59
59
  "format-check": "prettier . --check --ignore-path .gitignore",
60
60
  "leaks": "bash ./scripts/gitleaks/gitleaks.sh",
61
61
  "lint": "npm run lint-check -- --fix",
62
- "lint-check": "eslint '+(src)/**/*.+(ts|tsx)'",
62
+ "lint-check": "eslint '+(src|test)/**/*.+(ts|tsx)'",
63
63
  "prepare": "husky install",
64
64
  "prepublishOnly": "npm run build",
65
65
  "start": "npm run build && (cd examples/app-router && npm run dev)",
@@ -73,8 +73,8 @@
73
73
  ]
74
74
  },
75
75
  "dependencies": {
76
- "@descope/node-sdk": "1.6.2",
77
- "@descope/react-sdk": "2.0.6"
76
+ "@descope/node-sdk": "1.6.6",
77
+ "@descope/react-sdk": "2.0.10"
78
78
  },
79
79
  "devDependencies": {
80
80
  "@babel/core": "7.23.9",
@@ -89,6 +89,7 @@
89
89
  "@swc/core": "^1.4.0",
90
90
  "@testing-library/jest-dom": "^6.4.2",
91
91
  "@testing-library/react": "^14.2.1",
92
+ "@types/jest": "^29.5.12",
92
93
  "@types/react": "17.0.75",
93
94
  "@types/react-dom": "18.2.18",
94
95
  "@types/react-router-dom": "^5.3.3",
@@ -1 +0,0 @@
1
- {"version":3,"file":"authMiddleware.js","sources":["../../src/server/authMiddleware.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport { NextRequest, NextResponse } from 'next/server';\nimport descopeSdk from '@descope/node-sdk';\nimport type { AuthenticationInfo } from '@descope/node-sdk';\nimport { DESCOPE_SESSION_HEADER } from './constants';\nimport { getGlobalSdk } from './sdk';\n\ntype MiddlewareOptions = {\n\t// The Descope project ID to use for authentication\n\t// Defaults to process.env.DESCOPE_PROJECT_ID\n\tprojectId?: string;\n\n\t// The URL to redirect to if the user is not authenticated\n\t// Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided\n\tredirectUrl?: string;\n\n\t// An array of public routes that do not require authentication\n\t// In addition to the default public routes:\n\t// - process.env.SIGN_IN_ROUTE or /sign-in if not provided\n\t// - process.env.SIGN_UP_ROUTE or /sign-up if not provided\n\tpublicRoutes?: string[];\n};\n\nconst getSessionJwt = (req: NextRequest): string | undefined => {\n\tlet jwt = req.headers?.get('Authorization')?.split(' ')[1];\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\n\tjwt = req.cookies?.get(descopeSdk.SessionTokenCookieName)?.value;\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\treturn undefined;\n};\n\nconst defaultPublicRoutes = {\n\tsignIn: process.env.SIGN_IN_ROUTE || '/sign-in',\n\tsignUp: process.env.SIGN_UP_ROUTE || '/sign-up'\n};\n\nconst isPublicRoute = (req: NextRequest, options: MiddlewareOptions) => {\n\tconst isDefaultPublicRoute = Object.values(defaultPublicRoutes).includes(\n\t\treq.nextUrl.pathname\n\t);\n\tconst isPublic = options.publicRoutes?.includes(req.nextUrl.pathname);\n\n\treturn isDefaultPublicRoute || isPublic;\n};\n\nconst addSessionToHeadersIfExists = (\n\theaders: Headers,\n\tsession: AuthenticationInfo | undefined\n): Headers => {\n\tif (session) {\n\t\tconst requestHeaders = new Headers(headers);\n\t\trequestHeaders.set(\n\t\t\tDESCOPE_SESSION_HEADER,\n\t\t\tBuffer.from(JSON.stringify(session)).toString('base64')\n\t\t);\n\t\treturn requestHeaders;\n\t}\n\treturn headers;\n};\n\n// returns a Middleware that checks if the user is authenticated\n// if the user is not authenticated, it redirects to the redirectUrl\n// if the user is authenticated, it adds the session to the headers\nconst createAuthMiddleware =\n\t(options: MiddlewareOptions = {}) =>\n\tasync (req: NextRequest) => {\n\t\tconsole.debug('Auth middleware starts');\n\n\t\tconst jwt = getSessionJwt(req);\n\n\t\t// check if the user is authenticated\n\t\tlet session: AuthenticationInfo | undefined;\n\t\ttry {\n\t\t\tsession = await getGlobalSdk({\n\t\t\t\tprojectId: options.projectId\n\t\t\t}).validateJwt(jwt);\n\t\t} catch (err) {\n\t\t\tconsole.debug('Auth middleware, Failed to validate JWT', err);\n\t\t\tif (!isPublicRoute(req, options)) {\n\t\t\t\tconst defaultRedirectUrl =\n\t\t\t\t\toptions.redirectUrl || defaultPublicRoutes.signIn;\n\t\t\t\tconst url = req.nextUrl.clone();\n\t\t\t\turl.pathname = defaultRedirectUrl;\n\t\t\t\tconsole.debug(`Auth middleware, Redirecting to ${url}`);\n\t\t\t\treturn NextResponse.redirect(url);\n\t\t\t}\n\t\t}\n\n\t\tconsole.debug('Auth middleware finishes');\n\t\t// add the session to the request, if it exists\n\t\tconst headers = addSessionToHeadersIfExists(req.headers, session);\n\t\treturn NextResponse.next({\n\t\t\trequest: {\n\t\t\t\theaders\n\t\t\t}\n\t\t});\n\t};\n\nexport default createAuthMiddleware;\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sources":["../../src/server/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\nexport const DESCOPE_SESSION_HEADER = 'x-descope-session';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":"AAGO,MAAM,sBAAsB,GAAG,oBAAoB;AAE1D;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,eAAa;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sdk.js","sources":["../../src/server/sdk.ts"],"sourcesContent":["import descopeSdk from '@descope/node-sdk';\nimport { baseHeaders } from './constants';\n\ntype Sdk = ReturnType<typeof descopeSdk>;\ntype CreateSdkParams = Omit<Parameters<typeof descopeSdk>[0], 'projectId'> & {\n\tprojectId?: string | undefined;\n};\n\nlet globalSdk: Sdk;\n\nexport const createSdk = (config?: CreateSdkParams): Sdk =>\n\tdescopeSdk({\n\t\t...config,\n\t\tprojectId: config.projectId || process.env.DESCOPE_PROJECT_ID,\n\t\tmanagementKey: config.managementKey || process.env.DESCOPE_MANAGEMENT_KEY,\n\t\tbaseUrl: config.baseUrl || process.env.DESCOPE_BASE_URL,\n\t\tbaseHeaders: {\n\t\t\t...config?.baseHeaders,\n\t\t\t...baseHeaders\n\t\t}\n\t});\n\nexport const getGlobalSdk = (\n\tconfig?: Pick<CreateSdkParams, 'projectId'>\n): Sdk => {\n\tif (!globalSdk) {\n\t\tif (!config?.projectId && !process.env.DESCOPE_PROJECT_ID) {\n\t\t\tthrow new Error('Descope project ID is required to create the SDK');\n\t\t}\n\t\tglobalSdk = createSdk(config);\n\t}\n\n\treturn globalSdk;\n};\n"],"names":[],"mappings":";;;AAQA,IAAI,SAAc,CAAC;AAEN,MAAA,SAAS,GAAG,CAAC,MAAwB,KACjD,UAAU,CAAC;AACV,IAAA,GAAG,MAAM;IACT,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;IAC7D,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB;IACzE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;AACvD,IAAA,WAAW,EAAE;QACZ,GAAG,MAAM,EAAE,WAAW;AACtB,QAAA,GAAG,WAAW;AACd,KAAA;AACD,CAAA,EAAE;AAES,MAAA,YAAY,GAAG,CAC3B,MAA2C,KACnC;IACR,IAAI,CAAC,SAAS,EAAE;QACf,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE;AAC1D,YAAA,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;AACpE,SAAA;AACD,QAAA,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAC9B,KAAA;AAED,IAAA,OAAO,SAAS,CAAC;AAClB;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"session.js","sources":["../../src/server/session.ts"],"sourcesContent":["import { AuthenticationInfo } from '@descope/node-sdk';\nimport { NextApiRequest } from 'next';\nimport { headers } from 'next/headers';\nimport { DESCOPE_SESSION_HEADER } from './constants';\n\nconst extractSession = (\n\tdescopeSession?: string\n): AuthenticationInfo | undefined => {\n\tif (!descopeSession) {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\tconst authInfo = JSON.parse(\n\t\t\tBuffer.from(descopeSession, 'base64').toString()\n\t\t) as AuthenticationInfo;\n\t\treturn authInfo;\n\t} catch (err) {\n\t\treturn undefined;\n\t}\n};\n// returns the session token if it exists in the headers\n// This function require middleware\nexport const session = (): AuthenticationInfo | undefined =>\n\textractSession(headers()?.get(DESCOPE_SESSION_HEADER));\n\n// returns the session token if it exists in the request headers\n// This function require middleware\nexport const getSession = (\n\treq: NextApiRequest\n): AuthenticationInfo | undefined =>\n\textractSession(req.headers[DESCOPE_SESSION_HEADER.toLowerCase()] as string);\n"],"names":[],"mappings":";;;AAKA,MAAM,cAAc,GAAG,CACtB,cAAuB,KACY;IACnC,IAAI,CAAC,cAAc,EAAE;AACpB,QAAA,OAAO,SAAS,CAAC;AACjB,KAAA;IACD,IAAI;AACH,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAC1B,CAAC;AACxB,QAAA,OAAO,QAAQ,CAAC;AAChB,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACb,QAAA,OAAO,SAAS,CAAC;AACjB,KAAA;AACF,CAAC,CAAC;AACF;AACA;AACa,MAAA,OAAO,GAAG,MACtB,cAAc,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,sBAAsB,CAAC,EAAE;AAExD;AACA;MACa,UAAU,GAAG,CACzB,GAAmB,KAEnB,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,WAAW,EAAE,CAAW;;;;"}
File without changes