Skip to content

feat: support strict CSP (follow-up to #1193)#1240

Merged
mathuo merged 13 commits into
masterfrom
csp-followup
May 13, 2026
Merged

feat: support strict CSP (follow-up to #1193)#1240
mathuo merged 13 commits into
masterfrom
csp-followup

Conversation

@mathuo
Copy link
Copy Markdown
Owner

@mathuo mathuo commented May 6, 2026

Builds on @hyperNURb's #1193 (preserves all original commits/authorship) and addresses the items blocking that PR.

What this PR adds on top of #1193

  1. Merge with master — resolves the two conflicts (packages/dockview-core/src/dockview/options.ts imports + __generated__/dockview-core-exports.txt). Brings in the unrelated ReactComponentBridge test-flake fix (ce02eea24) so CI's test job stops failing.
  2. fix(dockview-core): avoid duplicating rules from external stylesheetsaddStyles previously appended a <link> for href-bearing sheets and fell through to inject inline <style> elements for the same sheet, which both duplicates rules (same-origin sheets) and triggers the security-warning path (cross-origin sheets). Flagged by the Copilot review on feat: support strict CSP #1193. Now we continue past the inline-injection block once the <link> has been appended, and the existing test is tightened to assert no <style> is produced for an href sheet.
  3. Format — runs prettier on dom.ts and dom.spec.ts so format:check passes.
  4. test(dockview-core): cover CSP nonce wiring
    • New popoutWindow.spec.ts (3 tests) drives PopoutWindow.open() with a mocked window.open and verifies the nonce option flows through addStyles into the <style> elements in the popout document, for both string and (targetDocument) => string forms.
    • New options.spec.ts asserts 'nonce' ∈ PROPERTY_KEYS_DOCKVIEW, which is the contract that lets the React and Vue wrappers auto-forward the option without explicit prop wiring (validates the description's claim that React/Vue are covered).

Test plan

  • yarn nx run dockview-core:format:check — clean
  • yarn nx run dockview-core:lint — 0 errors
  • yarn nx run dockview-core:test — 867/867 pass (+14 from new tests)
  • Verified the addStyles test would have caught the duplicate-rules bug (checked by reverting the continue locally — <style> length goes from 0 → 1)

🤖 Generated with Claude Code

hyperNURb and others added 13 commits April 16, 2026 15:54
Resolve conflicts in:
- packages/dockview-core/src/dockview/options.ts (kept both new
  imports from master and the CspNonce import from this branch)
- __generated__/dockview-core-exports.txt (regenerated via npm run gen)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… in addStyles

When a stylesheet has an href, addStyles already appends a <link> to
the target document. Previously it then also fell through and tried
to read cssRules to inject inline <style> elements for the same
sheet, which both duplicates the rules (same-origin sheets) and
logs a security warning (cross-origin sheets).

Continue past the inline-injection block once the <link> has been
appended. Also runs prettier on dom.ts and dom.spec.ts to satisfy
format:check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add three integration tests around PopoutWindow.open() that mock
window.open and verify the nonce option flows all the way into the
<style> elements injected into the popout document, both for
string nonces and for the (targetDocument) => string callback form.

Also adds a small contract test asserting that 'nonce' is in
PROPERTY_KEYS_DOCKVIEW, which is what makes the React and Vue
wrappers auto-forward the option without explicit prop wiring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The exported union `string | ((doc: Document) => string | undefined)` is
not just a nonce — only the first arm is. The second arm provides one.
Rename to CspNonceProvider so the type name describes both shapes
accurately. Also drop an unused `import { CspNonce }` line in
options.ts (the `export { ... } from '../dom'` re-export was already
sufficient).

While here, split the `dom.spec.ts` "preserves source order" test:
because addStyles now `continue`s past cssRules access for href-bearing
sheets, the previous test's throwing cssRules getter and console.warn
spy were dead code. The split now has one test for ordering (using a
plain href stylesheet in the middle) and a separate test that exercises
the warn path on a no-href sheet whose cssRules access throws.

Regenerate __generated__/dockview-core-exports.txt for the rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move `advanced/csp.mdx` -> `core/security.mdx` and retitle to "Security".
CSP is one slice of how Dockview behaves in security-hardened
environments alongside Trusted Types and same-origin popouts; the page
was already covering all three. Live alongside theming/events/dnd in
`core/` since this is operational config every production deploy hits,
not an edge case.

Two content changes worth flagging:

- Clarify that the `nonce` option only authorises the inline <style>
  elements Dockview injects. External CSS files Dockview reattaches
  as <link rel="stylesheet"> in the popout are still subject to your
  `style-src` source expressions — the URLs must be covered by 'self'
  or an explicit origin in the directive, not just by the nonce.
- Document the FOUC edge for href-bearing sheets in popouts: because
  they reload via <link> they're applied asynchronously, so the popout
  may flash unstyled for a frame on a slow origin. Invisible in
  practice for same-origin (cached) sheets.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolve add/add conflict in packages/dockview-core/src/__tests__/popoutWindow.spec.ts:
both branches added the file. Keep both describe blocks — this branch's CSP
nonce wiring tests (`PopoutWindow` describe) plus master's same-origin
URL assertion tests (`assertSameOriginPopoutUrl` describe).

Updated the CSP test URLs from 'about:blank' to '/popout.html' so they
clear master's new assertSameOriginPopoutUrl gate (which now runs in
PopoutWindow.open). Verified all 904 dockview-core tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `export { CspNonceProvider } from '../dom'` re-export only forwards
the name to consumers — it does not bring it into local scope, so the
type annotation `nonce?: CspNonceProvider` further down failed with
TS2304. Restore the local import alongside the re-export.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

@mathuo mathuo merged commit 6970489 into master May 13, 2026
9 checks passed
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.

2 participants