@firecms/user_management 3.0.0-3.0.0-canary.8.0 → 3.0.0-3.0.0-canary.27.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.
Files changed (39) hide show
  1. package/dist/UserManagementProvider.d.ts +4 -3
  2. package/dist/components/roles/RoleChip.d.ts +1 -1
  3. package/dist/components/roles/RolesDetailsForm.d.ts +1 -2
  4. package/dist/components/roles/RolesTable.d.ts +1 -1
  5. package/dist/components/roles/default_roles.d.ts +1 -1
  6. package/dist/components/users/UserDetailsForm.d.ts +2 -2
  7. package/dist/components/users/UsersTable.d.ts +2 -2
  8. package/dist/hooks/useBuildFirestoreUserManagement.d.ts +1 -3
  9. package/dist/hooks/useUserManagement.d.ts +3 -2
  10. package/dist/index.es.js +461 -443
  11. package/dist/index.es.js.map +1 -1
  12. package/dist/index.umd.js +1 -1
  13. package/dist/index.umd.js.map +1 -1
  14. package/dist/types/index.d.ts +1 -2
  15. package/dist/types/persisted_user.d.ts +5 -0
  16. package/dist/types/user_management.d.ts +12 -10
  17. package/dist/utils/permissions.d.ts +3 -4
  18. package/package.json +7 -9
  19. package/src/UserManagementProvider.tsx +4 -3
  20. package/src/components/roles/RoleChip.tsx +1 -1
  21. package/src/components/roles/RolesDetailsForm.tsx +1 -2
  22. package/src/components/roles/RolesTable.tsx +1 -2
  23. package/src/components/roles/RolesView.tsx +1 -2
  24. package/src/components/roles/default_roles.tsx +1 -1
  25. package/src/components/users/UserDetailsForm.tsx +14 -13
  26. package/src/components/users/UsersTable.tsx +6 -6
  27. package/src/components/users/UsersView.tsx +3 -3
  28. package/src/hooks/useBuildFirestoreUserManagement.tsx +53 -23
  29. package/src/hooks/useUserManagement.tsx +3 -3
  30. package/src/types/index.ts +1 -2
  31. package/src/types/persisted_user.ts +6 -0
  32. package/src/types/user_management.tsx +14 -11
  33. package/src/useUserManagementPlugin.tsx +2 -2
  34. package/src/utils/permissions.ts +7 -5
  35. package/dist/types/firecms_user.d.ts +0 -7
  36. package/dist/types/roles.d.ts +0 -31
  37. package/src/types/firecms_user.ts +0 -8
  38. package/src/types/roles.ts +0 -41
  39. package/tailwind.config.js +0 -68
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-3.0.0-canary.8.0",
4
+ "version": "3.0.0-3.0.0-canary.27.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -22,8 +22,7 @@
22
22
  "require": "./dist/index.umd.js",
23
23
  "types": "./dist/index.d.ts"
24
24
  },
25
- "./package.json": "./package.json",
26
- "./tailwind.config.js": "./tailwind.config.js"
25
+ "./package.json": "./package.json"
27
26
  },
28
27
  "packageManager": "yarn@4.1.0",
29
28
  "main": "./dist/index.umd.js",
@@ -31,9 +30,9 @@
31
30
  "types": "dist/index.d.ts",
32
31
  "source": "src/index.ts",
33
32
  "dependencies": {
34
- "@firecms/core": "^3.0.0-3.0.0-canary.8.0",
35
- "@firecms/formex": "^3.0.0-3.0.0-canary.8.0",
36
- "@firecms/ui": "^3.0.0-3.0.0-canary.8.0",
33
+ "@firecms/core": "^3.0.0-3.0.0-canary.27.0",
34
+ "@firecms/formex": "^3.0.0-3.0.0-canary.27.0",
35
+ "@firecms/ui": "^3.0.0-3.0.0-canary.27.0",
37
36
  "date-fns": "^3.6.0"
38
37
  },
39
38
  "peerDependencies": {
@@ -54,7 +53,7 @@
54
53
  "eslint-plugin-react": "^7.34.1",
55
54
  "eslint-plugin-react-hooks": "^4.6.0",
56
55
  "typescript": "^5.4.2",
57
- "vite": "^5.1.6"
56
+ "vite": "^5.2.3"
58
57
  },
