fix(deploy): close container final review

This commit is contained in:
2026-07-12 00:44:39 +02:00
parent 0ca6346f75
commit a3a266fd81
30 changed files with 526 additions and 37 deletions
+14
View File
@@ -14,6 +14,20 @@ describe("resolveBackendUrl", () => {
it("preserves the client default when Vite has no configured backend", () => {
expect(backendBaseUrl).toBe(import.meta.env.VITE_BACKEND_URL ?? "http://localhost:8787");
});
it.each(["/backend", "api", "//evil.test", "ftp://example.test", "https://user:pass@example.test"])(
"rejects unsupported backend URL %j",
(backendBaseUrl) => {
expect(() => resolveBackendUrl({ backendBaseUrl })).toThrow(/BACKEND_BASE_URL/);
},
);
it.each(["", "/", "/api", "/api/", "http://localhost:8787", "https://api.example.test/v1"])(
"accepts supported backend URL %j",
(backendBaseUrl) => {
expect(resolveBackendUrl({ backendBaseUrl })).toBe(backendBaseUrl);
},
);
});
describe("joinBackendPath", () => {
+13 -1
View File
@@ -9,7 +9,19 @@ declare global {
}
export function resolveBackendUrl(config: RuntimeConfig | undefined): string {
return config?.backendBaseUrl ?? import.meta.env.VITE_BACKEND_URL ?? "";
const value = config?.backendBaseUrl ?? import.meta.env.VITE_BACKEND_URL ?? "";
if (value === "" || value === "/" || value === "/api" || value === "/api/") return value;
try {
const url = new URL(value);
if ((url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password) {
return value;
}
} catch {
// Fall through to the single actionable runtime error below.
}
throw new Error(
"Invalid BACKEND_BASE_URL: use empty/root, /api, or an absolute http(s) URL without credentials",
);
}
export function joinBackendPath(base: string, path: string): string {