diff --git a/.env.example b/.env.example
index 06b67c08..744d5774 100644
--- a/.env.example
+++ b/.env.example
@@ -3,10 +3,6 @@
# Optional variables for the backend server functionality (modifying user data, etc.)
-# For database write access (dev).
-# A 16-character password with digits and letters.
-SUPABASE_DB_PASSWORD=09wATRREfAzyL5pc
-
# For Firebase access.
# Open a GitHub issue with your contribution ideas and an admin will give you the key.
# TODO: find a way to give anyone moderate access to dev firebase.
diff --git a/backend/shared/src/supabase/init.ts b/backend/shared/src/supabase/init.ts
index 58e107f0..0348b5aa 100644
--- a/backend/shared/src/supabase/init.ts
+++ b/backend/shared/src/supabase/init.ts
@@ -1,14 +1,12 @@
-import pgPromise from 'pg-promise'
-export { SupabaseClient } from 'common/supabase/utils'
-import { DEV_CONFIG } from 'common/envs/dev'
-import { PROD_CONFIG } from 'common/envs/prod'
-import { metrics, log, isProd } from '../utils'
-import { IDatabase, ITask } from 'pg-promise'
-import { IClient } from 'pg-promise/typescript/pg-subset'
-import { HOUR_MS } from 'common/util/time'
-import { METRICS_INTERVAL_MS } from 'shared/monitoring/metric-writer'
-import { getMonitoringContext } from 'shared/monitoring/context'
-import { type IConnectionParameters } from 'pg-promise/typescript/pg-subset'
+import pgPromise, {IDatabase, ITask} from 'pg-promise'
+import {log, metrics} from '../utils'
+import {IClient, type IConnectionParameters} from 'pg-promise/typescript/pg-subset'
+import {HOUR_MS} from 'common/util/time'
+import {METRICS_INTERVAL_MS} from 'shared/monitoring/metric-writer'
+import {getMonitoringContext} from 'shared/monitoring/context'
+import {ENV_CONFIG} from "common/envs/constants";
+
+export {SupabaseClient} from 'common/supabase/utils'
export const pgp = pgPromise({
error(err: any, e: pgPromise.IEventContext) {
@@ -21,9 +19,9 @@ export const pgp = pgPromise({
query() {
const ctx = getMonitoringContext()
if (ctx?.endpoint) {
- metrics.inc('pg/query_count', { endpoint: ctx.endpoint })
+ metrics.inc('pg/query_count', {endpoint: ctx.endpoint})
} else if (ctx?.job) {
- metrics.inc('pg/query_count', { job: ctx.job })
+ metrics.inc('pg/query_count', {job: ctx.job})
} else {
metrics.inc('pg/query_count')
}
@@ -38,10 +36,11 @@ export type SupabaseTransaction = ITask<{}>
export type SupabaseDirectClient = IDatabase<{}, IClient> | SupabaseTransaction
export function getInstanceId() {
- return (
- process.env.SUPABASE_INSTANCE_ID ??
- (isProd() ? PROD_CONFIG.supabaseInstanceId : DEV_CONFIG.supabaseInstanceId)
- )
+ return process.env.SUPABASE_INSTANCE_ID ?? ENV_CONFIG.supabaseInstanceId
+}
+
+export function getSupabasePwd() {
+ return ENV_CONFIG.supabaseServiceRoleKey ?? process.env.SUPABASE_DB_PASSWORD
}
const newClient = (
@@ -50,7 +49,7 @@ const newClient = (
password?: string
} & IConnectionParameters
) => {
- const { instanceId, password, ...settings } = props
+ const {instanceId, password, ...settings} = props
const config = {
// This host is IPV4 compatible, for the google cloud VM
@@ -60,7 +59,7 @@ const newClient = (
password: password,
database: 'postgres',
pool_mode: 'session',
- ssl: { rejectUnauthorized: false },
+ ssl: {rejectUnauthorized: false},
family: 4, // <- forces IPv4
...settings,
}
@@ -72,6 +71,7 @@ const newClient = (
// Use one connection to avoid WARNING: Creating a duplicate database object for the same connection.
let pgpDirect: IDatabase<{}, IClient> | null = null
+
export function createSupabaseDirectClient(
instanceId?: string,
password?: string
@@ -83,7 +83,7 @@ export function createSupabaseDirectClient(
"Can't connect to Supabase; no process.env.SUPABASE_INSTANCE_ID and no instance ID in config."
)
}
- password = password ?? process.env.SUPABASE_DB_PASSWORD
+ password = password ?? getSupabasePwd()
if (!password) {
throw new Error(
"Can't connect to Supabase; no process.env.SUPABASE_DB_PASSWORD."
@@ -101,10 +101,10 @@ export function createSupabaseDirectClient(
pool.on('acquire', () => metrics.inc('pg/connections_acquired'))
pool.on('release', () => metrics.inc('pg/connections_released'))
setInterval(() => {
- metrics.set('pg/pool_connections', pool.waitingCount, { state: 'waiting' })
- metrics.set('pg/pool_connections', pool.idleCount, { state: 'idle' })
- metrics.set('pg/pool_connections', pool.expiredCount, { state: 'expired' })
- metrics.set('pg/pool_connections', pool.totalCount, { state: 'total' })
+ metrics.set('pg/pool_connections', pool.waitingCount, {state: 'waiting'})
+ metrics.set('pg/pool_connections', pool.idleCount, {state: 'idle'})
+ metrics.set('pg/pool_connections', pool.expiredCount, {state: 'expired'})
+ metrics.set('pg/pool_connections', pool.totalCount, {state: 'total'})
}, METRICS_INTERVAL_MS)
return (pgpDirect = client)
}
@@ -114,7 +114,7 @@ export const createShortTimeoutDirectClient = () => {
if (shortTimeoutPgpClient) return shortTimeoutPgpClient
shortTimeoutPgpClient = newClient({
instanceId: getInstanceId(),
- password: process.env.SUPABASE_DB_PASSWORD,
+ password: getSupabasePwd(),
query_timeout: 1000 * 30,
max: 20,
})
diff --git a/backend/shared/src/utils.ts b/backend/shared/src/utils.ts
index e31406b1..77b40f1b 100644
--- a/backend/shared/src/utils.ts
+++ b/backend/shared/src/utils.ts
@@ -1,18 +1,20 @@
import {createSupabaseDirectClient, SupabaseDirectClient,} from 'shared/supabase/init'
-import * as admin from 'firebase-admin'
import {convertPrivateUser, convertUser} from 'common/supabase/users'
import {log, type Logger} from 'shared/monitoring/log'
import {metrics} from 'shared/monitoring/metrics'
-export { metrics }
-export { log, type Logger }
+export {metrics}
+export {log, type Logger}
export const getUser = async (
userId: string,
pg: SupabaseDirectClient = createSupabaseDirectClient()
) => {
return await pg.oneOrNone(
- `select * from users where id = $1 limit 1`,
+ `select *
+ from users
+ where id = $1
+ limit 1`,
[userId],
convertUser
)
@@ -23,7 +25,10 @@ export const getPrivateUser = async (
pg: SupabaseDirectClient = createSupabaseDirectClient()
) => {
return await pg.oneOrNone(
- `select * from private_users where id = $1 limit 1`,
+ `select *
+ from private_users
+ where id = $1
+ limit 1`,
[userId],
convertPrivateUser
)
@@ -34,7 +39,9 @@ export const getUserByUsername = async (
pg: SupabaseDirectClient = createSupabaseDirectClient()
) => {
const res = await pg.oneOrNone(
- `select * from users where username = $1`,
+ `select *
+ from users
+ where username = $1`,
username
)
@@ -46,20 +53,11 @@ export const getPrivateUserByKey = async (
pg: SupabaseDirectClient = createSupabaseDirectClient()
) => {
return await pg.oneOrNone(
- `select * from private_users where data->>'apiKey' = $1 limit 1`,
+ `select *
+ from private_users
+ where data ->> 'apiKey' = $1
+ limit 1`,
[apiKey],
convertPrivateUser
)
}
-
-// TODO: deprecate in favor of common/src/envs/is-prod.ts
-export const isProd = () => {
- // mqp: kind of hacky rn. the first clause is for cloud run API service,
- // second clause is for local scripts and cloud functions
- if (process.env.ENVIRONMENT) {
- return process.env.ENVIRONMENT == 'PROD'
- } else {
- return admin.app().options.projectId === 'compass-130ba'
- }
-}
-
diff --git a/common/src/envs/constants.ts b/common/src/envs/constants.ts
index 8413666a..1c602ad7 100644
--- a/common/src/envs/constants.ts
+++ b/common/src/envs/constants.ts
@@ -1,20 +1,11 @@
import {DEV_CONFIG} from './dev'
-import {EnvConfig, PROD_CONFIG} from './prod'
-
-// Valid in web client & Vercel deployments only.
-export const ENV = (process.env.NEXT_PUBLIC_FIREBASE_ENV ?? 'PROD') as
- | 'PROD'
- | 'DEV'
-
-export const CONFIGS: { [env: string]: EnvConfig } = {
- PROD: PROD_CONFIG,
- DEV: DEV_CONFIG,
-}
+import {PROD_CONFIG} from './prod'
+import {isProd} from "common/envs/is-prod";
export const MAX_DESCRIPTION_LENGTH = 16000
export const MAX_ANSWER_LENGTH = 240
-export const ENV_CONFIG = CONFIGS[ENV]
+export const ENV_CONFIG = isProd() ? PROD_CONFIG : DEV_CONFIG
export function isAdminId(id: string) {
return ENV_CONFIG.adminIds.includes(id)
@@ -23,6 +14,7 @@ export function isAdminId(id: string) {
export function isModId(id: string) {
return MOD_IDS.includes(id)
}
+
export const DOMAIN = ENV_CONFIG.domain
export const FIREBASE_CONFIG = ENV_CONFIG.firebaseConfig
export const PROJECT_ID = ENV_CONFIG.firebaseConfig.projectId
diff --git a/common/src/envs/dev.ts b/common/src/envs/dev.ts
index 5c60b7bd..ab161268 100644
--- a/common/src/envs/dev.ts
+++ b/common/src/envs/dev.ts
@@ -3,6 +3,7 @@ import { EnvConfig, PROD_CONFIG } from './prod'
export const DEV_CONFIG: EnvConfig = {
...PROD_CONFIG,
supabaseInstanceId: 'zbspxezubpzxmuxciurg',
+ supabaseServiceRoleKey: '09wATRREfAzyL5pc', // For database write access (dev). A 16-character password with digits and letters.
supabaseAnonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inpic3B4ZXp1YnB6eG11eGNpdXJnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTc2ODM0MTMsImV4cCI6MjA3MzI1OTQxM30.ZkM7zlawP8Nke0T3KJrqpOQ4DzqPaXTaJXLC2WU8Y7c',
firebaseConfig: {
apiKey: "AIzaSyBspL9glBXWbMsjmtt36dgb2yU0YGGhzKo",
diff --git a/common/src/envs/prod.ts b/common/src/envs/prod.ts
index b85e664b..b6b6a8f4 100644
--- a/common/src/envs/prod.ts
+++ b/common/src/envs/prod.ts
@@ -3,6 +3,7 @@ export type EnvConfig = {
firebaseConfig: FirebaseConfig
supabaseInstanceId: string
supabaseAnonKey: string
+ supabaseServiceRoleKey?: string
posthogKey: string
apiEndpoint: string
diff --git a/web/components/site-logo.tsx b/web/components/site-logo.tsx
index 4438a106..53cc7723 100644
--- a/web/components/site-logo.tsx
+++ b/web/components/site-logo.tsx
@@ -1,19 +1,19 @@
import Link from 'next/link'
import clsx from 'clsx'
-import { ENV } from 'common/envs/constants'
-import { Row } from 'web/components/layout/row'
+import {Row} from 'web/components/layout/row'
import FavIcon from "web/public/FavIcon";
+import {isProd} from "common/envs/is-prod";
export default function SiteLogo(props: {
noLink?: boolean
className?: string
}) {
- const { noLink, className } = props
+ const {noLink, className} = props
const inner = (
<>