@monocloud/auth-nextjs 0.0.0-canary-20251223204300
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/LICENSE +21 -0
- package/README.md +152 -0
- package/client/package.json +5 -0
- package/components/client/package.json +5 -0
- package/components/package.json +5 -0
- package/dist/chunk-CbDLau6x.cjs +34 -0
- package/dist/client/index.cjs +4 -0
- package/dist/client/index.d.mts +76 -0
- package/dist/client/index.mjs +3 -0
- package/dist/client-0gaUvMR7.mjs +105 -0
- package/dist/client-0gaUvMR7.mjs.map +1 -0
- package/dist/client-BjnSJS59.cjs +125 -0
- package/dist/client-BjnSJS59.cjs.map +1 -0
- package/dist/components/client/index.cjs +47 -0
- package/dist/components/client/index.cjs.map +1 -0
- package/dist/components/client/index.d.mts +65 -0
- package/dist/components/client/index.mjs +44 -0
- package/dist/components/client/index.mjs.map +1 -0
- package/dist/components/index.cjs +83 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.mts +80 -0
- package/dist/components/index.mjs +79 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/index.cjs +745 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +127 -0
- package/dist/index.mjs +714 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types-BleaXQUP.d.mts +402 -0
- package/package.json +92 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 MonoCloud
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
**MonoCloud Auth Next.js SDK – secure authentication and session management for Next.js applications.**
|
|
6
|
+
|
|
7
|
+
[MonoCloud](https://www.monocloud.com?utm_source=github&utm_medium=auth_js) is a modern, developer-friendly Identity & Access Management platform.
|
|
8
|
+
|
|
9
|
+
This SDK is designed specifically for **Next.js**, providing first-class integration with both the **App Router** and **Pages Router**. It leverages **Next.js Middleware**, **Server Components**, and **Edge-compatible APIs** to deliver secure, server-side authentication with minimal configuration.
|
|
10
|
+
|
|
11
|
+
## 📘 Documentation
|
|
12
|
+
|
|
13
|
+
- **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)
|
|
14
|
+
- **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)
|
|
15
|
+
|
|
16
|
+
## Supported Platforms
|
|
17
|
+
|
|
18
|
+
- **Next.js ≥ 13.0.0** (App Router & Pages Router)
|
|
19
|
+
- **Node.js ≥ 16.0.0**
|
|
20
|
+
- **Edge Runtime** (where supported by Next.js)
|
|
21
|
+
|
|
22
|
+
## 🚀 Getting Started
|
|
23
|
+
|
|
24
|
+
### Requirements
|
|
25
|
+
|
|
26
|
+
- A **MonoCloud Tenant**
|
|
27
|
+
- A **Client ID** and **Client Secret**
|
|
28
|
+
- A **Random secret** (32+ characters) for encrypting session cookies
|
|
29
|
+
|
|
30
|
+
## 📦 Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @monocloud/auth-nextjs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Initialization
|
|
37
|
+
|
|
38
|
+
### Set up environment variables
|
|
39
|
+
|
|
40
|
+
Create a `.env.local` file in your project root. The SDK automatically reads variables prefixed with `MONOCLOUD_AUTH__`.
|
|
41
|
+
|
|
42
|
+
```env
|
|
43
|
+
MONOCLOUD_AUTH_TENANT_DOMAIN=https://<your-tenant-domain>
|
|
44
|
+
MONOCLOUD_AUTH_CLIENT_ID=<your-client-id>
|
|
45
|
+
MONOCLOUD_AUTH_CLIENT_SECRET=<your-client-secret>
|
|
46
|
+
MONOCLOUD_AUTH_COOKIE_SECRET=<long-random-string>
|
|
47
|
+
MONOCLOUD_AUTH_APP_URL=http://localhost:3000
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Generate a secure cookie secret:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
openssl rand -hex 32
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
⚠️ Security Note: Never commit secrets to source control. Always load them from environment variables.
|
|
57
|
+
|
|
58
|
+
### Create Next Client
|
|
59
|
+
|
|
60
|
+
Create a shared MonoCloud client instance (for example, `lib/monocloud.ts`) and reuse it throughout your application.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { MonoCloudNextClient } from '@monocloud/auth-nextjs';
|
|
64
|
+
|
|
65
|
+
// Environment variables are picked up automatically
|
|
66
|
+
export const monoCloud = new MonoCloudNextClient();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
⚠️ Security Note: Never commit your credentials to version control. Load them from environment variables.
|
|
70
|
+
|
|
71
|
+
### Add MonoCloud Middleware
|
|
72
|
+
|
|
73
|
+
Protect your application by registering the MonoCloud middleware. Authentication routes, redirects, and callbacks are handled automatically.
|
|
74
|
+
|
|
75
|
+
‼️ Important (Next.js v16+): Starting with Next.js 16, authentication middleware is implemented using a **proxy-based approach** rather than traditional middleware files. MonoCloud follows this recommended proxy pattern for handling authentication flows.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { monoCloud } from '<shared-instance>';
|
|
79
|
+
|
|
80
|
+
export default monoCloud.authMiddleware();
|
|
81
|
+
|
|
82
|
+
// Allow static files
|
|
83
|
+
export const config = {
|
|
84
|
+
matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Get Session (Server-side)
|
|
89
|
+
|
|
90
|
+
Retrieve the authenticated session in **Server Components, Route Handlers, or API routes**.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { monoCloud } from '<shared-instance>';
|
|
94
|
+
|
|
95
|
+
export default async function Page() {
|
|
96
|
+
const session = await monoCloud.getSession();
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div>
|
|
100
|
+
<h1>Welcome, {session?.user?.name}</h1>
|
|
101
|
+
<p>Email: {session?.user?.email}</p>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Get User (Client-side)
|
|
108
|
+
|
|
109
|
+
Access user data in **Client Components** using the provided hook.
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
'use client';
|
|
113
|
+
|
|
114
|
+
import { useAuth } from '@monocloud/auth-nextjs/client';
|
|
115
|
+
|
|
116
|
+
export default function Page() {
|
|
117
|
+
const { user } = useAuth();
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<div>
|
|
121
|
+
<h1>Welcome, {user?.name}</h1>
|
|
122
|
+
<p>Email: {user?.email}</p>
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
## When should I use `auth-nextjs`?
|
|
128
|
+
|
|
129
|
+
Use **`@monocloud/auth-nextjs`** if you are building a **Next.js application** and want a secure authentication solution with minimal configuration.
|
|
130
|
+
|
|
131
|
+
This package is a good fit if you:
|
|
132
|
+
|
|
133
|
+
- Are using **Next.js (App Router or Pages Router)**
|
|
134
|
+
- Want **secure, cookie-based sessions** managed for you
|
|
135
|
+
- Need authentication in **Server Components, Route Handlers, API routes, and middleware/proxy**
|
|
136
|
+
- Prefer **framework-native helpers and React hooks**
|
|
137
|
+
- Want an **opinionated, batteries-included** authentication experience
|
|
138
|
+
|
|
139
|
+
## 🤝 Contributing & Support
|
|
140
|
+
|
|
141
|
+
### Issues & Feedback
|
|
142
|
+
|
|
143
|
+
- Use **GitHub Issues** for bug reports and feature requests.
|
|
144
|
+
- For tenant or account-specific help, contact MonoCloud Support through your dashboard.
|
|
145
|
+
|
|
146
|
+
### Security
|
|
147
|
+
|
|
148
|
+
Do **not** report security issues publicly. Please follow the contact instructions at: [https://www.monocloud.com/contact](https://www.monocloud.com/contact?utm_source=github&utm_medium=auth_js)
|
|
149
|
+
|
|
150
|
+
## 📄 License
|
|
151
|
+
|
|
152
|
+
Licensed under the **MIT License**. See the included [`LICENSE`](https://github.com/monocloud/auth-js/blob/main/LICENSE) file.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
|
|
29
|
+
Object.defineProperty(exports, '__toESM', {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
get: function () {
|
|
32
|
+
return __toESM;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { i as ExtraAuthParams, o as GroupOptions } from "../types-BleaXQUP.mjs";
|
|
2
|
+
import { MonoCloudUser } from "@monocloud/auth-node-core";
|
|
3
|
+
import React, { ComponentType, JSX } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/client/use-auth.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Authentication State returned by `useAuth` hook.
|
|
8
|
+
*/
|
|
9
|
+
interface AuthState {
|
|
10
|
+
/**
|
|
11
|
+
* Flag indicating if the authentication state is still loading.
|
|
12
|
+
*/
|
|
13
|
+
isLoading: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Flag indicating if the user is authenticated.
|
|
16
|
+
*/
|
|
17
|
+
isAuthenticated: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Error encountered during authentication, if any.
|
|
20
|
+
*/
|
|
21
|
+
error?: Error;
|
|
22
|
+
/**
|
|
23
|
+
* The authenticated user's information, if available.
|
|
24
|
+
*/
|
|
25
|
+
user?: MonoCloudUser;
|
|
26
|
+
/**
|
|
27
|
+
* Function to refetch the authentication state.
|
|
28
|
+
*/
|
|
29
|
+
refetch?: () => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @returns Authentication State
|
|
33
|
+
*/
|
|
34
|
+
declare const useAuth: () => AuthState;
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/client/protect.d.ts
|
|
37
|
+
/**
|
|
38
|
+
* Options for configuring page protection.
|
|
39
|
+
*/
|
|
40
|
+
type ProtectPageOptions = {
|
|
41
|
+
/**
|
|
42
|
+
*The url where the user will be redirected to after sign in
|
|
43
|
+
*/
|
|
44
|
+
returnUrl?: string;
|
|
45
|
+
/**
|
|
46
|
+
* A custom react element to render when the user is not authenticated or is not a member of the specified groups.
|
|
47
|
+
*/
|
|
48
|
+
onAccessDenied?: (user?: MonoCloudUser) => JSX.Element;
|
|
49
|
+
/**
|
|
50
|
+
* Authorization parameters to be used during authentication.
|
|
51
|
+
*/
|
|
52
|
+
authParams?: ExtraAuthParams;
|
|
53
|
+
/**
|
|
54
|
+
* Callback function to handle errors.
|
|
55
|
+
* If not provided, errors will be thrown.
|
|
56
|
+
*
|
|
57
|
+
* @param error - The error object.
|
|
58
|
+
* @returns JSX element to handle the error.
|
|
59
|
+
*/
|
|
60
|
+
onError?: (error: Error) => JSX.Element;
|
|
61
|
+
} & GroupOptions;
|
|
62
|
+
/**
|
|
63
|
+
* Function to protect a client rendered page component.
|
|
64
|
+
* Ensures that only authenticated users can access the component.
|
|
65
|
+
*
|
|
66
|
+
* @param Component - The component to protect.
|
|
67
|
+
* @param options - The options.
|
|
68
|
+
*
|
|
69
|
+
* @returns Protected clinet rendered page component.
|
|
70
|
+
*/
|
|
71
|
+
declare const protectPage: <P extends object>(Component: ComponentType<P & {
|
|
72
|
+
user: MonoCloudUser;
|
|
73
|
+
}>, options?: ProtectPageOptions) => React.FC<P>;
|
|
74
|
+
//#endregion
|
|
75
|
+
export { type AuthState, type ProtectPageOptions, protectPage, useAuth };
|
|
76
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { isUserInGroup } from "@monocloud/auth-node-core/utils";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
import React, { useEffect } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/client/use-auth.tsx
|
|
6
|
+
/**
|
|
7
|
+
* @returns Authentication State
|
|
8
|
+
*/
|
|
9
|
+
const useAuth = () => {
|
|
10
|
+
const { data, error, isLoading, mutate } = useSWR(process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`, async (url) => {
|
|
11
|
+
const res = await fetch(url, { credentials: "include" });
|
|
12
|
+
if (res.status === 204) return;
|
|
13
|
+
if (res.ok) return res.json();
|
|
14
|
+
throw new Error("Failed to fetch user");
|
|
15
|
+
});
|
|
16
|
+
if (error) return {
|
|
17
|
+
user: void 0,
|
|
18
|
+
isLoading: false,
|
|
19
|
+
isAuthenticated: false,
|
|
20
|
+
error,
|
|
21
|
+
refetch: () => mutate()
|
|
22
|
+
};
|
|
23
|
+
if (data) return {
|
|
24
|
+
user: data,
|
|
25
|
+
isLoading,
|
|
26
|
+
isAuthenticated: !!data && Object.keys(data).length > 0,
|
|
27
|
+
error: void 0,
|
|
28
|
+
refetch: () => mutate()
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
user: void 0,
|
|
32
|
+
isLoading,
|
|
33
|
+
isAuthenticated: false,
|
|
34
|
+
error: void 0,
|
|
35
|
+
refetch: () => {}
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/client/protect.tsx
|
|
41
|
+
const redirectToSignIn = (options) => {
|
|
42
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
43
|
+
searchParams.set("return_url", options.returnUrl ?? window.location.toString());
|
|
44
|
+
if (options === null || options === void 0 ? void 0 : options.scopes) searchParams.set("scope", options.scopes);
|
|
45
|
+
if (options === null || options === void 0 ? void 0 : options.resource) searchParams.set("resource", options.resource);
|
|
46
|
+
if (options === null || options === void 0 ? void 0 : options.acrValues) searchParams.set("acr_values", options.acrValues.join(" "));
|
|
47
|
+
if (options === null || options === void 0 ? void 0 : options.display) searchParams.set("display", options.display);
|
|
48
|
+
if (options === null || options === void 0 ? void 0 : options.prompt) searchParams.set("prompt", options.prompt);
|
|
49
|
+
if (options === null || options === void 0 ? void 0 : options.authenticatorHint) searchParams.set("authenticator_hint", options.authenticatorHint);
|
|
50
|
+
if (options === null || options === void 0 ? void 0 : options.uiLocales) searchParams.set("ui_locales", options.uiLocales);
|
|
51
|
+
if (options === null || options === void 0 ? void 0 : options.maxAge) searchParams.set("max_age", options.maxAge.toString());
|
|
52
|
+
if (options === null || options === void 0 ? void 0 : options.loginHint) searchParams.set("login_hint", options.loginHint);
|
|
53
|
+
window.location.assign(`${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/signin`}?${searchParams.toString()}`);
|
|
54
|
+
};
|
|
55
|
+
const handlePageError = (error, options) => {
|
|
56
|
+
/* v8 ignore else -- @preserve */
|
|
57
|
+
if (options === null || options === void 0 ? void 0 : options.onError) return options.onError(error);
|
|
58
|
+
/* v8 ignore next -- @preserve */
|
|
59
|
+
throw error;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Function to protect a client rendered page component.
|
|
63
|
+
* Ensures that only authenticated users can access the component.
|
|
64
|
+
*
|
|
65
|
+
* @param Component - The component to protect.
|
|
66
|
+
* @param options - The options.
|
|
67
|
+
*
|
|
68
|
+
* @returns Protected clinet rendered page component.
|
|
69
|
+
*/
|
|
70
|
+
const protectPage = (Component, options) => {
|
|
71
|
+
return (props) => {
|
|
72
|
+
const { user, error, isLoading } = useAuth();
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!user && !isLoading && !error) {
|
|
75
|
+
if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
|
|
76
|
+
const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
|
|
77
|
+
redirectToSignIn({
|
|
78
|
+
returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
|
|
79
|
+
...authParams
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}, [
|
|
83
|
+
user,
|
|
84
|
+
isLoading,
|
|
85
|
+
error
|
|
86
|
+
]);
|
|
87
|
+
if (error) return handlePageError(error, options);
|
|
88
|
+
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.onAccessDenied)) return options.onAccessDenied();
|
|
89
|
+
if (user) {
|
|
90
|
+
if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(user, options.groups, options.groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
|
|
91
|
+
const { onAccessDenied = () => /* @__PURE__ */ React.createElement("div", null, "Access Denied") } = options;
|
|
92
|
+
return onAccessDenied(user);
|
|
93
|
+
}
|
|
94
|
+
return /* @__PURE__ */ React.createElement(Component, {
|
|
95
|
+
user,
|
|
96
|
+
...props
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
export { redirectToSignIn as n, useAuth as r, protectPage as t };
|
|
105
|
+
//# sourceMappingURL=client-0gaUvMR7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-0gaUvMR7.mjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport { MonoCloudUser } from '@monocloud/auth-node-core';\nimport useSWR from 'swr';\n\n/**\n * Authentication State returned by `useAuth` hook.\n */\nexport interface AuthState {\n /**\n * Flag indicating if the authentication state is still loading.\n */\n isLoading: boolean;\n /**\n * Flag indicating if the user is authenticated.\n */\n isAuthenticated: boolean;\n /**\n * Error encountered during authentication, if any.\n */\n error?: Error;\n /**\n * The authenticated user's information, if available.\n */\n user?: MonoCloudUser;\n /**\n * Function to refetch the authentication state.\n */\n refetch?: () => void;\n}\n\n/**\n * @returns Authentication State\n */\nexport const useAuth = (): AuthState => {\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\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 async (url: string) => {\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 if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch: () => mutate(),\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: () => mutate(),\n };\n }\n\n return {\n user: undefined,\n isLoading,\n isAuthenticated: false,\n error: undefined,\n /* v8 ignore next -- @preserve */\n refetch: (): void => {},\n };\n};\n","/* eslint-disable react/display-name */\n'use client';\n\nimport React, { ComponentType, JSX, useEffect } from 'react';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport { useAuth } from './use-auth';\nimport { ExtraAuthParams, GroupOptions } from '../types';\n\n/**\n * Options for configuring page protection.\n */\nexport type ProtectPageOptions = {\n /**\n *The url where the user will be redirected to after sign in\n */\n returnUrl?: string;\n\n /**\n * A custom react element to render when the user is not authenticated or is not a member of the specified groups.\n */\n onAccessDenied?: (user?: MonoCloudUser) => JSX.Element;\n\n /**\n * Authorization parameters to be used during authentication.\n */\n authParams?: ExtraAuthParams;\n\n /**\n * Callback function to handle errors.\n * If not provided, errors will be thrown.\n *\n * @param error - The error object.\n * @returns JSX element to handle the error.\n */\n onError?: (error: Error) => JSX.Element;\n} & GroupOptions;\n\nexport const redirectToSignIn = (\n options: { returnUrl?: string } & ExtraAuthParams\n): void => {\n const searchParams = new URLSearchParams(window.location.search);\n searchParams.set(\n 'return_url',\n options.returnUrl ?? window.location.toString()\n );\n\n if (options?.scopes) {\n searchParams.set('scope', options.scopes);\n }\n if (options?.resource) {\n searchParams.set('resource', options.resource);\n }\n\n if (options?.acrValues) {\n searchParams.set('acr_values', options.acrValues.join(' '));\n }\n\n if (options?.display) {\n searchParams.set('display', options.display);\n }\n\n if (options?.prompt) {\n searchParams.set('prompt', options.prompt);\n }\n\n if (options?.authenticatorHint) {\n searchParams.set('authenticator_hint', options.authenticatorHint);\n }\n\n if (options?.uiLocales) {\n searchParams.set('ui_locales', options.uiLocales);\n }\n\n if (options?.maxAge) {\n searchParams.set('max_age', options.maxAge.toString());\n }\n\n if (options?.loginHint) {\n searchParams.set('login_hint', options.loginHint);\n }\n\n window.location.assign(\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`}?${searchParams.toString()}`\n );\n};\n\nconst handlePageError = (\n error: Error,\n options?: ProtectPageOptions\n): JSX.Element => {\n /* v8 ignore else -- @preserve */\n if (options?.onError) {\n return options.onError(error);\n }\n\n /* v8 ignore next -- @preserve */\n throw error;\n};\n\n/**\n * Function to protect a client rendered page component.\n * Ensures that only authenticated users can access the component.\n *\n * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected clinet rendered page component.\n */\nexport const protectPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectPageOptions\n): React.FC<P> => {\n return props => {\n const { user, error, isLoading } = useAuth();\n\n useEffect(() => {\n if (!user && !isLoading && !error) {\n if (options?.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 { onAccessDenied = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return onAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;AAkCA,MAAa,gBAA2B;CACtC,MAAM,EAAE,MAAM,OAAO,WAAW,WAAW,OACzC,QAAQ,IAAI,4CAEV,GAAG,QAAQ,IAAI,0BAA0B,GAAG,qBAC9C,OAAO,QAAgB;EACrB,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,MAAI,IAAI,WAAW,IACjB;AAGF,MAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,QAAM,IAAI,MAAM,uBAAuB;GAE1C;AAED,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP,eAAe,QAAQ;EACxB;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP,eAAe,QAAQ;EACxB;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;AC3CH,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,YACgB;;AAEhB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;AAYR,MAAa,eACX,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,EAAE,uBAAoC,oCAAC,aAAI,gBAAmB,KAClE;AACF,WAAO,eAAe,KAAK;;AAG7B,UAAO,oCAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CbDLau6x.cjs');
|
|
2
|
+
let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
|
|
3
|
+
let swr = require("swr");
|
|
4
|
+
swr = require_chunk.__toESM(swr);
|
|
5
|
+
let react = require("react");
|
|
6
|
+
react = require_chunk.__toESM(react);
|
|
7
|
+
|
|
8
|
+
//#region src/client/use-auth.tsx
|
|
9
|
+
/**
|
|
10
|
+
* @returns Authentication State
|
|
11
|
+
*/
|
|
12
|
+
const useAuth = () => {
|
|
13
|
+
const { data, error, isLoading, mutate } = (0, swr.default)(process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`, async (url) => {
|
|
14
|
+
const res = await fetch(url, { credentials: "include" });
|
|
15
|
+
if (res.status === 204) return;
|
|
16
|
+
if (res.ok) return res.json();
|
|
17
|
+
throw new Error("Failed to fetch user");
|
|
18
|
+
});
|
|
19
|
+
if (error) return {
|
|
20
|
+
user: void 0,
|
|
21
|
+
isLoading: false,
|
|
22
|
+
isAuthenticated: false,
|
|
23
|
+
error,
|
|
24
|
+
refetch: () => mutate()
|
|
25
|
+
};
|
|
26
|
+
if (data) return {
|
|
27
|
+
user: data,
|
|
28
|
+
isLoading,
|
|
29
|
+
isAuthenticated: !!data && Object.keys(data).length > 0,
|
|
30
|
+
error: void 0,
|
|
31
|
+
refetch: () => mutate()
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
user: void 0,
|
|
35
|
+
isLoading,
|
|
36
|
+
isAuthenticated: false,
|
|
37
|
+
error: void 0,
|
|
38
|
+
refetch: () => {}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/client/protect.tsx
|
|
44
|
+
const redirectToSignIn = (options) => {
|
|
45
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
46
|
+
searchParams.set("return_url", options.returnUrl ?? window.location.toString());
|
|
47
|
+
if (options === null || options === void 0 ? void 0 : options.scopes) searchParams.set("scope", options.scopes);
|
|
48
|
+
if (options === null || options === void 0 ? void 0 : options.resource) searchParams.set("resource", options.resource);
|
|
49
|
+
if (options === null || options === void 0 ? void 0 : options.acrValues) searchParams.set("acr_values", options.acrValues.join(" "));
|
|
50
|
+
if (options === null || options === void 0 ? void 0 : options.display) searchParams.set("display", options.display);
|
|
51
|
+
if (options === null || options === void 0 ? void 0 : options.prompt) searchParams.set("prompt", options.prompt);
|
|
52
|
+
if (options === null || options === void 0 ? void 0 : options.authenticatorHint) searchParams.set("authenticator_hint", options.authenticatorHint);
|
|
53
|
+
if (options === null || options === void 0 ? void 0 : options.uiLocales) searchParams.set("ui_locales", options.uiLocales);
|
|
54
|
+
if (options === null || options === void 0 ? void 0 : options.maxAge) searchParams.set("max_age", options.maxAge.toString());
|
|
55
|
+
if (options === null || options === void 0 ? void 0 : options.loginHint) searchParams.set("login_hint", options.loginHint);
|
|
56
|
+
window.location.assign(`${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/signin`}?${searchParams.toString()}`);
|
|
57
|
+
};
|
|
58
|
+
const handlePageError = (error, options) => {
|
|
59
|
+
/* v8 ignore else -- @preserve */
|
|
60
|
+
if (options === null || options === void 0 ? void 0 : options.onError) return options.onError(error);
|
|
61
|
+
/* v8 ignore next -- @preserve */
|
|
62
|
+
throw error;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Function to protect a client rendered page component.
|
|
66
|
+
* Ensures that only authenticated users can access the component.
|
|
67
|
+
*
|
|
68
|
+
* @param Component - The component to protect.
|
|
69
|
+
* @param options - The options.
|
|
70
|
+
*
|
|
71
|
+
* @returns Protected clinet rendered page component.
|
|
72
|
+
*/
|
|
73
|
+
const protectPage = (Component, options) => {
|
|
74
|
+
return (props) => {
|
|
75
|
+
const { user, error, isLoading } = useAuth();
|
|
76
|
+
(0, react.useEffect)(() => {
|
|
77
|
+
if (!user && !isLoading && !error) {
|
|
78
|
+
if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
|
|
79
|
+
const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
|
|
80
|
+
redirectToSignIn({
|
|
81
|
+
returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
|
|
82
|
+
...authParams
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}, [
|
|
86
|
+
user,
|
|
87
|
+
isLoading,
|
|
88
|
+
error
|
|
89
|
+
]);
|
|
90
|
+
if (error) return handlePageError(error, options);
|
|
91
|
+
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.onAccessDenied)) return options.onAccessDenied();
|
|
92
|
+
if (user) {
|
|
93
|
+
if ((options === null || options === void 0 ? void 0 : options.groups) && !(0, _monocloud_auth_node_core_utils.isUserInGroup)(user, options.groups, options.groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
|
|
94
|
+
const { onAccessDenied = () => /* @__PURE__ */ react.default.createElement("div", null, "Access Denied") } = options;
|
|
95
|
+
return onAccessDenied(user);
|
|
96
|
+
}
|
|
97
|
+
return /* @__PURE__ */ react.default.createElement(Component, {
|
|
98
|
+
user,
|
|
99
|
+
...props
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
//#endregion
|
|
107
|
+
Object.defineProperty(exports, 'protectPage', {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
get: function () {
|
|
110
|
+
return protectPage;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(exports, 'redirectToSignIn', {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
get: function () {
|
|
116
|
+
return redirectToSignIn;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(exports, 'useAuth', {
|
|
120
|
+
enumerable: true,
|
|
121
|
+
get: function () {
|
|
122
|
+
return useAuth;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=client-BjnSJS59.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-BjnSJS59.cjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport { MonoCloudUser } from '@monocloud/auth-node-core';\nimport useSWR from 'swr';\n\n/**\n * Authentication State returned by `useAuth` hook.\n */\nexport interface AuthState {\n /**\n * Flag indicating if the authentication state is still loading.\n */\n isLoading: boolean;\n /**\n * Flag indicating if the user is authenticated.\n */\n isAuthenticated: boolean;\n /**\n * Error encountered during authentication, if any.\n */\n error?: Error;\n /**\n * The authenticated user's information, if available.\n */\n user?: MonoCloudUser;\n /**\n * Function to refetch the authentication state.\n */\n refetch?: () => void;\n}\n\n/**\n * @returns Authentication State\n */\nexport const useAuth = (): AuthState => {\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\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 async (url: string) => {\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 if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch: () => mutate(),\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: () => mutate(),\n };\n }\n\n return {\n user: undefined,\n isLoading,\n isAuthenticated: false,\n error: undefined,\n /* v8 ignore next -- @preserve */\n refetch: (): void => {},\n };\n};\n","/* eslint-disable react/display-name */\n'use client';\n\nimport React, { ComponentType, JSX, useEffect } from 'react';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport { useAuth } from './use-auth';\nimport { ExtraAuthParams, GroupOptions } from '../types';\n\n/**\n * Options for configuring page protection.\n */\nexport type ProtectPageOptions = {\n /**\n *The url where the user will be redirected to after sign in\n */\n returnUrl?: string;\n\n /**\n * A custom react element to render when the user is not authenticated or is not a member of the specified groups.\n */\n onAccessDenied?: (user?: MonoCloudUser) => JSX.Element;\n\n /**\n * Authorization parameters to be used during authentication.\n */\n authParams?: ExtraAuthParams;\n\n /**\n * Callback function to handle errors.\n * If not provided, errors will be thrown.\n *\n * @param error - The error object.\n * @returns JSX element to handle the error.\n */\n onError?: (error: Error) => JSX.Element;\n} & GroupOptions;\n\nexport const redirectToSignIn = (\n options: { returnUrl?: string } & ExtraAuthParams\n): void => {\n const searchParams = new URLSearchParams(window.location.search);\n searchParams.set(\n 'return_url',\n options.returnUrl ?? window.location.toString()\n );\n\n if (options?.scopes) {\n searchParams.set('scope', options.scopes);\n }\n if (options?.resource) {\n searchParams.set('resource', options.resource);\n }\n\n if (options?.acrValues) {\n searchParams.set('acr_values', options.acrValues.join(' '));\n }\n\n if (options?.display) {\n searchParams.set('display', options.display);\n }\n\n if (options?.prompt) {\n searchParams.set('prompt', options.prompt);\n }\n\n if (options?.authenticatorHint) {\n searchParams.set('authenticator_hint', options.authenticatorHint);\n }\n\n if (options?.uiLocales) {\n searchParams.set('ui_locales', options.uiLocales);\n }\n\n if (options?.maxAge) {\n searchParams.set('max_age', options.maxAge.toString());\n }\n\n if (options?.loginHint) {\n searchParams.set('login_hint', options.loginHint);\n }\n\n window.location.assign(\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`}?${searchParams.toString()}`\n );\n};\n\nconst handlePageError = (\n error: Error,\n options?: ProtectPageOptions\n): JSX.Element => {\n /* v8 ignore else -- @preserve */\n if (options?.onError) {\n return options.onError(error);\n }\n\n /* v8 ignore next -- @preserve */\n throw error;\n};\n\n/**\n * Function to protect a client rendered page component.\n * Ensures that only authenticated users can access the component.\n *\n * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected clinet rendered page component.\n */\nexport const protectPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectPageOptions\n): React.FC<P> => {\n return props => {\n const { user, error, isLoading } = useAuth();\n\n useEffect(() => {\n if (!user && !isLoading && !error) {\n if (options?.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 { onAccessDenied = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return onAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;;;;AAkCA,MAAa,gBAA2B;CACtC,MAAM,EAAE,MAAM,OAAO,WAAW,4BAC9B,QAAQ,IAAI,4CAEV,GAAG,QAAQ,IAAI,0BAA0B,GAAG,qBAC9C,OAAO,QAAgB;EACrB,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,MAAI,IAAI,WAAW,IACjB;AAGF,MAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,QAAM,IAAI,MAAM,uBAAuB;GAE1C;AAED,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP,eAAe,QAAQ;EACxB;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP,eAAe,QAAQ;EACxB;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;AC3CH,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,YACgB;;AAEhB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;AAYR,MAAa,eACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,SAAS;AAE5C,6BAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,oDACE,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EAAE,uBAAoC,4CAAC,aAAI,gBAAmB,KAClE;AACF,WAAO,eAAe,KAAK;;AAG7B,UAAO,4CAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const require_chunk = require('../../chunk-CbDLau6x.cjs');
|
|
2
|
+
const require_client = require('../../client-BjnSJS59.cjs');
|
|
3
|
+
let _monocloud_auth_node_core_utils = require("@monocloud/auth-node-core/utils");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
react = require_chunk.__toESM(react);
|
|
6
|
+
|
|
7
|
+
//#region src/components/client/redirect-to-signin.tsx
|
|
8
|
+
/**
|
|
9
|
+
* A client side component that will redirect users to the sign in page.
|
|
10
|
+
*
|
|
11
|
+
* @type RedirectToSignInProps
|
|
12
|
+
*/
|
|
13
|
+
const RedirectToSignIn = ({ returnUrl, ...authParams }) => {
|
|
14
|
+
(0, react.useEffect)(() => {
|
|
15
|
+
require_client.redirectToSignIn({
|
|
16
|
+
returnUrl,
|
|
17
|
+
...authParams
|
|
18
|
+
});
|
|
19
|
+
}, [authParams, returnUrl]);
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/components/client/protected.tsx
|
|
25
|
+
/**
|
|
26
|
+
* A wrapper component that conditionally renders its children based on the user's authentication
|
|
27
|
+
* status and group membership.
|
|
28
|
+
*
|
|
29
|
+
* @param props - The properties for the Protected component.
|
|
30
|
+
*
|
|
31
|
+
* @returns The children if authorized, the `onAccessDenied` content if unauthorized,
|
|
32
|
+
* or `null` while loading.
|
|
33
|
+
*/
|
|
34
|
+
const Protected = ({ children, groups, groupsClaim, matchAllGroups = false, onAccessDenied = null }) => {
|
|
35
|
+
const { isLoading, error, isAuthenticated, user } = require_client.useAuth();
|
|
36
|
+
if (isLoading) return null;
|
|
37
|
+
if (error || !isAuthenticated || !user) {
|
|
38
|
+
if (onAccessDenied) return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, onAccessDenied);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
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 : onAccessDenied);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
exports.Protected = Protected;
|
|
46
|
+
exports.RedirectToSignIn = RedirectToSignIn;
|
|
47
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +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 * @type RedirectToSignInProps\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 onAccessDenied?: 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 * @param props - The properties for the Protected component.\n *\n * @returns The children if authorized, the `onAccessDenied` content if unauthorized,\n * or `null` while loading.\n */\nexport const Protected = ({\n children,\n groups,\n groupsClaim,\n matchAllGroups = false,\n onAccessDenied = 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 (onAccessDenied) {\n return <>{onAccessDenied}</>;\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 : onAccessDenied}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAa,oBAAoB,EAC/B,WACA,GAAG,iBAC8B;AACjC,4BAAgB;AACd,kCAAiB;GAAE;GAAW,GAAG;GAAY,CAAC;IAC7C,CAAC,YAAY,UAAU,CAAC;AAC3B,QAAO;;;;;;;;;;;;;;ACYT,MAAa,aAAa,EACxB,UACA,QACA,aACA,iBAAiB,OACjB,iBAAiB,WACgC;CACjD,MAAM,EAAE,WAAW,OAAO,iBAAiB,SAASA,wBAAS;AAE7D,KAAI,UACF,QAAO;AAGT,KAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM;AACtC,MAAI,eACF,QAAO,0EAAG,eAAkB;AAG9B,SAAO;;AAGT,QACE,0EACG,CAAC,6DAEA,MACA,QACA,eAAe,QAAQ,IAAI,yCAC3B,eACD,GACG,WACA,eACH"}
|