From 5116586d79df7216b124e74715f6414ffffa7e3a Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Tue, 13 May 2025 22:19:24 -0400 Subject: improve YAML syntax for defining allowed IPs --- packages/backend/src/config.ts | 50 ++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 2a3184f9b4..9725bcc367 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -84,7 +84,7 @@ type Source = { proxySmtp?: string; proxyBypassHosts?: string[]; - allowedPrivateNetworks?: string[]; + allowedPrivateNetworks?: PrivateNetworkSource[]; disallowExternalApRedirect?: boolean; maxFileSize?: number; @@ -154,11 +154,13 @@ type Source = { } }; +export type PrivateNetworkSource = string | { ip?: string, ports?: number[] }; + export type PrivateNetwork = { /** * CIDR IP/netmask definition of the IP range to match. */ - cidr: [ip: IPv4 | IPv6, mask: number]; + cidr: CIDR; /** * List of ports to match. @@ -168,17 +170,41 @@ export type PrivateNetwork = { ports?: number[]; }; -export function parsePrivateNetworks(patterns: string[]): PrivateNetwork[]; +export type CIDR = [ip: IPv4 | IPv6, mask: number]; + +export function parsePrivateNetworks(patterns: PrivateNetworkSource[]): PrivateNetwork[]; export function parsePrivateNetworks(patterns: undefined): undefined; -export function parsePrivateNetworks(patterns: string[] | undefined): PrivateNetwork[] | undefined; -export function parsePrivateNetworks(patterns: string[] | undefined): PrivateNetwork[] | undefined { - return patterns?.map(e => { - const [ip, ports] = e.split('#') as [string, ...(string | undefined)[]]; - return { - cidr: ipaddr.parseCIDR(ip), - ports: ports?.split(',').map(p => parseInt(p)), - }; - }); +export function parsePrivateNetworks(patterns: PrivateNetworkSource[] | undefined): PrivateNetwork[] | undefined; +export function parsePrivateNetworks(patterns: PrivateNetworkSource[] | undefined): PrivateNetwork[] | undefined { + if (!patterns) return undefined; + return patterns + .map(e => { + if (typeof(e) === 'string') { + const cidr = parseIpOrMask(e); + if (cidr) { + return { cidr } satisfies PrivateNetwork; + } + } else if (e.ip) { + const cidr = parseIpOrMask(e.ip); + if (cidr) { + return { cidr, ports: e.ports } satisfies PrivateNetwork; + } + } + + console.warn('[config] Skipping invalid entry in allowedPrivateNetworks: ', e); + return null; + }) + .filter(p => p != null); +} + +function parseIpOrMask(ipOrMask: string): CIDR | null { + if (ipaddr.isValidCIDR(ipOrMask)) { + return ipaddr.parseCIDR(ipOrMask); + } + if (ipaddr.isValid(ipOrMask)) { + return ipaddr.parseCIDR(ipOrMask); + } + return null; } export type Config = { -- cgit v1.2.3-freya