@edgedev/firebase 1.4.2 → 1.4.4

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.
Files changed (3) hide show
  1. package/README.md +25 -11
  2. package/edgeFirebase.ts +89 -81
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -242,10 +242,10 @@ edgeFirebase.removeUser("user@edgemarketingdesign.com");
242
242
 
243
243
  ### List Users
244
244
 
245
- This will list all users that are members of collections that the user running the function has assign access for, it will be a listed index by email/user id.
245
+ This will list all users that are members of the collection and subcollections passed to the function that the user running the function has assign access for, it will be a listed index by email/user id.
246
246
 
247
247
  ```javascript
248
- const users = await edgeFirebase.listUsers();
248
+ const users = await edgeFirebase.listUsers("myItems");
249
249
  ```
250
250
 
251
251
  ```typescript
@@ -257,8 +257,8 @@ interface usersByEmail {
257
257
  ```typescript
258
258
  interface user {
259
259
  email: string;
260
- roles: {[collectionPath: string ]: "admin" | "user"}
261
- specialPermissions: {[collectionPath: string]: permissions};
260
+ roles: role[];
261
+ specialPermissions: specialPermission[];
262
262
  userId: string;
263
263
  docId: string;
264
264
  uid: string;
@@ -266,14 +266,27 @@ interface user {
266
266
  }
267
267
  ```
268
268
 
269
+ ```typescript
270
+ interface role {
271
+ collectionPath: "-" | string; // - is root
272
+ role: "admin" | "user";
273
+ }
274
+ ```
269
275
 
276
+ ```typescript
277
+ interface specialPermission {
278
+ collectionPath: "-" | string; // - is root
279
+ permissions: permissions;
280
+ }
281
+ ```
270
282
 
271
- ### List Collections with Assign Access
272
-
273
- This function will list all collections that the user running it has assign access for.
274
-
275
- ```javascript
276
- const collections = await edgeFirebase.listCollectionsCanAssign(); // returns array of strings (collection paths)
283
+ ```typescript
284
+ interface permissions {
285
+ assign: boolean;
286
+ read: boolean;
287
+ write: boolean;
288
+ delete: boolean;
289
+ }
277
290
  ```
278
291
 
279
292
  # Firebase Authentication
@@ -302,7 +315,8 @@ interface UserDataObject {
302
315
  logInErrorMessage: string;
303
316
  meta: object;
304
317
  roles: role[]; //see role below
305
- specialPermissions: specialPermission[]; //see specialPermission bleow
318
+ specialPermissions: specialPermission[]; //see specialPermission below
319
+ canAssignCollectionPaths: string[]; //an array of collectionPaths that the user has "assign" access to
306
320
  }
307
321
 
308
322
  // sub types of UserDataObject:
package/edgeFirebase.ts CHANGED
@@ -92,6 +92,7 @@ interface UserDataObject {
92
92
  meta: object;
93
93
  roles: role[];
94
94
  specialPermissions: specialPermission[];
95
+ canAssignCollectionPaths: string[];
95
96
  }
96
97
 
97
98
  interface newUser {
@@ -103,8 +104,8 @@ interface newUser {
103
104
 
104
105
  interface user {
105
106
  email: string;
106
- roles: {[collectionPath: string ]: "admin" | "user"}
107
- specialPermissions: {[collectionPath: string]: permissions};
107
+ roles: role[];
108
+ specialPermissions: specialPermission[];
108
109
  userId: string;
109
110
  docId: string;
110
111
  uid: string;
@@ -209,6 +210,7 @@ export const EdgeFirebase = class {
209
210
  }
210
211
  }
211
212
  this.user.specialPermissions = specialPermissions;
213
+ this.listCollectionsCanAssign()
212
214
  }
213
215
  const metaUnsubscribe = onSnapshot(
214
216
  doc(this.db, "users", this.user.email),
@@ -218,7 +220,7 @@ export const EdgeFirebase = class {
218
220
  email: this.user.email,
219
221
  roles: [],
220
222
  specialPermissions: [],
221
- meta: {}
223
+ meta: {},
222
224
  });
223
225
  this.user.meta = {};
224
226
  } else {
@@ -245,6 +247,7 @@ export const EdgeFirebase = class {
245
247
  }
246
248
  }
247
249
  this.user.specialPermissions = specialPermissions;
250
+ this.listCollectionsCanAssign()
248
251
  }
