@monocloud/auth-nextjs 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.mts +43 -5
- package/dist/client/index.mjs +1 -1
- package/dist/{client-CnvBgZM-.mjs → client-D-3RMRNY.mjs} +43 -9
- package/dist/client-D-3RMRNY.mjs.map +1 -0
- package/dist/{client-Be6A2vEn.cjs → client-xfBYYato.cjs} +43 -9
- package/dist/client-xfBYYato.cjs.map +1 -0
- package/dist/components/client/index.cjs +9 -9
- package/dist/components/client/index.cjs.map +1 -1
- package/dist/components/client/index.d.mts +13 -8
- package/dist/components/client/index.mjs +9 -9
- package/dist/components/client/index.mjs.map +1 -1
- package/dist/components/index.d.mts +1 -1
- package/dist/index.cjs +29 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +21 -12
- package/dist/index.mjs +30 -14
- package/dist/index.mjs.map +1 -1
- package/dist/{types-DOfZTKa6.d.mts → types-CsBjAJce.d.mts} +79 -20
- package/package.json +3 -3
- package/dist/client-Be6A2vEn.cjs.map +0 -1
- package/dist/client-CnvBgZM-.mjs.map +0 -1
package/dist/client/index.cjs
CHANGED
package/dist/client/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as GroupOptions, i as ExtraAuthParams } from "../types-
|
|
1
|
+
import { a as GroupOptions, i as ExtraAuthParams } from "../types-CsBjAJce.mjs";
|
|
2
2
|
import { MonoCloudUser } from "@monocloud/auth-node-core";
|
|
3
3
|
import React, { ComponentType, JSX } from "react";
|
|
4
4
|
|
|
@@ -120,9 +120,13 @@ type ProtectPageOptions = {
|
|
|
120
120
|
*/
|
|
121
121
|
returnUrl?: string;
|
|
122
122
|
/**
|
|
123
|
-
* A custom react element to render when the user is not authenticated
|
|
123
|
+
* A custom react element to render when the user is not authenticated.
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
fallback?: (user?: MonoCloudUser) => JSX.Element;
|
|
126
|
+
/**
|
|
127
|
+
* A custom react element to render when the user is authenticated but does not belong to the required groups.
|
|
128
|
+
*/
|
|
129
|
+
groupFallback?: (user: MonoCloudUser) => JSX.Element;
|
|
126
130
|
/**
|
|
127
131
|
* Authorization parameters to be used during authentication.
|
|
128
132
|
*/
|
|
@@ -175,8 +179,42 @@ type ProtectPageOptions = {
|
|
|
175
179
|
* { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
|
|
176
180
|
* );
|
|
177
181
|
* ```
|
|
178
|
-
|
|
179
|
-
*
|
|
182
|
+
* @example Custom Fallback
|
|
183
|
+
*
|
|
184
|
+
* ```tsx
|
|
185
|
+
* "use client";
|
|
186
|
+
*
|
|
187
|
+
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
|
188
|
+
*
|
|
189
|
+
* export default protectPage(
|
|
190
|
+
* function Home() {
|
|
191
|
+
* return <>You are signed in</>;
|
|
192
|
+
* },
|
|
193
|
+
* {
|
|
194
|
+
* fallback: () => <div>Please sign in to continue</div>
|
|
195
|
+
* }
|
|
196
|
+
* );
|
|
197
|
+
* ```
|
|
198
|
+
*
|
|
199
|
+
* @example Group Protection with Group Fallback
|
|
200
|
+
*
|
|
201
|
+
* ```tsx
|
|
202
|
+
* "use client";
|
|
203
|
+
*
|
|
204
|
+
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
|
205
|
+
*
|
|
206
|
+
* export default protectPage(
|
|
207
|
+
* function Home() {
|
|
208
|
+
* return <>Welcome Admin</>;
|
|
209
|
+
* },
|
|
210
|
+
* {
|
|
211
|
+
* groups: ["admin"],
|
|
212
|
+
* groupFallback: (user) => <div>User {user.email} is not an admin</div>
|
|
213
|
+
* }
|
|
214
|
+
* );
|
|
215
|
+
* ```
|
|
216
|
+
*
|
|
217
|
+
* @example Pages Router
|
|
180
218
|
*
|
|
181
219
|
* ```tsx
|
|
182
220
|
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
package/dist/client/index.mjs
CHANGED
|
@@ -144,7 +144,7 @@ const handlePageError = (error, options) => {
|
|
|
144
144
|
/**
|
|
145
145
|
* Function to protect a client rendered page component.
|
|
146
146
|
* Ensures that only authenticated users can access the component.
|
|
147
|
-
*
|
|
147
|
+
*
|
|
148
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.**
|
|
149
149
|
*
|
|
150
150
|
* @param Component - The component to protect.
|
|
@@ -165,7 +165,7 @@ const handlePageError = (error, options) => {
|
|
|
165
165
|
* ```
|
|
166
166
|
*
|
|
167
167
|
* @example App Router with options
|
|
168
|
-
*
|
|
168
|
+
*
|
|
169
169
|
* See {@link ProtectPageOptions} for more options.
|
|
170
170
|
*
|
|
171
171
|
* ```tsx
|
|
@@ -180,7 +180,41 @@ const handlePageError = (error, options) => {
|
|
|
180
180
|
* { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
|
|
181
181
|
* );
|
|
182
182
|
* ```
|
|
183
|
-
|
|
183
|
+
* @example Custom Fallback
|
|
184
|
+
*
|
|
185
|
+
* ```tsx
|
|
186
|
+
* "use client";
|
|
187
|
+
*
|
|
188
|
+
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
|
189
|
+
*
|
|
190
|
+
* export default protectPage(
|
|
191
|
+
* function Home() {
|
|
192
|
+
* return <>You are signed in</>;
|
|
193
|
+
* },
|
|
194
|
+
* {
|
|
195
|
+
* fallback: () => <div>Please sign in to continue</div>
|
|
196
|
+
* }
|
|
197
|
+
* );
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @example Group Protection with Group Fallback
|
|
201
|
+
*
|
|
202
|
+
* ```tsx
|
|
203
|
+
* "use client";
|
|
204
|
+
*
|
|
205
|
+
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
|
206
|
+
*
|
|
207
|
+
* export default protectPage(
|
|
208
|
+
* function Home() {
|
|
209
|
+
* return <>Welcome Admin</>;
|
|
210
|
+
* },
|
|
211
|
+
* {
|
|
212
|
+
* groups: ["admin"],
|
|
213
|
+
* groupFallback: (user) => <div>User {user.email} is not an admin</div>
|
|
214
|
+
* }
|
|
215
|
+
* );
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
184
218
|
* @example Pages Router
|
|
185
219
|
*
|
|
186
220
|
* ```tsx
|
|
@@ -192,7 +226,7 @@ const handlePageError = (error, options) => {
|
|
|
192
226
|
* ```
|
|
193
227
|
*
|
|
194
228
|
* @example Pages Router with options
|
|
195
|
-
*
|
|
229
|
+
*
|
|
196
230
|
* See {@link ProtectPageOptions} for more options.
|
|
197
231
|
*
|
|
198
232
|
* ```tsx
|
|
@@ -211,7 +245,7 @@ const protectPage = (Component, options) => {
|
|
|
211
245
|
const { user, error, isLoading } = useAuth();
|
|
212
246
|
useEffect(() => {
|
|
213
247
|
if (!user && !isLoading && !error) {
|
|
214
|
-
if (options === null || options === void 0 ? void 0 : options.
|
|
248
|
+
if (options === null || options === void 0 ? void 0 : options.fallback) return;
|
|
215
249
|
const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
|
|
216
250
|
redirectToSignIn({
|
|
217
251
|
returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
|
|
@@ -224,11 +258,11 @@ const protectPage = (Component, options) => {
|
|
|
224
258
|
error
|
|
225
259
|
]);
|
|
226
260
|
if (error) return handlePageError(error, options);
|
|
227
|
-
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.
|
|
261
|
+
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.fallback)) return options.fallback();
|
|
228
262
|
if (user) {
|
|
229
263
|
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)) {
|
|
230
|
-
const {
|
|
231
|
-
return
|
|
264
|
+
const { groupFallback = () => /* @__PURE__ */ React.createElement("div", null, "Access Denied") } = options;
|
|
265
|
+
return groupFallback(user);
|
|
232
266
|
}
|
|
233
267
|
return /* @__PURE__ */ React.createElement(Component, {
|
|
234
268
|
user,
|
|
@@ -241,4 +275,4 @@ const protectPage = (Component, options) => {
|
|
|
241
275
|
|
|
242
276
|
//#endregion
|
|
243
277
|
export { redirectToSignIn as n, useAuth as r, protectPage as t };
|
|
244
|
-
//# sourceMappingURL=client-
|
|
278
|
+
//# sourceMappingURL=client-D-3RMRNY.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
|
@@ -147,7 +147,7 @@ const handlePageError = (error, options) => {
|
|
|
147
147
|
/**
|
|
148
148
|
* Function to protect a client rendered page component.
|
|
149
149
|
* Ensures that only authenticated users can access the component.
|
|
150
|
-
*
|
|
150
|
+
*
|
|
151
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.**
|
|
152
152
|
*
|
|
153
153
|
* @param Component - The component to protect.
|
|
@@ -168,7 +168,7 @@ const handlePageError = (error, options) => {
|
|
|
168
168
|
* ```
|
|
169
169
|
*
|
|
170
170
|
* @example App Router with options
|
|
171
|
-
*
|
|
171
|
+
*
|
|
172
172
|
* See {@link ProtectPageOptions} for more options.
|
|
173
173
|
*
|
|
174
174
|
* ```tsx
|
|
@@ -183,7 +183,41 @@ const handlePageError = (error, options) => {
|
|
|
183
183
|
* { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
|
|
184
184
|
* );
|
|
185
185
|
* ```
|
|
186
|
-
|
|
186
|
+
* @example Custom Fallback
|
|
187
|
+
*
|
|
188
|
+
* ```tsx
|
|
189
|
+
* "use client";
|
|
190
|
+
*
|
|
191
|
+
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
|
192
|
+
*
|
|
193
|
+
* export default protectPage(
|
|
194
|
+
* function Home() {
|
|
195
|
+
* return <>You are signed in</>;
|
|
196
|
+
* },
|
|
197
|
+
* {
|
|
198
|
+
* fallback: () => <div>Please sign in to continue</div>
|
|
199
|
+
* }
|
|
200
|
+
* );
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @example Group Protection with Group Fallback
|
|
204
|
+
*
|
|
205
|
+
* ```tsx
|
|
206
|
+
* "use client";
|
|
207
|
+
*
|
|
208
|
+
* import { protectPage } from "@monocloud/auth-nextjs/client";
|
|
209
|
+
*
|
|
210
|
+
* export default protectPage(
|
|
211
|
+
* function Home() {
|
|
212
|
+
* return <>Welcome Admin</>;
|
|
213
|
+
* },
|
|
214
|
+
* {
|
|
215
|
+
* groups: ["admin"],
|
|
216
|
+
* groupFallback: (user) => <div>User {user.email} is not an admin</div>
|
|
217
|
+
* }
|
|
218
|
+
* );
|
|
219
|
+
* ```
|
|
220
|
+
*
|
|
187
221
|
* @example Pages Router
|
|
188
222
|
*
|
|
189
223
|
* ```tsx
|
|
@@ -195,7 +229,7 @@ const handlePageError = (error, options) => {
|
|
|
195
229
|
* ```
|
|
196
230
|
*
|
|
197
231
|
* @example Pages Router with options
|
|
198
|
-
*
|
|
232
|
+
*
|
|
199
233
|
* See {@link ProtectPageOptions} for more options.
|
|
200
234
|
*
|
|
201
235
|
* ```tsx
|
|
@@ -214,7 +248,7 @@ const protectPage = (Component, options) => {
|
|
|
214
248
|
const { user, error, isLoading } = useAuth();
|
|
215
249
|
(0, react.useEffect)(() => {
|
|
216
250
|
if (!user && !isLoading && !error) {
|
|
217
|
-
if (options === null || options === void 0 ? void 0 : options.
|
|
251
|
+
if (options === null || options === void 0 ? void 0 : options.fallback) return;
|
|
218
252
|
const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
|
|
219
253
|
redirectToSignIn({
|
|
220
254
|
returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
|
|
@@ -227,11 +261,11 @@ const protectPage = (Component, options) => {
|
|
|
227
261
|
error
|
|
228
262
|
]);
|
|
229
263
|
if (error) return handlePageError(error, options);
|
|
230
|
-
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.
|
|
264
|
+
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.fallback)) return options.fallback();
|
|
231
265
|
if (user) {
|
|
232
266
|
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)) {
|
|
233
|
-
const {
|
|
234
|
-
return
|
|
267
|
+
const { groupFallback = () => /* @__PURE__ */ react.default.createElement("div", null, "Access Denied") } = options;
|
|
268
|
+
return groupFallback(user);
|
|
235
269
|
}
|
|
236
270
|
return /* @__PURE__ */ react.default.createElement(Component, {
|
|
237
271
|
user,
|
|
@@ -261,4 +295,4 @@ Object.defineProperty(exports, 'useAuth', {
|
|
|
261
295
|
return useAuth;
|
|
262
296
|
}
|
|
263
297
|
});
|
|
264
|
-
//# sourceMappingURL=client-
|
|
298
|
+
//# sourceMappingURL=client-xfBYYato.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require('../../chunk-CbDLau6x.cjs');
|
|
2
|
-
const require_client = require('../../client-
|
|
2
|
+
const require_client = require('../../client-xfBYYato.cjs');
|
|
3
3
|
let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
react = require_chunk.__toESM(react);
|
|
@@ -110,7 +110,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
110
110
|
*
|
|
111
111
|
* @param props - Props for customizing the Protected component.
|
|
112
112
|
*
|
|
113
|
-
* @returns The children if authorized, the `
|
|
113
|
+
* @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,
|
|
114
114
|
* or `null` while loading.
|
|
115
115
|
*
|
|
116
116
|
* @example App Router
|
|
@@ -122,7 +122,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
122
122
|
*
|
|
123
123
|
* export default function Home() {
|
|
124
124
|
* return (
|
|
125
|
-
* <Protected
|
|
125
|
+
* <Protected fallback={<>Sign in to view the message.</>}>
|
|
126
126
|
* <>You are breathtaking</>
|
|
127
127
|
* </Protected>
|
|
128
128
|
* );
|
|
@@ -141,7 +141,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
141
141
|
* export default function Home() {
|
|
142
142
|
* return (
|
|
143
143
|
* <Protected
|
|
144
|
-
*
|
|
144
|
+
* groupFallback={<>Only admins are allowed.</>}
|
|
145
145
|
* groups={["admin"]}
|
|
146
146
|
* >
|
|
147
147
|
* <>Signed in as admin</>
|
|
@@ -157,7 +157,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
157
157
|
*
|
|
158
158
|
* export default function Home() {
|
|
159
159
|
* return (
|
|
160
|
-
* <Protected
|
|
160
|
+
* <Protected fallback={<>Sign in to view the message.</>}>
|
|
161
161
|
* <>You are breathtaking</>
|
|
162
162
|
* </Protected>
|
|
163
163
|
* );
|
|
@@ -174,7 +174,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
174
174
|
* export default function Home() {
|
|
175
175
|
* return (
|
|
176
176
|
* <Protected
|
|
177
|
-
*
|
|
177
|
+
* groupFallback={<>Only admins are allowed.</>}
|
|
178
178
|
* groups={["admin"]}
|
|
179
179
|
* >
|
|
180
180
|
* <>Signed in as admin</>
|
|
@@ -184,14 +184,14 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
184
184
|
* ```
|
|
185
185
|
*
|
|
186
186
|
*/
|
|
187
|
-
const Protected = ({ children, groups, groupsClaim, matchAllGroups = false,
|
|
187
|
+
const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, fallback = null, groupFallback = null }) => {
|
|
188
188
|
const { isLoading, error, isAuthenticated, user } = require_client.useAuth();
|
|
189
189
|
if (isLoading) return null;
|
|
190
190
|
if (error || !isAuthenticated || !user) {
|
|
191
|
-
if (
|
|
191
|
+
if (fallback) return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, fallback);
|
|
192
192
|
return null;
|
|
193
193
|
}
|
|
194
|
-
return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, !groups || (0, _monocloud_auth_node_core_utils.isUserInGroup)(user, groups, groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, matchAllGroups) ? children :
|
|
194
|
+
return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, !groups || (0, _monocloud_auth_node_core_utils.isUserInGroup)(user, groups, groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, matchAllGroups) ? children : groupFallback);
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["useAuth"],"sources":["../../../src/components/client/redirect-to-signin.tsx","../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The url where the user will be redirected to after sign in.\n */\n returnUrl?: string;\n}\n\n/**\n * A client side component that will redirect users to the sign in page.\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 props - The props for customizing RedirectToSignIn\n *\n * @returns\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example App Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n */\nexport const RedirectToSignIn = ({\n returnUrl,\n ...authParams\n}: RedirectToSignInProps): null => {\n useEffect(() => {\n redirectToSignIn({ returnUrl, ...authParams });\n }, [authParams, returnUrl]);\n return null;\n};\n","import { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React, { JSX } from 'react';\nimport { useAuth } from '../../client';\n\nexport interface ProtectedComponentProps {\n /**\n * Components that should be rendered if the user is authenticated.\n */\n children: React.ReactNode;\n\n /**\n * A list of group names or IDs to which the user must belong to. The user should belong to atleast one of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim of user's groups. default: `groups`.\n */\n groupsClaim?: string;\n\n /**\n * Flag indicating if all groups specified should be present in the users profile. default: false.\n */\n matchAllGroups?: boolean;\n\n /**\n * A fallback component that should render if the user is not authenticated.\n */\n
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["useAuth"],"sources":["../../../src/components/client/redirect-to-signin.tsx","../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The url where the user will be redirected to after sign in.\n */\n returnUrl?: string;\n}\n\n/**\n * A client side component that will redirect users to the sign in page.\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 props - The props for customizing RedirectToSignIn\n *\n * @returns\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example App Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n */\nexport const RedirectToSignIn = ({\n returnUrl,\n ...authParams\n}: RedirectToSignInProps): null => {\n useEffect(() => {\n redirectToSignIn({ returnUrl, ...authParams });\n }, [authParams, returnUrl]);\n return null;\n};\n","import { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React, { JSX } from 'react';\nimport { useAuth } from '../../client';\n\nexport interface ProtectedComponentProps {\n /**\n * Components that should be rendered if the user is authenticated.\n */\n children: React.ReactNode;\n\n /**\n * A list of group names or IDs to which the user must belong to. The user should belong to atleast one of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim of user's groups. default: `groups`.\n */\n groupsClaim?: string;\n\n /**\n * Flag indicating if all groups specified should be present in the users profile. default: false.\n */\n matchAllGroups?: boolean;\n\n /**\n * A fallback component that should render if the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * A fallback component that should render if the user is authenticated but does not belong to the required groups.\n */\n groupFallback?: React.ReactNode;\n}\n\n/**\n * A wrapper component that conditionally renders its children based on the user's authentication\n * status and group membership.\n *\n * **Note⚠️: The component is hidden from view. The data is present in the browser. Use server side `protectPage()` for protecting components before that data is sent to the client.**\n *\n * @param props - Props for customizing the Protected component.\n *\n * @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,\n * or `null` while loading.\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected fallback={<>Sign in to view the message.</>}>\n * <>You are breathtaking</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example App Router with group options\n *\n * See {@link ProtectedComponentProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groupFallback={<>Only admins are allowed.</>}\n * groups={[\"admin\"]}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected fallback={<>Sign in to view the message.</>}>\n * <>You are breathtaking</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Pages Router with group options\n *\n * See {@link ProtectedComponentProps}.\n *\n * ```tsx\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groupFallback={<>Only admins are allowed.</>}\n * groups={[\"admin\"]}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n groupFallback = null,\n}: ProtectedComponentProps): JSX.Element | null => {\n const { isLoading, error, isAuthenticated, user } = useAuth();\n\n if (isLoading) {\n return null;\n }\n\n if (error || !isAuthenticated || !user) {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n return null;\n }\n\n return (\n <>\n {!groups ||\n isUserInGroup(\n user,\n groups,\n groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n matchAllGroups\n )\n ? children\n : groupFallback}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;AACjC,4BAAgB;AACd,kCAAiB;GAAE;GAAW,GAAG;GAAY,CAAC;IAC7C,CAAC,YAAY,UAAU,CAAC;AAC3B,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACUT,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,WAAW,MACX,gBAAgB,WACiC;CACjD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAASA,wBAAS;AAE7D,KAAI,UACF,QAAO;AAGT,KAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;AACtC,MAAI,SACF,QAAO,0EAAG,SAAY;AAGxB,SAAO;;AAGT,QACE,0EACG,CAAC,6DAEA,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,eACD,GACG,WACA,cACH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as ExtraAuthParams } from "../../types-
|
|
1
|
+
import { i as ExtraAuthParams } from "../../types-CsBjAJce.mjs";
|
|
2
2
|
import React, { JSX } from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/components/client/redirect-to-signin.d.ts
|
|
@@ -122,7 +122,11 @@ interface ProtectedComponentProps {
|
|
|
122
122
|
/**
|
|
123
123
|
* A fallback component that should render if the user is not authenticated.
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
fallback?: React.ReactNode;
|
|
126
|
+
/**
|
|
127
|
+
* A fallback component that should render if the user is authenticated but does not belong to the required groups.
|
|
128
|
+
*/
|
|
129
|
+
groupFallback?: React.ReactNode;
|
|
126
130
|
}
|
|
127
131
|
/**
|
|
128
132
|
* A wrapper component that conditionally renders its children based on the user's authentication
|
|
@@ -132,7 +136,7 @@ interface ProtectedComponentProps {
|
|
|
132
136
|
*
|
|
133
137
|
* @param props - Props for customizing the Protected component.
|
|
134
138
|
*
|
|
135
|
-
* @returns The children if authorized, the `
|
|
139
|
+
* @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,
|
|
136
140
|
* or `null` while loading.
|
|
137
141
|
*
|
|
138
142
|
* @example App Router
|
|
@@ -144,7 +148,7 @@ interface ProtectedComponentProps {
|
|
|
144
148
|
*
|
|
145
149
|
* export default function Home() {
|
|
146
150
|
* return (
|
|
147
|
-
* <Protected
|
|
151
|
+
* <Protected fallback={<>Sign in to view the message.</>}>
|
|
148
152
|
* <>You are breathtaking</>
|
|
149
153
|
* </Protected>
|
|
150
154
|
* );
|
|
@@ -163,7 +167,7 @@ interface ProtectedComponentProps {
|
|
|
163
167
|
* export default function Home() {
|
|
164
168
|
* return (
|
|
165
169
|
* <Protected
|
|
166
|
-
*
|
|
170
|
+
* groupFallback={<>Only admins are allowed.</>}
|
|
167
171
|
* groups={["admin"]}
|
|
168
172
|
* >
|
|
169
173
|
* <>Signed in as admin</>
|
|
@@ -179,7 +183,7 @@ interface ProtectedComponentProps {
|
|
|
179
183
|
*
|
|
180
184
|
* export default function Home() {
|
|
181
185
|
* return (
|
|
182
|
-
* <Protected
|
|
186
|
+
* <Protected fallback={<>Sign in to view the message.</>}>
|
|
183
187
|
* <>You are breathtaking</>
|
|
184
188
|
* </Protected>
|
|
185
189
|
* );
|
|
@@ -196,7 +200,7 @@ interface ProtectedComponentProps {
|
|
|
196
200
|
* export default function Home() {
|
|
197
201
|
* return (
|
|
198
202
|
* <Protected
|
|
199
|
-
*
|
|
203
|
+
* groupFallback={<>Only admins are allowed.</>}
|
|
200
204
|
* groups={["admin"]}
|
|
201
205
|
* >
|
|
202
206
|
* <>Signed in as admin</>
|
|
@@ -211,7 +215,8 @@ declare const Protected: ({
|
|
|
211
215
|
groups,
|
|
212
216
|
groupsClaim,
|
|
213
217
|
matchAllGroups,
|
|
214
|
-
|
|
218
|
+
fallback,
|
|
219
|
+
groupFallback
|
|
215
220
|
}: ProtectedComponentProps) => JSX.Element | null;
|
|
216
221
|
//#endregion
|
|
217
222
|
export { Protected, type ProtectedComponentProps, RedirectToSignIn, type RedirectToSignInProps };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as redirectToSignIn, r as useAuth } from "../../client-
|
|
1
|
+
import { n as redirectToSignIn, r as useAuth } from "../../client-D-3RMRNY.mjs";
|
|
2
2
|
import { isUserInGroup } from "@monocloud/auth-node-core/utils";
|
|
3
3
|
import React, { useEffect } from "react";
|
|
4
4
|
|
|
@@ -108,7 +108,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
108
108
|
*
|
|
109
109
|
* @param props - Props for customizing the Protected component.
|
|
110
110
|
*
|
|
111
|
-
* @returns The children if authorized, the `
|
|
111
|
+
* @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,
|
|
112
112
|
* or `null` while loading.
|
|
113
113
|
*
|
|
114
114
|
* @example App Router
|
|
@@ -120,7 +120,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
120
120
|
*
|
|
121
121
|
* export default function Home() {
|
|
122
122
|
* return (
|
|
123
|
-
* <Protected
|
|
123
|
+
* <Protected fallback={<>Sign in to view the message.</>}>
|
|
124
124
|
* <>You are breathtaking</>
|
|
125
125
|
* </Protected>
|
|
126
126
|
* );
|
|
@@ -139,7 +139,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
139
139
|
* export default function Home() {
|
|
140
140
|
* return (
|
|
141
141
|
* <Protected
|
|
142
|
-
*
|
|
142
|
+
* groupFallback={<>Only admins are allowed.</>}
|
|
143
143
|
* groups={["admin"]}
|
|
144
144
|
* >
|
|
145
145
|
* <>Signed in as admin</>
|
|
@@ -155,7 +155,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
155
155
|
*
|
|
156
156
|
* export default function Home() {
|
|
157
157
|
* return (
|
|
158
|
-
* <Protected
|
|
158
|
+
* <Protected fallback={<>Sign in to view the message.</>}>
|
|
159
159
|
* <>You are breathtaking</>
|
|
160
160
|
* </Protected>
|
|
161
161
|
* );
|
|
@@ -172,7 +172,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
172
172
|
* export default function Home() {
|
|
173
173
|
* return (
|
|
174
174
|
* <Protected
|
|
175
|
-
*
|
|
175
|
+
* groupFallback={<>Only admins are allowed.</>}
|
|
176
176
|
* groups={["admin"]}
|
|
177
177
|
* >
|
|
178
178
|
* <>Signed in as admin</>
|
|
@@ -182,14 +182,14 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
182
182
|
* ```
|
|
183
183
|
*
|
|
184
184
|
*/
|
|
185
|
-
const Protected = ({ children, groups, groupsClaim, matchAllGroups = false,
|
|
185
|
+
const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, fallback = null, groupFallback = null }) => {
|
|
186
186
|
const { isLoading, error, isAuthenticated, user } = useAuth();
|
|
187
187
|
if (isLoading) return null;
|
|
188
188
|
if (error || !isAuthenticated || !user) {
|
|
189
|
-
if (
|
|
189
|
+
if (fallback) return /* @__PURE__ */ React.createElement(React.Fragment, null, fallback);
|
|
190
190
|
return null;
|
|
191
191
|
}
|
|
192
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, !groups || isUserInGroup(user, groups, groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, matchAllGroups) ? children :
|
|
192
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, !groups || isUserInGroup(user, groups, groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, matchAllGroups) ? children : groupFallback);
|
|
193
193
|
};
|
|
194
194
|
|
|
195
195
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/client/redirect-to-signin.tsx","../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The url where the user will be redirected to after sign in.\n */\n returnUrl?: string;\n}\n\n/**\n * A client side component that will redirect users to the sign in page.\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 props - The props for customizing RedirectToSignIn\n *\n * @returns\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example App Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n */\nexport const RedirectToSignIn = ({\n returnUrl,\n ...authParams\n}: RedirectToSignInProps): null => {\n useEffect(() => {\n redirectToSignIn({ returnUrl, ...authParams });\n }, [authParams, returnUrl]);\n return null;\n};\n","import { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React, { JSX } from 'react';\nimport { useAuth } from '../../client';\n\nexport interface ProtectedComponentProps {\n /**\n * Components that should be rendered if the user is authenticated.\n */\n children: React.ReactNode;\n\n /**\n * A list of group names or IDs to which the user must belong to. The user should belong to atleast one of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim of user's groups. default: `groups`.\n */\n groupsClaim?: string;\n\n /**\n * Flag indicating if all groups specified should be present in the users profile. default: false.\n */\n matchAllGroups?: boolean;\n\n /**\n * A fallback component that should render if the user is not authenticated.\n */\n
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/client/redirect-to-signin.tsx","../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The url where the user will be redirected to after sign in.\n */\n returnUrl?: string;\n}\n\n/**\n * A client side component that will redirect users to the sign in page.\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 props - The props for customizing RedirectToSignIn\n *\n * @returns\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example App Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n */\nexport const RedirectToSignIn = ({\n returnUrl,\n ...authParams\n}: RedirectToSignInProps): null => {\n useEffect(() => {\n redirectToSignIn({ returnUrl, ...authParams });\n }, [authParams, returnUrl]);\n return null;\n};\n","import { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React, { JSX } from 'react';\nimport { useAuth } from '../../client';\n\nexport interface ProtectedComponentProps {\n /**\n * Components that should be rendered if the user is authenticated.\n */\n children: React.ReactNode;\n\n /**\n * A list of group names or IDs to which the user must belong to. The user should belong to atleast one of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim of user's groups. default: `groups`.\n */\n groupsClaim?: string;\n\n /**\n * Flag indicating if all groups specified should be present in the users profile. default: false.\n */\n matchAllGroups?: boolean;\n\n /**\n * A fallback component that should render if the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * A fallback component that should render if the user is authenticated but does not belong to the required groups.\n */\n groupFallback?: React.ReactNode;\n}\n\n/**\n * A wrapper component that conditionally renders its children based on the user's authentication\n * status and group membership.\n *\n * **Note⚠️: The component is hidden from view. The data is present in the browser. Use server side `protectPage()` for protecting components before that data is sent to the client.**\n *\n * @param props - Props for customizing the Protected component.\n *\n * @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,\n * or `null` while loading.\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected fallback={<>Sign in to view the message.</>}>\n * <>You are breathtaking</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example App Router with group options\n *\n * See {@link ProtectedComponentProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groupFallback={<>Only admins are allowed.</>}\n * groups={[\"admin\"]}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected fallback={<>Sign in to view the message.</>}>\n * <>You are breathtaking</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Pages Router with group options\n *\n * See {@link ProtectedComponentProps}.\n *\n * ```tsx\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groupFallback={<>Only admins are allowed.</>}\n * groups={[\"admin\"]}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n groupFallback = null,\n}: ProtectedComponentProps): JSX.Element | null => {\n const { isLoading, error, isAuthenticated, user } = useAuth();\n\n if (isLoading) {\n return null;\n }\n\n if (error || !isAuthenticated || !user) {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n return null;\n }\n\n return (\n <>\n {!groups ||\n isUserInGroup(\n user,\n groups,\n groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n matchAllGroups\n )\n ? children\n : groupFallback}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;AACjC,iBAAgB;AACd,mBAAiB;GAAE;GAAW,GAAG;GAAY,CAAC;IAC7C,CAAC,YAAY,UAAU,CAAC;AAC3B,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACUT,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,WAAW,MACX,gBAAgB,WACiC;CACjD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAAS,SAAS;AAE7D,KAAI,UACF,QAAO;AAGT,KAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;AACtC,MAAI,SACF,QAAO,0DAAG,SAAY;AAGxB,SAAO;;AAGT,QACE,0DACG,CAAC,UACF,cACE,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,eACD,GACG,WACA,cACH"}
|