@edgedev/firebase 2.0.7 → 2.0.9

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
@@ -594,7 +594,7 @@ export const EdgeFirebase = class {
594
594
 
595
595
  public sendPhoneCode = async (phone: string): Promise<any> => {
596
596
  try {
597
- const callable = httpsCallable(this.functions, "sendVerificationCode");
597
+ const callable = httpsCallable(this.functions, "edgeFirebase-sendVerificationCode");
598
598
  const result: any = await callable({phone: phone});
599
599
 
600
600
  if (result.data.success !== false) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/firebase",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
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
@@ -1,9 +1,14 @@
1
1
  const functions = require('firebase-functions')
2
+ const { PubSub } = require('@google-cloud/pubsub')
2
3
  const admin = require('firebase-admin')
3
4
 
5
+ const pubsub = new PubSub()
6
+
4
7
  admin.initializeApp()
5
8
 
6
- const { onCall, HttpsError } = require('firebase-functions/v2/https')
9
+ const { onMessagePublished } = require('firebase-functions/v2/pubsub')
10
+
11
+ const { onCall, HttpsError, onRequest } = require('firebase-functions/v2/https')
7
12
  const { onSchedule } = require('firebase-functions/v2/scheduler')
8
13
  const {
9
14
  onDocumentWritten,
@@ -19,6 +24,9 @@ const twilio = require('twilio')
19
24
  const db = getFirestore()
20
25
 
21
26
  module.exports = {
27
+ pubsub,
28
+ onMessagePublished,
29
+ onRequest,
22
30
  onSchedule,
23
31
  onDocumentWritten,
24
32
  onDocumentCreated,
@@ -1,8 +1,4 @@
1
- // TODO: THE permissionCheck will call a cloud function that will check the user's permissions also...
2
- // This could function will right to "rules-helpers" collction a document with the user's uid and the collection path and the permission
3
- // This will make the rules far more efficient and will allow for more complex rules // this only needs done really for snapshots...
4
- // All the other document reads and writes should be made using a cloud functions exclusively and the cloud function will check the permissions
5
- const { onCall, HttpsError, logger, getFirestore, functions, admin, twilio, db } = require('./config.js')
1
+ const { onCall, HttpsError, logger, getFirestore, functions, admin, twilio, db, onSchedule, pubsub } = require('./config.js')
6
2
 
7
3
  const authToken = process.env.TWILIO_AUTH_TOKEN
8
4
  const accountSid = process.env.TWILIO_SID
@@ -15,6 +11,52 @@ function formatPhoneNumber(phone) {
15
11
  return `+1${numericPhone}`
16
12
  }
17
13
 
14
+ exports.topicQueue = onSchedule({ schedule: 'every 1 minutes', timeoutSeconds: 180 }, async (event) => {
15
+ const queuedTopicsRef = db.collection('topic-queue')
16
+ const snapshot = await queuedTopicsRef.get()
17
+
18
+ for (const doc of snapshot.docs) {
19
+ await db.runTransaction(async (transaction) => {
20
+ const docSnapshot = await transaction.get(doc.ref)
21
+ if (!docSnapshot.exists) {
22
+ throw new Error('Document does not exist!')
23
+ }
24
+ const emailData = docSnapshot.data()
25
+ const emailTimestamp = emailData.timestamp ? emailData.timestamp.toMillis() : 0
26
+ const delayTimestamp = emailData.minuteDelay ? emailTimestamp + emailData.minuteDelay * 60 * 1000 : 0
27
+ const currentTimestamp = Date.now()
28
+ // Check if current time is beyond the timestamp + minuteDelay, or if timestamp or minuteDelay is not set
29
+ if (emailTimestamp > currentTimestamp || currentTimestamp >= delayTimestamp || !emailData.timestamp || !emailData.minuteDelay) {
30
+ // Check if topic and payload exist and are not empty
31
+ if (emailData.topic && emailData.payload && emailData.topic.trim() !== '' && emailData.payload.trim() !== '') {
32
+ try {
33
+ await pubsub.topic(emailData.topic).publishMessage({ data: Buffer.from(JSON.stringify(emailData.payload)) })
34
+ // Delete the document after successfully publishing the message
35
+ transaction.delete(doc.ref)
36
+ }
37
+ catch (error) {
38
+ console.error(`Error publishing message to topic ${emailData.topic}:`, error)
39
+ // Increment retry count and set new delay
40
+ const retryCount = emailData.retry ? emailData.retry + 1 : 1
41
+ if (retryCount <= 3) {
42
+ const minuteDelay = retryCount === 1 ? 1 : retryCount === 2 ? 10 : 30
43
+ transaction.update(doc.ref, { retry: retryCount, minuteDelay })
44
+ }
45
+ else {
46
+ // Delete the document if there was an error publishing the topic after 3 retries
47
+ transaction.delete(doc.ref)
48
+ }
49
+ }
50
+ }
51
+ // Delete the document if topic or payload does not exist or is empty
52
+ else {
53
+ transaction.delete(doc.ref)
54
+ }
55
+ }
56
+ })
57
+ }
58
+ })
59
+
18
60
  exports.sendVerificationCode = functions.https.onCall(async (data, context) => {
19
61
  const code = (Math.floor(Math.random() * 1000000) + 1000000).toString().substring(1)
20
62
  const phone = formatPhoneNumber(data.phone)
@@ -282,9 +324,9 @@ function setUser(userRef, newData, oldData, stagedDocId) {
282
324
  let userUpdate = { meta: newData.meta, stagedDocId }
283
325
 
284
326
  if (newData.meta && newData.meta.name) {
285
- const publicUserRef = db.collection('public-users').doc(newData.uid)
327
+ const publicUserRef = db.collection('public-users').doc(newData.userId)
286
328
  const publicMeta = { name: newData.meta.name }
287
- publicUserRef.set({ uid: newData.uid, meta: publicMeta, collectionPaths: newData.collectionPaths, userId: newData.uid })
329
+ publicUserRef.set({ uid: newData.uid, meta: publicMeta, collectionPaths: newData.collectionPaths, userId: newData.userId })
288
330
  }
289
331
 
290
332
  if (Object.prototype.hasOwnProperty.call(newData, 'roles')) {
@@ -9,6 +9,14 @@ service cloud.firestore {
9
9
  allow delete: if false;
10
10
  }
11
11
 
12
+ match /databases/{database}/documents/topic-queue/{topic} {
13
+ allow read: if false;
14
+ allow create: if false;
15
+ allow update: if false;
16
+ allow delete: if false;
17
+ }
18
+
19
+
12
20
  match /databases/{database}/documents/public-users/{user} {
13
21
  allow read: if request.auth != null;
14
22
  allow list: if request.auth != null;
@@ -16,7 +24,7 @@ service cloud.firestore {
16
24
  allow update: if false;
17
25
  allow delete: if false;
18
26
  }
19
-
27
+
20
28
  match /databases/{database}/documents/events/{event} {
21
29
  allow read: if false;
22
30
  allow create: if false;
@@ -237,7 +245,7 @@ service cloud.firestore {
237
245
  }
238
246
  function checkPermission(collectionPath, permissionCheck) {
239
247
  let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
240
- let skipPaths = ["collection-data", "users", "staged-users", "events", "rule-helpers", "phone-auth", "public-users"];
248
+ let skipPaths = ["collection-data", "users", "staged-users", "events", "rule-helpers", "phone-auth", "public-users", "topic-queue"];
241
249
  let ruleHelper = get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data;
242
250
  return !(collectionPath in skipPaths) &&
243
251
  !(permissionCheck == "write" &&