@firecms/user_management 3.0.0-beta.10 → 3.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/useBuildUserManagement.d.ts +5 -3
- package/dist/index.es.js +1841 -1162
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1839 -1161
- package/dist/index.umd.js.map +1 -1
- package/dist/types/user_management.d.ts +1 -5
- package/dist/useUserManagementPlugin.d.ts +5 -5
- package/dist/utils/permissions.d.ts +2 -2
- package/package.json +11 -9
- package/src/components/roles/RolesDetailsForm.tsx +13 -9
- package/src/components/users/UserDetailsForm.tsx +7 -10
- package/src/components/users/UsersTable.tsx +0 -2
- package/src/hooks/useBuildUserManagement.tsx +77 -42
- package/src/types/user_management.tsx +2 -6
- package/src/useUserManagementPlugin.tsx +6 -6
- package/src/utils/permissions.ts +2 -2
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Authenticator, PermissionsBuilder, Role, User } from "@firecms/core";
|
2
2
|
export type UserManagement<USER extends User = User> = {
|
3
|
+
authenticator?: Authenticator<USER>;
|
3
4
|
loading: boolean;
|
4
5
|
users: USER[];
|
5
6
|
saveUser: (user: USER) => Promise<USER>;
|
@@ -37,11 +38,6 @@ export type UserManagement<USER extends User = User> = {
|
|
37
38
|
* @param user
|
38
39
|
*/
|
39
40
|
defineRolesFor: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
|
40
|
-
/**
|
41
|
-
* You can build an authenticator callback from the current configuration of the user management.
|
42
|
-
* It will only allow access to users with the required roles.
|
43
|
-
*/
|
44
|
-
authenticator?: Authenticator;
|
45
41
|
rolesError?: Error;
|
46
42
|
usersError?: Error;
|
47
43
|
};
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import { FireCMSPlugin } from "@firecms/core";
|
2
|
-
import {
|
3
|
-
export declare function useUserManagementPlugin({ userManagement }: {
|
4
|
-
userManagement: UserManagement
|
1
|
+
import { FireCMSPlugin, User } from "@firecms/core";
|
2
|
+
import { UserManagement } from "./types";
|
3
|
+
export declare function useUserManagementPlugin<USER extends User = any>({ userManagement }: {
|
4
|
+
userManagement: UserManagement<USER>;
|
5
5
|
}): FireCMSPlugin;
|
6
6
|
export declare function IntroWidget({ noUsers, noRoles, userManagement }: {
|
7
7
|
noUsers: boolean;
|
8
8
|
noRoles: boolean;
|
9
|
-
userManagement: UserManagement<
|
9
|
+
userManagement: UserManagement<any>;
|
10
10
|
}): import("react/jsx-runtime").JSX.Element;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { EntityCollection, Permissions, Role, User } from "@firecms/core";
|
2
2
|
export declare const RESERVED_GROUPS: string[];
|
3
|
-
export declare function resolveUserRolePermissions<
|
3
|
+
export declare function resolveUserRolePermissions<USER extends User>({ collection, user }: {
|
4
4
|
collection: EntityCollection<any>;
|
5
|
-
user:
|
5
|
+
user: USER | null;
|
6
6
|
}): Permissions;
|
7
7
|
export declare function getUserRoles(roles: Role[], fireCMSUser: User): Role[] | undefined;
|
8
8
|
export declare const areRolesEqual: (rolesA: Role[], rolesB: Role[]) => boolean;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@firecms/user_management",
|
3
3
|
"type": "module",
|
4
|
-
"version": "3.0.0-beta.
|
4
|
+
"version": "3.0.0-beta.11",
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
7
7
|
},
|
@@ -29,9 +29,9 @@
|
|
29
29
|
"types": "dist/index.d.ts",
|
30
30
|
"source": "src/index.ts",
|
31
31
|
"dependencies": {
|
32
|
-
"@firecms/core": "^3.0.0-beta.
|
33
|
-
"@firecms/formex": "^3.0.0-beta.
|
34
|
-
"@firecms/ui": "^3.0.0-beta.
|
32
|
+
"@firecms/core": "^3.0.0-beta.11",
|
33
|
+
"@firecms/formex": "^3.0.0-beta.11",
|
34
|
+
"@firecms/ui": "^3.0.0-beta.11",
|
35
35
|
"date-fns": "^3.6.0"
|
36
36
|
},
|
37
37
|
"peerDependencies": {
|
@@ -39,11 +39,13 @@
|
|
39
39
|
"react-dom": "^18.3.1"
|
40
40
|
},
|
41
41
|
"devDependencies": {
|
42
|
-
"@types/node": "^20.
|
42
|
+
"@types/node": "^20.17.9",
|
43
43
|
"@types/react": "^18.3.11",
|
44
|
-
"@types/react-dom": "^18.3.
|
45
|
-
"
|
46
|
-
"
|
44
|
+
"@types/react-dom": "^18.3.1",
|
45
|
+
"babel-plugin-react-compiler": "beta",
|
46
|
+
"eslint-plugin-react-compiler": "beta",
|
47
|
+
"typescript": "^5.7.2",
|
48
|
+
"vite": "^5.4.11"
|
47
49
|
},
|
48
50
|
"scripts": {
|
49
51
|
"dev": "vite",
|
@@ -55,5 +57,5 @@
|
|
55
57
|
"src",
|
56
58
|
"bin"
|
57
59
|
],
|
58
|
-
"gitHead": "
|
60
|
+
"gitHead": "cb6d419faf2664cfd6cb2603a834e4bf499a92bb"
|
59
61
|
}
|
@@ -5,10 +5,11 @@ import { EntityCollection, FieldCaption, Role, toSnakeCase, useAuthController, U
|
|
5
5
|
import {
|
6
6
|
Button,
|
7
7
|
Checkbox,
|
8
|
+
CheckIcon,
|
8
9
|
Dialog,
|
9
10
|
DialogActions,
|
10
11
|
DialogContent,
|
11
|
-
|
12
|
+
DialogTitle,
|
12
13
|
LoadingButton,
|
13
14
|
Paper,
|
14
15
|
Select,
|
@@ -32,6 +33,7 @@ export const RoleYupSchema = Yup.object().shape({
|
|
32
33
|
|
33
34
|
function canRoleBeEdited(loggedUser: User) {
|
34
35
|
const loggedUserIsAdmin = loggedUser.roles?.map(r => r.id).includes("admin");
|
36
|
+
console.log("loggedUserIsAdmin", loggedUser);
|
35
37
|
if (!loggedUserIsAdmin) {
|
36
38
|
throw new Error("Only admins can edit roles");
|
37
39
|
}
|
@@ -142,14 +144,10 @@ export function RolesDetailsForm({
|
|
142
144
|
position: "relative",
|
143
145
|
height: "100%"
|
144
146
|
}}>
|
147
|
+
<DialogTitle variant={"h4"} gutterBottom={false}>
|
148
|
+
Role
|
149
|
+
</DialogTitle>
|
145
150
|
<DialogContent className="flex-grow">
|
146
|
-
<div
|
147
|
-
className="flex flex-row pt-12 pb-8">
|
148
|
-
<Typography variant={"h4"}
|
149
|
-
className="flex-grow">
|
150
|
-
Role
|
151
|
-
</Typography>
|
152
|
-
</div>
|
153
151
|
|
154
152
|
<div className={"grid grid-cols-12 gap-8"}>
|
155
153
|
|
@@ -341,6 +339,8 @@ export function RolesDetailsForm({
|
|
341
339
|
<div className={"col-span-12 md:col-span-4"}>
|
342
340
|
<Select
|
343
341
|
error={touched.config && Boolean(errors.config)}
|
342
|
+
size={"large"}
|
343
|
+
fullWidth={true}
|
344
344
|
id="createCollections"
|
345
345
|
name="createCollections"
|
346
346
|
label="Create collections"
|
@@ -363,6 +363,8 @@ export function RolesDetailsForm({
|
|
363
363
|
|
364
364
|
<div className={"col-span-12 md:col-span-4"}>
|
365
365
|
<Select
|
366
|
+
size={"large"}
|
367
|
+
fullWidth={true}
|
366
368
|
error={touched.config && Boolean(errors.config)}
|
367
369
|
id="editCollections"
|
368
370
|
name="editCollections"
|
@@ -389,6 +391,8 @@ export function RolesDetailsForm({
|
|
389
391
|
|
390
392
|
<div className={"col-span-12 md:col-span-4"}>
|
391
393
|
<Select
|
394
|
+
size={"large"}
|
395
|
+
fullWidth={true}
|
392
396
|
error={touched.config && Boolean(errors.config)}
|
393
397
|
id="deleteCollections"
|
394
398
|
name="deleteCollections"
|
@@ -433,7 +437,7 @@ export function RolesDetailsForm({
|
|
433
437
|
type="submit"
|
434
438
|
disabled={!dirty}
|
435
439
|
loading={isSubmitting}
|
436
|
-
startIcon={<
|
440
|
+
startIcon={<CheckIcon/>}
|
437
441
|
>
|
438
442
|
{isNewRole ? "Create role" : "Update"}
|
439
443
|
</LoadingButton>
|
@@ -2,15 +2,15 @@ import React, { useCallback } from "react";
|
|
2
2
|
import * as Yup from "yup";
|
3
3
|
import {
|
4
4
|
Button,
|
5
|
+
CheckIcon,
|
5
6
|
Dialog,
|
6
7
|
DialogActions,
|
7
8
|
DialogContent,
|
8
|
-
|
9
|
+
DialogTitle,
|
9
10
|
LoadingButton,
|
10
11
|
MultiSelect,
|
11
12
|
MultiSelectItem,
|
12
13
|
TextField,
|
13
|
-
Typography,
|
14
14
|
} from "@firecms/ui";
|
15
15
|
import { FieldCaption, Role, useAuthController, User, useSnackbarController } from "@firecms/core";
|
16
16
|
import { Formex, useCreateFormex } from "@firecms/formex";
|
@@ -140,14 +140,11 @@ export function UserDetailsForm({
|
|
140
140
|
position: "relative",
|
141
141
|
height: "100%"
|
142
142
|
}}>
|
143
|
+
|
144
|
+
<DialogTitle variant={"h4"} gutterBottom={false}>
|
145
|
+
User
|
146
|
+
</DialogTitle>
|
143
147
|
<DialogContent className="h-full flex-grow">
|
144
|
-
<div
|
145
|
-
className="flex flex-row pt-4 pb-4">
|
146
|
-
<Typography variant={"h4"}
|
147
|
-
className="flex-grow">
|
148
|
-
User
|
149
|
-
</Typography>
|
150
|
-
</div>
|
151
148
|
|
152
149
|
<div className={"grid grid-cols-12 gap-8"}>
|
153
150
|
|
@@ -220,7 +217,7 @@ export function UserDetailsForm({
|
|
220
217
|
type="submit"
|
221
218
|
disabled={!dirty}
|
222
219
|
loading={isSubmitting}
|
223
|
-
startIcon={<
|
220
|
+
startIcon={<CheckIcon/>}
|
224
221
|
>
|
225
222
|
{isNewUser ? "Create user" : "Update"}
|
226
223
|
</LoadingButton>
|
@@ -54,7 +54,6 @@ export function UsersTable({ onUserClicked }: {
|
|
54
54
|
|
55
55
|
<TableHeader>
|
56
56
|
<TableCell className="truncate w-16"></TableCell>
|
57
|
-
<TableCell>ID</TableCell>
|
58
57
|
<TableCell>Email</TableCell>
|
59
58
|
<TableCell>Name</TableCell>
|
60
59
|
<TableCell>Roles</TableCell>
|
@@ -88,7 +87,6 @@ export function UsersTable({ onUserClicked }: {
|
|
88
87
|
</IconButton>
|
89
88
|
</Tooltip>
|
90
89
|
</TableCell>
|
91
|
-
<TableCell>{user.uid}</TableCell>
|
92
90
|
<TableCell>{user.email}</TableCell>
|
93
91
|
<TableCell className={"font-medium align-left"}>{user.displayName}</TableCell>
|
94
92
|
<TableCell className="align-left">
|
@@ -3,6 +3,7 @@ import equal from "react-fast-compare"
|
|
3
3
|
|
4
4
|
import { UserManagement } from "../types";
|
5
5
|
import {
|
6
|
+
AuthController,
|
6
7
|
Authenticator,
|
7
8
|
DataSourceDelegate,
|
8
9
|
Entity,
|
@@ -13,9 +14,11 @@ import {
|
|
13
14
|
} from "@firecms/core";
|
14
15
|
import { resolveUserRolePermissions } from "../utils";
|
15
16
|
|
16
|
-
type UserWithRoleIds = Omit<
|
17
|
+
type UserWithRoleIds<USER extends User = any> = Omit<USER, "roles"> & { roles: string[] };
|
17
18
|
|
18
|
-
export interface UserManagementParams {
|
19
|
+
export interface UserManagementParams<CONTROLLER extends AuthController<any> = AuthController<any>> {
|
20
|
+
|
21
|
+
authController: CONTROLLER;
|
19
22
|
|
20
23
|
/**
|
21
24
|
* The delegate in charge of persisting the data.
|
@@ -62,6 +65,7 @@ export interface UserManagementParams {
|
|
62
65
|
/**
|
63
66
|
* This hook is used to build a user management object that can be used to
|
64
67
|
* manage users and roles in a Firestore backend.
|
68
|
+
* @param authController
|
65
69
|
* @param dataSourceDelegate
|
66
70
|
* @param usersPath
|
67
71
|
* @param rolesPath
|
@@ -70,38 +74,49 @@ export interface UserManagementParams {
|
|
70
74
|
* @param allowDefaultRolesCreation
|
71
75
|
* @param includeCollectionConfigPermissions
|
72
76
|
*/
|
73
|
-
export function useBuildUserManagement
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
export function useBuildUserManagement<CONTROLLER extends AuthController<any> = AuthController<any>,
|
78
|
+
USER extends User = CONTROLLER extends AuthController<infer U> ? U : any>
|
79
|
+
({
|
80
|
+
authController,
|
81
|
+
dataSourceDelegate,
|
82
|
+
usersPath = "__FIRECMS/config/users",
|
83
|
+
rolesPath = "__FIRECMS/config/roles",
|
84
|
+
usersLimit,
|
85
|
+
canEditRoles = true,
|
86
|
+
allowDefaultRolesCreation,
|
87
|
+
includeCollectionConfigPermissions
|
88
|
+
}: UserManagementParams<CONTROLLER>): UserManagement<USER> & CONTROLLER {
|
89
|
+
|
90
|
+
if (!authController) {
|
91
|
+
throw Error("useBuildUserManagement: You need to provide an authController since version 3.0.0-beta.11. Check https://firecms.co/docs/pro/migrating_from_v3_beta");
|
92
|
+
}
|
82
93
|
|
83
94
|
const [rolesLoading, setRolesLoading] = React.useState<boolean>(true);
|
84
95
|
const [usersLoading, setUsersLoading] = React.useState<boolean>(true);
|
85
96
|
const [roles, setRoles] = React.useState<Role[]>([]);
|
86
|
-
const [usersWithRoleIds, setUsersWithRoleIds] = React.useState<UserWithRoleIds[]>([]);
|
97
|
+
const [usersWithRoleIds, setUsersWithRoleIds] = React.useState<UserWithRoleIds<USER>[]>([]);
|
87
98
|
|
88
99
|
const users = usersWithRoleIds.map(u => ({
|
89
100
|
...u,
|
90
101
|
roles: roles.filter(r => u.roles?.includes(r.id))
|
91
|
-
}) as
|
102
|
+
}) as USER);
|
92
103
|
|
93
104
|
const [rolesError, setRolesError] = React.useState<Error | undefined>();
|
94
105
|
const [usersError, setUsersError] = React.useState<Error | undefined>();
|
95
106
|
|
96
|
-
const
|
107
|
+
const _usersLoading = usersLoading;
|
108
|
+
const _rolesLoading = rolesLoading;
|
109
|
+
|
110
|
+
const loading = _rolesLoading || _usersLoading;
|
97
111
|
|
98
112
|
useEffect(() => {
|
99
113
|
if (!dataSourceDelegate || !rolesPath) return;
|
100
114
|
if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;
|
101
|
-
if (
|
102
|
-
|
103
|
-
|
104
|
-
|
115
|
+
if (authController?.initialLoading) return;
|
116
|
+
// if (authController.user === null) {
|
117
|
+
// setRolesLoading(false);
|
118
|
+
// return;
|
119
|
+
// }
|
105
120
|
|
106
121
|
setRolesLoading(true);
|
107
122
|
return dataSourceDelegate.listenCollection?.({
|
@@ -110,8 +125,9 @@ export function useBuildUserManagement({
|
|
110
125
|
setRolesError(undefined);
|
111
126
|
try {
|
112
127
|
const newRoles = entityToRoles(entities);
|
113
|
-
if (!equal(newRoles, roles))
|
128
|
+
if (!equal(newRoles, roles)) {
|
114
129
|
setRoles(newRoles);
|
130
|
+
}
|
115
131
|
} catch (e) {
|
116
132
|
setRoles([]);
|
117
133
|
console.error("Error loading roles", e);
|
@@ -127,13 +143,14 @@ export function useBuildUserManagement({
|
|
127
143
|
}
|
128
144
|
});
|
129
145
|
|
130
|
-
}, [dataSourceDelegate?.initialised,
|
146
|
+
}, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, rolesPath]);
|
131
147
|
|
132
148
|
useEffect(() => {
|
133
149
|
if (!dataSourceDelegate || !usersPath) return;
|
134
|
-
if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised)
|
135
|
-
|
136
|
-
|
150
|
+
if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) {
|
151
|
+
return;
|
152
|
+
}
|
153
|
+
if (authController?.initialLoading) {
|
137
154
|
return;
|
138
155
|
}
|
139
156
|
|
@@ -141,11 +158,12 @@ export function useBuildUserManagement({
|
|
141
158
|
return dataSourceDelegate.listenCollection?.({
|
142
159
|
path: usersPath,
|
143
160
|
onUpdate(entities: Entity<any>[]): void {
|
161
|
+
console.debug("Updating users", entities);
|
144
162
|
setUsersError(undefined);
|
145
163
|
try {
|
146
164
|
const newUsers = entitiesToUsers(entities);
|
147
|
-
if (!equal(newUsers, usersWithRoleIds))
|
148
|
-
|
165
|
+
// if (!equal(newUsers, usersWithRoleIds))
|
166
|
+
setUsersWithRoleIds(newUsers);
|
149
167
|
} catch (e) {
|
150
168
|
setUsersWithRoleIds([]);
|
151
169
|
console.error("Error loading users", e);
|
@@ -154,16 +172,16 @@ export function useBuildUserManagement({
|
|
154
172
|
setUsersLoading(false);
|
155
173
|
},
|
156
174
|
onError(e: any): void {
|
157
|
-
setUsersWithRoleIds([]);
|
158
175
|
console.error("Error loading users", e);
|
176
|
+
setUsersWithRoleIds([]);
|
159
177
|
setUsersError(e);
|
160
178
|
setUsersLoading(false);
|
161
179
|
}
|
162
180
|
});
|
163
181
|
|
164
|
-
}, [dataSourceDelegate?.initialised,
|
182
|
+
}, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, usersPath]);
|
165
183
|
|
166
|
-
const saveUser = useCallback(async (user:
|
184
|
+
const saveUser = useCallback(async (user: USER): Promise<USER> => {
|
167
185
|
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
168
186
|
if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
|
169
187
|
|
@@ -238,39 +256,49 @@ export function useBuildUserManagement({
|
|
238
256
|
const collectionPermissions: PermissionsBuilder = useCallback(({
|
239
257
|
collection,
|
240
258
|
user
|
241
|
-
}) =>
|
242
|
-
|
243
|
-
|
244
|
-
|
259
|
+
}) =>
|
260
|
+
resolveUserRolePermissions({
|
261
|
+
collection,
|
262
|
+
user
|
263
|
+
}), []);
|
245
264
|
|
246
265
|
const defineRolesFor: ((user: User) => Role[] | undefined) = useCallback((user) => {
|
247
|
-
if (!
|
266
|
+
if (!usersWithRoleIds) throw Error("Users not loaded");
|
267
|
+
const users = usersWithRoleIds.map(u => ({
|
268
|
+
...u,
|
269
|
+
roles: roles.filter(r => u.roles?.includes(r.id))
|
270
|
+
}) as User);
|
248
271
|
const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());
|
249
272
|
return mgmtUser?.roles;
|
250
|
-
}, [
|
251
|
-
|
252
|
-
const authenticator: Authenticator = useCallback(({ user }) => {
|
253
|
-
console.debug("Authenticating user", user);
|
273
|
+
}, [roles, usersWithRoleIds]);
|
254
274
|
|
275
|
+
const authenticator: Authenticator<USER> = useCallback(({ user }) => {
|
255
276
|
if (loading) {
|
256
|
-
console.warn("User management is still loading");
|
257
277
|
return false;
|
258
278
|
}
|
259
279
|
|
260
|
-
// This is an example of how you can link the access system to the user management plugin
|
261
280
|
if (users.length === 0) {
|
281
|
+
console.warn("No users created yet");
|
262
282
|
return true; // If there are no users created yet, we allow access to every user
|
263
283
|
}
|
264
284
|
|
265
285
|
const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());
|
266
286
|
if (mgmtUser) {
|
287
|
+
console.debug("User found in user management system", mgmtUser);
|
267
288
|
return true;
|
268
289
|
}
|
269
290
|
|
270
291
|
throw Error("Could not find a user with the provided email in the user management system.");
|
271
|
-
}, [loading, users
|
292
|
+
}, [loading, users]);
|
293
|
+
|
294
|
+
const userRoles = authController.user ? defineRolesFor(authController.user) : undefined;
|
295
|
+
const isAdmin = (userRoles ?? []).some(r => r.id === "admin");
|
272
296
|
|
273
|
-
const
|
297
|
+
const userRoleIds = userRoles?.map(r => r.id);
|
298
|
+
useEffect(() => {
|
299
|
+
console.debug("Setting roles", userRoles);
|
300
|
+
authController.setUserRoles?.(userRoles ?? []);
|
301
|
+
}, [userRoleIds]);
|
274
302
|
|
275
303
|
return {
|
276
304
|
loading,
|
@@ -289,7 +317,14 @@ export function useBuildUserManagement({
|
|
289
317
|
includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
|
290
318
|
collectionPermissions,
|
291
319
|
defineRolesFor,
|
292
|
-
authenticator
|
320
|
+
authenticator,
|
321
|
+
...authController,
|
322
|
+
initialLoading: authController.initialLoading || loading,
|
323
|
+
userRoles: userRoles,
|
324
|
+
user: authController.user ? {
|
325
|
+
...authController.user,
|
326
|
+
roles: userRoles
|
327
|
+
} : null
|
293
328
|
}
|
294
329
|
}
|
295
330
|
|
@@ -2,6 +2,8 @@ import { Authenticator, PermissionsBuilder, Role, User } from "@firecms/core";
|
|
2
2
|
|
3
3
|
export type UserManagement<USER extends User = User> = {
|
4
4
|
|
5
|
+
authenticator?: Authenticator<USER>;
|
6
|
+
|
5
7
|
loading: boolean;
|
6
8
|
|
7
9
|
users: USER[];
|
@@ -49,12 +51,6 @@ export type UserManagement<USER extends User = User> = {
|
|
49
51
|
*/
|
50
52
|
defineRolesFor: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
|
51
53
|
|
52
|
-
/**
|
53
|
-
* You can build an authenticator callback from the current configuration of the user management.
|
54
|
-
* It will only allow access to users with the required roles.
|
55
|
-
*/
|
56
|
-
authenticator?: Authenticator;
|
57
|
-
|
58
54
|
rolesError?: Error;
|
59
55
|
usersError?: Error;
|
60
56
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
import { FireCMSPlugin, useAuthController, useSnackbarController } from "@firecms/core";
|
1
|
+
import { FireCMSPlugin, useAuthController, User, useSnackbarController } from "@firecms/core";
|
2
2
|
import { UserManagementProvider } from "./UserManagementProvider";
|
3
|
-
import {
|
3
|
+
import { UserManagement } from "./types";
|
4
4
|
import { AddIcon, Button, Paper, Typography } from "@firecms/ui";
|
5
5
|
import { DEFAULT_ROLES } from "./components/roles/default_roles";
|
6
6
|
|
7
|
-
export function useUserManagementPlugin({ userManagement }: {
|
8
|
-
userManagement: UserManagement
|
7
|
+
export function useUserManagementPlugin<USER extends User = any>({ userManagement }: {
|
8
|
+
userManagement: UserManagement<USER>,
|
9
9
|
}): FireCMSPlugin {
|
10
10
|
|
11
11
|
const noUsers = userManagement.users.length === 0;
|
@@ -39,7 +39,7 @@ export function IntroWidget({
|
|
39
39
|
}: {
|
40
40
|
noUsers: boolean;
|
41
41
|
noRoles: boolean;
|
42
|
-
userManagement: UserManagement<
|
42
|
+
userManagement: UserManagement<any>;
|
43
43
|
}) {
|
44
44
|
|
45
45
|
const authController = useAuthController();
|
@@ -53,7 +53,7 @@ export function IntroWidget({
|
|
53
53
|
|
54
54
|
return (
|
55
55
|
<Paper
|
56
|
-
className={"my-4 flex flex-col px-4 py-6 bg-white dark:bg-
|
56
|
+
className={"my-4 flex flex-col px-4 py-6 bg-white dark:bg-surface-accent-800 gap-2"}>
|
57
57
|
<Typography variant={"subtitle2"} className={"uppercase"}>Create your users and roles</Typography>
|
58
58
|
<Typography>
|
59
59
|
You have no users or roles defined. You can create default roles and add the current user as admin.
|
package/src/utils/permissions.ts
CHANGED
@@ -9,13 +9,13 @@ const DEFAULT_PERMISSIONS = {
|
|
9
9
|
delete: false
|
10
10
|
};
|
11
11
|
|
12
|
-
export function resolveUserRolePermissions<
|
12
|
+
export function resolveUserRolePermissions<USER extends User>
|
13
13
|
({
|
14
14
|
collection,
|
15
15
|
user
|
16
16
|
}: {
|
17
17
|
collection: EntityCollection<any>,
|
18
|
-
user:
|
18
|
+
user: USER | null
|
19
19
|
}): Permissions {
|
20
20
|
|
21
21
|
const roles = user?.roles;
|