From c68acfd78b2f1d15ceecac9e42bb421bccc4eb8c Mon Sep 17 00:00:00 2001 From: JustMe Date: Fri, 2 Oct 2026 14:12:14 +0800 Subject: [PATCH] fix: allow embedded worker API requests --- server/src/WebDrop.Frontend/EmbeddedFrontend.cs | 4 +++- web/src/core-bridge/worker/http.ts | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/server/src/WebDrop.Frontend/EmbeddedFrontend.cs b/server/src/WebDrop.Frontend/EmbeddedFrontend.cs index badefd8..4c6243b 100644 --- a/server/src/WebDrop.Frontend/EmbeddedFrontend.cs +++ b/server/src/WebDrop.Frontend/EmbeddedFrontend.cs @@ -87,7 +87,9 @@ public static class EmbeddedFrontend ? "public, max-age=31536000, immutable" : "no-store"; - if (path.Equals("index.html", StringComparison.Ordinal)) + // Dedicated workers enforce the CSP returned with their own script response. + // Give bundled JS the same app policy so the crypto worker can call the same-origin API. + if (path.Equals("index.html", StringComparison.Ordinal) || path.EndsWith(".js", StringComparison.OrdinalIgnoreCase)) context.Response.Headers["Content-Security-Policy"] = contentSecurityPolicy; if (!HttpMethods.IsHead(context.Request.Method)) diff --git a/web/src/core-bridge/worker/http.ts b/web/src/core-bridge/worker/http.ts index c04c939..473ed2d 100644 --- a/web/src/core-bridge/worker/http.ts +++ b/web/src/core-bridge/worker/http.ts @@ -1,7 +1,7 @@ import { supportsApiContract } from '../contract'; export type ApiError = Error & { status?: number; code?: string }; -let apiBase = '/api/v1'; +let apiBase = new URL('/api/v1', self.location.origin).toString(); let contractCheck: Promise | undefined; export function setApiBase(value: string): void { @@ -11,7 +11,10 @@ export function setApiBase(value: string): void { } export const fail = (status: number, code: string): ApiError => Object.assign(new Error(code), { status, code }); -export const apiPath = (path: string): string => `${apiBase.replace(/\/$/, '')}${path}`; +export const apiPath = (path: string): string => new URL( + `${apiBase.replace(/\/$/, '')}${path}`, + self.location.origin, +).toString(); function ensureApiContract(): Promise { contractCheck ??= fetch(apiPath('/info'), {