Skip to content

[Fix/205 csp storage] fix(core): include storage origin in CSP and add unit tests#226

Open
WebDevByCam wants to merge 6 commits intoemdash-cms:mainfrom
WebDevByCam:fix/205-csp-storage
Open

[Fix/205 csp storage] fix(core): include storage origin in CSP and add unit tests#226
WebDevByCam wants to merge 6 commits intoemdash-cms:mainfrom
WebDevByCam:fix/205-csp-storage

Conversation

@WebDevByCam
Copy link
Copy Markdown

What does this PR do?

Updates the Content Security Policy (CSP) for admin and API routes to include the configured storage origin.

  • Extracts CSP generation into a reusable buildEmDashCsp utility
  • Re-exports the helper from the middleware
  • Adds unit tests covering:
    • Inclusion of the storage origin
    • Safe handling of invalid URLs

Closes #205

Type of change

  • ✅ Bug fix
  • Feature (requires approved Discussion)
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • ✅ Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • ✅ I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm --silent lint:json | jq '.diagnostics | length' returns 0
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • ✅ I have added/updated tests for my changes (if applicable)
  • ✅ I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 4, 2026

🦋 Changeset detected

Latest commit: e5e7761

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/plugin-ai-moderation Patch
@emdash-cms/plugin-atproto Patch
@emdash-cms/plugin-audit-log Patch
@emdash-cms/plugin-color Patch
@emdash-cms/plugin-embeds Patch
@emdash-cms/plugin-forms Patch
@emdash-cms/plugin-webhook-notifier Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 4, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@WebDevByCam
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Apr 4, 2026
Copilot AI review requested due to automatic review settings April 4, 2026 08:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes S3/R2-style direct uploads being blocked by the admin/API Content Security Policy by adding the configured storage origin to the CSP, while extracting CSP generation into a standalone utility and adding unit coverage.

Changes:

  • Extract CSP generation into buildEmDashCsp() and add storage-origin support for connect-src and img-src.
  • Update admin/API middleware CSP header setting to pass the storage endpoint origin.
  • Add Vitest unit tests and a patch changeset for the fix.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/core/tests/unit/middleware-auth.test.ts Adds unit tests validating storage origin inclusion and invalid URL handling.
packages/core/src/astro/middleware/csp.ts Introduces a standalone CSP builder that can include marketplace + storage origins.
packages/core/src/astro/middleware/auth.ts Replaces inline CSP builder with shared helper and injects storage endpoint into CSP.
.changeset/fix-csp-storage.md Declares a patch release entry for the CSP fix + tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +41 to +42
emdash: EmDashHandlers;
emdashManifest: EmDashManifest;
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App.Locals now declares emdash and emdashManifest as required, but the core runtime middleware only attaches these fields on certain routes / conditions (see packages/core/src/astro/middleware.ts where locals.emdash is set inside the runtime init path, and many requests return early without setting it). Making them required makes the global Astro locals typing inaccurate for non-EmDash routes and can force downstream consumers/middlewares to assume these fields always exist. Consider reverting these to optional (or introducing a narrower locals type for the auth middleware context only).

Suggested change
emdash: EmDashHandlers;
emdashManifest: EmDashManifest;
emdash?: EmDashHandlers;
emdashManifest?: EmDashManifest;

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are wrong, you missed that locals.d.ts is the public contract for consumers of the package

typescript requires all interface augmentations to agree on optionality

@JULJERYT
Copy link
Copy Markdown
Contributor

JULJERYT commented Apr 6, 2026

all tests pass
@ascorbic could you change 33 line of packages/core/src/astro/middleware/auth.ts to:

import { buildEmDashCsp } from "./csp.js";

and 3 line of packages/core/tests/unit/middleware-auth.test.ts to:

import { buildEmDashCsp } from "../../src/astro/middleware/csp.js";

@JULJERYT
Copy link
Copy Markdown
Contributor

JULJERYT commented Apr 6, 2026

Thanks to Nick Gray for sponsoring my time on this review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Matt Kane <m@mk.gg>
"base-uri 'self'",
].join("; ");
}
export { buildEmDashCsp };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of re-exporting from here, can any other imports be changed to import directly from csp.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CSP connect-src blocks S3 signed uploads from admin UI

4 participants