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

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",
@@ -160,14 +161,13 @@ function useBuildUserManagement({
160
161
  }));
161
162
  const [rolesError, setRolesError] = React.useState();
162
163
  const [usersError, setUsersError] = React.useState();
163
- const loading = rolesLoading || usersLoading;
164
+ const _usersLoading = usersLoading;
165
+ const _rolesLoading = rolesLoading;
166
+ const loading = _rolesLoading || _usersLoading;
164
167
  useEffect(() => {
165
168
  if (!dataSourceDelegate || !rolesPath) return;
166
169
  if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
167
- if (dataSourceDelegate.authenticated !== void 0 && !dataSourceDelegate.authenticated) {
168
- setRolesLoading(false);
169
- return;
170
- }
170
+ if (authController?.initialLoading) return;
171
171
  setRolesLoading(true);
172
172
  return dataSourceDelegate.listenCollection?.({
173
173
  path: rolesPath,
@@ -175,8 +175,9 @@ function useBuildUserManagement({
175
175
  setRolesError(void 0);
176
176
  try {
177
177
  const newRoles = entityToRoles(entities);
178
- if (!equal(newRoles, roles))
178
+ if (!equal(newRoles, roles)) {
179
179
  setRoles(newRoles);
180
+ }
180
181
  } catch (e) {
181
182
  setRoles([]);
182
183
  console.error("Error loading roles", e);
@@ -191,23 +192,24 @@ function useBuildUserManagement({
191
192
  setRolesLoading(false);
192
193
  }
193
194
  });
194
- }, [dataSourceDelegate?.initialised, dataSourceDelegate?.authenticated, rolesPath]);
195
+ }, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, rolesPath]);
195
196
  useEffect(() => {
196
197
  if (!dataSourceDelegate || !usersPath) return;
197
- if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
198
- if (dataSourceDelegate.authenticated !== void 0 && !dataSourceDelegate.authenticated) {
199
- setUsersLoading(false);
198
+ if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) {
199
+ return;
200
+ }
201
+ if (authController?.initialLoading) {
200
202
  return;
201
203
  }
202
204
  setUsersLoading(true);
203
205
  return dataSourceDelegate.listenCollection?.({
204
206
  path: usersPath,
205
207
  onUpdate(entities) {
208
+ console.debug("Updating users", entities);
206
209
  setUsersError(void 0);
207
210
  try {
208
211
  const newUsers = entitiesToUsers(entities);
209
- if (!equal(newUsers, usersWithRoleIds))
210
- setUsersWithRoleIds(newUsers);
212
+ setUsersWithRoleIds(newUsers);
211
213
  } catch (e) {
212
214
  setUsersWithRoleIds([]);
213
215
  console.error("Error loading users", e);
@@ -216,13 +218,13 @@ function useBuildUserManagement({
216
218
  setUsersLoading(false);
217
219
  },
218
220
  onError(e) {
219
- setUsersWithRoleIds([]);
220
221
  console.error("Error loading users", e);
222
+ setUsersWithRoleIds([]);
221
223
  setUsersError(e);
222
224
  setUsersLoading(false);
223
225
  }
224
226
  });
225
- }, [dataSourceDelegate?.initialised, dataSourceDelegate?.authenticated, usersPath]);
227
+ }, [dataSourceDelegate?.initialised, authController?.initialLoading, authController?.user?.uid, usersPath]);
226
228
  const saveUser = useCallback(async (user) => {
227
229
  if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
228
230
  if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
@@ -294,26 +296,36 @@ function useBuildUserManagement({
294
296
  user
295
297
  }), []);
296
298
  const defineRolesFor = useCallback((user) => {
297
- if (!users) throw Error("Users not loaded");
298
- const mgmtUser = users.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
299
+ if (!usersWithRoleIds) throw Error("Users not loaded");
300
+ const users2 = usersWithRoleIds.map((u) => ({
301
+ ...u,
302
+ roles: roles.filter((r) => u.roles?.includes(r.id))
303
+ }));
304
+ const mgmtUser = users2.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
299
305
  return mgmtUser?.roles;
300
- }, [users]);
306
+ }, [roles, usersWithRoleIds]);
307
+ console.debug({
308
+ loading,
309
+ users,
310
+ usersError
311
+ });
301
312
  const authenticator = useCallback(({ user }) => {
302
- console.debug("Authenticating user", user);
303
313
  if (loading) {
304
- console.warn("User management is still loading");
305
314
  return false;
306
315
  }
307
316
  if (users.length === 0) {
317
+ console.warn("No users created yet");
308
318
  return true;
309
319
  }
310
320
  const mgmtUser = users.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
311
321
  if (mgmtUser) {
322
+ console.debug("User found in user management system", mgmtUser);
312
323
  return true;
313
324
  }
314
325
  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");
326
+ }, [loading, users]);
327
+ const userRoles = authController.user ? defineRolesFor(authController.user) : void 0;
328
+ const isAdmin = (userRoles ?? []).some((r) => r.id === "admin");
317
329
  return {
318
330
  loading,
319
331
  roles,
@@ -331,7 +343,14 @@ function useBuildUserManagement({
331
343
  includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
332
344
  collectionPermissions,
333
345
  defineRolesFor,
334
- authenticator
346
+ authenticator,
347
+ ...authController,
348
+ initialLoading: authController.initialLoading || loading,
349
+ userRoles,
350
+ user: authController.user ? {
351
+ ...authController.user,
352
+ roles: userRoles
353
+ } : null
335
354
  };
336
355
  }
337
356
  const entitiesToUsers = (docs) => {
@@ -386,6 +405,7 @@ const RoleYupSchema = Yup.object().shape({
386
405
  });
387
406
  function canRoleBeEdited(loggedUser) {
388
407
  const loggedUserIsAdmin = loggedUser.roles?.map((r) => r.id).includes("admin");
408
+ console.log("loggedUserIsAdmin", loggedUser);
389
409
  if (!loggedUserIsAdmin) {
390
410
  throw new Error("Only admins can edit roles");
391
411
  }
@@ -1328,7 +1348,6 @@ function UsersTable({ onUserClicked }) {
1328
1348
  /* @__PURE__ */ jsxs(Table, { className: "w-full", children: [
1329
1349
  /* @__PURE__ */ jsxs(TableHeader, { children: [
1330
1350
  /* @__PURE__ */ jsx(TableCell, { className: "truncate w-16" }),
1331
- /* @__PURE__ */ jsx(TableCell, { children: "ID" }),
1332
1351
  /* @__PURE__ */ jsx(TableCell, { children: "Email" }),
1333
1352
  /* @__PURE__ */ jsx(TableCell, { children: "Name" }),
1334
1353
  /* @__PURE__ */ jsx(TableCell, { children: "Roles" }),
@@ -1363,7 +1382,6 @@ function UsersTable({ onUserClicked }) {
1363
1382
  )
1364
1383
  }
1365
1384
  ) }),
1366
- /* @__PURE__ */ jsx(TableCell, { children: user.uid }),
1367
1385
  /* @__PURE__ */ jsx(TableCell, { children: user.email }),
1368
1386
  /* @__PURE__ */ jsx(TableCell, { className: "font-medium align-left", children: user.displayName }),
1369
1387
  /* @__PURE__ */ jsx(TableCell, { className: "align-left", children: userRoles ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: userRoles.map(
@@ -1531,7 +1549,7 @@ function IntroWidget({
1531
1549
  return /* @__PURE__ */ jsxs(
1532
1550
  Paper,
1533
1551
  {
1534
- className: "my-4 flex flex-col px-4 py-6 bg-white dark:bg-slate-800 gap-2",
1552
+ className: "my-4 flex flex-col px-4 py-6 bg-white dark:bg-surface-accent-800 gap-2",
1535
1553
  children: [
1536
1554
  /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", className: "uppercase", children: "Create your users and roles" }),
1537
1555
  /* @__PURE__ */ jsx(Typography, { children: "You have no users or roles defined. You can create default roles and add the current user as admin." }),