77 lines
2.3 KiB
JavaScript
77 lines
2.3 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),
|
|
},
|
|
|
|
socket: {
|
|
corsOrigin: process.env.SOCKET_IO_CORS_ORIGIN ?? 'http://localhost:3000',
|
|
},
|
|
|
|
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;
|