From d69c00eab02594784fdd103d42d926e459aad912 Mon Sep 17 00:00:00 2001 From: Riyadh Date: Wed, 20 May 2026 07:06:16 +0000 Subject: [PATCH] Make file uploads work on any device or network Update the file upload URL generation to use same-origin paths, ensuring compatibility across different network environments and devices by allowing the browser to automatically resolve the correct origin. --- artifacts/api-server/src/lib/objectStorage.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/artifacts/api-server/src/lib/objectStorage.ts b/artifacts/api-server/src/lib/objectStorage.ts index fb627ba9..61fc9807 100644 --- a/artifacts/api-server/src/lib/objectStorage.ts +++ b/artifacts/api-server/src/lib/objectStorage.ts @@ -160,13 +160,21 @@ class LocalDriver implements StorageDriver { ).toString("base64url"); const sig = createHmac("sha256", LOCAL_HMAC_SECRET).update(payload).digest("base64url"); const token = `${payload}.${sig}`; - const base = (process.env.PUBLIC_BASE_URL ?? `http://localhost:${process.env.PORT ?? "8080"}`).replace(/\/+$/, ""); - return `${base}/api/storage/_local/upload?token=${token}`; + // Return a SAME-ORIGIN path (not an absolute URL). The browser will + // resolve it against `window.location.origin`, so the upload always + // targets the public host the SPA is being served from — works for + // localhost, Tailscale (tx.local), LAN IPs, and remote phones alike + // without depending on PUBLIC_BASE_URL being set correctly. + return `/api/storage/_local/upload?token=${token}`; } parseUploadUrl(rawUrl: string): { bucketName: string; objectName: string } | null { try { - const u = new URL(rawUrl); + // Accept BOTH legacy absolute URLs (older signed URLs still in the + // wild) and the new same-origin paths. URL() needs a base for the + // relative form — the base is irrelevant since we only read + // pathname/searchParams. + const u = new URL(rawUrl, "http://placeholder.local"); if (!u.pathname.endsWith("/api/storage/_local/upload")) return null; const token = u.searchParams.get("token"); if (!token) return null;