


























@@ -0,0 +1,88 @@
1+import { describe, expect, it } from "vitest";
2+import { ensureControlUiAllowedOriginsForNonLoopbackBind } from "./gateway-control-ui-origins.js";
3+4+describe("ensureControlUiAllowedOriginsForNonLoopbackBind", () => {
5+it("seeds Fly-style runtime bind and port when config is empty", () => {
6+const result = ensureControlUiAllowedOriginsForNonLoopbackBind(
7+{ gateway: {} },
8+{
9+runtimeBind: "lan",
10+runtimePort: 3000,
11+isContainerEnvironment: () => false,
12+},
13+);
14+15+expect(result.bind).toBe("lan");
16+expect(result.seededOrigins).toEqual(["http://localhost:3000", "http://127.0.0.1:3000"]);
17+expect(result.config.gateway?.controlUi?.allowedOrigins).toEqual(result.seededOrigins);
18+});
19+20+it("uses runtime bind before config bind to match gateway startup precedence", () => {
21+const result = ensureControlUiAllowedOriginsForNonLoopbackBind(
22+{ gateway: { bind: "loopback" } },
23+{
24+runtimeBind: "lan",
25+isContainerEnvironment: () => false,
26+},
27+);
28+29+expect(result.bind).toBe("lan");
30+expect(result.seededOrigins).not.toBeNull();
31+});
32+33+it("uses runtime loopback before config non-loopback and avoids seeding", () => {
34+const result = ensureControlUiAllowedOriginsForNonLoopbackBind(
35+{ gateway: { bind: "lan" } },
36+{
37+runtimeBind: "loopback",
38+isContainerEnvironment: () => false,
39+},
40+);
41+42+expect(result.bind).toBeNull();
43+expect(result.seededOrigins).toBeNull();
44+});
45+46+it("uses runtime port before config port to match gateway startup precedence", () => {
47+const result = ensureControlUiAllowedOriginsForNonLoopbackBind(
48+{ gateway: { bind: "lan", port: 18789 } },
49+{
50+runtimePort: 3000,
51+isContainerEnvironment: () => false,
52+},
53+);
54+55+expect(result.seededOrigins).toEqual(["http://localhost:3000", "http://127.0.0.1:3000"]);
56+});
57+58+it("keeps container fallback when runtime and config bind are unset", () => {
59+const result = ensureControlUiAllowedOriginsForNonLoopbackBind(
60+{ gateway: {} },
61+{ isContainerEnvironment: () => true },
62+);
63+64+expect(result.bind).toBe("auto");
65+expect(result.seededOrigins).toEqual(["http://localhost:18789", "http://127.0.0.1:18789"]);
66+});
67+68+it("does not overwrite explicit allowed origins", () => {
69+const result = ensureControlUiAllowedOriginsForNonLoopbackBind(
70+{
71+gateway: {
72+controlUi: { allowedOrigins: ["https://control.example.com"] },
73+},
74+},
75+{
76+runtimeBind: "lan",
77+runtimePort: 3000,
78+isContainerEnvironment: () => false,
79+},
80+);
81+82+expect(result.bind).toBe("lan");
83+expect(result.seededOrigins).toBeNull();
84+expect(result.config.gateway?.controlUi?.allowedOrigins).toEqual([
85+"https://control.example.com",
86+]);
87+});
88+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。