/**
* Security Tests
* Validates security implementations
*/
const fs = require('fs');
const path = require('path');
let passed = 0;
let failed = 0;
function test(name, condition) {
if (condition) {
console.log(`✓ ${name}`);
passed++;
} else {
console.log(`✗ ${name}`);
failed++;
}
}
console.log('\n=== SECURITY TESTS ===\n');
// Test 1: Security utils module exists
const securityUtilsPath = path.join(__dirname, '..', 'dist', 'core', 'security', 'security-utils.js');
test('Security utils module exists', fs.existsSync(securityUtilsPath));
// Test 2: Check for CSP in webviews
console.log('\n--- Content Security Policy Tests ---');
const dataflowDesigner = fs.readFileSync(
path.join(__dirname, '..', 'src', 'views', 'dataflow-designer-panel.ts'), 'utf8'
);
test('Dataflow Designer has CSP',
dataflowDesigner.includes('getCSPMetaTag') && dataflowDesigner.includes('nonce')
);
const realtimeHub = fs.readFileSync(
path.join(__dirname, '..', 'src', 'views', 'realtimehub-tree-provider.ts'), 'utf8'
);
test('Real-Time Hub has CSP',
realtimeHub.includes('getCSPMetaTag') && realtimeHub.includes('nonce')
);
const dataWrangler = fs.readFileSync(
path.join(__dirname, '..', 'src', 'views', 'datawrangler-tree-provider.ts'), 'utf8'
);
test('Data Wrangler has CSP',
dataWrangler.includes('getCSPMetaTag') && dataWrangler.includes('nonce')
);
// Test 3: Check for HTML sanitization
console.log('\n--- HTML Sanitization Tests ---');
test('Dataflow Designer uses escapeHtml', dataflowDesigner.includes('escapeHtml'));
test('Real-Time Hub uses escapeHtml', realtimeHub.includes('escapeHtml'));
test('Data Wrangler uses escapeHtml', dataWrangler.includes('escapeHtml'));
// Test 4: Check for SQL sanitization
console.log('\n--- SQL Injection Prevention Tests ---');
const warehouseService = fs.readFileSync(
path.join(__dirname, '..', 'src', 'warehouse', 'warehouse-service.ts'), 'utf8'
);
test('Warehouse Service uses sanitizeSqlIdentifier',
warehouseService.includes('sanitizeSqlIdentifier')
);
const warehouseProvider = fs.readFileSync(
path.join(__dirname, '..', 'src', 'views', 'warehouse-tree-provider.ts'), 'utf8'
);
test('Warehouse Provider uses sanitizeSqlIdentifier',
warehouseProvider.includes('sanitizeSqlIdentifier')
);
// Test 5: Check for secure token storage
console.log('\n--- Secure Token Storage Tests ---');
const apiService = fs.readFileSync(
path.join(__dirname, '..', 'src', 'core', 'api', 'fabric-api-service.ts'), 'utf8'
);
test('API Service uses SecretStorage', apiService.includes('secretStorage'));
test('API Service has clearToken method', apiService.includes('clearToken'));
// Test 6: Check for rate limiting
console.log('\n--- Rate Limiting Tests ---');
test('API Service uses RateLimiter', apiService.includes('RateLimiter'));
test('API Service has timeout', apiService.includes('fetchWithTimeout'));
// Test 7: Check for error sanitization
console.log('\n--- Error Sanitization Tests ---');
test('API Service uses sanitizeErrorForDisplay', apiService.includes('sanitizeErrorForDisplay'));
const extension = fs.readFileSync(
path.join(__dirname, '..', 'src', 'extension.ts'), 'utf8'
);
test('Extension uses sanitizeErrorForDisplay', extension.includes('sanitizeErrorForDisplay'));
// Test 8: Check for input validation
console.log('\n--- Input Validation Tests ---');
test('Extension has workspace ID validation',
extension.includes('validateInput') || extension.includes('uuidRegex')
);
// Test 9: Check for message validation in webviews
console.log('\n--- Webview Message Validation Tests ---');
test('Dataflow Designer validates messages', dataflowDesigner.includes('validateWebviewMessage'));
// Test 10: Check for audit logging
console.log('\n--- Audit Logging Tests ---');
test('Extension initializes security', extension.includes('initializeSecurity'));
test('Extension uses AuditLogger', extension.includes('AuditLogger'));
// Test 11: Security files exist
console.log('\n--- Security Files Tests ---');
test('SECURITY.md exists',
fs.existsSync(path.join(__dirname, '..', 'SECURITY.md'))
);
test('SECURITY_AUDIT.md exists',
fs.existsSync(path.join(__dirname, '..', 'SECURITY_AUDIT.md'))
);
// Test 12: No dangerous patterns
console.log('\n--- Dangerous Pattern Checks ---');
const allSourceFiles = [
dataflowDesigner, realtimeHub, dataWrangler, warehouseService,
warehouseProvider, apiService, extension
].join('\n');
test('No eval() usage', !allSourceFiles.includes('eval('));
test('No new Function() usage', !allSourceFiles.includes('new Function('));
test('No document.write usage', !allSourceFiles.includes('document.write'));
// Test 13: Check security utils content
console.log('\n--- Security Utils Implementation Tests ---');
const securityUtils = fs.readFileSync(
path.join(__dirname, '..', 'src', 'core', 'security', 'security-utils.ts'), 'utf8'
);
test('Security utils has getNonce', securityUtils.includes('function getNonce'));
test('Security utils has escapeHtml', securityUtils.includes('function escapeHtml'));
test('Security utils has sanitizeSqlIdentifier', securityUtils.includes('function sanitizeSqlIdentifier'));
test('Security utils has RateLimiter class', securityUtils.includes('class RateLimiter'));
test('Security utils has SecureTokenStorage', securityUtils.includes('class SecureTokenStorage'));
test('Security utils has AuditLogger', securityUtils.includes('class AuditLogger'));
test('Security utils has SecurityError', securityUtils.includes('class SecurityError'));
test('Security utils has fetchWithTimeout', securityUtils.includes('function fetchWithTimeout'));
test('Security utils has validateWebviewMessage', securityUtils.includes('function validateWebviewMessage'));
test('Security utils has ValidationRules', securityUtils.includes('ValidationRules'));
// Summary
console.log('\n==================================================');
console.log('SECURITY TEST SUMMARY');
console.log('==================================================');
console.log(`Total: ${passed + failed}`);
console.log(`Passed: ${passed}`);
console.log(`Failed: ${failed}`);
if (failed > 0) {
process.exit(1);
}