const path = require('path'); if ( process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'development' && process.env.NODE_ENV !== 'test' ) { console.error( "NODE_ENV should be one of 'production', 'development' or 'test'." ); process.exit(1); } const environment = process.env.NODE_ENV; const production = process.env.NODE_ENV === 'production'; const projectRootPath = path.join(__dirname, '..'); // backend root path const credentials = { google: { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, redirectUri: process.env.GOOGLE_REDIRECT_URI || 'http://localhost:3002/api/calendar/oauth/callback', }, }; const defaultHost = environment === 'test' ? '127.0.0.1' : '0.0.0.0'; const emailConfig = { enabled: process.env.ENABLE_EMAIL === 'true', smtp: { host: process.env.EMAIL_SMTP_HOST, port: process.env.EMAIL_SMTP_PORT ? parseInt(process.env.EMAIL_SMTP_PORT, 10) : 587, secure: process.env.EMAIL_SMTP_SECURE === 'true', auth: { user: process.env.EMAIL_SMTP_USERNAME, pass: process.env.EMAIL_SMTP_PASSWORD, }, }, from: { address: process.env.EMAIL_FROM_ADDRESS, name: process.env.EMAIL_FROM_NAME || 'Tududi', }, }; const registrationConfig = { tokenExpiryHours: process.env.REGISTRATION_TOKEN_EXPIRY_HOURS ? parseInt(process.env.REGISTRATION_TOKEN_EXPIRY_HOURS, 10) : 24, }; const config = { allowedOrigins: process.env.TUDUDI_ALLOWED_ORIGINS ? process.env.TUDUDI_ALLOWED_ORIGINS.split(',').map((origin) => origin.trim() ) : [ 'http://localhost:8080', 'http://localhost:9292', 'http://127.0.0.1:8080', 'http://127.0.0.1:9292', ], dbFile: process.env.DB_FILE || path.join(projectRootPath, 'db', `${environment}.sqlite3`), disableScheduler: process.env.DISABLE_SCHEDULER === 'true', disableTelegram: process.env.DISABLE_TELEGRAM === 'true', email: process.env.TUDUDI_USER_EMAIL, environment, frontendUrl: process.env.FRONTEND_URL || 'http://localhost:8080', backendUrl: process.env.BACKEND_URL || 'http://localhost:3002', // Some CI/sandbox environments disallow binding to 0.0.0.0, so force // loopback for tests unless HOST is explicitly provided. host: process.env.HOST || defaultHost, port: process.env.PORT || 3002, password: process.env.TUDUDI_USER_PASSWORD, production, secret: process.env.TUDUDI_SESSION_SECRET || require('crypto').randomBytes(64).toString('hex'), credentials, emailConfig, registrationConfig, uploadPath: process.env.TUDUDI_UPLOAD_PATH || path.join(projectRootPath, 'uploads'), // API Documentation (Swagger) swagger: { enabled: process.env.SWAGGER_ENABLED !== 'false', }, trustProxy: (() => { const val = process.env.TUDUDI_TRUST_PROXY; if (val === undefined || val === '') return false; if (val === 'true') return true; if (val === 'false') return false; const num = Number(val); if (!isNaN(num) && val.trim() !== '') return num; return val; })(), // Rate limiting configuration rateLimiting: { // Disable rate limiting in test environment enabled: process.env.RATE_LIMITING_ENABLED !== 'false' && environment !== 'test', // Authentication endpoints (login, register) auth: { windowMs: parseInt(process.env.RATE_LIMIT_AUTH_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes max: parseInt(process.env.RATE_LIMIT_AUTH_MAX) || 5, // 5 requests per window }, // General API for unauthenticated requests api: { windowMs: parseInt(process.env.RATE_LIMIT_API_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes max: parseInt(process.env.RATE_LIMIT_API_MAX) || 100, // 100 requests per window }, // Authenticated API requests authenticatedApi: { windowMs: parseInt(process.env.RATE_LIMIT_AUTH_API_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes max: parseInt(process.env.RATE_LIMIT_AUTH_API_MAX) || 1000, // 1000 requests per window }, // Resource creation endpoints createResource: { windowMs: parseInt(process.env.RATE_LIMIT_CREATE_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes max: parseInt(process.env.RATE_LIMIT_CREATE_MAX) || 50, // 50 requests per window }, // API key management endpoints apiKeyManagement: { windowMs: parseInt(process.env.RATE_LIMIT_API_KEY_WINDOW_MS) || 60 * 60 * 1000, // 1 hour max: parseInt(process.env.RATE_LIMIT_API_KEY_MAX) || 10, // 10 requests per window }, }, }; console.log(`Using database file '${config.dbFile}'`); function setConfig({ dbFile } = {}) { if (dbFile != null) { config.dbFile = dbFile; } } function getConfig() { return config; } module.exports = { setConfig, getConfig };