Skip to content
Source
Sign inSign up

browserTargetResolver.test.ts

195 lines6.1 KB

1import { EnvironmentId } from "@t3tools/contracts";
2import { isPrivateNetworkHost, isPublicFaviconHost } from "@t3tools/shared/hostClassification";
3import { beforeEach, describe, expect, it, vi } from "vite-plus/test";
4​
5const readPreparedConnection = vi.fn();
6const env = vi.hoisted(() => ({ isElectron: false }));
7​
8vi.mock("~/state/session", () => ({ readPreparedConnection }));
9vi.mock("~/env", () => env);
10​
11describe("browser target resolver", () => {
12 beforeEach(() => readPreparedConnection.mockReset());
13​
14 it("refuses public relay hosts until the authenticated gateway exists", async () => {
15 readPreparedConnection.mockReturnValue({ httpBaseUrl: "https://relay.example.com" });
16 const { resolveDiscoveredServerUrl } = await import("./browserTargetResolver");
17 expect(
18 resolveDiscoveredServerUrl(EnvironmentId.make("environment-1"), "http://localhost:5173"),
19 ).toBe("http://localhost:5173");
20 });
21​
22 it("normalizes schemeless localhost server-picker values", async () => {
23 readPreparedConnection.mockReturnValue({ httpBaseUrl: "http://localhost:3773" });
24 const { resolveDiscoveredServerUrl } = await import("./browserTargetResolver");
25 expect(resolveDiscoveredServerUrl(EnvironmentId.make("environment-1"), "localhost:5173")).toBe(
26 "http://localhost:5173/",
27 );
28 expect(
29 resolveDiscoveredServerUrl(EnvironmentId.make("environment-1"), "0.0.0.0:3000/app"),
30 ).toBe("http://localhost:3000/app");
31 });
32​
33 it("maps discovered loopback servers onto a remote environment host", async () => {
34 readPreparedConnection.mockReturnValue({ httpBaseUrl: "http://192.168.1.25:3773" });
35 const { resolveDiscoveredServerUrl } = await import("./browserTargetResolver");
36 expect(
37 resolveDiscoveredServerUrl(EnvironmentId.make("environment-1"), "localhost:3000/app"),
38 ).toBe("http://192.168.1.25:3000/app");
39 });
40​
41 it("keeps localhost for servers on the desktop's own WSL or primary backend", async () => {
42 // WSL NAT advertises a distro IP, but loopback-bound servers only answer on localhost.
43 const { resolveDiscoveredServerUrl } = await import("./browserTargetResolver");
44 env.isElectron = true;
45 try {
46 for (const target of [
47 { _tag: "BearerConnectionTarget", connectionId: "local:wsl:Ubuntu" },
48 { _tag: "PrimaryConnectionTarget" },
49 ]) {
50 readPreparedConnection.mockReturnValue({ httpBaseUrl: "http://172.24.66.27:3773", target });
51 expect(
52 resolveDiscoveredServerUrl(EnvironmentId.make("environment-1"), "localhost:3001/"),
53 ).toBe("http://localhost:3001/");
54 }
55 readPreparedConnection.mockReturnValue({
56 httpBaseUrl: "http://192.168.1.25:3773",
57 target: { _tag: "BearerConnectionTarget", connectionId: "saved:remote" },
58 });
59 expect(
60 resolveDiscoveredServerUrl(EnvironmentId.make("environment-1"), "localhost:3001/"),
61 ).toBe("http://192.168.1.25:3001/");
62 } finally {
63 env.isElectron = false;
64 }
65 });
66​
67 it("classifies exact private IPv4 and IPv6 boundaries", async () => {
68 const privateHosts = [
69 "0.0.0.0",
70 "10.0.0.0",
71 "10.255.255.255",
72 "100.64.0.0",
73 "100.127.255.255",
74 "127.0.0.0",
75 "127.255.255.255",
76 "169.254.0.0",
77 "169.254.255.255",
78 "172.16.0.0",
79 "172.31.255.255",
80 "192.168.0.0",
81 "192.168.255.255",
82 "198.18.0.0",
83 "198.19.255.255",
84 "fc00::",
85 "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
86 "fe80::",
87 "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
88 "::ffff:192.168.1.1",
89 "localhost.",
90 "localhost..",
91 "devbox.",
92 "devbox..",
93 "printer.local.",
94 "printer.local..",
95 "printer.home.arpa.",
96 "printer.home.arpa..",
97 "devbox.example.ts.net.",
98 "devbox.example.ts.net..",
99 ];
100 const publicHosts = [
101 "1.0.0.0",
102 "100.63.255.255",
103 "100.128.0.0",
104 "169.253.255.255",
105 "169.255.0.0",
106 "172.15.255.255",
107 "172.32.0.0",
108 "192.167.255.255",
109 "192.169.0.0",
110 "198.17.255.255",
111 "198.20.0.0",
112 "fbff:ffff::",
113 "fec0::",
114 "2001:4860:4860::8888",
115 "::ffff:8.8.8.8",
116 "example.com.",
117 ];
118 expect(privateHosts.filter((host) => !isPrivateNetworkHost(host))).toEqual([]);
119 expect(publicHosts.filter(isPrivateNetworkHost)).toEqual([]);
120 });
121​
122 it("allows only globally routable hosts to reach a public favicon provider", async () => {
123 const nonPublic = [
124 "192.0.0.0",
125 "192.0.0.255",
126 "192.0.2.0",
127 "192.0.2.255",
128 "192.88.99.0",
129 "192.88.99.255",
130 "198.51.100.0",
131 "198.51.100.255",
132 "203.0.113.0",
133 "203.0.113.255",
134 "224.0.0.0",
135 "255.255.255.255",
136 "::2",
137 "100::",
138 "100::ffff:ffff:ffff:ffff",
139 "100:0:0:1::",
140 "100:0:0:1:ffff:ffff:ffff:ffff",
141 "64:ff9b:1::1",
142 "64:ff9b::a00:1",
143 "64:ff9b::7f00:1",
144 "64:ff9b::c0a8:101",
145 "64:ff9b::c000:201",
146 "2001:5::1",
147 "2001:2::",
148 "2001:2:0:ffff:ffff:ffff:ffff:ffff",
149 "2001:db8::",
150 "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff",
151 "3fff::",
152 "3fff:fff:ffff:ffff:ffff:ffff:ffff:ffff",
153 "5f00::1",
154 "fec0::",
155 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
156 "::ffff:192.0.2.1",
157 "app.test",
158 "app.test..",
159 "printer.local..",
160 "printer.home.arpa..",
161 "devbox.example.ts.net..",
162 "127.0.0.1..",
163 "127.1..",
164 "10.1..",
165 "172.16.1..",
166 "192.168.1..",
167 "service.internal",
168 "hidden.onion",
169 ];
170 const publicHosts = [
171 "191.255.255.255",
172 "192.0.1.255",
173 "192.0.3.0",
174 "198.51.99.255",
175 "198.51.101.0",
176 "203.0.112.255",
177 "203.0.114.0",
178 "223.255.255.255",
179 "1.1.1.1",
180 "2001:4860:4860::8888",
181 "2606:4700:4700::1111",
182 "64:ff9b::808:808",
183 "2001:1::1",
184 "2001:3::1",
185 "2001:4:112::1",
186 "2001:20::1",
187 "2001:30::1",
188 "::ffff:8.8.8.8",
189 "example.com",
190 "example.com.",
191 ];
192 expect(nonPublic.filter(isPublicFaviconHost)).toEqual([]);
193 expect(publicHosts.filter((host) => !isPublicFaviconHost(host))).toEqual([]);
194 });
195});