/** * server config — production safety tests (P2-7) * * P2-7 from the SRS audit: the JWT secret fallback must not leak into * production. The contract is: * 1. NODE_ENV=production + JWT_SECRET unset → process exits non-zero * (so a missing deploy config refuses to start, instead of running * with a hardcoded dev secret). * 2. NODE_ENV=production + JWT_SECRET set → boots, exports the secret. * 3. NODE_ENV=development (or unset) + JWT_SECRET unset → boots with * a clearly-marked dev fallback and a loud warning. * * We spawn child processes to test (1) and (2) because the prod path * calls process.exit(1), which would kill the test runner. For (3) we * import the module directly in a child NODE_ENV=development so the * dev fallback is exercised. */ const { spawnSync } = require('child_process'); const path = require('path'); const CONFIG_JS = path.join(__dirname, '..', 'src', 'config', 'index.js'); function spawnConfig(env) { return spawnSync(process.execPath, ['-e', `require(${JSON.stringify(CONFIG_JS)})`], { env: { ...process.env, ...env }, encoding: 'utf8', timeout: 10000, }); } describe('server config — production safety (P2-7)', () => { it('crashes on startup when NODE_ENV=production and JWT_SECRET is missing', () => { const result = spawnConfig({ NODE_ENV: 'production', ALLOWED_ORIGINS: 'https://example.com', // explicitly clear JWT_SECRET JWT_SECRET: '', }); expect(result.status).not.toBe(0); const combined = (result.stdout || '') + (result.stderr || ''); expect(combined).toMatch(/FATAL/i); expect(combined).toMatch(/JWT_SECRET/); }); it('crashes on startup when ALLOWED_ORIGINS is missing in production', () => { const result = spawnConfig({ NODE_ENV: 'production', JWT_SECRET: 'a-real-secret-with-enough-entropy-for-tests', ALLOWED_ORIGINS: '', }); expect(result.status).not.toBe(0); const combined = (result.stdout || '') + (result.stderr || ''); expect(combined).toMatch(/FATAL/i); expect(combined).toMatch(/ALLOWED_ORIGINS/); }); it('boots in production when JWT_SECRET + ALLOWED_ORIGINS are set', () => { const result = spawnConfig({ NODE_ENV: 'production', JWT_SECRET: 'a-real-secret-with-enough-entropy-for-tests', ALLOWED_ORIGINS: 'https://example.com', }); expect(result.status).toBe(0); }); it('boots in development with a clearly-marked dev fallback when JWT_SECRET is unset', () => { const result = spawnConfig({ NODE_ENV: 'development', // JWT_SECRET deliberately unset JWT_SECRET: '', ALLOWED_ORIGINS: '', }); // In dev we want the server to start (so contributors can run without // a .env). The fallback is a known-insecure string we should never // see in production. expect(result.status).toBe(0); // The config emits a loud WARNING so the dev sees it in logs. const combined = (result.stdout || '') + (result.stderr || ''); expect(combined).toMatch(/WARNING.*JWT_SECRET/); }); });