Document display route proxies bytes instead of redirecting to Case Vault

kveton fixed a production "Failed to load document" error by replacing a 302 redirect to a Case Vault presigned URL with a backend byte proxy. The single-document display endpoint now downloads the file server-side and streams it to the browser with the correct content-type and `private, no-store` cache headers.

securityinfrastructure

The broken state: GET /single-documents/:id/display called getSignedUrl() and redirected the browser to a Case Vault presigned URL. The cross-origin request was failing in production, producing a "Failed to load document" error in the viewer.

The fix calls downloadFile() instead, buffers the result, and responds directly. Content-type resolution picks between application/pdf, application/msword, and the DOCX content-type based on the file type and whether a PDF rendition is available. Content-Disposition: inline and Cache-Control: private, no-store are set explicitly.

Alongside this, the Account > Models page got a small loading-state fix. The profile fetch was running five async calls sequentially; during the gap before completion, the UI would briefly show a "missing key" warning. That fix had missed the prior PR's merge window and was bundled here.

So what Worth pulling if your document display path redirects to third-party storage and you're seeing cross-origin failures. The fix also applies the explicit auth-boundary principle: if your threat model requires the backend to own all storage credentials, a proxy is the correct architecture.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

2 commits from CaseMark/mikeoss-casedotdev, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
96ee1a64 Avoid false missing key state during profile load kveton 2026-05-04 ↗ GitHub
8b7e3e0a Proxy Case document display bytes kveton 2026-05-04 ↗ GitHub

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-284.md from inside the repo you want the changes in.

⬇ Download capture-thread-284.md