import { beforeEach, describe, expect, it, mock } from "bun:test"; // The trust boundary of FRE-366: x-forwarded-for is client-controlled text, // believed only when the direct peer is the loopback production proxy. These // tests pin that boundary — a regression here either re-records the proxy as // the visitor (unique visitors collapses to one host) or lets any client // spoof its address. let directIp: string | null = null; mock.module("vinxi/http", () => ({ getRequestIP: () => directIp })); const { resolveClientIp, isLoopbackAddress, requestHost } = await import( "./request-client" ); function event( headers: Record = {}, url = "https://nook.freno.me/downloads" ) { return { request: new Request(url, { headers }), nativeEvent: {} } as never; } beforeEach(() => { directIp = null; }); describe("resolveClientIp", () => { it("takes the first forwarded hop when the direct peer is the loopback proxy", () => { directIp = "127.0.0.1"; expect( resolveClientIp(event({ "x-forwarded-for": "198.51.100.9, 10.0.0.1" })) ).toBe("198.51.100.9"); directIp = "::1"; expect( resolveClientIp(event({ "x-forwarded-for": "198.51.100.10" })) ).toBe("198.51.100.10"); }); it("ignores a forwarded header from a real peer — it is spoofable", () => { directIp = "203.0.113.7"; expect( resolveClientIp(event({ "x-forwarded-for": "198.51.100.9" })) ).toBe("203.0.113.7"); }); it("keeps the loopback peer when the proxy set no forwarded header", () => { directIp = "::ffff:127.0.0.1"; expect(resolveClientIp(event())).toBe("::ffff:127.0.0.1"); }); it("records nothing rather than inventing an address", () => { expect(resolveClientIp(event())).toBeNull(); }); }); describe("isLoopbackAddress", () => { it("covers the v4 range, the shorthand and the v6 forms", () => { expect(isLoopbackAddress("127.0.0.1")).toBe(true); expect(isLoopbackAddress("127.0.0.53")).toBe(true); expect(isLoopbackAddress("::1")).toBe(true); expect(isLoopbackAddress("::ffff:127.0.0.1")).toBe(true); expect(isLoopbackAddress("203.0.113.7")).toBe(false); expect(isLoopbackAddress("10.0.0.1")).toBe(false); }); }); describe("requestHost", () => { it("reads the host the client addressed from the request URL", () => { expect(requestHost(event())).toBe("nook.freno.me"); expect(requestHost(event({}, "https://freno.me/"))).toBe("freno.me"); }); });