@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.
- package/dist/hooks/useBuildUserManagement.d.ts +5 -3
- package/dist/index.es.js +43 -25
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +43 -25
- 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 +5 -5
- package/src/components/roles/RolesDetailsForm.tsx +1 -0
- package/src/components/users/UsersTable.tsx +0 -2
- package/src/hooks/useBuildUserManagement.tsx +91 -42
- package/src/types/user_management.tsx +2 -6
- package/src/useUserManagementPlugin.tsx +6 -6
- package/src/utils/permissions.ts +2 -2
@@ -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
|
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 (
|
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,
|
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)
|
198
|
-
|
199
|
-
|
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
|
-
|
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,
|
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 (!
|
298
|
-
const
|
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
|
-
}, [
|
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
|
316
|
-
const
|
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-
|
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." }),
|