import { tap, expect } from '@git.zone/tstest/tapbundle'; import * as plugins from '../ts/plugins.js'; import { DcRouterDb, IpIntelligenceDoc, SecurityBlockRuleDoc, SecurityPolicyAuditDoc } from '../ts/db/index.js'; import { SecurityPolicyManager } from '../ts/security/index.js'; const createTestDb = async () => { const storagePath = plugins.path.join( plugins.os.tmpdir(), `dcrouter-security-policy-${Date.now()}-${Math.random().toString(16).slice(2)}`, ); DcRouterDb.resetInstance(); const db = DcRouterDb.getInstance({ storagePath, dbName: `dcrouter-security-policy-${Date.now()}-${Math.random().toString(16).slice(2)}`, }); await db.start(); await db.getDb().mongoDb.createCollection('__test_init'); return { async cleanup() { await db.stop(); DcRouterDb.resetInstance(); await plugins.fs.promises.rm(storagePath, { recursive: true, force: true }); }, }; }; const testDbPromise = createTestDb(); const clearTestState = async () => { for (const rule of await SecurityBlockRuleDoc.findAll()) { await rule.delete(); } for (const record of await IpIntelligenceDoc.findAll()) { await record.delete(); } for (const event of await SecurityPolicyAuditDoc.findRecent(1000)) { await event.delete(); } }; const createIntelligenceResult = (asn: number) => ({ asn, asnOrg: `ASN ${asn}`, registrantOrg: null, registrantCountry: null, networkRange: null, networkCidrs: null, abuseContact: null, country: null, countryCode: 'US', city: null, latitude: null, longitude: null, accuracyRadius: null, timezone: null, }); tap.test('SecurityPolicyManager compiles start-end CIDR rules for edge firewall snapshots', async () => { await testDbPromise; await clearTestState(); const manager = new SecurityPolicyManager(); await manager.createBlockRule({ type: 'cidr', value: '203.0.113.0 - 203.0.113.255', reason: 'test range', }); const policy = await manager.compilePolicy(); expect(policy.blockedCidrs).toEqual(['203.0.113.0/24']); const firewall = await manager.compileRemoteIngressFirewall(); expect(firewall.blockedIps).toEqual(['203.0.113.0/24']); }); tap.test('SecurityPolicyManager compiles intelligence network ranges for ASN rules', async () => { await testDbPromise; await clearTestState(); const manager = new SecurityPolicyManager(); const intelligenceDoc = new IpIntelligenceDoc(); intelligenceDoc.ipAddress = '198.51.100.23'; intelligenceDoc.asn = 64500; intelligenceDoc.asnOrg = 'Example Network'; intelligenceDoc.networkRange = '198.51.100.0 - 198.51.100.127'; intelligenceDoc.firstSeenAt = Date.now(); intelligenceDoc.lastSeenAt = Date.now(); intelligenceDoc.updatedAt = Date.now(); intelligenceDoc.seenCount = 1; await intelligenceDoc.save(); await manager.createBlockRule({ type: 'asn', value: 'AS64500', reason: 'test asn range', }); const policy = await manager.compilePolicy(); expect(policy.blockedCidrs).toEqual(['198.51.100.0/25']); }); tap.test('SecurityPolicyManager compiles intelligence CIDR arrays for ASN rules', async () => { await testDbPromise; await clearTestState(); const manager = new SecurityPolicyManager(); const intelligenceDoc = new IpIntelligenceDoc(); intelligenceDoc.ipAddress = '198.51.100.130'; intelligenceDoc.asn = 64501; intelligenceDoc.asnOrg = 'Example Split Network'; intelligenceDoc.networkRange = null; intelligenceDoc.networkCidrs = ['198.51.100.128/25', '198.51.101.0/24']; intelligenceDoc.firstSeenAt = Date.now(); intelligenceDoc.lastSeenAt = Date.now(); intelligenceDoc.updatedAt = Date.now(); intelligenceDoc.seenCount = 1; await intelligenceDoc.save(); await manager.createBlockRule({ type: 'asn', value: 'AS64501', reason: 'test asn cidr array', }); const policy = await manager.compilePolicy(); expect(policy.blockedCidrs).toEqual(['198.51.100.128/25', '198.51.101.0/24']); }); tap.test('SecurityPolicyManager returns an explicit empty edge firewall snapshot', async () => { await testDbPromise; await clearTestState(); const manager = new SecurityPolicyManager(); const firewall = await manager.compileRemoteIngressFirewall(); expect(firewall).toEqual({ blockedIps: [] }); }); tap.test('SecurityPolicyManager filters listed IP intelligence records', async () => { await testDbPromise; await clearTestState(); const manager = new SecurityPolicyManager(); for (const [ipAddress, asn] of [['8.8.8.8', 15169], ['1.1.1.1', 13335]] as const) { const intelligenceDoc = new IpIntelligenceDoc(); intelligenceDoc.ipAddress = ipAddress; intelligenceDoc.asn = asn; intelligenceDoc.asnOrg = `ASN ${asn}`; intelligenceDoc.firstSeenAt = Date.now(); intelligenceDoc.lastSeenAt = Date.now(); intelligenceDoc.updatedAt = Date.now(); intelligenceDoc.seenCount = 1; await intelligenceDoc.save(); } const records = await manager.listIpIntelligence({ ipAddresses: ['1.1.1.1'] }); expect(records).toHaveLength(1); expect(records[0].ipAddress).toEqual('1.1.1.1'); }); tap.test('SecurityPolicyManager force refresh waits for an in-flight background observation', async () => { await testDbPromise; await clearTestState(); const manager = new SecurityPolicyManager({ intelligenceRefreshMs: 0 }); let releaseFirstLookup!: () => void; let lookupCount = 0; (manager as any).smartNetwork = { getIpIntelligence: async () => { lookupCount++; if (lookupCount === 1) { await new Promise((resolve) => { releaseFirstLookup = resolve; }); return createIntelligenceResult(64500); } return createIntelligenceResult(64501); }, stop: async () => {}, }; const backgroundObservation = manager.observeIp('8.8.8.8'); await new Promise((resolve) => setTimeout(resolve, 10)); const forcedRefresh = manager.refreshIpIntelligence('8.8.8.8'); releaseFirstLookup(); const record = await forcedRefresh; await backgroundObservation; expect(lookupCount).toEqual(2); expect(record?.asn).toEqual(64501); }); tap.test('cleanup security policy test db', async () => { const dbHandle = await testDbPromise; await clearTestState(); await dbHandle.cleanup(); }); export default tap.start();