// Configuration for MacroPad Relay Server import dotenv from 'dotenv'; import path from 'path'; dotenv.config(); function parseTrustProxy(): boolean | number | string { const v = process.env.TRUST_PROXY ?? '1'; if (v === 'false') return false; if (v === 'true') return true; const n = Number(v); return Number.isNaN(n) ? v : n; } export const config = { port: parseInt(process.env.PORT || '3000', 10), host: process.env.HOST || '0.0.0.0', // Data storage dataDir: process.env.DATA_DIR || path.join(__dirname, '..', 'data'), // Session settings sessionIdLength: parseInt(process.env.SESSION_ID_LENGTH || '12', 10), // Maximum number of sessions that may exist at once maxSessions: parseInt(process.env.MAX_SESSIONS || '1000', 10), // Minimum password length enforced when creating a new session minPasswordLength: parseInt(process.env.MIN_PASSWORD_LENGTH || '6', 10), // Sessions unused for this many days are pruned sessionTtlDays: parseInt(process.env.SESSION_TTL_DAYS || '90', 10), // Security bcryptRounds: parseInt(process.env.BCRYPT_ROUNDS || '10', 10), // Rate limiting (HTTP) rateLimitWindowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000', 10), // 15 minutes rateLimitMax: parseInt(process.env.RATE_LIMIT_MAX || '300', 10), // WebSocket upgrade rate limiting (per IP) wsUpgradeWindowMs: parseInt(process.env.WS_UPGRADE_WINDOW_MS || '60000', 10), // 1 minute wsUpgradeMax: parseInt(process.env.WS_UPGRADE_MAX || '60', 10), // max upgrades per IP per window // Auth brute-force protection authMaxSocketFailures: parseInt(process.env.AUTH_MAX_SOCKET_FAILURES || '5', 10), authLockoutMaxAttempts: parseInt(process.env.AUTH_LOCKOUT_MAX_ATTEMPTS || '10', 10), authLockoutWindowMs: parseInt(process.env.AUTH_LOCKOUT_WINDOW_MS || '900000', 10), // 15 minutes authLockoutDurationMs: parseInt(process.env.AUTH_LOCKOUT_DURATION_MS || '900000', 10), // 15 minutes // WebSocket pingInterval: parseInt(process.env.PING_INTERVAL || '30000', 10), // 30 seconds requestTimeout: parseInt(process.env.REQUEST_TIMEOUT || '30000', 10), // 30 seconds // Origin / CORS allowlist (comma-separated). Empty = same-host only. allowedOrigins: (process.env.ALLOWED_ORIGINS || '') .split(',') .map((o) => o.trim()) .filter((o) => o.length > 0), // Trust the X-Forwarded-* headers from a reverse proxy trustProxy: parseTrustProxy(), // Logging logLevel: process.env.LOG_LEVEL || 'info', // Environment nodeEnv: process.env.NODE_ENV || 'development', isDevelopment: process.env.NODE_ENV !== 'production', };