249
252
  }
250
253
  );
@@ -438,19 +441,28 @@ export const EdgeFirebase = class {
438
441
  newUser.specialPermissions
439
442
  );
440
443
  if (canAssignRole.canDo && canAssignSpecialPermissions.canDo) {
441
- const userMeta: userMeta = {
442
- docId: newUser.email,
443
- userId: "",
444
- email: newUser.email,
445
- roles: newUser.roles,
446
- specialPermissions: newUser.specialPermissions,
447
- meta: newUser.meta
448
- };
449
- this.generateUserMeta(userMeta);
450
- return this.sendResponse({
451
- success: true,
452
- message: ""
453
- });
444
+ const userRef = doc(this.db, "users", newUser.email);
445
+ const userSnap = await getDoc(userRef);
446
+ if (!userSnap.exists()) {
447
+ const userMeta: userMeta = {
448
+ docId: newUser.email,
449
+ userId: "",
450
+ email: newUser.email,
451
+ roles: newUser.roles,
452
+ specialPermissions: newUser.specialPermissions,
453
+ meta: newUser.meta
454
+ };
455
+ this.generateUserMeta(userMeta);
456
+ return this.sendResponse({
457
+ success: true,
458
+ message: ""
459
+ });
460
+ } else {
461
+ return this.sendResponse({
462
+ success: false,
463
+ message: "User already exists"
464
+ });
465
+ }
454
466
  } else {
455
467
  return this.sendResponse({
456
468
  success: false,
@@ -715,7 +727,8 @@ export const EdgeFirebase = class {
715
727
  logInErrorMessage: "",
716
728
  meta: {},
717
729
  roles: [],
718
- specialPermissions: []
730
+ specialPermissions: [],
731
+ canAssignCollectionPaths: [],
719
732
  });
720
733
 
721
734
  public getDocData = async (
@@ -988,8 +1001,7 @@ export const EdgeFirebase = class {
988
1001
  }
989
1002
  };
990
1003
 
991
- // TODO: change this function to be synced dynamically on the user object
992
- public listCollectionsCanAssign = async (): Promise<string[]> => {
1004
+ private listCollectionsCanAssign = async (): Promise<void> => {
993
1005
  let collectionPaths = [];
994
1006
  for (const role of this.user.roles) {
995
1007
  const canAssign = await this.permissionCheck(
@@ -1033,75 +1045,71 @@ export const EdgeFirebase = class {
1033
1045
  }
1034
1046
  }
1035
1047
  collectionPathList = [...new Set(collectionPathList)];
1036
- return collectionPathList;
1048
+ this.user.canAssignCollectionPaths = collectionPathList;
1037
1049
  };
1038
1050
 
1039
- // TODO: finish making this query by collectionPath if passed.. in furture will be used to get users by collectionPath
1040
- // because having one giant list of users is not scalable
1041
1051
  public listUsers = async (collectionPath = ''): Promise<usersByEmail> => {
1042
1052
  const userList = {};
1043
- if (collectionPath) {
1044
- const canAssign = await this.permissionCheck("assign", collectionPath);
1045
- if (!canAssign) {
1046
- return {}
1047
- }
1048
- }
1049
- const collectionPathList = await this.listCollectionsCanAssign();
1050
- for (const collectionPath of collectionPathList) {
1051
- const roleUsers = await getDocs(
1052
- query(
1053
- collection(this.db, "users"),
1054
- where(
1055
- "roles." + collectionPath + ".collectionPath",
1056
- "==",
1057
- collectionPath
1053
+
1054
+ for (const collectionPathCheck of this.user.canAssignCollectionPaths) {
1055
+
1056
+ if (collectionPathCheck.startsWith(collectionPath.replaceAll('/', '-'))) {
1057
+ const roleUsers = await getDocs(
1058
+ query(
1059
+ collection(this.db, "users"),
1060
+ where(
1061
+ "roles." + collectionPathCheck + ".collectionPath",
1062
+ "==",
1063
+ collectionPathCheck
1064
+ )
1058
1065
  )
1059
- )
1060
- );
1061
- roleUsers.forEach((doc) => {
1062
- const user = doc.data();
1063
- if (!Object.prototype.hasOwnProperty.call(userList, user.docId)) {
1064
- userList[user.email] = {
1065
- docId: user.docId,
1066
- email: user.email,
1067
- roles: {[collectionPath]: user.roles[collectionPath].role },
1068
- specialPermissions: {},
1069
- meta: user.meta,
1070
- last_updated: user.last_updated,
1071
- userId: user.userId,
1072
- uid: user.uid
1066
+ );
1067
+
1068
+ roleUsers.forEach((doc) => {
1069
+ const user = doc.data();
1070
+ if (!Object.prototype.hasOwnProperty.call(userList, user.docId)) {
1071
+ userList[user.email] = {
1072
+ docId: user.docId,
1073
+ email: user.email,
1074
+ roles: [{collectionPathCheck, role: user.roles[collectionPathCheck].role }],
1075
+ specialPermissions: [],
1076
+ meta: user.meta,
1077
+ last_updated: user.last_updated,
1078
+ userId: user.userId,
1079
+ uid: user.uid
1080
+ }
1081
+ } else {
1082
+ userList[user.email].roles.push({ collectionPathCheck, role: user.roles[collectionPathCheck].role })
1073
1083
  }
1074
- } else {
1075
- userList[user.email].roles[collectionPath] = user.roles[collectionPath].role
1076
- }
1077
- });
1078
- const specialPermissionsUsers = await getDocs(
1079
- query(
1080
- collection(this.db, "users"),
1081
- where(
1082
- "specialPermissions." + collectionPath + ".collectionPath",
1083
- "==",
1084
- collectionPath
1084
+ });
1085
+ const specialPermissionsUsers = await getDocs(
1086
+ query(
1087
+ collection(this.db, "users"),
1088
+ where(
1089
+ "specialPermissions." + collectionPathCheck + ".collectionPath",
1090
+ "==",
1091
+ collectionPathCheck
1092
+ )
1085
1093
  )
1086
- )
1087
- );
1088
- specialPermissionsUsers.forEach((doc) => {
1089
- const user = doc.data();
1090
- if (!Object.prototype.hasOwnProperty.call(userList, user.docId)) {
1091
- userList[user.email] = {
1092
- docId: user.docId,
1093
- email: user.email,
1094
- role: {},
1095
- specialPermissions: {[collectionPath]: user.specialPermissions[collectionPath].permissions},
1096
- meta: user.meta,
1097
- last_updated: user.last_updated,
1098
- userId: user.userId,
1099
- uid: user.uid
1094
+ );
1095
+ specialPermissionsUsers.forEach((doc) => {
1096
+ const user = doc.data();
1097
+ if (!Object.prototype.hasOwnProperty.call(userList, user.docId)) {
1098
+ userList[user.email] = {
1099
+ docId: user.docId,
1100
+ email: user.email,
1101
+ role: [],
1102
+ specialPermissions: [{ collectionPathCheck, permissions: user.specialPermissions[collectionPathCheck].permissions }],
1103
+ meta: user.meta,
1104
+ last_updated: user.last_updated,
1105
+ userId: user.userId,
1106
+ uid: user.uid
1107
+ }
1108
+ } else {
1109
+ userList[user.email].specialPermissions.push({ collectionPathCheck, permissions: user.specialPermissions[collectionPathCheck].permissions })
1100
1110
  }
1101
- } else {
1102
- userList[user.email].specialPermissions[collectionPath] = user.specialPermissions[collectionPath].permissions
1103
- }
1104
- });
1111
+ });
1112
+ }
1105
1113
  }
1106
1114
  return userList;
1107
1115
  };
@@ -1186,7 +1194,7 @@ export const EdgeFirebase = class {
1186
1194
  }
1187
1195
  };
1188
1196
 
1189
- public storeUserRoles = async (
1197
+ private storeUserRoles = async (
1190
1198
  email: string,
1191
1199
  collectionPath: string,
1192
1200
  role: "admin" | "user"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/firebase",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "Vue 3 / Nuxt 3 Plugin or Nuxt 3 global composable for firebase authentication and firestore.",
5
5
  "main": "index.ts",
6
6
  "scripts": {