@edgedev/firebase 2.0.36 → 2.1.36

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/edgeFirebase.ts CHANGED
@@ -349,64 +349,6 @@ export const EdgeFirebase = class {
349
349
  this.unsubscribe.userMeta = metaUnsubscribe;
350
350
  };
351
351
 
352
- private startCollectionPermissionsSync = async (): Promise<void> => {
353
- // TODO: In future get roles from user and only sync those collections
354
- // Perhaps by getting all "first segments" and get all that start with that
355
- const q = this.getQuery('collection-data');
356
- const docs = await getDocs(q);
357
- let items = {}
358
- docs.forEach((doc) => {
359
- const item = doc.data();
360
- item.docId = doc.id;
361
- items[doc.id] = item;
362
- });
363
- this.state.collectionPermissions = items;
364
- if (!this.state.collectionPermissions['-default-']) {
365
- const collectionItem = {
366
- collectionPath: '-default-',
367
- docId: '-default-',
368
- admin: {
369
- assign: true,
370
- read: true,
371
- write: true,
372
- delete: true
373
- },
374
- editor: {
375
- assign: false,
376
- read: true,
377
- write: true,
378
- delete: true
379
- },
380
- writer: {
381
- assign: false,
382
- read: true,
383
- write: true,
384
- delete: false
385
- },
386
- user: {
387
- assign: false,
388
- read: true,
389
- write: false,
390
- delete: false
391
- }
392
- };
393
- await setDoc(
394
- doc(this.db, "collection-data", "-default-"),
395
- collectionItem
396
- );
397
- }
398
- this.stopSnapshot('collection-data');
399
- const unsubscribe = onSnapshot(q, (querySnapshot) => {
400
- items = {};
401
- querySnapshot.forEach((doc) => {
402
- const item = doc.data();
403
- item.docId = doc.id;
404
- items[doc.id] = item;
405
- });
406
- this.state.collectionPermissions = items;
407
- });
408
- this.unsubscribe['collection-data'] = unsubscribe
409
- }
410
352
 
