@monocloud/auth-nextjs 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,21 @@
1
- ![MonoCloud Logo](https://raw.githubusercontent.com/monocloud/auth-js/refs/heads/main/MonoCloud.png)
1
+ <div align="center">
2
+ <a href="https://www.monocloud.com?utm_source=github&utm_medium=auth_js" target="_blank" rel="noopener noreferrer">
3
+ <picture>
4
+ <img src="https://raw.githubusercontent.com/monocloud/auth-js/refs/heads/main/packages/nextjs/banner.svg" alt="MonoCloud Banner">
5
+ </picture>
6
+ </a>
7
+ <div align="right">
8
+ <a href="https://www.npmjs.com/package/@monocloud/auth-nextjs" target="_blank">
9
+ <img src="https://img.shields.io/npm/v/@monocloud/auth-nextjs" alt="NPM" />
10
+ </a>
11
+ <a href="https://opensource.org/licenses/MIT">
12
+ <img src="https://img.shields.io/:license-MIT-blue.svg?style=flat" alt="License: MIT" />
13
+ </a>
14
+ <a href="https://github.com/monocloud/auth-js/actions/workflows/build.yml">
15
+ <img src="https://github.com/monocloud/auth-js/actions/workflows/build.yml/badge.svg" alt="Build Status" />
16
+ </a>
17
+ </div>
18
+ </div>
2
19
 
3
20
  ## Introduction
4
21
 
@@ -11,8 +28,8 @@ This SDK is designed specifically for **Next.js**, providing first-class integra
11
28
  ## 📘 Documentation
12
29
 
13
30
  - **Documentation:** [https://www.monocloud.com/docs](https://www.monocloud.com/docs?utm_source=github&utm_medium=auth_js)
14
- - **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)
15
- - **SDK Reference:** [https://www.monocloud.com/docs/sdk-reference/nextjs](https://www.monocloud.com/docs/sdk-reference/nextjs/index?utm_source=github&utm_medium=auth_js)
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/sdk-reference/nextjs](https://www.monocloud.com/docs/sdk-reference/nextjs/index?utm_source=github&utm_medium=auth_js)
16
33
  - **API Reference:** [https://monocloud.github.io/auth-js](https://monocloud.github.io/auth-js?utm_source=github&utm_medium=auth_js)
17
34
 
18
35
  ## Supported Platforms
@@ -41,7 +58,7 @@ npm install @monocloud/auth-nextjs
41
58
 
42
59
  Create a `.env.local` file in your project root. The SDK automatically reads variables prefixed with `MONOCLOUD_AUTH__`.
43
60
 
44
- ```env
61
+ ```bash
45
62
  MONOCLOUD_AUTH_TENANT_DOMAIN=https://<your-tenant-domain>
46
63
  MONOCLOUD_AUTH_CLIENT_ID=<your-client-id>
47
64
  MONOCLOUD_AUTH_CLIENT_SECRET=<your-client-secret>
@@ -1,4 +1,4 @@
1
- //#region rolldown:runtime
1
+ //#region \0rolldown/runtime.js
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,4 +1,5 @@
1
- const require_client = require('../client-xfBYYato.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_protect_client_page = require('../protect-client-page-B1fOU4Zl.cjs');
2
3
 
3
- exports.protectPage = require_client.protectPage;
4
- exports.useAuth = require_client.useAuth;
4
+ exports.protectClientPage = require_protect_client_page.protectClientPage;
5
+ exports.useAuth = require_protect_client_page.useAuth;
@@ -1,12 +1,14 @@
1
- import { a as GroupOptions, i as ExtraAuthParams } from "../types-CsBjAJce.mjs";
1
+ import { c as ExtraAuthParams, l as GroupOptions } from "../types-xS_Me3Qg.mjs";
2
2
  import { MonoCloudUser } from "@monocloud/auth-node-core";
3
- import React, { ComponentType, JSX } from "react";
3
+ import React, { ComponentType } from "react";
4
4
 
5
5
  //#region src/client/use-auth.d.ts
6
6
  /**
7
7
  * Authentication State returned by `useAuth` hook.
8
+ *
9
+ * @category Types
8
10
  */
9
- interface AuthState {
11
+ interface AuthenticationState {
10
12
  /**
11
13
  * Flag indicating if the authentication state is still loading.
12
14
  */
@@ -31,32 +33,33 @@ interface AuthState {
31
33
  }
32
34
  /**
33
35
  *
34
- * Hook for getting the user's profile on client components
35
- *
36
- * @returns Authentication State
36
+ * `useAuth()` is a client-side hook that provides access to the current authentication state.
37
37
  *
38
- * @example App Router
38
+ * It can only be used inside **Client Components**.
39
39
  *
40
- * ```tsx
40
+ * @example Basic Usage
41
+ * ```tsx title="Basic Usage"
41
42
  * "use client";
42
43
  *
43
44
  * import { useAuth } from "@monocloud/auth-nextjs/client";
44
45
  *
45
46
  * export default function Home() {
46
- * const { user } = useAuth();
47
+ * const { user, isAuthenticated } = useAuth();
48
+ *
49
+ * if (!isAuthenticated) {
50
+ * return <>Not signed in</>;
51
+ * }
47
52
  *
48
53
  * return <>User Id: {user?.sub}</>;
49
54
  * }
50
55
  * ```
51
56
  *
52
- * @example App Router - Refetch user from Userinfo endpoint
53
- *
54
- * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.
55
- * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`
57
+ * @example Refetch user
56
58
  *
57
- * **Note⚠️: You need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for force refresh to work**
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.
58
61
  *
59
- * ```tsx
62
+ * ```tsx title="Refetch User"
60
63
  * "use client";
61
64
  *
62
65
  * import { useAuth } from "@monocloud/auth-nextjs/client";
@@ -66,67 +69,38 @@ interface AuthState {
66
69
  *
67
70
  * return (
68
71
  * <>
69
- * <pre>{JSON.stringify(user)}</pre>
70
- * <button onClick={() => refetch(true)}>Refresh</button>
72
+ * <pre>{JSON.stringify(user, null, 2)}</pre>
73
+ * <button onClick={() => refetch(true)}>Refresh Profile</button>
71
74
  * </>
72
75
  * );
73
76
  * }
74
77
  * ```
75
78
  *
76
- * @example Pages Router
77
- *
78
- * ```tsx
79
- * import { useAuth } from "@monocloud/auth-nextjs/client";
80
- *
81
- * export default function Home() {
82
- * const { user } = useAuth();
83
- *
84
- * return <>User Id: {user?.sub}</>;
85
- * }
86
- * ```
87
- *
88
- * @example Pages Router - Refetch user from Userinfo endpoint
89
- *
90
- * Calling `refetch(true)` will force refresh the user's profile from the userinfo endpoint.
91
- * If you do not intent to refersh from your tenants userinfo endpoint, use just `refetch()`
92
- *
93
- * **Note⚠️: You need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for force refresh to work**
94
- *
95
- * ```tsx
96
- * import { useAuth } from "@monocloud/auth-nextjs/client";
97
- *
98
- * export default function Home() {
99
- * const { user, refetch } = useAuth();
100
- *
101
- * return (
102
- * <>
103
- * <pre>{JSON.stringify(user)}</pre>
104
- * <button onClick={() => refetch(true)}>Refresh</button>
105
- * </>
106
- * );
107
- * }
108
- * ```
79
+ * @returns
109
80
  *
81
+ * @category Hooks
110
82
  */
111
- declare const useAuth: () => AuthState;
83
+ declare const useAuth: () => AuthenticationState;
112
84
  //#endregion
113
- //#region src/client/protect.d.ts
85
+ //#region src/client/protect-client-page.d.ts
114
86
  /**
115
87
  * Options for configuring page protection.
88
+ *
89
+ * @category Types
116
90
  */
117
- type ProtectPageOptions = {
91
+ interface ProtectClientPageOptions extends GroupOptions {
118
92
  /**
119
- *The url where the user will be redirected to after sign in
93
+ * The URL where the user will be redirected to after sign in.
120
94
  */
121
95
  returnUrl?: string;
122
96
  /**
123
97
  * A custom react element to render when the user is not authenticated.
124
98
  */
125
- fallback?: (user?: MonoCloudUser) => JSX.Element;
99
+ onAccessDenied?: () => React.ReactNode;
126
100
  /**
127
101
  * A custom react element to render when the user is authenticated but does not belong to the required groups.
128
102
  */
129
- groupFallback?: (user: MonoCloudUser) => JSX.Element;
103
+ onGroupAccessDenied?: (user: MonoCloudUser) => React.ReactNode;
130
104
  /**
131
105
  * Authorization parameters to be used during authentication.
132
106
  */
@@ -138,110 +112,91 @@ type ProtectPageOptions = {
138
112
  * @param error - The error object.
139
113
  * @returns JSX element to handle the error.
140
114
  */
141
- onError?: (error: Error) => JSX.Element;
142
- } & GroupOptions;
115
+ onError?: (error: Error) => React.ReactNode;
116
+ }
143
117
  /**
144
- * Function to protect a client rendered page component.
145
- * Ensures that only authenticated users can access the component.
146
- *
147
- * **Note⚠️: Since `window.location` is set as `returnUrl` query param by default, you need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for returning to the same page.**
118
+ * `protectClientPage()` wraps a **client-rendered page component** and ensures that only authenticated users can access it.
148
119
  *
149
- * @param Component - The component to protect.
150
- * @param options - The options.
120
+ * If the user is authenticated, the wrapped component receives a `user` prop.
151
121
  *
152
- * @returns Protected client rendered page component.
122
+ * > This function runs on the client and controls rendering only.
123
+ * > To enforce access before rendering (server-side), use the server {@link MonoCloudNextClient.protectPage | protectPage()} method on {@link MonoCloudNextClient}.
153
124
  *
154
- * @example App Router
125
+ * @example Basic Usage
155
126
  *
156
- * ```tsx
127
+ * ```tsx title="Basic Usage"
157
128
  * "use client";
158
129
  *
159
- * import { protectPage } from "@monocloud/auth-nextjs/client";
130
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
160
131
  *
161
- * export default protectPage(function Home() {
162
- * return <>You are signed in</>;
132
+ * export default protectClientPage(function Home({ user }) {
133
+ * return <>Signed in as {user.email}</>;
163
134
  * });
164
135
  * ```
165
136
  *
166
- * @example App Router with options
137
+ * @example With Options
167
138
  *
168
- * See {@link ProtectPageOptions} for more options.
169
- *
170
- * ```tsx
139
+ * ```tsx title="With Options"
171
140
  * "use client";
172
141
  *
173
- * import { protectPage } from "@monocloud/auth-nextjs/client";
142
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
174
143
  *
175
- * export default protectPage(
176
- * function Home() {
177
- * return <>You are signed in</>;
144
+ * export default protectClientPage(
145
+ * function Home({ user }) {
146
+ * return <>Signed in as {user.email}</>;
178
147
  * },
179
- * { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
148
+ * {
149
+ * returnUrl: "/dashboard",
150
+ * authParams: { loginHint: "user@example.com" }
151
+ * }
180
152
  * );
181
153
  * ```
182
- * @example Custom Fallback
183
154
  *
184
- * ```tsx
155
+ * @example Custom access denied UI
156
+ *
157
+ * ```tsx title="Custom access denied UI"
185
158
  * "use client";
186
159
  *
187
- * import { protectPage } from "@monocloud/auth-nextjs/client";
160
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
188
161
  *
189
- * export default protectPage(
190
- * function Home() {
191
- * return <>You are signed in</>;
162
+ * export default protectClientPage(
163
+ * function Home({ user }) {
164
+ * return <>Signed in as {user.email}</>;
192
165
  * },
193
166
  * {
194
- * fallback: () => <div>Please sign in to continue</div>
167
+ * onAccessDenied: () => <div>Please sign in to continue</div>
195
168
  * }
196
169
  * );
197
170
  * ```
198
171
  *
199
- * @example Group Protection with Group Fallback
172
+ * @example Group protection
200
173
  *
201
- * ```tsx
174
+ * ```tsx title="Group protection"
202
175
  * "use client";
203
176
  *
204
- * import { protectPage } from "@monocloud/auth-nextjs/client";
177
+ * import { protectClientPage } from "@monocloud/auth-nextjs/client";
205
178
  *
206
- * export default protectPage(
207
- * function Home() {
208
- * return <>Welcome Admin</>;
179
+ * export default protectClientPage(
180
+ * function Home({ user }) {
181
+ * return <>Welcome Admin {user.email}</>;
209
182
  * },
210
183
  * {
211
184
  * groups: ["admin"],
212
- * groupFallback: (user) => <div>User {user.email} is not an admin</div>
185
+ * onGroupAccessDenied: (user) => <div>User {user.email} is not an admin</div>
213
186
  * }
214
187
  * );
215
188
  * ```
216
189
  *
217
- * @example Pages Router
218
- *
219
- * ```tsx
220
- * import { protectPage } from "@monocloud/auth-nextjs/client";
221
- *
222
- * export default protectPage(function Home() {
223
- * return <>You are signed in</>;
224
- * });
225
- * ```
190
+ * @param Component - The page component to protect
191
+ * @param options - Optional configuration
192
+ * @returns A protected React component.
226
193
  *
227
- * @example Pages Router with options
194
+ * @category Functions
228
195
  *
229
- * See {@link ProtectPageOptions} for more options.
230
- *
231
- * ```tsx
232
- * import { protectPage } from "@monocloud/auth-nextjs/client";
233
- *
234
- * export default protectPage(
235
- * function Home() {
236
- * return <>You are signed in</>;
237
- * },
238
- * { returnUrl: "/dashboard", authParams: { loginHint: "username" } }
239
- * );
240
- * ```
241
196
  */
242
- declare const protectPage: <P extends object>(Component: ComponentType<P & {
197
+ declare const protectClientPage: <P extends object>(Component: ComponentType<P & {
243
198
  user: MonoCloudUser;
244
- }>, options?: ProtectPageOptions) => React.FC<P>;
199
+ }>, options?: ProtectClientPageOptions) => React.FC<P>;
245
200
  //#endregion
246
- export { type AuthState, type ProtectPageOptions, protectPage, useAuth };
201
+ export { type AuthenticationState, type ProtectClientPageOptions, protectClientPage, useAuth };
247
202
  //# sourceMappingURL=index.d.mts.map
@@ -1,3 +1,3 @@
1
- import { r as useAuth, t as protectPage } from "../client-D-3RMRNY.mjs";
1
+ import { r as useAuth, t as protectClientPage } from "../protect-client-page-BFlGkK8F.mjs";
2
2
 
3
- export { protectPage, useAuth };
3
+ export { protectClientPage, useAuth };
@@ -1,22 +1,22 @@
1
- const require_chunk = require('../../chunk-CbDLau6x.cjs');
2
- const require_client = require('../../client-xfBYYato.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../../chunk-C0xms8kb.cjs');
3
+ const require_protect_client_page = require('../../protect-client-page-B1fOU4Zl.cjs');
4
+ require('../../client/index.cjs');
3
5
  let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
4
6
  let react = require("react");
5
7
  react = require_chunk.__toESM(react);
6
8
 
7
9
  //#region src/components/client/redirect-to-signin.tsx
8
10
  /**
9
- * A client side component that will redirect users to the sign in page.
11
+ * `<RedirectToSignIn>` is a **client-side component** that immediately redirects the user to the MonoCloud sign-in page when it is rendered.
10
12
  *
11
- * **Note⚠️: Since `window.location` is set as `returnUrl` query param by default, you need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for returning to the same page.**
13
+ * It does not render any UI.
12
14
  *
13
- * @param props - The props for customizing RedirectToSignIn
15
+ * > This component must be used inside a Client Component (`"use client"`).
14
16
  *
15
- * @returns
16
- *
17
- * @example App Router
17
+ * @example Basic Usage
18
18
  *
19
- * ```tsx
19
+ * ```tsx title="Basic Usage"
20
20
  * "use client";
21
21
  *
22
22
  * import { useAuth } from "@monocloud/auth-nextjs/client";
@@ -33,11 +33,11 @@ react = require_chunk.__toESM(react);
33
33
  * }
34
34
  * ```
35
35
  *
36
- * @example App Router with options
36
+ * @example With Options
37
37
  *
38
- * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.
38
+ * You can customize the authorization request by passing in props.
39
39
  *
40
- * ```tsx
40
+ * ```tsx title="With options"
41
41
  * "use client";
42
42
  *
43
43
  * import { useAuth } from "@monocloud/auth-nextjs/client";
@@ -47,52 +47,26 @@ react = require_chunk.__toESM(react);
47
47
  * const { isLoading, isAuthenticated } = useAuth();
48
48
  *
49
49
  * if (!isLoading && !isAuthenticated) {
50
- * return <RedirectToSignIn returnUrl="/dashboard" loginHint="username" />;
51
- * }
52
- *
53
- * return <>You are signed in</>;
54
- * }
55
- * ```
56
- *
57
- * @example Pages Router
58
- *
59
- * ```tsx
60
- * import { useAuth } from "@monocloud/auth-nextjs/client";
61
- * import { RedirectToSignIn } from "@monocloud/auth-nextjs/components/client";
62
- *
63
- * export default function Home() {
64
- * const { isLoading, isAuthenticated } = useAuth();
65
- *
66
- * if (!isLoading && !isAuthenticated) {
67
- * return <RedirectToSignIn />;
50
+ * return (
51
+ * <RedirectToSignIn
52
+ * returnUrl="/dashboard"
53
+ * loginHint="user@example.com"
54
+ * />
55
+ * );
68
56
  * }
69
57
  *
70
58
  * return <>You are signed in</>;
71
59
  * }
72
60
  * ```
73
61
  *
74
- * @example Pages Router with options
75
- *
76
- * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.
77
- *
78
- * ```tsx
79
- * import { useAuth } from "@monocloud/auth-nextjs/client";
80
- * import { RedirectToSignIn } from "@monocloud/auth-nextjs/components/client";
81
- *
82
- * export default function Home() {
83
- * const { isLoading, isAuthenticated } = useAuth();
84
- *
85
- * if (!isLoading && !isAuthenticated) {
86
- * return <RedirectToSignIn returnUrl="/dashboard" loginHint="username" />;
87
- * }
62
+ * @param props - The props for customizing RedirectToSignIn.
63
+ * @returns
88
64
  *
89
- * return <>You are signed in</>;
90
- * }
91
- * ```
65
+ * @category Components
92
66
  */
93
67
  const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
94
68
  (0, react.useEffect)(() => {
95
- require_client.redirectToSignIn({
69
+ require_protect_client_page.redirectToSignIn({
96
70
  returnUrl,
97
71
  ...authParams
98
72
  });
@@ -103,19 +77,14 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
103
77
  //#endregion
104
78
  //#region src/components/client/protected.tsx
105
79
  /**
106
- * A wrapper component that conditionally renders its children based on the user's authentication
107
- * status and group membership.
108
- *
109
- * **Note⚠️: The component is hidden from view. The data is present in the browser. Use server side `protectPage()` for protecting components before that data is sent to the client.**
80
+ * `<Protected>` conditionally renders its children based on the users authentication state and (optionally) group membership.
110
81
  *
111
- * @param props - Props for customizing the Protected component.
82
+ * > `<Protected>` runs on the client and only affects what is rendered. It does **not** prevent data from being sent to the browser.
83
+ * > 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()}.
112
84
  *
113
- * @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,
114
- * or `null` while loading.
85
+ * @example Basic Usage
115
86
  *
116
- * @example App Router
117
- *
118
- * ```tsx
87
+ * ```tsx title="Basic Usage"
119
88
  * "use client";
120
89
  *
121
90
  * import { Protected } from "@monocloud/auth-nextjs/components/client";
@@ -123,17 +92,15 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
123
92
  * export default function Home() {
124
93
  * return (
125
94
  * <Protected fallback={<>Sign in to view the message.</>}>
126
- * <>You are breathtaking</>
95
+ * <>This is the protected content.</>
127
96
  * </Protected>
128
97
  * );
129
98
  * }
130
99
  * ```
131
100
  *
132
- * @example App Router with group options
133
- *
134
- * See {@link ProtectedComponentProps}.
101
+ * @example With Groups
135
102
  *
136
- * ```tsx
103
+ * ```tsx title="With Groups"
137
104
  * "use client";
138
105
  *
139
106
  * import { Protected } from "@monocloud/auth-nextjs/components/client";
@@ -141,8 +108,8 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
141
108
  * export default function Home() {
142
109
  * return (
143
110
  * <Protected
144
- * groupFallback={<>Only admins are allowed.</>}
145
111
  * groups={["admin"]}
112
+ * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access admin content.</>}
146
113
  * >
147
114
  * <>Signed in as admin</>
148
115
  * </Protected>
@@ -150,48 +117,39 @@ const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
150
117
  * }
151
118
  * ```
152
119
  *
153
- * @example Pages Router
154
- *
155
- * ```tsx
156
- * import { Protected } from "@monocloud/auth-nextjs/components/client";
120
+ * @example Requiring all groups
157
121
  *
158
- * export default function Home() {
159
- * return (
160
- * <Protected fallback={<>Sign in to view the message.</>}>
161
- * <>You are breathtaking</>
162
- * </Protected>
163
- * );
164
- * }
165
- * ```
166
- *
167
- * @example Pages Router with group options
168
- *
169
- * See {@link ProtectedComponentProps}.
122
+ * ```tsx title="Requiring all groups"
123
+ * "use client";
170
124
  *
171
- * ```tsx
172
125
  * import { Protected } from "@monocloud/auth-nextjs/components/client";
173
126
  *
174
127
  * export default function Home() {
175
128
  * return (
176
129
  * <Protected
177
- * groupFallback={<>Only admins are allowed.</>}
178
- * groups={["admin"]}
130
+ * groups={["admin", "billing"]}
131
+ * matchAllGroups
132
+ * onGroupAccessDenied={(user) => <>User {user.email} is not allowed to access billing content.</>}
179
133
  * >
180
- * <>Signed in as admin</>
134
+ * <>Sensitive settings</>
181
135
  * </Protected>
182
136
  * );
183
137
  * }
184
138
  * ```
185
139
  *
140
+ * @param props - Props for customizing the Protected component.
141
+ * @returns The children if authorized, the `fallback` or `onGroupAccessDenied` content if unauthenticated or unauthorized, or `null` while loading.
142
+ *
143
+ * @category Components
186
144
  */
187
- const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, fallback = null, groupFallback = null }) => {
188
- const { isLoading, error, isAuthenticated, user } = require_client.useAuth();
145
+ const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, fallback = null, onGroupAccessDenied = () => /* @__PURE__ */ react.default.createElement(react.default.Fragment, null) }) => {
146
+ const { isLoading, error, isAuthenticated, user } = require_protect_client_page.useAuth();
189
147
  if (isLoading) return null;
190
148
  if (error || !isAuthenticated || !user) {
191
- if (fallback) return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, fallback);
149
+ if (fallback) return fallback;
192
150
  return null;
193
151
  }
194
- return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, !groups || (0, _monocloud_auth_node_core_utils.isUserInGroup)(user, groups, groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, matchAllGroups) ? children : groupFallback);
152
+ 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));
195
153
  };
196
154
 
197
155
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useAuth"],"sources":["../../../src/components/client/redirect-to-signin.tsx","../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect';\nimport { ExtraAuthParams } from '../../types';\n\n/**\n * Props for the `<RedirectToSignIn />` Component\n */\nexport interface RedirectToSignInProps extends ExtraAuthParams {\n /**\n * The url where the user will be redirected to after sign in.\n */\n returnUrl?: string;\n}\n\n/**\n * A client side component that will redirect users to the sign in page.\n *\n * **Note⚠️: Since `window.location` is set as `returnUrl` query param by default, you need to set the env `MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES=true` or `allowQueryParamOverrides` should be `true` in the client initialization for returning to the same page.**\n *\n * @param props - The props for customizing RedirectToSignIn\n *\n * @returns\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example App Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n *\n * @example Pages Router with options\n *\n * You can customize the authorization request by passing in props. See {@link RedirectToSignInProps}.\n *\n * ```tsx\n * import { useAuth } from \"@monocloud/auth-nextjs/client\";\n * import { RedirectToSignIn } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * const { isLoading, isAuthenticated } = useAuth();\n *\n * if (!isLoading && !isAuthenticated) {\n * return <RedirectToSignIn returnUrl=\"/dashboard\" loginHint=\"username\" />;\n * }\n *\n * return <>You are signed in</>;\n * }\n * ```\n */\nexport const RedirectToSignIn = ({\n returnUrl,\n ...authParams\n}: RedirectToSignInProps): null => {\n useEffect(() => {\n redirectToSignIn({ returnUrl, ...authParams });\n }, [authParams, returnUrl]);\n return null;\n};\n","import { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport React, { JSX } from 'react';\nimport { useAuth } from '../../client';\n\nexport interface ProtectedComponentProps {\n /**\n * Components that should be rendered if the user is authenticated.\n */\n children: React.ReactNode;\n\n /**\n * A list of group names or IDs to which the user must belong to. The user should belong to atleast one of the specified groups.\n */\n groups?: string[];\n\n /**\n * Name of the claim of user's groups. default: `groups`.\n */\n groupsClaim?: string;\n\n /**\n * Flag indicating if all groups specified should be present in the users profile. default: false.\n */\n matchAllGroups?: boolean;\n\n /**\n * A fallback component that should render if the user is not authenticated.\n */\n fallback?: React.ReactNode;\n\n /**\n * A fallback component that should render if the user is authenticated but does not belong to the required groups.\n */\n groupFallback?: React.ReactNode;\n}\n\n/**\n * A wrapper component that conditionally renders its children based on the user's authentication\n * status and group membership.\n *\n * **Note⚠️: The component is hidden from view. The data is present in the browser. Use server side `protectPage()` for protecting components before that data is sent to the client.**\n *\n * @param props - Props for customizing the Protected component.\n *\n * @returns The children if authorized, the `fallback` or `groupFallback` content if unauthenticated or unauthorized,\n * or `null` while loading.\n *\n * @example App Router\n *\n * ```tsx\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected fallback={<>Sign in to view the message.</>}>\n * <>You are breathtaking</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example App Router with group options\n *\n * See {@link ProtectedComponentProps}.\n *\n * ```tsx\n * \"use client\";\n *\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groupFallback={<>Only admins are allowed.</>}\n * groups={[\"admin\"]}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Pages Router\n *\n * ```tsx\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected fallback={<>Sign in to view the message.</>}>\n * <>You are breathtaking</>\n * </Protected>\n * );\n * }\n * ```\n *\n * @example Pages Router with group options\n *\n * See {@link ProtectedComponentProps}.\n *\n * ```tsx\n * import { Protected } from \"@monocloud/auth-nextjs/components/client\";\n *\n * export default function Home() {\n * return (\n * <Protected\n * groupFallback={<>Only admins are allowed.</>}\n * groups={[\"admin\"]}\n * >\n * <>Signed in as admin</>\n * </Protected>\n * );\n * }\n * ```\n *\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n fallback = null,\n groupFallback = null,\n}: ProtectedComponentProps): JSX.Element | null => {\n const { isLoading, error, isAuthenticated, user } = useAuth();\n\n if (isLoading) {\n return null;\n }\n\n if (error || !isAuthenticated || !user) {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n return null;\n }\n\n return (\n <>\n {!groups ||\n isUserInGroup(\n user,\n groups,\n groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n matchAllGroups\n )\n ? children\n : groupFallback}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;AACjC,4BAAgB;AACd,kCAAiB;GAAE;GAAW,GAAG;GAAY,CAAC;IAC7C,CAAC,YAAY,UAAU,CAAC;AAC3B,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACUT,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,WAAW,MACX,gBAAgB,WACiC;CACjD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAASA,wBAAS;AAE7D,KAAI,UACF,QAAO;AAGT,KAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;AACtC,MAAI,SACF,QAAO,0EAAG,SAAY;AAGxB,SAAO;;AAGT,QACE,0EACG,CAAC,6DAEA,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,eACD,GACG,WACA,cACH"}
1
+ {"version":3,"file":"index.cjs","names":["useAuth"],"sources":["../../../src/components/client/redirect-to-signin.tsx","../../../src/components/client/protected.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { redirectToSignIn } from '../../client/protect-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 * URL to redirect the user to after sign-in.\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","import { 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 users 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;AACjC,4BAAgB;AACd,+CAAiB;GAAE;GAAW,GAAG;GAAY,CAAC;IAC7C,CAAC,YAAY,UAAU,CAAC;AAC3B,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC6BT,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,WAAW,MACX,4BAA6C,yEAAK,OACG;CACrD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAASA,qCAAS;AAE7D,KAAI,UACF,QAAO;AAGT,KAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;AACtC,MAAI,SACF,QAAO;AAGT,SAAO;;AAGT,QACE,0EACG,CAAC,6DAEA,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,eACD,GACG,WACA,oBAAoB,KAAK,CAC5B"}