@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.
@@ -1,4 +1,4 @@
1
- const require_chunk = require('./chunk-CbDLau6x.cjs');
1
+ const require_chunk = require('./chunk-C0xms8kb.cjs');
2
2
  let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
3
3
  let swr = require("swr");
4
4
  swr = require_chunk.__toESM(swr);
@@ -14,32 +14,33 @@ const fetchUser = async (url) => {
14
14
  };
15
15
  /**
16
16
  *
17
- * Hook for getting the user's profile on client components
17
+ * `useAuth()` is a client-side hook that provides access to the current authentication state.
18
18
  *
19
- * @returns Authentication State
19
+ * It can only be used inside **Client Components**.
20
20
  *
21
- * @example App Router
22
- *
23
- * ```tsx
21
+ * @example Basic Usage
22
+ * ```tsx title="Basic Usage"
24
23
  * "use client";
25
24
  *
26
25
  * import { useAuth } from "@monocloud/auth-nextjs/client";
27
26
  *
28
27
  * export default function Home() {
29
- * const { user } = useAuth();
28
+ * const { user, isAuthenticated } = useAuth();
29
+ *
30
+ * if (!isAuthenticated) {
31
+ * return <>Not signed in</>;
32
+ * }
30
33
  *
31
34
  * return <>User Id: {user?.sub}</>;
32
35
  * }
33
36
  * ```
34
37
  *
35
- * @example App Router - Refetch user from Userinfo endpoint
38
+ * @example Refetch user
36
39
  *
37
- * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.
38
- * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`
40
+ * Calling `refetch(true)` forces a refresh of the user profile from the UserInfo endpoint.
41
+ * Calling `refetch()` refreshes authentication state without forcing a UserInfo request.
39
42
  *
40
- * **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**
41
- *
42
- * ```tsx
43
+ * ```tsx title="Refetch User"
43
44
  * "use client";
44
45
  *
45
46
  * import { useAuth } from "@monocloud/auth-nextjs/client";
@@ -49,47 +50,16 @@ const fetchUser = async (url) => {
49
50
  *
50
51
  * return (
51
52
  * <>
52
- * <pre>{JSON.stringify(user)}</pre>
53
- * <button onClick={() => refetch(true)}>Refresh</button>
53
+ * <pre>{JSON.stringify(user, null, 2)}</pre>
54
+ * <button onClick={() => refetch(true)}>Refresh Profile</button>
54
55
  * </>
55
56
  * );
56
57
  * }
57
58
  * ```
58
59
  *
59
- * @example Pages Router
60
- *
61
- * ```tsx
62
- * import { useAuth } from "@monocloud/auth-nextjs/client";
63
- *
64
- * export default function Home() {
65
- * const { user } = useAuth();
66
- *
67
- * return <>User Id: {user?.sub}</>;
68
- * }
69
- * ```
70
- *
71
- * @example Pages Router - Refetch user from Userinfo endpoint
72
- *
73
- * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.
74
- * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`
75
- *
76
- * **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**
77
- *
78
- * ```tsx
79
- * import { useAuth } from "@monocloud/auth-nextjs/client";
80
- *
81
- * export default function Home() {
82
- * const { user, refetch } = useAuth();
83
- *
84
- * return (
85
- * <>
86
- * <pre>{JSON.stringify(user)}</pre>
87
- * <button onClick={() => refetch(true)}>Refresh</button>
88
- * </>
89
- * );
90
- * }
91
- * ```
60
+ * @returns
92
61
  *
62
+ * @category Hooks
93
63
  */
