@edgedev/firebase 2.1.61 → 2.1.63
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 +26 -1
- package/package.json +1 -1
- package/src/edgeFirebase.js +112 -2
package/edgeFirebase.ts
CHANGED
|
@@ -606,9 +606,34 @@ export const EdgeFirebase = class {
|
|
|
606
606
|
const userRef = doc(this.db, "staged-users", userRegister.registrationCode);
|
|
607
607
|
userSnap = await getDoc(userRef);
|
|
608
608
|
} catch (error) {
|
|
609
|
+
let errorMessage = error.message
|
|
610
|
+
|
|
611
|
+
switch (error.code) {
|
|
612
|
+
case 'permission-denied':
|
|
613
|
+
errorMessage = "This registration code is no longer valid or has already been used."
|
|
614
|
+
break
|
|
615
|
+
case 'unavailable':
|
|
616
|
+
errorMessage = "Your device or browser could not connect to the registration service. Please check your internet connection or try again using a different browser."
|
|
617
|
+
break
|
|
618
|
+
case 'not-found':
|
|
619
|
+
errorMessage = "This registration code does not exist. Please check for typos or contact support."
|
|
620
|
+
break
|
|
621
|
+
case 'deadline-exceeded':
|
|
622
|
+
errorMessage = "The request timed out. Please try again in a moment, or check your connection."
|
|
623
|
+
break
|
|
624
|
+
case 'internal':
|
|
625
|
+
errorMessage = "Something went wrong in your browser that prevented the registration from completing. Try refreshing or switching browsers."
|
|
626
|
+
break
|
|
627
|
+
case 'resource-exhausted':
|
|
628
|
+
errorMessage = "Too many requests from this device. Please wait a few minutes and try again."
|
|
629
|
+
break
|
|
630
|
+
case 'failed-precondition':
|
|
631
|
+
errorMessage = "Your browser is not supported or is blocking key features required for registration. Try updating or switching browsers."
|
|
632
|
+
break
|
|
633
|
+
}
|
|
609
634
|
return this.sendResponse({
|
|
610
635
|
success: false,
|
|
611
|
-
message:
|
|
636
|
+
message: errorMessage,
|
|
612
637
|
meta: {}
|
|
613
638
|
});
|
|
614
639
|
}
|
package/package.json
CHANGED
package/src/edgeFirebase.js
CHANGED
|
@@ -78,10 +78,14 @@ exports.fileDeleted = onObjectDeleted({ region: process.env.FIREBASE_STORAGE_BUC
|
|
|
78
78
|
const docId = event.data.metadata?.fileDocId
|
|
79
79
|
const toR2 = event.data.metadata?.toR2
|
|
80
80
|
const cloudflareImageId = event.data.metadata?.cloudflareImageId
|
|
81
|
+
const cloudflareVideoId = event.data.metadata?.cloudflareVideoId
|
|
81
82
|
const r2ProcessCompleted = event.data.metadata?.r2ProcessCompleted
|
|
82
83
|
if (cloudflareImageId) {
|
|
83
84
|
await deleteCloudflareImage(cloudflareImageId)
|
|
84
85
|
}
|
|
86
|
+
if (cloudflareVideoId) {
|
|
87
|
+
await deleteCloudflareVideo(cloudflareVideoId)
|
|
88
|
+
}
|
|
85
89
|
if (toR2) {
|
|
86
90
|
if (r2ProcessCompleted === 'true') {
|
|
87
91
|
await deleteR2File(event.data.metadata?.r2FilePath)
|
|
@@ -174,7 +178,7 @@ exports.toR2 = onObjectFinalized(
|
|
|
174
178
|
r2ProcessCompleted: 'true',
|
|
175
179
|
},
|
|
176
180
|
}
|
|
177
|
-
if (contentType.startsWith('image/')) {
|
|
181
|
+
if (contentType.startsWith('image/') && process.env.CF_IMAGES_TOKEN) {
|
|
178
182
|
try {
|
|
179
183
|
const cloudflareImage = await uploadToCloudflareImage({
|
|
180
184
|
r2FilePath,
|
|
@@ -184,7 +188,6 @@ exports.toR2 = onObjectFinalized(
|
|
|
184
188
|
fileName,
|
|
185
189
|
fileSize,
|
|
186
190
|
})
|
|
187
|
-
console.log(cloudflareImage)
|
|
188
191
|
|
|
189
192
|
updatedMetadata = {
|
|
190
193
|
metadata: {
|
|
@@ -205,6 +208,37 @@ exports.toR2 = onObjectFinalized(
|
|
|
205
208
|
}
|
|
206
209
|
}
|
|
207
210
|
|
|
211
|
+
if (contentType.startsWith('video/') && process.env.CF_IMAGES_TOKEN) {
|
|
212
|
+
try {
|
|
213
|
+
const cloudflareVideo = await uploadToCloudflareVideo({
|
|
214
|
+
r2FilePath,
|
|
215
|
+
r2URL,
|
|
216
|
+
fileDocId,
|
|
217
|
+
orgId,
|
|
218
|
+
fileName,
|
|
219
|
+
fileSize,
|
|
220
|
+
})
|
|
221
|
+
console.log(cloudflareVideo)
|
|
222
|
+
updatedMetadata = {
|
|
223
|
+
metadata: {
|
|
224
|
+
...event.data.metadata,
|
|
225
|
+
r2FilePath,
|
|
226
|
+
r2URL,
|
|
227
|
+
uploadCompletedToR2: 'true', // Add custom metadata after file save
|
|
228
|
+
r2ProcessCompleted: 'true',
|
|
229
|
+
cloudflareVideoId: cloudflareVideo.id,
|
|
230
|
+
cloudflareVideoPlayback: cloudflareVideo.playback,
|
|
231
|
+
cloudflareVideoThumbnail: cloudflareVideo.thumbnail,
|
|
232
|
+
cloudflareVideoPreview: cloudflareVideo.preview,
|
|
233
|
+
cloudflareUploadCompleted: true,
|
|
234
|
+
},
|
|
235
|
+
}
|
|
236
|
+
await docRef.set({ cloudflareVideoId: cloudflareVideo.id, cloudflareVideoPlayback: cloudflareVideo.playback, cloudflareVideoThumbnail: cloudflareVideo.thumbnail, cloudflareVideoPreview: cloudflareVideo.preview, cloudflareUploadCompleted: true }, { merge: true })
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
console.error('Cloudflare Video Upload Failed', e)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
208
242
|
await fileRef.setMetadata(updatedMetadata)
|
|
209
243
|
console.log(`File uploaded to Cloudflare R2: ${fileName}`)
|
|
210
244
|
}
|
|
@@ -699,3 +733,79 @@ async function deleteCloudflareImage(imageId) {
|
|
|
699
733
|
|
|
700
734
|
return true
|
|
701
735
|
}
|
|
736
|
+
|
|
737
|
+
async function uploadToCloudflareVideo({ r2FilePath, r2URL, fileDocId, orgId, fileSize }) {
|
|
738
|
+
const API_TOKEN = process.env.CF_IMAGES_TOKEN
|
|
739
|
+
const ACCOUNT_ID = process.env.CF_ACCOUNT_ID
|
|
740
|
+
|
|
741
|
+
const cleanedr2FilePath = r2FilePath
|
|
742
|
+
.replaceAll('/', '-')
|
|
743
|
+
.replace('.firebasestorage.app-organizations', '')
|
|
744
|
+
|
|
745
|
+
const metadata = {
|
|
746
|
+
orgId,
|
|
747
|
+
fileDocId,
|
|
748
|
+
fileName: cleanedr2FilePath,
|
|
749
|
+
fileSize,
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const body = {
|
|
753
|
+
url: r2URL,
|
|
754
|
+
meta: {
|
|
755
|
+
name: cleanedr2FilePath,
|
|
756
|
+
...metadata,
|
|
757
|
+
},
|
|
758
|
+
allowDownloads: true,
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const response = await fetch(
|
|
762
|
+
`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/stream/copy`,
|
|
763
|
+
{
|
|
764
|
+
method: 'POST',
|
|
765
|
+
headers: {
|
|
766
|
+
'Authorization': `Bearer ${API_TOKEN}`,
|
|
767
|
+
'Content-Type': 'application/json',
|
|
768
|
+
},
|
|
769
|
+
body: JSON.stringify(body),
|
|
770
|
+
},
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
const result = await response.json()
|
|
774
|
+
|
|
775
|
+
if (!result.success) {
|
|
776
|
+
const errorMessages = (result.errors || [])
|
|
777
|
+
.map(error => error.message || 'Unknown error')
|
|
778
|
+
.join('; ')
|
|
779
|
+
throw new Error(`Cloudflare Stream upload failed: ${errorMessages}`)
|
|
780
|
+
}
|
|
781
|
+
console.log(result.result)
|
|
782
|
+
const { uid, preview, playback, thumbnail } = result.result
|
|
783
|
+
|
|
784
|
+
return {
|
|
785
|
+
id: uid,
|
|
786
|
+
preview,
|
|
787
|
+
playback,
|
|
788
|
+
thumbnail,
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
async function deleteCloudflareVideo(videoId) {
|
|
793
|
+
const API_TOKEN = process.env.CF_IMAGES_TOKEN
|
|
794
|
+
const ACCOUNT_ID = process.env.CF_ACCOUNT_ID
|
|
795
|
+
|
|
796
|
+
const response = await fetch(
|
|
797
|
+
`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/stream/${videoId}`,
|
|
798
|
+
{
|
|
799
|
+
method: 'DELETE',
|
|
800
|
+
headers: {
|
|
801
|
+
Authorization: `Bearer ${API_TOKEN}`,
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
)
|
|
805
|
+
|
|
806
|
+
if (!response.ok) {
|
|
807
|
+
throw new Error(`Failed to delete Cloudflare video: ${response.statusText}`)
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
return true
|
|
811
|
+
}
|