@monocloud/auth-nextjs 0.1.5 → 0.1.7

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.
@@ -0,0 +1,563 @@
1
+ import { Authenticators, AuthorizationParams, DisplayOptions, MonoCloudUser, Prompt } from "@monocloud/auth-node-core";
2
+ import { JSX } from "react";
3
+ import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
4
+ import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult, NextApiRequest, NextApiResponse } from "next/types";
5
+ import { ParsedUrlQuery } from "node:querystring";
6
+
7
+ //#region src/types.d.ts
8
+ /**
9
+ * Context object provided to App Router route handlers.
10
+ *
11
+ * Contains dynamic route parameters resolved from the matched route segment (for example, `[id]` or `[...slug]`).
12
+ *
13
+ * In streaming or async environments, `params` may be provided as a Promise.
14
+ *
15
+ * @category Types
16
+ */
17
+ interface AppRouterContext {
18
+ /**
19
+ * Dynamic route parameters extracted from the request URL.
20
+ */
21
+ params: Record<string, string | string[]> | Promise<Record<string, string | string[]>>;
22
+ }
23
+ /**
24
+ * Handler function returned by `monoCloudAuth()`.
25
+ *
26
+ * This handler processes authentication routes such as sign-in, callback, sign-out, and userinfo across supported Next.js runtimes (App Router, Pages Router, and API routes).
27
+ *
28
+ * @category Types (Handler)
29
+ */
30
+ type MonoCloudAuthHandler = (
31
+ /**
32
+ * Incoming request object.
33
+ */
34
+
35
+ req: Request | NextRequest | NextApiRequest,
36
+ /**
37
+ * Response object or App Router context.
38
+ */
39
+
40
+ resOrCtx?: Response | NextResponse<any> | NextApiResponse<any> | AppRouterContext) => Promise<Response | NextResponse | void | any>;
41
+ /**
42
+ * Possible return values from a Next.js middleware or proxy handler.
43
+ *
44
+ * @category Types
45
+ */
46
+ type NextMiddlewareResult = NextResponse | Response | null | undefined | void;
47
+ /**
48
+ * Handler invoked when access is denied during Next.js middleware execution.
49
+ *
50
+ * This callback allows you to customize how unauthenticated or unauthorized requests are handled, for example by redirecting, rewriting, or returning a custom response.
51
+ *
52
+ * @category Types (Handler)
53
+ *
54
+ * @param request The incoming Next.js request.
55
+ * @param event The associated Next.js fetch event.
56
+ * @returns A middleware result that determines how the request should proceed.
57
+ */
58
+ type NextMiddlewareOnAccessDenied = (request: NextRequest, event: NextFetchEvent) => NextMiddlewareResult | Promise<NextMiddlewareResult>;
59
+ /**
60
+ * Handler invoked when an authenticated user is denied access during Next.js middleware execution due to group authorization rules.
61
+ *
62
+ * This callback allows you to customize how authorization failures are handled, for example by redirecting, rewriting, or returning a custom response.
63
+ *
64
+ * @category Types (Handler)
65
+ *
66
+ * @param request The incoming Next.js request.
67
+ * @param event The associated Next.js fetch event.
68
+ * @param user The authenticated user who failed the group authorization check.
69
+ * @returns A middleware result that determines how the request should proceed.
70
+ */
71
+ type NextMiddlewareOnGroupAccessDenied = (request: NextRequest, event: NextFetchEvent, user: MonoCloudUser) => NextMiddlewareResult | Promise<NextMiddlewareResult>;
72
+ /**
73
+ *
74
+ * Defines how routes are matched and protected by authentication and optional group-based authorization.
75
+ *
76
+ * @category Types
77
+ *
78
+ */
79
+ type ProtectedRouteMatcher = string | RegExp | {
80
+ /**
81
+ * Route patterns that should be protected.
82
+ *
83
+ * Each entry may be:
84
+ * - A relative route path
85
+ * - A regular expression used to match routes
86
+ */
87
+ routes: (string | RegExp)[];
88
+ /**
89
+ * Optional group-based access control.
90
+ *
91
+ * When provided, only users belonging to **at least one** of the specified group IDs or names are allowed access.
92
+ */
93
+ groups: string[];
94
+ };
95
+ /**
96
+ * Function used to dynamically determine whether a request should be treated as a protected route.
97
+ *
98
+ * @category Types (Handler)
99
+ *
100
+ * @param req The incoming Next.js request.
101
+ * @returns Return `true` to require authentication for the request, or `false` to allow it to continue without protection.
102
+ */
103
+ type CustomProtectedRouteMatcher = (req: NextRequest) => Promise<boolean> | boolean;
104
+ /**
105
+ * Handler invoked when an error occurs during execution of an App Router endpoint.
106
+ *
107
+ * Allows custom error handling such as logging, transforming the response, or returning a custom `NextResponse`
108
+ *
109
+ * @category Types (Handler)
110
+ *
111
+ * @param req The incoming Next.js request.
112
+ * @param ctx The App Router context containing dynamic route parameters.
113
+ * @param error The error thrown during endpoint execution.
114
+ * @returns Returns a `NextResponse` or `void`.
115
+ */
116
+ type AppOnError<T = any> = (req: NextRequest, ctx: T, error: Error) => Promise<NextResponse | void> | NextResponse | void;
117
+ /**
118
+ * Handler invoked when an error occurs during execution of a Pages Router API endpoint.
119
+ *
120
+ * Allows custom error handling such as logging, modifying the response, or sending a custom error payload.
121
+ *
122
+ * @category Types (Handler)
123
+ *
124
+ * @param req The incoming Next.js API request.
125
+ * @param res The outgoing Next.js API response.
126
+ * @param error The error thrown during endpoint execution.
127
+ * @returns Returns `void` or a Promise that resolves when error handling is complete.
128
+ */
129
+ type PageOnError = (req: NextApiRequest, res: NextApiResponse, error: Error) => Promise<void> | void;
130
+ /**
131
+ * Error handler invoked when an exception occurs during execution of the sign-in, callback, sign-out, or userinfo endpoints.
132
+ *
133
+ * > - In the **App Router**, you must either return a `NextResponse` or throw an error. Otherwise, the request will remain unresolved.
134
+ * > - In the **Pages Router**, you must send a response (for example, `res.send()` or `res.json()`) after handling the error, or the request will hang.
135
+ *
136
+ * @category Types (Handler)
137
+ */
138
+ type OnError = AppOnError | PageOnError;
139
+ /**
140
+ * Options for `monoCloudAuth()`.
141
+ *
142
+ * @category Types
143
+ */
144
+ interface MonoCloudAuthOptions {
145
+ /**
146
+ * Optional error handler invoked when an exception occurs during execution of the sign-in, callback, sign-out, or userinfo endpoints.
147
+ */
148
+ onError?: OnError;
149
+ }
150
+ /**
151
+ * Configuration used to determine which routes require authentication.
152
+ *
153
+ * You can provide:
154
+ *
155
+ * - An array of {@link ProtectedRouteMatcher} values to declaratively define protected routes.
156
+ * - A {@link CustomProtectedRouteMatcher} function for fully dynamic protection logic.
157
+ *
158
+ * @category Types
159
+ */
160
+ type ProtectedRoutes = ProtectedRouteMatcher[] | CustomProtectedRouteMatcher;
161
+ /**
162
+ * Options for configuring the MonoCloud authentication middleware.
163
+ *
164
+ * These options control which routes are protected and how authentication and authorization failures are handled during request processing.
165
+ *
166
+ * @category Types
167
+ */
168
+ interface MonoCloudMiddlewareOptions {
169
+ /**
170
+ * Error handler invoked when an error occurs during execution of authentication endpoints handled by the middleware.
171
+ *
172
+ * @param req The incoming Next.js request.
173
+ * @param evt The associated Next.js fetch event.
174
+ * @param error The error thrown during execution.
175
+ * @returns Returns a response to continue the middleware chain, or `void`.
176
+ */
177
+ onError?: (req: NextRequest, evt: NextFetchEvent, error: Error) => Promise<NextResponse | void> | NextResponse | void;
178
+ /**
179
+ * Defines which routes require authentication.
180
+ *
181
+ * Accepts either an array of {@link ProtectedRouteMatcher} or a {@link CustomProtectedRouteMatcher}.
182
+ *
183
+ * - If omitted, all routes matched by the middleware config are protected.
184
+ * - If an empty array is provided, no routes are protected.
185
+ */
186
+ protectedRoutes?: ProtectedRoutes;
187
+ /**
188
+ * Name of the claim in the user profile that contains group memberships.
189
+ *
190
+ * @defaultValue 'groups'
191
+ */
192
+ groupsClaim?: string;
193
+ /**
194
+ * When `true`, the user must belong to **all** specified groups for authorization to succeed. Otherwise, membership in any one group is sufficient.
195
+ *
196
+ * @defaultValue false
197
+ */
198
+ matchAll?: boolean;
199
+ /**
200
+ * Middleware handler invoked when the user is not authenticated.
201
+ */
202
+ onAccessDenied?: NextMiddlewareOnAccessDenied;
203
+ /**
204
+ * Middleware handler invoked when the user is authenticated but does not satisfy group authorization requirements.
205
+ */
206
+ onGroupAccessDenied?: NextMiddlewareOnGroupAccessDenied;
207
+ }
208
+ /**
209
+ * A subset of authorization parameters supported by client-side helpers.
210
+ *
211
+ * @category Types
212
+ */
213
+ interface ExtraAuthParams extends Pick<AuthorizationParams, 'scopes' | 'resource' | 'prompt' | 'display' | 'uiLocales' | 'acrValues' | 'authenticatorHint' | 'maxAge' | 'loginHint'> {}
214
+ /**
215
+ * Represents a Next.js App Router page component (Server Component).
216
+ *
217
+ * @category Types (Handler)
218
+ *
219
+ * @param props Page props provided by Next.js, including dynamic route parameters and URL search parameters.
220
+ * @returns A JSX element, or a Promise resolving to one.
221
+ */
222
+ type AppRouterPageHandler = (props: {
223
+ /**
224
+ * Dynamic route parameters extracted from the URL.
225
+ */
226
+ params?: Record<string, string | string[]>;
227
+ /**
228
+ * URL search parameters (`?key=value`) parsed by Next.js.
229
+ */
230
+ searchParams?: Record<string, string | string[] | undefined>;
231
+ }) => Promise<JSX.Element> | JSX.Element;
232
+ /**
233
+ * Represents a Next.js App Router Route Handler function.
234
+ *
235
+ * @category Types (Handler)
236
+ *
237
+ * @param req The incoming request object.
238
+ * @param ctx Route context containing dynamic route parameters.
239
+ * @returns A `Response` or `NextResponse`, or a Promise resolving to one.
240
+ */
241
+ type AppRouterApiHandlerFn = (req: NextRequest | Request, ctx: AppRouterContext) => Promise<Response | NextResponse> | Response | NextResponse;
242
+ /**
243
+ * Options for configuring `protectPage()` in the App Router.
244
+ *
245
+ * @category Types
246
+ */
247
+ interface ProtectAppPageOptions extends GroupOptions {
248
+ /**
249
+ * The URL the user should be returned to after successful authentication.
250
+ *
251
+ * Defaults to the current request URL.
252
+ */
253
+ returnUrl?: string;
254
+ /**
255
+ * Alternate Server Component rendered when the user is **not authenticated**.
256
+ *
257
+ * If not provided, the default behavior redirects the user to the sign-in flow.
258
+ */
259
+ onAccessDenied?: (props: {
260
+ params?: Record<string, string | string[]>;
261
+ searchParams?: Record<string, string | string[] | undefined>;
262
+ }) => Promise<JSX.Element> | JSX.Element;
263
+ /**
264
+ * Alternate Server Component rendered when the user is authenticated but does **not** belong to the required groups.
265
+ *
266
+ * Receives the resolved authenticated user.
267
+ */
268
+ onGroupAccessDenied?: (props: {
269
+ user: MonoCloudUser;
270
+ params?: Record<string, string | string[]>;
271
+ searchParams?: Record<string, string | string[] | undefined>;
272
+ }) => Promise<JSX.Element> | JSX.Element;
273
+ /**
274
+ * Additional authorization parameters applied when redirecting the user to authenticate.
275
+ */
276
+ authParams?: ExtraAuthParams;
277
+ }
278
+ /**
279
+ * Options for configuring `protectPage()` in the Pages Router.
280
+ *
281
+ * @category Types
282
+ *
283
+ * @typeParam P Props returned from `getServerSideProps`.
284
+ * @typeParam Q Query parameters parsed from the URL.
285
+ */
286
+ interface ProtectPagePageOptions<P extends Record<string, any> = Record<string, any>, Q extends ParsedUrlQuery = ParsedUrlQuery> extends GroupOptions {
287
+ /**
288
+ * An optional `getServerSideProps` implementation that runs after authentication (and group checks, if configured). Use this to compute additional props for the page.
289
+ */
290
+ getServerSideProps?: GetServerSideProps<P, Q>;
291
+ /**
292
+ * The URL the user should be returned to after successful authentication.
293
+ *
294
+ * Defaults to the current request URL.
295
+ */
296
+ returnUrl?: string;
297
+ /**
298
+ * Called when no valid session exists.
299
+ *
300
+ * If not provided, the default behavior redirects the user to the sign-in flow.
301
+ */
302
+ onAccessDenied?: ProtectPagePageOnAccessDeniedType<P, Q>;
303
+ /**
304
+ * Called when the user is authenticated but does not satisfy the group requirements.
305
+ *
306
+ * If not provided, the default behavior continues rendering and sets `groupAccessDenied` in the returned props, or applies the SDK’s default access-denied behavior.
307
+ */
308
+ onGroupAccessDenied?: ProtectPagePageOnGroupAccessDeniedType<P, Q>;
309
+ /**
310
+ * Additional authorization parameters applied when redirecting the user to authenticate.
311
+ */
312
+ authParams?: ExtraAuthParams;
313
+ }
314
+ /**
315
+ * Handler invoked when no valid session exists while running a Pages Router `getServerSideProps` protected by `protectPage()`.
316
+ *
317
+ * @category Types (Handler)
318
+ *
319
+ * @typeParam P Props returned from `getServerSideProps`.
320
+ * @typeParam Q Query parameters parsed from the URL.
321
+ * @param context The Next.js `getServerSideProps` context.
322
+ * @returns A `getServerSideProps` result.
323
+ */
324
+ type ProtectPagePageOnAccessDeniedType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q>) => Promise<GetServerSidePropsResult<P>> | GetServerSidePropsResult<P>;
325
+ /**
326
+ * Handler invoked when an authenticated user does not satisfy the required group restrictions while running a Pages Router `getServerSideProps` protected by `protectPage()`.
327
+ *
328
+ * @category Types (Handler)
329
+ *
330
+ * @typeParam P Props returned from `getServerSideProps`.
331
+ * @typeParam Q Query parameters parsed from the URL.
332
+ * @param context The Next.js `getServerSideProps` context.
333
+ * @returns A `getServerSideProps` result.
334
+ */
335
+ type ProtectPagePageOnGroupAccessDeniedType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q> & {
336
+ user: MonoCloudUser;
337
+ }) => Promise<GetServerSidePropsResult<P>> | GetServerSidePropsResult<P>;
338
+ /**
339
+ * Return type produced by the `protectPage()` wrapper for the Pages Router.
340
+ *
341
+ * Represents a `getServerSideProps` compatible function that resolves authentication before executing page logic and injects the authenticated `user` into the returned props.
342
+ *
343
+ * @category Types (Handler)
344
+ *
345
+ * @typeParam P Props returned from `getServerSideProps`.
346
+ * @typeParam Q Query parameters parsed from the URL.
347
+ */
348
+ type ProtectPagePageReturnType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q>) => Promise<GetServerSidePropsResult<P & {
349
+ user: MonoCloudUser;
350
+ accessDenied?: boolean;
351
+ }>>;
352
+ /**
353
+ * App Router Server Component wrapped by `protectPage()`.
354
+ *
355
+ * This component is only executed after authentication (and optional authorization) succeeds. The authenticated `user` is injected into the component props automatically.
356
+ *
357
+ * @category Types (Handler)
358
+ */
359
+ type ProtectedAppServerComponent = (props: {
360
+ /**
361
+ * The authenticated user resolved from the current session.
362
+ */
363
+ user: MonoCloudUser;
364
+ /**
365
+ * Dynamic route parameters provided by the App Router.
366
+ */
367
+ params?: Record<string, string | string[]>;
368
+ /**
369
+ * URL search parameters provided by the App Router.
370
+ */
371
+ searchParams?: Record<string, string | string[] | undefined>;
372
+ }) => Promise<JSX.Element> | JSX.Element;
373
+ /**
374
+ * Handler invoked when a request is denied because the user is not authenticated in an App Router API route.
375
+ *
376
+ * @category Types (Handler)
377
+ *
378
+ * @param req The incoming Next.js request.
379
+ * @param ctx The App Router context containing dynamic route parameters.
380
+ *
381
+ * @returns Returns a `Response` (or `NextResponse`) or a Promise resolving to one.
382
+ */
383
+ type AppRouterApiOnAccessDeniedHandler = (req: NextRequest, ctx: AppRouterContext) => Promise<Response> | Response;
384
+ /**
385
+ * Handler invoked when a request is denied because the authenticated user does not satisfy the required group restrictions in an App Router API route.
386
+ *
387
+ * @category Types (Handler)
388
+ *
389
+ * @param req The incoming Next.js request.
390
+ * @param ctx The App Router context containing dynamic route parameters.
391
+ * @param user The authenticated user associated with the request.
392
+ *
393
+ * @returns Returns a `Response` (or `NextResponse`) or a Promise resolving to one.
394
+ */
395
+ type AppRouterApiOnGroupAccessDeniedHandler = (req: NextRequest, ctx: AppRouterContext, user: MonoCloudUser) => Promise<Response> | Response;
396
+ /**
397
+ * Options for configuring `protectApi()` in the App Router.
398
+ *
399
+ * @category Types
400
+ */
401
+ interface ProtectApiAppOptions extends GroupOptions {
402
+ /**
403
+ * Alternate API route handler invoked when the request is not authenticated.
404
+ */
405
+ onAccessDenied?: AppRouterApiOnAccessDeniedHandler;
406
+ /**
407
+ * Alternate API route handler invoked when the request is authenticated but the user does not satisfy the required group restrictions.
408
+ */
409
+ onGroupAccessDenied?: AppRouterApiOnGroupAccessDeniedHandler;
410
+ }
411
+ /**
412
+ * Handler function invoked when a request is not authenticated in a Pages Router API route.
413
+ *
414
+ * @category Types (Handler)
415
+ *
416
+ * @param req The incoming Next.js API request.
417
+ * @param res The Next.js API response object used to send the custom response.
418
+ * @returns The handler should send a response using `res` (for example, `res.status(...).json(...)`). Returning a value does not automatically end the request.
419
+ */
420
+ type PageRouterApiOnAccessDeniedHandler = (req: NextApiRequest, res: NextApiResponse<any>) => Promise<unknown> | unknown;
421
+ /**
422
+ * Handler function invoked when an authenticated user is denied access in a Pages Router API route due to group authorization restrictions.
423
+ *
424
+ * @category Types (Handler)
425
+ *
426
+ * @param req The incoming Next.js API request.
427
+ * @param res The Next.js API response object used to send the custom response.
428
+ * @returns The handler should send a response using `res` (for example, `res.status(...).json(...)`). Returning a value does not automatically end the request.
429
+ *
430
+ * @returns
431
+ */
432
+ type PageRouterApiOnGroupAccessDeniedHandler = (req: NextApiRequest, res: NextApiResponse<any>, user: MonoCloudUser) => Promise<unknown> | unknown;
433
+ /**
434
+ * Options for configuring `protectApi()` in the Pages Router.
435
+ *
436
+ * @category Types
437
+ */
438
+ interface ProtectApiPageOptions extends GroupOptions {
439
+ /**
440
+ * Alternate API handler invoked when the request is unauthenticated.
441
+ */
442
+ onAccessDenied?: PageRouterApiOnAccessDeniedHandler;
443
+ /**
444
+ * Alternate API handler invoked when the user is authenticated but does not satisfy the configured group authorization rules.
445
+ */
446
+ onGroupAccessDenied?: PageRouterApiOnGroupAccessDeniedHandler;
447
+ }
448
+ /**
449
+ * Options for configuring the `protect()` helper.
450
+ *
451
+ * @category Types
452
+ */
453
+ interface ProtectOptions extends GroupOptions {
454
+ /**
455
+ * The URL to return to after successful authentication.
456
+ *
457
+ * If not provided, the current request URL is used.
458
+ */
459
+ returnUrl?: string;
460
+ /**
461
+ * Additional authorization parameters to include when redirecting the user to the sign-in flow.
462
+ */
463
+ authParams?: ExtraAuthParams;
464
+ }
465
+ /**
466
+ * Configuration options for evaluating user group membership.
467
+ *
468
+ * @category Types
469
+ */
470
+ interface IsUserInGroupOptions {
471
+ /**
472
+ * The name of the claim in the user profile that contains group information. This value is read from the authenticated user's session.
473
+ *
474
+ * @defaultValue 'groups'
475
+ */
476
+ groupsClaim?: string;
477
+ /**
478
+ * Determines how multiple groups are evaluated. When `true`, the user must belong to **all** specified groups for authorization to succeed. Otherwise, membership in any one group is sufficient.
479
+ *
480
+ * @defaultValue false
481
+ */
482
+ matchAll?: boolean;
483
+ }
484
+ /**
485
+ * Configuration options that require the user to belong to specific groups.
486
+ *
487
+ * @category Types
488
+ */
489
+ interface GroupOptions extends IsUserInGroupOptions {
490
+ /**
491
+ * A list of group IDs or group names the authenticated user must belong to.
492
+ *
493
+ * Group membership is evaluated using the configured `groupsClaim` from the user session.
494
+ */
495
+ groups?: string[];
496
+ }
497
+ /**
498
+ * Options for `redirectToSignIn()`
499
+ *
500
+ * @category Types
501
+ */
502
+ interface RedirectToSignInOptions {
503
+ /**
504
+ * URL to return the user to after successful authentication. Must be a relative application URL.
505
+ */
506
+ returnUrl?: string;
507
+ /**
508
+ * Maximum allowed time (in seconds) since the user's last authentication.
509
+ */
510
+ maxAge?: number;
511
+ /**
512
+ * Hint to the authorization server indicating which authenticator should be used during sign-in.
513
+ */
514
+ authenticatorHint?: Authenticators;
515
+ /**
516
+ * Scopes to request during authentication.
517
+ */
518
+ scopes?: string[];
519
+ /**
520
+ * Resource indicators the access token should be issued for.
521
+ */
522
+ resource?: string[];
523
+ /**
524
+ * Preferred UI language(s) for the authentication experience.
525
+ */
526
+ uiLocales?: string;
527
+ /**
528
+ * Preferred display mode for the authentication UI.
529
+ */
530
+ display?: DisplayOptions;
531
+ /**
532
+ * Authentication Context Class Reference (ACR) values requesting specific authentication methods or assurance levels.
533
+ */
534
+ acrValues?: string[];
535
+ /**
536
+ * Hint about the user's identifier (for example, email or username).
537
+ */
538
+ loginHint?: string;
539
+ /**
540
+ * Controls whether the authorization server should force specific user interactions during authentication
541
+ */
542
+ prompt?: Prompt;
543
+ }
544
+ /**
545
+ * Options for `redirectToSignOut()`
546
+ *
547
+ * @category Types
548
+ */
549
+ interface RedirectToSignOutOptions {
550
+ /**
551
+ * URL where the authorization server should redirect the user after a successful sign-out.
552
+ *
553
+ * This value must match one of the registered Sign-out Redirect URLs configured for the application.
554
+ */
555
+ postLogoutRedirectUri?: string;
556
+ /**
557
+ * When enabled, the user is also signed out from MonoCloud (Single Sign-Out).
558
+ */
559
+ federated?: boolean;
560
+ }
561
+ //#endregion
562
+ export { ProtectedRouteMatcher as A, ProtectAppPageOptions as C, ProtectPagePageOptions as D, ProtectPagePageOnGroupAccessDeniedType as E, RedirectToSignInOptions as M, RedirectToSignOutOptions as N, ProtectPagePageReturnType as O, ProtectApiPageOptions as S, ProtectPagePageOnAccessDeniedType as T, OnError as _, AppRouterContext as a, PageRouterApiOnGroupAccessDeniedHandler as b, ExtraAuthParams as c, MonoCloudAuthHandler as d, MonoCloudAuthOptions as f, NextMiddlewareResult as g, NextMiddlewareOnGroupAccessDenied as h, AppRouterApiOnGroupAccessDeniedHandler as i, ProtectedRoutes as j, ProtectedAppServerComponent as k, GroupOptions as l, NextMiddlewareOnAccessDenied as m, AppRouterApiHandlerFn as n, AppRouterPageHandler as o, MonoCloudMiddlewareOptions as p, AppRouterApiOnAccessDeniedHandler as r, CustomProtectedRouteMatcher as s, AppOnError as t, IsUserInGroupOptions as u, PageOnError as v, ProtectOptions as w, ProtectApiAppOptions as x, PageRouterApiOnAccessDeniedHandler as y };
563
+ //# sourceMappingURL=types-xS_Me3Qg.d.mts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monocloud/auth-nextjs",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "MonoCloud Next.js Authentication SDK",
5
5
  "keywords": [
6
6
  "monocloud",
@@ -56,18 +56,19 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "cookie": "1.1.1",
59
- "swr": "2.3.8",
60
- "@monocloud/auth-node-core": "0.1.4"
59
+ "swr": "2.4.0",
60
+ "@monocloud/auth-node-core": "0.1.6",
61
+ "@monocloud/auth-core": "0.1.5"
61
62
  },
