import { tap, expect } from '@push.rocks/tapbundle'; import { ContentScanner, ThreatCategory } from '../ts/security/classes.contentscanner.js'; import { Email } from '../ts/mta/classes.email.js'; // Test instantiation tap.test('ContentScanner - should be instantiable', async () => { const scanner = ContentScanner.getInstance({ scanBody: true, scanSubject: true, scanAttachments: true }); expect(scanner).toBeTruthy(); }); // Test singleton pattern tap.test('ContentScanner - should use singleton pattern', async () => { const scanner1 = ContentScanner.getInstance(); const scanner2 = ContentScanner.getInstance(); // Both instances should be the same object expect(scanner1 === scanner2).toEqual(true); }); // Test clean email can be correctly distinguished from high-risk email tap.test('ContentScanner - should distinguish between clean and suspicious emails', async () => { // Create an instance with a higher minimum threat score const scanner = new ContentScanner({ minThreatScore: 50 // Higher threshold to consider clean }); // Create a truly clean email with no potentially sensitive data patterns const cleanEmail = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Project Update', text: 'The project is on track. Let me know if you have questions.', html: '

The project is on track. Let me know if you have questions.

' }); // Create a highly suspicious email const suspiciousEmail = new Email({ from: 'admin@bank-fake.com', to: 'victim@example.com', subject: 'URGENT: Your account needs verification now!', text: 'Click here to verify your account or it will be suspended: https://bit.ly/12345', html: '

Click here to verify your account or it will be suspended: click here

' }); // Test both emails const cleanResult = await scanner.scanEmail(cleanEmail); const suspiciousResult = await scanner.scanEmail(suspiciousEmail); console.log('Clean vs Suspicious results:', { cleanScore: cleanResult.threatScore, suspiciousScore: suspiciousResult.threatScore }); // Verify the scanner can distinguish between them // Suspicious email should have a significantly higher score expect(suspiciousResult.threatScore > cleanResult.threatScore + 40).toEqual(true); // Verify clean email scans all expected elements expect(cleanResult.scannedElements.length > 0).toEqual(true); }); // Test phishing detection in subject tap.test('ContentScanner - should detect phishing in subject', async () => { // Create a dedicated scanner for this test const scanner = new ContentScanner({ scanSubject: true, scanBody: true, scanAttachments: false, customRules: [] }); const email = new Email({ from: 'security@bank-account-verify.com', to: 'victim@example.com', subject: 'URGENT: Verify your bank account details immediately', text: 'Your account will be suspended. Please verify your details.', html: '

Your account will be suspended. Please verify your details.

' }); const result = await scanner.scanEmail(email); console.log('Phishing email scan result:', result); // We only care that it detected something suspicious expect(result.threatScore >= 20).toEqual(true); // Check if any threat was detected (specific type may vary) expect(result.threatType).toBeTruthy(); }); // Test malware indicators in body tap.test('ContentScanner - should detect malware indicators in body', async () => { const scanner = ContentScanner.getInstance(); const email = new Email({ from: 'invoice@company.com', to: 'recipient@example.com', subject: 'Your invoice', text: 'Please see the attached invoice. You need to enable macros to view this document properly.', html: '

Please see the attached invoice. You need to enable macros to view this document properly.

' }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatType === ThreatCategory.MALWARE || result.threatType).toBeTruthy(); expect(result.threatScore >= 30).toEqual(true); }); // Test suspicious link detection tap.test('ContentScanner - should detect suspicious links', async () => { const scanner = ContentScanner.getInstance(); const email = new Email({ from: 'newsletter@example.com', to: 'recipient@example.com', subject: 'Weekly Newsletter', text: 'Check our latest offer at https://bit.ly/2x3F5 and https://t.co/abc123', html: '

Check our latest offer at here and here

' }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatType).toEqual(ThreatCategory.SUSPICIOUS_LINK); expect(result.threatScore >= 30).toEqual(true); }); // Test script injection detection tap.test('ContentScanner - should detect script injection', async () => { const scanner = ContentScanner.getInstance(); const email = new Email({ from: 'newsletter@example.com', to: 'recipient@example.com', subject: 'Newsletter', text: 'Check our website', html: '

Check our website

' }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatType).toEqual(ThreatCategory.XSS); expect(result.threatScore >= 40).toEqual(true); }); // Test executable attachment detection tap.test('ContentScanner - should detect executable attachments', async () => { const scanner = ContentScanner.getInstance(); const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Software Update', text: 'Please install the attached software update.', attachments: [{ filename: 'update.exe', content: Buffer.from('MZ...fake executable content...'), contentType: 'application/octet-stream' }] }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatType).toEqual(ThreatCategory.EXECUTABLE); expect(result.threatScore >= 70).toEqual(true); }); // Test macro document detection tap.test('ContentScanner - should detect macro documents', async () => { // Create a mock Office document with macro indicators const fakeDocContent = Buffer.from('Document content...vbaProject.bin...Auto_Open...DocumentOpen...Microsoft VBA...'); const scanner = ContentScanner.getInstance(); const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Financial Report', text: 'Please review the attached financial report.', attachments: [{ filename: 'report.docm', content: fakeDocContent, contentType: 'application/vnd.ms-word.document.macroEnabled.12' }] }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatType).toEqual(ThreatCategory.MALICIOUS_MACRO); expect(result.threatScore >= 60).toEqual(true); }); // Test compound threat detection (multiple indicators) tap.test('ContentScanner - should detect compound threats', async () => { const scanner = ContentScanner.getInstance(); const email = new Email({ from: 'security@bank-verify.com', to: 'victim@example.com', subject: 'URGENT: Verify your account details immediately', text: 'Your account will be suspended unless you verify your details at https://bit.ly/2x3F5', html: '

Your account will be suspended unless you verify your details here.

', attachments: [{ filename: 'verification.exe', content: Buffer.from('MZ...fake executable content...'), contentType: 'application/octet-stream' }] }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatScore > 70).toEqual(true); // Should have a high score due to multiple threats }); // Test custom rules tap.test('ContentScanner - should apply custom rules', async () => { // Create a scanner with custom rules const scanner = new ContentScanner({ customRules: [ { pattern: /CUSTOM_PATTERN_FOR_TESTING/, type: ThreatCategory.CUSTOM_RULE, score: 50, description: 'Custom pattern detected' } ] }); const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Test Custom Rule', text: 'This message contains CUSTOM_PATTERN_FOR_TESTING that should be detected.' }); const result = await scanner.scanEmail(email); expect(result.isClean).toEqual(false); expect(result.threatType).toEqual(ThreatCategory.CUSTOM_RULE); expect(result.threatScore >= 50).toEqual(true); }); // Test threat level classification tap.test('ContentScanner - should classify threat levels correctly', async () => { expect(ContentScanner.getThreatLevel(10)).toEqual('none'); expect(ContentScanner.getThreatLevel(25)).toEqual('low'); expect(ContentScanner.getThreatLevel(50)).toEqual('medium'); expect(ContentScanner.getThreatLevel(80)).toEqual('high'); }); export default tap.start();