super-productivity/packages/super-sync-server/tests/security-fixes.spec.ts
Johannes Millan 8ba3a07f70 test(sync): fix failing unit tests for recent server changes
- passkey.spec.ts: accept both email verification and auto-verify messages
- security-fixes.spec.ts: update expected CORS origins to include preview pattern
- sync-operations.spec.ts: use CURRENT_SCHEMA_VERSION instead of hardcoded value
2026-01-24 21:14:58 +01:00

155 lines
5.2 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { loadConfigFromEnv } from '../src/config';
// Store original env
const originalEnv = { ...process.env };
const resetEnv = (): void => {
process.env = { ...originalEnv };
};
describe('Security Fixes', () => {
beforeEach(() => {
resetEnv();
vi.resetModules();
});
afterEach(() => {
resetEnv();
});
describe('Wildcard CORS Blocking in Production', () => {
it('should throw error when CORS_ORIGINS=* in production', () => {
process.env.NODE_ENV = 'production';
process.env.PUBLIC_URL = 'https://example.com';
process.env.CORS_ORIGINS = '*';
expect(() => loadConfigFromEnv()).toThrow(
'CORS_ORIGINS wildcard (*) is not allowed in production',
);
});
it('should allow wildcard CORS in development with warning', () => {
process.env.NODE_ENV = 'development';
process.env.CORS_ORIGINS = '*';
// Should not throw
const config = loadConfigFromEnv();
expect(config.cors.allowedOrigins).toContain('*');
});
it('should allow explicit origins in production', () => {
process.env.NODE_ENV = 'production';
process.env.PUBLIC_URL = 'https://example.com';
process.env.CORS_ORIGINS = 'https://app.example.com,https://admin.example.com';
const config = loadConfigFromEnv();
expect(config.cors.allowedOrigins).toEqual([
'https://app.example.com',
'https://admin.example.com',
]);
});
it('should throw when wildcard is one of multiple origins in production', () => {
process.env.NODE_ENV = 'production';
process.env.PUBLIC_URL = 'https://example.com';
process.env.CORS_ORIGINS = 'https://example.com,*';
expect(() => loadConfigFromEnv()).toThrow(
'CORS_ORIGINS wildcard (*) is not allowed in production',
);
});
it('should use default secure origins when CORS_ORIGINS not set', () => {
process.env.NODE_ENV = 'production';
process.env.PUBLIC_URL = 'https://example.com';
delete process.env.CORS_ORIGINS;
const config = loadConfigFromEnv();
expect(config.cors.allowedOrigins).toEqual([
'https://app.super-productivity.com',
/^https:\/\/[a-zA-Z0-9-]+\.super-productivity-preview\.pages\.dev$/,
]);
});
});
describe('HTML Escape Function (XSS Prevention)', () => {
it('should escape HTML special characters in privacy template', async () => {
// We test the escapeHtml function indirectly through the server module
// by checking that privacy config values are escaped
// This is tested by verifying the server module has the escapeHtml function
// and uses it for all privacy template replacements
const serverModule = await import('../src/server');
expect(serverModule).toBeDefined();
// The actual XSS prevention is tested by integration - the function exists
// and is applied to all template replacements
});
});
describe('Content Security Policy', () => {
it('should have CSP enabled in helmet configuration', async () => {
// This test verifies the server creates with CSP enabled
// The actual CSP directives are tested by integration
const { createServer } = await import('../src/server');
expect(createServer).toBeDefined();
// The CSP is configured in the server setup
// We verify the configuration exists and is not false
});
});
describe('HTTPS Enforcement in Production', () => {
it('should reject non-HTTPS PUBLIC_URL in production', () => {
process.env.NODE_ENV = 'production';
process.env.PUBLIC_URL = 'http://example.com';
process.env.CORS_ORIGINS = 'https://app.example.com';
expect(() => loadConfigFromEnv()).toThrow(
'PUBLIC_URL must use HTTPS in production',
);
});
it('should allow HTTP PUBLIC_URL in development', () => {
process.env.NODE_ENV = 'development';
process.env.PUBLIC_URL = 'http://localhost:1900';
const config = loadConfigFromEnv();
expect(config.publicUrl).toBe('http://localhost:1900');
});
});
describe('Test Mode Security', () => {
it('should reject TEST_MODE in production', () => {
process.env.NODE_ENV = 'production';
process.env.PUBLIC_URL = 'https://example.com';
process.env.CORS_ORIGINS = 'https://app.example.com';
process.env.TEST_MODE = 'true';
process.env.TEST_MODE_CONFIRM = 'yes-i-understand-the-risks';
expect(() => loadConfigFromEnv()).toThrow(
'TEST_MODE cannot be enabled in production',
);
});
it('should require confirmation for TEST_MODE', () => {
process.env.NODE_ENV = 'development';
process.env.TEST_MODE = 'true';
// Missing TEST_MODE_CONFIRM
expect(() => loadConfigFromEnv()).toThrow(
'TEST_MODE requires TEST_MODE_CONFIRM=yes-i-understand-the-risks',
);
});
it('should allow TEST_MODE with proper confirmation in development', () => {
process.env.NODE_ENV = 'development';
process.env.TEST_MODE = 'true';
process.env.TEST_MODE_CONFIRM = 'yes-i-understand-the-risks';
const config = loadConfigFromEnv();
expect(config.testMode?.enabled).toBe(true);
});
});
});