manifold/firestore.rules

225 lines
8.2 KiB
Plaintext
Raw Normal View History

2022-01-05 17:42:43 +00:00
rules_version = '2';
// 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',
'ingawei@gmail.com'
2022-07-16 19:52:59 +00:00
]
2022-01-24 06:45:46 +00:00
}
match /stats/stats {
allow read;
}
match /globalConfig/globalConfig {
allow read;
allow update: if isAdmin()
allow create: if isAdmin()
}
2022-01-05 17:42:43 +00:00
match /users/{userId} {
allow read;
allow update: if userId == request.auth.uid
&& request.resource.data.diff(resource.data).affectedKeys()
2022-10-10 20:51:27 +00:00
.hasOnly(['bio', 'website', 'twitterHandle', 'discordHandle', 'followedCategories', 'lastPingTime','shouldShowWelcome', 'hasSeenContractFollowModal', 'homeSections']);
2022-07-15 14:45:52 +00:00
// User referral rules
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
&& !(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);
}
match /{somePath=**}/portfolioHistory/{portfolioHistoryId} {
allow read;
}
match /{somePath=**}/contract-metrics/{contractId} {
allow read;
}
Challenge Bets (#679) * Challenge bets * Store avatar url * Fix before and after probs * Check balance before creation * Calculate winning shares * pretty * Change winning value * Set shares to equal each other * Fix share challenge link * pretty * remove lib refs * Probability of bet is set to market * Remove peer pill * Cleanup * Button on contract page * don't show challenge if not binary or if resolved * challenge button (WIP) * fix accept challenge: don't change pool/probability * Opengraph preview [WIP] * elim lib * Edit og card props * Change challenge text * New card gen attempt * Get challenge on server * challenge button styling * Use env domain * Remove other window ref * Use challenge creator as avatar * Remove user name * Remove s from property, replace prob with outcome * challenge form * share text * Add in challenge parts to template and url * Challenge url params optional * Add challenge params to parse request * Parse please * Don't remove prob * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Add to readme about how to dev og-image * Add emojis * button: gradient background, 2xl size * beautify accept bet screen * update question button * Add separate challenge template * Accepted challenge sharing card, fix accept bet call * accept challenge button * challenge winner page * create challenge screen * Your outcome/cost=> acceptorOutcome/cost * New create challenge panel * Fix main merge * Add challenge slug to bet and filter by it * Center title * Add helper text * Add FAQ section * Lint * Columnize the user areas in preview link too * Absolutely position * Spacing * Orientation * Restyle challenges list, cache contract name * Make copying easy on mobile * Link spacing * Fix spacing * qr codes! * put your challenges first * eslint * Changes to contract buttons and create challenge modal * Change titles around for current bet * Add back in contract title after winning * Cleanup * Add challenge enabled flag * Spacing of switch button * Put sharing qr code in modal Co-authored-by: mantikoros <sgrugett@gmail.com>
2022-08-04 21:27:02 +00:00
match /{somePath=**}/challenges/{challengeId}{
allow read;
}
match /contracts/{contractId}/follows/{userId} {
allow read;
allow create, delete: if userId == request.auth.uid;
}
Challenge Bets (#679) * Challenge bets * Store avatar url * Fix before and after probs * Check balance before creation * Calculate winning shares * pretty * Change winning value * Set shares to equal each other * Fix share challenge link * pretty * remove lib refs * Probability of bet is set to market * Remove peer pill * Cleanup * Button on contract page * don't show challenge if not binary or if resolved * challenge button (WIP) * fix accept challenge: don't change pool/probability * Opengraph preview [WIP] * elim lib * Edit og card props * Change challenge text * New card gen attempt * Get challenge on server * challenge button styling * Use env domain * Remove other window ref * Use challenge creator as avatar * Remove user name * Remove s from property, replace prob with outcome * challenge form * share text * Add in challenge parts to template and url * Challenge url params optional * Add challenge params to parse request * Parse please * Don't remove prob * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Add to readme about how to dev og-image * Add emojis * button: gradient background, 2xl size * beautify accept bet screen * update question button * Add separate challenge template * Accepted challenge sharing card, fix accept bet call * accept challenge button * challenge winner page * create challenge screen * Your outcome/cost=> acceptorOutcome/cost * New create challenge panel * Fix main merge * Add challenge slug to bet and filter by it * Center title * Add helper text * Add FAQ section * Lint * Columnize the user areas in preview link too * Absolutely position * Spacing * Orientation * Restyle challenges list, cache contract name * Make copying easy on mobile * Link spacing * Fix spacing * qr codes! * put your challenges first * eslint * Changes to contract buttons and create challenge modal * Change titles around for current bet * Add back in contract title after winning * Cleanup * Add challenge enabled flag * Spacing of switch button * Put sharing qr code in modal Co-authored-by: mantikoros <sgrugett@gmail.com>
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;
}
match /users/{userId}/follows/{followUserId} {
allow read;
allow write: if request.auth.uid == userId;
2022-01-19 03:50:50 +00:00
}
match /users/{userId}/likes/{likeId} {
allow read;
allow write: if request.auth.uid == userId;
}
match /{somePath=**}/follows/{followUserId} {
allow read;
}
2022-01-19 03:50:50 +00:00
match /private-users/{userId} {
allow read: if userId == request.auth.uid || isAdmin();
allow update: if (userId == request.auth.uid || isAdmin())
&& request.resource.data.diff(resource.data).affectedKeys()
2022-09-20 13:59:48 +00:00
.hasOnly(['apiKey', '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;
}
match /private-users/{userId}/latency/{loadTimeId} {
allow create: if userId == request.auth.uid;
}
match /private-users/{userId}/cache/{docId} {
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()
.hasOnly(['tags', 'lowercaseTags', 'groupSlugs', 'groupLinks', 'flaggedByUsernames']);
allow update: if request.resource.data.diff(resource.data).affectedKeys()
2022-10-03 15:26:39 +00:00
.hasOnly(['description', 'closeTime', 'question', 'visibility', 'unlistedById'])
&& resource.data.creatorId == request.auth.uid;
2022-02-09 18:58:33 +00:00
allow update: if isAdmin();
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;
}
match /{somePath=**}/liquidity/{liquidityId} {
allow read;
}
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;
}
Free response (#47) * Answer datatype and MULTI outcome type for Contract * Create free answer contract * Automatically sort Tailwind classes with Prettier (#45) * Add Prettier Tailwind plugin * Autoformat Tailwind classes with Prettier * Allow for non-binary contracts in contract page and related components * logo with white inside, transparent bg * Create answer * Some UI for showing answers * Answer bet panel * Convert rest of calcuate file to generic multi contracts * Working betting with ante'd NONE answer * Numbered answers. Layout & calculation tweaks * Can bet. More layout tweaks! * Resolve answer UI * Resolve multi market * Resolved market UI * Fix feed and cards for multi contracts * Sell bets. Various fixes * Tweaks for trades page * Always dev mode * Create answer bet has isAnte: true * Fix card showing 0% for multi contracts * Fix grouped bets feed for multi outcomes * None option converted to none of the above label at bottom of list. Button to resolve none. * Tweaks to no answers yet, resolve button layout * Show ante bets on new answers in the feed * Update placeholder text for description * Consolidate firestore rules for subcollections * Remove Contract and Bet type params. Use string type for outcomes. * Increase char limit to 10k for answers. Preserve line breaks. * Don't show resolve options after answer chosen * Fix type error in script * Remove NONE resolution option * Change outcomeType to include 'MULTI' and 'FREE_RESPONSE' * Show bet probability change and payout when creating answer * User info change: also change answers * Append answers to contract field 'answers' * sort trades by resolved * Don't include trailing !:,.; in links * Stop flooring inputs into formatMoney * Revert "Stop flooring inputs into formatMoney" This reverts commit 2f7ab1842916bc903e60231cbf45b934db2f2658. * Consistently floor user.balance * Expand create panel on focus From Richard Hanania's feedback * welcome email: include link to manifold * Fix home page in dev on branches that are not free-response * Close emails (#50) * script init for stephen dev * market close emails * order of operations * template email * sendMarketCloseEmail: handle unsubscribe * remove debugging * marketCloseEmails: every hour * sendMarketCloseEmails: check undefined * marketCloseEmails: "every hour" => "every 1 hours" * Set up a read API using Vercel serverless functions (#49) * Set up read API using Vercel serverless functions Featuring: /api/v0/markets /api/v0/market/[contractId] /api/v0/slug/[contractSlug] * Include tags in API * Tweaks. Remove filter for only binary contract * Fix bet probability change for NO bets * Put back isProd calculation Co-authored-by: Austin Chen <akrolsmir@gmail.com> Co-authored-by: mantikoros <sgrugett@gmail.com> Co-authored-by: mantikoros <95266179+mantikoros@users.noreply.github.com>
2022-02-17 23:00:19 +00:00
match /{somePath=**}/comments/{commentId} {
2022-01-05 17:42:43 +00:00
allow read;
}
Free response (#47) * Answer datatype and MULTI outcome type for Contract * Create free answer contract * Automatically sort Tailwind classes with Prettier (#45) * Add Prettier Tailwind plugin * Autoformat Tailwind classes with Prettier * Allow for non-binary contracts in contract page and related components * logo with white inside, transparent bg * Create answer * Some UI for showing answers * Answer bet panel * Convert rest of calcuate file to generic multi contracts * Working betting with ante'd NONE answer * Numbered answers. Layout & calculation tweaks * Can bet. More layout tweaks! * Resolve answer UI * Resolve multi market * Resolved market UI * Fix feed and cards for multi contracts * Sell bets. Various fixes * Tweaks for trades page * Always dev mode * Create answer bet has isAnte: true * Fix card showing 0% for multi contracts * Fix grouped bets feed for multi outcomes * None option converted to none of the above label at bottom of list. Button to resolve none. * Tweaks to no answers yet, resolve button layout * Show ante bets on new answers in the feed * Update placeholder text for description * Consolidate firestore rules for subcollections * Remove Contract and Bet type params. Use string type for outcomes. * Increase char limit to 10k for answers. Preserve line breaks. * Don't show resolve options after answer chosen * Fix type error in script * Remove NONE resolution option * Change outcomeType to include 'MULTI' and 'FREE_RESPONSE' * Show bet probability change and payout when creating answer * User info change: also change answers * Append answers to contract field 'answers' * sort trades by resolved * Don't include trailing !:,.; in links * Stop flooring inputs into formatMoney * Revert "Stop flooring inputs into formatMoney" This reverts commit 2f7ab1842916bc903e60231cbf45b934db2f2658. * Consistently floor user.balance * Expand create panel on focus From Richard Hanania's feedback * welcome email: include link to manifold * Fix home page in dev on branches that are not free-response * Close emails (#50) * script init for stephen dev * market close emails * order of operations * template email * sendMarketCloseEmail: handle unsubscribe * remove debugging * marketCloseEmails: every hour * sendMarketCloseEmails: check undefined * marketCloseEmails: "every hour" => "every 1 hours" * Set up a read API using Vercel serverless functions (#49) * Set up read API using Vercel serverless functions Featuring: /api/v0/markets /api/v0/market/[contractId] /api/v0/slug/[contractSlug] * Include tags in API * Tweaks. Remove filter for only binary contract * Fix bet probability change for NO bets * Put back isProd calculation Co-authored-by: Austin Chen <akrolsmir@gmail.com> Co-authored-by: mantikoros <sgrugett@gmail.com> Co-authored-by: mantikoros <95266179+mantikoros@users.noreply.github.com>
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
match /{somePath=**}/followers/{userId} {
allow read;
allow create, update: if request.auth.uid == userId && request.resource.data.userId == userId;
allow delete: if request.auth.uid == userId;
}
match /txns/{txnId} {
allow read;
}
// 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;
}
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']);
}
match /{somePath=**}/groupMembers/{memberId} {
allow read;
}
match /{somePath=**}/groupContracts/{contractId} {
allow read;
}
2022-09-18 21:23:07 +00:00
match /groups/{groupId} {
allow read;
allow update: if (request.auth.uid == resource.data.creatorId || isAdmin())
&& request.resource.data.diff(resource.data)
.affectedKeys()
.hasOnly(['name', 'about', 'anyoneCanJoin', 'aboutPostId', 'pinnedItems' ]);
2022-09-18 21:23:07 +00:00
allow delete: if request.auth.uid == resource.data.creatorId;
2022-09-18 21:23:07 +00:00
match /groupContracts/{contractId} {
allow write: if isGroupMember() || request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.creatorId
}
2022-09-18 21:23:07 +00:00
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);
allow delete: if request.auth.uid == resource.data.userId;
}
function isGroupMember() {
return exists(/databases/$(database)/documents/groups/$(groupId)/groupMembers/$(request.auth.uid));
}
match /comments/{commentId} {
allow read;
allow create: if request.auth != null && commentMatchesUser(request.auth.uid, request.resource.data) && isGroupMember();
}
}
match /posts/{postId} {
allow read;
allow update: if isAdmin() || request.auth.uid == resource.data.creatorId
&& request.resource.data.diff(resource.data)
.affectedKeys()
.hasOnly(['name', 'content']);
allow delete: if isAdmin() || request.auth.uid == resource.data.creatorId;
match /comments/{commentId} {
allow read;
allow create: if request.auth != null && commentMatchesUser(request.auth.uid, request.resource.data) ;
}
}
2022-01-05 17:42:43 +00:00
}
}