@edgedev/firebase 1.7.2 → 1.7.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.
- package/README.md +6 -10
- package/edgeFirebase.ts +104 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,7 +125,6 @@ exports.updateUser = functions.firestore.document('staged-users/{docId}').onUpda
|
|
|
125
125
|
return shouldProcess(eventRef).then((process) => {
|
|
126
126
|
if (process) {
|
|
127
127
|
// Note: we can trust on newData.uid because we are checking in rules that it matches the auth.uid
|
|
128
|
-
// TODO: user might be invited to join another org with reg code.. if used when logged will combine new staged-user doc into first stage-user doc and sync to users.
|
|
129
128
|
if (newData.userId) {
|
|
130
129
|
const userRef = db.collection('users').doc(newData.userId)
|
|
131
130
|
setUser(userRef, newData, oldData, stagedDocId).then(() => {
|
|
@@ -181,9 +180,6 @@ exports.updateUser = functions.firestore.document('staged-users/{docId}').onUpda
|
|
|
181
180
|
})
|
|
182
181
|
|
|
183
182
|
function setUser(userRef, newData, oldData, stagedDocId) {
|
|
184
|
-
// IT's OK If "users" doesn't match exactly matched "staged-users" because this is only preventing
|
|
185
|
-
// writing from outside the @edgdev/firebase functions, so discrepancies will be rare since
|
|
186
|
-
// the package will prevent before it gets this far.
|
|
187
183
|
return userRef.get().then((user) => {
|
|
188
184
|
let userUpdate = { meta: newData.meta, stagedDocId }
|
|
189
185
|
|
|
@@ -1009,38 +1005,38 @@ service cloud.firestore {
|
|
|
1009
1005
|
allow get: if checkPermission(seg1 + "-" + seg2, "read");
|
|
1010
1006
|
allow list: if checkPermission(seg1, "read");
|
|
1011
1007
|
allow create: if checkPermission(seg1, "write");
|
|
1012
|
-
allow update: if checkPermission(seg1, "write");
|
|
1008
|
+
allow update: if checkPermission(seg1 + "-" + seg2, "write");
|
|
1013
1009
|
allow delete: if checkPermission(seg1, "delete");
|
|
1014
1010
|
match /{seg3} {
|
|
1015
1011
|
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "read");
|
|
1016
1012
|
allow list: if checkPermission(seg1 + "-" + seg2, "read");
|
|
1017
1013
|
allow create: if checkPermission(seg1 + "-" + seg2, "write");
|
|
1018
|
-
allow update: if checkPermission(seg1 + "-" + seg2, "write");
|
|
1014
|
+
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "write");
|
|
1019
1015
|
allow delete: if checkPermission(seg1 + "-" + seg2, "delete");
|
|
1020
1016
|
match /{seg4} {
|
|
1021
1017
|
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "read");
|
|
1022
1018
|
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "read");
|
|
1023
1019
|
allow create: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "write");
|
|
1024
|
-
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "write");
|
|
1020
|
+
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "write");
|
|
1025
1021
|
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "delete");
|
|
1026
1022
|
|
|
1027
1023
|
match /{seg5} {
|
|
1028
1024
|
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "read");
|
|
1029
1025
|
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "read");
|
|
1030
1026
|
allow create: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "write");
|
|
1031
|
-
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "write");
|
|
1027
|
+
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "write");
|
|
1032
1028
|
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "delete");
|
|
1033
1029
|
match /{seg6} {
|
|
1034
1030
|
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "read");
|
|
1035
1031
|
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "read");
|
|
1036
1032
|
allow create: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "write");
|
|
1037
|
-
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "write");
|
|
1033
|
+
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "write");
|
|
1038
1034
|
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "delete");
|
|
1039
1035
|
match /{seg7} {
|
|
1040
1036
|
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6 + "-" + seg7, "read");
|
|
1041
1037
|
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "read");
|
|
1042
1038
|
allow create: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "write");
|
|
1043
|
-
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "write");
|
|
1039
|
+
allow update: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6 + "-" + seg7, "write");
|
|
1044
1040
|
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "delete");
|
|
1045
1041
|
}
|
|
1046
1042
|
}
|
package/edgeFirebase.ts
CHANGED
|
@@ -44,6 +44,9 @@ import {
|
|
|
44
44
|
connectAuthEmulator,
|
|
45
45
|
} from "firebase/auth";
|
|
46
46
|
|
|
47
|
+
|
|
48
|
+
import { getAnalytics, logEvent } from "firebase/analytics";
|
|
49
|
+
|
|
47
50
|
interface FirestoreQuery {
|
|
48
51
|
field: string;
|
|
49
52
|
operator: WhereFilterOp; // '==' | '<' | '<=' | '>' | '>=' | 'array-contains' | 'in' | 'array-contains-any';
|
|
@@ -108,7 +111,7 @@ interface newUser {
|
|
|
108
111
|
role: string,
|
|
109
112
|
dynamicDocumentField: string, // This is the field in the document that will be set by the value of "dynamicDocumentFieldValue" passed during registration, like "name"
|
|
110
113
|
documentStructure: {
|
|
111
|
-
[key: string]:
|
|
114
|
+
[key: string]: unknown
|
|
112
115
|
}
|
|
113
116
|
};
|
|
114
117
|
}
|
|
@@ -151,6 +154,7 @@ interface firebaseConfig {
|
|
|
151
154
|
messagingSenderId: string;
|
|
152
155
|
appId: string;
|
|
153
156
|
emulatorAuth?: string;
|
|
157
|
+
measurementId?: string;
|
|
154
158
|
emulatorFirestore?: string;
|
|
155
159
|
}
|
|
156
160
|
|
|
@@ -174,6 +178,7 @@ export const EdgeFirebase = class {
|
|
|
174
178
|
storageBucket: "",
|
|
175
179
|
messagingSenderId: "",
|
|
176
180
|
appId: "",
|
|
181
|
+
measurementId: "",
|
|
177
182
|
emulatorAuth: "",
|
|
178
183
|
emulatorFirestore: ""
|
|
179
184
|
},
|
|
@@ -196,6 +201,10 @@ export const EdgeFirebase = class {
|
|
|
196
201
|
connectFirestoreEmulator(this.db, "localhost", this.firebaseConfig.emulatorFirestore)
|
|
197
202
|
}
|
|
198
203
|
|
|
204
|
+
if (this.firebaseConfig.measurementId) {
|
|
205
|
+
this.anaytics = getAnalytics(this.app);
|
|
206
|
+
}
|
|
207
|
+
|
|
199
208
|
this.setOnAuthStateChanged();
|
|
200
209
|
}
|
|
201
210
|
|
|
@@ -205,6 +214,14 @@ export const EdgeFirebase = class {
|
|
|
205
214
|
public auth = null;
|
|
206
215
|
public db = null;
|
|
207
216
|
|
|
217
|
+
private anaytics = null;
|
|
218
|
+
|
|
219
|
+
public logAnalyticsEvent = (eventName: string, eventParams: object = {}) => {
|
|
220
|
+
if (this.anaytics) {
|
|
221
|
+
logEvent(this.anaytics, eventName, eventParams);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
208
225
|
private initUserMetaPermissions = async (docSnap): Promise<void> => {
|
|
209
226
|
this.user.meta = {};
|
|
210
227
|
if (docSnap.exists()) {
|
|
@@ -352,6 +369,7 @@ export const EdgeFirebase = class {
|
|
|
352
369
|
this.user.uid = userAuth.uid;
|
|
353
370
|
this.user.logInError = false;
|
|
354
371
|
this.user.logInErrorMessage = "";
|
|
372
|
+
this.logAnalyticsEvent("login", { uid: this.user.uid });
|
|
355
373
|
this.waitForUser();
|
|
356
374
|
} else {
|
|
357
375
|
this.user.email = "";
|
|
@@ -417,7 +435,7 @@ export const EdgeFirebase = class {
|
|
|
417
435
|
initRoleHelper["edge-assignment-helper"] = {permissionType: "roles"}
|
|
418
436
|
await setDoc(doc(this.db, "rule-helpers", response.user.uid), initRoleHelper);
|
|
419
437
|
await updateDoc(doc(this.db, "staged-users/" + userRegister.registrationCode), stagedUserUpdate)
|
|
420
|
-
|
|
438
|
+
this.logAnalyticsEvent("sign_up", { uid: response.user.uid});
|
|
421
439
|
return this.sendResponse({
|
|
422
440
|
success: true,
|
|
423
441
|
message: "",
|
|
@@ -806,6 +824,7 @@ export const EdgeFirebase = class {
|
|
|
806
824
|
if (this.unsubscibe[key] instanceof Function) {
|
|
807
825
|
this.unsubscibe[key]();
|
|
808
826
|
this.unsubscibe[key] = null;
|
|
827
|
+
this.data[key] = {};
|
|
809
828
|
}
|
|
810
829
|
}
|
|
811
830
|
signOut(this.auth).then(() => {
|
|
@@ -829,7 +848,7 @@ export const EdgeFirebase = class {
|
|
|
829
848
|
credentials.password
|
|
830
849
|
)
|
|
831
850
|
.then(() => {
|
|
832
|
-
|
|
851
|
+
// Do nothing
|
|
833
852
|
})
|
|
834
853
|
.catch((error) => {
|
|
835
854
|
this.user.email = "";
|
|
@@ -1480,62 +1499,107 @@ export const EdgeFirebase = class {
|
|
|
1480
1499
|
}
|
|
1481
1500
|
};
|
|
1482
1501
|
|
|
1483
|
-
//
|
|
1484
|
-
public
|
|
1502
|
+
// TODO: Add documentation for this function
|
|
1503
|
+
public changeDoc = async (
|
|
1485
1504
|
collectionPath: string,
|
|
1486
|
-
|
|
1505
|
+
docId: string,
|
|
1506
|
+
item: object
|
|
1487
1507
|
): Promise<actionResponse> => {
|
|
1488
|
-
const canWrite = await this.permissionCheck("write", collectionPath);
|
|
1508
|
+
const canWrite = await this.permissionCheck("write", collectionPath + "/" + docId);
|
|
1489
1509
|
if (!canWrite) {
|
|
1490
1510
|
return this.sendResponse({
|
|
1491
1511
|
success: false,
|
|
1492
|
-
message: `You do not have permission to write to "${collectionPath}"`,
|
|
1512
|
+
message: `You do not have permission to write to "${collectionPath}/${docId}"`,
|
|
1493
1513
|
meta: {}
|
|
1494
1514
|
});
|
|
1495
1515
|
} else {
|
|
1516
|
+
const docRef = doc(this.db, collectionPath, docId);
|
|
1517
|
+
const docSnap = await getDoc(docRef);
|
|
1518
|
+
if (!docSnap.exists()) {
|
|
1519
|
+
return this.sendResponse({
|
|
1520
|
+
success: false,
|
|
1521
|
+
message: `Document "${docId}" does not exist in "${collectionPath}"`,
|
|
1522
|
+
meta: {}
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1496
1525
|
const cloneItem = JSON.parse(JSON.stringify(item));
|
|
1497
1526
|
const currentTime = new Date().getTime();
|
|
1498
1527
|
cloneItem.last_updated = currentTime;
|
|
1499
1528
|
cloneItem.uid = this.user.uid;
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1529
|
+
await updateDoc(doc(this.db, collectionPath, docId), cloneItem);
|
|
1530
|
+
return this.sendResponse({
|
|
1531
|
+
success: true,
|
|
1532
|
+
message: "",
|
|
1533
|
+
meta: {}
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
};
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
public storeDoc = async (
|
|
1540
|
+
collectionPath: string,
|
|
1541
|
+
item: object,
|
|
1542
|
+
): Promise<actionResponse> => {
|
|
1543
|
+
|
|
1544
|
+
const cloneItem = JSON.parse(JSON.stringify(item));
|
|
1545
|
+
const currentTime = new Date().getTime();
|
|
1546
|
+
cloneItem.last_updated = currentTime;
|
|
1547
|
+
cloneItem.uid = this.user.uid;
|
|
1548
|
+
if (!Object.prototype.hasOwnProperty.call(cloneItem, "doc_created_at")) {
|
|
1549
|
+
cloneItem.doc_created_at = currentTime;
|
|
1550
|
+
}
|
|
1551
|
+
if (Object.prototype.hasOwnProperty.call(cloneItem, "docId")) {
|
|
1552
|
+
const canWrite = await this.permissionCheck("write", collectionPath + "/" + cloneItem.docId);
|
|
1553
|
+
if (!canWrite) {
|
|
1512
1554
|
return this.sendResponse({
|
|
1513
|
-
success:
|
|
1514
|
-
message: ""
|
|
1515
|
-
meta: {
|
|
1555
|
+
success: false,
|
|
1556
|
+
message: `You do not have permission to write to "${collectionPath}/${cloneItem.docId}"`,
|
|
1557
|
+
meta: {}
|
|
1516
1558
|
});
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
)
|
|
1522
|
-
|
|
1523
|
-
if (canRead) {
|
|
1524
|
-
if (Object.prototype.hasOwnProperty.call(this.data, collectionPath)) {
|
|
1525
|
-
this.data[collectionPath][docRef.id] = cloneItem;
|
|
1526
|
-
}
|
|
1559
|
+
}
|
|
1560
|
+
const docId = cloneItem.docId;
|
|
1561
|
+
const canRead = this.permissionCheckOnly("read", collectionPath);
|
|
1562
|
+
if (canRead) {
|
|
1563
|
+
if (Object.prototype.hasOwnProperty.call(this.data, collectionPath)) {
|
|
1564
|
+
this.data[collectionPath][docId] = cloneItem;
|
|
1527
1565
|
}
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1566
|
+
}
|
|
1567
|
+
await setDoc(doc(this.db, collectionPath, docId), cloneItem);
|
|
1568
|
+
return this.sendResponse({
|
|
1569
|
+
success: true,
|
|
1570
|
+
message: "",
|
|
1571
|
+
meta: {docId}
|
|
1572
|
+
});
|
|
1573
|
+
} else {
|
|
1574
|
+
const canWrite = await this.permissionCheck("write", collectionPath);
|
|
1575
|
+
if (!canWrite) {
|
|
1532
1576
|
return this.sendResponse({
|
|
1533
|
-
success:
|
|
1534
|
-
message: ""
|
|
1535
|
-
meta: {
|
|
1577
|
+
success: false,
|
|
1578
|
+
message: `You do not have permission to write to "${collectionPath}"`,
|
|
1579
|
+
meta: {}
|
|
1536
1580
|
});
|
|
1537
1581
|
}
|
|
1582
|
+
const docRef = await addDoc(
|
|
1583
|
+
collection(this.db, collectionPath),
|
|
1584
|
+
cloneItem
|
|
1585
|
+
);
|
|
1586
|
+
const canRead = this.permissionCheckOnly("read", collectionPath);
|
|
1587
|
+
if (canRead) {
|
|
1588
|
+
if (Object.prototype.hasOwnProperty.call(this.data, collectionPath)) {
|
|
1589
|
+
this.data[collectionPath][docRef.id] = cloneItem;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
await this.storeDoc(
|
|
1593
|
+
collectionPath,
|
|
1594
|
+
{ ...cloneItem, docId: docRef.id }
|
|
1595
|
+
);
|
|
1596
|
+
return this.sendResponse({
|
|
1597
|
+
success: true,
|
|
1598
|
+
message: "",
|
|
1599
|
+
meta: {docId: docRef.id}
|
|
1600
|
+
});
|
|
1538
1601
|
}
|
|
1602
|
+
|
|
1539
1603
|
};
|
|
1540
1604
|
|
|
1541
1605
|
// Composable to delete a document
|