import assert from "node:assert/strict"; import test from "node:test"; // @ts-expect-error Node's native TypeScript runner resolves explicit .ts imports. import { isSameOriginRequest } from "../lib/request-origin.ts"; function request(headers: Record, url = "http://localhost:3000/api/workspace"): Request { return new Request(url, { method: "POST", headers }); } test("127.0.0.1 page may save when Next normalizes request.url to localhost", () => { assert.equal(isSameOriginRequest(request({ Host: "127.0.0.1:3000", Origin: "http://127.0.0.1:3000", "Sec-Fetch-Site": "same-origin", })), true); }); test("localhost and IPv6 same-origin hosts may save", () => { for (const host of ["localhost:3000", "[::1]:3000"]) { assert.equal(isSameOriginRequest(request({ Host: host, Origin: `http://${host}` })), true); } }); test("evil origin and cross-site fetches remain forbidden", () => { assert.equal(isSameOriginRequest(request({ Host: "127.0.0.1:3000", Origin: "https://evil.example" })), false); assert.equal(isSameOriginRequest(request({ Host: "127.0.0.1:3000", Origin: "http://127.0.0.1:3000", "Sec-Fetch-Site": "cross-site", })), false); }); test("forwarded-host cannot override the actual Host header", () => { assert.equal(isSameOriginRequest(request({ Host: "localhost:3000", Origin: "https://evil.example", "X-Forwarded-Host": "evil.example", })), false); }); test("port/protocol mismatches and malformed origins are forbidden", () => { for (const origin of ["http://localhost:3001", "https://localhost:3000", "null", "broken", "http://localhost:3000/path"]) { assert.equal(isSameOriginRequest(request({ Host: "localhost:3000", Origin: origin })), false); } }); test("non-browser clients without Origin remain supported, and URL is a Host fallback", () => { assert.equal(isSameOriginRequest(request({})), true); assert.equal(isSameOriginRequest(request({ Origin: "http://localhost:3000" })), true); assert.equal(isSameOriginRequest(request({ "Sec-Fetch-Site": "cross-site" })), false); });