geocrop-platform./apps/nextgen/server/tests/config.test.js

83 lines
3.0 KiB
JavaScript

/**
* 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/);
});
});