128 lines
4.9 KiB
TypeScript
128 lines
4.9 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import * as smartproxy from '../ts/index.js';
|
|
import { RouteValidator } from '../ts/proxies/smart-proxy/utils/route-validator.js';
|
|
import { IpUtils } from '../ts/core/utils/ip-utils.js';
|
|
|
|
tap.test('IP Validation - Shorthand patterns', async () => {
|
|
|
|
// Test shorthand patterns are now accepted
|
|
const testPatterns = [
|
|
{ pattern: '192.168.*', shouldPass: true },
|
|
{ pattern: '192.168.*.*', shouldPass: true },
|
|
{ pattern: '10.*', shouldPass: true },
|
|
{ pattern: '10.*.*.*', shouldPass: true },
|
|
{ pattern: '172.16.*', shouldPass: true },
|
|
{ pattern: '10.0.0.0/8', shouldPass: true },
|
|
{ pattern: '192.168.0.0/16', shouldPass: true },
|
|
{ pattern: '192.168.1.100', shouldPass: true },
|
|
{ pattern: '*', shouldPass: true },
|
|
{ pattern: '192.168.1.1-192.168.1.100', shouldPass: true },
|
|
];
|
|
|
|
for (const { pattern, shouldPass } of testPatterns) {
|
|
const route = {
|
|
name: 'test',
|
|
match: { ports: 80 },
|
|
action: { type: 'forward' as const, targets: [{ host: 'localhost', port: 8080 }] },
|
|
security: { ipAllowList: [pattern] }
|
|
};
|
|
|
|
const result = RouteValidator.validateRoute(route);
|
|
|
|
if (shouldPass) {
|
|
expect(result.valid).toEqual(true);
|
|
console.log(`✅ Pattern '${pattern}' correctly accepted`);
|
|
} else {
|
|
expect(result.valid).toEqual(false);
|
|
console.log(`✅ Pattern '${pattern}' correctly rejected`);
|
|
}
|
|
}
|
|
});
|
|
|
|
tap.test('IP Matching - Runtime shorthand pattern matching', async () => {
|
|
|
|
// Test runtime matching with shorthand patterns
|
|
const testCases = [
|
|
{ ip: '192.168.1.100', patterns: ['192.168.*'], expected: true },
|
|
{ ip: '192.168.1.100', patterns: ['192.168.1.*'], expected: true },
|
|
{ ip: '192.168.1.100', patterns: ['192.168.2.*'], expected: false },
|
|
{ ip: '10.0.0.1', patterns: ['10.*'], expected: true },
|
|
{ ip: '10.1.2.3', patterns: ['10.*'], expected: true },
|
|
{ ip: '172.16.0.1', patterns: ['10.*'], expected: false },
|
|
{ ip: '192.168.1.1', patterns: ['192.168.*.*'], expected: true },
|
|
];
|
|
|
|
for (const { ip, patterns, expected } of testCases) {
|
|
const result = IpUtils.isGlobIPMatch(ip, patterns);
|
|
expect(result).toEqual(expected);
|
|
console.log(`✅ IP ${ip} with pattern ${patterns[0]} = ${result} (expected ${expected})`);
|
|
}
|
|
});
|
|
|
|
tap.test('IP Matching - CIDR notation', async () => {
|
|
|
|
// Test CIDR notation matching
|
|
const cidrTests = [
|
|
{ ip: '10.0.0.1', cidr: '10.0.0.0/8', expected: true },
|
|
{ ip: '10.255.255.255', cidr: '10.0.0.0/8', expected: true },
|
|
{ ip: '11.0.0.1', cidr: '10.0.0.0/8', expected: false },
|
|
{ ip: '192.168.1.1', cidr: '192.168.0.0/16', expected: true },
|
|
{ ip: '192.168.255.255', cidr: '192.168.0.0/16', expected: true },
|
|
{ ip: '192.169.0.1', cidr: '192.168.0.0/16', expected: false },
|
|
{ ip: '192.168.1.100', cidr: '192.168.1.0/24', expected: true },
|
|
{ ip: '192.168.2.100', cidr: '192.168.1.0/24', expected: false },
|
|
];
|
|
|
|
for (const { ip, cidr, expected } of cidrTests) {
|
|
const result = IpUtils.isGlobIPMatch(ip, [cidr]);
|
|
expect(result).toEqual(expected);
|
|
console.log(`✅ IP ${ip} in CIDR ${cidr} = ${result} (expected ${expected})`);
|
|
}
|
|
});
|
|
|
|
tap.test('IP Matching - Range notation', async () => {
|
|
|
|
// Test range notation matching
|
|
const rangeTests = [
|
|
{ ip: '192.168.1.1', range: '192.168.1.1-192.168.1.100', expected: true },
|
|
{ ip: '192.168.1.50', range: '192.168.1.1-192.168.1.100', expected: true },
|
|
{ ip: '192.168.1.100', range: '192.168.1.1-192.168.1.100', expected: true },
|
|
{ ip: '192.168.1.101', range: '192.168.1.1-192.168.1.100', expected: false },
|
|
{ ip: '192.168.2.50', range: '192.168.1.1-192.168.1.100', expected: false },
|
|
];
|
|
|
|
for (const { ip, range, expected } of rangeTests) {
|
|
const result = IpUtils.isGlobIPMatch(ip, [range]);
|
|
expect(result).toEqual(expected);
|
|
console.log(`✅ IP ${ip} in range ${range} = ${result} (expected ${expected})`);
|
|
}
|
|
});
|
|
|
|
tap.test('IP Matching - Mixed patterns', async () => {
|
|
|
|
// Test with mixed pattern types
|
|
const allowList = [
|
|
'10.0.0.0/8', // CIDR
|
|
'192.168.*', // Shorthand glob
|
|
'172.16.1.*', // Specific subnet glob
|
|
'8.8.8.8', // Single IP
|
|
'1.1.1.1-1.1.1.10' // Range
|
|
];
|
|
|
|
const tests = [
|
|
{ ip: '10.1.2.3', expected: true }, // Matches CIDR
|
|
{ ip: '192.168.100.1', expected: true }, // Matches shorthand glob
|
|
{ ip: '172.16.1.5', expected: true }, // Matches specific glob
|
|
{ ip: '8.8.8.8', expected: true }, // Matches single IP
|
|
{ ip: '1.1.1.5', expected: true }, // Matches range
|
|
{ ip: '9.9.9.9', expected: false }, // Doesn't match any
|
|
];
|
|
|
|
for (const { ip, expected } of tests) {
|
|
const result = IpUtils.isGlobIPMatch(ip, allowList);
|
|
expect(result).toEqual(expected);
|
|
console.log(`✅ IP ${ip} in mixed patterns = ${result} (expected ${expected})`);
|
|
}
|
|
});
|
|
|
|
export default tap.start(); |