411
353
  private ruleHelperReset = async (): Promise<void> => {
412
354
  const initRoleHelper = { uid: this.user.uid, 'edge-assignment-helper': {permissionType: "roles"} }
@@ -417,7 +359,6 @@ export const EdgeFirebase = class {
417
359
  private startUserMetaSync = async (docSnap): Promise<void> => {
418
360
  // Took this out because if another client is logged in, it breaks the other client
419
361
  // await this.ruleHelperReset();
420
- await this.startCollectionPermissionsSync()
421
362
  await this.initUserMetaPermissions(docSnap);
422
363
  this.user.loggedIn = true;
423
364
  this.user.loggingIn = false;
@@ -1060,6 +1001,8 @@ export const EdgeFirebase = class {
1060
1001
  this.state.ruleHelpers[ruleKey] = ruleCheck;
1061
1002
  }
1062
1003
 
1004
+
1005
+
1063
1006
  public permissionCheckOnly = (action: action, collectionPath: string): boolean => {
1064
1007
  const collection = collectionPath.replaceAll("-", "/").split("/");
1065
1008
  let index = collection.length;
@@ -1079,10 +1022,12 @@ export const EdgeFirebase = class {
1079
1022
  );
1080
1023
 
1081
1024
  if (role) {
1082
- permissionData = this.getCollectionPermissions(
1083
- permissionCheck,
1084
- role.role
1085
- );
1025
+ permissionData = this.state.permissions[role.role] || {
1026
+ read: false,
1027
+ write: false,
1028
+ delete: false,
1029
+ assign: false
1030
+ };
1086
1031
  }
1087
1032
  const specialPermission = this.user.specialPermissions.find(
1088
1033
  (r) => r.collectionPath === permissionCheck
@@ -1096,10 +1041,12 @@ export const EdgeFirebase = class {
1096
1041
  if (!permissionData[action]) {
1097
1042
  const rootRole = this.user.roles.find((r) => r.collectionPath === "-");
1098
1043
  if (rootRole) {
1099
- permissionData = this.getCollectionPermissions(
1100
- "-",
1101
- rootRole.role
1102
- );
1044
+ permissionData = this.state.permissions[rootRole.role] || {
1045
+ read: false,
1046
+ write: false,
1047
+ delete: false,
1048
+ assign: false
1049
+ };
1103
1050
  }
1104
1051
  const rootSpecialPermission = this.user.specialPermissions.find(
1105
1052
  (r) => r.collectionPath === "-"
@@ -1122,32 +1069,6 @@ export const EdgeFirebase = class {
1122
1069
  return check;
1123
1070
  };
1124
1071
 
1125
- private getCollectionPermissions = (
1126
- collectionPath: string,
1127
- role: string
1128
- ): permissions => {
1129
- if (Object.prototype.hasOwnProperty.call(this.state.collectionPermissions, collectionPath)) {
1130
- if (Object.prototype.hasOwnProperty.call(this.state.collectionPermissions[collectionPath], role)) {
1131
- const permissionData = this.state.collectionPermissions[collectionPath][role];
1132
- return {
1133
- read: permissionData.read,
1134
- write: permissionData.write,
1135
- delete: permissionData.delete,
1136
- assign: permissionData.assign
1137
- };
1138
- }
1139
- }
1140
- if (Object.prototype.hasOwnProperty.call(this.state.collectionPermissions, '-default-')) {
1141
- return this.state.collectionPermissions['-default-'][role];
1142
- }
1143
- return {
1144
- read: false,
1145
- write: false,
1146
- delete: false,
1147
- assign: false
1148
- };
1149
- };
1150
-
1151
1072
  private generateUserMeta = async (userMeta: newUser): Promise<actionResponse> => {
1152
1073
  const roles: role[] = userMeta.roles || [];
1153
1074
  const specialPermissions: specialPermission[] = userMeta.specialPermissions || [];
@@ -1277,7 +1198,12 @@ export const EdgeFirebase = class {
1277
1198
  });
1278
1199
 
1279
1200
  public state = reactive({
1280
- collectionPermissions: {},
1201
+ permissions: {
1202
+ 'admin': {'assign': true, 'delete': true, 'read': true, 'write': true},
1203
+ 'editor': {'assign': false, 'delete': true, 'read': true, 'write': true},
1204
+ 'user': {'assign': false, 'delete': false, 'read': true, 'write': false},
1205
+ 'writer': {'assign': false, 'delete': false, 'read': true, 'write': true}
1206
+ },
1281
1207
  users: {},
1282
1208
  registrationCode: "",
1283
1209
  registrationMeta: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/firebase",
3
- "version": "2.0.36",
3
+ "version": "2.1.36",
4
4
  "description": "Vue 3 / Nuxt 3 Plugin or Nuxt 3 plugin for firebase authentication and firestore.",
5
5
  "main": "index.ts",
6
6
  "scripts": {
package/src/config.js CHANGED
@@ -26,6 +26,41 @@ const { getFirestore } = require('firebase-admin/firestore')
26
26
  const twilio = require('twilio')
27
27
  const db = getFirestore()
28
28
 
29
+ // The permissionCheck function
30
+
31
+ const permissions = {
32
+ 'admin': {'assign': true, 'delete': true, 'read': true, 'write': true},
33
+ 'editor': {'assign': false, 'delete': true, 'read': true, 'write': true},
34
+ 'user': {'assign': false, 'delete': false, 'read': true, 'write': false},
35
+ 'writer': {'assign': false, 'delete': false, 'read': true, 'write': true}
36
+ };
37
+
38
+ const permissionCheck = async (userId, action, originalFilePath) => {
39
+ // Fetch user document
40
+ const collectionPath = originalFilePath.replace(/\//g, '-')
41
+ const userDoc = await db.collection('users').doc(userId).get()
42
+ if (!userDoc.exists) {
43
+ console.log('No such user!')
44
+ return false // Or handle as needed
45
+ }
46
+ const userData = userDoc.data()
47
+
48
+ // Fetch roles from user data
49
+ const roles = Object.values(userData.roles || {})
50
+
51
+ for (const role of roles) {
52
+ // Check if the role's collectionPath is a prefix of the collectionPath
53
+ if (collectionPath.startsWith(role.collectionPath)) {
54
+ // Use permissions object instead of fetching collection data
55
+ const rolePermissions = permissions[role.role];
56
+ if (rolePermissions && rolePermissions[action]) {
57
+ return true;
58
+ }
59
+ }
60
+ }
61
+ return false;
62
+ }
63
+
29
64
  module.exports = {
30
65
  pubsub,
31
66
  onMessagePublished,
@@ -46,5 +81,7 @@ module.exports = {
46
81
  twilio,
47
82
  db,
48
83
  Storage,
84
+ permissionCheck,
49
85
  }
50
86
 
87
+
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-var-requires */
2
2
  /* eslint-disable no-undef */
3
- const { onCall, HttpsError, logger, getFirestore, functions, admin, twilio, db, onSchedule, onDocumentUpdated, pubsub, Storage } = require('./config.js')
3
+ const { onCall, HttpsError, logger, getFirestore, functions, admin, twilio, db, onSchedule, onDocumentUpdated, pubsub, Storage, permissionCheck } = require('./config.js')
4
4
 
5
5
  const authToken = process.env.TWILIO_AUTH_TOKEN
6
6
  const accountSid = process.env.TWILIO_SID
@@ -13,32 +13,6 @@ function formatPhoneNumber(phone) {
13
13
  return `+1${numericPhone}`
14
14
  }
15
15
 
16
- const permissionCheck = async (userId, action, originalFilePath) => {
17
- // Fetch user document
18
- const collectionPath = originalFilePath.replace(/\//g, '-')
19
- const userDoc = await db.collection('users').doc(userId).get()
20
- const userData = userDoc.data()
21
-
22
- // Fetch roles from user data
23
- const roles = Object.values(userData.roles || {})
24
-
25
- for (const role of roles) {
26
- // Check if the role's collectionPath is a prefix of the collectionPath
27
- if (collectionPath.startsWith(role.collectionPath)) {
28
- // Fetch collection data
29
- const collectionDoc = await db.collection('collection-data').doc(role.collectionPath).get()
30
- const collectionData = collectionDoc.exists ? collectionDoc.data() : await db.collection('collection-data').doc('-default-').get().then(doc => doc.data())
31
-
32
- // Check if action is permitted
33
- if (collectionData && collectionData[role.role] && collectionData[role.role][action]) {
34
- return true
35
- }
36
- }
37
- }
38
- // If no permission found, return false
39
- return false
40
- }
41
-
42
16
  exports.topicQueue = onSchedule({ schedule: 'every 1 minutes', timeoutSeconds: 180 }, async (event) => {
43
17
  const queuedTopicsRef = db.collection('topic-queue')
44
18
  const snapshot = await queuedTopicsRef.get()
@@ -156,18 +130,8 @@ exports.verifyPhoneNumber = onCall(async (request) => {
156
130
  })
157
131
 
158
132
  exports.initFirestore = onCall(async (request) => {
159
- // checks to see of the collections 'collection-data' and 'staged-users' exist if not will seed them with data
160
- const collectionData = await db.collection('collection-data').get()
133
+ // checks to see of the collections 'staged-users' exist if not will seed them with data
161
134
  const stagedUsers = await db.collection('staged-users').get()
162
- if (collectionData.empty) {
163
- // create a document with the id of '-' and one called '-default-':
164
- const admin = { assign: true, delete: true, read: true, write: true }
165
- const editor = { assign: false, delete: true, read: true, write: true }
166
- const writer = { assign: false, delete: false, read: true, write: true }
167
- const user = { assign: false, delete: false, read: true, write: false }
168
- await db.collection('collection-data').doc('-').set({ admin, editor, writer, user })
169
- await db.collection('collection-data').doc('-default-').set({ admin, editor, writer, user })
170
- }
171
135
  if (stagedUsers.empty) {
172
136
  const templateUser = {
173
137
  docId: 'organization-registration-template',
@@ -56,11 +56,14 @@ service cloud.firestore {
56
56
 
57
57
  match /databases/{database}/documents/collection-data/{collectionPath} {
58
58
  // TODO: these rules need tested.
59
- function getRolePermission(role, collection, permissionCheck) {
60
- let pathCollectionPermissions = get(/databases/$(database)/documents/collection-data/$(collection)).data;
61
- let defaultPermissions = get(/databases/$(database)/documents/collection-data/-default-).data;
62
- return (role in pathCollectionPermissions && pathCollectionPermissions[role][permissionCheck]) ||
63
- (role in defaultPermissions && defaultPermissions[role][permissionCheck]);
59
+ function getRolePermission(role, permissionCheck) {
60
+ let permissions = {
61
+ 'admin': {'assign': true, 'delete': true, 'read': true, 'write': true},
62
+ 'editor': {'assign': false, 'delete': true, 'read': true, 'write': true},
63
+ 'user': {'assign': false, 'delete': false, 'read': true, 'write': false},
64
+ 'writer': {'assign': false, 'delete': false, 'read': true, 'write': true}
65
+ };
66
+ return permissions[role][permissionCheck];
64
67
  }
65
68
  function canAssign() {
66
69
  let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
@@ -76,7 +79,7 @@ service cloud.firestore {
76
79
  "roles" in user &&
77
80
  ruleHelper[collectionPath].permissionCheckPath in user.roles &&
78
81
  "role" in user.roles[ruleHelper[collectionPath].permissionCheckPath] &&
79
- getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, collectionPath, "assign")
82
+ getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, "assign")
80
83
  );
81
84
  }
82
85
  allow read: if request.auth != null; // All signed in users can read collection-data
@@ -141,7 +144,7 @@ service cloud.firestore {
141
144
  (
142
145
  (
143
146
  "roles" in user &&
144
- getRolePermission(user.roles[permissionCheckPath].role, permissionCheckPath, "assign")
147
+ getRolePermission(user.roles[permissionCheckPath].role, "assign")
145
148
  ) ||
146
149
  (
147
150
  "specialPermissions" in user &&
@@ -160,7 +163,7 @@ service cloud.firestore {
160
163
  (
161
164
  "roles" in user &&
162
165
  ruleHelper["edge-assignment-helper"].permissionCheckPath in user.roles &&
163
- getRolePermission(user.roles[ruleHelper["edge-assignment-helper"].permissionCheckPath].role, ruleHelper["edge-assignment-helper"].permissionCheckPath, 'assign')
166
+ getRolePermission(user.roles[ruleHelper["edge-assignment-helper"].permissionCheckPath].role, 'assign')
164
167
  ) ||
165
168
  (
166
169
  "specialPermissions" in user &&
@@ -188,7 +191,7 @@ service cloud.firestore {
188
191
  (
189
192
  "roles" in user &&
190
193
  permissionCheckPath in user.roles &&
191
- getRolePermission(user.roles[permissionCheckPath].role, permissionCheckPath, "assign")
194
+ getRolePermission(user.roles[permissionCheckPath].role, "assign")
192
195
  ) ||
193
196
  (
194
197
  "specialPermissions" in user &&
@@ -216,12 +219,15 @@ service cloud.firestore {
216
219
  return request.resource.data.roles.size() == 0 && request.resource.data.specialPermissions.size() == 0;
217
220
  }
218
221
 
219
- function getRolePermission(role, collection, permissionCheck) {
220
- let pathCollectionPermissions = get(/databases/$(database)/documents/collection-data/$(collection)).data;
221
- let defaultPermissions = get(/databases/$(database)/documents/collection-data/-default-).data;
222
- return (role in pathCollectionPermissions && pathCollectionPermissions[role][permissionCheck]) ||
223
- (role in defaultPermissions && defaultPermissions[role][permissionCheck]);
224
- }
222
+ function getRolePermission(role, permissionCheck) {
223
+ let permissions = {
224
+ 'admin': {'assign': true, 'delete': true, 'read': true, 'write': true},
225
+ 'editor': {'assign': false, 'delete': true, 'read': true, 'write': true},
226
+ 'user': {'assign': false, 'delete': false, 'read': true, 'write': false},
227
+ 'writer': {'assign': false, 'delete': false, 'read': true, 'write': true}
228
+ };
229
+ return permissions[role][permissionCheck];
230
+ }
225
231
 
226
232
  function canGet () {
227
233
  return resource == null ||
@@ -237,11 +243,14 @@ service cloud.firestore {
237
243
  }
238
244
 
239
245
  match /databases/{database}/documents/{seg1} {
240
- function getRolePermission(role, collection, permissionCheck) {
241
- let pathCollectionPermissions = get(/databases/$(database)/documents/collection-data/$(collection)).data;
242
- let defaultPermissions = get(/databases/$(database)/documents/collection-data/-default-).data;
243
- return (role in pathCollectionPermissions && pathCollectionPermissions[role][permissionCheck]) ||
244
- (role in defaultPermissions && defaultPermissions[role][permissionCheck]);
246
+ function getRolePermission(role, permissionCheck) {
247
+ let permissions = {
248
+ 'admin': {'assign': true, 'delete': true, 'read': true, 'write': true},
249
+ 'editor': {'assign': false, 'delete': true, 'read': true, 'write': true},
250
+ 'user': {'assign': false, 'delete': false, 'read': true, 'write': false},
251
+ 'writer': {'assign': false, 'delete': false, 'read': true, 'write': true}
252
+ };
253
+ return permissions[role][permissionCheck];
245
254
  }
246
255
  function checkPermission(collectionPath, permissionCheck) {
247
256
  let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
@@ -267,7 +276,7 @@ service cloud.firestore {
267
276
  (
268
277
  "roles" in user &&
269
278
  ruleHelper[collectionPath].permissionCheckPath in user.roles &&
270
- getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, ruleHelper[collectionPath].permissionCheckPath, permissionCheck)
279
+ getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, permissionCheck)
271
280
  ) ||
272
281
  (
273
282
  "specialPermissions" in user &&