Clean ENV

This commit is contained in:
MartinBraquet
2025-09-20 18:26:03 +02:00
parent b4f0ef8b43
commit d7c95e2ae0
5 changed files with 40 additions and 51 deletions

View File

@@ -1,27 +1,25 @@
import * as admin from 'firebase-admin'
import { PrivateUser } from 'common/user'
import { randomString } from 'common/util/random'
import { cleanDisplayName, cleanUsername } from 'common/util/clean-username'
import { getIp, track } from 'shared/analytics'
import { APIError, APIHandler } from './helpers/endpoint'
import { getDefaultNotificationPreferences } from 'common/user-notification-preferences'
import { removeUndefinedProps } from 'common/util/object'
import { generateAvatarUrl } from 'shared/helpers/generate-and-update-avatar-urls'
import { getStorage } from 'firebase-admin/storage'
import { DEV_CONFIG } from 'common/envs/dev'
import { PROD_CONFIG } from 'common/envs/prod'
import { RESERVED_PATHS } from 'common/envs/constants'
import { log, isProd, getUser, getUserByUsername } from 'shared/utils'
import { createSupabaseDirectClient } from 'shared/supabase/init'
import { insert } from 'shared/supabase/utils'
import { convertPrivateUser, convertUser } from 'common/supabase/users'
import {PrivateUser} from 'common/user'
import {randomString} from 'common/util/random'
import {cleanDisplayName, cleanUsername} from 'common/util/clean-username'
import {getIp, track} from 'shared/analytics'
import {APIError, APIHandler} from './helpers/endpoint'
import {getDefaultNotificationPreferences} from 'common/user-notification-preferences'
import {removeUndefinedProps} from 'common/util/object'
import {generateAvatarUrl} from 'shared/helpers/generate-and-update-avatar-urls'
import {getStorage} from 'firebase-admin/storage'
import {ENV_CONFIG, RESERVED_PATHS} from 'common/envs/constants'
import {getUser, getUserByUsername, log} from 'shared/utils'
import {createSupabaseDirectClient} from 'shared/supabase/init'
import {insert} from 'shared/supabase/utils'
import {convertPrivateUser, convertUser} from 'common/supabase/users'
export const createUser: APIHandler<'create-user'> = async (
props,
auth,
req
) => {
const { deviceToken: preDeviceToken } = props
const {deviceToken: preDeviceToken} = props
const firebaseUser = await admin.auth().getUser(auth.uid)
const testUserAKAEmailPasswordUser =
@@ -63,7 +61,9 @@ export const createUser: APIHandler<'create-user'> = async (
// Check username case-insensitive
const dupes = await pg.one<number>(
`select count(*) from users where username ilike $1`,
`select count(*)
from users
where username ilike $1`,
[username],
(r) => r.count
)
@@ -71,7 +71,7 @@ export const createUser: APIHandler<'create-user'> = async (
const isReservedName = RESERVED_PATHS.includes(username)
if (usernameExists || isReservedName) username += randomString(4)
const { user, privateUser } = await pg.tx(async (tx) => {
const {user, privateUser} = await pg.tx(async (tx) => {
const preexistingUser = await getUser(auth.uid, tx)
if (preexistingUser)
throw new APIError(403, 'User already exists', {
@@ -81,13 +81,13 @@ export const createUser: APIHandler<'create-user'> = async (
// Check exact username to avoid problems with duplicate requests
const sameNameUser = await getUserByUsername(username, tx)
if (sameNameUser)
throw new APIError(403, 'Username already taken', { username })
throw new APIError(403, 'Username already taken', {username})
const user = removeUndefinedProps({
avatarUrl,
isBannedFromPosting: Boolean(
(deviceToken && bannedDeviceTokens.includes(deviceToken)) ||
(ip && bannedIpAddresses.includes(ip))
(ip && bannedIpAddresses.includes(ip))
),
link: {},
})
@@ -120,10 +120,10 @@ export const createUser: APIHandler<'create-user'> = async (
}
})
log('created user ', { username: user.username, firebaseId: auth.uid })
log('created user ', {username: user.username, firebaseId: auth.uid})
const continuation = async () => {
await track(auth.uid, 'create profile', { username: user.username })
await track(auth.uid, 'create profile', {username: user.username})
}
return {
@@ -136,9 +136,7 @@ export const createUser: APIHandler<'create-user'> = async (
}
function getStorageBucketId() {
return isProd()
? PROD_CONFIG.firebaseConfig.storageBucket
: DEV_CONFIG.firebaseConfig.storageBucket
return ENV_CONFIG.firebaseConfig.storageBucket
}
// Automatically ban users with these device tokens or ip addresses.

View File

@@ -1,8 +1,6 @@
import { sign } from 'jsonwebtoken'
import { APIError, APIHandler } from './helpers/endpoint'
import { DEV_CONFIG } from 'common/envs/dev'
import { PROD_CONFIG } from 'common/envs/prod'
import { isProd } from 'shared/utils'
import {sign} from 'jsonwebtoken'
import {APIError, APIHandler} from './helpers/endpoint'
import {ENV_CONFIG} from "common/envs/constants";
export const getSupabaseToken: APIHandler<'get-supabase-token'> = async (
_,
@@ -12,21 +10,17 @@ export const getSupabaseToken: APIHandler<'get-supabase-token'> = async (
if (jwtSecret == null) {
throw new APIError(500, "No SUPABASE_JWT_SECRET; couldn't sign token.")
}
const instanceId = isProd()
? PROD_CONFIG.supabaseInstanceId
: DEV_CONFIG.supabaseInstanceId
const instanceId = ENV_CONFIG.supabaseInstanceId
if (!instanceId) {
throw new APIError(500, 'No Supabase instance ID in config.')
}
const payload = { role: 'anon' } // postgres role
const payload = {role: 'anon'} // postgres role
return {
jwt: sign(payload, jwtSecret, {
algorithm: 'HS256', // same as what supabase uses for its auth tokens
expiresIn: '1d',
audience: instanceId,
issuer: isProd()
? PROD_CONFIG.firebaseConfig.projectId
: DEV_CONFIG.firebaseConfig.projectId,
issuer: ENV_CONFIG.firebaseConfig.projectId,
subject: auth.uid,
}),
}

View File

@@ -1,11 +1,10 @@
import { Request } from 'express'
import { trackAuditEvent } from 'shared/audit-events'
import { PostHog } from 'posthog-node'
import { isProd, log } from 'shared/utils'
import { PROD_CONFIG } from 'common/envs/prod'
import { DEV_CONFIG } from 'common/envs/dev'
import {Request} from 'express'
import {trackAuditEvent} from 'shared/audit-events'
import {PostHog} from 'posthog-node'
import {log} from 'shared/utils'
import {ENV_CONFIG} from "common/envs/constants";
const key = isProd() ? PROD_CONFIG.posthogKey : DEV_CONFIG.posthogKey
const key = ENV_CONFIG.posthogKey
const client = new PostHog(key, {
host: 'https://us.i.posthog.com',
@@ -35,7 +34,7 @@ export const trackPublicEvent = async (
properties?: any
) => {
const allProperties = Object.assign(properties ?? {}, {})
const { commentId, ...data } = allProperties
const {commentId, ...data} = allProperties
try {
client.capture({
distinctId: userId,

View File

@@ -1,10 +1,10 @@
export const isProd = () => {
// For cloud run API service
if (process.env.ENVIRONMENT) {
return process.env.ENVIRONMENT == 'PROD'
return process.env.ENVIRONMENT?.toUpperCase() == 'PROD'
// For local web dev and vercel
} else if (process.env.NEXT_PUBLIC_FIREBASE_ENV) {
return process.env.NEXT_PUBLIC_FIREBASE_ENV == 'PROD'
return process.env.NEXT_PUBLIC_FIREBASE_ENV?.toUpperCase() == 'PROD'
} else {
// For local scripts and cloud functions
// eslint-disable-next-line @typescript-eslint/no-var-requires

View File

@@ -16,8 +16,6 @@ case $ENV in
exit 1
esac
ENVIRONMENT=$ENV
NEXT_PUBLIC_FIREBASE_ENV="${ENVIRONMENT}"
WEB_DIR=web
source .env
@@ -25,7 +23,7 @@ source .env
npx dotenv -e .env -- npx concurrently \
-n API,NEXT,TS \
-c white,magenta,cyan \
"cross-env ENV=$NEXT_ENV yarn --cwd=backend/api dev" \
"cross-env ENV=$NEXT_ENV ENVIRONMENT=$NEXT_ENV yarn --cwd=backend/api dev" \
"cross-env NEXT_PUBLIC_FIREBASE_ENV=$NEXT_ENV yarn --cwd=$WEB_DIR serve" \
"cross-env yarn --cwd=$WEB_DIR ts-watch"