59
58
  "scripts": {
60
59
  "dev": "vite",
@@ -64,7 +63,6 @@
64
63
  "files": [
65
64
  "dist",
66
65
  "src",
67
- "tailwind.config.js",
68
66
  "bin"
69
67
  ],
70
68
  "eslintConfig": {
@@ -73,5 +71,5 @@
73
71
  "react-app/jest"
74
72
  ]
75
73
  },
76
- "gitHead": "35cdb977614cf59e5ae8e5eede12c9bda98c8bc1"
74
+ "gitHead": "17a60c250932174649cf62f3794247ff5b2e07e2"
77
75
  }
@@ -1,13 +1,14 @@
1
1
  import React, { PropsWithChildren } from "react";
2
- import { UserManagement, UserWithRoles } from "./types";
2
+ import { UserManagement } from "./types";
3
+ import { User } from "@firecms/core";
3
4
 
4
5
  export const UserManagementContext = React.createContext<UserManagement<any>>({} as any);
5
6
 
6
- export interface UserManagementProviderProps<U extends UserWithRoles = UserWithRoles> {
7
+ export interface UserManagementProviderProps<U extends User = User> {
7
8
  userManagement: UserManagement<U>
8
9
  }
9
10
 
10
- export function UserManagementProvider<U extends UserWithRoles = UserWithRoles>({
11
+ export function UserManagementProvider<U extends User = User>({
11
12
  children,
12
13
  userManagement
13
14
  }: PropsWithChildren<UserManagementProviderProps<U>>) {
@@ -1,5 +1,5 @@
1
1
  import { Chip, getColorSchemeForSeed } from "@firecms/ui";
2
- import { Role } from "../../types";
2
+ import { Role } from "@firecms/core";
3
3
 
4
4
  export type RoleChipProps = {
5
5
  role: Role;
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
  import * as Yup from "yup";
3
3
 
4
- import { EntityCollection, FieldCaption, toSnakeCase, } from "@firecms/core";
4
+ import { EntityCollection, FieldCaption, Role, toSnakeCase, } from "@firecms/core";
5
5
  import {
6
6
  Button,
7
7
  Checkbox,
@@ -24,7 +24,6 @@ import {
24
24
  } from "@firecms/ui";
25
25
  import { useUserManagement } from "../../hooks";
26
26
  import { Formex, getIn, useCreateFormex } from "@firecms/formex";
27
- import { Role } from "../../types";
28
27
 
29
28
  export const RoleYupSchema = Yup.object().shape({
30
29
  id: Yup.string().required("Required"),
@@ -13,9 +13,8 @@ import {
13
13
  Tooltip,
14
14
  Typography
15
15
  } from "@firecms/ui";
16
- import { DeleteConfirmationDialog } from "@firecms/core";
16
+ import { DeleteConfirmationDialog, Role } from "@firecms/core";
17
17
  import { useUserManagement } from "../../hooks";
18
- import { Role } from "../../types";
19
18
  import { RoleChip } from "./RoleChip";
20
19
  import { DEFAULT_ROLES } from "./default_roles";
21
20
 
@@ -1,11 +1,10 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
 
3
- import { useNavigationController } from "@firecms/core";
3
+ import { Role, useNavigationController } from "@firecms/core";
4
4
  import { AddIcon, Button, Container, Tooltip, Typography } from "@firecms/ui";
5
5
  import { RolesTable } from "./RolesTable";
6
6
  import { RolesDetailsForm } from "./RolesDetailsForm";
7
7
  import { useUserManagement } from "../../hooks";
8
- import { Role } from "../../types";
9
8
 
10
9
  export const RolesView = React.memo(
11
10
  function RolesView({ children }: { children?: React.ReactNode }) {
@@ -1,4 +1,4 @@
1
- import { Role } from "../../types";
1
+ import { Role } from "@firecms/core";
2
2
 
3
3
  export const DEFAULT_ROLES: Role[] = [
4
4
  {
@@ -12,10 +12,9 @@ import {
12
12
  TextField,
13
13
  Typography,
14
14
  } from "@firecms/ui";
15
- import { FieldCaption, useSnackbarController } from "@firecms/core";
15
+ import { FieldCaption, Role, useAuthController, User, useSnackbarController } from "@firecms/core";
16
16
  import { Formex, useCreateFormex } from "@firecms/formex";
17
17
 
18
- import { Role, UserWithRoles } from "../../types";
19
18
  import { areRolesEqual } from "../../utils";
20
19
  import { useUserManagement } from "../../hooks";
21
20
  import { RoleChip } from "../roles";
@@ -26,17 +25,17 @@ export const UserYupSchema = Yup.object().shape({
26
25
  roles: Yup.array().min(1)
27
26
  });
28
27
 
29
- function canUserBeEdited(loggedUser: UserWithRoles, user: UserWithRoles, users: UserWithRoles[], roles: Role[], prevUser?: UserWithRoles) {
30
- const admins = users.filter(u => u.roles.map(r => r.id).includes("admin"));
31
- const loggedUserIsAdmin = loggedUser.roles.map(r => r.id).includes("admin");
32
- const didRolesChange = !prevUser || !areRolesEqual(prevUser.roles, user.roles);
28
+ function canUserBeEdited(loggedUser: User, user: User, users: User[], roles: Role[], prevUser?: User) {
29
+ const admins = users.filter(u => u.roles?.map(r => r.id).includes("admin"));
30
+ const loggedUserIsAdmin = loggedUser.roles?.map(r => r.id).includes("admin");
31
+ const didRolesChange = !prevUser || !areRolesEqual(prevUser.roles ?? [], user.roles ?? []);
33
32
 
34
33
  if (didRolesChange && !loggedUserIsAdmin) {
35
34
  throw new Error("Only admins can change roles");
36
35
  }
37
36
 
38
37
  // was the admin role removed
39
- const adminRoleRemoved = prevUser && prevUser.roles.map(r => r.id).includes("admin") && !user.roles.map(r => r.id).includes("admin");
38
+ const adminRoleRemoved = prevUser && prevUser.roles?.map(r => r.id).includes("admin") && !user.roles?.map(r => r.id).includes("admin");
40
39
 
41
40
  // avoid removing the last admin
42
41
  if (adminRoleRemoved && admins.length === 1) {
@@ -51,20 +50,22 @@ export function UserDetailsForm({
51
50
  handleClose
52
51
  }: {
53
52
  open: boolean,
54
- user?: UserWithRoles,
53
+ user?: User,
55
54
  handleClose: () => void
56
55
  }) {
57
56
 
58
57
  const snackbarController = useSnackbarController();
59
58
  const {
60
- loggedInUser,
59
+ user: loggedInUser
60
+ } = useAuthController();
61
+ const {
61
62
  saveUser,
62
63
  users,
63
64
  roles,
64
65
  } = useUserManagement();
65
66
  const isNewUser = !userProp;
66
67
 
67
- const onUserUpdated = useCallback((savedUser: UserWithRoles): Promise<UserWithRoles> => {
68
+ const onUserUpdated = useCallback((savedUser: User): Promise<User> => {
68
69
  if (!loggedInUser) {
69
70
  throw new Error("Logged user not found");
70
71
  }
@@ -81,7 +82,7 @@ export function UserDetailsForm({
81
82
  displayName: "",
82
83
  email: "",
83
84
  roles: roles.filter(r => r.id === "editor")
84
- } as UserWithRoles,
85
+ } as User,
85
86
  validation: (values) => {
86
87
  return UserYupSchema.validate(values, { abortEarly: false })
87
88
  .then(() => {
@@ -93,7 +94,7 @@ export function UserDetailsForm({
93
94
  }, {});
94
95
  });
95
96
  },
96
- onSubmit: (user: UserWithRoles, formexController) => {
97
+ onSubmit: (user: User, formexController) => {
97
98
 
98
99
  return onUserUpdated(user)
99
100
  .then(() => {
@@ -181,7 +182,7 @@ export function UserDetailsForm({
181
182
  <div className={"col-span-12"}>
182
183
  <MultiSelect
183
184
  label="Roles"
184
- value={values.roles.map(r => r.id) ?? []}
185
+ value={values.roles?.map(r => r.id) ?? []}
185
186
  onMultiValueChange={(value: string[]) => setFieldValue("roles", value.map(id => roles.find(r => r.id === id) as Role))}
186
187
  renderValue={(value: string) => {
187
188
  const userRole = roles
@@ -5,9 +5,9 @@ import * as locales from "date-fns/locale";
5
5
 
6
6
  import {
7
7
  defaultDateFormat,
8
- DeleteConfirmationDialog,
8
+ DeleteConfirmationDialog, Role,
9
9
  useAuthController,
10
- useCustomizationController,
10
+ useCustomizationController, User,
11
11
  useSnackbarController
12
12
  } from "@firecms/core";
13
13
  import {
@@ -23,19 +23,19 @@ import {
23
23
  Tooltip,
24
24
  Typography,
25
25
  } from "@firecms/ui";
26
- import { Role, UserWithRoles } from "../../types";
27
26
  import { useUserManagement } from "../../hooks";
28
27
  import { RoleChip } from "../roles";
28
+ import { PersistedUser } from "../../types";
29
29
 
30
30
  export function UsersTable({ onUserClicked }: {
31
- onUserClicked: (user: UserWithRoles) => void;
31
+ onUserClicked: (user: User) => void;
32
32
  }) {
33
33
 
34
34
  const {
35
35
  users,
36
36
  saveUser,
37
37
  deleteUser
38
- } = useUserManagement();
38
+ } = useUserManagement<PersistedUser>();
39
39
 
40
40
  const authController = useAuthController();
41
41
  const snackbarController = useSnackbarController();
@@ -44,7 +44,7 @@ export function UsersTable({ onUserClicked }: {
44
44
  const dateUtilsLocale = customizationController?.locale ? locales[customizationController?.locale as keyof typeof locales] : undefined;
45
45
  const dateFormat: string = customizationController?.dateTimeFormat ?? defaultDateFormat;
46
46
 
47
- const [userToBeDeleted, setUserToBeDeleted] = useState<UserWithRoles | undefined>(undefined);
47
+ const [userToBeDeleted, setUserToBeDeleted] = useState<User | undefined>(undefined);
48
48
  const [deleteInProgress, setDeleteInProgress] = useState<boolean>(false);
49
49
 
50
50
  return (
@@ -3,19 +3,19 @@ import { AddIcon, Button, Container, Typography } from "@firecms/ui";
3
3
  import { UsersTable } from "./UsersTable";
4
4
  import { UserDetailsForm } from "./UserDetailsForm";
5
5
  import React, { useCallback, useState } from "react";
6
- import { UserWithRoles } from "../../types";
7
6
  import { useUserManagement } from "../../hooks/useUserManagement";
7
+ import { User } from "@firecms/core";
8
8
 
9
9
  export const UsersView = function UsersView({ children }: { children?: React.ReactNode }) {
10
10
 
11
11
  const [dialogOpen, setDialogOpen] = useState<boolean>();
12
- const [selectedUser, setSelectedUser] = useState<UserWithRoles | undefined>();
12
+ const [selectedUser, setSelectedUser] = useState<User | undefined>();
13
13
 
14
14
  const { users, usersLimit } = useUserManagement();
15
15
 
16
16
  const reachedUsersLimit = usersLimit !== undefined && (users && users.length >= usersLimit);
17
17
 
18
- const onUserClicked = useCallback((user: UserWithRoles) => {
18
+ const onUserClicked = useCallback((user: User) => {
19
19
  setSelectedUser(user);
20
20
  setDialogOpen(true);
21
21
  }, []);
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useRef } from "react";
2
2
  import {
3
+ addDoc,
3
4
  collection,
4
5
  deleteDoc,
5
6
  doc,
@@ -10,8 +11,8 @@ import {
10
11
  setDoc
11
12
  } from "firebase/firestore";
12
13
  import { FirebaseApp } from "firebase/app";
13
- import { Role, UserManagement, UserWithRoles } from "../types";
14
- import { AuthController, PermissionsBuilder, User } from "@firecms/core";
14
+ import { UserManagement } from "../types";
15
+ import { Authenticator, PermissionsBuilder, Role, User } from "@firecms/core";
15
16
  import { resolveUserRolePermissions } from "../utils";
16
17
 
17
18
  type UserWithRoleIds = User & { roles: string[] };
@@ -41,8 +42,6 @@ export interface UserManagementParams {
41
42
 
42
43
  canEditRoles?: boolean;
43
44
 
44
- authController: AuthController;
45
-
46
45
  /**
47
46
  * If there are no roles in the database, provide a button to create the default roles.
48
47
  */
@@ -70,7 +69,6 @@ export function useBuildFirestoreUserManagement({
70
69
  rolesPath = "__FIRECMS/config/roles",
71
70
  usersLimit,
72
71
  canEditRoles = true,
73
- authController,
74
72
  allowDefaultRolesCreation,
75
73
  includeCollectionConfigPermissions
76
74
  }: UserManagementParams): UserManagement {
@@ -85,22 +83,13 @@ export function useBuildFirestoreUserManagement({
85
83
  const users = usersWithRoleIds.map(u => ({
86
84
  ...u,
87
85
  roles: roles.filter(r => u.roles?.includes(r.id))
88
- }) as UserWithRoles);
86
+ }) as User);
89
87
 
90
88
  const [rolesError, setRolesError] = React.useState<Error | undefined>();
91
89
  const [usersError, setUsersError] = React.useState<Error | undefined>();
92
90
 
93
91
  const loading = rolesLoading || usersLoading;
94
92
 
95
- const loggedInUser: UserWithRoles | undefined = users.find(u => u.email?.toLowerCase() === authController.user?.email?.toLowerCase());
96
- // console.log("authController", authController);
97
- // if (!loading && !authController.authLoading) {
98
- // const user = authController.user;
99
- // if (user) {
100
- // loggedInUser = users.find(u => u.email?.toLowerCase() === user.email?.toLowerCase());
101
- // }
102
- // }
103
-
104
93
  useEffect(() => {
105
94
  if (!firebaseApp) return;
106
95
  firestoreRef.current = getFirestore(firebaseApp);
@@ -155,16 +144,24 @@ export function useBuildFirestoreUserManagement({
155
144
  );
156
145
  }, [firebaseApp, usersPath]);
157
146
 
158
- const saveUser = useCallback(async (user: UserWithRoles): Promise<UserWithRoles> => {
147
+ const saveUser = useCallback(async (user: User): Promise<User> => {
159
148
  const firestore = firestoreRef.current;
160
149
  if (!firestore || !usersPath) throw Error("useFirestoreConfigurationPersistence Firestore not initialised");
161
150
  console.debug("Persisting user", user);
162
- const roleIds = user.roles.map(r => r.id);
151
+ const roleIds = user.roles?.map(r => r.id);
163
152
  const {
164
153
  uid,
165
154
  ...userData
166
155
  } = user;
167
- return setDoc(doc(firestore, usersPath, uid), { ...userData, roles: roleIds }, { merge: true }).then(() => user);
156
+ const data = {
157
+ ...userData,
158
+ roles: roleIds
159
+ };
160
+ if (uid) {
161
+ return setDoc(doc(firestore, usersPath, uid), data, { merge: true }).then(() => user);
162
+ } else {
163
+ return addDoc(collection(firestore, usersPath), data).then(() => user);
164
+ }
168
165
  }, [usersPath]);
169
166
 
170
167
  const saveRole = useCallback((role: Role): Promise<void> => {
@@ -179,7 +176,7 @@ export function useBuildFirestoreUserManagement({
179
176
  return setDoc(ref, roleData, { merge: true });
180
177
  }, [rolesPath]);
181
178
 
182
- const deleteUser = useCallback(async (user: UserWithRoles): Promise<void> => {
179
+ const deleteUser = useCallback(async (user: User): Promise<void> => {
183
180
  const firestore = firestoreRef.current;
184
181
  if (!firestore || !usersPath) throw Error("useFirestoreConfigurationPersistence Firestore not initialised");
185
182
  console.debug("Deleting", user);
@@ -198,14 +195,45 @@ export function useBuildFirestoreUserManagement({
198
195
 
199
196
  const collectionPermissions: PermissionsBuilder = useCallback(({
200
197
  collection,
198
+ user
201
199
  }) => resolveUserRolePermissions({
202
200
  collection,
203
- user: loggedInUser ?? null
204
- }), [loggedInUser?.uid]);
201
+ user
202
+ }), []);
203
+
204
+ const userIds = users.map(u => u.uid);
205
+ const defineRolesFor: ((user: User) => Role[] | undefined) = useCallback((user) => {
206
+ if (!users) throw Error("Users not loaded");
207
+ const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());
208
+ return mgmtUser?.roles;
209
+ }, [userIds]);
210
+
211
+ const authenticator: Authenticator = useCallback(({ user }) => {
212
+ console.log("Authenticating user", user);
213
+ // return true;"
214
+
215
+ // console.log("authentication", user, userManagement);
216
+ if (loading) {
217
+ console.log("User management is still loading");
218
+ return false;
219
+ }
220
+
221
+ // This is an example of how you can link the access system to the user management plugin
222
+ if (users.length === 0) {
223
+ return true; // If there are no users created yet, we allow access to every user
224
+ }
225
+
226
+ const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());
227
+ if (mgmtUser) {
228
+ // authController.setRoles(mgmtUser.roles ?? [])
229
+ return true;
230
+ }
231
+
232
+ throw Error("Could not find a user with the provided email");
233
+ }, [loading, users])
205
234
 
206
235
  return {
207
236
  loading,
208
- loggedInUser,
209
237
  roles,
210
238
  users,
211
239
  saveUser,
@@ -216,7 +244,9 @@ export function useBuildFirestoreUserManagement({
216
244
  canEditRoles: canEditRoles === undefined ? true : canEditRoles,
217
245
  allowDefaultRolesCreation: allowDefaultRolesCreation === undefined ? true : allowDefaultRolesCreation,
218
246
  includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
219
- collectionPermissions
247
+ collectionPermissions,
248
+ defineRolesFor,
249
+ authenticator
220
250
  }
221
251
  }
222
252
 
@@ -1,5 +1,5 @@
1
1
  import { useContext } from "react";
2
- import { UserManagement } from "../types/user_management";
2
+ import { UserManagement } from "../types";
3
3
  import { UserManagementContext } from "../UserManagementProvider";
4
-
5
- export const useUserManagement = () => useContext<UserManagement>(UserManagementContext);
4
+ import { User } from "@firecms/core";
5
+ export const useUserManagement = <USER extends User>() => useContext<UserManagement<USER>>(UserManagementContext);
@@ -1,3 +1,2 @@
1
- export * from "./firecms_user";
2
- export * from "./roles";
3
1
  export * from "./user_management";
2
+ export * from "./persisted_user";
@@ -0,0 +1,6 @@
1
+ import { User } from "@firecms/core";
2
+
3
+ export type PersistedUser = User & {
4
+ updated_on?: Date;
5
+ created_on?: Date;
6
+ }
@@ -1,18 +1,9 @@
1
- import { UserWithRoles } from "./firecms_user";
2
- import { Role } from "./roles";
3
- import { PermissionsBuilder } from "@firecms/core";
1
+ import { Authenticator, PermissionsBuilder, Role, User } from "@firecms/core";
4
2
 
5
- export type UserManagement<USER extends UserWithRoles = UserWithRoles> = {
3
+ export type UserManagement<USER extends User = User> = {
6
4
 
7
5
  loading: boolean;
8
6
 
9
- /**
10
- * The user currently logged in, in the user management system.
11
- * This is the same user that is logged in the Authenticator, but with the roles
12
- * and permissions loaded.
13
- */
14
- loggedInUser: USER | undefined;
15
-
16
7
  users: USER[];
17
8
  saveUser: (user: USER) => Promise<USER>;
18
9
  deleteUser: (user: USER) => Promise<void>;
@@ -47,4 +38,16 @@ export type UserManagement<USER extends UserWithRoles = UserWithRoles> = {
47
38
  */
48
39
  collectionPermissions: PermissionsBuilder;
49
40
 
41
+ /**
42
+ * Define the roles for a given user. You will typically want to plug this into your auth controller.
43
+ * @param user
44
+ */
45
+ defineRolesFor: (user: User) => Promise<Role[]> | Role[] | undefined;
46
+
47
+ /**
48
+ * You can build an authenticator callback from the current configuration of the user management.
49
+ * It will only allow access to users with the required roles.
50
+ */
51
+ authenticator?: Authenticator;
52
+
50
53
  };
@@ -1,4 +1,4 @@
1
- import { AuthController, FireCMSPlugin } from "@firecms/core";
1
+ import { FireCMSPlugin } from "@firecms/core";
2
2
  import { UserManagementProvider } from "./UserManagementProvider";
3
3
  import { UserManagement } from "./types";
4
4
 
@@ -6,7 +6,7 @@ export function useUserManagementPlugin({ userManagement }: {
6
6
  userManagement: UserManagement,
7
7
  }): FireCMSPlugin {
8
8
  return {
9
- name: "User management plugin",
9
+ key: "user_management",
10
10
  loading: userManagement.loading,
11
11
  provider: {
12
12
  Component: UserManagementProvider,
@@ -1,5 +1,4 @@
1
- import { CMSType, EntityCollection, Permissions } from "@firecms/core";
2
- import { Role, UserWithRoles } from "../types";
1
+ import { EntityCollection, Permissions, Role, User } from "@firecms/core";
3
2
 
4
3
  export const RESERVED_GROUPS = ["Admin"];
5
4
 
@@ -10,8 +9,11 @@ const DEFAULT_PERMISSIONS = {
10
9
  delete: false
11
10
  };
12
11
 
13
- export function resolveUserRolePermissions<UserType extends UserWithRoles>
14
- ({ collection, user }: {
12
+ export function resolveUserRolePermissions<UserType extends User>
13
+ ({
14
+ collection,
15
+ user
16
+ }: {
15
17
  collection: EntityCollection<any>,
16
18
  user: UserType | null
17
19
  }): Permissions {
@@ -66,7 +68,7 @@ const mergePermissions = (permA: Permissions, permB: Permissions) => {
66
68
  };
67
69
  }
68
70
 
69
- export function getUserRoles(roles: Role[], fireCMSUser: UserWithRoles): Role[] | undefined {
71
+ export function getUserRoles(roles: Role[], fireCMSUser: User): Role[] | undefined {
70
72
  return !roles
71
73
  ? undefined
72
74
  : (fireCMSUser.roles
@@ -1,7 +0,0 @@
1
- import { User } from "@firecms/core";
2
- import { Role } from "./roles";
3
- export type UserWithRoles = User & {
4
- updated_on?: Date;
5
- created_on?: Date;
6
- roles: Role[];
7
- };
@@ -1,31 +0,0 @@
1
- import { Permissions } from "@firecms/core";
2
- export type Role = {
3
- /**
4
- * ID of the role
5
- */
6
- id: string;
7
- /**
8
- * Name of the role
9
- */
10
- name: string;
11
- /**
12
- * If this flag is true, the user can perform any action
13
- */
14
- isAdmin?: boolean;
15
- /**
16
- * Default permissions for all collections for this role.
17
- * You can override this values at the collection level using
18
- * {@link collectionPermissions}
19
- */
20
- defaultPermissions?: Permissions;
21
- /**
22
- * Record of stripped collection ids to their permissions.
23
- * @see stripCollectionPath
24
- */
25
- collectionPermissions?: Record<string, Permissions>;
26
- config?: {
27
- createCollections?: boolean;
28
- editCollections?: boolean | "own";
29
- deleteCollections?: boolean | "own";
30
- };
31
- };
@@ -1,8 +0,0 @@
1
- import { User } from "@firecms/core";
2
- import { Role } from "./roles";
3
-
4
- export type UserWithRoles = User & {
5
- updated_on?: Date;
6
- created_on?: Date;
7
- roles: Role[];
8
- }
@@ -1,41 +0,0 @@
1
- import { Permissions } from "@firecms/core";
2
-
3
- export type Role = {
4
-
5
- /**
6
- * ID of the role
7
- */
8
- id: string;
9
-
10
- /**
11
- * Name of the role
12
- */
13
- name: string;
14
-
15
- /**
16
- * If this flag is true, the user can perform any action
17
- */
18
- isAdmin?: boolean;
19
-
20
- /**
21
- * Default permissions for all collections for this role.
22
- * You can override this values at the collection level using
23
- * {@link collectionPermissions}
24
- */
25
- defaultPermissions?: Permissions;
26
-
27
- /**
28
- * Record of stripped collection ids to their permissions.
29
- * @see stripCollectionPath
30
- */
31
- collectionPermissions?: Record<string, Permissions>;
32
-
33
- config?: {
34
-
35
- createCollections?: boolean;
36
-
37
- editCollections?: boolean | "own";
38
-
39
- deleteCollections?: boolean | "own";
40
- }
41
- }