@monocloud/auth-nextjs 0.1.1 → 0.1.2

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.
@@ -1,79 +1,32 @@
1
1
  import { Authenticators, AuthorizationParams, DisplayOptions, MonoCloudUser, Prompt } from "@monocloud/auth-node-core";
2
- import { NextFetchEvent, NextMiddleware, NextRequest, NextResponse } from "next/server";
3
2
  import { JSX } from "react";
4
- import { NextApiRequestCookies } from "next/dist/server/api-utils";
5
- import { NextMiddlewareResult } from "next/dist/server/web/types";
6
- import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult, NextApiHandler, NextApiRequest, NextApiResponse } from "next/types";
7
- import { IncomingMessage, ServerResponse } from "node:http";
3
+ import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
4
+ import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult, NextApiRequest, NextApiResponse } from "next/types";
8
5
  import { ParsedUrlQuery } from "node:querystring";
9
6
 
10
7
  //#region src/types.d.ts
8
+
9
+ /**
10
+ * Context object passed to App Router API route handlers.
11
+ * Contains the dynamic route parameters.
12
+ */
11
13
  interface AppRouterContext {
12
14
  params: Record<string, string | string[]>;
13
15
  }
14
- type NextAnyRequest = NextRequest | NextApiRequest | (IncomingMessage & {
15
- cookies: NextApiRequestCookies;
16
- });
17
- type NextAnyResponse = NextApiResponse | AppRouterContext | NextResponse | ServerResponse;
18
16
  /**
19
- * @typeparam TResult - The type of the result returned by the handler.
17
+ * Return type of `monoCloudAuth()` handler.
20
18
  */
21
- interface BaseFuncHandler<TResult> {
22
- /**
23
- * @param req - The Next.js request object.
24
- * @param ctx - The AppRouterContext or NextResponse object representing the response context.
25
- * @returns A promise of the result.
26
- */
27
- (req: NextRequest, ctx: AppRouterContext | NextResponse): Promise<TResult>;
28
- /**
29
- * @param req - The Next.js API request object.
30
- * @param res - The Next.js API response object.
31
- * @returns A promise of the result.
32
- */
33
- (req: NextApiRequest, res: NextApiResponse): Promise<TResult>;
34
- /**
35
- * @param req - The Next.js request object.
36
- * @param res - The Next.js response object.
37
- * @returns A promise of the result.
38
- */
39
- (req: NextAnyRequest, res: NextAnyResponse): Promise<TResult>;
40
- /**
41
- * @returns A promise of the result.
42
- */
43
- (): Promise<TResult>;
44
- }
19
+ type MonoCloudAuthHandler = (req: Request | NextRequest | NextApiRequest, resOrCtx?: Response | NextResponse<any> | NextApiResponse<any> | AppRouterContext) => Promise<Response | NextResponse | void | any>;
20
+ /** Return type of Next.js middleware/proxy */
21
+ type NextMiddlewareResult = NextResponse | Response | null | undefined | void;
45
22
  /**
46
- * @typeparam TResult - The type of the result returned by the function.
47
- * @typeparam TOptions - The type of the additional options parameter (default: `any`).
23
+ * Handler function triggered when a user is denied access in Next.js Middleware.
24
+ *
25
+ * @param request - The incoming Next.js request.
26
+ * @param event - The Next.js fetch event.
27
+ * @param user - The authenticated user object (if available).
28
+ * @returns A `NextMiddlewareResult` (e.g., a redirect or rewrite) or a Promise resolving to one.
48
29
  */
