@firecms/user_management 3.0.0-canary.144 → 3.0.0-canary.146

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,6 +1,7 @@
1
1
  import { UserManagement } from "../types";
2
- import { DataSourceDelegate } from "@firecms/core";
3
- export interface UserManagementParams {
2
+ import { AuthController, DataSourceDelegate, User } from "@firecms/core";
3
+ export interface UserManagementParams<CONTROLLER extends AuthController<any> = AuthController<any>, USER extends User = CONTROLLER extends AuthController<infer U> ? U : any> {
4
+ authController: CONTROLLER;
4
5
  /**
5
6
  * The delegate in charge of persisting the data.
6
7
  */
@@ -38,6 +39,7 @@ export interface UserManagementParams {
38
39
  /**
39
40
  * This hook is used to build a user management object that can be used to
40
41
  * manage users and roles in a Firestore backend.
42
+ * @param authController
41
43
  * @param dataSourceDelegate
42
44
  * @param usersPath
43
45
  * @param rolesPath
@@ -46,4 +48,4 @@ export interface UserManagementParams {
46
48
  * @param allowDefaultRolesCreation
47
49
  * @param includeCollectionConfigPermissions
48
50
  */
49
- export declare function useBuildUserManagement({ dataSourceDelegate, usersPath, rolesPath, usersLimit, canEditRoles, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementParams): UserManagement;
51
+ export declare function useBuildUserManagement<CONTROLLER extends AuthController<any> = AuthController<any>, USER extends User = CONTROLLER extends AuthController<infer U> ? U : any>({ authController, dataSourceDelegate, usersPath, rolesPath, usersLimit, canEditRoles, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementParams<CONTROLLER, USER>): UserManagement<USER> & CONTROLLER;
package/dist/index.es.js CHANGED
@@ -142,6 +142,7 @@ function hexToRgbaWithOpacity(hexColor, opacity = 10) {
142
142
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
143
143
  }
144
144
  function useBuildUserManagement({
145
+ authController,
145
146
  dataSourceDelegate,
146
147
  usersPath = "__FIRECMS/config/users",
147
148
  rolesPath = "__FIRECMS/config/roles",
@@ -150,6 +151,9 @@ function useBuildUserManagement({
150
151
  allowDefaultRolesCreation,
151
152
  includeCollectionConfigPermissions
152
153
  }) {
154
+ if (!authController) {
155
+ 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");
156
+ }
153
157
  const [rolesLoading, setRolesLoading] = React.useState(true);
154
158
  const [usersLoading, setUsersLoading] = React.useState(true);
155
159
  const [roles, setRoles] = React.useState([]);
@@ -160,14 +164,13 @@ function useBuildUserManagement({
160
164
  }));
161
165
  const [rolesError, setRolesError] = React.useState();
162
166
  const [usersError, setUsersError] = React.useState();
163
- const loading = rolesLoading || usersLoading;
167
+ const _usersLoading = usersLoading;
168
+ const _rolesLoading = rolesLoading;
169
+ const loading = _rolesLoading || _usersLoading;
164
170
  useEffect(() => {
165
171
  if (!dataSourceDelegate || !rolesPath) return;
166
172
  if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
167
- if (dataSourceDelegate.authenticated !== void 0 && !dataSourceDelegate.authenticated) {
168
- setRolesLoading(false);
169
- return;
170
- }
173
+ if (authController?.initialLoading) return;
171
174
  setRolesLoading(true);
172
175
  return dataSourceDelegate.listenCollection?.({
173
176
  path: rolesPath,
@@ -175,8 +178,9 @@ function useBuildUserManagement({
175
178
  setRolesError(void 0);
176
179
  try {
177
180
  const newRoles = entityToRoles(entities);
178
- if (!equal(newRoles, roles))
181
+ if (!equal(newRoles, roles)) {
179
182
  setRoles(newRoles);
183
+ }
180
184
  } catch (e) {
181
185
  setRoles([]);
182
186
  console.error("Error loading roles", e);
@@ -191,23 +195,24 @@ function useBuildUserManagement({
191
195
  setRolesLoading(false);
192
196
  }
193
197
  });
194
- }, [dataSourceDelegate?.initialised, dataSourceDelegate?.authenticated, rolesPath]);
198
+ }, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, rolesPath]);
195
199
  useEffect(() => {
196
200
  if (!dataSourceDelegate || !usersPath) return;
197
- if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
198
- if (dataSourceDelegate.authenticated !== void 0 && !dataSourceDelegate.authenticated) {
199
- setUsersLoading(false);
201
+ if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) {
202
+ return;
203
+ }
204
+ if (authController?.initialLoading) {
200
205
  return;
201
206
  }
202
207
  setUsersLoading(true);
203
208
  return dataSourceDelegate.listenCollection?.({
204
209
  path: usersPath,
205
210
  onUpdate(entities) {
211
+ console.debug("Updating users", entities);
206
212
  setUsersError(void 0);
207
213
  try {
208
214
  const newUsers = entitiesToUsers(entities);
209
- if (!equal(newUsers, usersWithRoleIds))
210
- setUsersWithRoleIds(newUsers);
215
+ setUsersWithRoleIds(newUsers);
211
216
  } catch (e) {
212
217
  setUsersWithRoleIds([]);
213
218
  console.error("Error loading users", e);
@@ -216,13 +221,13 @@ function useBuildUserManagement({
216
221
  setUsersLoading(false);
217
222
  },
218
223
  onError(e) {
219
- setUsersWithRoleIds([]);
220
224
  console.error("Error loading users", e);
225
+ setUsersWithRoleIds([]);
221
226
  setUsersError(e);
222
227
  setUsersLoading(false);
223
228
  }
224
229
  });
225
- }, [dataSourceDelegate?.initialised, dataSourceDelegate?.authenticated, usersPath]);
230
+ }, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, usersPath]);
226
231
  const saveUser = useCallback(async (user) => {
227
232
  if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
228
233
  if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
@@ -294,26 +299,31 @@ function useBuildUserManagement({
294
299
  user
295
300
  }), []);
296
301
  const defineRolesFor = useCallback((user) => {
297
- if (!users) throw Error("Users not loaded");
298
- const mgmtUser = users.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
302
+ if (!usersWithRoleIds) throw Error("Users not loaded");
303
+ const users2 = usersWithRoleIds.map((u) => ({
304
+ ...u,
305
+ roles: roles.filter((r) => u.roles?.includes(r.id))
306
+ }));
307
+ const mgmtUser = users2.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
299
308
  return mgmtUser?.roles;
300
- }, [users]);
309
+ }, [roles, usersWithRoleIds]);
301
310
  const authenticator = useCallback(({ user }) => {
302
- console.debug("Authenticating user", user);
303
311
  if (loading) {
304
- console.warn("User management is still loading");
305
312
  return false;
306
313
  }
307
314
  if (users.length === 0) {
315
+ console.warn("No users created yet");
308
316
  return true;
309
317
  }
310
318
  const mgmtUser = users.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
311
319
  if (mgmtUser) {
320
+ console.debug("User found in user management system", mgmtUser);
312
321
  return true;
313
322
  }
314
323
  throw Error("Could not find a user with the provided email in the user management system.");
315
- }, [loading, users, usersError, rolesError]);
316
- const isAdmin = roles.some((r) => r.id === "admin");
324
+ }, [loading, users]);
325
+ const userRoles = authController.user ? defineRolesFor(authController.user) : void 0;
326
+ const isAdmin = (userRoles ?? []).some((r) => r.id === "admin");
317
327
  return {
318
328
  loading,
319
329
  roles,
@@ -331,7 +341,14 @@ function useBuildUserManagement({
331
341
  includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
332
342
  collectionPermissions,
333
343
  defineRolesFor,
334
- authenticator
344
+ authenticator,
345
+ ...authController,
346
+ initialLoading: authController.initialLoading || loading,
347
+ userRoles,
348
+ user: authController.user ? {
349
+ ...authController.user,
350
+ roles: userRoles
351
+ } : null
335
352
  };
336
353
  }
337
354
  const entitiesToUsers = (docs) => {
@@ -386,6 +403,7 @@ const RoleYupSchema = Yup.object().shape({
386
403
  });
387
404
  function canRoleBeEdited(loggedUser) {
388
405
  const loggedUserIsAdmin = loggedUser.roles?.map((r) => r.id).includes("admin");
406
+ console.log("loggedUserIsAdmin", loggedUser);
389
407
  if (!loggedUserIsAdmin) {
390
408
  throw new Error("Only admins can edit roles");
391
409
  }
@@ -1328,7 +1346,6 @@ function UsersTable({ onUserClicked }) {
1328
1346
  /* @__PURE__ */ jsxs(Table, { className: "w-full", children: [
1329
1347
  /* @__PURE__ */ jsxs(TableHeader, { children: [
1330
1348
  /* @__PURE__ */ jsx(TableCell, { className: "truncate w-16" }),
1331
- /* @__PURE__ */ jsx(TableCell, { children: "ID" }),
1332
1349
  /* @__PURE__ */ jsx(TableCell, { children: "Email" }),
1333
1350
  /* @__PURE__ */ jsx(TableCell, { children: "Name" }),
1334
1351
  /* @__PURE__ */ jsx(TableCell, { children: "Roles" }),
@@ -1363,7 +1380,6 @@ function UsersTable({ onUserClicked }) {
1363
1380
  )
1364
1381
  }
1365
1382
  ) }),
1366
- /* @__PURE__ */ jsx(TableCell, { children: user.uid }),
1367
1383
  /* @__PURE__ */ jsx(TableCell, { children: user.email }),
1368
1384
  /* @__PURE__ */ jsx(TableCell, { className: "font-medium align-left", children: user.displayName }),
1369
1385
  /* @__PURE__ */ jsx(TableCell, { className: "align-left", children: userRoles ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: userRoles.map(
@@ -1531,7 +1547,7 @@ function IntroWidget({
1531
1547
  return /* @__PURE__ */ jsxs(
1532
1548
  Paper,
1533
1549
  {
1534
- className: "my-4 flex flex-col px-4 py-6 bg-white dark:bg-slate-800 gap-2",
1550
+ className: "my-4 flex flex-col px-4 py-6 bg-white dark:bg-surface-accent-800 gap-2",
1535
1551
  children: [
1536
1552
  /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", className: "uppercase", children: "Create your users and roles" }),
1537
1553
  /* @__PURE__ */ jsx(Typography, { children: "You have no users or roles defined. You can create default roles and add the current user as admin." }),