import 'dotenv/config'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, '..'); function bool(v, fallback = false) { if (v === undefined || v === '') return fallback; return /^(1|true|yes|on)$/i.test(v); } function int(v, fallback) { const n = Number.parseInt(v, 10); return Number.isFinite(n) ? n : fallback; } function resolveFromRoot(p) { return path.isAbsolute(p) ? p : path.resolve(ROOT, p); } const config = { root: ROOT, env: process.env.NODE_ENV ?? 'development', host: process.env.HOST ?? '0.0.0.0', port: int(process.env.PORT, 3000), baseUrl: process.env.BASE_URL ?? 'http://localhost:3000', logLevel: process.env.LOG_LEVEL ?? 'info', db: { path: resolveFromRoot(process.env.DB_PATH ?? './data/fertig.sqlite'), migrationsDir: path.join(__dirname, 'db', 'migrations'), }, auth: { sessionSecret: process.env.SESSION_SECRET ?? '', cookieName: process.env.SESSION_COOKIE_NAME ?? 'fcg_sid', sessionTtlDays: int(process.env.SESSION_TTL_DAYS, 30), bcryptRounds: int(process.env.BCRYPT_ROUNDS, 12), }, uploads: { dir: resolveFromRoot(process.env.UPLOAD_DIR ?? './public/uploads'), maxSizeMb: int(process.env.MAX_UPLOAD_SIZE_MB, 5), allowedMime: (process.env.ALLOWED_UPLOAD_MIME ?? 'image/png,image/jpeg,image/webp') .split(',') .map((s) => s.trim()) .filter(Boolean), }, email: { host: process.env.SMTP_HOST ?? '', port: int(process.env.SMTP_PORT, 587), secure: bool(process.env.SMTP_SECURE, false), user: process.env.SMTP_USER ?? '', pass: process.env.SMTP_PASS ?? '', from: process.env.SMTP_FROM ?? 'Fertig Classic Games ', verificationTtlHours: int(process.env.VERIFICATION_TOKEN_TTL_HOURS, 24), }, publicDir: path.join(ROOT, 'public'), }; if (!config.auth.sessionSecret) { if (config.env === 'production') { throw new Error('SESSION_SECRET must be set in production'); } console.warn('[config] SESSION_SECRET is empty — using an insecure dev default'); config.auth.sessionSecret = 'dev-insecure-secret-do-not-use-in-production'; } export default config;