49
- type FuncHandler<TResult, TOptions = any> = BaseFuncHandler<TResult> & {
50
- /**
51
- * @param req - The Next.js request object.
52
- * @param ctx - The context object, which can be either an AppRouterContext or a NextResponse.
53
- * @param options - Additional options passed to the function (optional).
54
- * @returns A promise of the result.
55
- */
56
- (req: NextRequest, ctx: AppRouterContext | NextResponse, options?: TOptions): Promise<TResult>;
57
- /**
58
- * @param req - The Next.js API request object.
59
- * @param res - The Next.js API response object.
60
- * @param options - Additional options passed to the function (optional).
61
- * @returns A promise of the result.
62
- */
63
- (req: NextApiRequest, res: NextApiResponse, options?: TOptions): Promise<TResult>;
64
- /**
65
- * @param req - The generic Next.js request object.
66
- * @param res - The generic Next.js response object.
67
- * @param options - Additional options passed to the function (optional).
68
- * @returns A promise of the result.
69
- */
70
- (req: NextAnyRequest, res: NextAnyResponse, options?: TOptions): Promise<TResult>;
71
- /**
72
- * @param options - Additional options passed to the function (optional).
73
- * @returns A promise of the result.
74
- */
75
- (options?: TOptions): Promise<TResult>;
76
- };
77
30
  type NextMiddlewareOnAccessDenied = (request: NextRequest, event: NextFetchEvent, user?: MonoCloudUser) => NextMiddlewareResult | Promise<NextMiddlewareResult>;
78
31
  /**
79
32
  *
@@ -163,38 +116,25 @@ interface MonoCloudMiddlewareOptions {
163
116
  onAccessDenied?: NextMiddlewareOnAccessDenied;
164
117
  }
165
118
  /**
166
- * A middleware that protects pages and apis and handles authentication.
167
- * This middleware function can be configured with options or directly invoked with request and event parameters.
119
+ * A subset of authorization parameters used on client side functions
168
120
  */
169
- interface MonoCloudMiddleware {
170
- /**
171
- * A middleware that protects pages and apis and handles authentication.
172
- *
173
- * @param options - Options to configure the MonoCloud authentication middleware.
174
- * @returns A Next.js middleware function.
175
- */
176
- (options?: MonoCloudMiddlewareOptions): NextMiddleware;
177
- /**
178
- * A middleware that protects pages and apis and handles authentication.
179
- *
180
- * @returns A promise resolving to a Next.js middleware result or a Next.js middleware result.
181
- */
182
- (
183
- /**
184
- * The Next.js request object.
185
- */
186
- request: NextRequest,
187
- /**
188
- * The Next.js fetch event object.
189
- */
190
- event: NextFetchEvent): Promise<NextMiddlewareResult> | NextMiddlewareResult;
191
- }
192
121
  type ExtraAuthParams = Pick<AuthorizationParams, 'scopes' | 'resource' | 'prompt' | 'display' | 'uiLocales' | 'acrValues' | 'authenticatorHint' | 'maxAge' | 'loginHint'>;
122
+ /**
123
+ * Represents a Next.js App Router React Server Component.
124
+ *
125
+ * @param props - The props object containing `params` and `searchParams`.
126
+ *
127
+ * @returns A JSX Element or a Promise resolving to one.
128
+ */
193
129
  type AppRouterPageHandler = (props: {
194
130
  params?: Record<string, string | string[]>;
195
131
  searchParams?: Record<string, string | string[] | undefined>;
196
132
  }) => Promise<JSX.Element> | JSX.Element;
197
- type AppRouterApiHandlerFn = (req: NextRequest, ctx: AppRouterContext) => Promise<Response> | Response;
133
+ /** App Router API Route Handler */
134
+ type AppRouterApiHandlerFn = (req: NextRequest | Request, ctx: AppRouterContext) => Promise<Response | NextResponse> | Response | NextResponse;
135
+ /**
136
+ * Options for configuring `protectPage()` in the App Router.
137
+ */
198
138
  type ProtectAppPageOptions = {
199
139
  /**
200
140
  * The URL to return to after authentication.
@@ -213,6 +153,12 @@ type ProtectAppPageOptions = {
213
153
  */
214
154
  authParams?: ExtraAuthParams;
215
155
  } & GroupOptions;
