[Feature] Re-trigger CSP consent when tool adds new permissions since last approval - #613
[Feature] Re-trigger CSP consent when tool adds new permissions since last approval#613Power-Maverick with Copilot wants to merge 3 commits into
Conversation
…t approval - Add `seenOptional` field to `CspConsentRecord` to track all optional domains presented at consent time (approved or declined). This enables accurate detection of truly new optional permissions versus domains the user previously saw and chose not to approve. - Update `grantCspConsent` in `settingsManager.ts` to accept and persist `seenOptionalDomains` as 4th parameter. - Propagate the new parameter through the IPC handler in `index.ts` and the renderer-facing preload in `preload.ts`. - Add `CspReconsentContext` interface to `view.ts` (also re-exported from `cspExceptionModal.ts`). When supplied, the CSP modal renders in re-consent mode: new required/optional permissions appear under "New Required" / "New Optional" sections (with checkboxes), while previously approved domains are shown as an informational read-only "Previously Approved" section with reduced opacity. - Update `openCspExceptionModal` to accept an optional `CspReconsentContext` and pass it through to the view builder. - In `toolManagement.ts`, after confirming an existing consent record exists for a tool, compute the current required and optional domains and compare against `required` and `seenOptional` in the stored record. If any new domains are found, open the re-consent modal. On accept, the consent record is updated by merging new domains into the existing sets. On decline, the old consent record is left unchanged and the tool launch is cancelled with a notification. - Add 3 unit tests for the new `seenOptional` behaviour in `settingsManager.test.ts`.
❌ PR Checklist — Action RequiredThe following items must be completed before this PR can be merged:
🔴 |
|
@copilot build failed |
... Fixed in the latest commit. The |
Bundle Size Report 📦
Bundle Analysis ReportsThe detailed bundle analysis reports are available in the workflow artifacts:
Download the artifacts from the workflow run to view interactive visualizations. Bundle size tracking is now active! This helps prevent bundle bloat. |
|
@copilot whats the expected change in the Supabase when update for a tool is processed? |
No changes to Supabase are expected — the desktop app only reads from Supabase, never writes tool metadata back to it. Here's the full flow when a tool update is processed:
So Supabase is the source of truth for what |
One-time CSP consent meant a tool update silently gaining new network permissions without the user ever seeing them. This adds re-consent detection: on each tool launch, current permissions are diffed against what was stored at last consent, and if new domains appear the modal fires again showing only the delta.
Summary
When a tool update adds new CSP permissions, the app now detects the change at launch time and re-shows the consent modal highlighting only the new permissions alongside previously approved ones as read-only context. Declining re-consent preserves the existing consent record unchanged and cancels the launch.
Closes #157
Type of change
Changes
src/common/types/settings.ts— AddedseenOptional: string[]toCspConsentRecord. Tracks all optional domains presented to the user (approved or declined), so previously-declined optional domains aren't treated as new on the next launch.src/main/managers/settingsManager.ts—grantCspConsentaccepts a 4thseenOptionalDomainsparameter and persists it.src/main/index.ts/src/main/preload.ts— IPC handler and preload API updated to forwardseenOptionalDomains.src/renderer/modals/cspException/view.ts— NewCspReconsentContextinterface; view renders in two modes:New Required+New Optional(actionable) +Previously Approved(read-only, dimmed).src/renderer/modules/cspExceptionModal.ts—openCspExceptionModalaccepts optionalCspReconsentContext; re-exported for callers.src/renderer/modules/toolManagement.ts— After finding an existing consent record, diffs current domain sets againstrequiredandseenOptional. New domains trigger re-consent modal. On accept, merges new domains into stored sets. On decline, leaves consent unchanged and cancels launch.Re-consent detection logic:
Architecture checklist
Packages (
types&validation)packages/Code quality
pnpm run typecheckpasses with 0 errors (warnings are acceptable)pnpm run lintpasses with 0 errors (warnings are acceptable)pnpm run buildcompletes successfullyTesting
pnpm run test:unitpasses (for changes tosrc/main/,src/common/, orsrc/renderer/utilities)pnpm run test:e2epasses (for UI / navigation / end-to-end flows)pnpm run dev)Scenario tested:
3 new unit tests added to
tests/unit/main/managers/settingsManager.test.tscoveringseenOptionalpersistence, default-to-empty-array behaviour, and full record shape viagetCspConsents(). All 168 unit tests pass.Breaking changes
grantCspConsentIPC and preload API gains a 4th optional parameterseenOptionalDomains?: string[]. Existing callers that omit it default to[]. Existing storedCspConsentRecordobjects withoutseenOptionalare handled gracefully: the re-consent logic falls back to the storedoptionallist (seenOptional ?? optional), which means users with prior consents will see a one-time re-prompt if the tool has optional permissions they previously declined — a safe and intentional UX trade-off for the migration.Reviewer notes
seenOptional ?? optional) means users upgrading from old consent records may see the re-consent modal once for optional domains they had declined before. This is intentional and bounded to a single extra prompt.previouslyApprovedRequired+previouslyApprovedOptionalin the re-consent context are the user-approved subsets, not the full seen set — only the "Previously Approved" section in the UI shows domains the user actually allowed.