@tinyhttp/proxy-addr
Advanced tools
Comparing version 2.1.4 to 2.2.0
@@ -5,3 +5,9 @@ import { IncomingMessage } from 'node:http'; | ||
type Req = Pick<IncomingMessage, 'headers' | 'socket'>; | ||
type Trust = ((addr: string, i: number) => boolean) | number[] | string[] | string; | ||
export type TrustParameter = string | number | string[]; | ||
export type TrustFunction = (addr: string, i: number) => boolean; | ||
export type Trust = TrustFunction | TrustParameter; | ||
type Subnet = { | ||
ip: IPv4 | IPv6; | ||
range: number; | ||
}; | ||
/** | ||
@@ -11,6 +17,6 @@ * Get all addresses in the request, optionally stopping | ||
* | ||
* @param request | ||
* @param req | ||
* @param trust | ||
*/ | ||
declare function alladdrs(req: Req, trust: Trust): string[]; | ||
declare function alladdrs(req: Req, trust?: Trust): string[]; | ||
/** | ||
@@ -21,3 +27,3 @@ * Compile argument into trust function. | ||
*/ | ||
declare function compile(val: string | string[] | number[]): (addr: string) => boolean; | ||
declare function compile(val: string | number | string[]): (addr: string, i: number) => boolean; | ||
/** | ||
@@ -29,7 +35,7 @@ * Parse IP notation string into range subnet. | ||
*/ | ||
export declare function parseIPNotation(note: string): [IPv4 | IPv6, string | number]; | ||
export declare function parseIPNotation(note: string): Subnet; | ||
/** | ||
* Determine address of proxied request. | ||
* | ||
* @param request | ||
* @param req | ||
* @param trust | ||
@@ -36,0 +42,0 @@ * @public |
@@ -11,6 +11,11 @@ import { forwarded } from "@tinyhttp/forwarded"; | ||
}; | ||
function isIPRangeName(val) { | ||
return Object.prototype.hasOwnProperty.call(IP_RANGES, val); | ||
} | ||
const isIPv4 = (val) => val.kind() === "ipv4"; | ||
const isIPv6 = (val) => val.kind() === "ipv6"; | ||
const trustNone = () => false; | ||
function alladdrs(req, trust) { | ||
const addrs = forwarded(req); | ||
if (!trust) return addrs; | ||
if (trust == null) return addrs; | ||
if (typeof trust !== "function") trust = compile(trust); | ||
@@ -26,17 +31,19 @@ for (let i = 0; i < addrs.length - 1; i++) { | ||
if (typeof val === "string") trust = [val]; | ||
else if (typeof val === "number") return compileHopsTrust(val); | ||
else if (Array.isArray(val)) trust = val.slice(); | ||
else throw new TypeError("unsupported trust argument"); | ||
for (let i = 0; i < trust.length; i++) { | ||
val = trust[i]; | ||
if (!Object.prototype.hasOwnProperty.call(IP_RANGES, val)) continue; | ||
val = IP_RANGES[val]; | ||
trust.splice.apply(trust, [i, 1].concat(val)); | ||
i += val.length - 1; | ||
const element = trust[i]; | ||
if (!isIPRangeName(element)) continue; | ||
const namedRange = IP_RANGES[element]; | ||
trust.splice(i, 1, ...namedRange); | ||
i += namedRange.length - 1; | ||
} | ||
return compileTrust(compileRangeSubnets(trust)); | ||
} | ||
function compileHopsTrust(hops) { | ||
return (_, i) => i < hops; | ||
} | ||
function compileRangeSubnets(arr) { | ||
const rangeSubnets = new Array(arr.length); | ||
for (let i = 0; i < arr.length; i++) rangeSubnets[i] = parseIPNotation(arr[i]); | ||
return rangeSubnets; | ||
return arr.map((ip) => parseIPNotation(ip)); | ||
} | ||
@@ -52,14 +59,13 @@ function compileTrust(rangeSubnets) { | ||
let ip = parseip(str); | ||
if (pos === -1 && ip.kind() === "ipv6") { | ||
ip = ip; | ||
if (ip.isIPv4MappedAddress()) ip = ip.toIPv4Address(); | ||
const max = ip.kind() === "ipv6" ? 128 : 32; | ||
if (pos === -1) { | ||
if (isIPv6(ip) && ip.isIPv4MappedAddress()) ip = ip.toIPv4Address(); | ||
return { ip, range: max }; | ||
} | ||
const max = ip.kind() === "ipv6" ? 128 : 32; | ||
let range = pos !== -1 ? note.substring(pos + 1, note.length) : null; | ||
if (range === null) range = max; | ||
else if (DIGIT_REGEXP.test(range)) range = Number.parseInt(range, 10); | ||
else if (ip.kind() === "ipv4" && isip(range)) range = parseNetmask(range); | ||
else range = null; | ||
if (typeof range === "number" && (range <= 0 || range > max)) throw new TypeError(`invalid range on address: ${note}`); | ||
return [ip, range]; | ||
const rangeString = note.substring(pos + 1, note.length); | ||
let range = null; | ||
if (DIGIT_REGEXP.test(rangeString)) range = Number.parseInt(rangeString, 10); | ||
else if (ip.kind() === "ipv4" && isip(rangeString)) range = parseNetmask(rangeString); | ||
if (range == null || range <= 0 || range > max) throw new TypeError(`invalid range on address: ${note}`); | ||
return { ip, range }; | ||
} | ||
@@ -78,16 +84,14 @@ function parseNetmask(netmask) { | ||
const ip = parseip(addr); | ||
let ipconv; | ||
let ipconv = null; | ||
const kind = ip.kind(); | ||
for (let i = 0; i < subnets.length; i++) { | ||
const subnet = subnets[i]; | ||
const subnetip = subnet[0]; | ||
const subnetkind = subnetip.kind(); | ||
const subnetrange = subnet[1]; | ||
const subnetKind = subnet.ip.kind(); | ||
let trusted = ip; | ||
if (kind !== subnetkind) { | ||
if (subnetkind === "ipv4" && !ip.isIPv4MappedAddress()) continue; | ||
if (!ipconv) ipconv = subnetkind === "ipv4" ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); | ||
if (kind !== subnetKind) { | ||
if (isIPv6(ip) && !ip.isIPv4MappedAddress()) continue; | ||
if (!ipconv) ipconv = isIPv4(ip) ? ip.toIPv4MappedAddress() : ip.toIPv4Address(); | ||
trusted = ipconv; | ||
} | ||
if (trusted.match(subnetip, subnetrange)) return true; | ||
if (trusted.match(subnet.ip, subnet.range)) return true; | ||
} | ||
@@ -98,6 +102,4 @@ return false; | ||
function trustSingle(subnet) { | ||
const subnetip = subnet[0]; | ||
const subnetkind = subnetip.kind(); | ||
const subnetisipv4 = subnetkind === "ipv4"; | ||
const subnetrange = subnet[1]; | ||
const subnetKind = subnet.ip.kind(); | ||
const subnetIsIPv4 = subnetKind === "ipv4"; | ||
return function trust(addr) { | ||
@@ -107,7 +109,7 @@ if (!isip(addr)) return false; | ||
const kind = ip.kind(); | ||
if (kind !== subnetkind) { | ||
if (subnetisipv4 && !ip.isIPv4MappedAddress()) return false; | ||
ip = subnetisipv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); | ||
if (kind !== subnetKind) { | ||
if (subnetIsIPv4 && !ip.isIPv4MappedAddress()) return false; | ||
ip = subnetIsIPv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); | ||
} | ||
return ip.match(subnetip, subnetrange); | ||
return ip.match(subnet.ip, subnet.range); | ||
}; | ||
@@ -114,0 +116,0 @@ } |
{ | ||
"name": "@tinyhttp/proxy-addr", | ||
"version": "2.1.4", | ||
"version": "2.2.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "description": "proxy-addr rewrite with TypeScript and ESM support", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17529
161