From 79905345e55eddeca4514ff4049f9e289a6eb85c Mon Sep 17 00:00:00 2001 From: SepehrYahyaee <7heycallmegray@gmail.com> Date: Sat, 13 Jun 2026 17:43:00 +0330 Subject: [PATCH] Fix car-damage links --- src/helpers/urlCreator.ts | 58 +++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/helpers/urlCreator.ts b/src/helpers/urlCreator.ts index 5d00ae7..a1cf24b 100644 --- a/src/helpers/urlCreator.ts +++ b/src/helpers/urlCreator.ts @@ -4,35 +4,59 @@ type StoredFileCapture = { }; /** - * Build a public file URL from a relative storage path (e.g. `files/...`). - * Uses the current `URL` env so deployments with custom routing stay correct. + * Reduce any stored file reference to the canonical relative storage path + * (e.g. `files/claim-captures/x.jpg`). + * + * Handles values that were persisted as absolute URLs on a different portal + * (e.g. `https://host/car-damage/user/api/files/...`) so we never leak a + * baked-in host/prefix into responses served from another origin. + */ +function toRelativeFilePath(value: string | null | undefined): string { + const s = String(value ?? "").trim(); + if (!s) return ""; + + // Prefer the `files/...` segment wherever it appears in the string. + const match = s.match(/(?:^|\/)(files\/.+)$/i); + if (match) return match[1]; + + // No recognizable file root: keep external URLs intact, otherwise strip + // any leading slashes so we can safely prefix the base URL. + if (/^https?:\/\//i.test(s)) return s; + return s.replace(/^\/+/, ""); +} + +/** + * Build a public file URL from a stored path (relative or absolute). + * + * The link is always rebuilt from the current `URL` env, so deployments with + * custom routing (different sub-paths per portal) stay correct even when the + * persisted value was created elsewhere. */ export function buildFileLink(path: string): string { - const normalized = String(path ?? "").trim(); - if (!normalized) return normalized; - if (/^https?:\/\//i.test(normalized)) { - return normalized; - } + const relative = toRelativeFilePath(path); + if (!relative) return ""; + + // Already an absolute external URL with no recognizable file root. + if (/^https?:\/\//i.test(relative)) return relative; const baseUrl = (process.env.URL ?? "").replace(/\/+$/, ""); - const relativePath = normalized.replace(/^\/+/, ""); if (process.env.NODE_ENV === "local") { - return `${baseUrl}/${relativePath}`; + return `${baseUrl}/${relative}`; } - return `${baseUrl}/api/${relativePath}`; + return `${baseUrl}/api/${relative}`; } /** * Resolve a file URL from persisted capture metadata. - * Prefer rebuilding from `path` so stale baked-in URLs (e.g. user-portal prefix) - * do not leak into expert/other API responses. + * + * Prefer `path`, fall back to `url`, and always rebuild through + * {@link buildFileLink} so stale portal-prefixed values (e.g. `.../user/api/...`) + * are normalized to the current server origin. */ export function resolveStoredFileUrl( stored?: StoredFileCapture | null, ): string | undefined { - const path = stored?.path?.trim(); - if (path) { - return buildFileLink(path); - } - return stored?.url; + const source = stored?.path?.trim() || stored?.url?.trim(); + if (!source) return undefined; + return buildFileLink(source); }