156
+ /**
157
+ * Options for configuring `protectPage()` in the Pages Router.
158
+ *
159
+ * @typeParam P - The type of the props returned by `getServerSideProps`.
160
+ * @typeParam Q - The type of the parsed query object.
161
+ */
216
162
  type ProtectPagePageOptions<P extends Record<string, any> = Record<string, any>, Q extends ParsedUrlQuery = ParsedUrlQuery> = {
217
163
  /**
218
164
  * Function to fetch server-side props for the protected page handler.
@@ -235,77 +181,78 @@ type ProtectPagePageOptions<P extends Record<string, any> = Record<string, any>,
235
181
  */
236
182
  authParams?: ExtraAuthParams;
237
183
  } & GroupOptions;
184
+ /**
185
+ * Handler function triggered when a user is denied access in a Pages Router `getServerSideProps` flow.
186
+ *
187
+ * @typeParam P - The type of the props.
188
+ * @typeParam Q - The type of the parsed query object.
189
+ *
190
+ * @param context - The server-side props context extended with the optional user object.
191
+ *
192
+ * @returns The result for `getServerSideProps`.
193
+ */
238
194
  type ProtectPagePageOnAccessDeniedType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q> & {
239
195
  user?: MonoCloudUser;
240
196
  }) => Promise<GetServerSidePropsResult<P>> | GetServerSidePropsResult<P>;
241
- type ProtectPagePageReturnType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q>) => Promise<GetServerSidePropsResult<P & {
242
- user: MonoCloudUser;
243
- }>>;
244
197
  /**
245
- * Type definition for protecting a server rendered page handler function.
246
- * This type takes optional protection options and returns the protected page handler.
198
+ * The return type of the `protectPage()` wrapper for Pages Router.
199
+ * It returns a function compatible with `getServerSideProps` that injects the user into props.
247
200
  *
248
- * @typeparam P - The type of parameters accepted by the page handler.
249
- * @typeparam Q - The type of query parameters parsed from the URL.
250
- * @returns Protected page handler function.
251
- */
252
- type ProtectPagePage = <P extends Record<string, any> = Record<string, any>, Q extends ParsedUrlQuery = ParsedUrlQuery>(
253
- /**
254
- * Protection options
255
- */
256
- options?: ProtectPagePageOptions<P, Q>) => ProtectPagePageReturnType<P, Q>;
257
- /**
258
- * Type definition for protecting a server rendered AppRouter page handler function.
201
+ * @typeParam P - The type of the props.
202
+ * @typeParam Q - The type of the parsed query object.
259
203
  *
260
- * @returns Protected page handler function.
204
+ * @returns `GetServerSidePropsResult` with user injected
261
205
  */
262
- type ProtectAppPage = (
206
+ type ProtectPagePageReturnType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q>) => Promise<GetServerSidePropsResult<P & {
207
+ user: MonoCloudUser;
208
+ accessDenied?: boolean;
209
+ }>>;
263
210
  /**
264
- * The component to protect
211
+ * The App Router server component that protectPage wraps and secures
265
212
  */
266
- component: (props: {
213
+ type ProtectedAppServerComponent = (props: {
267
214
  user: MonoCloudUser;
268
215
  params?: Record<string, string | string[]>;
269
216
  searchParams?: Record<string, string | string[] | undefined>;
270
- }) => Promise<JSX.Element> | JSX.Element,
271
- /**
272
- * Protection options
273
- */
274
- options?: ProtectAppPageOptions) => AppRouterPageHandler;
217
+ }) => Promise<JSX.Element> | JSX.Element;
275
218
  /**
276
- * Protects a server rendered page.
219
+ * Handler function triggered when a user is denied access in an App Router API route.
220
+ *
221
+ * @param req - The incoming Next.js request.
222
+ * @param ctx - The App Router context.
223
+ *
224
+ * @param user - The authenticated user object (if available).
225
+ *
226
+ * @returns A Response/NextResponse or Promise resolving to one.
277
227
  */
