@firecms/user_management 3.0.0-canary.83 → 3.0.0-canary.85
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} +6 -7
- package/dist/index.es.js +96 -83
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +95 -81
- 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} +102 -92
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,10 @@ 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
|
47
46
|
*/
|
48
|
-
export declare function
|
47
|
+
export declare function useBuildUserManagement({ dataSourceDelegate, usersPath, rolesPath, usersLimit, canEditRoles, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementParams): UserManagement;
|
package/dist/index.es.js
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import React, { useEffect, useCallback, useContext, useState } from "react";
|
2
|
-
import { getFirestore, onSnapshot, collection, setDoc, doc, addDoc, deleteDoc } from "@firebase/firestore";
|
3
2
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
4
3
|
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
4
|
import * as Yup from "yup";
|
@@ -15,13 +14,13 @@ const DEFAULT_PERMISSIONS = {
|
|
15
14
|
delete: false
|
16
15
|
};
|
17
16
|
function resolveUserRolePermissions({
|
18
|
-
collection
|
17
|
+
collection,
|
19
18
|
user
|
20
19
|
}) {
|
21
20
|
const roles = user?.roles;
|
22
21
|
if (!roles) {
|
23
22
|
return DEFAULT_PERMISSIONS;
|
24
|
-
} else if (
|
23
|
+
} else if (collection.ownerId === user?.uid) {
|
25
24
|
return {
|
26
25
|
read: true,
|
27
26
|
create: true,
|
@@ -35,7 +34,7 @@ function resolveUserRolePermissions({
|
|
35
34
|
edit: false,
|
36
35
|
delete: false
|
37
36
|
};
|
38
|
-
return roles.map((role) => resolveCollectionRole(role,
|
37
|
+
return roles.map((role) => resolveCollectionRole(role, collection.id)).reduce(mergePermissions, basePermissions);
|
39
38
|
}
|
40
39
|
}
|
41
40
|
function resolveCollectionRole(role, id) {
|
@@ -140,8 +139,8 @@ function hexToRgbaWithOpacity(hexColor, opacity = 10) {
|
|
140
139
|
const alpha = opacity / 100;
|
141
140
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
142
141
|
}
|
143
|
-
function
|
144
|
-
|
142
|
+
function useBuildUserManagement({
|
143
|
+
dataSourceDelegate,
|
145
144
|
usersPath = "__FIRECMS/config/users",
|
146
145
|
rolesPath = "__FIRECMS/config/roles",
|
147
146
|
usersLimit,
|
@@ -161,59 +160,52 @@ function useFirestoreUserManagement({
|
|
161
160
|
const [usersError, setUsersError] = React.useState();
|
162
161
|
const loading = rolesLoading || usersLoading;
|
163
162
|
useEffect(() => {
|
164
|
-
if (!
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
setRoles(newRoles);
|
174
|
-
} catch (e) {
|
175
|
-
console.error("Error loading roles", e);
|
176
|
-
setRolesError(e);
|
177
|
-
}
|
178
|
-
setRolesLoading(false);
|
179
|
-
},
|
180
|
-
error: (e) => {
|
163
|
+
if (!dataSourceDelegate || !rolesPath) return;
|
164
|
+
dataSourceDelegate.listenCollection?.({
|
165
|
+
path: rolesPath,
|
166
|
+
onUpdate(entities) {
|
167
|
+
setRolesError(void 0);
|
168
|
+
try {
|
169
|
+
const newRoles = entityToRoles(entities);
|
170
|
+
setRoles(newRoles);
|
171
|
+
} catch (e) {
|
181
172
|
console.error("Error loading roles", e);
|
182
173
|
setRolesError(e);
|
183
|
-
setRolesLoading(false);
|
184
174
|
}
|
175
|
+
setRolesLoading(false);
|
176
|
+
},
|
177
|
+
onError(e) {
|
178
|
+
console.error("Error loading roles", e);
|
179
|
+
setRolesError(e);
|
180
|
+
setRolesLoading(false);
|
185
181
|
}
|
186
|
-
);
|
187
|
-
}, [
|
182
|
+
});
|
183
|
+
}, [dataSourceDelegate, rolesPath]);
|
188
184
|
useEffect(() => {
|
189
|
-
if (!
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
setUsersWithRoleIds(newUsers);
|
199
|
-
} catch (e) {
|
200
|
-
console.error("Error loading users", e);
|
201
|
-
setUsersError(e);
|
202
|
-
}
|
203
|
-
setUsersLoading(false);
|
204
|
-
},
|
205
|
-
error: (e) => {
|
185
|
+
if (!dataSourceDelegate || !usersPath) return;
|
186
|
+
dataSourceDelegate.listenCollection?.({
|
187
|
+
path: usersPath,
|
188
|
+
onUpdate(entities) {
|
189
|
+
setUsersError(void 0);
|
190
|
+
try {
|
191
|
+
const newUsers = entitiesToUsers(entities);
|
192
|
+
setUsersWithRoleIds(newUsers);
|
193
|
+
} catch (e) {
|
206
194
|
console.error("Error loading users", e);
|
207
195
|
setUsersError(e);
|
208
|
-
setUsersLoading(false);
|
209
196
|
}
|
197
|
+
setUsersLoading(false);
|
198
|
+
},
|
199
|
+
onError(e) {
|
200
|
+
console.error("Error loading users", e);
|
201
|
+
setUsersError(e);
|
202
|
+
setUsersLoading(false);
|
210
203
|
}
|
211
|
-
);
|
212
|
-
}, [
|
204
|
+
});
|
205
|
+
}, [dataSourceDelegate, usersPath]);
|
213
206
|
const saveUser = useCallback(async (user) => {
|
214
|
-
if (!
|
215
|
-
|
216
|
-
if (!firestore || !usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
207
|
+
if (!dataSourceDelegate) throw Error("useFirestoreUserManagement Firebase not initialised");
|
208
|
+
if (!usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
217
209
|
console.debug("Persisting user", user);
|
218
210
|
const roleIds = user.roles?.map((r) => r.id);
|
219
211
|
const {
|
@@ -225,45 +217,66 @@ function useFirestoreUserManagement({
|
|
225
217
|
roles: roleIds
|
226
218
|
};
|
227
219
|
if (uid) {
|
228
|
-
return
|
220
|
+
return dataSourceDelegate.saveEntity({
|
221
|
+
status: "existing",
|
222
|
+
path: usersPath,
|
223
|
+
entityId: uid,
|
224
|
+
values: data
|
225
|
+
}).then(() => user);
|
229
226
|
} else {
|
230
|
-
return
|
227
|
+
return dataSourceDelegate.saveEntity({
|
228
|
+
status: "new",
|
229
|
+
path: usersPath,
|
230
|
+
values: data
|
231
|
+
}).then(() => user);
|
231
232
|
}
|
232
|
-
}, [usersPath,
|
233
|
+
}, [usersPath, dataSourceDelegate]);
|
233
234
|
const saveRole = useCallback((role) => {
|
234
|
-
if (!
|
235
|
-
|
236
|
-
if (!firestore || !rolesPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
235
|
+
if (!dataSourceDelegate) throw Error("useFirestoreUserManagement Firebase not initialised");
|
236
|
+
if (!rolesPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
237
237
|
console.debug("Persisting role", role);
|
238
238
|
const {
|
239
239
|
id,
|
240
240
|
...roleData
|
241
241
|
} = role;
|
242
|
-
|
243
|
-
|
244
|
-
|
242
|
+
return dataSourceDelegate.saveEntity({
|
243
|
+
status: "existing",
|
244
|
+
path: rolesPath,
|
245
|
+
entityId: id,
|
246
|
+
values: roleData
|
247
|
+
}).then(() => {
|
248
|
+
return;
|
249
|
+
});
|
250
|
+
}, [rolesPath, dataSourceDelegate]);
|
245
251
|
const deleteUser = useCallback(async (user) => {
|
246
|
-
if (!
|
247
|
-
|
248
|
-
if (!firestore || !usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
252
|
+
if (!dataSourceDelegate) throw Error("useFirestoreUserManagement Firebase not initialised");
|
253
|
+
if (!usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
249
254
|
console.debug("Deleting", user);
|
250
255
|
const { uid } = user;
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
256
|
+
const entity = {
|
257
|
+
path: usersPath,
|
258
|
+
id: uid,
|
259
|
+
values: {}
|
260
|
+
};
|
261
|
+
await dataSourceDelegate.deleteEntity({ entity });
|
262
|
+
}, [usersPath, dataSourceDelegate]);
|
263
|
+
const deleteRole = useCallback(async (role) => {
|
264
|
+
if (!dataSourceDelegate) throw Error("useFirestoreUserManagement Firebase not initialised");
|
265
|
+
if (!rolesPath) throw Error("useFirestoreUserManagement Firestore not initialised");
|
257
266
|
console.debug("Deleting", role);
|
258
267
|
const { id } = role;
|
259
|
-
const
|
260
|
-
|
261
|
-
|
268
|
+
const entity = {
|
269
|
+
path: usersPath,
|
270
|
+
id,
|
271
|
+
values: {}
|
272
|
+
};
|
273
|
+
await dataSourceDelegate.deleteEntity({ entity });
|
274
|
+
}, [rolesPath, dataSourceDelegate]);
|
262
275
|
const collectionPermissions = useCallback(({
|
263
|
-
collection
|
276
|
+
collection,
|
264
277
|
user
|
265
278
|
}) => resolveUserRolePermissions({
|
266
|
-
collection
|
279
|
+
collection,
|
267
280
|
user
|
268
281
|
}), []);
|
269
282
|
const defineRolesFor = useCallback((user) => {
|
@@ -307,22 +320,22 @@ function useFirestoreUserManagement({
|
|
307
320
|
authenticator
|
308
321
|
};
|
309
322
|
}
|
310
|
-
const
|
311
|
-
return docs.map((
|
312
|
-
const data =
|
323
|
+
const entitiesToUsers = (docs) => {
|
324
|
+
return docs.map((doc) => {
|
325
|
+
const data = doc.values;
|
313
326
|
const newVar = {
|
314
|
-
uid:
|
327
|
+
uid: doc.id,
|
315
328
|
...data,
|
316
|
-
created_on: data?.created_on
|
317
|
-
updated_on: data?.updated_on
|
329
|
+
created_on: data?.created_on,
|
330
|
+
updated_on: data?.updated_on
|
318
331
|
};
|
319
332
|
return newVar;
|
320
333
|
});
|
321
334
|
};
|
322
|
-
const
|
323
|
-
return
|
324
|
-
id:
|
325
|
-
...
|
335
|
+
const entityToRoles = (entities) => {
|
336
|
+
return entities.map((doc) => ({
|
337
|
+
id: doc.id,
|
338
|
+
...doc.values
|
326
339
|
}));
|
327
340
|
};
|
328
341
|
const UserManagementContext = React.createContext({});
|
@@ -1519,7 +1532,7 @@ export {
|
|
1519
1532
|
getUserRoles,
|
1520
1533
|
hexToRgbaWithOpacity,
|
1521
1534
|
resolveUserRolePermissions,
|
1522
|
-
|
1535
|
+
useBuildUserManagement,
|
1523
1536
|
useUserManagement,
|
1524
1537
|
useUserManagementPlugin,
|
1525
1538
|
userManagementAdminViews
|