@firecms/user_management 3.0.0-beta.10 → 3.0.0-beta.12

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.
@@ -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>;
@@ -7,14 +8,6 @@ export type UserManagement<USER extends User = User> = {
7
8
  roles: Role[];
8
9
  saveRole: (role: Role) => Promise<void>;
9
10
  deleteRole: (role: Role) => Promise<void>;
10
- /**
11
- * Maximum number of users that can be created.
12
- */
13
- usersLimit?: number;
14
- /**
15
- * Can the logged user edit roles?
16
- */
17
- canEditRoles?: boolean;
18
11
  /**
19
12
  * Is the logged user Admin?
20
13
  */
@@ -37,11 +30,6 @@ export type UserManagement<USER extends User = User> = {
37
30
  * @param user
38
31
  */
39
32
  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
33
  rolesError?: Error;
46
34
  usersError?: Error;
47
35
  };
@@ -1,10 +1,10 @@
1
- import { FireCMSPlugin } from "@firecms/core";
2
- import { PersistedUser, UserManagement } from "./types";
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<PersistedUser>;
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<UserType extends User>({ collection, user }: {
3
+ export declare function resolveUserRolePermissions<USER extends User>({ collection, user }: {
4
4
  collection: EntityCollection<any>;
5
- user: UserType | null;
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.10",
4
+ "version": "3.0.0-beta.12",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -29,21 +29,23 @@
29
29
  "types": "dist/index.d.ts",
30
30
  "source": "src/index.ts",
31
31
  "dependencies": {
32
- "@firecms/core": "^3.0.0-beta.10",
33
- "@firecms/formex": "^3.0.0-beta.10",
34
- "@firecms/ui": "^3.0.0-beta.10",
32
+ "@firecms/core": "^3.0.0-beta.12",
33
+ "@firecms/formex": "^3.0.0-beta.12",
34
+ "@firecms/ui": "^3.0.0-beta.12",
35
35
  "date-fns": "^3.6.0"
36
36
  },
37
37
  "peerDependencies": {
38
- "react": "^18.3.1",
39
- "react-dom": "^18.3.1"
38
+ "react": ">=18.0.0",
39
+ "react-dom": ">=18.0.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@types/node": "^20.16.11",
43
- "@types/react": "^18.3.11",
42
+ "@types/node": "^20.17.14",
43
+ "@types/react": "^18.3.18",
44
44
  "@types/react-dom": "^18.3.0",
45
- "typescript": "^5.6.3",
46
- "vite": "^5.4.8"
45
+ "babel-plugin-react-compiler": "beta",
46
+ "eslint-plugin-react-compiler": "beta",
47
+ "typescript": "^5.7.3",
48
+ "vite": "^5.4.14"
47
49
  },
48
50
  "scripts": {
49
51
  "dev": "vite",
@@ -55,5 +57,5 @@
55
57
  "src",
56
58
  "bin"
57
59
  ],
58
- "gitHead": "f844c3f86094efec6c33313c3f106f30cdcd309f"
60
+ "gitHead": "8de3edb4560643922fe44e9c357985f64c3951c1"
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
- DoneIcon,
12
+ DialogTitle,
12
13
  LoadingButton,
13
14
  Paper,
14
15
  Select,
@@ -142,14 +143,10 @@ export function RolesDetailsForm({
142
143
  position: "relative",
143
144
  height: "100%"
144
145
  }}>
146
+ <DialogTitle variant={"h4"} gutterBottom={false}>
147
+ Role
148
+ </DialogTitle>
145
149
  <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
150
 
154
151
  <div className={"grid grid-cols-12 gap-8"}>
155
152
 
@@ -341,6 +338,8 @@ export function RolesDetailsForm({
341
338
  <div className={"col-span-12 md:col-span-4"}>
342
339
  <Select
343
340
  error={touched.config && Boolean(errors.config)}
341
+ size={"large"}
342
+ fullWidth={true}
344
343
  id="createCollections"
345
344
  name="createCollections"
346
345
  label="Create collections"
@@ -363,6 +362,8 @@ export function RolesDetailsForm({
363
362
 
364
363
  <div className={"col-span-12 md:col-span-4"}>
365
364
  <Select
365
+ size={"large"}
366
+ fullWidth={true}
366
367
  error={touched.config && Boolean(errors.config)}
367
368
  id="editCollections"
368
369
  name="editCollections"
@@ -389,6 +390,8 @@ export function RolesDetailsForm({
389
390
 
390
391
  <div className={"col-span-12 md:col-span-4"}>
391
392
  <Select
393
+ size={"large"}
394
+ fullWidth={true}
392
395
  error={touched.config && Boolean(errors.config)}
393
396
  id="deleteCollections"
394
397
  name="deleteCollections"
@@ -433,7 +436,7 @@ export function RolesDetailsForm({
433
436
  type="submit"
434
437
  disabled={!dirty}
435
438
  loading={isSubmitting}
436
- startIcon={<DoneIcon/>}
439
+ startIcon={<CheckIcon/>}
437
440
  >
438
441
  {isNewRole ? "Create role" : "Update"}
439
442
  </LoadingButton>
@@ -1,10 +1,9 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
 
3
3
  import { Role, useNavigationController } from "@firecms/core";
4
- import { AddIcon, Button, Container, Tooltip, Typography } from "@firecms/ui";
4
+ import { AddIcon, Button, Container, Typography } from "@firecms/ui";
5
5
  import { RolesTable } from "./RolesTable";
6
6
  import { RolesDetailsForm } from "./RolesDetailsForm";
7
- import { useUserManagement } from "../../hooks";
8
7
 
9
8
  export const RolesView = React.memo(
10
9
  function RolesView({ children }: { children?: React.ReactNode }) {
@@ -13,8 +12,6 @@ export const RolesView = React.memo(
13
12
  const [dialogOpen, setDialogOpen] = useState(false);
14
13
  const [selectedRole, setSelectedRole] = useState<Role | undefined>();
15
14
 
16
- const { canEditRoles } = useUserManagement();
17
-
18
15
  const onRoleClicked = useCallback((user: Role) => {
19
16
  setDialogOpen(true);
20
17
  setSelectedRole(user);
@@ -36,26 +33,21 @@ export const RolesView = React.memo(
36
33
  component="h4">
37
34
  Roles
38
35
  </Typography>
39
- <Tooltip
40
- asChild={true}
41
- title={!canEditRoles ? "Update plans to customise roles" : undefined}>
42
- <Button
43
- size={"large"}
44
- disabled={!canEditRoles}
45
- startIcon={<AddIcon/>}
46
- onClick={() => setDialogOpen(true)}>
47
- Add role
48
- </Button>
49
- </Tooltip>
36
+ <Button
37
+ size={"large"}
38
+ startIcon={<AddIcon/>}
39
+ onClick={() => setDialogOpen(true)}>
40
+ Add role
41
+ </Button>
50
42
  </div>
51
43
 
52
- <RolesTable onRoleClicked={onRoleClicked} editable={Boolean(canEditRoles)}/>
44
+ <RolesTable onRoleClicked={onRoleClicked} editable={true}/>
53
45
 
54
46
  <RolesDetailsForm
55
47
  key={selectedRole?.id ?? "new"}
56
48
  open={dialogOpen}
57
49
  role={selectedRole}
58
- editable={canEditRoles}
50
+ editable={true}
59
51
  collections={collections}
60
52
  handleClose={handleClose}/>
61
53
 
@@ -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
- DoneIcon,
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={<DoneIcon/>}
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">
@@ -11,9 +11,7 @@ export const UsersView = function UsersView({ children }: { children?: React.Rea
11
11
  const [dialogOpen, setDialogOpen] = useState<boolean>();
12
12
  const [selectedUser, setSelectedUser] = useState<User | undefined>();
13
13
 
14
- const { users, usersLimit } = useUserManagement();
15
-
16
- const reachedUsersLimit = usersLimit !== undefined && (users && users.length >= usersLimit);
14
+ const { users } = useUserManagement();
17
15
 
18
16
  const onUserClicked = useCallback((user: User) => {
19
17
  setSelectedUser(user);
@@ -39,7 +37,6 @@ export const UsersView = function UsersView({ children }: { children?: React.Rea
39
37
  </Typography>
40
38
  <Button
41
39
  size={"large"}
42
- disabled={reachedUsersLimit}
43
40
  startIcon={<AddIcon/>}
44
41
  onClick={() => setDialogOpen(true)}>
45
42
  Add user
@@ -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<User, "roles"> & { roles: string[] };
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.
@@ -37,16 +40,6 @@ export interface UserManagementParams {
37
40
  */
38
41
  rolesPath?: string;
39
42
 
40
- /**
41
- * Maximum number of users that can be created.
42
- */
43
- usersLimit?: number;
44
-
45
- /**
46
- * Can the logged user edit roles
47
- */
48
- canEditRoles?: boolean;
49
-
50
43
  /**
51
44
  * If there are no roles in the database, provide a button to create the default roles.
52
45
  */
@@ -62,46 +55,54 @@ export interface UserManagementParams {
62
55
  /**
63
56
  * This hook is used to build a user management object that can be used to
64
57
  * manage users and roles in a Firestore backend.
58
+ * @param authController
65
59
  * @param dataSourceDelegate
66
60
  * @param usersPath
67
61
  * @param rolesPath
68
- * @param usersLimit
69
- * @param canEditRoles
70
62
  * @param allowDefaultRolesCreation
71
63
  * @param includeCollectionConfigPermissions
72
64
  */
73
- export function useBuildUserManagement({
74
- dataSourceDelegate,
75
- usersPath = "__FIRECMS/config/users",
76
- rolesPath = "__FIRECMS/config/roles",
77
- usersLimit,
78
- canEditRoles = true,
79
- allowDefaultRolesCreation,
80
- includeCollectionConfigPermissions
81
- }: UserManagementParams): UserManagement {
65
+ export function useBuildUserManagement<CONTROLLER extends AuthController<any> = AuthController<any>,
66
+ USER extends User = CONTROLLER extends AuthController<infer U> ? U : any>
67
+ ({
68
+ authController,
69
+ dataSourceDelegate,
70
+ usersPath = "__FIRECMS/config/users",
71
+ rolesPath = "__FIRECMS/config/roles",
72
+ allowDefaultRolesCreation,
73
+ includeCollectionConfigPermissions
74
+ }: UserManagementParams<CONTROLLER>): UserManagement<USER> & CONTROLLER {
75
+
76
+ if (!authController) {
77
+ 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");
78
+ }
82
79
 
83
80
  const [rolesLoading, setRolesLoading] = React.useState<boolean>(true);
84
81
  const [usersLoading, setUsersLoading] = React.useState<boolean>(true);
85
82
  const [roles, setRoles] = React.useState<Role[]>([]);
86
- const [usersWithRoleIds, setUsersWithRoleIds] = React.useState<UserWithRoleIds[]>([]);
83
+ const [usersWithRoleIds, setUsersWithRoleIds] = React.useState<UserWithRoleIds<USER>[]>([]);
87
84
 
88
85
  const users = usersWithRoleIds.map(u => ({
89
86
  ...u,
90
87
  roles: roles.filter(r => u.roles?.includes(r.id))
91
- }) as User);
88
+ }) as USER);
92
89
 
93
90
  const [rolesError, setRolesError] = React.useState<Error | undefined>();
94
91
  const [usersError, setUsersError] = React.useState<Error | undefined>();
95
92
 
96
- const loading = rolesLoading || usersLoading;
93
+ const _usersLoading = usersLoading;
94
+ const _rolesLoading = rolesLoading;
95
+
96
+ const loading = _rolesLoading || _usersLoading;
97
97
 
98
98
  useEffect(() => {
99
99
  if (!dataSourceDelegate || !rolesPath) return;
100
100
  if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;
101
- if (dataSourceDelegate.authenticated !== undefined && !dataSourceDelegate.authenticated) {
102
- setRolesLoading(false);
103
- return;
104
- }
101
+ if (authController?.initialLoading) return;
102
+ // if (authController.user === null) {
103
+ // setRolesLoading(false);
104
+ // return;
105
+ // }
105
106
 
106
107
  setRolesLoading(true);
107
108
  return dataSourceDelegate.listenCollection?.({
@@ -110,8 +111,9 @@ export function useBuildUserManagement({
110
111
  setRolesError(undefined);
111
112
  try {
112
113
  const newRoles = entityToRoles(entities);
113
- if (!equal(newRoles, roles))
114
+ if (!equal(newRoles, roles)) {
114
115
  setRoles(newRoles);
116
+ }
115
117
  } catch (e) {
116
118
  setRoles([]);
117
119
  console.error("Error loading roles", e);
@@ -127,13 +129,14 @@ export function useBuildUserManagement({
127
129
  }
128
130
  });
129
131
 
130
- }, [dataSourceDelegate?.initialised, dataSourceDelegate?.authenticated, rolesPath]);
132
+ }, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, rolesPath]);
131
133
 
132
134
  useEffect(() => {
133
135
  if (!dataSourceDelegate || !usersPath) return;
134
- if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;
135
- if (dataSourceDelegate.authenticated !== undefined && !dataSourceDelegate.authenticated) {
136
- setUsersLoading(false);
136
+ if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) {
137
+ return;
138
+ }
139
+ if (authController?.initialLoading) {
137
140
  return;
138
141
  }
139
142
 
@@ -141,11 +144,12 @@ export function useBuildUserManagement({
141
144
  return dataSourceDelegate.listenCollection?.({
142
145
  path: usersPath,
143
146
  onUpdate(entities: Entity<any>[]): void {
147
+ console.debug("Updating users", entities);
144
148
  setUsersError(undefined);
145
149
  try {
146
150
  const newUsers = entitiesToUsers(entities);
147
- if (!equal(newUsers, usersWithRoleIds))
148
- setUsersWithRoleIds(newUsers);
151
+ // if (!equal(newUsers, usersWithRoleIds))
152
+ setUsersWithRoleIds(newUsers);
149
153
  } catch (e) {
150
154
  setUsersWithRoleIds([]);
151
155
  console.error("Error loading users", e);
@@ -154,16 +158,16 @@ export function useBuildUserManagement({
154
158
  setUsersLoading(false);
155
159
  },
156
160
  onError(e: any): void {
157
- setUsersWithRoleIds([]);
158
161
  console.error("Error loading users", e);
162
+ setUsersWithRoleIds([]);
159
163
  setUsersError(e);
160
164
  setUsersLoading(false);
161
165
  }
162
166
  });
163
167
 
164
- }, [dataSourceDelegate?.initialised, dataSourceDelegate?.authenticated, usersPath]);
168
+ }, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, usersPath]);
165
169
 
166
- const saveUser = useCallback(async (user: User): Promise<User> => {
170
+ const saveUser = useCallback(async (user: USER): Promise<USER> => {
167
171
  if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
168
172
  if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
169
173
 
@@ -238,39 +242,49 @@ export function useBuildUserManagement({
238
242
  const collectionPermissions: PermissionsBuilder = useCallback(({
239
243
  collection,
240
244
  user
241
- }) => resolveUserRolePermissions({
242
- collection,
243
- user
244
- }), []);
245
+ }) =>
246
+ resolveUserRolePermissions({
247
+ collection,
248
+ user
249
+ }), []);
245
250
 
246
251
  const defineRolesFor: ((user: User) => Role[] | undefined) = useCallback((user) => {
247
- if (!users) throw Error("Users not loaded");
252
+ if (!usersWithRoleIds) throw Error("Users not loaded");
253
+ const users = usersWithRoleIds.map(u => ({
254
+ ...u,
255
+ roles: roles.filter(r => u.roles?.includes(r.id))
256
+ }) as User);
248
257
  const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());
249
258
  return mgmtUser?.roles;
250
- }, [users]);
251
-
252
- const authenticator: Authenticator = useCallback(({ user }) => {
253
- console.debug("Authenticating user", user);
259
+ }, [roles, usersWithRoleIds]);
254
260
 
261
+ const authenticator: Authenticator<USER> = useCallback(({ user }) => {
255
262
  if (loading) {
256
- console.warn("User management is still loading");
257
263
  return false;
258
264
  }
259
265
 
260
- // This is an example of how you can link the access system to the user management plugin
261
266
  if (users.length === 0) {
267
+ console.warn("No users created yet");
262
268
  return true; // If there are no users created yet, we allow access to every user
263
269
  }
264
270
 
265
271
  const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());
266
272
  if (mgmtUser) {
273
+ console.debug("User found in user management system", mgmtUser);
267
274
  return true;
268
275
  }
269
276
 
270
277
  throw Error("Could not find a user with the provided email in the user management system.");
271
- }, [loading, users, usersError, rolesError]);
278
+ }, [loading, users]);
272
279
 
273
- const isAdmin = roles.some(r => r.id === "admin");
280
+ const userRoles = authController.user ? defineRolesFor(authController.user) : undefined;
281
+ const isAdmin = (userRoles ?? []).some(r => r.id === "admin");
282
+
283
+ const userRoleIds = userRoles?.map(r => r.id);
284
+ useEffect(() => {
285
+ console.debug("Setting roles", userRoles);
286
+ authController.setUserRoles?.(userRoles ?? []);
287
+ }, [userRoleIds]);
274
288
 
275
289
  return {
276
290
  loading,
@@ -281,15 +295,20 @@ export function useBuildUserManagement({
281
295
  rolesError,
282
296
  deleteUser,
283
297
  deleteRole,
284
- usersLimit,
285
298
  usersError,
286
299
  isAdmin,
287
- canEditRoles: canEditRoles === undefined ? true : canEditRoles,
288
300
  allowDefaultRolesCreation: allowDefaultRolesCreation === undefined ? true : allowDefaultRolesCreation,
289
301
  includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
290
302
  collectionPermissions,
291
303
  defineRolesFor,
292
- authenticator
304
+ authenticator,
305
+ ...authController,
306
+ initialLoading: authController.initialLoading || loading,
307
+ userRoles: userRoles,
308
+ user: authController.user ? {
309
+ ...authController.user,
310
+ roles: userRoles
311
+ } : null
293
312
  }
294
313
  }
295
314
 
@@ -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[];
@@ -12,16 +14,6 @@ export type UserManagement<USER extends User = User> = {
12
14
  saveRole: (role: Role) => Promise<void>;
13
15
  deleteRole: (role: Role) => Promise<void>;
14
16
 
15
- /**
16
- * Maximum number of users that can be created.
17
- */
18
- usersLimit?: number;
19
-
20
- /**
21
- * Can the logged user edit roles?
22
- */
23
- canEditRoles?: boolean;
24
-
25
17
  /**
26
18
  * Is the logged user Admin?
27
19
  */
@@ -49,12 +41,6 @@ export type UserManagement<USER extends User = User> = {
49
41
  */
50
42
  defineRolesFor: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
51
43
 
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
44
  rolesError?: Error;
59
45
  usersError?: Error;
60
46
 
@@ -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 { PersistedUser, UserManagement } from "./types";
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<PersistedUser>;
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-slate-800 gap-2"}>
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.
@@ -9,13 +9,13 @@ const DEFAULT_PERMISSIONS = {
9
9
  delete: false
10
10
  };
11
11
 
12
- export function resolveUserRolePermissions<UserType extends User>
12
+ export function resolveUserRolePermissions<USER extends User>
13
13
  ({
14
14
  collection,
15
15
  user
16
16
  }: {
17
17
  collection: EntityCollection<any>,
18
- user: UserType | null
18
+ user: USER | null
19
19
  }): Permissions {
20
20
 
21
21
  const roles = user?.roles;