feat(frontend): support embedded API prefixes
This commit is contained in:
@@ -15,6 +15,10 @@ describe("resolveBackendUrl", () => {
|
|||||||
expect(backendBaseUrl).toBe("/api");
|
expect(backendBaseUrl).toBe("/api");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts a same-origin prefixed API base for embedded deployments", () => {
|
||||||
|
expect(resolveBackendUrl({ backendBaseUrl: "/embedded/api" })).toBe("/embedded/api");
|
||||||
|
});
|
||||||
|
|
||||||
it.each(["/backend", "api", "//evil.test", "ftp://example.test", "https://user:pass@example.test"])(
|
it.each(["/backend", "api", "//evil.test", "ftp://example.test", "https://user:pass@example.test"])(
|
||||||
"rejects any browser-facing backend URL %j",
|
"rejects any browser-facing backend URL %j",
|
||||||
(backendBaseUrl) => {
|
(backendBaseUrl) => {
|
||||||
|
|||||||
@@ -1,6 +1,18 @@
|
|||||||
export function resolveBackendUrl(value?: string): string {
|
export interface RuntimeConfig {
|
||||||
if (value === undefined || value === "/api") return "/api";
|
backendBaseUrl?: string;
|
||||||
throw new Error("Invalid backend URL: the browser must use the same-origin /api route");
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
__THOTHII_CONFIG__?: RuntimeConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveBackendUrl(value?: string | RuntimeConfig): string {
|
||||||
|
const candidate = typeof value === "string" ? value : value?.backendBaseUrl;
|
||||||
|
if (candidate === undefined || candidate === "/api") return "/api";
|
||||||
|
if (/^\/(?:[A-Za-z0-9._~-]+\/)+api$/.test(candidate)) return candidate;
|
||||||
|
throw new Error("Invalid backend URL: the browser must use a same-origin API route");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function joinBackendPath(base: string, path: string): string {
|
export function joinBackendPath(base: string, path: string): string {
|
||||||
@@ -9,4 +21,6 @@ export function joinBackendPath(base: string, path: string): string {
|
|||||||
return `${normalizedBase}/${normalizedPath}`;
|
return `${normalizedBase}/${normalizedPath}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const backendBaseUrl = resolveBackendUrl();
|
export const backendBaseUrl = resolveBackendUrl(
|
||||||
|
typeof window === "undefined" ? undefined : window.__THOTHII_CONFIG__,
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user