@monocloud/auth-nextjs 0.1.9 → 0.1.11
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/README.md +1 -1
- package/dist/{chunk-C0xms8kb.cjs → _virtual/_rolldown/runtime.cjs} +1 -6
- package/dist/client/index.cjs +3 -2
- package/dist/client/index.d.mts +3 -203
- package/dist/client/index.mjs +2 -1
- package/dist/{protect-client-page-BdsnH8gs.cjs → client/protect-client-page.cjs} +9 -112
- package/dist/client/protect-client-page.cjs.map +1 -0
- package/dist/client/protect-client-page.d.mts +123 -0
- package/dist/{protect-client-page-BFVskb3X.mjs → client/protect-client-page.mjs} +5 -91
- package/dist/client/protect-client-page.mjs.map +1 -0
- package/dist/client/use-auth.cjs +96 -0
- package/dist/client/use-auth.cjs.map +1 -0
- package/dist/client/use-auth.d.mts +84 -0
- package/dist/client/use-auth.mjs +94 -0
- package/dist/client/use-auth.mjs.map +1 -0
- package/dist/components/client/index.cjs +4 -156
- package/dist/components/client/index.d.mts +3 -189
- package/dist/components/client/index.mjs +3 -153
- package/dist/components/client/protected.cjs +89 -0
- package/dist/components/client/protected.cjs.map +1 -0
- package/dist/components/client/protected.d.mts +114 -0
- package/dist/components/client/protected.mjs +87 -0
- package/dist/components/client/protected.mjs.map +1 -0
- package/dist/components/client/redirect-to-signin.cjs +77 -0
- package/dist/components/client/redirect-to-signin.cjs.map +1 -0
- package/dist/components/client/redirect-to-signin.d.mts +78 -0
- package/dist/components/client/redirect-to-signin.mjs +76 -0
- package/dist/components/client/redirect-to-signin.mjs.map +1 -0
- package/dist/components/index.cjs +6 -168
- package/dist/components/index.d.mts +4 -188
- package/dist/components/index.mjs +4 -164
- package/dist/components/signin.cjs +63 -0
- package/dist/components/signin.cjs.map +1 -0
- package/dist/components/signin.d.mts +72 -0
- package/dist/components/signin.mjs +61 -0
- package/dist/components/signin.mjs.map +1 -0
- package/dist/components/signout.cjs +49 -0
- package/dist/components/signout.cjs.map +1 -0
- package/dist/components/signout.d.mts +55 -0
- package/dist/components/signout.mjs +47 -0
- package/dist/components/signout.mjs.map +1 -0
- package/dist/components/signup.cjs +67 -0
- package/dist/components/signup.cjs.map +1 -0
- package/dist/components/signup.d.mts +70 -0
- package/dist/components/signup.mjs +65 -0
- package/dist/components/signup.mjs.map +1 -0
- package/dist/index.cjs +15 -1136
- package/dist/index.d.mts +5 -1681
- package/dist/index.mjs +4 -1125
- package/dist/initialize.cjs +284 -0
- package/dist/initialize.cjs.map +1 -0
- package/dist/initialize.d.mts +1383 -0
- package/dist/initialize.mjs +274 -0
- package/dist/initialize.mjs.map +1 -0
- package/dist/monocloud-next-client.cjs +600 -0
- package/dist/monocloud-next-client.cjs.map +1 -0
- package/dist/monocloud-next-client.d.mts +330 -0
- package/dist/monocloud-next-client.mjs +599 -0
- package/dist/monocloud-next-client.mjs.map +1 -0
- package/dist/requests/monocloud-app-router-request.cjs +32 -0
- package/dist/requests/monocloud-app-router-request.cjs.map +1 -0
- package/dist/requests/monocloud-app-router-request.mjs +31 -0
- package/dist/requests/monocloud-app-router-request.mjs.map +1 -0
- package/dist/requests/monocloud-cookie-request.cjs +22 -0
- package/dist/requests/monocloud-cookie-request.cjs.map +1 -0
- package/dist/requests/monocloud-cookie-request.mjs +21 -0
- package/dist/requests/monocloud-cookie-request.mjs.map +1 -0
- package/dist/requests/monocloud-page-router-request.cjs +37 -0
- package/dist/requests/monocloud-page-router-request.cjs.map +1 -0
- package/dist/requests/monocloud-page-router-request.mjs +36 -0
- package/dist/requests/monocloud-page-router-request.mjs.map +1 -0
- package/dist/responses/monocloud-app-router-response.cjs +67 -0
- package/dist/responses/monocloud-app-router-response.cjs.map +1 -0
- package/dist/responses/monocloud-app-router-response.mjs +66 -0
- package/dist/responses/monocloud-app-router-response.mjs.map +1 -0
- package/dist/responses/monocloud-cookie-response.cjs +20 -0
- package/dist/responses/monocloud-cookie-response.cjs.map +1 -0
- package/dist/responses/monocloud-cookie-response.mjs +19 -0
- package/dist/responses/monocloud-cookie-response.mjs.map +1 -0
- package/dist/responses/monocloud-page-router-response.cjs +54 -0
- package/dist/responses/monocloud-page-router-response.cjs.map +1 -0
- package/dist/responses/monocloud-page-router-response.mjs +53 -0
- package/dist/responses/monocloud-page-router-response.mjs.map +1 -0
- package/dist/{types-ClljFIvK.d.mts → types.d.mts} +2 -2
- package/dist/utils.cjs +89 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.mjs +80 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +3 -3
- package/dist/components/client/index.cjs.map +0 -1
- package/dist/components/client/index.mjs.map +0 -1
- package/dist/components/index.cjs.map +0 -1
- package/dist/components/index.mjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/protect-client-page-BFVskb3X.mjs.map +0 -1
- package/dist/protect-client-page-BdsnH8gs.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ This SDK is designed specifically for **Next.js**, providing first-class integra
|
|
|
29
29
|
|
|
30
30
|
- **Documentation:** [https://www.monocloud.com/docs](https://www.monocloud.com/docs?utm_source=github&utm_medium=auth_js)
|
|
31
31
|
- **Quickstart:** [https://www.monocloud.com/docs/quickstarts/nextjs-app-router](https://www.monocloud.com/docs/quickstarts/nextjs-app-router?utm_source=github&utm_medium=auth_js)
|
|
32
|
-
- **SDK Reference:** [https://www.monocloud.com/docs/
|
|
32
|
+
- **SDK Reference:** [https://www.monocloud.com/docs/sdks/nextjs](https://www.monocloud.com/docs/sdks/nextjs/index?utm_source=github&utm_medium=auth_js)
|
|
33
33
|
- **API Reference:** [https://monocloud.github.io/auth-js](https://monocloud.github.io/auth-js?utm_source=github&utm_medium=auth_js)
|
|
34
34
|
|
|
35
35
|
## Supported Platforms
|
package/dist/client/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const
|
|
2
|
+
const require_use_auth = require('./use-auth.cjs');
|
|
3
|
+
const require_protect_client_page = require('./protect-client-page.cjs');
|
|
3
4
|
|
|
4
5
|
exports.protectClientPage = require_protect_client_page.protectClientPage;
|
|
5
|
-
exports.useAuth =
|
|
6
|
+
exports.useAuth = require_use_auth.useAuth;
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,203 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//#region src/client/use-auth.d.ts
|
|
6
|
-
/**
|
|
7
|
-
* Authentication State returned by `useAuth` hook.
|
|
8
|
-
*
|
|
9
|
-
* @category Types
|
|
10
|
-
*/
|
|
11
|
-
interface AuthenticationState {
|
|
12
|
-
/**
|
|
13
|
-
* Flag indicating if the authentication state is still loading.
|
|
14
|
-
*/
|
|
15
|
-
isLoading: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Flag indicating if the user is authenticated.
|
|
18
|
-
*/
|
|
19
|
-
isAuthenticated: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Error encountered during authentication, if any.
|
|
22
|
-
*/
|
|
23
|
-
error?: Error;
|
|
24
|
-
/**
|
|
25
|
-
* The authenticated user's information, if available.
|
|
26
|
-
*/
|
|
27
|
-
user?: MonoCloudUser;
|
|
28
|
-
/**
|
|
29
|
-
* Function to refetch the authentication state.
|
|
30
|
-
*
|
|
31
|
-
*/
|
|
32
|
-
refetch: (refresh?: boolean) => void;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
* `useAuth()` is a client-side hook that provides access to the current authentication state.
|
|
37
|
-
*
|
|
38
|
-
* It can only be used inside **Client Components**.
|
|
39
|
-
*
|
|
40
|
-
* @example Basic Usage
|
|
41
|
-
* ```tsx title="Basic Usage"
|
|
42
|
-
* "use client";
|
|
43
|
-
*
|
|
44
|
-
* import { useAuth } from "@monocloud/auth-nextjs/client";
|
|
45
|
-
*
|
|
46
|
-
* export default function Home() {
|
|
47
|
-
* const { user, isAuthenticated } = useAuth();
|
|
48
|
-
*
|
|
49
|
-
* if (!isAuthenticated) {
|
|
50
|
-
* return <>Not signed in</>;
|
|
51
|
-
* }
|
|
52
|
-
*
|
|
53
|
-
* return <>User Id: {user?.sub}</>;
|
|
54
|
-
* }
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* @example Refetch user
|
|
58
|
-
*
|
|
59
|
-
* Calling `refetch(true)` forces a refresh of the user profile from the `UserInfo` endpoint.
|
|
60
|
-
* Calling `refetch()` refreshes authentication state without forcing a `UserInfo` request.
|
|
61
|
-
*
|
|
62
|
-
* ```tsx title="Refetch User"
|
|
63
|
-
* "use client";
|
|
64
|
-
*
|
|
65
|
-
* import { useAuth } from "@monocloud/auth-nextjs/client";
|
|
66
|
-
*
|
|
67
|
-
* export default function Home() {
|
|
68
|
-
* const { user, refetch } = useAuth();
|
|
69
|
-
*
|
|
70
|
-
* return (
|
|
71
|
-
* <>
|
|
72
|
-
* <pre>{JSON.stringify(user, null, 2)}</pre>
|
|
73
|
-
* <button onClick={() => refetch(true)}>Refresh Profile</button>
|
|
74
|
-
* </>
|
|
75
|
-
* );
|
|
76
|
-
* }
|
|
77
|
-
* ```
|
|
78
|
-
*
|
|
79
|
-
* @returns
|
|
80
|
-
*
|
|
81
|
-
* @category Hooks
|
|
82
|
-
*/
|
|
83
|
-
declare const useAuth: () => AuthenticationState;
|
|
84
|
-
//#endregion
|
|
85
|
-
//#region src/client/protect-client-page.d.ts
|
|
86
|
-
/**
|
|
87
|
-
* Options for configuring page protection.
|
|
88
|
-
*
|
|
89
|
-
* @category Types
|
|
90
|
-
*/
|
|
91
|
-
interface ProtectClientPageOptions extends GroupOptions {
|
|
92
|
-
/**
|
|
93
|
-
* The URL where the user will be redirected to after sign in.
|
|
94
|
-
*/
|
|
95
|
-
returnUrl?: string;
|
|
96
|
-
/**
|
|
97
|
-
* A custom react element to render when the user is not authenticated.
|
|
98
|
-
*/
|
|
99
|
-
onAccessDenied?: () => React.ReactNode;
|
|
100
|
-
/**
|
|
101
|
-
* A custom react element to render when the user is authenticated but does not belong to the required groups.
|
|
102
|
-
*/
|
|
103
|
-
onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;
|
|
104
|
-
/**
|
|
105
|
-
* Authorization parameters to be used during authentication.
|
|
106
|
-
*/
|
|
107
|
-
authParams?: ExtraAuthParams;
|
|
108
|
-
/**
|
|
109
|
-
* Callback function to handle errors.
|
|
110
|
-
* If not provided, errors will be thrown.
|
|
111
|
-
*
|
|
112
|
-
* @param error - The error object.
|
|
113
|
-
* @returns JSX element to handle the error.
|
|
114
|
-
*/
|
|
115
|
-
onError?: (error: Error) => React.ReactNode;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.
|
|
119
|
-
*
|
|
120
|
-
* If the user is authenticated, the wrapped component receives a `user` prop.
|
|
121
|
-
*
|
|
122
|
-
* > This function runs on the client and controls rendering only.
|
|
123
|
-
* > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.
|
|
124
|
-
*
|
|
125
|
-
* @example Basic Usage
|
|
126
|
-
*
|
|
127
|
-
* ```tsx title="Basic Usage"
|
|
128
|
-
* "use client";
|
|
129
|
-
*
|
|
130
|
-
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
131
|
-
*
|
|
132
|
-
* export default protectClientPage(function Home({ user }) {
|
|
133
|
-
* return <>Signed in as {user.email}</>;
|
|
134
|
-
* });
|
|
135
|
-
* ```
|
|
136
|
-
*
|
|
137
|
-
* @example With Options
|
|
138
|
-
*
|
|
139
|
-
* ```tsx title="With Options"
|
|
140
|
-
* "use client";
|
|
141
|
-
*
|
|
142
|
-
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
143
|
-
*
|
|
144
|
-
* export default protectClientPage(
|
|
145
|
-
* function Home({ user }) {
|
|
146
|
-
* return <>Signed in as {user.email}</>;
|
|
147
|
-
* },
|
|
148
|
-
* {
|
|
149
|
-
* returnUrl: "/dashboard",
|
|
150
|
-
* authParams: { loginHint: "user@example.com" }
|
|
151
|
-
* }
|
|
152
|
-
* );
|
|
153
|
-
* ```
|
|
154
|
-
*
|
|
155
|
-
* @example Custom access denied UI
|
|
156
|
-
*
|
|
157
|
-
* ```tsx title="Custom access denied UI"
|
|
158
|
-
* "use client";
|
|
159
|
-
*
|
|
160
|
-
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
161
|
-
*
|
|
162
|
-
* export default protectClientPage(
|
|
163
|
-
* function Home({ user }) {
|
|
164
|
-
* return <>Signed in as {user.email}</>;
|
|
165
|
-
* },
|
|
166
|
-
* {
|
|
167
|
-
* onAccessDenied: () => <div>Please sign in to continue</div>
|
|
168
|
-
* }
|
|
169
|
-
* );
|
|
170
|
-
* ```
|
|
171
|
-
*
|
|
172
|
-
* @example Group protection
|
|
173
|
-
*
|
|
174
|
-
* ```tsx title="Group protection"
|
|
175
|
-
* "use client";
|
|
176
|
-
*
|
|
177
|
-
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
178
|
-
*
|
|
179
|
-
* export default protectClientPage(
|
|
180
|
-
* function Home({ user }) {
|
|
181
|
-
* return <>Welcome Admin {user.email}</>;
|
|
182
|
-
* },
|
|
183
|
-
* {
|
|
184
|
-
* groups: ["admin"],
|
|
185
|
-
* onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>
|
|
186
|
-
* }
|
|
187
|
-
* );
|
|
188
|
-
* ```
|
|
189
|
-
*
|
|
190
|
-
* @param Component - The page component to protect
|
|
191
|
-
* @typeParam P - Props of the protected component (excluding `user`).
|
|
192
|
-
* @param options - Optional configuration
|
|
193
|
-
* @returns A protected React component.
|
|
194
|
-
*
|
|
195
|
-
* @category Functions
|
|
196
|
-
*
|
|
197
|
-
*/
|
|
198
|
-
declare const protectClientPage: <P extends object>(Component: ComponentType<P & {
|
|
199
|
-
user: MonoCloudUser;
|
|
200
|
-
}>, options?: ProtectClientPageOptions) => React.FC<P>;
|
|
201
|
-
//#endregion
|
|
202
|
-
export { type AuthenticationState, type ProtectClientPageOptions, protectClientPage, useAuth };
|
|
203
|
-
//# sourceMappingURL=index.d.mts.map
|
|
1
|
+
import { AuthenticationState, useAuth } from "./use-auth.mjs";
|
|
2
|
+
import { ProtectClientPageOptions, protectClientPage } from "./protect-client-page.mjs";
|
|
3
|
+
export { type AuthenticationState, type ProtectClientPageOptions, protectClientPage, useAuth };
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,98 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
const require_use_auth = require('./use-auth.cjs');
|
|
2
5
|
let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
|
|
3
|
-
let swr = require("swr");
|
|
4
|
-
swr = require_chunk.__toESM(swr);
|
|
5
6
|
let react = require("react");
|
|
6
|
-
react =
|
|
7
|
+
react = require_runtime.__toESM(react);
|
|
7
8
|
|
|
8
|
-
//#region src/client/use-auth.tsx
|
|
9
|
-
const fetchUser = async (url) => {
|
|
10
|
-
const res = await fetch(url, { credentials: "include" });
|
|
11
|
-
if (res.status === 204) return;
|
|
12
|
-
if (res.ok) return res.json();
|
|
13
|
-
throw new Error("Failed to fetch user");
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* `useAuth()` is a client-side hook that provides access to the current authentication state.
|
|
18
|
-
*
|
|
19
|
-
* It can only be used inside **Client Components**.
|
|
20
|
-
*
|
|
21
|
-
* @example Basic Usage
|
|
22
|
-
* ```tsx title="Basic Usage"
|
|
23
|
-
* "use client";
|
|
24
|
-
*
|
|
25
|
-
* import { useAuth } from "@monocloud/auth-nextjs/client";
|
|
26
|
-
*
|
|
27
|
-
* export default function Home() {
|
|
28
|
-
* const { user, isAuthenticated } = useAuth();
|
|
29
|
-
*
|
|
30
|
-
* if (!isAuthenticated) {
|
|
31
|
-
* return <>Not signed in</>;
|
|
32
|
-
* }
|
|
33
|
-
*
|
|
34
|
-
* return <>User Id: {user?.sub}</>;
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*
|
|
38
|
-
* @example Refetch user
|
|
39
|
-
*
|
|
40
|
-
* Calling `refetch(true)` forces a refresh of the user profile from the `UserInfo` endpoint.
|
|
41
|
-
* Calling `refetch()` refreshes authentication state without forcing a `UserInfo` request.
|
|
42
|
-
*
|
|
43
|
-
* ```tsx title="Refetch User"
|
|
44
|
-
* "use client";
|
|
45
|
-
*
|
|
46
|
-
* import { useAuth } from "@monocloud/auth-nextjs/client";
|
|
47
|
-
*
|
|
48
|
-
* export default function Home() {
|
|
49
|
-
* const { user, refetch } = useAuth();
|
|
50
|
-
*
|
|
51
|
-
* return (
|
|
52
|
-
* <>
|
|
53
|
-
* <pre>{JSON.stringify(user, null, 2)}</pre>
|
|
54
|
-
* <button onClick={() => refetch(true)}>Refresh Profile</button>
|
|
55
|
-
* </>
|
|
56
|
-
* );
|
|
57
|
-
* }
|
|
58
|
-
* ```
|
|
59
|
-
*
|
|
60
|
-
* @returns
|
|
61
|
-
*
|
|
62
|
-
* @category Hooks
|
|
63
|
-
*/
|
|
64
|
-
const useAuth = () => {
|
|
65
|
-
const key = process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`;
|
|
66
|
-
const { data, error, isLoading, mutate } = (0, swr.default)(key, fetchUser);
|
|
67
|
-
const refetch = (refresh) => {
|
|
68
|
-
const url = new URL(key, "https://dummy");
|
|
69
|
-
if (refresh) url.searchParams.set("refresh", "true");
|
|
70
|
-
mutate(async () => await fetchUser(url.pathname + url.search), { revalidate: false });
|
|
71
|
-
};
|
|
72
|
-
if (error) return {
|
|
73
|
-
user: void 0,
|
|
74
|
-
isLoading: false,
|
|
75
|
-
isAuthenticated: false,
|
|
76
|
-
error,
|
|
77
|
-
refetch
|
|
78
|
-
};
|
|
79
|
-
if (data) return {
|
|
80
|
-
user: data,
|
|
81
|
-
isLoading,
|
|
82
|
-
isAuthenticated: !!data && Object.keys(data).length > 0,
|
|
83
|
-
error: void 0,
|
|
84
|
-
refetch
|
|
85
|
-
};
|
|
86
|
-
return {
|
|
87
|
-
user: void 0,
|
|
88
|
-
isLoading,
|
|
89
|
-
isAuthenticated: false,
|
|
90
|
-
error: void 0,
|
|
91
|
-
refetch: () => {}
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
//#endregion
|
|
96
9
|
//#region src/client/protect-client-page.tsx
|
|
97
10
|
const redirectToSignIn = (options) => {
|
|
98
11
|
const searchParams = new URLSearchParams(window.location.search);
|
|
@@ -197,7 +110,7 @@ const handlePageError = (error, options) => {
|
|
|
197
110
|
*/
|
|
198
111
|
const protectClientPage = (Component, options) => {
|
|
199
112
|
return (props) => {
|
|
200
|
-
const { user, error, isLoading } = useAuth();
|
|
113
|
+
const { user, error, isLoading } = require_use_auth.useAuth();
|
|
201
114
|
(0, react.useEffect)(() => {
|
|
202
115
|
if (!user && !isLoading && !error) {
|
|
203
116
|
if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
|
|
@@ -229,22 +142,6 @@ const protectClientPage = (Component, options) => {
|
|
|
229
142
|
};
|
|
230
143
|
|
|
231
144
|
//#endregion
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return protectClientPage;
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
Object.defineProperty(exports, 'redirectToSignIn', {
|
|
239
|
-
enumerable: true,
|
|
240
|
-
get: function () {
|
|
241
|
-
return redirectToSignIn;
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
Object.defineProperty(exports, 'useAuth', {
|
|
245
|
-
enumerable: true,
|
|
246
|
-
get: function () {
|
|
247
|
-
return useAuth;
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
//# sourceMappingURL=protect-client-page-BdsnH8gs.cjs.map
|
|
145
|
+
exports.protectClientPage = protectClientPage;
|
|
146
|
+
exports.redirectToSignIn = redirectToSignIn;
|
|
147
|
+
//# sourceMappingURL=protect-client-page.cjs.map
|
|
@@ -0,0 +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":";;;;;;;;;AA8CA,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAChE,cAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,UAAU,CAChD;AAED,uDAAI,QAAS,OACX,cAAa,IAAI,SAAS,QAAQ,OAAO;AAE3C,uDAAI,QAAS,SACX,cAAa,IAAI,YAAY,QAAQ,SAAS;AAGhD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,IAAI,CAAC;AAG7D,uDAAI,QAAS,QACX,cAAa,IAAI,WAAW,QAAQ,QAAQ;AAG9C,uDAAI,QAAS,OACX,cAAa,IAAI,UAAU,QAAQ,OAAO;AAG5C,uDAAI,QAAS,kBACX,cAAa,IAAI,sBAAsB,QAAQ,kBAAkB;AAGnE,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,uDAAI,QAAS,OACX,cAAa,IAAI,WAAW,QAAQ,OAAO,UAAU,CAAC;AAGxD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,QAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,UAAU,GACjJ;;AAGH,MAAM,mBACJ,OACA,YACoB;;AAEpB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFR,MAAa,qBACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAcA,0BAAS;AAE5C,6BAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,oDACE,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EACJ,4BAA6C,4CAAC,aAAI,gBAAmB,KACnE;AACJ,WAAO,oBAAoB,KAAK;;AAGlC,UAAO,4CAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { ExtraAuthParams, GroupOptions } from "../types.mjs";
|
|
2
|
+
import { MonoCloudUser } from "@monocloud/auth-node-core";
|
|
3
|
+
import React, { ComponentType } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/client/protect-client-page.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Options for configuring page protection.
|
|
8
|
+
*
|
|
9
|
+
* @category Types
|
|
10
|
+
*/
|
|
11
|
+
interface ProtectClientPageOptions extends GroupOptions {
|
|
12
|
+
/**
|
|
13
|
+
* The URL where the user will be redirected to after sign in.
|
|
14
|
+
*/
|
|
15
|
+
returnUrl?: string;
|
|
16
|
+
/**
|
|
17
|
+
* A custom react element to render when the user is not authenticated.
|
|
18
|
+
*/
|
|
19
|
+
onAccessDenied?: () => React.ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* A custom react element to render when the user is authenticated but does not belong to the required groups.
|
|
22
|
+
*/
|
|
23
|
+
onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Authorization parameters to be used during authentication.
|
|
26
|
+
*/
|
|
27
|
+
authParams?: ExtraAuthParams;
|
|
28
|
+
/**
|
|
29
|
+
* Callback function to handle errors.
|
|
30
|
+
* If not provided, errors will be thrown.
|
|
31
|
+
*
|
|
32
|
+
* @param error - The error object.
|
|
33
|
+
* @returns JSX element to handle the error.
|
|
34
|
+
*/
|
|
35
|
+
onError?: (error: Error) => React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.
|
|
39
|
+
*
|
|
40
|
+
* If the user is authenticated, the wrapped component receives a `user` prop.
|
|
41
|
+
*
|
|
42
|
+
* > This function runs on the client and controls rendering only.
|
|
43
|
+
* > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.
|
|
44
|
+
*
|
|
45
|
+
* @example Basic Usage
|
|
46
|
+
*
|
|
47
|
+
* ```tsx title="Basic Usage"
|
|
48
|
+
* "use client";
|
|
49
|
+
*
|
|
50
|
+
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
51
|
+
*
|
|
52
|
+
* export default protectClientPage(function Home({ user }) {
|
|
53
|
+
* return <>Signed in as {user.email}</>;
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @example With Options
|
|
58
|
+
*
|
|
59
|
+
* ```tsx title="With Options"
|
|
60
|
+
* "use client";
|
|
61
|
+
*
|
|
62
|
+
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
63
|
+
*
|
|
64
|
+
* export default protectClientPage(
|
|
65
|
+
* function Home({ user }) {
|
|
66
|
+
* return <>Signed in as {user.email}</>;
|
|
67
|
+
* },
|
|
68
|
+
* {
|
|
69
|
+
* returnUrl: "/dashboard",
|
|
70
|
+
* authParams: { loginHint: "user@example.com" }
|
|
71
|
+
* }
|
|
72
|
+
* );
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example Custom access denied UI
|
|
76
|
+
*
|
|
77
|
+
* ```tsx title="Custom access denied UI"
|
|
78
|
+
* "use client";
|
|
79
|
+
*
|
|
80
|
+
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
81
|
+
*
|
|
82
|
+
* export default protectClientPage(
|
|
83
|
+
* function Home({ user }) {
|
|
84
|
+
* return <>Signed in as {user.email}</>;
|
|
85
|
+
* },
|
|
86
|
+
* {
|
|
87
|
+
* onAccessDenied: () => <div>Please sign in to continue</div>
|
|
88
|
+
* }
|
|
89
|
+
* );
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @example Group protection
|
|
93
|
+
*
|
|
94
|
+
* ```tsx title="Group protection"
|
|
95
|
+
* "use client";
|
|
96
|
+
*
|
|
97
|
+
* import { protectClientPage } from "@monocloud/auth-nextjs/client";
|
|
98
|
+
*
|
|
99
|
+
* export default protectClientPage(
|
|
100
|
+
* function Home({ user }) {
|
|
101
|
+
* return <>Welcome Admin {user.email}</>;
|
|
102
|
+
* },
|
|
103
|
+
* {
|
|
104
|
+
* groups: ["admin"],
|
|
105
|
+
* onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>
|
|
106
|
+
* }
|
|
107
|
+
* );
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @param Component - The page component to protect
|
|
111
|
+
* @typeParam P - Props of the protected component (excluding `user`).
|
|
112
|
+
* @param options - Optional configuration
|
|
113
|
+
* @returns A protected React component.
|
|
114
|
+
*
|
|
115
|
+
* @category Functions
|
|
116
|
+
*
|
|
117
|
+
*/
|
|
118
|
+
declare const protectClientPage: <P extends object>(Component: ComponentType<P & {
|
|
119
|
+
user: MonoCloudUser;
|
|
120
|
+
}>, options?: ProtectClientPageOptions) => React.FC<P>;
|
|
121
|
+
//#endregion
|
|
122
|
+
export { ProtectClientPageOptions, protectClientPage };
|
|
123
|
+
//# sourceMappingURL=protect-client-page.d.mts.map
|
|
@@ -1,95 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useAuth } from "./use-auth.mjs";
|
|
1
4
|
import { isUserInGroup } from "@monocloud/auth-node-core/utils";
|
|
2
|
-
import useSWR from "swr";
|
|
3
5
|
import React, { useEffect } from "react";
|
|
4
6
|
|
|
5
|
-
//#region src/client/use-auth.tsx
|
|
6
|
-
const fetchUser = async (url) => {
|
|
7
|
-
const res = await fetch(url, { credentials: "include" });
|
|
8
|
-
if (res.status === 204) return;
|
|
9
|
-
if (res.ok) return res.json();
|
|
10
|
-
throw new Error("Failed to fetch user");
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* `useAuth()` is a client-side hook that provides access to the current authentication state.
|
|
15
|
-
*
|
|
16
|
-
* It can only be used inside **Client Components**.
|
|
17
|
-
*
|
|
18
|
-
* @example Basic Usage
|
|
19
|
-
* ```tsx title="Basic Usage"
|
|
20
|
-
* "use client";
|
|
21
|
-
*
|
|
22
|
-
* import { useAuth } from "@monocloud/auth-nextjs/client";
|
|
23
|
-
*
|
|
24
|
-
* export default function Home() {
|
|
25
|
-
* const { user, isAuthenticated } = useAuth();
|
|
26
|
-
*
|
|
27
|
-
* if (!isAuthenticated) {
|
|
28
|
-
* return <>Not signed in</>;
|
|
29
|
-
* }
|
|
30
|
-
*
|
|
31
|
-
* return <>User Id: {user?.sub}</>;
|
|
32
|
-
* }
|
|
33
|
-
* ```
|
|
34
|
-
*
|
|
35
|
-
* @example Refetch user
|
|
36
|
-
*
|
|
37
|
-
* Calling `refetch(true)` forces a refresh of the user profile from the `UserInfo` endpoint.
|
|
38
|
-
* Calling `refetch()` refreshes authentication state without forcing a `UserInfo` request.
|
|
39
|
-
*
|
|
40
|
-
* ```tsx title="Refetch User"
|
|
41
|
-
* "use client";
|
|
42
|
-
*
|
|
43
|
-
* import { useAuth } from "@monocloud/auth-nextjs/client";
|
|
44
|
-
*
|
|
45
|
-
* export default function Home() {
|
|
46
|
-
* const { user, refetch } = useAuth();
|
|
47
|
-
*
|
|
48
|
-
* return (
|
|
49
|
-
* <>
|
|
50
|
-
* <pre>{JSON.stringify(user, null, 2)}</pre>
|
|
51
|
-
* <button onClick={() => refetch(true)}>Refresh Profile</button>
|
|
52
|
-
* </>
|
|
53
|
-
* );
|
|
54
|
-
* }
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* @returns
|
|
58
|
-
*
|
|
59
|
-
* @category Hooks
|
|
60
|
-
*/
|
|
61
|
-
const useAuth = () => {
|
|
62
|
-
const key = process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`;
|
|
63
|
-
const { data, error, isLoading, mutate } = useSWR(key, fetchUser);
|
|
64
|
-
const refetch = (refresh) => {
|
|
65
|
-
const url = new URL(key, "https://dummy");
|
|
66
|
-
if (refresh) url.searchParams.set("refresh", "true");
|
|
67
|
-
mutate(async () => await fetchUser(url.pathname + url.search), { revalidate: false });
|
|
68
|
-
};
|
|
69
|
-
if (error) return {
|
|
70
|
-
user: void 0,
|
|
71
|
-
isLoading: false,
|
|
72
|
-
isAuthenticated: false,
|
|
73
|
-
error,
|
|
74
|
-
refetch
|
|
75
|
-
};
|
|
76
|
-
if (data) return {
|
|
77
|
-
user: data,
|
|
78
|
-
isLoading,
|
|
79
|
-
isAuthenticated: !!data && Object.keys(data).length > 0,
|
|
80
|
-
error: void 0,
|
|
81
|
-
refetch
|
|
82
|
-
};
|
|
83
|
-
return {
|
|
84
|
-
user: void 0,
|
|
85
|
-
isLoading,
|
|
86
|
-
isAuthenticated: false,
|
|
87
|
-
error: void 0,
|
|
88
|
-
refetch: () => {}
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
//#endregion
|
|
93
7
|
//#region src/client/protect-client-page.tsx
|
|
94
8
|
const redirectToSignIn = (options) => {
|
|
95
9
|
const searchParams = new URLSearchParams(window.location.search);
|
|
@@ -226,5 +140,5 @@ const protectClientPage = (Component, options) => {
|
|
|
226
140
|
};
|
|
227
141
|
|
|
228
142
|
//#endregion
|
|
229
|
-
export {
|
|
230
|
-
//# sourceMappingURL=protect-client-page
|
|
143
|
+
export { protectClientPage, redirectToSignIn };
|
|
144
|
+
//# sourceMappingURL=protect-client-page.mjs.map
|
|
@@ -0,0 +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":";;;;;;;AA8CA,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAChE,cAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,UAAU,CAChD;AAED,uDAAI,QAAS,OACX,cAAa,IAAI,SAAS,QAAQ,OAAO;AAE3C,uDAAI,QAAS,SACX,cAAa,IAAI,YAAY,QAAQ,SAAS;AAGhD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,IAAI,CAAC;AAG7D,uDAAI,QAAS,QACX,cAAa,IAAI,WAAW,QAAQ,QAAQ;AAG9C,uDAAI,QAAS,OACX,cAAa,IAAI,UAAU,QAAQ,OAAO;AAG5C,uDAAI,QAAS,kBACX,cAAa,IAAI,sBAAsB,QAAQ,kBAAkB;AAGnE,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,uDAAI,QAAS,OACX,cAAa,IAAI,WAAW,QAAQ,OAAO,UAAU,CAAC;AAGxD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,QAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,UAAU,GACjJ;;AAGH,MAAM,mBACJ,OACA,YACoB;;AAEpB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFR,MAAa,qBACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,SAAS;AAE5C,kBAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,CAAC,cACC,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EACJ,4BAA6C,oCAAC,aAAI,gBAAmB,KACnE;AACJ,WAAO,oBAAoB,KAAK;;AAGlC,UAAO,oCAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
|