NetworkRestrictions.utils.ts75 lines · main
1import { collapseIPv6Number, IPv4CidrRange, IPv6CidrRange, Validator } from 'ip-num'
2
3const privateIPv4Ranges = [
4 IPv4CidrRange.fromCidr('10.0.0.0/8'),
5 IPv4CidrRange.fromCidr('172.16.0.0/12'),
6 IPv4CidrRange.fromCidr('192.168.0.0/16'),
7]
8
9const privateIPv6Ranges = [IPv6CidrRange.fromCidr('fc00::/7')]
10
11export const isValidAddress = (address: string) => {
12 // Only validating address, should not include cidr block size
13 if (address.includes('/')) return false
14 const [isIpv4] = Validator.isValidIPv4String(address)
15 const [isIpv6] = Validator.isValidIPv6String(address)
16 return isIpv4 || isIpv6
17}
18
19export const checkIfPrivate = (type: 'IPv4' | 'IPv6' | undefined, cidr: string) => {
20 try {
21 if (type === undefined) return false
22 if (type === 'IPv4') {
23 const address = IPv4CidrRange.fromCidr(`${cidr}/32`)
24 const res = privateIPv4Ranges.map((range) => address.inside(range))
25 return res.includes(true)
26 } else {
27 const address = IPv6CidrRange.fromCidr(`${cidr}/128`)
28 const res = privateIPv6Ranges.map((range) => address.inside(range))
29 return res.includes(true)
30 }
31 } catch (error) {
32 return false
33 }
34}
35
36const padHexadecimal = (str: string) => `${'0'.repeat(4 - str.length)}${str}`
37
38export const getAddressEndRange = (type: 'IPv4' | 'IPv6', address: string) => {
39 if (type === 'IPv4') {
40 try {
41 const cidr = IPv4CidrRange.fromCidr(address)
42 const start = cidr.getFirst().octets.join('.')
43 const end = cidr.getLast().octets.join('.')
44 return { start, end }
45 } catch (error: any) {
46 return undefined
47 }
48 } else {
49 try {
50 const cidr = IPv6CidrRange.fromCidr(address)
51 const start = cidr.getFirst().hexadecatet.toString().split(',').map(padHexadecimal).join(':')
52 const end = cidr.getLast().hexadecatet.toString().split(',').map(padHexadecimal).join(':')
53 return { start, end }
54 } catch (error: any) {
55 return undefined
56 }
57 }
58}
59
60// [Joshen] Using same logic as worker
61// https://github.com/briven/platform/blob/840c9596e8bf9e9090ec94de1756bd511e67393a/worker/src/tasks/db/add_as_pooler_tenant.ts#L176C15-L176C15
62export const normalize = (address: string) => {
63 const [isIpV4] = Validator.isValidIPv4String(address.split('/')[0])
64 if (isIpV4) {
65 const cidr = IPv4CidrRange.fromCidr(address)
66 const base = cidr.getFirst().toString()
67 const mask = cidr.getPrefix().toString()
68 return `${base}/${mask}`
69 } else {
70 const cidr = IPv6CidrRange.fromCidr(address)
71 const base = collapseIPv6Number(cidr.getFirst().toString())
72 const mask = cidr.getPrefix().toString()
73 return `${base}/${mask}`
74 }
75}