import { expect, tap } from '@push.rocks/tapbundle'; import { IpUtils } from '../../../ts/core/utils/ip-utils.js'; tap.test('ip-utils - normalizeIP', async () => { // IPv4 normalization const ipv4Variants = IpUtils.normalizeIP('127.0.0.1'); expect(ipv4Variants).toEqual(['127.0.0.1', '::ffff:127.0.0.1']); // IPv6-mapped IPv4 normalization const ipv6MappedVariants = IpUtils.normalizeIP('::ffff:127.0.0.1'); expect(ipv6MappedVariants).toEqual(['::ffff:127.0.0.1', '127.0.0.1']); // IPv6 normalization const ipv6Variants = IpUtils.normalizeIP('::1'); expect(ipv6Variants).toEqual(['::1']); // Invalid/empty input handling expect(IpUtils.normalizeIP('')).toEqual([]); expect(IpUtils.normalizeIP(null as any)).toEqual([]); expect(IpUtils.normalizeIP(undefined as any)).toEqual([]); }); tap.test('ip-utils - isGlobIPMatch', async () => { // Direct matches expect(IpUtils.isGlobIPMatch('127.0.0.1', ['127.0.0.1'])).toEqual(true); expect(IpUtils.isGlobIPMatch('::1', ['::1'])).toEqual(true); // Wildcard matches expect(IpUtils.isGlobIPMatch('127.0.0.1', ['127.0.0.*'])).toEqual(true); expect(IpUtils.isGlobIPMatch('127.0.0.1', ['127.0.*.*'])).toEqual(true); expect(IpUtils.isGlobIPMatch('127.0.0.1', ['127.*.*.*'])).toEqual(true); // IPv4-mapped IPv6 handling expect(IpUtils.isGlobIPMatch('::ffff:127.0.0.1', ['127.0.0.1'])).toEqual(true); expect(IpUtils.isGlobIPMatch('127.0.0.1', ['::ffff:127.0.0.1'])).toEqual(true); // Match multiple patterns expect(IpUtils.isGlobIPMatch('127.0.0.1', ['10.0.0.1', '127.0.0.1', '192.168.1.1'])).toEqual(true); // Non-matching patterns expect(IpUtils.isGlobIPMatch('127.0.0.1', ['10.0.0.1'])).toEqual(false); expect(IpUtils.isGlobIPMatch('127.0.0.1', ['128.0.0.1'])).toEqual(false); expect(IpUtils.isGlobIPMatch('127.0.0.1', ['127.0.0.2'])).toEqual(false); // Edge cases expect(IpUtils.isGlobIPMatch('', ['127.0.0.1'])).toEqual(false); expect(IpUtils.isGlobIPMatch('127.0.0.1', [])).toEqual(false); expect(IpUtils.isGlobIPMatch('127.0.0.1', null as any)).toEqual(false); expect(IpUtils.isGlobIPMatch(null as any, ['127.0.0.1'])).toEqual(false); }); tap.test('ip-utils - isIPAuthorized', async () => { // Basic tests to check the core functionality works // No restrictions - all IPs allowed expect(IpUtils.isIPAuthorized('127.0.0.1')).toEqual(true); // Basic blocked IP test const blockedIP = '8.8.8.8'; const blockedIPs = [blockedIP]; expect(IpUtils.isIPAuthorized(blockedIP, [], blockedIPs)).toEqual(false); // Basic allowed IP test const allowedIP = '10.0.0.1'; const allowedIPs = [allowedIP]; expect(IpUtils.isIPAuthorized(allowedIP, allowedIPs)).toEqual(true); expect(IpUtils.isIPAuthorized('192.168.1.1', allowedIPs)).toEqual(false); }); tap.test('ip-utils - isPrivateIP', async () => { // Private IPv4 ranges expect(IpUtils.isPrivateIP('10.0.0.1')).toEqual(true); expect(IpUtils.isPrivateIP('172.16.0.1')).toEqual(true); expect(IpUtils.isPrivateIP('172.31.255.255')).toEqual(true); expect(IpUtils.isPrivateIP('192.168.0.1')).toEqual(true); expect(IpUtils.isPrivateIP('127.0.0.1')).toEqual(true); // Public IPv4 addresses expect(IpUtils.isPrivateIP('8.8.8.8')).toEqual(false); expect(IpUtils.isPrivateIP('203.0.113.1')).toEqual(false); // IPv4-mapped IPv6 handling expect(IpUtils.isPrivateIP('::ffff:10.0.0.1')).toEqual(true); expect(IpUtils.isPrivateIP('::ffff:8.8.8.8')).toEqual(false); // Private IPv6 addresses expect(IpUtils.isPrivateIP('::1')).toEqual(true); expect(IpUtils.isPrivateIP('fd00::')).toEqual(true); expect(IpUtils.isPrivateIP('fe80::1')).toEqual(true); // Public IPv6 addresses expect(IpUtils.isPrivateIP('2001:db8::1')).toEqual(false); // Edge cases expect(IpUtils.isPrivateIP('')).toEqual(false); expect(IpUtils.isPrivateIP(null as any)).toEqual(false); expect(IpUtils.isPrivateIP(undefined as any)).toEqual(false); }); tap.test('ip-utils - isPublicIP', async () => { // Public IPv4 addresses expect(IpUtils.isPublicIP('8.8.8.8')).toEqual(true); expect(IpUtils.isPublicIP('203.0.113.1')).toEqual(true); // Private IPv4 ranges expect(IpUtils.isPublicIP('10.0.0.1')).toEqual(false); expect(IpUtils.isPublicIP('172.16.0.1')).toEqual(false); expect(IpUtils.isPublicIP('192.168.0.1')).toEqual(false); expect(IpUtils.isPublicIP('127.0.0.1')).toEqual(false); // Public IPv6 addresses expect(IpUtils.isPublicIP('2001:db8::1')).toEqual(true); // Private IPv6 addresses expect(IpUtils.isPublicIP('::1')).toEqual(false); expect(IpUtils.isPublicIP('fd00::')).toEqual(false); expect(IpUtils.isPublicIP('fe80::1')).toEqual(false); // Edge cases - the implementation treats these as non-private, which is technically correct but might not be what users expect const emptyResult = IpUtils.isPublicIP(''); expect(emptyResult).toEqual(true); const nullResult = IpUtils.isPublicIP(null as any); expect(nullResult).toEqual(true); const undefinedResult = IpUtils.isPublicIP(undefined as any); expect(undefinedResult).toEqual(true); }); tap.test('ip-utils - cidrToGlobPatterns', async () => { // Class C network const classC = IpUtils.cidrToGlobPatterns('192.168.1.0/24'); expect(classC).toEqual(['192.168.1.*']); // Class B network const classB = IpUtils.cidrToGlobPatterns('172.16.0.0/16'); expect(classB).toEqual(['172.16.*.*']); // Class A network const classA = IpUtils.cidrToGlobPatterns('10.0.0.0/8'); expect(classA).toEqual(['10.*.*.*']); // Small subnet (/28 = 16 addresses) const smallSubnet = IpUtils.cidrToGlobPatterns('192.168.1.0/28'); expect(smallSubnet.length).toEqual(16); expect(smallSubnet).toContain('192.168.1.0'); expect(smallSubnet).toContain('192.168.1.15'); // Invalid inputs expect(IpUtils.cidrToGlobPatterns('')).toEqual([]); expect(IpUtils.cidrToGlobPatterns('192.168.1.0')).toEqual([]); expect(IpUtils.cidrToGlobPatterns('192.168.1.0/')).toEqual([]); expect(IpUtils.cidrToGlobPatterns('192.168.1.0/33')).toEqual([]); expect(IpUtils.cidrToGlobPatterns('invalid/24')).toEqual([]); }); export default tap.start();