-
Notifications
You must be signed in to change notification settings - Fork 2
/
firestore.rules
131 lines (115 loc) · 5.77 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /lobbies/{code} {
allow get: if true;
function lobbyData(){
return get(/databases/$(database)/documents/lobbies/$(code)).data;
}
function inLobby(){
return request.auth.uid in lobbyData().uids;
}
function isAlive(){
return request.auth.uid in lobbyData().alivePlayers;
}
match /privatePlayers/{uid} {
allow get: if request.auth.uid == uid;
}
match /promptAnswers/{uid} {
function validAnswer() {
return request.resource.data.keys().hasOnly(['answer'])
&& request.resource.data.answer is string
&& 0 < request.resource.data.answer.size() && request.resource.data.answer.size() <= 50
&& request.resource.data.answer == request.resource.data.answer.trim();
}
allow write: if request.auth.uid == uid && validAnswer() && inLobby() && lobbyData().state == "PROMPT";
}
match /chatRooms/{roomId} {
// functions to use in chatmessages
function roomData(){
return get(/databases/$(database)/documents/lobbies/$(code)/chatRooms/$(roomId)).data
}
function inPair(){
return request.auth.uid in roomData().pair
}
function isStalker(){
return get(/databases/$(database)/documents/lobbies/$(code)/privatePlayers/$(request.auth.uid)).data.stalker == true;
}
function canRead(){
return inPair() || request.auth.uid in roomData().viewers ;
}
// firestore didn't like me using the above function for chatroom
// I think its because the info is in the resource object
allow read: if request.auth.uid in resource.data.pair || request.auth.uid in resource.data.viewers || isStalker() || !isAlive();
match /chatMessages/{messageId}{
function validateChatMessage() {
return request.resource.data.keys().hasOnly(['sender', 'text', 'timestamp'])
&& request.resource.data.sender == request.auth.uid && request.resource.data.text is string
&& request.resource.data.text.size() > 0 && request.resource.data.text.size() <= 100
&& request.resource.data.text.trim() == request.resource.data.text
&& request.resource.data.timestamp is timestamp && request.resource.data.timestamp == request.time;
}
allow read: if canRead();
allow create: if inPair() && validateChatMessage();
}
}
match /chatMessages/{messageId}{
function validateLobbyChatMessage() {
return request.resource.data.keys().hasOnly(['sender', 'text', 'timestamp', 'alive'])
&& request.resource.data.sender == request.auth.uid && request.resource.data.text is string
&& request.resource.data.text.size() > 0 && request.resource.data.text.size() <= 100
&& request.resource.data.text.trim() == request.resource.data.text
&& request.resource.data.timestamp is timestamp && request.resource.data.timestamp == request.time
&& request.resource.data.alive == isAlive();
}
function chatSenderAlive(){
return resource.data.alive;
}
//if in lobby and message sender is alive allow read
//if in lobby and player is dead allow read
allow read: if inLobby() && (chatSenderAlive() || ! isAlive());
allow create: if validateLobbyChatMessage();
}
match /votes/{uid} {
function checkTarget(){
return request.resource.data.keys().hasOnly(['target'])
&& (request.resource.data.target == null || (request.resource.data.target is string
&& request.resource.data.target in lobbyData().alivePlayers));
}
function notPastTarget(){
return checkTarget() && request.resource.data.target != resource.data.target;
}
allow get: if request.auth.uid == uid;
allow create: if request.auth.uid == uid && inLobby() && checkTarget() && isAlive();
allow update: if request.auth.uid == uid && inLobby() && notPastTarget() && isAlive();
}
}
match /users/{userId} {
function validateDisplayAndAvatar(){
return request.resource.data.keys().hasOnly(['displayName', 'avatar', 'catWins', 'catfishWins', 'playedAsCat', 'playedAsCatfish'])
&& request.resource.data.displayName is string && request.resource.data.displayName.size() >= 3
&& request.resource.data.displayName.size() <= 15
&& request.resource.data.displayName == request.resource.data.displayName.trim()
&& request.resource.data.displayName.matches('[A-Za-z0-9-_ ]+')
&& request.resource.data.avatar is number && int(request.resource.data.avatar) == request.resource.data.avatar
&& request.resource.data.avatar >= 0 && request.resource.data.avatar <=12;
}
function statsAreZero() {
return request.resource.data.catWins == 0
&& request.resource.data.catfishWins == 0
&& request.resource.data.playedAsCat == 0
&& request.resource.data.playedAsCatfish == 0;
}
function statsAreNotChanged(){
return request.resource.data.catWins == resource.data.catWins
&& request.resource.data.catfishWins == resource.data.catfishWins
&& request.resource.data.playedAsCat == resource.data.playedAsCat
&& request.resource.data.playedAsCatfish == resource.data.playedAsCatfish
}
// allows anyone to read that information
allow read;
allow create: if request.auth.uid == userId && validateDisplayAndAvatar() && statsAreZero();
allow update: if request.auth.uid == userId && validateDisplayAndAvatar() && statsAreNotChanged();
}
}
}