/** * Same-origin proxy for Supabase Storage signed URLs. * * Agent sandboxes (Claude Desktop's code execution, some MCP clients) only * allow network egress to the host the MCP server lives on. Our signed * Storage URLs point at .supabase.co, so a model-free upload or a * document download from such a sandbox was refused before it left the box * (user report 2026-08-21). These helpers rewrite a signed URL onto this * app's own origin (`/api/storage/...`) and resolve it back to the upstream * Storage URL inside the proxy route. * * The signed token travels unchanged and is the only credential on both * sides: the proxy grants nothing the public Storage host did not already * grant, and it refuses every path that is not a signed object path on the * documents bucket. Without NEXT_PUBLIC_APP_URL (a self-host that never set * it) the rewrite is a no-op rather than a broken localhost link. */ export const STORAGE_PROXY_ROUTE = '/api/storage' /** * Content types a browser renders natively without a script context: PDF * and the raster image formats the document archive accepts. These are the * only types either document-serving route (the inline preview proxy and the * signed-URL proxy below) hands to the browser as-is. Everything else that * can reach the archive (text/html mail bodies, application/xhtml+xml * iXBRL, Peppol application/xml and text/xml, image/svg+xml, application/json, * unknown or legacy types) is active content when it lands on our origin: * an uploader-controlled