62
63
  "devDependencies": {
63
64
  "@edge-runtime/vm": "5.0.0",
64
65
  "@testing-library/dom": "10.4.1",
65
- "@testing-library/react": "16.3.1",
66
+ "@testing-library/react": "16.3.2",
66
67
  "@types/body-parser": "1.19.6",
67
- "@types/react": "19.2.7",
68
+ "@types/react": "19.2.13",
68
69
  "@types/react-dom": "19.2.3",
69
- "body-parser": "2.2.1",
70
- "eslint": "9.39.2",
70
+ "body-parser": "2.2.2",
71
+ "eslint": "10.0.0",
71
72
  "nock": "15.0.0",
72
73
  "tough-cookie": "6.0.0",
73
74
  "url-search-params-polyfill": "8.2.5",
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-D-3RMRNY.mjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport useSWR from 'swr';\n\n/**\n * Authentication State returned by `useAuth` hook.\n */\nexport interface AuthState {\n /**\n * Flag indicating if the authentication state is still loading.\n */\n isLoading: boolean;\n /**\n * Flag indicating if the user is authenticated.\n */\n isAuthenticated: boolean;\n /**\n * Error encountered during authentication, if any.\n */\n error?: Error;\n /**\n * The authenticated user's information, if available.\n */\n user?: MonoCloudUser;\n /**\n * Function to refetch the authentication state.\n *\n */\n refetch: (refresh?: boolean) => void;\n}\n\nconst fetchUser = async (url: string): Promise<MonoCloudUser | undefined> => {\n const res = await fetch(url, { credentials: 'include' });\n\n if (res.status === 204) {\n return undefined;\n }\n\n if (res.ok) {\n return res.json();\n }\n\n throw new Error('Failed to fetch user');\n};\n\n/**\n *\n * Hook for getting the user's profile on client components\n *\n * @returns Authentication State\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user } = useAuth();\n *\n * return <>User Id: {user?.sub}</>;\n * }\n * ```\n *\n * @example App Router - Refetch user from Userinfo endpoint\n *\n * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.\n * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`\n *\n * **Note⚠️: You need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for force refresh to work**\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user, refetch } = useAuth();\n *\n * return (\n * <>\n * <pre>{JSON.stringify(user)}</pre>\n * <button onClick={() => refetch(true)}>Refresh</button>\n * </>\n * );\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user } = useAuth();\n *\n * return <>User Id: {user?.sub}</>;\n * }\n * ```\n *\n * @example Pages Router - Refetch user from Userinfo endpoint\n *\n * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.\n * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`\n *\n * **Note⚠️: You need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for force refresh to work**\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user, refetch } = useAuth();\n *\n * return (\n * <>\n * <pre>{JSON.stringify(user)}</pre>\n * <button onClick={() => refetch(true)}>Refresh</button>\n * </>\n * );\n * }\n * ```\n *\n */\nexport const useAuth = (): AuthState => {\n const key =\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ??\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/userinfo`;\n\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\n key,\n fetchUser\n );\n\n const refetch = (refresh?: boolean): void => {\n const url = new URL(key, 'https://dummy');\n if (refresh) {\n url.searchParams.set('refresh', 'true');\n }\n\n void mutate(async () => await fetchUser(url.pathname + url.search), {\n revalidate: false,\n });\n };\n\n if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch,\n };\n }\n\n if (data) {\n return {\n user: data,\n isLoading,\n isAuthenticated: !!data && Object.keys(data).length > 0,\n error: undefined,\n refetch,\n };\n }\n\n return {\n user: undefined,\n isLoading,\n isAuthenticated: false,\n error: undefined,\n /* v8 ignore next -- @preserve */\n refetch: (): void => {},\n };\n};\n","/* eslint-disable react/display-name */\n'use client';\n\nimport React, { ComponentType, JSX, useEffect } from 'react';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport { useAuth } from './use-auth';\nimport { ExtraAuthParams, GroupOptions } from '../types';\n\n/**\n * Options for configuring page protection.\n */\nexport type ProtectPageOptions = {\n /**\n *The url where the user will be redirected to after sign in\n */\n returnUrl?: string;\n\n /**\n * A custom react element to render when the user is not authenticated.\n */\n fallback?: (user?: MonoCloudUser) => JSX.Element;\n\n /**\n * A custom react element to render when the user is authenticated but does not belong to the required groups.\n */\n groupFallback?: (user: MonoCloudUser) => JSX.Element;\n\n /**\n * Authorization parameters to be used during authentication.\n */\n authParams?: ExtraAuthParams;\n\n /**\n * Callback function to handle errors.\n * If not provided, errors will be thrown.\n *\n * @param error - The error object.\n * @returns JSX element to handle the error.\n */\n onError?: (error: Error) => JSX.Element;\n} & GroupOptions;\n\nexport const redirectToSignIn = (\n options: { returnUrl?: string } & ExtraAuthParams\n): void => {\n const searchParams = new URLSearchParams(window.location.search);\n searchParams.set(\n 'return_url',\n options.returnUrl ?? window.location.toString()\n );\n\n if (options?.scopes) {\n searchParams.set('scope', options.scopes);\n }\n if (options?.resource) {\n searchParams.set('resource', options.resource);\n }\n\n if (options?.acrValues) {\n searchParams.set('acr_values', options.acrValues.join(' '));\n }\n\n if (options?.display) {\n searchParams.set('display', options.display);\n }\n\n if (options?.prompt) {\n searchParams.set('prompt', options.prompt);\n }\n\n if (options?.authenticatorHint) {\n searchParams.set('authenticator_hint', options.authenticatorHint);\n }\n\n if (options?.uiLocales) {\n searchParams.set('ui_locales', options.uiLocales);\n }\n\n if (options?.maxAge) {\n searchParams.set('max_age', options.maxAge.toString());\n }\n\n if (options?.loginHint) {\n searchParams.set('login_hint', options.loginHint);\n }\n\n window.location.assign(\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`}?${searchParams.toString()}`\n );\n};\n\nconst handlePageError = (\n error: Error,\n options?: ProtectPageOptions\n): JSX.Element => {\n /* v8 ignore else -- @preserve */\n if (options?.onError) {\n return options.onError(error);\n }\n\n /* v8 ignore next -- @preserve */\n throw error;\n};\n\n/**\n * Function to protect a client rendered page component.\n * Ensures that only authenticated users can access the component.\n *\n * **Note⚠️: Since `window.location` is set as `returnUrl` query param by default, you need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for returning to the same page.**\n *\n * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected client rendered page component.\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(function Home() {\n * return <>You are signed in</>;\n * });\n * ```\n *\n * @example App Router with options\n *\n * See {@link ProtectPageOptions} for more options.\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>You are signed in</>;\n * },\n * { returnUrl: \"/dashboard\", authParams: { loginHint: \"username\" } }\n * );\n * ```\n * @example Custom Fallback\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>You are signed in</>;\n * },\n * {\n * fallback: () => <div>Please sign in to continue</div>\n * }\n * );\n * ```\n *\n * @example Group Protection with Group Fallback\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>Welcome Admin</>;\n * },\n * {\n * groups: [\"admin\"],\n * groupFallback: (user) => <div>User {user.email} is not an admin</div>\n * }\n * );\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(function Home() {\n * return <>You are signed in</>;\n * });\n * ```\n *\n * @example Pages Router with options\n *\n * See {@link ProtectPageOptions} for more options.\n *\n * ```tsx\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>You are signed in</>;\n * },\n * { returnUrl: \"/dashboard\", authParams: { loginHint: \"username\" } }\n * );\n * ```\n */\nexport const protectPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectPageOptions\n): React.FC<P> => {\n return props => {\n const { user, error, isLoading } = useAuth();\n\n useEffect(() => {\n if (!user && !isLoading && !error) {\n if (options?.fallback) {\n return;\n }\n\n const authParams = options?.authParams ?? {};\n redirectToSignIn({\n returnUrl: options?.returnUrl,\n ...authParams,\n });\n }\n }, [user, isLoading, error]);\n\n if (error) {\n return handlePageError(error, options);\n }\n\n if (!user && !isLoading && options?.fallback) {\n return options.fallback();\n }\n\n if (user) {\n if (\n options?.groups &&\n !isUserInGroup(\n user,\n options.groups,\n options.groupsClaim ??\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n options.matchAll\n )\n ) {\n const { groupFallback = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return groupFallback(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-xfBYYato.cjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport useSWR from 'swr';\n\n/**\n * Authentication State returned by `useAuth` hook.\n */\nexport interface AuthState {\n /**\n * Flag indicating if the authentication state is still loading.\n */\n isLoading: boolean;\n /**\n * Flag indicating if the user is authenticated.\n */\n isAuthenticated: boolean;\n /**\n * Error encountered during authentication, if any.\n */\n error?: Error;\n /**\n * The authenticated user's information, if available.\n */\n user?: MonoCloudUser;\n /**\n * Function to refetch the authentication state.\n *\n */\n refetch: (refresh?: boolean) => void;\n}\n\nconst fetchUser = async (url: string): Promise<MonoCloudUser | undefined> => {\n const res = await fetch(url, { credentials: 'include' });\n\n if (res.status === 204) {\n return undefined;\n }\n\n if (res.ok) {\n return res.json();\n }\n\n throw new Error('Failed to fetch user');\n};\n\n/**\n *\n * Hook for getting the user's profile on client components\n *\n * @returns Authentication State\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user } = useAuth();\n *\n * return <>User Id: {user?.sub}</>;\n * }\n * ```\n *\n * @example App Router - Refetch user from Userinfo endpoint\n *\n * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.\n * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`\n *\n * **Note⚠️: You need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for force refresh to work**\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user, refetch } = useAuth();\n *\n * return (\n * <>\n * <pre>{JSON.stringify(user)}</pre>\n * <button onClick={() => refetch(true)}>Refresh</button>\n * </>\n * );\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user } = useAuth();\n *\n * return <>User Id: {user?.sub}</>;\n * }\n * ```\n *\n * @example Pages Router - Refetch user from Userinfo endpoint\n *\n * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.\n * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`\n *\n * **Note⚠️: You need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for force refresh to work**\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user, refetch } = useAuth();\n *\n * return (\n * <>\n * <pre>{JSON.stringify(user)}</pre>\n * <button onClick={() => refetch(true)}>Refresh</button>\n * </>\n * );\n * }\n * ```\n *\n */\nexport const useAuth = (): AuthState => {\n const key =\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ??\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/userinfo`;\n\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\n key,\n fetchUser\n );\n\n const refetch = (refresh?: boolean): void => {\n const url = new URL(key, 'https://dummy');\n if (refresh) {\n url.searchParams.set('refresh', 'true');\n }\n\n void mutate(async () => await fetchUser(url.pathname + url.search), {\n revalidate: false,\n });\n };\n\n if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch,\n };\n }\n\n if (data) {\n return {\n user: data,\n isLoading,\n isAuthenticated: !!data && Object.keys(data).length > 0,\n error: undefined,\n refetch,\n };\n }\n\n return {\n user: undefined,\n isLoading,\n isAuthenticated: false,\n error: undefined,\n /* v8 ignore next -- @preserve */\n refetch: (): void => {},\n };\n};\n","/* eslint-disable react/display-name */\n'use client';\n\nimport React, { ComponentType, JSX, useEffect } from 'react';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport { useAuth } from './use-auth';\nimport { ExtraAuthParams, GroupOptions } from '../types';\n\n/**\n * Options for configuring page protection.\n */\nexport type ProtectPageOptions = {\n /**\n *The url where the user will be redirected to after sign in\n */\n returnUrl?: string;\n\n /**\n * A custom react element to render when the user is not authenticated.\n */\n fallback?: (user?: MonoCloudUser) => JSX.Element;\n\n /**\n * A custom react element to render when the user is authenticated but does not belong to the required groups.\n */\n groupFallback?: (user: MonoCloudUser) => JSX.Element;\n\n /**\n * Authorization parameters to be used during authentication.\n */\n authParams?: ExtraAuthParams;\n\n /**\n * Callback function to handle errors.\n * If not provided, errors will be thrown.\n *\n * @param error - The error object.\n * @returns JSX element to handle the error.\n */\n onError?: (error: Error) => JSX.Element;\n} & GroupOptions;\n\nexport const redirectToSignIn = (\n options: { returnUrl?: string } & ExtraAuthParams\n): void => {\n const searchParams = new URLSearchParams(window.location.search);\n searchParams.set(\n 'return_url',\n options.returnUrl ?? window.location.toString()\n );\n\n if (options?.scopes) {\n searchParams.set('scope', options.scopes);\n }\n if (options?.resource) {\n searchParams.set('resource', options.resource);\n }\n\n if (options?.acrValues) {\n searchParams.set('acr_values', options.acrValues.join(' '));\n }\n\n if (options?.display) {\n searchParams.set('display', options.display);\n }\n\n if (options?.prompt) {\n searchParams.set('prompt', options.prompt);\n }\n\n if (options?.authenticatorHint) {\n searchParams.set('authenticator_hint', options.authenticatorHint);\n }\n\n if (options?.uiLocales) {\n searchParams.set('ui_locales', options.uiLocales);\n }\n\n if (options?.maxAge) {\n searchParams.set('max_age', options.maxAge.toString());\n }\n\n if (options?.loginHint) {\n searchParams.set('login_hint', options.loginHint);\n }\n\n window.location.assign(\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`}?${searchParams.toString()}`\n );\n};\n\nconst handlePageError = (\n error: Error,\n options?: ProtectPageOptions\n): JSX.Element => {\n /* v8 ignore else -- @preserve */\n if (options?.onError) {\n return options.onError(error);\n }\n\n /* v8 ignore next -- @preserve */\n throw error;\n};\n\n/**\n * Function to protect a client rendered page component.\n * Ensures that only authenticated users can access the component.\n *\n * **Note⚠️: Since `window.location` is set as `returnUrl` query param by default, you need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for returning to the same page.**\n *\n * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected client rendered page component.\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(function Home() {\n * return <>You are signed in</>;\n * });\n * ```\n *\n * @example App Router with options\n *\n * See {@link ProtectPageOptions} for more options.\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>You are signed in</>;\n * },\n * { returnUrl: \"/dashboard\", authParams: { loginHint: \"username\" } }\n * );\n * ```\n * @example Custom Fallback\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>You are signed in</>;\n * },\n * {\n * fallback: () => <div>Please sign in to continue</div>\n * }\n * );\n * ```\n *\n * @example Group Protection with Group Fallback\n *\n * ```tsx\n * \"use client\";\n *\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>Welcome Admin</>;\n * },\n * {\n * groups: [\"admin\"],\n * groupFallback: (user) => <div>User {user.email} is not an admin</div>\n * }\n * );\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(function Home() {\n * return <>You are signed in</>;\n * });\n * ```\n *\n * @example Pages Router with options\n *\n * See {@link ProtectPageOptions} for more options.\n *\n * ```tsx\n * import { protectPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectPage(\n * function Home() {\n * return <>You are signed in</>;\n * },\n * { returnUrl: \"/dashboard\", authParams: { loginHint: \"username\" } }\n * );\n * ```\n */\nexport const protectPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectPageOptions\n): React.FC<P> => {\n return props => {\n const { user, error, isLoading } = useAuth();\n\n useEffect(() => {\n if (!user && !isLoading && !error) {\n if (options?.fallback) {\n return;\n }\n\n const authParams = options?.authParams ?? {};\n redirectToSignIn({\n returnUrl: options?.returnUrl,\n ...authParams,\n });\n }\n }, [user, isLoading, error]);\n\n if (error) {\n return handlePageError(error, options);\n }\n\n if (!user && !isLoading && options?.fallback) {\n return options.fallback();\n }\n\n if (user) {\n if (\n options?.groups &&\n !isUserInGroup(\n user,\n options.groups,\n options.groupsClaim ??\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n options.matchAll\n )\n ) {\n const { groupFallback = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return groupFallback(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":"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"}