278
- type ProtectPage = ProtectAppPage & ProtectPagePage;
279
- type AppRouterApiOnAccessDeniedHandlerFn = (req: NextRequest, res: AppRouterContext, user?: MonoCloudUser) => Promise<Response> | Response;
228
+ type AppRouterApiOnAccessDeniedHandler = (req: NextRequest, ctx: AppRouterContext, user?: MonoCloudUser) => Promise<Response> | Response;
229
+ /** Options for App Router `protectApi()` */
280
230
  type ProtectApiAppOptions = {
281
231
  /**
282
232
  * Alternate app router api handler called when the user is not authenticated or is not a member of the specified groups.
283
233
  */
284
- onAccessDenied?: AppRouterApiOnAccessDeniedHandlerFn;
234
+ onAccessDenied?: AppRouterApiOnAccessDeniedHandler;
285
235
  } & GroupOptions;
286
- type ProtectAppApi = (req: NextRequest, ctx: AppRouterContext, handler: AppRouterApiHandlerFn, options?: ProtectApiAppOptions) => Promise<Response> | Response;
287
- type NextPageRouterApiOnAccessDeniedHandler = (req: NextApiRequest, res: NextApiResponse<any>, user?: MonoCloudUser) => Promise<unknown> | unknown;
236
+ /**
237
+ * Handler function triggered when a user is denied access in a Pages Router API route.
238
+ *
239
+ * @param req - The incoming Next.js API request.
240
+ * @param res - The Next.js API response.
241
+ * @param user - The authenticated user object (if available).
242
+ *
243
+ * @returns
244
+ */
245
+ type PageRouterApiOnAccessDeniedHandler = (req: NextApiRequest, res: NextApiResponse<any>, user?: MonoCloudUser) => Promise<unknown> | unknown;
246
+ /** Options for Page Router `protectApi()` */
288
247
  type ProtectApiPageOptions = {
289
248
  /**
290
249
  * Alternate page router api handler called when the user is not authenticated or is not a member of the specified groups.
291
250
  */
292
- onAccessDenied?: NextPageRouterApiOnAccessDeniedHandler;
251
+ onAccessDenied?: PageRouterApiOnAccessDeniedHandler;
293
252
  } & GroupOptions;