94
64
  const useAuth = () => {
95
65
  const key = process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`;
@@ -123,7 +93,7 @@ const useAuth = () => {
123
93
  };
124
94
 
125
95
  //#endregion
126
- //#region src/client/protect.tsx
96
+ //#region src/client/protect-client-page.tsx
127
97
  const redirectToSignIn = (options) => {
128
98
  const searchParams = new URLSearchParams(window.location.search);
129
99
  searchParams.set("return_url", options.returnUrl ?? window.location.toString());
@@ -145,110 +115,91 @@ const handlePageError = (error, options) => {
145
115
  throw error;
146
116
  };
147
117
  /**
148
- * Function to protect a client rendered page component.
149
- * Ensures that only authenticated users can access the component.
150
- *
151
- * **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.**
118
+ * `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.
152
119
  *
153
- * @param Component - The component to protect.
154
- * @param options - The options.
120
+ * If the user is authenticated, the wrapped component receives a `user` prop.
155
121
  *
156
- * @returns Protected client rendered page component.
122
+ * > This function runs on the client and controls rendering only.
123
+ * > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.
157
124
  *
158
- * @example App Router
125
+ * @example Basic Usage
159
126
  *
160
- * ```tsx
127
+ * ```tsx title="Basic Usage"
161
128
  * "use client";
162
129
  *
163
- * import { protectPage } from "@monocloud/auth-nextjs/client";
130
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
164
131
  *
165
- * export default protectPage(function Home() {
166
- * return <>You are signed in</>;
132
+ * export default protectClientPage(function Home({ user }) {
133
+ * return <>Signed in as {user.email}</>;
167
134
  * });
168
135
  * ```
169
136
  *
170
- * @example App Router with options
171
- *
172
- * See {@link ProtectPageOptions} for more options.
137
+ * @example With Options
173
138
  *
174
- * ```tsx
139
+ * ```tsx title="With Options"
175
140
  * "use client";
176
141
  *
177
- * import { protectPage } from "@monocloud/auth-nextjs/client";
142
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
178
143
  *
179
- * export default protectPage(
180
- * function Home() {
181
- * return <>You are signed in</>;
144
+ * export default protectClientPage(
145
+ * function Home({ user }) {
146
+ * return <>Signed in as {user.email}</>;
182
147
  * },
183
- * { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
148
+ * {
149
+ * returnUrl: "/dashboard",
150
+ * authParams: { loginHint: "user@example.com" }
151
+ * }
184
152
  * );
185
153
  * ```
186
- * @example Custom Fallback
187
154
  *
188
- * ```tsx
155
+ * @example Custom access denied UI
156
+ *
157
+ * ```tsx title="Custom access denied UI"
189
158
  * "use client";
190
159
  *
191
- * import { protectPage } from "@monocloud/auth-nextjs/client";
160
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
192
161
  *
193
- * export default protectPage(
194
- * function Home() {
195
- * return <>You are signed in</>;
162
+ * export default protectClientPage(
163
+ * function Home({ user }) {
164
+ * return <>Signed in as {user.email}</>;
196
165
  * },
197
166
  * {
198
- * fallback: () => <div>Please sign in to continue</div>
167
+ * onAccessDenied: () => <div>Please sign in to continue</div>
199
168
  * }
200
169
  * );
201
170
  * ```
202
171
  *
203
- * @example Group Protection with Group Fallback
172
+ * @example Group protection
204
173
  *
205
- * ```tsx
174
+ * ```tsx title="Group protection"
206
175
  * "use client";
207
176
  *
208
- * import { protectPage } from "@monocloud/auth-nextjs/client";
177
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
209
178
  *
210
- * export default protectPage(
211
- * function Home() {
212
- * return <>Welcome Admin</>;
179
+ * export default protectClientPage(
180
+ * function Home({ user }) {
181
+ * return <>Welcome Admin {user.email}</>;
213
182
  * },
214
183
  * {
215
184
  * groups: ["admin"],
216
- * groupFallback: (user) => <div>User {user.email} is not an admin</div>
185
+ * onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>
217
186
  * }
218
187
  * );
219
188
  * ```
220
189
  *
221
- * @example Pages Router
222
- *
223
- * ```tsx
224
- * import { protectPage } from "@monocloud/auth-nextjs/client";
225
- *
226
- * export default protectPage(function Home() {
227
- * return <>You are signed in</>;
228
- * });
229
- * ```
230
- *
231
- * @example Pages Router with options
232
- *
233
- * See {@link ProtectPageOptions} for more options.
190
+ * @param Component - The page component to protect
191
+ * @param options - Optional configuration
192
+ * @returns A protected React component.
234
193
  *
235
- * ```tsx
236
- * import { protectPage } from "@monocloud/auth-nextjs/client";
194
+ * @category Functions
237
195
  *
238
- * export default protectPage(
239
- * function Home() {
240
- * return <>You are signed in</>;
241
- * },
242
- * { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
243
- * );
244
- * ```
245
196
  */
246
- const protectPage = (Component, options) => {
197
+ const protectClientPage = (Component, options) => {
247
198
  return (props) => {
248
199
  const { user, error, isLoading } = useAuth();
249
200
  (0, react.useEffect)(() => {
250
201
  if (!user && !isLoading && !error) {
251
- if (options === null || options === void 0 ? void 0 : options.fallback) return;
202
+ if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
252
203
  const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
253
204
  redirectToSignIn({
254
205
  returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
@@ -261,11 +212,11 @@ const protectPage = (Component, options) => {
261
212
  error
262
213
  ]);
263
214
  if (error) return handlePageError(error, options);
264
- if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.fallback)) return options.fallback();
215
+ if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.onAccessDenied)) return options.onAccessDenied();
265
216
  if (user) {
266
217
  if ((options === null || options === void 0 ? void 0 : options.groups) && !(0, _monocloud_auth_node_core_utils.isUserInGroup)(user, options.groups, options.groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
267
- const { groupFallback = () => /* @__PURE__ */ react.default.createElement("div", null, "Access Denied") } = options;
268
- return groupFallback(user);
218
+ const { onGroupAccessDenied = () => /* @__PURE__ */ react.default.createElement("div", null, "Access Denied") } = options;
219
+ return onGroupAccessDenied(user);
269
220
  }
270
221
  return /* @__PURE__ */ react.default.createElement(Component, {
271
222
  user,
@@ -277,10 +228,10 @@ const protectPage = (Component, options) => {
277
228
  };
278
229
 
279
230
  //#endregion
280
- Object.defineProperty(exports, 'protectPage', {
231
+ Object.defineProperty(exports, 'protectClientPage', {
281
232
  enumerable: true,
282
233
  get: function () {
283
- return protectPage;
234
+ return protectClientPage;
284
235
  }
285
236
  });
286
237
  Object.defineProperty(exports, 'redirectToSignIn', {
@@ -295,4 +246,4 @@ Object.defineProperty(exports, 'useAuth', {
295
246
  return useAuth;
296
247
  }
297
248
  });
298
- //# sourceMappingURL=client-xfBYYato.cjs.map
249
+ //# sourceMappingURL=protect-client-page-B1fOU4Zl.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protect-client-page-B1fOU4Zl.cjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect-client-page.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 *\n * @category Types\n */\nexport interface AuthenticationState {\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 * `useAuth()` is a client-side hook that provides access to the current authentication state.\n *\n * It can only be used inside **Client Components**.\n *\n * @example Basic Usage\n * ```tsx title=\"Basic Usage\"\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user, isAuthenticated } = useAuth();\n *\n * if (!isAuthenticated) {\n * return <>Not signed in</>;\n * }\n *\n * return <>User Id: {user?.sub}</>;\n * }\n * ```\n *\n * @example Refetch user\n *\n * Calling `refetch(true)` forces a refresh of the user profile from the UserInfo endpoint.\n * Calling `refetch()` refreshes authentication state without forcing a UserInfo request.\n *\n * ```tsx title=\"Refetch User\"\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, null, 2)}</pre>\n * <button onClick={() => refetch(true)}>Refresh Profile</button>\n * </>\n * );\n * }\n * ```\n *\n * @returns\n *\n * @category Hooks\n */\nexport const useAuth = (): AuthenticationState => {\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, 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';\nimport type { MonoCloudNextClient } from '../monocloud-next-client';\n\n/**\n * Options for configuring page protection.\n *\n * @category Types\n */\nexport interface ProtectClientPageOptions extends GroupOptions {\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 onAccessDenied?: () => React.ReactNode;\n\n /**\n * A custom react element to render when the user is authenticated but does not belong to the required groups.\n */\n onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;\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) => React.ReactNode;\n}\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?: ProtectClientPageOptions\n): React.ReactNode => {\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 * `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.\n *\n * If the user is authenticated, the wrapped component receives a `user` prop.\n *\n * > This function runs on the client and controls rendering only.\n * > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(function Home({ user }) {\n * return <>Signed in as {user.email}</>;\n * });\n * ```\n *\n * @example With Options\n *\n * ```tsx title=\"With Options\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(\n * function Home({ user }) {\n * return <>Signed in as {user.email}</>;\n * },\n * {\n * returnUrl: \"/dashboard\",\n * authParams: { loginHint: \"user@example.com\" }\n * }\n * );\n * ```\n *\n * @example Custom access denied UI\n *\n * ```tsx title=\"Custom access denied UI\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(\n * function Home({ user }) {\n * return <>Signed in as {user.email}</>;\n * },\n * {\n * onAccessDenied: () => <div>Please sign in to continue</div>\n * }\n * );\n * ```\n *\n * @example Group protection\n *\n * ```tsx title=\"Group protection\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(\n * function Home({ user }) {\n * return <>Welcome Admin {user.email}</>;\n * },\n * {\n * groups: [\"admin\"],\n * onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>\n * }\n * );\n * ```\n *\n * @param Component - The page component to protect\n * @param options - Optional configuration\n * @returns A protected React component.\n *\n * @category Functions\n *\n */\nexport const protectClientPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectClientPageOptions\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 {\n onGroupAccessDenied = (): React.ReactNode => <div>Access Denied</div>,\n } = options;\n return onGroupAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;AAkCA,MAAM,YAAY,OAAO,QAAoD;CAC3E,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,KAAI,IAAI,WAAW,IACjB;AAGF,KAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,OAAM,IAAI,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDzC,MAAa,gBAAqC;CAChD,MAAM,MACJ,QAAQ,IAAI,4CAEZ,GAAG,QAAQ,IAAI,0BAA0B,GAAG;CAE9C,MAAM,EAAE,MAAM,OAAO,WAAW,4BAC9B,KACA,UACD;CAED,MAAM,WAAW,YAA4B;EAC3C,MAAM,MAAM,IAAI,IAAI,KAAK,gBAAgB;AACzC,MAAI,QACF,KAAI,aAAa,IAAI,WAAW,OAAO;AAGzC,EAAK,OAAO,YAAY,MAAM,UAAU,IAAI,WAAW,IAAI,OAAO,EAAE,EAClE,YAAY,OACb,CAAC;;AAGJ,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP;EACD;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP;EACD;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;ACpGH,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,YACoB;;AAEpB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFR,MAAa,qBACX,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,EACJ,4BAA6C,4CAAC,aAAI,gBAAmB,KACnE;AACJ,WAAO,oBAAoB,KAAK;;AAGlC,UAAO,4CAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
@@ -11,32 +11,33 @@ const fetchUser = async (url) => {
11
11
  };
12
12
  /**
13
13
  *
14
- * Hook for getting the user's profile on client components
14
+ * `useAuth()` is a client-side hook that provides access to the current authentication state.
15
15
  *
16
- * @returns Authentication State
16
+ * It can only be used inside **Client Components**.
17
17
  *
18
- * @example App Router
19
- *
20
- * ```tsx
18
+ * @example Basic Usage
19
+ * ```tsx title="Basic Usage"
21
20
  * "use client";
22
21
  *
23
22
  * import { useAuth } from "@monocloud/auth-nextjs/client";
24
23
  *
25
24
  * export default function Home() {
26
- * const { user } = useAuth();
25
+ * const { user, isAuthenticated } = useAuth();
26
+ *
27
+ * if (!isAuthenticated) {
28
+ * return <>Not signed in</>;
29
+ * }
27
30
  *
28
31
  * return <>User Id: {user?.sub}</>;
29
32
  * }
30
33
  * ```
31
34
  *
32
- * @example App Router - Refetch user from Userinfo endpoint
35
+ * @example Refetch user
33
36
  *
34
- * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.
35
- * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`
37
+ * Calling `refetch(true)` forces a refresh of the user profile from the UserInfo endpoint.
38
+ * Calling `refetch()` refreshes authentication state without forcing a UserInfo request.
36
39
  *
37
- * **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**
38
- *
39
- * ```tsx
40
+ * ```tsx title="Refetch User"
40
41
  * "use client";
41
42
  *
42
43
  * import { useAuth } from "@monocloud/auth-nextjs/client";
@@ -46,47 +47,16 @@ const fetchUser = async (url) => {
46
47
  *
47
48
  * return (
48
49
  * <>
49
- * <pre>{JSON.stringify(user)}</pre>
50
- * <button onClick={() => refetch(true)}>Refresh</button>
50
+ * <pre>{JSON.stringify(user, null, 2)}</pre>
51
+ * <button onClick={() => refetch(true)}>Refresh Profile</button>
51
52
  * </>
52
53
  * );
53
54
  * }
54
55
  * ```
55
56
  *
56
- * @example Pages Router
57
- *
58
- * ```tsx
59
- * import { useAuth } from "@monocloud/auth-nextjs/client";
60
- *
61
- * export default function Home() {
62
- * const { user } = useAuth();
63
- *
64
- * return <>User Id: {user?.sub}</>;
65
- * }
66
- * ```
67
- *
68
- * @example Pages Router - Refetch user from Userinfo endpoint
69
- *
70
- * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.
71
- * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`
72
- *
73
- * **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**
74
- *
75
- * ```tsx
76
- * import { useAuth } from "@monocloud/auth-nextjs/client";
77
- *
78
- * export default function Home() {
79
- * const { user, refetch } = useAuth();
80
- *
81
- * return (
82
- * <>
83
- * <pre>{JSON.stringify(user)}</pre>
84
- * <button onClick={() => refetch(true)}>Refresh</button>
85
- * </>
86
- * );
87
- * }
88
- * ```
57
+ * @returns
89
58
  *
59
+ * @category Hooks
90
60
  */
91
61
  const useAuth = () => {
92
62
  const key = process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`;
@@ -120,7 +90,7 @@ const useAuth = () => {
120
90
  };
121
91
 
122
92
  //#endregion
123
- //#region src/client/protect.tsx
93
+ //#region src/client/protect-client-page.tsx
124
94
  const redirectToSignIn = (options) => {
125
95
  const searchParams = new URLSearchParams(window.location.search);
126
96
  searchParams.set("return_url", options.returnUrl ?? window.location.toString());
@@ -142,110 +112,91 @@ const handlePageError = (error, options) => {
142
112
  throw error;
143
113
  };
144
114
  /**
145
- * Function to protect a client rendered page component.
146
- * Ensures that only authenticated users can access the component.
147
- *
148
- * **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.**
115
+ * `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.
149
116
  *
150
- * @param Component - The component to protect.
151
- * @param options - The options.
117
+ * If the user is authenticated, the wrapped component receives a `user` prop.
152
118
  *
153
- * @returns Protected client rendered page component.
119
+ * > This function runs on the client and controls rendering only.
120
+ * > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.
154
121
  *
155
- * @example App Router
122
+ * @example Basic Usage
156
123
  *
157
- * ```tsx
124
+ * ```tsx title="Basic Usage"
158
125
  * "use client";
159
126
  *
160
- * import { protectPage } from "@monocloud/auth-nextjs/client";
127
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
161
128
  *
162
- * export default protectPage(function Home() {
163
- * return <>You are signed in</>;
129
+ * export default protectClientPage(function Home({ user }) {
130
+ * return <>Signed in as {user.email}</>;
164
131
  * });
165
132
  * ```
166
133
  *
167
- * @example App Router with options
168
- *
169
- * See {@link ProtectPageOptions} for more options.
134
+ * @example With Options
170
135
  *
171
- * ```tsx
136
+ * ```tsx title="With Options"
172
137
  * "use client";
173
138
  *
174
- * import { protectPage } from "@monocloud/auth-nextjs/client";
139
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
175
140
  *
176
- * export default protectPage(
177
- * function Home() {
178
- * return <>You are signed in</>;
141
+ * export default protectClientPage(
142
+ * function Home({ user }) {
143
+ * return <>Signed in as {user.email}</>;
179
144
  * },
180
- * { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
145
+ * {
146
+ * returnUrl: "/dashboard",
147
+ * authParams: { loginHint: "user@example.com" }
148
+ * }
181
149
  * );
182
150
  * ```
183
- * @example Custom Fallback
184
151
  *
185
- * ```tsx
152
+ * @example Custom access denied UI
153
+ *
154
+ * ```tsx title="Custom access denied UI"
186
155
  * "use client";
187
156
  *
188
- * import { protectPage } from "@monocloud/auth-nextjs/client";
157
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
189
158
  *
190
- * export default protectPage(
191
- * function Home() {
192
- * return <>You are signed in</>;
159
+ * export default protectClientPage(
160
+ * function Home({ user }) {
161
+ * return <>Signed in as {user.email}</>;
193
162
  * },
194
163
  * {
195
- * fallback: () => <div>Please sign in to continue</div>
164
+ * onAccessDenied: () => <div>Please sign in to continue</div>
196
165
  * }
197
166
  * );
198
167
  * ```
199
168
  *
200
- * @example Group Protection with Group Fallback
169
+ * @example Group protection
201
170
  *
202
- * ```tsx
171
+ * ```tsx title="Group protection"
203
172
  * "use client";
204
173
  *
205
- * import { protectPage } from "@monocloud/auth-nextjs/client";
174
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
206
175
  *
207
- * export default protectPage(
208
- * function Home() {
209
- * return <>Welcome Admin</>;
176
+ * export default protectClientPage(
177
+ * function Home({ user }) {
178
+ * return <>Welcome Admin {user.email}</>;
210
179
  * },
211
180
  * {
212
181
  * groups: ["admin"],
213
- * groupFallback: (user) => <div>User {user.email} is not an admin</div>
182
+ * onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>
214
183
  * }
215
184
  * );
216
185
  * ```
217
186
  *
218
- * @example Pages Router
219
- *
220
- * ```tsx
221
- * import { protectPage } from "@monocloud/auth-nextjs/client";
222
- *
223
- * export default protectPage(function Home() {
224
- * return <>You are signed in</>;
225
- * });
226
- * ```
227
- *
228
- * @example Pages Router with options
229
- *
230
- * See {@link ProtectPageOptions} for more options.
187
+ * @param Component - The page component to protect
188
+ * @param options - Optional configuration
189
+ * @returns A protected React component.
231
190
  *
232
- * ```tsx
233
- * import { protectPage } from "@monocloud/auth-nextjs/client";
191
+ * @category Functions
234
192
  *
235
- * export default protectPage(
236
- * function Home() {
237
- * return <>You are signed in</>;
238
- * },
239
- * { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
240
- * );
241
- * ```
242
193
  */
243
- const protectPage = (Component, options) => {
194
+ const protectClientPage = (Component, options) => {
244
195
  return (props) => {
245
196
  const { user, error, isLoading } = useAuth();
246
197
  useEffect(() => {
247
198
  if (!user && !isLoading && !error) {
248
- if (options === null || options === void 0 ? void 0 : options.fallback) return;
199
+ if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
249
200
  const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
250
201
  redirectToSignIn({
251
202
  returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
@@ -258,11 +209,11 @@ const protectPage = (Component, options) => {
258
209
  error
259
210
  ]);
260
211
  if (error) return handlePageError(error, options);
261
- if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.fallback)) return options.fallback();
212
+ if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.onAccessDenied)) return options.onAccessDenied();
262
213
  if (user) {
263
214
  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)) {
264
- const { groupFallback = () => /* @__PURE__ */ React.createElement("div", null, "Access Denied") } = options;
265
- return groupFallback(user);
215
+ const { onGroupAccessDenied = () => /* @__PURE__ */ React.createElement("div", null, "Access Denied") } = options;
216
+ return onGroupAccessDenied(user);
266
217
  }
267
218
  return /* @__PURE__ */ React.createElement(Component, {
268
219
  user,
@@ -274,5 +225,5 @@ const protectPage = (Component, options) => {
274
225
  };
275
226
 
276
227
  //#endregion
277
- export { redirectToSignIn as n, useAuth as r, protectPage as t };
278
- //# sourceMappingURL=client-D-3RMRNY.mjs.map
228
+ export { redirectToSignIn as n, useAuth as r, protectClientPage as t };
229
+ //# sourceMappingURL=protect-client-page-BFlGkK8F.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protect-client-page-BFlGkK8F.mjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect-client-page.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 *\n * @category Types\n */\nexport interface AuthenticationState {\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 * `useAuth()` is a client-side hook that provides access to the current authentication state.\n *\n * It can only be used inside **Client Components**.\n *\n * @example Basic Usage\n * ```tsx title=\"Basic Usage\"\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n *\n * export default function Home() {\n * const { user, isAuthenticated } = useAuth();\n *\n * if (!isAuthenticated) {\n * return <>Not signed in</>;\n * }\n *\n * return <>User Id: {user?.sub}</>;\n * }\n * ```\n *\n * @example Refetch user\n *\n * Calling `refetch(true)` forces a refresh of the user profile from the UserInfo endpoint.\n * Calling `refetch()` refreshes authentication state without forcing a UserInfo request.\n *\n * ```tsx title=\"Refetch User\"\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, null, 2)}</pre>\n * <button onClick={() => refetch(true)}>Refresh Profile</button>\n * </>\n * );\n * }\n * ```\n *\n * @returns\n *\n * @category Hooks\n */\nexport const useAuth = (): AuthenticationState => {\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, 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';\nimport type { MonoCloudNextClient } from '../monocloud-next-client';\n\n/**\n * Options for configuring page protection.\n *\n * @category Types\n */\nexport interface ProtectClientPageOptions extends GroupOptions {\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 onAccessDenied?: () => React.ReactNode;\n\n /**\n * A custom react element to render when the user is authenticated but does not belong to the required groups.\n */\n onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;\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) => React.ReactNode;\n}\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?: ProtectClientPageOptions\n): React.ReactNode => {\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 * `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.\n *\n * If the user is authenticated, the wrapped component receives a `user` prop.\n *\n * > This function runs on the client and controls rendering only.\n * > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(function Home({ user }) {\n * return <>Signed in as {user.email}</>;\n * });\n * ```\n *\n * @example With Options\n *\n * ```tsx title=\"With Options\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(\n * function Home({ user }) {\n * return <>Signed in as {user.email}</>;\n * },\n * {\n * returnUrl: \"/dashboard\",\n * authParams: { loginHint: \"user@example.com\" }\n * }\n * );\n * ```\n *\n * @example Custom access denied UI\n *\n * ```tsx title=\"Custom access denied UI\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(\n * function Home({ user }) {\n * return <>Signed in as {user.email}</>;\n * },\n * {\n * onAccessDenied: () => <div>Please sign in to continue</div>\n * }\n * );\n * ```\n *\n * @example Group protection\n *\n * ```tsx title=\"Group protection\"\n * \"use client\";\n *\n * import { protectClientPage } from \"@monocloud/auth-nextjs/client\";\n *\n * export default protectClientPage(\n * function Home({ user }) {\n * return <>Welcome Admin {user.email}</>;\n * },\n * {\n * groups: [\"admin\"],\n * onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>\n * }\n * );\n * ```\n *\n * @param Component - The page component to protect\n * @param options - Optional configuration\n * @returns A protected React component.\n *\n * @category Functions\n *\n */\nexport const protectClientPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectClientPageOptions\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 {\n onGroupAccessDenied = (): React.ReactNode => <div>Access Denied</div>,\n } = options;\n return onGroupAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":"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"}