@grasp-labs/ds-microfrontends-integration 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/groups/GroupsProvider.d.ts +62 -0
- package/dist/components/groups/RouteGuard.d.ts +31 -0
- package/dist/components/groups/index.d.ts +2 -0
- package/dist/components/index.d.ts +2 -1
- package/dist/dev/express-auth-middleware.js +21 -30
- package/dist/{index-DFqk0a9d.js → index-p4MWsN-O.js} +4048 -4050
- package/dist/{index.esm-BKoMny5G-DYIv1MUa.js → index.esm-BKoMny5G-BhFU8unB.js} +1 -1
- package/dist/index.js +28 -25
- package/dist/mf-common.js +3 -1
- package/dist/types/Groups.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Group } from '../../types';
|
|
3
|
+
export type GroupsContextValue = {
|
|
4
|
+
groups: Group[];
|
|
5
|
+
hasGroup: (groupNames: string | string[]) => boolean;
|
|
6
|
+
};
|
|
7
|
+
export type GroupsProviderProps = {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
groups: Group[];
|
|
10
|
+
/**
|
|
11
|
+
* Optional override for the hasGroup function.
|
|
12
|
+
* Useful for dev/standalone mode or testing scenarios.
|
|
13
|
+
* When provided, this function will be used instead of the default group checking logic.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* // Dev mode - all groups pass
|
|
18
|
+
* <GroupsProvider groups={[]} hasGroup={() => true}>
|
|
19
|
+
* <App />
|
|
20
|
+
* </GroupsProvider>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
hasGroup?: (groupNames: string | string[]) => boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Provides groups context to child components.
|
|
27
|
+
* App should fetch groups before mounting this provider.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* // Normal mode
|
|
32
|
+
* <GroupsProvider groups={groups}>
|
|
33
|
+
* <App />
|
|
34
|
+
* </GroupsProvider>
|
|
35
|
+
*
|
|
36
|
+
* // Dev/standalone mode - bypass all group checks
|
|
37
|
+
* <GroupsProvider groups={[]} hasGroup={() => true}>
|
|
38
|
+
* <App />
|
|
39
|
+
* </GroupsProvider>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const GroupsProvider: ({ children, groups, hasGroup: hasGroupOverride, }: GroupsProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
/**
|
|
44
|
+
* Hook to access groups context and group-checking utilities.
|
|
45
|
+
*
|
|
46
|
+
* @returns The groups context with group-checking methods.
|
|
47
|
+
* @throws Error if used outside of GroupsProvider.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const { groups, hasGroup } = useGroups();
|
|
52
|
+
*
|
|
53
|
+
* if (hasGroup('admin')) {
|
|
54
|
+
* // User has admin group
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* if (hasGroup(['admin', 'moderator'])) {
|
|
58
|
+
* // User has at least one of these groups
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare const useGroups: () => GroupsContextValue;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type RouteGuardProps = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
requiredGroups: string | string[];
|
|
5
|
+
fallback?: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* RouteGuard component that conditionally renders children based on user groups.
|
|
9
|
+
*
|
|
10
|
+
* @param requiredGroups - Single group name or array of group names. If array, user needs at least one group.
|
|
11
|
+
* @param fallback - Optional component to render when access is denied
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // User needs admin group
|
|
16
|
+
* <RouteGuard requiredGroups="admin">
|
|
17
|
+
* <AdminPanel />
|
|
18
|
+
* </RouteGuard>
|
|
19
|
+
*
|
|
20
|
+
* // User needs at least one of these groups
|
|
21
|
+
* <RouteGuard requiredGroups={['admin', 'moderator']}>
|
|
22
|
+
* <ModeratedContent />
|
|
23
|
+
* </RouteGuard>
|
|
24
|
+
*
|
|
25
|
+
* // With fallback
|
|
26
|
+
* <RouteGuard requiredGroups="admin" fallback={<AccessDenied />}>
|
|
27
|
+
* <AdminPanel />
|
|
28
|
+
* </RouteGuard>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare const RouteGuard: ({ children, requiredGroups, fallback, }: RouteGuardProps) => ReactNode;
|
|
@@ -142,32 +142,20 @@ function b(e) {
|
|
|
142
142
|
const o = (r) => r.startsWith("/") ? r : `/${r}`;
|
|
143
143
|
return {
|
|
144
144
|
loginPagePath: o(e.loginPagePath ?? "/__login"),
|
|
145
|
-
afterLoginRedirectPath: o(
|
|
146
|
-
e.afterLoginRedirectPath ?? process.env.VITE_BASE_PATH ?? "/"
|
|
147
|
-
),
|
|
145
|
+
afterLoginRedirectPath: o(e.afterLoginRedirectPath ?? process.env.VITE_BASE_PATH ?? "/"),
|
|
148
146
|
authServerLoginUrl: e.authServerLoginUrl ?? "https://auth-dev.grasp-daas.com/rest-auth/login/"
|
|
149
147
|
};
|
|
150
148
|
}
|
|
151
149
|
function d(e, o, r) {
|
|
152
|
-
return e.type("html").send(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
})
|
|
157
|
-
);
|
|
150
|
+
return e.type("html").send(m({
|
|
151
|
+
loginPath: o,
|
|
152
|
+
errorMessage: r
|
|
153
|
+
}));
|
|
158
154
|
}
|
|
159
|
-
function k({
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
" 🔐 Dev Auth Middleware Active",
|
|
164
|
-
"",
|
|
165
|
-
` Login: ${p}`,
|
|
166
|
-
"",
|
|
167
|
-
` ${n}Tip: Set DEV_AUTH_TOKEN env var to skip login${t}`,
|
|
168
|
-
"",
|
|
169
|
-
c
|
|
170
|
-
];
|
|
155
|
+
function k({
|
|
156
|
+
loginPagePath: e
|
|
157
|
+
}) {
|
|
158
|
+
const o = "\x1B[33m", r = "\x1B[34m", n = "\x1B[2m", t = "\x1B[0m", a = "─".repeat(50), s = `${o}┌${a}┐${t}`, c = `${o}└${a}┘${t}`, i = process.env.HOST ?? "localhost", l = process.env.PORT ?? "XXXX", p = `${r}http://${i}:${l}${e}${t}`, h = [s, "", " 🔐 Dev Auth Middleware Active", "", ` Login: ${p}`, "", ` ${n}Tip: Set DEV_AUTH_TOKEN env var to skip login${t}`, "", c];
|
|
171
159
|
console.log(h.join(`
|
|
172
160
|
`));
|
|
173
161
|
}
|
|
@@ -181,11 +169,16 @@ async function y({
|
|
|
181
169
|
} catch (i) {
|
|
182
170
|
return a(i);
|
|
183
171
|
}
|
|
184
|
-
const {
|
|
172
|
+
const {
|
|
173
|
+
email: s,
|
|
174
|
+
password: c
|
|
175
|
+
} = n.body ?? {};
|
|
185
176
|
if (!s || !c)
|
|
186
177
|
return d(t, o, "Email and password are required.");
|
|
187
178
|
try {
|
|
188
|
-
const {
|
|
179
|
+
const {
|
|
180
|
+
access_token: i
|
|
181
|
+
} = await x({
|
|
189
182
|
email: s,
|
|
190
183
|
password: c,
|
|
191
184
|
authServerLoginUrl: e
|
|
@@ -198,7 +191,9 @@ async function y({
|
|
|
198
191
|
}
|
|
199
192
|
const w = v();
|
|
200
193
|
function v() {
|
|
201
|
-
const e = g({
|
|
194
|
+
const e = g({
|
|
195
|
+
extended: !0
|
|
196
|
+
});
|
|
202
197
|
return (o, r) => new Promise((n, t) => {
|
|
203
198
|
e(o, r, (a) => {
|
|
204
199
|
if (a) {
|
|
@@ -226,14 +221,10 @@ async function x({
|
|
|
226
221
|
})
|
|
227
222
|
});
|
|
228
223
|
if (!n.ok)
|
|
229
|
-
throw new Error(
|
|
230
|
-
`Authentication failed with status ${n.status} and response: ${await n.text()}`
|
|
231
|
-
);
|
|
224
|
+
throw new Error(`Authentication failed with status ${n.status} and response: ${await n.text()}`);
|
|
232
225
|
const t = await n.json();
|
|
233
226
|
if (!("access_token" in t && "refresh_token" in t))
|
|
234
|
-
throw new Error(
|
|
235
|
-
`Authentication response is missing access_token or refresh_token: ${JSON.stringify(t, null, 2)}`
|
|
236
|
-
);
|
|
227
|
+
throw new Error(`Authentication response is missing access_token or refresh_token: ${JSON.stringify(t, null, 2)}`);
|
|
237
228
|
return t;
|
|
238
229
|
}
|
|
239
230
|
const u = {
|