'use strict'; const fs = require('fs'); /** * Liest einen Secret-Wert aus einer Datei (Docker Secrets Pattern) * oder fällt auf eine Umgebungsvariable zurück. */ function readSecret(fileEnvKey, fallbackEnvKey) { const filePath = process.env[fileEnvKey]; if (filePath) { try { return fs.readFileSync(filePath, 'utf8').trim(); } catch (err) { throw new Error(`Secret-Datei nicht lesbar (${fileEnvKey}=${filePath}): ${err.message}`); } } const val = process.env[fallbackEnvKey]; if (!val) { throw new Error(`Weder ${fileEnvKey} noch ${fallbackEnvKey} gesetzt.`); } return val; } const config = { server: { port: parseInt(process.env.PORT || '3001', 10), nodeEnv: process.env.NODE_ENV || 'development', }, directus: { url: process.env.DIRECTUS_URL || 'http://directus:8055', // Service-Account-Token (statisch, kein User-Login) get token() { return readSecret('DIRECTUS_TOKEN_FILE', 'DIRECTUS_TOKEN'); }, // Maximale Anzahl Empfänger pro Render-Request (Schutz vor Ressourcen-Erschöpfung) maxRecipients: parseInt(process.env.MAX_RECIPIENTS || '200', 10), }, pdfRenderer: { // Gotenberg REST-Endpunkt (intern) url: process.env.PDF_RENDERER_URL || 'http://gotenberg:3000', // Timeout in ms für PDF-Konvertierung timeoutMs: parseInt(process.env.PDF_RENDERER_TIMEOUT_MS || '30000', 10), }, templates: { // Lokaler Bind-Mount; alternativ werden Templates aus Directus geladen localPath: process.env.TEMPLATE_STORE_PATH || '/templates', // TTL für den In-Memory-Cache (ms) cacheTtlMs: parseInt(process.env.TEMPLATE_CACHE_TTL_MS || '300000', 10), }, audit: { host: process.env.AUDIT_DB_HOST || 'sb-audit-db', port: parseInt(process.env.AUDIT_DB_PORT || '5432', 10), database: process.env.AUDIT_DB_NAME || 'sb_audit', user: process.env.AUDIT_DB_USER || 'sb_audit_user', get password() { return readSecret('AUDIT_DB_PASSWORD_FILE', 'AUDIT_DB_PASSWORD'); }, ssl: process.env.AUDIT_DB_SSL === 'true', }, rateLimit: { // Render-Endpunkt: max. Requests pro Zeitfenster windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '60000', 10), max: parseInt(process.env.RATE_LIMIT_MAX || '20', 10), }, log: { level: process.env.LOG_LEVEL || 'info', }, }; module.exports = config;