@firecms/user_management 3.0.0-canary.84 → 3.0.0-canary.86
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/index.d.ts +1 -1
- package/dist/hooks/{useFirestoreUserManagement.d.ts → useBuildUserManagement.d.ts} +8 -7
- package/dist/index.es.js +99 -81
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +97 -79
- package/dist/index.umd.js.map +1 -1
- package/package.json +8 -9
- package/src/hooks/index.ts +1 -1
- package/src/hooks/{useFirestoreUserManagement.tsx → useBuildUserManagement.tsx} +115 -97
package/dist/hooks/index.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export * from "./
|
1
|
+
export * from "./useBuildUserManagement";
|
2
2
|
export * from "./useUserManagement";
|
@@ -1,17 +1,16 @@
|
|
1
|
-
import { FirebaseApp } from "@firebase/app";
|
2
1
|
import { UserManagement } from "../types";
|
2
|
+
import { DataSourceDelegate } from "@firecms/core";
|
3
3
|
export interface UserManagementParams {
|
4
4
|
/**
|
5
|
-
* The
|
6
|
-
* collection indicated by `configPath`.
|
5
|
+
* The delegate in charge of persisting the data.
|
7
6
|
*/
|
8
|
-
|
7
|
+
dataSourceDelegate?: DataSourceDelegate;
|
9
8
|
/**
|
10
9
|
* Path where the plugin users configuration is stored.
|
11
10
|
* Default: __FIRECMS/config/users
|
12
11
|
* You can specify a different path if you want to store the user management configuration in a different place.
|
13
12
|
* Please keep in mind that the FireCMS users are not necessarily the same as the Firebase users (but they can be).
|
14
|
-
* The path should be relative to the root of the
|
13
|
+
* The path should be relative to the root of the database, and should always have an odd number of segments.
|
15
14
|
*/
|
16
15
|
usersPath?: string;
|
17
16
|
/**
|
@@ -39,10 +38,12 @@ export interface UserManagementParams {
|
|
39
38
|
/**
|
40
39
|
* This hook is used to build a user management object that can be used to
|
41
40
|
* manage users and roles in a Firestore backend.
|
42
|
-
* @param
|
41
|
+
* @param dataSourceDelegate
|
43
42
|
* @param usersPath
|
44
43
|
* @param rolesPath
|
45
44
|
* @param usersLimit
|
46
45
|
* @param canEditRoles
|
46
|
+
* @param allowDefaultRolesCreation
|
47
|
+
* @param includeCollectionConfigPermissions
|
47
48
|
*/
|
48
|
-
export declare function
|
49
|
+
export declare function useBuildUserManagement({ dataSourceDelegate, usersPath, rolesPath, usersLimit, canEditRoles, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementParams): UserManagement;
|
package/dist/index.es.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import React, { useEffect, useCallback, useContext, useState } from "react";
|
2
|
-
import
|
2
|
+
import equal from "react-fast-compare";
|
3
3
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
4
4
|
import { getColorSchemeForSeed, Chip, Dialog, DialogContent, Typography, TextField, Paper, Table, TableHeader, TableCell, TableBody, TableRow, Tooltip, Checkbox, Select, SelectItem, DialogActions, Button, LoadingButton, DoneIcon, IconButton, DeleteIcon, CenteredView, Container, AddIcon, MultiSelect, MultiSelectItem } from "@firecms/ui";
|
5
5
|
import * as Yup from "yup";
|
@@ -15,13 +15,13 @@ const DEFAULT_PERMISSIONS = {
|
|
15
15
|
delete: false
|
16
16
|
};
|
17
17
|
function resolveUserRolePermissions({
|
18
|
-
collection
|
18
|
+
collection,
|
19
19
|
user
|
20
20
|
}) {
|
21
21
|
const roles = user?.roles;
|
22
22
|
if (!roles) {
|
23
23
|
return DEFAULT_PERMISSIONS;
|
24
|
-
} else if (
|
24
|
+
} else if (collection.ownerId === user?.uid) {
|
25
25
|
return {
|
26
26
|
read: true,
|
27
27
|
create: true,
|
@@ -35,7 +35,7 @@ function resolveUserRolePermissions({
|
|
35
35
|
edit: false,
|
36
36
|
delete: false
|
37
37
|
};
|
38
|
-
return roles.map((role) => resolveCollectionRole(role,
|
38
|
+
return roles.map((role) => resolveCollectionRole(role, collection.id)).reduce(mergePermissions, basePermissions);
|
39
39
|
}
|
40
40
|
}
|
41
41
|
function resolveCollectionRole(role, id) {
|
@@ -140,8 +140,8 @@ function hexToRgbaWithOpacity(hexColor, opacity = 10) {
|
|
140
140
|
const alpha = opacity / 100;
|
141
141
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
142
142
|
}
|
143
|
-
function
|
144
|
-
|
143
|
+
function useBuildUserManagement({
|
144
|
+
dataSourceDelegate,
|
145
145
|
usersPath = "__FIRECMS/config/users",
|
146
146
|
rolesPath = "__FIRECMS/config/roles",
|
147
147
|
usersLimit,
|
@@ -161,59 +161,56 @@ function useFirestoreUserManagement({
|
|
161
161
|
const [usersError, setUsersError] = React.useState();
|
162
162
|
const loading = rolesLoading || usersLoading;
|
163
163
|
useEffect(() => {
|
164
|
-
if (!
|
165
|
-
|
166
|
-
return
|
167
|
-
|
168
|
-
{
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
164
|
+
if (!dataSourceDelegate || !rolesPath) return;
|
165
|
+
if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
|
166
|
+
return dataSourceDelegate.listenCollection?.({
|
167
|
+
path: rolesPath,
|
168
|
+
onUpdate(entities) {
|
169
|
+
setRolesError(void 0);
|
170
|
+
try {
|
171
|
+
const newRoles = entityToRoles(entities);
|
172
|
+
if (!equal(newRoles, roles))
|
173
173
|
setRoles(newRoles);
|
174
|
-
|
175
|
-
console.error("Error loading roles", e);
|
176
|
-
setRolesError(e);
|
177
|
-
}
|
178
|
-
setRolesLoading(false);
|
179
|
-
},
|
180
|
-
error: (e) => {
|
174
|
+
} catch (e) {
|
181
175
|
console.error("Error loading roles", e);
|
182
176
|
setRolesError(e);
|
183
|
-
setRolesLoading(false);
|
184
177
|
}
|
178
|
+
setRolesLoading(false);
|
179
|
+
},
|
180
|
+
onError(e) {
|
181
|
+
console.error("Error loading roles", e);
|
182
|
+
setRolesError(e);
|
183
|
+
setRolesLoading(false);
|
185
184
|
}
|
186
|
-
);
|
187
|
-
}, [
|
185
|
+
});
|
186
|
+
}, [dataSourceDelegate, rolesPath]);
|
188
187
|
useEffect(() => {
|
189
|
-
if (!
|
190
|
-
|
191
|
-
return
|
192
|
-
|
193
|
-
{
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
188
|
+
if (!dataSourceDelegate || !usersPath) return;
|
189
|
+
if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
|
190
|
+
return dataSourceDelegate.listenCollection?.({
|
191
|
+
path: usersPath,
|
192
|
+
onUpdate(entities) {
|
193
|
+
setUsersError(void 0);
|
194
|
+
try {
|
195
|
+
const newUsers = entitiesToUsers(entities);
|
196
|
+
if (!equal(newUsers, usersWithRoleIds))
|
198
197
|
setUsersWithRoleIds(newUsers);
|
199
|
-
|
200
|
-
console.error("Error loading users", e);
|
201
|
-
setUsersError(e);
|
202
|
-
}
|
203
|
-
setUsersLoading(false);
|
204
|
-
},
|
205
|
-
error: (e) => {
|
198
|
+
} catch (e) {
|
206
199
|
console.error("Error loading users", e);
|
207
200
|
setUsersError(e);
|
208
|
-
setUsersLoading(false);
|
209
201
|
}
|
202
|
+
setUsersLoading(false);
|
203
|
+
},
|
204
|
+
onError(e) {
|
205
|
+
console.error("Error loading users", e);
|
206
|
+
setUsersError(e);
|
207
|
+
setUsersLoading(false);
|
210
208
|
}
|
211
|
-
);
|
212
|
-
}, [
|
209
|
+
});
|
210
|
+
}, [dataSourceDelegate, usersPath]);
|
213
211
|
const saveUser = useCallback(async (user) => {
|
214
|
-
if (!
|
215
|
-
|
216
|
-
if (!firestore || !usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
212
|
+
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
213
|
+
if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
|
217
214
|
console.debug("Persisting user", user);
|
218
215
|
const roleIds = user.roles?.map((r) => r.id);
|
219
216
|
const {
|
@@ -225,45 +222,66 @@ function useFirestoreUserManagement({
|
|
225
222
|
roles: roleIds
|
226
223
|
};
|
227
224
|
if (uid) {
|
228
|
-
return
|
225
|
+
return dataSourceDelegate.saveEntity({
|
226
|
+
status: "existing",
|
227
|
+
path: usersPath,
|
228
|
+
entityId: uid,
|
229
|
+
values: data
|
230
|
+
}).then(() => user);
|
229
231
|
} else {
|
230
|
-
return
|
232
|
+
return dataSourceDelegate.saveEntity({
|
233
|
+
status: "new",
|
234
|
+
path: usersPath,
|
235
|
+
values: data
|
236
|
+
}).then(() => user);
|
231
237
|
}
|
232
|
-
}, [usersPath,
|
238
|
+
}, [usersPath, dataSourceDelegate]);
|
233
239
|
const saveRole = useCallback((role) => {
|
234
|
-
if (!
|
235
|
-
|
236
|
-
if (!firestore || !rolesPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
240
|
+
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
241
|
+
if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
|
237
242
|
console.debug("Persisting role", role);
|
238
243
|
const {
|
239
244
|
id,
|
240
245
|
...roleData
|
241
246
|
} = role;
|
242
|
-
|
243
|
-
|
244
|
-
|
247
|
+
return dataSourceDelegate.saveEntity({
|
248
|
+
status: "existing",
|
249
|
+
path: rolesPath,
|
250
|
+
entityId: id,
|
251
|
+
values: roleData
|
252
|
+
}).then(() => {
|
253
|
+
return;
|
254
|
+
});
|
255
|
+
}, [rolesPath, dataSourceDelegate]);
|
245
256
|
const deleteUser = useCallback(async (user) => {
|
246
|
-
if (!
|
247
|
-
|
248
|
-
if (!firestore || !usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
257
|
+
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
258
|
+
if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
|
249
259
|
console.debug("Deleting", user);
|
250
260
|
const { uid } = user;
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
261
|
+
const entity = {
|
262
|
+
path: usersPath,
|
263
|
+
id: uid,
|
264
|
+
values: {}
|
265
|
+
};
|
266
|
+
await dataSourceDelegate.deleteEntity({ entity });
|
267
|
+
}, [usersPath, dataSourceDelegate]);
|
268
|
+
const deleteRole = useCallback(async (role) => {
|
269
|
+
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
270
|
+
if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
|
257
271
|
console.debug("Deleting", role);
|
258
272
|
const { id } = role;
|
259
|
-
const
|
260
|
-
|
261
|
-
|
273
|
+
const entity = {
|
274
|
+
path: usersPath,
|
275
|
+
id,
|
276
|
+
values: {}
|
277
|
+
};
|
278
|
+
await dataSourceDelegate.deleteEntity({ entity });
|
279
|
+
}, [rolesPath, dataSourceDelegate]);
|
262
280
|
const collectionPermissions = useCallback(({
|
263
|
-
collection
|
281
|
+
collection,
|
264
282
|
user
|
265
283
|
}) => resolveUserRolePermissions({
|
266
|
-
collection
|
284
|
+
collection,
|
267
285
|
user
|
268
286
|
}), []);
|
269
287
|
const defineRolesFor = useCallback((user) => {
|
@@ -307,22 +325,22 @@ function useFirestoreUserManagement({
|
|
307
325
|
authenticator
|
308
326
|
};
|
309
327
|
}
|
310
|
-
const
|
311
|
-
return docs.map((
|
312
|
-
const data =
|
328
|
+
const entitiesToUsers = (docs) => {
|
329
|
+
return docs.map((doc) => {
|
330
|
+
const data = doc.values;
|
313
331
|
const newVar = {
|
314
|
-
uid:
|
332
|
+
uid: doc.id,
|
315
333
|
...data,
|
316
|
-
created_on: data?.created_on
|
317
|
-
updated_on: data?.updated_on
|
334
|
+
created_on: data?.created_on,
|
335
|
+
updated_on: data?.updated_on
|
318
336
|
};
|
319
337
|
return newVar;
|
320
338
|
});
|
321
339
|
};
|
322
|
-
const
|
323
|
-
return
|
324
|
-
id:
|
325
|
-
...
|
340
|
+
const entityToRoles = (entities) => {
|
341
|
+
return entities.map((doc) => ({
|
342
|
+
id: doc.id,
|
343
|
+
...doc.values
|
326
344
|
}));
|
327
345
|
};
|
328
346
|
const UserManagementContext = React.createContext({});
|
@@ -1519,7 +1537,7 @@ export {
|
|
1519
1537
|
getUserRoles,
|
1520
1538
|
hexToRgbaWithOpacity,
|
1521
1539
|
resolveUserRolePermissions,
|
1522
|
-
|
1540
|
+
useBuildUserManagement,
|
1523
1541
|
useUserManagement,
|
1524
1542
|
useUserManagementPlugin,
|
1525
1543
|
userManagementAdminViews
|