Files
serienbrief/serienbrief-backend/src/config/index.js
T

78 lines
2.3 KiB
JavaScript
Raw Normal View History

2026-05-20 09:24:11 +02:00
'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;