import { describe, it, expect, beforeAll } from 'vitest';
import request from 'supertest';
import { createServer } from '../../server/index';
import crypto from 'crypto';
describe('Security Audit Tests', () => {
let app: any;
let server: any;
beforeAll(async () => {
// Create test server instance
app = await createServer();
server = app.listen(0); // Use random port
});
describe('Authentication Security', () => {
it('should reject requests without authentication', async () => {
const response = await request(app)
.get('/api/v1/cases')
.expect(401);
expect(response.body).toHaveProperty('error');
});
it('should reject invalid JWT tokens', async () => {
const response = await request(app)
.get('/api/v1/cases')
.set('Authorization', 'Bearer invalid-token')
.expect(401);
expect(response.body.error).toContain('Invalid token');
});
it('should enforce rate limiting on auth endpoints', async () => {
const requests = Array.from({ length: 10 }, () =>
request(app)
.post('/api/v1/auth/login')
.send({ email: 'test@test.com', password: 'wrongpassword' })
);
const responses = await Promise.all(requests);
const rateLimitedResponses = responses.filter(r => r.status === 429);
expect(rateLimitedResponses.length).toBeGreaterThan(0);
});
it('should validate password strength requirements', async () => {
const weakPasswords = ['123', 'password', 'abc123'];
for (const password of weakPasswords) {
const response = await request(app)
.post('/api/v1/auth/register')
.send({
email: 'test@example.com',
password,
registrationNumber: 'REG12345678',
firstName: 'Test',
lastName: 'User'
});
expect(response.status).toBe(400);
expect(response.body.error).toContain('password');
}
});
});
describe('Input Validation Security', () => {
it('should prevent SQL injection in case creation', async () => {
const sqlInjectionPayloads = [
"'; DROP TABLE users; --",
"' OR '1'='1",
"UNION SELECT * FROM users",
];
const validToken = generateTestToken();
for (const payload of sqlInjectionPayloads) {
const response = await request(app)
.post('/api/v1/cases/create')
.set('Authorization', `Bearer ${validToken}`)
.send({
caseType: payload,
jurisdiction: 'ILLINOIS-COOK',
petitioner: 'Test Petitioner',
filingDate: new Date().toISOString()
});
// Should either be rejected with validation error or sanitized
expect([400, 422]).toContain(response.status);
}
});
it('should prevent XSS in case descriptions', async () => {
const xssPayloads = [
'',
'
',
'javascript:alert("xss")',
];
const validToken = generateTestToken();
for (const payload of xssPayloads) {
const response = await request(app)
.post('/api/v1/cases/create')
.set('Authorization', `Bearer ${validToken}`)
.send({
caseType: 'CIVIL',
jurisdiction: 'ILLINOIS-COOK',
petitioner: 'Test Petitioner',
description: payload,
filingDate: new Date().toISOString()
});
if (response.status === 201) {
// If accepted, ensure XSS payload is sanitized
expect(response.body.description).not.toContain('