forked from 20266142/Overheard
69 lines
2.8 KiB
Plaintext
69 lines
2.8 KiB
Plaintext
rules_version = '2';
|
|
service cloud.firestore {
|
|
match /databases/{database}/documents {
|
|
match /messages/{messageId} {
|
|
|
|
// anyone can read messages
|
|
allow read: if true;
|
|
|
|
// anyone can create a message
|
|
// text must exist and be under 240 characters
|
|
allow create: if
|
|
request.resource.data.text is string &&
|
|
request.resource.data.text.size() <= 240;
|
|
|
|
// the only update allowed is an echo
|
|
// echoCount and lastEchoAt fields can be changed
|
|
// this prevents anyone from editing the text of someone else's message
|
|
allow update: if
|
|
request.resource.data.diff(resource.data)
|
|
.affectedKeys().hasOnly(['echoCount', 'lastEchoAt']);
|
|
|
|
// nobody can delete messages through the client
|
|
allow delete: if false;
|
|
}
|
|
|
|
// --- "passport stamps" --------------------------------------------------
|
|
// each anonymous-auth user has their own users/{uid}/stamps/{geohash4}
|
|
// subcollection (see firebase/stamps.js) - request.auth.uid == userId
|
|
// means a device can only ever read/write its OWN stamps, never anyone
|
|
// else's. Stamps are permanent once earned: no update/delete from the
|
|
// client, and create is validated the same way the messages create rule
|
|
// above validates its fields.
|
|
match /users/{userId}/stamps/{stampId} {
|
|
allow read: if request.auth != null && request.auth.uid == userId;
|
|
|
|
allow create: if
|
|
request.auth != null && request.auth.uid == userId &&
|
|
request.resource.data.keys().hasAll(['geohash4', 'city', 'country', 'iconId', 'color', 'earnedAt']) &&
|
|
request.resource.data.geohash4 is string &&
|
|
request.resource.data.city is string &&
|
|
request.resource.data.country is string;
|
|
|
|
allow update: if false;
|
|
allow delete: if false;
|
|
}
|
|
|
|
// --- global "memory counter" (GlobalCountPill) -------------------------
|
|
// a single shared doc, meta/stats, holding totalMessagesEverPosted.
|
|
// anyone can read it (it's shown to every visitor); writes are limited to
|
|
// just that one field, same "only these fields can change" pattern as the
|
|
// echoCount update rule above, so this doc can't be hijacked to store
|
|
// arbitrary data.
|
|
match /meta/stats {
|
|
allow read: if true;
|
|
|
|
// first-ever write: only the counter field, and it must be a number
|
|
allow create: if
|
|
request.resource.data.keys().hasOnly(['totalMessagesEverPosted']) &&
|
|
request.resource.data.totalMessagesEverPosted is number;
|
|
|
|
// every later write (increment(1)) may only touch that same field
|
|
allow update: if
|
|
request.resource.data.diff(resource.data).affectedKeys().hasOnly(['totalMessagesEverPosted']);
|
|
|
|
// nobody can delete the counter through the client
|
|
allow delete: if false;
|
|
}
|
|
}
|
|
} |