Files

31 lines
1.5 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import { isPublicAddress, resolvePublicHttpsUrl } from "../src/infra/outbound-url.ts";
test("outbound URL validation rejects private, loopback, and reserved addresses", async () => {
assert.equal(isPublicAddress("10.0.0.8"), false);
assert.equal(isPublicAddress("192.168.1.10"), false);
assert.equal(isPublicAddress("127.0.0.1"), false);
assert.equal(isPublicAddress("::1"), false);
assert.equal(isPublicAddress("1.1.1.1"), true);
await assert.rejects(
resolvePublicHttpsUrl("https://provider.example.test/v1", async () => [{ address: "10.0.0.8", family: 4 }]),
/不允许指向本机、私有或保留网络/,
);
});
test("outbound URL validation pins a resolved public address", async () => {
const target = await resolvePublicHttpsUrl("https://provider.example.test/api", async () => [{ address: "1.1.1.1", family: 4 }]);
assert.equal(target.address, "1.1.1.1");
assert.equal(target.family, 4);
assert.equal(target.url.pathname, "/api");
});
test("local provider URLs require an explicit private-network opt-in", async () => {
const resolver = async () => [{ address: "127.0.0.1", family: 4 as const }];
await assert.rejects(resolvePublicHttpsUrl("http://localhost:3100/v1", resolver), /必须是无内嵌凭证的 HTTPS URL/);
const target = await resolvePublicHttpsUrl("http://localhost:3100/v1", resolver, { allowPrivateNetwork: true });
assert.equal(target.address, "127.0.0.1");
assert.equal(target.url.protocol, "http:");
});