From dea14b8377b434497a9ce8049db19d0c63763fa4 Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:12:23 +0330 Subject: [PATCH] Import source: backend/src/config/env Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- backend/src/config/env.ts | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 backend/src/config/env.ts diff --git a/backend/src/config/env.ts b/backend/src/config/env.ts new file mode 100644 index 0000000..3c45ca0 --- /dev/null +++ b/backend/src/config/env.ts @@ -0,0 +1,44 @@ +import path from 'node:path'; + +const rootDir = process.cwd(); + +export const env = { + nodeEnv: process.env.NODE_ENV ?? 'development', + port: Number(process.env.PORT ?? 4001), + frontendUrl: process.env.FRONTEND_URL ?? 'http://localhost:5173', + publicAppUrl: process.env.PUBLIC_APP_URL ?? process.env.FRONTEND_URL ?? 'http://localhost:5173', + dataDir: path.resolve(rootDir, process.env.DATA_DIR ?? './data'), + maxFileSizeBytes: Number(process.env.MAX_FILE_SIZE_BYTES ?? 524_288_000), + previewMaxFileSizeBytes: Number(process.env.PREVIEW_MAX_FILE_SIZE_BYTES ?? 25_000_000), + jwtAccessSecret: process.env.JWT_ACCESS_SECRET ?? 'dev-access-secret-change-me', + jwtRefreshSecret: process.env.JWT_REFRESH_SECRET ?? 'dev-refresh-secret-change-me', + adminApiKey: process.env.ADMIN_API_KEY ?? '', + bcryptRounds: Number(process.env.BCRYPT_ROUNDS ?? 12), + gdriveClientId: process.env.GDRIVE_CLIENT_ID ?? '', + gdriveClientSecret: process.env.GDRIVE_CLIENT_SECRET ?? '', + gdriveRefreshToken: process.env.GDRIVE_REFRESH_TOKEN ?? '', + gdriveFolderId: process.env.GDRIVE_FOLDER_ID ?? '1CukB7NsVnHbLFEQDKzadcGb8NpitilfM', +}; + +export function assertProductionEnv() { + if (env.nodeEnv !== 'production') return; + + const missing = []; + const isHex64 = (val: string) => /^[a-fA-F0-9]{32,}$/.test(val); + + if (!process.env.JWT_ACCESS_SECRET || !isHex64(env.jwtAccessSecret)) { + missing.push('JWT_ACCESS_SECRET (must be 64-char hex)'); + } + if (!process.env.JWT_REFRESH_SECRET || !isHex64(env.jwtRefreshSecret)) { + missing.push('JWT_REFRESH_SECRET (must be 64-char hex)'); + } + if (!process.env.ADMIN_API_KEY || !isHex64(env.adminApiKey)) { + missing.push('ADMIN_API_KEY (must be 64-char hex)'); + } + if (!process.env.FRONTEND_URL) missing.push('FRONTEND_URL'); + if (!process.env.PUBLIC_APP_URL) missing.push('PUBLIC_APP_URL'); + + if (missing.length) { + throw new Error(`Missing or weak production configuration: ${missing.join(', ')}`); + } +}