Files
livedash-node/tests/integration/security-headers-basic.test.ts
Kaj Kowalski 1eea2cc3e4 refactor: fix biome linting issues and update project documentation
- Fix 36+ biome linting issues reducing errors/warnings from 227 to 191
- Replace explicit 'any' types with proper TypeScript interfaces
- Fix React hooks dependencies and useCallback patterns
- Resolve unused variables and parameter assignment issues
- Improve accessibility with proper label associations
- Add comprehensive API documentation for admin and security features
- Update README.md with accurate PostgreSQL setup and current tech stack
- Create complete documentation for audit logging, CSP monitoring, and batch processing
- Fix outdated project information and missing developer workflows
2025-07-12 00:28:09 +02:00

179 lines
6.4 KiB
TypeScript

import { describe, it, expect } from "vitest";
describe("Security Headers Configuration", () => {
describe("Next.js Config Validation", () => {
it("should have valid security headers configuration", async () => {
// Import the Next.js config
const nextConfig = await import("../../next.config.js");
expect(nextConfig.default).toBeDefined();
expect(nextConfig.default.headers).toBeDefined();
expect(typeof nextConfig.default.headers).toBe("function");
});
it("should generate expected headers structure", async () => {
const nextConfig = await import("../../next.config.js");
const headers = await nextConfig.default.headers();
expect(Array.isArray(headers)).toBe(true);
expect(headers.length).toBeGreaterThan(0);
// Find the main security headers configuration
const securityConfig = headers.find(
(h) => h.source === "/(.*)" && h.headers.length > 1
);
expect(securityConfig).toBeDefined();
if (securityConfig) {
const headerNames = securityConfig.headers.map((h) => h.key);
// Check required security headers are present
expect(headerNames).toContain("X-Content-Type-Options");
expect(headerNames).toContain("X-Frame-Options");
expect(headerNames).toContain("X-XSS-Protection");
expect(headerNames).toContain("Referrer-Policy");
expect(headerNames).toContain("Content-Security-Policy");
expect(headerNames).toContain("Permissions-Policy");
expect(headerNames).toContain("X-DNS-Prefetch-Control");
}
});
it("should have correct security header values", async () => {
const nextConfig = await import("../../next.config.js");
const headers = await nextConfig.default.headers();
const securityConfig = headers.find(
(h) => h.source === "/(.*)" && h.headers.length > 1
);
if (securityConfig) {
const headerMap = new Map(
securityConfig.headers.map((h) => [h.key, h.value])
);
expect(headerMap.get("X-Content-Type-Options")).toBe("nosniff");
expect(headerMap.get("X-Frame-Options")).toBe("DENY");
expect(headerMap.get("X-XSS-Protection")).toBe("1; mode=block");
expect(headerMap.get("Referrer-Policy")).toBe(
"strict-origin-when-cross-origin"
);
expect(headerMap.get("X-DNS-Prefetch-Control")).toBe("off");
// CSP should contain essential directives
const csp = headerMap.get("Content-Security-Policy");
expect(csp).toContain("default-src 'self'");
expect(csp).toContain("frame-ancestors 'none'");
expect(csp).toContain("object-src 'none'");
// Permissions Policy should restrict dangerous features
const permissions = headerMap.get("Permissions-Policy");
expect(permissions).toContain("camera=()");
expect(permissions).toContain("microphone=()");
expect(permissions).toContain("geolocation=()");
}
});
it("should handle HSTS header based on environment", async () => {
const nextConfig = await import("../../next.config.js");
// Test production environment
const originalEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "production";
const prodHeaders = await nextConfig.default.headers();
const hstsConfig = prodHeaders.find((h) =>
h.headers.some((header) => header.key === "Strict-Transport-Security")
);
if (hstsConfig) {
const hstsHeader = hstsConfig.headers.find(
(h) => h.key === "Strict-Transport-Security"
);
expect(hstsHeader?.value).toBe(
"max-age=31536000; includeSubDomains; preload"
);
}
// Test development environment
process.env.NODE_ENV = "development";
const devHeaders = await nextConfig.default.headers();
const devHstsConfig = devHeaders.find((h) =>
h.headers.some((header) => header.key === "Strict-Transport-Security")
);
// In development, HSTS header array should be empty
if (devHstsConfig) {
expect(devHstsConfig.headers.length).toBe(0);
}
// Restore original environment
process.env.NODE_ENV = originalEnv;
});
});
describe("CSP Directive Validation", () => {
it("should have comprehensive CSP directives", async () => {
const nextConfig = await import("../../next.config.js");
const headers = await nextConfig.default.headers();
const securityConfig = headers.find(
(h) => h.source === "/(.*)" && h.headers.length > 1
);
const cspHeader = securityConfig?.headers.find(
(h) => h.key === "Content-Security-Policy"
);
expect(cspHeader).toBeDefined();
if (cspHeader) {
const csp = cspHeader.value;
// Essential security directives
expect(csp).toContain("default-src 'self'");
expect(csp).toContain("object-src 'none'");
expect(csp).toContain("base-uri 'self'");
expect(csp).toContain("form-action 'self'");
expect(csp).toContain("frame-ancestors 'none'");
expect(csp).toContain("upgrade-insecure-requests");
// Next.js compatibility directives
expect(csp).toContain(
"script-src 'self' 'unsafe-eval' 'unsafe-inline'"
);
expect(csp).toContain("style-src 'self' 'unsafe-inline'");
expect(csp).toContain("img-src 'self' data: https:");
expect(csp).toContain("font-src 'self' data:");
expect(csp).toContain("connect-src 'self' https:");
}
});
});
describe("Permissions Policy Validation", () => {
it("should restrict dangerous browser features", async () => {
const nextConfig = await import("../../next.config.js");
const headers = await nextConfig.default.headers();
const securityConfig = headers.find(
(h) => h.source === "/(.*)" && h.headers.length > 1
);
const permissionsHeader = securityConfig?.headers.find(
(h) => h.key === "Permissions-Policy"
);
expect(permissionsHeader).toBeDefined();
if (permissionsHeader) {
const permissions = permissionsHeader.value;
// Should disable privacy-sensitive features
expect(permissions).toContain("camera=()");
expect(permissions).toContain("microphone=()");
expect(permissions).toContain("geolocation=()");
expect(permissions).toContain("interest-cohort=()");
expect(permissions).toContain("browsing-topics=()");
}
});
});
});