Manifold for Teams: Support different Firestore dbs (#53)
* Add Firebase config for TheoremOne * Fix build * Check in Firebase indexes * Whitelist admins and new users by email
This commit is contained in:
parent
77b4ca4f22
commit
ebed7c15c0
14
common/access.ts
Normal file
14
common/access.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
export function isWhitelisted(email?: string) {
|
||||||
|
return true
|
||||||
|
// e.g. return email.endsWith('@theoremone.co') || isAdmin(email)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isAdmin(email: string) {
|
||||||
|
const ADMINS = [
|
||||||
|
'akrolsmir@gmail.com', // Austin
|
||||||
|
'jahooma@gmail.com', // James
|
||||||
|
'taowell@gmail.com', // Stephen
|
||||||
|
'manticmarkets@gmail.com', // Manifold
|
||||||
|
]
|
||||||
|
return ADMINS.includes(email)
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
"source": "functions"
|
"source": "functions"
|
||||||
},
|
},
|
||||||
"firestore": {
|
"firestore": {
|
||||||
"rules": "firestore.rules"
|
"rules": "firestore.rules",
|
||||||
|
"indexes": "firestore.indexes.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
234
firestore.indexes.json
Normal file
234
firestore.indexes.json
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
{
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"collectionGroup": "contracts",
|
||||||
|
"queryScope": "COLLECTION",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "creatorId",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "createdTime",
|
||||||
|
"order": "DESCENDING"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "contracts",
|
||||||
|
"queryScope": "COLLECTION",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "isResolved",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "closeTime",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "contracts",
|
||||||
|
"queryScope": "COLLECTION",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "isResolved",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "visibility",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "closeTime",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "contracts",
|
||||||
|
"queryScope": "COLLECTION",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "isResolved",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "visibility",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "volume24Hours",
|
||||||
|
"order": "DESCENDING"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "contracts",
|
||||||
|
"queryScope": "COLLECTION",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "isResolved",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "volume24Hours",
|
||||||
|
"order": "DESCENDING"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "contracts",
|
||||||
|
"queryScope": "COLLECTION",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "slug",
|
||||||
|
"order": "ASCENDING"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "createdTime",
|
||||||
|
"order": "DESCENDING"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldOverrides": [
|
||||||
|
{
|
||||||
|
"collectionGroup": "answers",
|
||||||
|
"fieldPath": "username",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrayConfig": "CONTAINS",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "bets",
|
||||||
|
"fieldPath": "createdTime",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrayConfig": "CONTAINS",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "bets",
|
||||||
|
"fieldPath": "userId",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrayConfig": "CONTAINS",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "comments",
|
||||||
|
"fieldPath": "createdTime",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrayConfig": "CONTAINS",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "comments",
|
||||||
|
"fieldPath": "userUsername",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrayConfig": "CONTAINS",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collectionGroup": "followers",
|
||||||
|
"fieldPath": "userId",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "DESCENDING",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrayConfig": "CONTAINS",
|
||||||
|
"queryScope": "COLLECTION"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order": "ASCENDING",
|
||||||
|
"queryScope": "COLLECTION_GROUP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
3
functions/.gitignore
vendored
3
functions/.gitignore
vendored
|
@ -1,3 +1,6 @@
|
||||||
|
# Secrets
|
||||||
|
.env*
|
||||||
|
|
||||||
# Compiled JavaScript files
|
# Compiled JavaScript files
|
||||||
lib/**/*.js
|
lib/**/*.js
|
||||||
lib/**/*.js.map
|
lib/**/*.js.map
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
cleanUsername,
|
cleanUsername,
|
||||||
} from '../../common/util/clean-username'
|
} from '../../common/util/clean-username'
|
||||||
import { sendWelcomeEmail } from './emails'
|
import { sendWelcomeEmail } from './emails'
|
||||||
|
import { isWhitelisted } from '../../common/access'
|
||||||
|
|
||||||
export const createUser = functions
|
export const createUser = functions
|
||||||
.runWith({ minInstances: 1 })
|
.runWith({ minInstances: 1 })
|
||||||
|
@ -32,6 +33,9 @@ export const createUser = functions
|
||||||
const fbUser = await admin.auth().getUser(userId)
|
const fbUser = await admin.auth().getUser(userId)
|
||||||
|
|
||||||
const email = fbUser.email
|
const email = fbUser.email
|
||||||
|
if (!isWhitelisted(email)) {
|
||||||
|
return { status: 'error', message: `${email} is not whitelisted` }
|
||||||
|
}
|
||||||
const emailName = email?.replace(/@.*$/, '')
|
const emailName = email?.replace(/@.*$/, '')
|
||||||
|
|
||||||
const rawName = fbUser.displayName || emailName || 'User' + randomString(4)
|
const rawName = fbUser.displayName || emailName || 'User' + randomString(4)
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import { useUser } from './use-user'
|
import { isAdmin } from '../../common/access'
|
||||||
|
import { usePrivateUser, useUser } from './use-user'
|
||||||
|
|
||||||
export const useAdmin = () => {
|
export const useAdmin = () => {
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const adminIds = [
|
const privateUser = usePrivateUser(user?.id)
|
||||||
'igi2zGXsfxYPgB0DJTXVJVmwCOr2', // Austin
|
return isAdmin(privateUser?.email || '')
|
||||||
'5LZ4LgYuySdL1huCWe7bti02ghx2', // James
|
|
||||||
'tlmGNz9kjXc2EteizMORes4qvWl2', // Stephen
|
|
||||||
'IPTOzEqrpkWmEzh6hwvAyY9PqFb2', // Manifold
|
|
||||||
]
|
|
||||||
return adminIds.includes(user?.id || '')
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { getFirestore } from '@firebase/firestore'
|
import { getFirestore } from '@firebase/firestore'
|
||||||
import { initializeApp, getApps, getApp } from 'firebase/app'
|
import { initializeApp, getApps, getApp } from 'firebase/app'
|
||||||
|
|
||||||
|
// Used to decide which Stripe instance to point to
|
||||||
export const isProd = process.env.NEXT_PUBLIC_FIREBASE_ENV !== 'DEV'
|
export const isProd = process.env.NEXT_PUBLIC_FIREBASE_ENV !== 'DEV'
|
||||||
|
|
||||||
const firebaseConfig = isProd
|
const FIREBASE_CONFIGS = {
|
||||||
? {
|
DEV: {
|
||||||
apiKey: 'AIzaSyDp3J57vLeAZCzxLD-vcPaGIkAmBoGOSYw',
|
apiKey: 'AIzaSyDp3J57vLeAZCzxLD-vcPaGIkAmBoGOSYw',
|
||||||
authDomain: 'mantic-markets.firebaseapp.com',
|
authDomain: 'mantic-markets.firebaseapp.com',
|
||||||
projectId: 'mantic-markets',
|
projectId: 'mantic-markets',
|
||||||
|
@ -12,8 +13,8 @@ const firebaseConfig = isProd
|
||||||
messagingSenderId: '128925704902',
|
messagingSenderId: '128925704902',
|
||||||
appId: '1:128925704902:web:f61f86944d8ffa2a642dc7',
|
appId: '1:128925704902:web:f61f86944d8ffa2a642dc7',
|
||||||
measurementId: 'G-SSFK1Q138D',
|
measurementId: 'G-SSFK1Q138D',
|
||||||
}
|
},
|
||||||
: {
|
PROD: {
|
||||||
apiKey: 'AIzaSyBoq3rzUa8Ekyo3ZaTnlycQYPRCA26VpOw',
|
apiKey: 'AIzaSyBoq3rzUa8Ekyo3ZaTnlycQYPRCA26VpOw',
|
||||||
authDomain: 'dev-mantic-markets.firebaseapp.com',
|
authDomain: 'dev-mantic-markets.firebaseapp.com',
|
||||||
projectId: 'dev-mantic-markets',
|
projectId: 'dev-mantic-markets',
|
||||||
|
@ -21,8 +22,20 @@ const firebaseConfig = isProd
|
||||||
messagingSenderId: '134303100058',
|
messagingSenderId: '134303100058',
|
||||||
appId: '1:134303100058:web:27f9ea8b83347251f80323',
|
appId: '1:134303100058:web:27f9ea8b83347251f80323',
|
||||||
measurementId: 'G-YJC9E37P37',
|
measurementId: 'G-YJC9E37P37',
|
||||||
|
},
|
||||||
|
THEOREMONE: {
|
||||||
|
apiKey: 'AIzaSyBSXL6Ys7InNHnCKSy-_E_luhh4Fkj4Z6M',
|
||||||
|
authDomain: 'theoremone-manifold.firebaseapp.com',
|
||||||
|
projectId: 'theoremone-manifold',
|
||||||
|
storageBucket: 'theoremone-manifold.appspot.com',
|
||||||
|
messagingSenderId: '698012149198',
|
||||||
|
appId: '1:698012149198:web:b342af75662831aa84b79f',
|
||||||
|
measurementId: 'G-Y3EZ1WNT6E',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
const ENV = process.env.NEXT_PUBLIC_FIREBASE_ENV ?? 'PROD'
|
||||||
|
// @ts-ignore
|
||||||
|
const firebaseConfig = FIREBASE_CONFIGS[ENV]
|
||||||
// Initialize Firebase
|
// Initialize Firebase
|
||||||
export const app = getApps().length ? getApp() : initializeApp(firebaseConfig)
|
export const app = getApps().length ? getApp() : initializeApp(firebaseConfig)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user