Move supabase dev pwd inside code

This commit is contained in:
MartinBraquet
2025-09-20 18:12:46 +02:00
parent 6d30cd7ae4
commit b4f0ef8b43
7 changed files with 52 additions and 64 deletions

View File

@@ -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.

View File

@@ -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,
})

View File

@@ -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'
}
}

View File

@@ -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

View File

@@ -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",

View File

@@ -3,6 +3,7 @@ export type EnvConfig = {
firebaseConfig: FirebaseConfig
supabaseInstanceId: string
supabaseAnonKey: string
supabaseServiceRoleKey?: string
posthogKey: string
apiEndpoint: string

View File

@@ -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 = (
<>
<FavIcon className="dark:invert"/>
<div className={clsx('my-auto text-xl font-thin logo')}>
{ENV == 'DEV' ? 'Compass dev' : 'Compass'}
{isProd() ? 'Compass' : 'Compass dev'}
</div>
</>
)