mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
## Problem Two v0.5.6-only regressions were introduced by #4614 (the first enforced Tauri CSP): 1. **Tab-complete caret regression** — after tab-completing an @mention, #channel, or :emoji: shortcode, the cursor landed inside the inserted text instead of after the trailing space. TipTap inserts the correct text including the trailing space, but without its base stylesheet (`.ProseMirror { white-space: break-spaces }`) the trailing space collapses visually and the caret appears mid-name. 2. **Emoji picker unstyled** — the emoji-mart picker rendered as a giant unstyled layout (oversized search SVG, collapsed grid) because emoji-mart's shadow-root stylesheet injection was also blocked. Both symptoms have the same root cause. ## Root Cause Tauri's build-time asset processor scans `index.html` for inline `<style>` elements, injects a nonce token, and adds the corresponding `'nonce-…'` source to `style-src` at runtime. Per the CSP spec, **once a nonce is present in a directive, the browser ignores `'unsafe-inline'` for that directive**. `index.html` contained an inline `<style>` with the boot background color. When Tauri nonced it and injected `'nonce-…'` into `style-src`, the intended `style-src 'self' 'unsafe-inline'` became effectively `style-src 'self' 'nonce-…'` — blocking any runtime stylesheet injection not covered by a matching nonce: - TipTap's `injectCSS()` → `createStyleTag()` injecting `.ProseMirror { white-space: break-spaces; … }` - emoji-mart's shadow-root `document.createElement('style')` injection (Inline scripts follow a separate path — they are SHA-256 hashed, not nonced.) This only reproduces in packaged builds (where Tauri's custom protocol serves the HTML and enforces the policy). `tauri dev` loads from the Vite dev server and is not affected. ## Fix Move `html { background-color: #000; }` from an inline `<style>` in `index.html` to `desktop/public/boot.css`, linked via `<link rel="stylesheet">`. A linked stylesheet is not subject to Tauri's nonce injection, so `'unsafe-inline'` in `style-src` applies as declared. The `<link>` is render-blocking (same as the inline style was), so boot-flash behaviour is identical. **The production CSP string is unchanged.** This fix makes the policy apply as intended — no security properties are altered. Will's follow-up with the security team (Jordan Mecom / Eli Foster, authors of #4614) is noted for post-ship. A Tauri-faithful CSP harness for the Vite dev path (so this class of regression is visible before a packaged build) is tracked as a separate follow-up. ## Files Changed - `desktop/index.html` — replace inline `<style>` with `<link rel="stylesheet" href="/boot.css" />` - `desktop/public/boot.css` — new file, the extracted `html { background-color: #000; }` plus rationale comment - `desktop/src-tauri/tests/csp.rs` — update comment: nonce for styles, SHA-256 for the boot script ## Testing - `just desktop-typecheck` ✅ - `just desktop-test` ✅ (4535/4535) - `just desktop-tauri-test` ✅ (all Rust tests including `csp.rs`) - Packaged validation: `pnpm tauri build --debug` completed; compiled binary bakes `style-src 'self' 'unsafe-inline'` with no nonce source injected ✅ --------- Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>