Skip to content

In-app destructive-confirm modal + Content-Security-Policy#139

Merged
silverbucket merged 1 commit into
masterfrom
ux/confirm-modal-and-csp
Jul 4, 2026
Merged

In-app destructive-confirm modal + Content-Security-Policy#139
silverbucket merged 1 commit into
masterfrom
ux/confirm-modal-and-csp

Conversation

@silverbucket

Copy link
Copy Markdown
Owner

Closes #60
Closes #67
Closes #79

In-app destructive confirm (#60, #67)

  • New store primitive requestConfirm(options) → Promise<boolean> with a single globally-rendered modal (sits above the song-editor overlay; Escape/backdrop cancel; a newer request supersedes a pending one as cancelled).
  • All ten window.confirm sites converted: song delete, delete-all-data, member/instrument/tuning/technique removal, and the song editor's discard-changes guard. The editor's redundant inline two-step delete is removed — one confirm pattern everywhere, styled like the app instead of the system dialog.
  • deleteAllData now requires typing the band name ("Delete everything" stays disabled until it matches) — replacing the old chained double confirm whose near-identical wording was easy to click through.
  • Forget (×) on the login screen confirms first (Recent-account: 'Forget' (×) is a 44x44 hit target with no confirmation #67) — it deletes the account's entire local mirror, so a bare mistappable 44×44 target was no longer acceptable.

Content-Security-Policy (#79)

  • Strict policy injected as a meta tag at build time only (the dev server stays unrestricted for HMR): default-src 'self', script-src 'self' (no inline allowance), style-src 'self' 'unsafe-inline' (Svelte style attributes), img-src 'self' data: blob:, connect-src 'self' https: http: (rs.js talks to whatever host the user's WebFinger points at, including plain-HTTP LAN servers), worker-src 'self' blob:, object-src 'none', base-uri 'self', form-action 'self'.
  • To keep script-src 'self' hash-free, the inline FOITC theme script moved to /public/theme-init.js (blocking external script, precached by the SW).
  • With no third-party JS and now no inline script surface, localStorage-token exfiltration via injected script is refused by the browser — the property Add Content-Security-Policy meta to harden token-in-localStorage #79 asked to formalize.

Testing

  • 336 unit tests (new: confirm request/supersede semantics; deleteSong gated on confirm).
  • 158/158 chromium e2e and 158/158 mobile (WebKit) e2e — page objects/specs updated from native-dialog handlers to the modal, plus new coverage: typed-name gating for delete-all, cancel-after-typing, and the discard-confirm keep-editing path.
  • Real-browser smoke against the CSP'd production build: boot, offline mirror hydrate, theme init, favicon, toast actions — zero CSP violations.

Note for staging verification

Worth one pass on setlist-staging.5apps.com after deploy: the OAuth redirect + auth-relay.html flow under CSP, and an installed-PWA session (Workbox + dynamic icons run under worker-src/img-src blob:).

Closes #60, #67, #79.

Confirm modal (#60, #67):
- New store primitive requestConfirm(options) -> Promise<boolean> with a
  globally rendered modal (App.svelte, above the editor overlay). A
  newer request supersedes a pending one (resolved as cancelled).
- All ten window.confirm sites converted: song delete, delete-all,
  member/instrument/tuning/technique removal, and the editor's
  discard-changes guard. The song editor's redundant inline two-step
  delete is gone — one confirm pattern everywhere.
- deleteAllData uses typed-band-name verification instead of the old
  chained double confirm with near-identical wording.
- Forgetting a recent account now confirms before wiping (the x was a
  bare 44x44 target that deletes the whole local mirror).

CSP (#79):
- Strict policy injected at build time (dev server unrestricted):
  default/script/style/img/font/connect/worker/manifest/object/base-uri/
  form-action. script-src 'self' with NO inline allowance — the theme
  FOITC script moved from inline <script> to /public/theme-init.js
  (blocking external, precached).
- connect-src allows https:/http: because rs.js talks to whatever host
  the user's WebFinger points at, including plain-HTTP LAN servers.
- Verified in a real browser against the built bundle: boot, mirror
  hydrate, theme, favicon, toasts — zero CSP violations.

336 unit tests, 158/158 chromium e2e, 158/158 mobile (WebKit) e2e.
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@silverbucket, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 25 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e6c1a810-e9f5-45c9-aee3-fb74d83806c8

📥 Commits

Reviewing files that changed from the base of the PR and between fdcedae and 7cfeb02.

📒 Files selected for processing (13)
  • index.html
  • public/theme-init.js
  • src/App.svelte
  • src/lib/components/songs/SongEditor.svelte
  • src/lib/stores/app.svelte.js
  • src/lib/stores/app.test.js
  • tests/e2e/band.spec.ts
  • tests/e2e/data-management.spec.ts
  • tests/e2e/song-editor.spec.ts
  • tests/pages/BandPage.ts
  • tests/pages/ConnectPage.ts
  • tests/pages/SongEditorPage.ts
  • vite.config.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ux/confirm-modal-and-csp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@silverbucket

Copy link
Copy Markdown
Owner Author

@coderabbitai code review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

@silverbucket: Sure, I'll review the changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@silverbucket silverbucket merged commit d7ac5e7 into master Jul 4, 2026
6 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

1 participant