forked from lacrypta/bar-menu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfirestore.rules
105 lines (89 loc) · 3.37 KB
/
firestore.rules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
//*************************//
//******** Functions ********//
//*************************//
function filterCreateOrder(orderData) {
return
validateOrderSchema(orderData) &&
orderData.status == 'pending';
}
function filterUpdateOrder(orderData) {
let affectedKeys = orderData.diff(resource.data).affectedKeys();
return
affectedKeys.hasOnly(["paymentId", "user"]) &&
!(affectedKeys.hasAny(["user"]) && !validateUserSchema(orderData.user)) &&
!(affectedKeys.hasAny(["paymentId"]) && !validatePaymentId(orderData.paymentId, resource.id));
}
function filterCreatePayment(paymentData) {
return
validatePaymentSchema(paymentData) &&
paymentData.status == 'waiting' &&
!paymentData.keys().hasAny(["preference_id"]) &&
get(/databases/$(database)/documents/orders/$(paymentData.orderId)).data.status in ['pending', 'processing'];
}
// Order Schema
function validateOrderSchema(orderData) {
return
orderData.keys().hasOnly(['user', 'status', 'createdAt']) &&
validateUserSchema(orderData.user) &&
orderData.createdAt == request.time &&
orderData.status in ['pending', 'processing', 'completed', 'cancelled'];
}
// User Schema
function validateUserSchema(userData) {
return
userData.keys().hasOnly(['fullname', 'email']) &&
userData.fullname is string &&
userData.fullname.size() > 3 &&
isValidEmail(userData.email);
}
// Payment Schema
function validatePaymentSchema(paymentData) {
let limitedKeys = ['method', 'amount', 'preference_id', 'address', 'secret', 'status', 'createdAt', 'orderId'];
return
paymentData.keys().hasOnly(limitedKeys) &&
paymentData.amount > 0 &&
paymentData.method in ['crypto', 'mercadopago', 'invitation', 'bank'] &&
paymentData.status in ['waiting', 'executing', 'paid', 'cancelled'] &&
paymentData.createdAt == request.time &&
exists(/databases/$(database)/documents/orders/$(paymentData.orderId));
}
function validatePaymentId(paymentId, orderId) {
return get(/databases/$(database)/documents/payments/$(paymentId)).data.orderId == orderId;
}
// Only Admin User
function isAdmin() {
return request.auth.token.adminAccount == true;
}
// Validate email
function isValidEmail(email) {
return email.matches('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,5}$');
}
//*************************//
//******** Matches ********//
//*************************//
// Admin full read access
allow read: if isAdmin();
// Orders
match /orders/{orderId} {
allow read: if isAdmin();
allow get: if true;
allow create: if filterCreateOrder(request.resource.data);
allow update: if filterUpdateOrder(request.resource.data);
// allow write: if isAdmin() && validateOrderSchema(request.resource.data);
}
// Payments
match /payments/{paymentId} {
allow get: if true;
allow write: if isAdmin();
allow create: if filterCreatePayment(request.resource.data);
}
// Purchases
match /purchases/{purchaseId} {
allow get: if true;
allow write: if isAdmin();
}
}
}