2022-01-05 17:42:43 +00:00
|
|
|
rules_version = '2';
|
|
|
|
|
2022-04-29 23:35:56 +00:00
|
|
|
// To pick the right project: `firebase projects:list`, then `firebase use <project-name>`
|
2022-01-24 06:45:46 +00:00
|
|
|
// To deploy: `firebase deploy --only firestore:rules`
|
2022-01-05 17:42:43 +00:00
|
|
|
service cloud.firestore {
|
|
|
|
match /databases/{database}/documents {
|
|
|
|
|
2022-01-24 06:45:46 +00:00
|
|
|
function isAdmin() {
|
2022-07-16 19:52:59 +00:00
|
|
|
return request.auth.token.email in [
|
|
|
|
'akrolsmir@gmail.com',
|
|
|
|
'jahooma@gmail.com',
|
|
|
|
'taowell@gmail.com',
|
2022-08-23 00:50:59 +00:00
|
|
|
'abc.sinclair@gmail.com',
|
2022-08-25 13:05:26 +00:00
|
|
|
'manticmarkets@gmail.com',
|
2022-09-08 15:16:54 +00:00
|
|
|
'iansphilips@gmail.com',
|
2022-09-08 15:51:58 +00:00
|
|
|
'd4vidchee@gmail.com',
|
|
|
|
'federicoruizcassarino@gmail.com'
|
2022-07-16 19:52:59 +00:00
|
|
|
]
|
2022-01-24 06:45:46 +00:00
|
|
|
}
|
|
|
|
|
2022-06-26 21:42:42 +00:00
|
|
|
match /stats/stats {
|
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-01-05 17:42:43 +00:00
|
|
|
match /users/{userId} {
|
|
|
|
allow read;
|
2022-08-13 03:13:09 +00:00
|
|
|
allow update: if userId == request.auth.uid
|
2022-06-02 17:14:01 +00:00
|
|
|
&& request.resource.data.diff(resource.data).affectedKeys()
|
2022-08-24 16:49:53 +00:00
|
|
|
.hasOnly(['bio', 'bannerUrl', 'website', 'twitterHandle', 'discordHandle', 'followedCategories', 'lastPingTime','shouldShowWelcome', 'hasSeenContractFollowModal']);
|
2022-07-15 14:45:52 +00:00
|
|
|
// User referral rules
|
2022-08-13 03:13:09 +00:00
|
|
|
allow update: if userId == request.auth.uid
|
2022-07-15 14:45:52 +00:00
|
|
|
&& request.resource.data.diff(resource.data).affectedKeys()
|
2022-07-18 16:40:44 +00:00
|
|
|
.hasOnly(['referredByUserId', 'referredByContractId', 'referredByGroupId'])
|
2022-07-15 14:45:52 +00:00
|
|
|
// only one referral allowed per user
|
|
|
|
&& !("referredByUserId" in resource.data)
|
|
|
|
// user can't refer themselves
|
2022-08-13 03:13:09 +00:00
|
|
|
&& !(userId == request.resource.data.referredByUserId);
|
2022-07-15 14:45:52 +00:00
|
|
|
// quid pro quos enabled (only once though so nbd) - bc I can't make this work:
|
|
|
|
// && (get(/databases/$(database)/documents/users/$(request.resource.data.referredByUserId)).referredByUserId == resource.data.id);
|
2022-06-02 17:14:01 +00:00
|
|
|
}
|
2022-06-26 21:42:42 +00:00
|
|
|
|
2022-06-22 20:29:40 +00:00
|
|
|
match /{somePath=**}/portfolioHistory/{portfolioHistoryId} {
|
|
|
|
allow read;
|
|
|
|
}
|
2022-06-02 17:14:01 +00:00
|
|
|
|
2022-08-04 21:27:02 +00:00
|
|
|
match /{somePath=**}/challenges/{challengeId}{
|
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-08-24 16:49:53 +00:00
|
|
|
match /contracts/{contractId}/follows/{userId} {
|
|
|
|
allow read;
|
|
|
|
allow create, delete: if userId == request.auth.uid;
|
|
|
|
}
|
|
|
|
|
2022-08-04 21:27:02 +00:00
|
|
|
match /contracts/{contractId}/challenges/{challengeId}{
|
|
|
|
allow read;
|
|
|
|
allow create: if request.auth.uid == request.resource.data.creatorId;
|
|
|
|
// allow update if there have been no claims yet and if the challenge is still open
|
|
|
|
allow update: if request.auth.uid == resource.data.creatorId;
|
|
|
|
}
|
|
|
|
|
2022-06-02 17:14:01 +00:00
|
|
|
match /users/{userId}/follows/{followUserId} {
|
|
|
|
allow read;
|
|
|
|
allow write: if request.auth.uid == userId;
|
2022-01-19 03:50:50 +00:00
|
|
|
}
|
|
|
|
|
2022-08-30 15:38:59 +00:00
|
|
|
match /users/{userId}/likes/{likeId} {
|
|
|
|
allow read;
|
|
|
|
allow write: if request.auth.uid == userId;
|
|
|
|
}
|
|
|
|
|
2022-06-08 03:24:18 +00:00
|
|
|
match /{somePath=**}/follows/{followUserId} {
|
2022-06-03 04:52:14 +00:00
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-01-19 03:50:50 +00:00
|
|
|
match /private-users/{userId} {
|
2022-08-13 03:13:09 +00:00
|
|
|
allow read: if userId == request.auth.uid || isAdmin();
|
|
|
|
allow update: if (userId == request.auth.uid || isAdmin())
|
2022-06-02 17:14:01 +00:00
|
|
|
&& request.resource.data.diff(resource.data).affectedKeys()
|
2022-09-14 16:26:08 +00:00
|
|
|
.hasOnly(['apiKey', 'unsubscribedFromResolutionEmails', 'unsubscribedFromCommentEmails', 'unsubscribedFromAnswerEmails', 'unsubscribedFromWeeklyTrendingEmails', 'notificationPreferences', 'twitchInfo']);
|
2022-01-05 17:42:43 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 03:28:38 +00:00
|
|
|
match /private-users/{userId}/views/{viewId} {
|
|
|
|
allow create: if userId == request.auth.uid;
|
|
|
|
}
|
|
|
|
|
2022-04-19 05:16:08 +00:00
|
|
|
match /private-users/{userId}/events/{eventId} {
|
|
|
|
allow create: if userId == request.auth.uid;
|
|
|
|
}
|
|
|
|
|
2022-04-21 06:00:08 +00:00
|
|
|
match /private-users/{userId}/latency/{loadTimeId} {
|
|
|
|
allow create: if userId == request.auth.uid;
|
|
|
|
}
|
|
|
|
|
2022-05-12 15:07:10 +00:00
|
|
|
match /private-users/{userId}/cache/{docId} {
|
2022-05-01 16:36:54 +00:00
|
|
|
allow read: if userId == request.auth.uid || isAdmin();
|
|
|
|
}
|
|
|
|
|
2022-01-05 17:42:43 +00:00
|
|
|
match /contracts/{contractId} {
|
|
|
|
allow read;
|
2022-01-26 23:45:05 +00:00
|
|
|
allow update: if request.resource.data.diff(resource.data).affectedKeys()
|
2022-07-22 22:28:53 +00:00
|
|
|
.hasOnly(['tags', 'lowercaseTags', 'groupSlugs', 'groupLinks']);
|
2022-06-02 17:23:25 +00:00
|
|
|
allow update: if request.resource.data.diff(resource.data).affectedKeys()
|
2022-07-18 20:52:28 +00:00
|
|
|
.hasOnly(['description', 'closeTime', 'question'])
|
2022-06-02 17:14:01 +00:00
|
|
|
&& resource.data.creatorId == request.auth.uid;
|
2022-02-09 18:58:33 +00:00
|
|
|
allow update: if isAdmin();
|
2022-06-22 16:35:50 +00:00
|
|
|
match /comments/{commentId} {
|
|
|
|
allow create: if request.auth != null && commentMatchesUser(request.auth.uid, request.resource.data);
|
|
|
|
}
|
2022-01-05 17:42:43 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 17:47:39 +00:00
|
|
|
match /{somePath=**}/bets/{betId} {
|
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-06-08 18:00:49 +00:00
|
|
|
match /{somePath=**}/liquidity/{liquidityId} {
|
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-04-27 08:17:29 +00:00
|
|
|
function commentMatchesUser(userId, comment) {
|
|
|
|
// it's a bad look if someone can impersonate other ids/names/avatars so check everything
|
|
|
|
let user = get(/databases/$(database)/documents/users/$(userId));
|
|
|
|
return comment.userId == userId
|
|
|
|
&& comment.userName == user.data.name
|
|
|
|
&& comment.userUsername == user.data.username
|
|
|
|
&& comment.userAvatarUrl == user.data.avatarUrl;
|
|
|
|
}
|
|
|
|
|
2022-02-17 23:00:19 +00:00
|
|
|
match /{somePath=**}/comments/{commentId} {
|
2022-01-05 17:42:43 +00:00
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-02-17 23:00:19 +00:00
|
|
|
match /{somePath=**}/answers/{answerId} {
|
2022-01-05 22:52:54 +00:00
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-01-26 20:03:32 +00:00
|
|
|
|
2022-02-04 00:13:04 +00:00
|
|
|
match /{somePath=**}/followers/{userId} {
|
|
|
|
allow read;
|
2022-04-27 08:17:29 +00:00
|
|
|
allow create, update: if request.auth.uid == userId && request.resource.data.userId == userId;
|
|
|
|
allow delete: if request.auth.uid == userId;
|
2022-02-04 00:13:04 +00:00
|
|
|
}
|
2022-04-29 23:35:56 +00:00
|
|
|
|
|
|
|
match /txns/{txnId} {
|
|
|
|
allow read;
|
|
|
|
}
|
2022-06-02 17:14:01 +00:00
|
|
|
|
2022-06-23 08:07:52 +00:00
|
|
|
// Note: `resource` = existing doc, `request.resource` = incoming doc
|
|
|
|
match /manalinks/{slug} {
|
|
|
|
// Anyone can view any manalink
|
|
|
|
allow get;
|
|
|
|
// Only you can create a manalink with your fromId
|
|
|
|
allow create: if request.auth.uid == request.resource.data.fromId;
|
|
|
|
// Only you can list and change your own manalinks
|
|
|
|
allow list, update: if request.auth.uid == resource.data.fromId;
|
|
|
|
}
|
|
|
|
|
2022-06-02 17:14:01 +00:00
|
|
|
match /users/{userId}/notifications/{notificationId} {
|
|
|
|
allow read;
|
|
|
|
allow update: if resource.data.userId == request.auth.uid
|
|
|
|
&& request.resource.data.diff(resource.data).affectedKeys()
|
|
|
|
.hasOnly(['isSeen', 'viewTime']);
|
|
|
|
}
|
2022-09-14 08:52:31 +00:00
|
|
|
|
2022-09-03 00:06:48 +00:00
|
|
|
match /{somePath=**}/groupMembers/{memberId} {
|
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
|
|
|
match /{somePath=**}/groupContracts/{contractId} {
|
|
|
|
allow read;
|
|
|
|
}
|
|
|
|
|
2022-09-12 16:34:56 +00:00
|
|
|
match /groups/{groupId} {
|
2022-06-22 18:17:56 +00:00
|
|
|
allow read;
|
2022-08-31 18:29:49 +00:00
|
|
|
allow update: if (request.auth.uid == resource.data.creatorId || isAdmin())
|
2022-06-22 18:17:56 +00:00
|
|
|
&& request.resource.data.diff(resource.data)
|
|
|
|
.affectedKeys()
|
2022-09-03 00:06:48 +00:00
|
|
|
.hasOnly(['name', 'about', 'anyoneCanJoin', 'aboutPostId' ]);
|
2022-06-22 18:17:56 +00:00
|
|
|
allow delete: if request.auth.uid == resource.data.creatorId;
|
|
|
|
|
2022-09-03 00:06:48 +00:00
|
|
|
match /groupContracts/{contractId} {
|
|
|
|
allow write: if isGroupMember() || request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.creatorId
|
|
|
|
}
|
|
|
|
|
|
|
|
match /groupMembers/{memberId}{
|
|
|
|
allow create: if request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.creatorId || (request.auth.uid == request.resource.data.userId && get(/databases/$(database)/documents/groups/$(groupId)).data.anyoneCanJoin);
|
2022-09-12 16:34:56 +00:00
|
|
|
allow delete: if request.auth.uid == resource.data.userId;
|
2022-09-03 00:06:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function isGroupMember() {
|
|
|
|
return exists(/databases/$(database)/documents/groups/$(groupId)/groupMembers/$(request.auth.uid));
|
2022-06-22 18:17:56 +00:00
|
|
|
}
|
2022-09-03 00:06:48 +00:00
|
|
|
|
2022-06-22 18:17:56 +00:00
|
|
|
match /comments/{commentId} {
|
|
|
|
allow read;
|
2022-09-03 00:06:48 +00:00
|
|
|
allow create: if request.auth != null && commentMatchesUser(request.auth.uid, request.resource.data) && isGroupMember();
|
2022-06-22 18:17:56 +00:00
|
|
|
}
|
2022-09-03 00:06:48 +00:00
|
|
|
|
2022-06-22 18:17:56 +00:00
|
|
|
}
|
2022-08-29 15:06:17 +00:00
|
|
|
|
|
|
|
match /posts/{postId} {
|
|
|
|
allow read;
|
2022-08-31 18:29:49 +00:00
|
|
|
allow update: if isAdmin() || request.auth.uid == resource.data.creatorId
|
2022-08-29 15:06:17 +00:00
|
|
|
&& request.resource.data.diff(resource.data)
|
|
|
|
.affectedKeys()
|
|
|
|
.hasOnly(['name', 'content']);
|
2022-08-31 18:29:49 +00:00
|
|
|
allow delete: if isAdmin() || request.auth.uid == resource.data.creatorId;
|
2022-09-07 22:09:20 +00:00
|
|
|
match /comments/{commentId} {
|
|
|
|
allow read;
|
|
|
|
allow create: if request.auth != null && commentMatchesUser(request.auth.uid, request.resource.data) ;
|
|
|
|
}
|
2022-08-29 15:06:17 +00:00
|
|
|
}
|
2022-01-05 17:42:43 +00:00
|
|
|
}
|
2022-04-27 07:34:23 +00:00
|
|
|
}
|