import { expect, tap } from '@git.zone/tstest/tapbundle'; import { SharedSecurityManager } from '../../../ts/core/utils/shared-security-manager.js'; import type { IRouteConfig, IRouteContext } from '../../../ts/proxies/smart-proxy/models/route-types.js'; // Test security manager tap.test('Shared Security Manager', async () => { let securityManager: SharedSecurityManager; // Set up a new security manager for each test securityManager = new SharedSecurityManager({ maxConnectionsPerIP: 5, connectionRateLimitPerMinute: 10 }); tap.test('should validate IPs correctly', async () => { // Should allow IPs under connection limit expect(securityManager.validateIP('192.168.1.1').allowed).toBeTrue(); // Track multiple connections for (let i = 0; i < 4; i++) { securityManager.trackConnectionByIP('192.168.1.1', `conn_${i}`); } // Should still allow IPs under connection limit expect(securityManager.validateIP('192.168.1.1').allowed).toBeTrue(); // Add one more to reach the limit securityManager.trackConnectionByIP('192.168.1.1', 'conn_4'); // Should now block IPs over connection limit expect(securityManager.validateIP('192.168.1.1').allowed).toBeFalse(); // Remove a connection securityManager.removeConnectionByIP('192.168.1.1', 'conn_0'); // Should allow again after connection is removed expect(securityManager.validateIP('192.168.1.1').allowed).toBeTrue(); }); tap.test('should authorize IPs based on allow/block lists', async () => { // Test with allow list only expect(securityManager.isIPAuthorized('192.168.1.1', ['192.168.1.*'])).toBeTrue(); expect(securityManager.isIPAuthorized('192.168.2.1', ['192.168.1.*'])).toBeFalse(); // Test with block list expect(securityManager.isIPAuthorized('192.168.1.5', ['*'], ['192.168.1.5'])).toBeFalse(); expect(securityManager.isIPAuthorized('192.168.1.1', ['*'], ['192.168.1.5'])).toBeTrue(); // Test with both allow and block lists expect(securityManager.isIPAuthorized('192.168.1.1', ['192.168.1.*'], ['192.168.1.5'])).toBeTrue(); expect(securityManager.isIPAuthorized('192.168.1.5', ['192.168.1.*'], ['192.168.1.5'])).toBeFalse(); }); tap.test('should validate route access', async () => { const route: IRouteConfig = { match: { ports: [8080] }, action: { type: 'forward', target: { host: 'target.com', port: 443 } }, security: { ipAllowList: ['10.0.0.*', '192.168.1.*'], ipBlockList: ['192.168.1.100'], maxConnections: 3 } }; const allowedContext: IRouteContext = { clientIp: '192.168.1.1', port: 8080, serverIp: '127.0.0.1', isTls: false, timestamp: Date.now(), connectionId: 'test_conn_1' }; const blockedByIPContext: IRouteContext = { ...allowedContext, clientIp: '192.168.1.100' }; const blockedByRangeContext: IRouteContext = { ...allowedContext, clientIp: '172.16.0.1' }; const blockedByMaxConnectionsContext: IRouteContext = { ...allowedContext, connectionId: 'test_conn_4' }; expect(securityManager.isAllowed(route, allowedContext)).toBeTrue(); expect(securityManager.isAllowed(route, blockedByIPContext)).toBeFalse(); expect(securityManager.isAllowed(route, blockedByRangeContext)).toBeFalse(); // Test max connections for route - assuming implementation has been updated if ((securityManager as any).trackConnectionByRoute) { (securityManager as any).trackConnectionByRoute(route, 'conn_1'); (securityManager as any).trackConnectionByRoute(route, 'conn_2'); (securityManager as any).trackConnectionByRoute(route, 'conn_3'); // Should now block due to max connections expect(securityManager.isAllowed(route, blockedByMaxConnectionsContext)).toBeFalse(); } }); tap.test('should clean up expired entries', async () => { const route: IRouteConfig = { match: { ports: [8080] }, action: { type: 'forward', target: { host: 'target.com', port: 443 } }, security: { rateLimit: { enabled: true, maxRequests: 5, window: 60 // 60 seconds } } }; const context: IRouteContext = { clientIp: '192.168.1.1', port: 8080, serverIp: '127.0.0.1', isTls: false, timestamp: Date.now(), connectionId: 'test_conn_1' }; // Test rate limiting if method exists if ((securityManager as any).checkRateLimit) { // Add 5 attempts (max allowed) for (let i = 0; i < 5; i++) { expect((securityManager as any).checkRateLimit(route, context)).toBeTrue(); } // Should now be blocked expect((securityManager as any).checkRateLimit(route, context)).toBeFalse(); // Force cleanup (normally runs periodically) if ((securityManager as any).cleanup) { (securityManager as any).cleanup(); } // Should still be blocked since entries are not expired yet expect((securityManager as any).checkRateLimit(route, context)).toBeFalse(); } }); }); // Export test runner export default tap.start();