Skip to content

fix(app): derive renderer CSP origins from SPOOL_SHARE_BACKEND#380

Merged
graydawnc merged 2 commits into
mainfrom
fix/csp-backend-origin
Jun 10, 2026
Merged

fix(app): derive renderer CSP origins from SPOOL_SHARE_BACKEND#380
graydawnc merged 2 commits into
mainfrom
fix/csp-backend-origin

Conversation

@graydawnc

Copy link
Copy Markdown
Collaborator

What

Refactors the renderer CSP into a buildCsp() builder and appends the SPOOL_SHARE_BACKEND override origin (when set) to connect-src and img-src in both dev and prod profiles. Origins are compared after URL.origin normalization so a trailing-slash spelling of the default doesn't duplicate entries. The canonical spool.pro family stays in the prod allow-list unconditionally — published-share URLs and avatar links keep pointing there even when the API origin is overridden.

Why

Main-process fetches follow SPOOL_SHARE_BACKEND, but the renderer's direct fetches (user-avatar <img> loads from /api/avatars/<id>, renderer-side API calls) were pinned to the hardcoded spool.pro family. Pointing the app at staging or a local mock made those requests silently disappear behind CSP — broken image, empty network tab, no console hint. Found in the pre-GA launch audit.

Test plan

  • 4 new cases in csp.test.ts: override origin lands in connect-src/img-src (both profiles), spool.pro family retained alongside the override, no-override output is byte-identical to the previous fixtures (19 tests green)
  • Publish e2e runs the app with SPOOL_SHARE_BACKEND pointed at the in-process mock — exercises the override path on every run

🤖 Generated with Claude Code

graydawnc and others added 2 commits June 10, 2026 14:33
The Share button, Publish/Export tab labels, and the popover/tablist
aria-labels were the last hardcoded English strings in the share-publish
surfaces after the #372 i18n pass. Route them through t() with new
shareEditor.shareMenu.* keys across all 7 locales.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The prod CSP hardcoded the spool.pro origin family in connect-src and
img-src. When SPOOL_SHARE_BACKEND redirects API traffic elsewhere
(staging, local mock), main-process fetches follow the override but the
renderer's direct fetches — avatar <img> loads and api calls — get
silently blocked by CSP, which looks like a broken image with an empty
network tab.

buildCsp() now appends the override origin (normalized via URL.origin,
so a trailing-slash default doesn't duplicate) to both directives in
both profiles. The canonical spool.pro family stays unconditionally:
published-share URLs and avatar links keep pointing there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Base automatically changed from fix/sharemenu-i18n to main June 10, 2026 06:57
@graydawnc
graydawnc added this pull request to the merge queue Jun 10, 2026
Merged via the queue into main with commit a724cc1 Jun 10, 2026
3 checks passed
@graydawnc
graydawnc deleted the fix/csp-backend-origin branch June 10, 2026 06:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant