@edgedev/create-edge-app 1.0.48 → 1.0.49
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/.nvmrc +1 -0
- package/components/ui/sidebar/Sidebar.vue +85 -0
- package/components/ui/sidebar/SidebarContent.vue +17 -0
- package/components/ui/sidebar/SidebarFooter.vue +17 -0
- package/components/ui/sidebar/SidebarGroup.vue +17 -0
- package/components/ui/sidebar/SidebarGroupAction.vue +27 -0
- package/components/ui/sidebar/SidebarGroupContent.vue +17 -0
- package/components/ui/sidebar/SidebarGroupLabel.vue +24 -0
- package/components/ui/sidebar/SidebarHeader.vue +17 -0
- package/components/ui/sidebar/SidebarInput.vue +21 -0
- package/components/ui/sidebar/SidebarInset.vue +20 -0
- package/components/ui/sidebar/SidebarMenu.vue +17 -0
- package/components/ui/sidebar/SidebarMenuAction.vue +34 -0
- package/components/ui/sidebar/SidebarMenuBadge.vue +25 -0
- package/components/ui/sidebar/SidebarMenuButton.vue +49 -0
- package/components/ui/sidebar/SidebarMenuButtonChild.vue +33 -0
- package/components/ui/sidebar/SidebarMenuItem.vue +17 -0
- package/components/ui/sidebar/SidebarMenuSkeleton.vue +33 -0
- package/components/ui/sidebar/SidebarMenuSub.vue +21 -0
- package/components/ui/sidebar/SidebarMenuSubButton.vue +35 -0
- package/components/ui/sidebar/SidebarMenuSubItem.vue +9 -0
- package/components/ui/sidebar/SidebarProvider.vue +80 -0
- package/components/ui/sidebar/SidebarRail.vue +32 -0
- package/components/ui/sidebar/SidebarSeparator.vue +18 -0
- package/components/ui/sidebar/SidebarTrigger.vue +26 -0
- package/components/ui/sidebar/index.ts +59 -0
- package/components/ui/sidebar/utils.ts +19 -0
- package/package.json +1 -1
- package/firestore.rules +0 -342
- package/firestore.rules.backup +0 -323
- package/functions/.env.dev +0 -7
- package/functions/.env.prod +0 -7
- package/functions/index.js +0 -7
- package/functions/package.json +0 -37
- package/functions/stripe.js +0 -103
- package/storage.rules +0 -61
package/firestore.rules.backup
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
rules_version = '2';
|
|
2
|
-
// #EDGE FIREBASE RULES START
|
|
3
|
-
service cloud.firestore {
|
|
4
|
-
|
|
5
|
-
match /databases/{database}/documents/phone-auth/{phone} {
|
|
6
|
-
allow read: if false;
|
|
7
|
-
allow create: if false;
|
|
8
|
-
allow update: if false;
|
|
9
|
-
allow delete: if false;
|
|
10
|
-
}
|
|
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
|
-
|
|
20
|
-
match /databases/{database}/documents/public-users/{user} {
|
|
21
|
-
allow read: if request.auth != null;
|
|
22
|
-
allow list: if request.auth != null;
|
|
23
|
-
allow create: if false;
|
|
24
|
-
allow update: if false;
|
|
25
|
-
allow delete: if false;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
match /databases/{database}/documents/events/{event} {
|
|
29
|
-
allow read: if false;
|
|
30
|
-
allow create: if false;
|
|
31
|
-
allow update: if false;
|
|
32
|
-
allow delete: if false;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
match /databases/{database}/documents/rule-helpers/{helper} {
|
|
36
|
-
allow read: if false;
|
|
37
|
-
allow create: if request.auth.uid == request.resource.data.uid;
|
|
38
|
-
allow update: if request.auth.uid == request.resource.data.uid;
|
|
39
|
-
allow delete: if false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
match /databases/{database}/documents/users/{user} {
|
|
43
|
-
function readSelf() {
|
|
44
|
-
return resource == null ||
|
|
45
|
-
(
|
|
46
|
-
"userId" in resource.data &&
|
|
47
|
-
resource.data.userId == request.auth.uid
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
allow read: if readSelf();
|
|
52
|
-
allow create: if false;
|
|
53
|
-
allow update: if false;
|
|
54
|
-
allow delete: if false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
match /databases/{database}/documents/collection-data/{collectionPath} {
|
|
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]);
|
|
64
|
-
}
|
|
65
|
-
function canAssign() {
|
|
66
|
-
let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
|
|
67
|
-
let ruleHelper = get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data['edge-assignment-helper'];
|
|
68
|
-
return collectionPath.matches("^" + ruleHelper[collectionPath].permissionCheckPath + ".*$") &&
|
|
69
|
-
(
|
|
70
|
-
"specialPermissions" in user &&
|
|
71
|
-
ruleHelper[collectionPath].permissionCheckPath in user.specialPermissions &&
|
|
72
|
-
"assign" in user.specialPermissions[ruleHelper[collectionPath].permissionCheckPath] &&
|
|
73
|
-
user.specialPermissions[ruleHelper[collectionPath].permissionCheckPath]["assign"]
|
|
74
|
-
) ||
|
|
75
|
-
(
|
|
76
|
-
"roles" in user &&
|
|
77
|
-
ruleHelper[collectionPath].permissionCheckPath in user.roles &&
|
|
78
|
-
"role" in user.roles[ruleHelper[collectionPath].permissionCheckPath] &&
|
|
79
|
-
getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, collectionPath, "assign")
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
allow read: if request.auth != null; // All signed in users can read collection-data
|
|
83
|
-
allow create: if canAssign();
|
|
84
|
-
allow update: if canAssign();
|
|
85
|
-
allow delete: if canAssign();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
match /databases/{database}/documents/staged-users/{user} {
|
|
89
|
-
|
|
90
|
-
function canUpdate() {
|
|
91
|
-
let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
|
|
92
|
-
let ruleHelper = get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data;
|
|
93
|
-
|
|
94
|
-
return (
|
|
95
|
-
request.auth.uid == request.resource.data.uid &&
|
|
96
|
-
(
|
|
97
|
-
(
|
|
98
|
-
(
|
|
99
|
-
request.resource.data.userId == resource.data.userId ||
|
|
100
|
-
resource.data.userId == ""
|
|
101
|
-
) &&
|
|
102
|
-
(
|
|
103
|
-
request.resource.data.userId == request.auth.uid ||
|
|
104
|
-
request.resource.data.templateUserId == request.auth.uid
|
|
105
|
-
)
|
|
106
|
-
) ||
|
|
107
|
-
(
|
|
108
|
-
request.resource.data.userId == resource.data.userId &&
|
|
109
|
-
"edge-assignment-helper" in ruleHelper &&
|
|
110
|
-
permissionUpdatesCheck(user, ruleHelper, "roles") &&
|
|
111
|
-
permissionUpdatesCheck(user, ruleHelper, "specialPermssions")
|
|
112
|
-
)
|
|
113
|
-
)
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function permissionUpdatesCheck(user, ruleHelper, permissionType) {
|
|
120
|
-
return !(permissionType in request.resource.data) ||
|
|
121
|
-
(
|
|
122
|
-
resource.data.userId == request.auth.uid &&
|
|
123
|
-
request.resource.data[permissionType].keys().hasOnly(resource.data[permissionType].keys())
|
|
124
|
-
) ||
|
|
125
|
-
(
|
|
126
|
-
resource.data.userId != request.auth.uid &&
|
|
127
|
-
permissionCheck(permissionType, user, ruleHelper)
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
function permissionCheck(permissionType, user, ruleHelper) {
|
|
131
|
-
let lastPathUpdated = ruleHelper["edge-assignment-helper"].fullPath;
|
|
132
|
-
let permissionCheckPath = ruleHelper["edge-assignment-helper"].permissionCheckPath;
|
|
133
|
-
return request.resource.data[permissionType].diff(resource.data[permissionType]).affectedKeys().size() == 0 ||
|
|
134
|
-
(
|
|
135
|
-
request.resource.data[permissionType].diff(resource.data[permissionType]).affectedKeys().size() == 1 &&
|
|
136
|
-
request.resource.data[permissionType].diff(resource.data[permissionType]).affectedKeys() == [lastPathUpdated].toSet() &&
|
|
137
|
-
(
|
|
138
|
-
permissionCheckPath == "-" ||
|
|
139
|
-
lastPathUpdated.matches("^" + permissionCheckPath + ".*$")
|
|
140
|
-
) &&
|
|
141
|
-
(
|
|
142
|
-
(
|
|
143
|
-
"roles" in user &&
|
|
144
|
-
getRolePermission(user.roles[permissionCheckPath].role, permissionCheckPath, "assign")
|
|
145
|
-
) ||
|
|
146
|
-
(
|
|
147
|
-
"specialPermissions" in user &&
|
|
148
|
-
permissionCheckPath in user.specialPermissions &&
|
|
149
|
-
"assign" in user.specialPermissions[permissionCheckPath] &&
|
|
150
|
-
user.specialPermissions[permissionCheckPath]["assign"]
|
|
151
|
-
)
|
|
152
|
-
)
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function canAssign(user, ruleHelper) {
|
|
157
|
-
return request.auth != null &&
|
|
158
|
-
"edge-assignment-helper" in ruleHelper &&
|
|
159
|
-
(
|
|
160
|
-
(
|
|
161
|
-
"roles" in user &&
|
|
162
|
-
ruleHelper["edge-assignment-helper"].permissionCheckPath in user.roles &&
|
|
163
|
-
getRolePermission(user.roles[ruleHelper["edge-assignment-helper"].permissionCheckPath].role, ruleHelper["edge-assignment-helper"].permissionCheckPath, 'assign')
|
|
164
|
-
) ||
|
|
165
|
-
(
|
|
166
|
-
"specialPermissions" in user &&
|
|
167
|
-
ruleHelper["edge-assignment-helper"].permissionCheckPath in user.specialPermissions &&
|
|
168
|
-
"assign" in user.specialPermissions[ruleHelper["edge-assignment-helper"].permissionCheckPath] &&
|
|
169
|
-
user.specialPermissions[ruleHelper["edge-assignment-helper"].permissionCheckPath]["assign"]
|
|
170
|
-
)
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function canAssignSubCreatePath(user, ruleHelper) {
|
|
175
|
-
let permissionCheckPath = ruleHelper["edge-assignment-helper"].permissionCheckPath;
|
|
176
|
-
return (
|
|
177
|
-
!("subCreate" in request.resource.data) ||
|
|
178
|
-
(
|
|
179
|
-
"subCreate" in request.resource.data &&
|
|
180
|
-
request.resource.data.subCreate.keys().size() == 0
|
|
181
|
-
)
|
|
182
|
-
)||
|
|
183
|
-
(
|
|
184
|
-
permissionCheckPath == "-" ||
|
|
185
|
-
request.resource.data.subCreate.rootPath.matches("^" + permissionCheckPath + ".*$")
|
|
186
|
-
) &&
|
|
187
|
-
(
|
|
188
|
-
(
|
|
189
|
-
"roles" in user &&
|
|
190
|
-
permissionCheckPath in user.roles &&
|
|
191
|
-
getRolePermission(user.roles[permissionCheckPath].role, permissionCheckPath, "assign")
|
|
192
|
-
) ||
|
|
193
|
-
(
|
|
194
|
-
"specialPermissions" in user &&
|
|
195
|
-
permissionCheckPath in user.specialPermissions &&
|
|
196
|
-
"assign" in user.specialPermissions[permissionCheckPath] &&
|
|
197
|
-
user.specialPermissions[permissionCheckPath]["assign"]
|
|
198
|
-
)
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function canList() {
|
|
204
|
-
let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
|
|
205
|
-
let ruleHelper = get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data;
|
|
206
|
-
return canAssign(user, ruleHelper);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function canCreate() {
|
|
210
|
-
let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
|
|
211
|
-
let ruleHelper = get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data;
|
|
212
|
-
return noPermissionData() && canAssign(user, ruleHelper) && canAssignSubCreatePath(user, ruleHelper);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function noPermissionData() {
|
|
216
|
-
return request.resource.data.roles.size() == 0 && request.resource.data.specialPermissions.size() == 0;
|
|
217
|
-
}
|
|
218
|
-
|
|
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
|
-
}
|
|
225
|
-
|
|
226
|
-
function canGet () {
|
|
227
|
-
return resource == null ||
|
|
228
|
-
("userId" in resource.data && resource.data.userId == "") ||
|
|
229
|
-
("userId" in resource.data && resource.data.userId == request.auth.uid) ||
|
|
230
|
-
canAssign(get(/databases/$(database)/documents/users/$(request.auth.uid)).data, get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data);
|
|
231
|
-
}
|
|
232
|
-
allow get: if canGet();
|
|
233
|
-
allow list: if canList();
|
|
234
|
-
allow create: if canCreate();
|
|
235
|
-
allow update: if canUpdate();
|
|
236
|
-
allow delete: if false // TODO if isTemplate is true... can delete... otherwise users never deleted just removed from collection paths
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
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]);
|
|
245
|
-
}
|
|
246
|
-
function checkPermission(collectionPath, permissionCheck) {
|
|
247
|
-
let user = get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
|
|
248
|
-
let skipPaths = ["collection-data", "users", "staged-users", "events", "rule-helpers", "phone-auth", "public-users", "topic-queue"];
|
|
249
|
-
let ruleHelper = get(/databases/$(database)/documents/rule-helpers/$(request.auth.uid)).data;
|
|
250
|
-
return !(collectionPath in skipPaths) &&
|
|
251
|
-
!(permissionCheck == "write" &&
|
|
252
|
-
(
|
|
253
|
-
("stripeCustomerId" in request.resource.data && (!("stripeCustomerId" in resource.data) || resource.data.stripeCustomerId != request.resource.data.stripeCustomerId)) ||
|
|
254
|
-
("stripeSubscription" in request.resource.data && (!("stripeSubscription" in resource.data) || resource.data.stripeSubscription != request.resource.data.stripeSubscription))
|
|
255
|
-
)
|
|
256
|
-
) &&
|
|
257
|
-
request.auth != null &&
|
|
258
|
-
collectionPath in ruleHelper &&
|
|
259
|
-
"permissionCheckPath" in ruleHelper[collectionPath] &&
|
|
260
|
-
(
|
|
261
|
-
ruleHelper[collectionPath].permissionCheckPath == "-" ||
|
|
262
|
-
collectionPath.matches("^" + ruleHelper[collectionPath].permissionCheckPath + ".*$")
|
|
263
|
-
) &&
|
|
264
|
-
(
|
|
265
|
-
(
|
|
266
|
-
"roles" in user &&
|
|
267
|
-
ruleHelper[collectionPath].permissionCheckPath in user.roles &&
|
|
268
|
-
getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, ruleHelper[collectionPath].permissionCheckPath, permissionCheck)
|
|
269
|
-
) ||
|
|
270
|
-
(
|
|
271
|
-
"specialPermissions" in user &&
|
|
272
|
-
ruleHelper[collectionPath].permissionCheckPath in user.specialPermissions &&
|
|
273
|
-
permissionCheck in user.specialPermissions[ruleHelper[collectionPath].permissionCheckPath] &&
|
|
274
|
-
user.specialPermissions[ruleHelper[collectionPath].permissionCheckPath][permissionCheck]
|
|
275
|
-
)
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
match /{seg2} {
|
|
279
|
-
allow get: if checkPermission(seg1 + "-" + seg2, "read");
|
|
280
|
-
allow list: if checkPermission(seg1, "read");
|
|
281
|
-
allow create: if request.auth.uid == request.resource.data.uid && checkPermission(seg1, "write");
|
|
282
|
-
allow update: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2, "write");
|
|
283
|
-
allow delete: if checkPermission(seg1, "delete");
|
|
284
|
-
match /{seg3} {
|
|
285
|
-
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "read");
|
|
286
|
-
allow list: if checkPermission(seg1 + "-" + seg2, "read");
|
|
287
|
-
allow create: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2, "write");
|
|
288
|
-
allow update: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3, "write");
|
|
289
|
-
allow delete: if checkPermission(seg1 + "-" + seg2, "delete");
|
|
290
|
-
match /{seg4} {
|
|
291
|
-
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "read");
|
|
292
|
-
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "read");
|
|
293
|
-
allow create: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3, "write");
|
|
294
|
-
allow update: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "write");
|
|
295
|
-
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3, "delete");
|
|
296
|
-
|
|
297
|
-
match /{seg5} {
|
|
298
|
-
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "read");
|
|
299
|
-
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "read");
|
|
300
|
-
allow create: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "write");
|
|
301
|
-
allow update: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "write");
|
|
302
|
-
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4, "delete");
|
|
303
|
-
match /{seg6} {
|
|
304
|
-
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "read");
|
|
305
|
-
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "read");
|
|
306
|
-
allow create: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "write");
|
|
307
|
-
allow update: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "write");
|
|
308
|
-
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5, "delete");
|
|
309
|
-
match /{seg7} {
|
|
310
|
-
allow get: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6 + "-" + seg7, "read");
|
|
311
|
-
allow list: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "read");
|
|
312
|
-
allow create: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "write");
|
|
313
|
-
allow update: if request.auth.uid == request.resource.data.uid && checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6 + "-" + seg7, "write");
|
|
314
|
-
allow delete: if checkPermission(seg1 + "-" + seg2 + "-" + seg3 + "-" + seg4 + "-" + seg5 + "-" + seg6, "delete");
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
// #EDGE FIREBASE RULES END
|
package/functions/.env.dev
DELETED
package/functions/.env.prod
DELETED
package/functions/index.js
DELETED
package/functions/package.json
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "functions",
|
|
3
|
-
"private": true,
|
|
4
|
-
"description": "Cloud Functions for Firebase",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"engines": {
|
|
7
|
-
"node": "16"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"serve": "firebase emulators:start --only functions",
|
|
11
|
-
"shell": "firebase functions:shell",
|
|
12
|
-
"start": "npm run shell",
|
|
13
|
-
"deploy": "firebase deploy --only functions",
|
|
14
|
-
"logs": "firebase functions:log"
|
|
15
|
-
},
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"@aws-sdk/client-s3": "^3.582.0",
|
|
18
|
-
"@aws-sdk/s3-request-presigner": "^3.582.0",
|
|
19
|
-
"@google-cloud/pubsub": "^4.9.0",
|
|
20
|
-
"aws-sdk": "^2.1692.0",
|
|
21
|
-
"axios": "^1.7.2",
|
|
22
|
-
"crypto": "^1.0.1",
|
|
23
|
-
"dotenv": "^16.4.7",
|
|
24
|
-
"exceljs": "^4.4.0",
|
|
25
|
-
"firebase-admin": "^13.0.2",
|
|
26
|
-
"firebase-functions": "^6.2.0",
|
|
27
|
-
"form-data": "^4.0.1",
|
|
28
|
-
"formidable-serverless": "^1.1.1",
|
|
29
|
-
"moment-timezone": "^0.5.46",
|
|
30
|
-
"openai": "^4.78.1",
|
|
31
|
-
"stripe": "^13.11.0",
|
|
32
|
-
"twilio": "^4.23.0"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"firebase-functions-test": "^0.2.0"
|
|
36
|
-
}
|
|
37
|
-
}
|
package/functions/stripe.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
const stripe = require('stripe')(process.env.STRIPE_API_KEY)
|
|
2
|
-
const { onCall, HttpsError, logger, getFirestore, functions, admin, twilio, db, onRequest } = require('./config.js')
|
|
3
|
-
|
|
4
|
-
exports.redirectToBilling = onCall(async (request) => {
|
|
5
|
-
const data = request.data
|
|
6
|
-
const auth = request.auth
|
|
7
|
-
|
|
8
|
-
if (data.uid !== auth.uid) {
|
|
9
|
-
throw new HttpsError('failed-precondition', 'The function must be called by the user who is to be redirected.')
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const userDoc = await db.collection('staged-users').doc(data.uid).get()
|
|
13
|
-
if (!userDoc.exists) {
|
|
14
|
-
throw new HttpsError('not-found', 'No user found for the provided ID.')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const collectionPaths = userDoc.data().collectionPaths
|
|
18
|
-
if (!collectionPaths || collectionPaths.length === 0) {
|
|
19
|
-
throw new HttpsError('not-found', 'No collection paths found for the user.')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const orgDoc = await db.doc(collectionPaths[0].replace('-', '/')).get()
|
|
23
|
-
if (!orgDoc.exists) {
|
|
24
|
-
throw new HttpsError('not-found', 'No organization found for the user.')
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const stripeCustomerId = orgDoc.data().stripeCustomerId
|
|
28
|
-
if (!stripeCustomerId) {
|
|
29
|
-
throw new HttpsError('not-found', 'No Stripe customer ID found for the organization.')
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const session = await stripe.billingPortal.sessions.create({
|
|
33
|
-
customer: stripeCustomerId,
|
|
34
|
-
return_url: process.env.STRIPE_RETURN_URL,
|
|
35
|
-
})
|
|
36
|
-
return { url: session.url }
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
exports.webhook = onRequest(async (request, response) => {
|
|
40
|
-
let event
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
event = stripe.webhooks.constructEvent(request.rawBody, request.headers['stripe-signature'], process.env.STRIPE_SECRET)
|
|
44
|
-
}
|
|
45
|
-
catch (err) {
|
|
46
|
-
await db.collection('stripe').add({
|
|
47
|
-
message: err.message,
|
|
48
|
-
name: err.name,
|
|
49
|
-
stack: err.stack,
|
|
50
|
-
})
|
|
51
|
-
response.status(400).send(`Webhook Error: ${err.message}`)
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const session = event.data.object
|
|
56
|
-
const client_reference_id = session.client_reference_id
|
|
57
|
-
|
|
58
|
-
let docRef
|
|
59
|
-
if (client_reference_id) {
|
|
60
|
-
// Check if client_reference_id exists
|
|
61
|
-
docRef = db.collection('organizations').doc(client_reference_id)
|
|
62
|
-
}
|
|
63
|
-
else if (session.customer) {
|
|
64
|
-
// If client_reference_id doesn't exist, check if session.customer exists
|
|
65
|
-
const orgsSnapshot = await db.collection('organizations').where('stripeCustomerId', '==', session.customer).get()
|
|
66
|
-
if (!orgsSnapshot.empty) {
|
|
67
|
-
docRef = orgsSnapshot.docs[0].ref
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (docRef) {
|
|
72
|
-
const doc = await docRef.get()
|
|
73
|
-
if (doc.exists) {
|
|
74
|
-
// Record any event related to the client_reference_id
|
|
75
|
-
const date = new Date()
|
|
76
|
-
const formattedDate = `${date.getFullYear()}${(`0${date.getMonth() + 1}`).slice(-2)}${(`0${date.getDate()}`).slice(-2)}${(`0${date.getHours()}`).slice(-2)}${(`0${date.getMinutes()}`).slice(-2)}${(`0${date.getSeconds()}`).slice(-2)}${(`00${date.getMilliseconds()}`).slice(-3)}`
|
|
77
|
-
const docId = `${event.type}-${formattedDate}`
|
|
78
|
-
await docRef.collection('stripe').doc(docId).set({ session, event })
|
|
79
|
-
|
|
80
|
-
// Handle subscription events
|
|
81
|
-
|
|
82
|
-
if (session.customer) {
|
|
83
|
-
await docRef.update({ stripeCustomerId: session.customer })
|
|
84
|
-
}
|
|
85
|
-
if (session?.lines?.data[0]?.plan?.product) {
|
|
86
|
-
await docRef.update({ stripeProductId: session.lines.data[0].plan.product })
|
|
87
|
-
}
|
|
88
|
-
if (session?.lines?.data[0]?.price?.id) {
|
|
89
|
-
await docRef.update({ stripePriceId: session.lines.data[0].price.id })
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (['customer.subscription.created', 'customer.subscription.updated', 'customer.subscription.deleted'].includes(event.type)) {
|
|
93
|
-
await docRef.update({ stripeSubscription: session.status })
|
|
94
|
-
}
|
|
95
|
-
response.json({ received: true })
|
|
96
|
-
return
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// If no matching organization, store to a root collection called 'stripe'
|
|
101
|
-
await db.collection('stripe').add(session)
|
|
102
|
-
response.json({ received: true })
|
|
103
|
-
})
|
package/storage.rules
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
rules_version = '2';
|
|
2
|
-
service firebase.storage {
|
|
3
|
-
match /b/{bucket}/o {
|
|
4
|
-
match /{allPaths=**} {
|
|
5
|
-
allow read, write: if false;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
// #EDGE FIREBASE RULES START
|
|
10
|
-
service firebase.storage {
|
|
11
|
-
match /b/{bucket}/o {
|
|
12
|
-
// Match the file path structure you're using, simulating the Firestore document path structure for permissions.
|
|
13
|
-
function getRolePermission(role, permissionCheck) {
|
|
14
|
-
let permissions = {
|
|
15
|
-
'admin': {'assign': true, 'delete': true, 'read': true, 'write': true},
|
|
16
|
-
'editor': {'assign': false, 'delete': true, 'read': true, 'write': true},
|
|
17
|
-
'user': {'assign': false, 'delete': false, 'read': true, 'write': false},
|
|
18
|
-
'writer': {'assign': false, 'delete': false, 'read': true, 'write': true}
|
|
19
|
-
};
|
|
20
|
-
return permissions[role][permissionCheck];
|
|
21
|
-
}
|
|
22
|
-
function checkPermission(permissionCheck, collectionPath) {
|
|
23
|
-
let user = firestore.get(/databases/(default)/documents/users/$(request.auth.uid)).data;
|
|
24
|
-
let ruleHelper = firestore.get(/databases/(default)/documents/rule-helpers/$(request.auth.uid)).data;
|
|
25
|
-
return request.auth != null &&
|
|
26
|
-
collectionPath in ruleHelper &&
|
|
27
|
-
"permissionCheckPath" in ruleHelper[collectionPath] &&
|
|
28
|
-
(
|
|
29
|
-
ruleHelper[collectionPath].permissionCheckPath == "-" ||
|
|
30
|
-
collectionPath.matches("^" + ruleHelper[collectionPath].permissionCheckPath + ".*$")
|
|
31
|
-
) &&
|
|
32
|
-
(
|
|
33
|
-
(
|
|
34
|
-
"roles" in user &&
|
|
35
|
-
ruleHelper[collectionPath].permissionCheckPath in user.roles &&
|
|
36
|
-
getRolePermission(user.roles[ruleHelper[collectionPath].permissionCheckPath].role, permissionCheck)
|
|
37
|
-
) ||
|
|
38
|
-
(
|
|
39
|
-
"specialPermissions" in user &&
|
|
40
|
-
ruleHelper[collectionPath].permissionCheckPath in user.specialPermissions &&
|
|
41
|
-
permissionCheck in user.specialPermissions[ruleHelper[collectionPath].permissionCheckPath] &&
|
|
42
|
-
user.specialPermissions[ruleHelper[collectionPath].permissionCheckPath][permissionCheck]
|
|
43
|
-
)
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
match /public/{fileId} {
|
|
47
|
-
// Public directory with special rules
|
|
48
|
-
allow read: if true; // Unrestricted read access
|
|
49
|
-
allow write, delete: if request.auth != null; // Write and delete require authentication
|
|
50
|
-
}
|
|
51
|
-
match /{dir}/{fileId} {
|
|
52
|
-
// General read permission check based on Firestore data
|
|
53
|
-
allow read: if checkPermission("read", dir);
|
|
54
|
-
// General write permission check, including creating and updating files
|
|
55
|
-
allow write: if checkPermission("write", dir);
|
|
56
|
-
// General delete permission check
|
|
57
|
-
allow delete: if checkPermission("write", dir);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// #EDGE FIREBASE RULES END
|