test: simplify trusted proxy coverage

This commit is contained in:
Peter Steinberger 2026-03-13 17:52:49 +00:00
parent 87c447ed46
commit 118abfbdb7
1 changed files with 141 additions and 111 deletions

View File

@ -49,117 +49,147 @@ describe("isLocalishHost", () => {
}); });
describe("isTrustedProxyAddress", () => { describe("isTrustedProxyAddress", () => {
describe("exact IP matching", () => { it.each([
it("returns true when IP matches exactly", () => { {
expect(isTrustedProxyAddress("192.168.1.1", ["192.168.1.1"])).toBe(true); name: "matches exact IP entries",
}); ip: "192.168.1.1",
trustedProxies: ["192.168.1.1"],
it("returns false when IP does not match", () => { expected: true,
expect(isTrustedProxyAddress("192.168.1.2", ["192.168.1.1"])).toBe(false); },
}); {
name: "rejects non-matching exact IP entries",
it("returns true when IP matches one of multiple proxies", () => { ip: "192.168.1.2",
expect(isTrustedProxyAddress("10.0.0.5", ["192.168.1.1", "10.0.0.5", "172.16.0.1"])).toBe( trustedProxies: ["192.168.1.1"],
true, expected: false,
); },
}); {
name: "matches one of multiple exact entries",
it("ignores surrounding whitespace in exact IP entries", () => { ip: "10.0.0.5",
expect(isTrustedProxyAddress("10.0.0.5", [" 10.0.0.5 "])).toBe(true); trustedProxies: ["192.168.1.1", "10.0.0.5", "172.16.0.1"],
}); expected: true,
}); },
{
describe("CIDR subnet matching", () => { name: "ignores surrounding whitespace in exact IP entries",
it("returns true when IP is within /24 subnet", () => { ip: "10.0.0.5",
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.0/24"])).toBe(true); trustedProxies: [" 10.0.0.5 "],
expect(isTrustedProxyAddress("10.42.0.1", ["10.42.0.0/24"])).toBe(true); expected: true,
expect(isTrustedProxyAddress("10.42.0.254", ["10.42.0.0/24"])).toBe(true); },
}); {
name: "matches /24 CIDR entries",
it("returns false when IP is outside /24 subnet", () => { ip: "10.42.0.59",
expect(isTrustedProxyAddress("10.42.1.1", ["10.42.0.0/24"])).toBe(false); trustedProxies: ["10.42.0.0/24"],
expect(isTrustedProxyAddress("10.43.0.1", ["10.42.0.0/24"])).toBe(false); expected: true,
}); },
{
it("returns true when IP is within /16 subnet", () => { name: "rejects IPs outside /24 CIDR entries",
expect(isTrustedProxyAddress("172.19.5.100", ["172.19.0.0/16"])).toBe(true); ip: "10.42.1.1",
expect(isTrustedProxyAddress("172.19.255.255", ["172.19.0.0/16"])).toBe(true); trustedProxies: ["10.42.0.0/24"],
}); expected: false,
},
it("returns false when IP is outside /16 subnet", () => { {
expect(isTrustedProxyAddress("172.20.0.1", ["172.19.0.0/16"])).toBe(false); name: "matches /16 CIDR entries",
}); ip: "172.19.255.255",
trustedProxies: ["172.19.0.0/16"],
it("returns true when IP is within /32 subnet (single IP)", () => { expected: true,
expect(isTrustedProxyAddress("10.42.0.0", ["10.42.0.0/32"])).toBe(true); },
}); {
name: "rejects IPs outside /16 CIDR entries",
it("returns false when IP does not match /32 subnet", () => { ip: "172.20.0.1",
expect(isTrustedProxyAddress("10.42.0.1", ["10.42.0.0/32"])).toBe(false); trustedProxies: ["172.19.0.0/16"],
}); expected: false,
},
it("handles mixed exact IPs and CIDR notation", () => { {
const proxies = ["192.168.1.1", "10.42.0.0/24", "172.19.0.0/16"]; name: "treats /32 as a single-IP CIDR",
expect(isTrustedProxyAddress("192.168.1.1", proxies)).toBe(true); // exact match ip: "10.42.0.0",
expect(isTrustedProxyAddress("10.42.0.59", proxies)).toBe(true); // CIDR match trustedProxies: ["10.42.0.0/32"],
expect(isTrustedProxyAddress("172.19.5.100", proxies)).toBe(true); // CIDR match expected: true,
expect(isTrustedProxyAddress("10.43.0.1", proxies)).toBe(false); // no match },
}); {
name: "rejects non-matching /32 CIDR entries",
it("supports IPv6 CIDR notation", () => { ip: "10.42.0.1",
expect(isTrustedProxyAddress("2001:db8::1234", ["2001:db8::/32"])).toBe(true); trustedProxies: ["10.42.0.0/32"],
expect(isTrustedProxyAddress("2001:db9::1234", ["2001:db8::/32"])).toBe(false); expected: false,
}); },
}); {
name: "handles mixed exact IP and CIDR entries",
describe("backward compatibility", () => { ip: "172.19.5.100",
it("preserves exact IP matching behavior (no CIDR notation)", () => { trustedProxies: ["192.168.1.1", "10.42.0.0/24", "172.19.0.0/16"],
// Old configs with exact IPs should work exactly as before expected: true,
expect(isTrustedProxyAddress("192.168.1.1", ["192.168.1.1"])).toBe(true); },
expect(isTrustedProxyAddress("192.168.1.2", ["192.168.1.1"])).toBe(false); {
expect(isTrustedProxyAddress("10.0.0.5", ["192.168.1.1", "10.0.0.5"])).toBe(true); name: "rejects IPs missing from mixed exact IP and CIDR entries",
}); ip: "10.43.0.1",
trustedProxies: ["192.168.1.1", "10.42.0.0/24", "172.19.0.0/16"],
it("does NOT treat plain IPs as /32 CIDR (exact match only)", () => { expected: false,
// "10.42.0.1" without /32 should match ONLY that exact IP },
expect(isTrustedProxyAddress("10.42.0.1", ["10.42.0.1"])).toBe(true); {
expect(isTrustedProxyAddress("10.42.0.2", ["10.42.0.1"])).toBe(false); name: "supports IPv6 CIDR notation",
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.1"])).toBe(false); ip: "2001:db8::1234",
}); trustedProxies: ["2001:db8::/32"],
expected: true,
it("handles IPv4-mapped IPv6 addresses (existing normalizeIp behavior)", () => { },
// Existing normalizeIp() behavior should be preserved {
expect(isTrustedProxyAddress("::ffff:192.168.1.1", ["192.168.1.1"])).toBe(true); name: "rejects IPv6 addresses outside the configured CIDR",
}); ip: "2001:db9::1234",
}); trustedProxies: ["2001:db8::/32"],
expected: false,
describe("edge cases", () => { },
it("returns false when IP is undefined", () => { {
expect(isTrustedProxyAddress(undefined, ["192.168.1.1"])).toBe(false); name: "preserves exact matching behavior for plain IP entries",
}); ip: "10.42.0.59",
trustedProxies: ["10.42.0.1"],
it("returns false when trustedProxies is undefined", () => { expected: false,
expect(isTrustedProxyAddress("192.168.1.1", undefined)).toBe(false); },
}); {
name: "normalizes IPv4-mapped IPv6 addresses",
it("returns false when trustedProxies is empty", () => { ip: "::ffff:192.168.1.1",
expect(isTrustedProxyAddress("192.168.1.1", [])).toBe(false); trustedProxies: ["192.168.1.1"],
}); expected: true,
},
it("returns false for invalid CIDR notation", () => { {
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.0/33"])).toBe(false); // invalid prefix name: "returns false when IP is undefined",
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.0/-1"])).toBe(false); // negative prefix ip: undefined,
expect(isTrustedProxyAddress("10.42.0.59", ["invalid/24"])).toBe(false); // invalid IP trustedProxies: ["192.168.1.1"],
}); expected: false,
},
it("ignores surrounding whitespace in CIDR entries", () => { {
expect(isTrustedProxyAddress("10.42.0.59", [" 10.42.0.0/24 "])).toBe(true); name: "returns false when trusted proxies are undefined",
}); ip: "192.168.1.1",
trustedProxies: undefined,
it("ignores blank trusted proxy entries", () => { expected: false,
expect(isTrustedProxyAddress("10.0.0.5", [" ", "\t"])).toBe(false); },
expect(isTrustedProxyAddress("10.0.0.5", [" ", "10.0.0.5", ""])).toBe(true); {
}); name: "returns false when trusted proxies are empty",
ip: "192.168.1.1",
trustedProxies: [],
expected: false,
},
{
name: "rejects invalid CIDR prefixes and addresses",
ip: "10.42.0.59",
trustedProxies: ["10.42.0.0/33", "10.42.0.0/-1", "invalid/24", "2001:db8::/129"],
expected: false,
},
{
name: "ignores surrounding whitespace in CIDR entries",
ip: "10.42.0.59",
trustedProxies: [" 10.42.0.0/24 "],
expected: true,
},
{
name: "ignores blank trusted proxy entries",
ip: "10.0.0.5",
trustedProxies: [" ", "10.0.0.5", ""],
expected: true,
},
{
name: "treats all-blank trusted proxy entries as no match",
ip: "10.0.0.5",
trustedProxies: [" ", "\t"],
expected: false,
},
])("$name", ({ ip, trustedProxies, expected }) => {
expect(isTrustedProxyAddress(ip, trustedProxies)).toBe(expected);
}); });
}); });