@monocloud/auth-nextjs 0.1.14 → 0.1.16
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/_virtual/_rolldown/runtime.cjs +7 -13
- package/dist/client/index.cjs +4 -5
- package/dist/client/index.mjs +1 -2
- package/dist/client/protect-client-page.cjs +4 -6
- package/dist/client/protect-client-page.cjs.map +1 -1
- package/dist/client/protect-client-page.mjs +2 -4
- package/dist/client/protect-client-page.mjs.map +1 -1
- package/dist/client/use-auth.cjs +4 -5
- package/dist/client/use-auth.cjs.map +1 -1
- package/dist/client/use-auth.mjs +3 -4
- package/dist/client/use-auth.mjs.map +1 -1
- package/dist/components/client/index.cjs +4 -5
- package/dist/components/client/index.mjs +1 -2
- package/dist/components/client/protected.cjs +5 -7
- package/dist/components/client/protected.cjs.map +1 -1
- package/dist/components/client/protected.mjs +2 -4
- package/dist/components/client/protected.mjs.map +1 -1
- package/dist/components/client/redirect-to-signin.cjs +3 -6
- package/dist/components/client/redirect-to-signin.cjs.map +1 -1
- package/dist/components/client/redirect-to-signin.mjs +2 -4
- package/dist/components/client/redirect-to-signin.mjs.map +1 -1
- package/dist/components/index.cjs +5 -6
- package/dist/components/index.mjs +1 -2
- package/dist/components/signin.cjs +2 -3
- package/dist/components/signin.cjs.map +1 -1
- package/dist/components/signin.mjs +1 -2
- package/dist/components/signin.mjs.map +1 -1
- package/dist/components/signout.cjs +2 -3
- package/dist/components/signout.cjs.map +1 -1
- package/dist/components/signout.mjs +1 -2
- package/dist/components/signout.mjs.map +1 -1
- package/dist/components/signup.cjs +2 -3
- package/dist/components/signup.cjs.map +1 -1
- package/dist/components/signup.mjs +1 -2
- package/dist/components/signup.mjs.map +1 -1
- package/dist/index.cjs +29 -31
- package/dist/index.mjs +1 -2
- package/dist/initialize.cjs +2 -3
- package/dist/initialize.cjs.map +1 -1
- package/dist/initialize.d.mts +1 -1
- package/dist/initialize.mjs +1 -2
- package/dist/initialize.mjs.map +1 -1
- package/dist/monocloud-next-client.cjs +17 -19
- package/dist/monocloud-next-client.cjs.map +1 -1
- package/dist/monocloud-next-client.d.mts +1 -1
- package/dist/monocloud-next-client.mjs +10 -11
- package/dist/monocloud-next-client.mjs.map +1 -1
- package/dist/requests/monocloud-app-router-request.cjs +1 -2
- package/dist/requests/monocloud-app-router-request.cjs.map +1 -1
- package/dist/requests/monocloud-app-router-request.mjs +1 -1
- package/dist/requests/monocloud-app-router-request.mjs.map +1 -1
- package/dist/requests/monocloud-cookie-request.cjs +3 -4
- package/dist/requests/monocloud-cookie-request.cjs.map +1 -1
- package/dist/requests/monocloud-cookie-request.mjs +3 -3
- package/dist/requests/monocloud-cookie-request.mjs.map +1 -1
- package/dist/requests/monocloud-page-router-request.cjs +1 -2
- package/dist/requests/monocloud-page-router-request.cjs.map +1 -1
- package/dist/requests/monocloud-page-router-request.mjs +1 -1
- package/dist/requests/monocloud-page-router-request.mjs.map +1 -1
- package/dist/responses/monocloud-app-router-response.cjs +1 -3
- package/dist/responses/monocloud-app-router-response.cjs.map +1 -1
- package/dist/responses/monocloud-app-router-response.mjs +1 -2
- package/dist/responses/monocloud-app-router-response.mjs.map +1 -1
- package/dist/responses/monocloud-cookie-response.cjs +2 -3
- package/dist/responses/monocloud-cookie-response.cjs.map +1 -1
- package/dist/responses/monocloud-cookie-response.mjs +2 -2
- package/dist/responses/monocloud-cookie-response.mjs.map +1 -1
- package/dist/responses/monocloud-page-router-response.cjs +1 -3
- package/dist/responses/monocloud-page-router-response.cjs.map +1 -1
- package/dist/responses/monocloud-page-router-response.mjs +1 -2
- package/dist/responses/monocloud-page-router-response.mjs.map +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/utils.cjs +8 -9
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.mjs +2 -2
- package/dist/utils.mjs.map +1 -1
- package/package.json +8 -8
|
@@ -6,16 +6,12 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
}
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
19
15
|
}
|
|
20
16
|
return to;
|
|
21
17
|
};
|
|
@@ -23,7 +19,5 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
19
|
value: mod,
|
|
24
20
|
enumerable: true
|
|
25
21
|
}) : target, mod));
|
|
26
|
-
|
|
27
22
|
//#endregion
|
|
28
|
-
|
|
29
|
-
exports.__toESM = __toESM;
|
|
23
|
+
exports.__toESM = __toESM;
|
package/dist/client/index.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
const require_use_auth = require(
|
|
3
|
-
const require_protect_client_page = require(
|
|
4
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_use_auth = require("./use-auth.cjs");
|
|
3
|
+
const require_protect_client_page = require("./protect-client-page.cjs");
|
|
5
4
|
exports.protectClientPage = require_protect_client_page.protectClientPage;
|
|
6
|
-
exports.useAuth = require_use_auth.useAuth;
|
|
5
|
+
exports.useAuth = require_use_auth.useAuth;
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const require_use_auth = require('./use-auth.cjs');
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_use_auth = require("./use-auth.cjs");
|
|
5
4
|
let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
|
|
6
5
|
let react = require("react");
|
|
7
6
|
react = require_runtime.__toESM(react);
|
|
8
|
-
|
|
9
7
|
//#region src/client/protect-client-page.tsx
|
|
10
8
|
const redirectToSignIn = (options) => {
|
|
11
9
|
const searchParams = new URLSearchParams(window.location.search);
|
|
@@ -140,8 +138,8 @@ const protectClientPage = (Component, options) => {
|
|
|
140
138
|
return null;
|
|
141
139
|
};
|
|
142
140
|
};
|
|
143
|
-
|
|
144
141
|
//#endregion
|
|
145
142
|
exports.protectClientPage = protectClientPage;
|
|
146
143
|
exports.redirectToSignIn = redirectToSignIn;
|
|
144
|
+
|
|
147
145
|
//# sourceMappingURL=protect-client-page.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect-client-page.cjs","names":["useAuth"],"sources":["../../src/client/protect-client-page.tsx"],"sourcesContent":["/* 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 * @typeParam P - Props of the protected component (excluding `user`).\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":"
|
|
1
|
+
{"version":3,"file":"protect-client-page.cjs","names":["useAuth"],"sources":["../../src/client/protect-client-page.tsx"],"sourcesContent":["/* 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 * @typeParam P - Props of the protected component (excluding `user`).\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":";;;;;;;AA8CA,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,MAAM;CAC/D,aAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,SAAS,CAChD;CAEA,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,QACX,aAAa,IAAI,SAAS,QAAQ,MAAM;CAE1C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,UACX,aAAa,IAAI,YAAY,QAAQ,QAAQ;CAG/C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,WACX,aAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,GAAG,CAAC;CAG5D,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,SACX,aAAa,IAAI,WAAW,QAAQ,OAAO;CAG7C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,QACX,aAAa,IAAI,UAAU,QAAQ,MAAM;CAG3C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,mBACX,aAAa,IAAI,sBAAsB,QAAQ,iBAAiB;CAGlE,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,WACX,aAAa,IAAI,cAAc,QAAQ,SAAS;CAGlD,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,QACX,aAAa,IAAI,WAAW,QAAQ,OAAO,SAAS,CAAC;CAGvD,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,WACX,aAAa,IAAI,cAAc,QAAQ,SAAS;CAGlD,OAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,SAAS,GACjJ;AACF;AAEA,MAAM,mBACJ,OACA,YACoB;;CAEpB,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,SACX,OAAO,QAAQ,QAAQ,KAAK;;CAI9B,MAAM;AACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFA,MAAa,qBACX,WACA,YACgB;CAChB,QAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAcA,iBAAAA,QAAQ;EAE3C,CAAA,GAAA,MAAA,iBAAgB;GACd,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;IACjC,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,gBACX;IAGF,MAAM,cAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAa,QAAS,eAAc,CAAC;IAC3C,iBAAiB;KACf,WAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAW,QAAS;KACpB,GAAG;IACL,CAAC;GACH;EACF,GAAG;GAAC;GAAM;GAAW;EAAK,CAAC;EAE3B,IAAI,OACF,OAAO,gBAAgB,OAAO,OAAO;EAGvC,IAAI,CAAC,QAAQ,CAAC,cAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAa,QAAS,iBAClC,OAAO,QAAQ,eAAe;EAGhC,IAAI,MAAM;GACR,KAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IACE,QAAS,WACT,EAAA,GAAA,gCAAA,eACE,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,QACV,GACA;IACA,MAAM,EACJ,4BAA6C,sBAAA,QAAA,cAAC,OAAA,MAAI,eAAkB,MAClE;IACJ,OAAO,oBAAoB,IAAI;GACjC;GAEA,OAAO,sBAAA,QAAA,cAAC,WAAD;IAAiB;IAAM,GAAI;GAAQ,CAAA;EAC5C;EAEA,OAAO;CACT;AACF"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
3
2
|
import { useAuth } from "./use-auth.mjs";
|
|
4
3
|
import { isUserInGroup } from "@monocloud/auth-node-core/utils";
|
|
5
4
|
import React, { useEffect } from "react";
|
|
6
|
-
|
|
7
5
|
//#region src/client/protect-client-page.tsx
|
|
8
6
|
const redirectToSignIn = (options) => {
|
|
9
7
|
const searchParams = new URLSearchParams(window.location.search);
|
|
@@ -138,7 +136,7 @@ const protectClientPage = (Component, options) => {
|
|
|
138
136
|
return null;
|
|
139
137
|
};
|
|
140
138
|
};
|
|
141
|
-
|
|
142
139
|
//#endregion
|
|
143
140
|
export { protectClientPage, redirectToSignIn };
|
|
141
|
+
|
|
144
142
|
//# sourceMappingURL=protect-client-page.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect-client-page.mjs","names":[],"sources":["../../src/client/protect-client-page.tsx"],"sourcesContent":["/* 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 * @typeParam P - Props of the protected component (excluding `user`).\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":"
|
|
1
|
+
{"version":3,"file":"protect-client-page.mjs","names":[],"sources":["../../src/client/protect-client-page.tsx"],"sourcesContent":["/* 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 * @typeParam P - Props of the protected component (excluding `user`).\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":";;;;;AA8CA,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,MAAM;CAC/D,aAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,SAAS,CAChD;CAEA,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,QACX,aAAa,IAAI,SAAS,QAAQ,MAAM;CAE1C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,UACX,aAAa,IAAI,YAAY,QAAQ,QAAQ;CAG/C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,WACX,aAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,GAAG,CAAC;CAG5D,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,SACX,aAAa,IAAI,WAAW,QAAQ,OAAO;CAG7C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,QACX,aAAa,IAAI,UAAU,QAAQ,MAAM;CAG3C,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,mBACX,aAAa,IAAI,sBAAsB,QAAQ,iBAAiB;CAGlE,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,WACX,aAAa,IAAI,cAAc,QAAQ,SAAS;CAGlD,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,QACX,aAAa,IAAI,WAAW,QAAQ,OAAO,SAAS,CAAC;CAGvD,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,WACX,aAAa,IAAI,cAAc,QAAQ,SAAS;CAGlD,OAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,SAAS,GACjJ;AACF;AAEA,MAAM,mBACJ,OACA,YACoB;;CAEpB,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,SACX,OAAO,QAAQ,QAAQ,KAAK;;CAI9B,MAAM;AACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFA,MAAa,qBACX,WACA,YACgB;CAChB,QAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,QAAQ;EAE3C,gBAAgB;GACd,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;IACjC,IAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAI,QAAS,gBACX;IAGF,MAAM,cAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAa,QAAS,eAAc,CAAC;IAC3C,iBAAiB;KACf,WAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAW,QAAS;KACpB,GAAG;IACL,CAAC;GACH;EACF,GAAG;GAAC;GAAM;GAAW;EAAK,CAAC;EAE3B,IAAI,OACF,OAAO,gBAAgB,OAAO,OAAO;EAGvC,IAAI,CAAC,QAAQ,CAAC,cAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IAAa,QAAS,iBAClC,OAAO,QAAQ,eAAe;EAGhC,IAAI,MAAM;GACR,KAAA,YAAA,QAAA,YAAA,KAAA,IAAA,KAAA,IACE,QAAS,WACT,CAAC,cACC,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,QACV,GACA;IACA,MAAM,EACJ,4BAA6C,sBAAA,cAAC,OAAA,MAAI,eAAkB,MAClE;IACJ,OAAO,oBAAoB,IAAI;GACjC;GAEA,OAAO,sBAAA,cAAC,WAAD;IAAiB;IAAM,GAAI;GAAQ,CAAA;EAC5C;EAEA,OAAO;CACT;AACF"}
|
package/dist/client/use-auth.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
4
3
|
let swr = require("swr");
|
|
5
4
|
swr = require_runtime.__toESM(swr);
|
|
6
|
-
|
|
7
5
|
//#region src/client/use-auth.tsx
|
|
8
6
|
const fetchUser = async (url) => {
|
|
9
7
|
const res = await fetch(url, { credentials: "include" });
|
|
@@ -87,10 +85,11 @@ const useAuth = () => {
|
|
|
87
85
|
isLoading,
|
|
88
86
|
isAuthenticated: false,
|
|
89
87
|
error: void 0,
|
|
88
|
+
/* v8 ignore next -- @preserve */
|
|
90
89
|
refetch: () => {}
|
|
91
90
|
};
|
|
92
91
|
};
|
|
93
|
-
|
|
94
92
|
//#endregion
|
|
95
93
|
exports.useAuth = useAuth;
|
|
94
|
+
|
|
96
95
|
//# sourceMappingURL=use-auth.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-auth.cjs","names":[],"sources":["../../src/client/use-auth.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"],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-auth.cjs","names":[],"sources":["../../src/client/use-auth.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"],"mappings":";;;;;AAkCA,MAAM,YAAY,OAAO,QAAoD;CAC3E,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,UAAU,CAAC;CAEvD,IAAI,IAAI,WAAW,KACjB;CAGF,IAAI,IAAI,IACN,OAAO,IAAI,KAAK;CAGlB,MAAM,IAAI,MAAM,sBAAsB;AACxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,MAAa,gBAAqC;CAChD,MAAM,MACJ,QAAQ,IAAI,4CAEZ,GAAG,QAAQ,IAAI,0BAA0B,GAAG;CAE9C,MAAM,EAAE,MAAM,OAAO,WAAW,YAAA,GAAA,IAAA,SAC9B,KACA,SACF;CAEA,MAAM,WAAW,YAA4B;EAC3C,MAAM,MAAM,IAAI,IAAI,KAAK,eAAe;EACxC,IAAI,SACF,IAAI,aAAa,IAAI,WAAW,MAAM;EAGxC,OAAY,YAAY,MAAM,UAAU,IAAI,WAAW,IAAI,MAAM,GAAG,EAClE,YAAY,MACd,CAAC;CACH;CAEA,IAAI,OACF,OAAO;EACL,MAAM,KAAA;EACN,WAAW;EACX,iBAAiB;EACV;EACP;CACF;CAGF,IAAI,MACF,OAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,IAAI,EAAE,SAAS;EACtD,OAAO,KAAA;EACP;CACF;CAGF,OAAO;EACL,MAAM,KAAA;EACN;EACA,iBAAiB;EACjB,OAAO,KAAA;;EAEP,eAAqB,CAAC;CACxB;AACF"}
|
package/dist/client/use-auth.mjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
3
2
|
import useSWR from "swr";
|
|
4
|
-
|
|
5
3
|
//#region src/client/use-auth.tsx
|
|
6
4
|
const fetchUser = async (url) => {
|
|
7
5
|
const res = await fetch(url, { credentials: "include" });
|
|
@@ -85,10 +83,11 @@ const useAuth = () => {
|
|
|
85
83
|
isLoading,
|
|
86
84
|
isAuthenticated: false,
|
|
87
85
|
error: void 0,
|
|
86
|
+
/* v8 ignore next -- @preserve */
|
|
88
87
|
refetch: () => {}
|
|
89
88
|
};
|
|
90
89
|
};
|
|
91
|
-
|
|
92
90
|
//#endregion
|
|
93
91
|
export { useAuth };
|
|
92
|
+
|
|
94
93
|
//# sourceMappingURL=use-auth.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-auth.mjs","names":[],"sources":["../../src/client/use-auth.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"],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-auth.mjs","names":[],"sources":["../../src/client/use-auth.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"],"mappings":";;;AAkCA,MAAM,YAAY,OAAO,QAAoD;CAC3E,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,UAAU,CAAC;CAEvD,IAAI,IAAI,WAAW,KACjB;CAGF,IAAI,IAAI,IACN,OAAO,IAAI,KAAK;CAGlB,MAAM,IAAI,MAAM,sBAAsB;AACxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,MAAa,gBAAqC;CAChD,MAAM,MACJ,QAAQ,IAAI,4CAEZ,GAAG,QAAQ,IAAI,0BAA0B,GAAG;CAE9C,MAAM,EAAE,MAAM,OAAO,WAAW,WAAW,OACzC,KACA,SACF;CAEA,MAAM,WAAW,YAA4B;EAC3C,MAAM,MAAM,IAAI,IAAI,KAAK,eAAe;EACxC,IAAI,SACF,IAAI,aAAa,IAAI,WAAW,MAAM;EAGxC,OAAY,YAAY,MAAM,UAAU,IAAI,WAAW,IAAI,MAAM,GAAG,EAClE,YAAY,MACd,CAAC;CACH;CAEA,IAAI,OACF,OAAO;EACL,MAAM,KAAA;EACN,WAAW;EACX,iBAAiB;EACV;EACP;CACF;CAGF,IAAI,MACF,OAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,IAAI,EAAE,SAAS;EACtD,OAAO,KAAA;EACP;CACF;CAGF,OAAO;EACL,MAAM,KAAA;EACN;EACA,iBAAiB;EACjB,OAAO,KAAA;;EAEP,eAAqB,CAAC;CACxB;AACF"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
const require_redirect_to_signin = require(
|
|
3
|
-
const require_protected = require(
|
|
4
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_redirect_to_signin = require("./redirect-to-signin.cjs");
|
|
3
|
+
const require_protected = require("./protected.cjs");
|
|
5
4
|
exports.Protected = require_protected.Protected;
|
|
6
|
-
exports.RedirectToSignIn = require_redirect_to_signin.RedirectToSignIn;
|
|
5
|
+
exports.RedirectToSignIn = require_redirect_to_signin.RedirectToSignIn;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
require('../../client/index.cjs');
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_use_auth = require("../../client/use-auth.cjs");
|
|
4
|
+
require("../../client/index.cjs");
|
|
6
5
|
let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
|
|
7
6
|
let react = require("react");
|
|
8
7
|
react = require_runtime.__toESM(react);
|
|
9
|
-
|
|
10
8
|
//#region src/components/client/protected.tsx
|
|
11
9
|
/**
|
|
12
10
|
* `<Protected>` conditionally renders its children based on the user’s authentication state and (optionally) group membership.
|
|
@@ -83,7 +81,7 @@ const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, fall
|
|
|
83
81
|
}
|
|
84
82
|
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 : onGroupAccessDenied(user));
|
|
85
83
|
};
|
|
86
|
-
|
|
87
84
|
//#endregion
|
|
88
85
|
exports.Protected = Protected;
|
|
86
|
+
|
|
89
87
|
//# sourceMappingURL=protected.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protected.cjs","names":["useAuth"],"sources":["../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React from 'react';\nimport { useAuth } from '../../client';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport type { MonoCloudNextClient } from '../../monocloud-next-client';\n\n/**\n * Props for the `<Protected />` component.\n *\n * @category Types\n */\nexport interface ProtectedComponentProps {\n /**\n * Content to render when access is allowed.\n */\n children: React.ReactNode;\n\n /**\n * Groups required to view the protected content. By default, the user must belong to **any** of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim that contains groups in the user profile.\n * @defaultValue 'groups'\n */\n groupsClaim?: string;\n\n /**\n * If `true`, the user must belong to **all** specified `groups` (instead of any).\n * @defaultValue false\n */\n matchAllGroups?: boolean;\n\n /**\n * Content to render when the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * Rendered when the user is authenticated but does not meet the `groups` requirement. If omitted, nothing is rendered (or `fallback` is used only for unauthenticated users).\n */\n onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;\n}\n\n/**\n * `<Protected>` conditionally renders its children based on the user’s authentication state and (optionally) group membership.\n *\n * > `<Protected>` runs on the client and only affects what is rendered. It does **not** prevent data from being sent to the browser.\n * > To enforce access before content is rendered or sent to the client, use server-side protection such as {@link MonoCloudNextClient.protectPage | protectPage()}, or {@link MonoCloudNextClient.protect | protect()}.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 * <>This is the protected content.</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example With Groups\n *\n * ```tsx title=\"With Groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\"]}\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access admin content.</>}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Requiring all groups\n *\n * ```tsx title=\"Requiring all groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\", \"billing\"]}\n * matchAllGroups\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access billing content.</>}\n * >\n * <>Sensitive settings</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @param props - Props for customizing the Protected component.\n * @returns The children if authorized, the `fallback` or `onGroupAccessDenied` content if unauthenticated or unauthorized, or `null` while loading.\n *\n * @category Components\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n onGroupAccessDenied = (): React.ReactNode => <></>,\n}: ProtectedComponentProps): React.ReactNode | 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 : onGroupAccessDenied(user)}\n </>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"protected.cjs","names":["useAuth"],"sources":["../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React from 'react';\nimport { useAuth } from '../../client';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport type { MonoCloudNextClient } from '../../monocloud-next-client';\n\n/**\n * Props for the `<Protected />` component.\n *\n * @category Types\n */\nexport interface ProtectedComponentProps {\n /**\n * Content to render when access is allowed.\n */\n children: React.ReactNode;\n\n /**\n * Groups required to view the protected content. By default, the user must belong to **any** of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim that contains groups in the user profile.\n * @defaultValue 'groups'\n */\n groupsClaim?: string;\n\n /**\n * If `true`, the user must belong to **all** specified `groups` (instead of any).\n * @defaultValue false\n */\n matchAllGroups?: boolean;\n\n /**\n * Content to render when the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * Rendered when the user is authenticated but does not meet the `groups` requirement. If omitted, nothing is rendered (or `fallback` is used only for unauthenticated users).\n */\n onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;\n}\n\n/**\n * `<Protected>` conditionally renders its children based on the user’s authentication state and (optionally) group membership.\n *\n * > `<Protected>` runs on the client and only affects what is rendered. It does **not** prevent data from being sent to the browser.\n * > To enforce access before content is rendered or sent to the client, use server-side protection such as {@link MonoCloudNextClient.protectPage | protectPage()}, or {@link MonoCloudNextClient.protect | protect()}.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 * <>This is the protected content.</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example With Groups\n *\n * ```tsx title=\"With Groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\"]}\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access admin content.</>}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Requiring all groups\n *\n * ```tsx title=\"Requiring all groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\", \"billing\"]}\n * matchAllGroups\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access billing content.</>}\n * >\n * <>Sensitive settings</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @param props - Props for customizing the Protected component.\n * @returns The children if authorized, the `fallback` or `onGroupAccessDenied` content if unauthenticated or unauthorized, or `null` while loading.\n *\n * @category Components\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n onGroupAccessDenied = (): React.ReactNode => <></>,\n}: ProtectedComponentProps): React.ReactNode | 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 : onGroupAccessDenied(user)}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiHA,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,WAAW,MACX,4BAA6C,sBAAA,QAAA,cAAA,MAAA,QAAA,UAAA,IAAI,QACI;CACrD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAASA,iBAAAA,QAAQ;CAE5D,IAAI,WACF,OAAO;CAGT,IAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;EACtC,IAAI,UACF,OAAO;EAGT,OAAO;CACT;CAEA,OACE,sBAAA,QAAA,cAAA,MAAA,QAAA,UAAA,MACG,CAAC,WAAA,GAAA,gCAAA,eAEA,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,cACF,IACI,WACA,oBAAoB,IAAI,CAC5B;AAEN"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
3
2
|
import { useAuth } from "../../client/use-auth.mjs";
|
|
4
3
|
import "../../client/index.mjs";
|
|
5
4
|
import { isUserInGroup } from "@monocloud/auth-node-core/utils";
|
|
6
5
|
import React from "react";
|
|
7
|
-
|
|
8
6
|
//#region src/components/client/protected.tsx
|
|
9
7
|
/**
|
|
10
8
|
* `<Protected>` conditionally renders its children based on the user’s authentication state and (optionally) group membership.
|
|
@@ -81,7 +79,7 @@ const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, fall
|
|
|
81
79
|
}
|
|
82
80
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, !groups || isUserInGroup(user, groups, groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, matchAllGroups) ? children : onGroupAccessDenied(user));
|
|
83
81
|
};
|
|
84
|
-
|
|
85
82
|
//#endregion
|
|
86
83
|
export { Protected };
|
|
84
|
+
|
|
87
85
|
//# sourceMappingURL=protected.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protected.mjs","names":[],"sources":["../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React from 'react';\nimport { useAuth } from '../../client';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport type { MonoCloudNextClient } from '../../monocloud-next-client';\n\n/**\n * Props for the `<Protected />` component.\n *\n * @category Types\n */\nexport interface ProtectedComponentProps {\n /**\n * Content to render when access is allowed.\n */\n children: React.ReactNode;\n\n /**\n * Groups required to view the protected content. By default, the user must belong to **any** of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim that contains groups in the user profile.\n * @defaultValue 'groups'\n */\n groupsClaim?: string;\n\n /**\n * If `true`, the user must belong to **all** specified `groups` (instead of any).\n * @defaultValue false\n */\n matchAllGroups?: boolean;\n\n /**\n * Content to render when the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * Rendered when the user is authenticated but does not meet the `groups` requirement. If omitted, nothing is rendered (or `fallback` is used only for unauthenticated users).\n */\n onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;\n}\n\n/**\n * `<Protected>` conditionally renders its children based on the user’s authentication state and (optionally) group membership.\n *\n * > `<Protected>` runs on the client and only affects what is rendered. It does **not** prevent data from being sent to the browser.\n * > To enforce access before content is rendered or sent to the client, use server-side protection such as {@link MonoCloudNextClient.protectPage | protectPage()}, or {@link MonoCloudNextClient.protect | protect()}.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 * <>This is the protected content.</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example With Groups\n *\n * ```tsx title=\"With Groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\"]}\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access admin content.</>}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Requiring all groups\n *\n * ```tsx title=\"Requiring all groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\", \"billing\"]}\n * matchAllGroups\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access billing content.</>}\n * >\n * <>Sensitive settings</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @param props - Props for customizing the Protected component.\n * @returns The children if authorized, the `fallback` or `onGroupAccessDenied` content if unauthenticated or unauthorized, or `null` while loading.\n *\n * @category Components\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n onGroupAccessDenied = (): React.ReactNode => <></>,\n}: ProtectedComponentProps): React.ReactNode | 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 : onGroupAccessDenied(user)}\n </>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"protected.mjs","names":[],"sources":["../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React from 'react';\nimport { useAuth } from '../../client';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport type { MonoCloudNextClient } from '../../monocloud-next-client';\n\n/**\n * Props for the `<Protected />` component.\n *\n * @category Types\n */\nexport interface ProtectedComponentProps {\n /**\n * Content to render when access is allowed.\n */\n children: React.ReactNode;\n\n /**\n * Groups required to view the protected content. By default, the user must belong to **any** of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim that contains groups in the user profile.\n * @defaultValue 'groups'\n */\n groupsClaim?: string;\n\n /**\n * If `true`, the user must belong to **all** specified `groups` (instead of any).\n * @defaultValue false\n */\n matchAllGroups?: boolean;\n\n /**\n * Content to render when the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * Rendered when the user is authenticated but does not meet the `groups` requirement. If omitted, nothing is rendered (or `fallback` is used only for unauthenticated users).\n */\n onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;\n}\n\n/**\n * `<Protected>` conditionally renders its children based on the user’s authentication state and (optionally) group membership.\n *\n * > `<Protected>` runs on the client and only affects what is rendered. It does **not** prevent data from being sent to the browser.\n * > To enforce access before content is rendered or sent to the client, use server-side protection such as {@link MonoCloudNextClient.protectPage | protectPage()}, or {@link MonoCloudNextClient.protect | protect()}.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 * <>This is the protected content.</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example With Groups\n *\n * ```tsx title=\"With Groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\"]}\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access admin content.</>}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Requiring all groups\n *\n * ```tsx title=\"Requiring all groups\"\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groups={[\"admin\", \"billing\"]}\n * matchAllGroups\n * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access billing content.</>}\n * >\n * <>Sensitive settings</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @param props - Props for customizing the Protected component.\n * @returns The children if authorized, the `fallback` or `onGroupAccessDenied` content if unauthenticated or unauthorized, or `null` while loading.\n *\n * @category Components\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n onGroupAccessDenied = (): React.ReactNode => <></>,\n}: ProtectedComponentProps): React.ReactNode | 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 : onGroupAccessDenied(user)}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiHA,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,WAAW,MACX,4BAA6C,sBAAA,cAAA,MAAA,UAAA,IAAI,QACI;CACrD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAAS,QAAQ;CAE5D,IAAI,WACF,OAAO;CAGT,IAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;EACtC,IAAI,UACF,OAAO;EAGT,OAAO;CACT;CAEA,OACE,sBAAA,cAAA,MAAA,UAAA,MACG,CAAC,UACF,cACE,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,cACF,IACI,WACA,oBAAoB,IAAI,CAC5B;AAEN"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
-
const require_protect_client_page = require('../../client/protect-client-page.cjs');
|
|
1
|
+
"use client";
|
|
2
|
+
const require_protect_client_page = require("../../client/protect-client-page.cjs");
|
|
5
3
|
let react = require("react");
|
|
6
|
-
|
|
7
4
|
//#region src/components/client/redirect-to-signin.tsx
|
|
8
5
|
/**
|
|
9
6
|
* `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.
|
|
@@ -71,7 +68,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
71
68
|
}, [authParams, returnUrl]);
|
|
72
69
|
return null;
|
|
73
70
|
};
|
|
74
|
-
|
|
75
71
|
//#endregion
|
|
76
72
|
exports.RedirectToSignIn = RedirectToSignIn;
|
|
73
|
+
|
|
77
74
|
//# sourceMappingURL=redirect-to-signin.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redirect-to-signin.cjs","names":[],"sources":["../../../src/components/client/redirect-to-signin.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect-client-page';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n *\n * @category Types\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The URL to return to after successful authentication. If not provided, the current URL is used.\n */\n returnUrl?: string;\n}\n\n/**\n * `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.\n *\n * It does not render any UI.\n *\n * > This component must be used inside a Client Component (`\"use client\"`).\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 With Options\n *\n * You can customize the authorization request by passing in props.\n *\n * ```tsx title=\"With options\"\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 (\n * <RedirectToSignIn\n * returnUrl=\"/dashboard\"\n * loginHint=\"user@example.com\"\n * />\n * );\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @param props - The props for customizing RedirectToSignIn.\n * @returns\n *\n * @category Components\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"],"mappings":"
|
|
1
|
+
{"version":3,"file":"redirect-to-signin.cjs","names":[],"sources":["../../../src/components/client/redirect-to-signin.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect-client-page';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n *\n * @category Types\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The URL to return to after successful authentication. If not provided, the current URL is used.\n */\n returnUrl?: string;\n}\n\n/**\n * `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.\n *\n * It does not render any UI.\n *\n * > This component must be used inside a Client Component (`\"use client\"`).\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 With Options\n *\n * You can customize the authorization request by passing in props.\n *\n * ```tsx title=\"With options\"\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 (\n * <RedirectToSignIn\n * returnUrl=\"/dashboard\"\n * loginHint=\"user@example.com\"\n * />\n * );\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @param props - The props for customizing RedirectToSignIn.\n * @returns\n *\n * @category Components\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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;CACjC,CAAA,GAAA,MAAA,iBAAgB;EACd,4BAAA,iBAAiB;GAAE;GAAW,GAAG;EAAW,CAAC;CAC/C,GAAG,CAAC,YAAY,SAAS,CAAC;CAC1B,OAAO;AACT"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
3
2
|
import { redirectToSignIn } from "../../client/protect-client-page.mjs";
|
|
4
3
|
import { useEffect } from "react";
|
|
5
|
-
|
|
6
4
|
//#region src/components/client/redirect-to-signin.tsx
|
|
7
5
|
/**
|
|
8
6
|
* `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.
|
|
@@ -70,7 +68,7 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
|
70
68
|
}, [authParams, returnUrl]);
|
|
71
69
|
return null;
|
|
72
70
|
};
|
|
73
|
-
|
|
74
71
|
//#endregion
|
|
75
72
|
export { RedirectToSignIn };
|
|
73
|
+
|
|
76
74
|
//# sourceMappingURL=redirect-to-signin.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redirect-to-signin.mjs","names":[],"sources":["../../../src/components/client/redirect-to-signin.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect-client-page';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n *\n * @category Types\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The URL to return to after successful authentication. If not provided, the current URL is used.\n */\n returnUrl?: string;\n}\n\n/**\n * `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.\n *\n * It does not render any UI.\n *\n * > This component must be used inside a Client Component (`\"use client\"`).\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 With Options\n *\n * You can customize the authorization request by passing in props.\n *\n * ```tsx title=\"With options\"\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 (\n * <RedirectToSignIn\n * returnUrl=\"/dashboard\"\n * loginHint=\"user@example.com\"\n * />\n * );\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @param props - The props for customizing RedirectToSignIn.\n * @returns\n *\n * @category Components\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"],"mappings":"
|
|
1
|
+
{"version":3,"file":"redirect-to-signin.mjs","names":[],"sources":["../../../src/components/client/redirect-to-signin.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect-client-page';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n *\n * @category Types\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The URL to return to after successful authentication. If not provided, the current URL is used.\n */\n returnUrl?: string;\n}\n\n/**\n * `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.\n *\n * It does not render any UI.\n *\n * > This component must be used inside a Client Component (`\"use client\"`).\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\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 With Options\n *\n * You can customize the authorization request by passing in props.\n *\n * ```tsx title=\"With options\"\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 (\n * <RedirectToSignIn\n * returnUrl=\"/dashboard\"\n * loginHint=\"user@example.com\"\n * />\n * );\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @param props - The props for customizing RedirectToSignIn.\n * @returns\n *\n * @category Components\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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;CACjC,gBAAgB;EACd,iBAAiB;GAAE;GAAW,GAAG;EAAW,CAAC;CAC/C,GAAG,CAAC,YAAY,SAAS,CAAC;CAC1B,OAAO;AACT"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
const require_signin = require(
|
|
3
|
-
const require_signup = require(
|
|
4
|
-
const require_signout = require(
|
|
5
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_signin = require("./signin.cjs");
|
|
3
|
+
const require_signup = require("./signup.cjs");
|
|
4
|
+
const require_signout = require("./signout.cjs");
|
|
6
5
|
exports.SignIn = require_signin.SignIn;
|
|
7
6
|
exports.SignOut = require_signout.SignOut;
|
|
8
|
-
exports.SignUp = require_signup.SignUp;
|
|
7
|
+
exports.SignUp = require_signup.SignUp;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const require_runtime = require(
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
2
|
let react = require("react");
|
|
3
3
|
react = require_runtime.__toESM(react);
|
|
4
|
-
|
|
5
4
|
//#region src/components/signin.tsx
|
|
6
5
|
/**
|
|
7
6
|
* `<SignIn>` renders a link that initiates the MonoCloud sign-in flow.
|
|
@@ -57,7 +56,7 @@ const SignIn = ({ children, authenticatorHint, loginHint, prompt, display, uiLoc
|
|
|
57
56
|
...props
|
|
58
57
|
}, children);
|
|
59
58
|
};
|
|
60
|
-
|
|
61
59
|
//#endregion
|
|
62
60
|
exports.SignIn = SignIn;
|
|
61
|
+
|
|
63
62
|
//# sourceMappingURL=signin.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signin.cjs","names":[],"sources":["../../src/components/signin.tsx"],"sourcesContent":["import React from 'react';\nimport { ExtraAuthParams } from '../types';\n\n/**\n * Props for the `<SignIn />` component.\n *\n * @category Types\n */\nexport interface SignInProps extends ExtraAuthParams {\n /**\n * Content rendered inside the link (for example, button text).\n */\n children: React.ReactNode;\n\n /**\n * URL to redirect to after successful sign-in.\n */\n returnUrl?: string;\n}\n\n/**\n * `<SignIn>` renders a link that initiates the MonoCloud sign-in flow.\n *\n * It can be used in both **App Router** and **Pages Router**, and may be rendered from either **Server** or **Client Components**.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\n * import { SignIn } from \"@monocloud/auth-nextjs/components\";\n *\n * export default function Home() {\n * return <SignIn>Sign In</SignIn>;\n * }\n * ```\n *\n * @example Customize the authorization request\n *\n * You can customize the authorization request by passing props:\n *\n * ```tsx title=\"Customize the authorization request\"\n * import { SignIn } from \"@monocloud/auth-nextjs/components\";\n *\n * export default function Home() {\n * return (\n * <SignIn loginHint=\"user@example.com\" authenticatorHint=\"password\" returnUrl=\"/dashboard\">\n * Sign In\n * </SignIn>\n * );\n * }\n * ```\n *\n * @param props - Properties for the SignIn component.\n * @returns An anchor element that links to the sign-in endpoint with the specified parameters.\n *\n * @category Components\n */\nexport const SignIn = ({\n children,\n authenticatorHint,\n loginHint,\n prompt,\n display,\n uiLocales,\n scopes,\n acrValues,\n resource,\n maxAge,\n returnUrl,\n ...props\n}: SignInProps &\n Omit<\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n 'resource'\n >): React.ReactNode => {\n const signInUrl =\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ??\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`;\n\n const query = new URLSearchParams();\n\n if (authenticatorHint) {\n query.set('authenticator_hint', authenticatorHint);\n }\n\n if (prompt) {\n query.set('prompt', prompt);\n }\n\n if (display) {\n query.set('display', display);\n }\n\n if (uiLocales) {\n query.set('ui_locales', uiLocales);\n }\n\n if (scopes) {\n query.set('scope', scopes);\n }\n\n if (acrValues) {\n query.set('acr_values', acrValues.join(' '));\n }\n\n if (resource) {\n query.set('resource', resource);\n }\n\n if (maxAge) {\n query.set('max_age', maxAge.toString());\n }\n\n if (loginHint) {\n query.set('login_hint', loginHint);\n }\n\n if (returnUrl) {\n query.set('return_url', returnUrl);\n }\n\n return (\n <a\n href={`${signInUrl}${query.size ? `?${query.toString()}` : ''}`}\n {...props}\n >\n {children}\n </a>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"signin.cjs","names":[],"sources":["../../src/components/signin.tsx"],"sourcesContent":["import React from 'react';\nimport { ExtraAuthParams } from '../types';\n\n/**\n * Props for the `<SignIn />` component.\n *\n * @category Types\n */\nexport interface SignInProps extends ExtraAuthParams {\n /**\n * Content rendered inside the link (for example, button text).\n */\n children: React.ReactNode;\n\n /**\n * URL to redirect to after successful sign-in.\n */\n returnUrl?: string;\n}\n\n/**\n * `<SignIn>` renders a link that initiates the MonoCloud sign-in flow.\n *\n * It can be used in both **App Router** and **Pages Router**, and may be rendered from either **Server** or **Client Components**.\n *\n * @example Basic Usage\n *\n * ```tsx title=\"Basic Usage\"\n * import { SignIn } from \"@monocloud/auth-nextjs/components\";\n *\n * export default function Home() {\n * return <SignIn>Sign In</SignIn>;\n * }\n * ```\n *\n * @example Customize the authorization request\n *\n * You can customize the authorization request by passing props:\n *\n * ```tsx title=\"Customize the authorization request\"\n * import { SignIn } from \"@monocloud/auth-nextjs/components\";\n *\n * export default function Home() {\n * return (\n * <SignIn loginHint=\"user@example.com\" authenticatorHint=\"password\" returnUrl=\"/dashboard\">\n * Sign In\n * </SignIn>\n * );\n * }\n * ```\n *\n * @param props - Properties for the SignIn component.\n * @returns An anchor element that links to the sign-in endpoint with the specified parameters.\n *\n * @category Components\n */\nexport const SignIn = ({\n children,\n authenticatorHint,\n loginHint,\n prompt,\n display,\n uiLocales,\n scopes,\n acrValues,\n resource,\n maxAge,\n returnUrl,\n ...props\n}: SignInProps &\n Omit<\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n 'resource'\n >): React.ReactNode => {\n const signInUrl =\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ??\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`;\n\n const query = new URLSearchParams();\n\n if (authenticatorHint) {\n query.set('authenticator_hint', authenticatorHint);\n }\n\n if (prompt) {\n query.set('prompt', prompt);\n }\n\n if (display) {\n query.set('display', display);\n }\n\n if (uiLocales) {\n query.set('ui_locales', uiLocales);\n }\n\n if (scopes) {\n query.set('scope', scopes);\n }\n\n if (acrValues) {\n query.set('acr_values', acrValues.join(' '));\n }\n\n if (resource) {\n query.set('resource', resource);\n }\n\n if (maxAge) {\n query.set('max_age', maxAge.toString());\n }\n\n if (loginHint) {\n query.set('login_hint', loginHint);\n }\n\n if (returnUrl) {\n query.set('return_url', returnUrl);\n }\n\n return (\n <a\n href={`${signInUrl}${query.size ? `?${query.toString()}` : ''}`}\n {...props}\n >\n {children}\n </a>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA,MAAa,UAAU,EACrB,UACA,mBACA,WACA,QACA,SACA,WACA,QACA,WACA,UACA,QACA,WACA,GAAG,YAKoB;CACvB,MAAM,YACJ,QAAQ,IAAI,yCAEZ,GAAG,QAAQ,IAAI,0BAA0B,GAAG;CAE9C,MAAM,QAAQ,IAAI,gBAAgB;CAElC,IAAI,mBACF,MAAM,IAAI,sBAAsB,iBAAiB;CAGnD,IAAI,QACF,MAAM,IAAI,UAAU,MAAM;CAG5B,IAAI,SACF,MAAM,IAAI,WAAW,OAAO;CAG9B,IAAI,WACF,MAAM,IAAI,cAAc,SAAS;CAGnC,IAAI,QACF,MAAM,IAAI,SAAS,MAAM;CAG3B,IAAI,WACF,MAAM,IAAI,cAAc,UAAU,KAAK,GAAG,CAAC;CAG7C,IAAI,UACF,MAAM,IAAI,YAAY,QAAQ;CAGhC,IAAI,QACF,MAAM,IAAI,WAAW,OAAO,SAAS,CAAC;CAGxC,IAAI,WACF,MAAM,IAAI,cAAc,SAAS;CAGnC,IAAI,WACF,MAAM,IAAI,cAAc,SAAS;CAGnC,OACE,sBAAA,QAAA,cAAC,KAAD;EACE,MAAM,GAAG,YAAY,MAAM,OAAO,IAAI,MAAM,SAAS,MAAM;EAC3D,GAAI;CAGH,GADA,QACA;AAEP"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
2
|
//#region src/components/signin.tsx
|
|
4
3
|
/**
|
|
5
4
|
* `<SignIn>` renders a link that initiates the MonoCloud sign-in flow.
|
|
@@ -55,7 +54,7 @@ const SignIn = ({ children, authenticatorHint, loginHint, prompt, display, uiLoc
|
|
|
55
54
|
...props
|
|
56
55
|
}, children);
|
|
57
56
|
};
|
|
58
|
-
|
|
59
57
|
//#endregion
|
|
60
58
|
export { SignIn };
|
|
59
|
+
|
|
61
60
|
//# sourceMappingURL=signin.mjs.map
|