294
- type ProtectPageApi = (req: NextApiRequest, res: NextApiResponse, handler: NextApiHandler, options?: ProtectApiPageOptions) => Promise<unknown>;
295
- type ProtectApiPage = (
296
253
  /**
297
- * The api route handler function to protect
254
+ * Options for the `protect()` helper function.
298
255
  */
299
- handler: NextApiHandler, options?: ProtectApiPageOptions) => NextApiHandler;
300
- type ProtectApiApp = (
301
- /**
302
- * The api route handler function to protect
303
- */
304
- handler: AppRouterApiHandlerFn, options?: ProtectApiAppOptions) => AppRouterApiHandlerFn;
305
- /**
306
- * Protects an api route handler.
307
- */
308
- type ProtectApi = ProtectApiApp & ProtectApiPage;
309
256
  type ProtectOptions = {
310
257
  /**
311
258
  * The url where the user will be redirected to after sign in.
@@ -317,11 +264,8 @@ type ProtectOptions = {
317
264
  authParams?: ExtraAuthParams;
318
265
  } & GroupOptions;
319
266
  /**
320
- * Redirects user to sign in page if not already authenticated.
321
- *
322
- * @param options - The Protect options
267
+ * Configuration options for checking if a user belongs to specific groups.
323
268
  */
324
- type Protect = (options?: ProtectOptions) => Promise<void>;
325
269
  interface IsUserInGroupOptions {
326
270
  /**
327
271
  * The name of the groups claim in the user profile. Default: `groups`.
@@ -332,6 +276,9 @@ interface IsUserInGroupOptions {
332
276
  */
333
277
  matchAll?: boolean;
334
278
  }
279
+ /**
280
+ * Extended configuration options that include a list of required groups.
281
+ */
335
282
  interface GroupOptions extends IsUserInGroupOptions {
336
283
  /**
337
284
  * A list of group IDs or names specifying the groups the user must belong to.
@@ -396,7 +343,9 @@ interface RedirectToSignOutOptions {
396
343
  * The url authorization server should redirect the user to after a successful sign out. This url has to be registered in the client's sign out url section.
397
344
  */
398
345
  postLogoutRedirectUri?: string;
346
+ /** Whether to also sign out the user from MonoCloud */
347
+ federated?: boolean;
399
348
  }
400
349
  //#endregion
401
- export { ProtectPagePageOnAccessDeniedType as C, RedirectToSignOutOptions as D, RedirectToSignInOptions as E, ProtectPagePage as S, ProtectPagePageReturnType as T, ProtectAppPage as _, FuncHandler as a, ProtectPage as b, MonoCloudAuthOptions as c, NextAnyRequest as d, NextAnyResponse as f, ProtectAppApi as g, ProtectApi as h, ExtraAuthParams as i, MonoCloudMiddleware as l, Protect as m, AppRouterContext as n, GroupOptions as o, NextPageRouterApiOnAccessDeniedHandler as p, BaseFuncHandler as r, IsUserInGroupOptions as s, AppRouterApiOnAccessDeniedHandlerFn as t, MonoCloudMiddlewareOptions as u, ProtectAppPageOptions as v, ProtectPagePageOptions as w, ProtectPageApi as x, ProtectOptions as y };
402
- //# sourceMappingURL=types-BleaXQUP.d.mts.map
350
+ export { ProtectPagePageOptions as _, GroupOptions as a, RedirectToSignInOptions as b, MonoCloudAuthOptions as c, PageRouterApiOnAccessDeniedHandler as d, ProtectApiAppOptions as f, ProtectPagePageOnAccessDeniedType as g, ProtectOptions as h, ExtraAuthParams as i, MonoCloudMiddlewareOptions as l, ProtectAppPageOptions as m, AppRouterApiOnAccessDeniedHandler as n, IsUserInGroupOptions as o, ProtectApiPageOptions as p, AppRouterPageHandler as r, MonoCloudAuthHandler as s, AppRouterApiHandlerFn as t, NextMiddlewareResult as u, ProtectPagePageReturnType as v, RedirectToSignOutOptions as x, ProtectedAppServerComponent as y };
351
+ //# sourceMappingURL=types-DOfZTKa6.d.mts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monocloud/auth-nextjs",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "MonoCloud Next.js Authentication SDK",
5
5
  "keywords": [
6
6
  "monocloud",
@@ -57,7 +57,7 @@
57
57
  "dependencies": {
58
58
  "cookie": "1.1.1",
59
59
  "swr": "2.3.8",
60
- "@monocloud/auth-node-core": "0.1.1"
60
+ "@monocloud/auth-node-core": "0.1.2"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@edge-runtime/vm": "5.0.0",
@@ -1,105 +0,0 @@
1
- import { isUserInGroup } from "@monocloud/auth-node-core/utils";
2
- import useSWR from "swr";
3
- import React, { useEffect } from "react";
4
-
5
- //#region src/client/use-auth.tsx
6
- /**
7
- * @returns Authentication State
8
- */
9
- const useAuth = () => {
10
- const { data, error, isLoading, mutate } = useSWR(process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`, async (url) => {
11
- const res = await fetch(url, { credentials: "include" });
12
- if (res.status === 204) return;
13
- if (res.ok) return res.json();
14
- throw new Error("Failed to fetch user");
15
- });
16
- if (error) return {
17
- user: void 0,
18
- isLoading: false,
19
- isAuthenticated: false,
20
- error,
21
- refetch: () => mutate()
22
- };
23
- if (data) return {
24
- user: data,
25
- isLoading,
26
- isAuthenticated: !!data && Object.keys(data).length > 0,
27
- error: void 0,
28
- refetch: () => mutate()
29
- };
30
- return {
31
- user: void 0,
32
- isLoading,
33
- isAuthenticated: false,
34
- error: void 0,
35
- refetch: () => {}
36
- };
37
- };
38
-
39
- //#endregion
40
- //#region src/client/protect.tsx
41
- const redirectToSignIn = (options) => {
42
- const searchParams = new URLSearchParams(window.location.search);
43
- searchParams.set("return_url", options.returnUrl ?? window.location.toString());
44
- if (options === null || options === void 0 ? void 0 : options.scopes) searchParams.set("scope", options.scopes);
45
- if (options === null || options === void 0 ? void 0 : options.resource) searchParams.set("resource", options.resource);
46
- if (options === null || options === void 0 ? void 0 : options.acrValues) searchParams.set("acr_values", options.acrValues.join(" "));
47
- if (options === null || options === void 0 ? void 0 : options.display) searchParams.set("display", options.display);
48
- if (options === null || options === void 0 ? void 0 : options.prompt) searchParams.set("prompt", options.prompt);
49
- if (options === null || options === void 0 ? void 0 : options.authenticatorHint) searchParams.set("authenticator_hint", options.authenticatorHint);
50
- if (options === null || options === void 0 ? void 0 : options.uiLocales) searchParams.set("ui_locales", options.uiLocales);
51
- if (options === null || options === void 0 ? void 0 : options.maxAge) searchParams.set("max_age", options.maxAge.toString());
52
- if (options === null || options === void 0 ? void 0 : options.loginHint) searchParams.set("login_hint", options.loginHint);
53
- window.location.assign(`${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/signin`}?${searchParams.toString()}`);
54
- };
55
- const handlePageError = (error, options) => {
56
- /* v8 ignore else -- @preserve */
57
- if (options === null || options === void 0 ? void 0 : options.onError) return options.onError(error);
58
- /* v8 ignore next -- @preserve */
59
- throw error;
60
- };
61
- /**
62
- * Function to protect a client rendered page component.
63
- * Ensures that only authenticated users can access the component.
64
- *
65
- * @param Component - The component to protect.
66
- * @param options - The options.
67
- *
68
- * @returns Protected clinet rendered page component.
69
- */
70
- const protectPage = (Component, options) => {
71
- return (props) => {
72
- const { user, error, isLoading } = useAuth();
73
- useEffect(() => {
74
- if (!user && !isLoading && !error) {
75
- if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
76
- const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
77
- redirectToSignIn({
78
- returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
79
- ...authParams
80
- });
81
- }
82
- }, [
83
- user,
84
- isLoading,
85
- error
86
- ]);
87
- if (error) return handlePageError(error, options);
88
- if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.onAccessDenied)) return options.onAccessDenied();
89
- if (user) {
90
- if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(user, options.groups, options.groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
91
- const { onAccessDenied = () => /* @__PURE__ */ React.createElement("div", null, "Access Denied") } = options;
92
- return onAccessDenied(user);
93
- }
94
- return /* @__PURE__ */ React.createElement(Component, {
95
- user,
96
- ...props
97
- });
98
- }
99
- return null;
100
- };
101
- };
102
-
103
- //#endregion
104
- export { redirectToSignIn as n, useAuth as r, protectPage as t };
105
- //# sourceMappingURL=client-0gaUvMR7.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-0gaUvMR7.mjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport { 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 refetch?: () => void;\n}\n\n/**\n * @returns Authentication State\n */\nexport const useAuth = (): AuthState => {\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\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 async (url: string) => {\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 if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch: () => mutate(),\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: () => mutate(),\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 or is not a member of the specified groups.\n */\n onAccessDenied?: (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 * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected clinet rendered page component.\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?.onAccessDenied) {\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?.onAccessDenied) {\n return options.onAccessDenied();\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 { onAccessDenied = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return onAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;AAkCA,MAAa,gBAA2B;CACtC,MAAM,EAAE,MAAM,OAAO,WAAW,WAAW,OACzC,QAAQ,IAAI,4CAEV,GAAG,QAAQ,IAAI,0BAA0B,GAAG,qBAC9C,OAAO,QAAgB;EACrB,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,MAAI,IAAI,WAAW,IACjB;AAGF,MAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,QAAM,IAAI,MAAM,uBAAuB;GAE1C;AAED,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP,eAAe,QAAQ;EACxB;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP,eAAe,QAAQ;EACxB;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;AC3CH,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAChE,cAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,UAAU,CAChD;AAED,uDAAI,QAAS,OACX,cAAa,IAAI,SAAS,QAAQ,OAAO;AAE3C,uDAAI,QAAS,SACX,cAAa,IAAI,YAAY,QAAQ,SAAS;AAGhD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,IAAI,CAAC;AAG7D,uDAAI,QAAS,QACX,cAAa,IAAI,WAAW,QAAQ,QAAQ;AAG9C,uDAAI,QAAS,OACX,cAAa,IAAI,UAAU,QAAQ,OAAO;AAG5C,uDAAI,QAAS,kBACX,cAAa,IAAI,sBAAsB,QAAQ,kBAAkB;AAGnE,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,uDAAI,QAAS,OACX,cAAa,IAAI,WAAW,QAAQ,OAAO,UAAU,CAAC;AAGxD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,QAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,UAAU,GACjJ;;AAGH,MAAM,mBACJ,OACA,YACgB;;AAEhB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;AAYR,MAAa,eACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,SAAS;AAE5C,kBAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,CAAC,cACC,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EAAE,uBAAoC,oCAAC,aAAI,gBAAmB,KAClE;AACF,WAAO,eAAe,KAAK;;AAG7B,UAAO,oCAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-BjnSJS59.cjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport { 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 refetch?: () => void;\n}\n\n/**\n * @returns Authentication State\n */\nexport const useAuth = (): AuthState => {\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\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 async (url: string) => {\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 if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch: () => mutate(),\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: () => mutate(),\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 or is not a member of the specified groups.\n */\n onAccessDenied?: (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 * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected clinet rendered page component.\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?.onAccessDenied) {\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?.onAccessDenied) {\n return options.onAccessDenied();\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 { onAccessDenied = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return onAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;;;;AAkCA,MAAa,gBAA2B;CACtC,MAAM,EAAE,MAAM,OAAO,WAAW,4BAC9B,QAAQ,IAAI,4CAEV,GAAG,QAAQ,IAAI,0BAA0B,GAAG,qBAC9C,OAAO,QAAgB;EACrB,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,MAAI,IAAI,WAAW,IACjB;AAGF,MAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,QAAM,IAAI,MAAM,uBAAuB;GAE1C;AAED,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP,eAAe,QAAQ;EACxB;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP,eAAe,QAAQ;EACxB;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;AC3CH,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAChE,cAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,UAAU,CAChD;AAED,uDAAI,QAAS,OACX,cAAa,IAAI,SAAS,QAAQ,OAAO;AAE3C,uDAAI,QAAS,SACX,cAAa,IAAI,YAAY,QAAQ,SAAS;AAGhD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,IAAI,CAAC;AAG7D,uDAAI,QAAS,QACX,cAAa,IAAI,WAAW,QAAQ,QAAQ;AAG9C,uDAAI,QAAS,OACX,cAAa,IAAI,UAAU,QAAQ,OAAO;AAG5C,uDAAI,QAAS,kBACX,cAAa,IAAI,sBAAsB,QAAQ,kBAAkB;AAGnE,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,uDAAI,QAAS,OACX,cAAa,IAAI,WAAW,QAAQ,OAAO,UAAU,CAAC;AAGxD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,QAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,UAAU,GACjJ;;AAGH,MAAM,mBACJ,OACA,YACgB;;AAEhB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;AAYR,MAAa,eACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,SAAS;AAE5C,6BAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,oDACE,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EAAE,uBAAoC,4CAAC,aAAI,gBAAmB,KAClE;AACF,WAAO,eAAe,KAAK;;AAG7B,UAAO,4CAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}