fertig-classic-games/server/config.js

73 lines
2.2 KiB
JavaScript

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 <no-reply@localhost>',
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;