mirror of https://github.com/openclaw/openclaw.git
test: simplify trusted proxy coverage
This commit is contained in:
parent
87c447ed46
commit
118abfbdb7
|
|
@ -49,117 +49,147 @@ describe("isLocalishHost", () => {
|
|||
});
|
||||
|
||||
describe("isTrustedProxyAddress", () => {
|
||||
describe("exact IP matching", () => {
|
||||
it("returns true when IP matches exactly", () => {
|
||||
expect(isTrustedProxyAddress("192.168.1.1", ["192.168.1.1"])).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when IP does not match", () => {
|
||||
expect(isTrustedProxyAddress("192.168.1.2", ["192.168.1.1"])).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when IP matches one of multiple proxies", () => {
|
||||
expect(isTrustedProxyAddress("10.0.0.5", ["192.168.1.1", "10.0.0.5", "172.16.0.1"])).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("ignores surrounding whitespace in exact IP entries", () => {
|
||||
expect(isTrustedProxyAddress("10.0.0.5", [" 10.0.0.5 "])).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("CIDR subnet matching", () => {
|
||||
it("returns true when IP is within /24 subnet", () => {
|
||||
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.0/24"])).toBe(true);
|
||||
expect(isTrustedProxyAddress("10.42.0.1", ["10.42.0.0/24"])).toBe(true);
|
||||
expect(isTrustedProxyAddress("10.42.0.254", ["10.42.0.0/24"])).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when IP is outside /24 subnet", () => {
|
||||
expect(isTrustedProxyAddress("10.42.1.1", ["10.42.0.0/24"])).toBe(false);
|
||||
expect(isTrustedProxyAddress("10.43.0.1", ["10.42.0.0/24"])).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when IP is within /16 subnet", () => {
|
||||
expect(isTrustedProxyAddress("172.19.5.100", ["172.19.0.0/16"])).toBe(true);
|
||||
expect(isTrustedProxyAddress("172.19.255.255", ["172.19.0.0/16"])).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when IP is outside /16 subnet", () => {
|
||||
expect(isTrustedProxyAddress("172.20.0.1", ["172.19.0.0/16"])).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when IP is within /32 subnet (single IP)", () => {
|
||||
expect(isTrustedProxyAddress("10.42.0.0", ["10.42.0.0/32"])).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when IP does not match /32 subnet", () => {
|
||||
expect(isTrustedProxyAddress("10.42.0.1", ["10.42.0.0/32"])).toBe(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"];
|
||||
expect(isTrustedProxyAddress("192.168.1.1", proxies)).toBe(true); // exact match
|
||||
expect(isTrustedProxyAddress("10.42.0.59", proxies)).toBe(true); // CIDR match
|
||||
expect(isTrustedProxyAddress("172.19.5.100", proxies)).toBe(true); // CIDR match
|
||||
expect(isTrustedProxyAddress("10.43.0.1", proxies)).toBe(false); // no match
|
||||
});
|
||||
|
||||
it("supports IPv6 CIDR notation", () => {
|
||||
expect(isTrustedProxyAddress("2001:db8::1234", ["2001:db8::/32"])).toBe(true);
|
||||
expect(isTrustedProxyAddress("2001:db9::1234", ["2001:db8::/32"])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("backward compatibility", () => {
|
||||
it("preserves exact IP matching behavior (no CIDR notation)", () => {
|
||||
// Old configs with exact IPs should work exactly as before
|
||||
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);
|
||||
});
|
||||
|
||||
it("does NOT treat plain IPs as /32 CIDR (exact match only)", () => {
|
||||
// "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);
|
||||
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.1"])).toBe(false);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
describe("edge cases", () => {
|
||||
it("returns false when IP is undefined", () => {
|
||||
expect(isTrustedProxyAddress(undefined, ["192.168.1.1"])).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when trustedProxies is undefined", () => {
|
||||
expect(isTrustedProxyAddress("192.168.1.1", undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when trustedProxies is empty", () => {
|
||||
expect(isTrustedProxyAddress("192.168.1.1", [])).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false for invalid CIDR notation", () => {
|
||||
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.0/33"])).toBe(false); // invalid prefix
|
||||
expect(isTrustedProxyAddress("10.42.0.59", ["10.42.0.0/-1"])).toBe(false); // negative prefix
|
||||
expect(isTrustedProxyAddress("10.42.0.59", ["invalid/24"])).toBe(false); // invalid IP
|
||||
});
|
||||
|
||||
it("ignores surrounding whitespace in CIDR entries", () => {
|
||||
expect(isTrustedProxyAddress("10.42.0.59", [" 10.42.0.0/24 "])).toBe(true);
|
||||
});
|
||||
|
||||
it("ignores blank trusted proxy entries", () => {
|
||||
expect(isTrustedProxyAddress("10.0.0.5", [" ", "\t"])).toBe(false);
|
||||
expect(isTrustedProxyAddress("10.0.0.5", [" ", "10.0.0.5", ""])).toBe(true);
|
||||
});
|
||||
it.each([
|
||||
{
|
||||
name: "matches exact IP entries",
|
||||
ip: "192.168.1.1",
|
||||
trustedProxies: ["192.168.1.1"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "rejects non-matching exact IP entries",
|
||||
ip: "192.168.1.2",
|
||||
trustedProxies: ["192.168.1.1"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "matches one of multiple exact entries",
|
||||
ip: "10.0.0.5",
|
||||
trustedProxies: ["192.168.1.1", "10.0.0.5", "172.16.0.1"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "ignores surrounding whitespace in exact IP entries",
|
||||
ip: "10.0.0.5",
|
||||
trustedProxies: [" 10.0.0.5 "],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "matches /24 CIDR entries",
|
||||
ip: "10.42.0.59",
|
||||
trustedProxies: ["10.42.0.0/24"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "rejects IPs outside /24 CIDR entries",
|
||||
ip: "10.42.1.1",
|
||||
trustedProxies: ["10.42.0.0/24"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "matches /16 CIDR entries",
|
||||
ip: "172.19.255.255",
|
||||
trustedProxies: ["172.19.0.0/16"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "rejects IPs outside /16 CIDR entries",
|
||||
ip: "172.20.0.1",
|
||||
trustedProxies: ["172.19.0.0/16"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "treats /32 as a single-IP CIDR",
|
||||
ip: "10.42.0.0",
|
||||
trustedProxies: ["10.42.0.0/32"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "rejects non-matching /32 CIDR entries",
|
||||
ip: "10.42.0.1",
|
||||
trustedProxies: ["10.42.0.0/32"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "handles mixed exact IP and CIDR entries",
|
||||
ip: "172.19.5.100",
|
||||
trustedProxies: ["192.168.1.1", "10.42.0.0/24", "172.19.0.0/16"],
|
||||
expected: 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"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "supports IPv6 CIDR notation",
|
||||
ip: "2001:db8::1234",
|
||||
trustedProxies: ["2001:db8::/32"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "rejects IPv6 addresses outside the configured CIDR",
|
||||
ip: "2001:db9::1234",
|
||||
trustedProxies: ["2001:db8::/32"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "preserves exact matching behavior for plain IP entries",
|
||||
ip: "10.42.0.59",
|
||||
trustedProxies: ["10.42.0.1"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "normalizes IPv4-mapped IPv6 addresses",
|
||||
ip: "::ffff:192.168.1.1",
|
||||
trustedProxies: ["192.168.1.1"],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "returns false when IP is undefined",
|
||||
ip: undefined,
|
||||
trustedProxies: ["192.168.1.1"],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "returns false when trusted proxies are undefined",
|
||||
ip: "192.168.1.1",
|
||||
trustedProxies: undefined,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue