6.4 KiB
spec, created, status
| spec | created | status |
|---|---|---|
| docs/specs/secure-context-browser-fallbacks/spec.md | 2026-08-02 | implemented |
Implementation Plan: Secure-context browser fallbacks
Overview
Route every client-only UUID through the existing guarded generator, then extract the existing clipboard fallback into a shared utility and migrate direct Clipboard API call sites to it. The audit confirms that file hashing, voice input, notifications, and sound already check capability boundaries; the focused tests will preserve those fallbacks while covering the newly repaired workflow, layout, and copy paths.
Root cause
useWorkflowCreation, workflow step creation, and layout profile creation call
crypto.randomUUID() directly. On a non-localhost HTTP origin the browser
exposes crypto but not randomUUID, so Add Workflow throws before its draft
state is updated. The shared generateUUID() helper already handles that
condition, but those call sites bypass it. Several copy actions similarly call
navigator.clipboard.writeText() directly even though the existing copy hook
has a DOM fallback for insecure contexts.
Frontend — client-only UUIDs
apps/web/app/settings/workspace/use-workflow-creation.ts: usegenerateUUID()for temporary workflow IDs.apps/web/components/settings/workflow-card-actions.ts: usegenerateUUID()for temporary step IDs.apps/web/lib/layout/layout-profiles.ts: usegenerateUUID()for layout profile IDs.apps/web/app/settings/workspace/use-workflow-creation.test.ts,apps/web/components/settings/workflow-card-actions.test.ts, andapps/web/lib/layout/layout-profiles.test.ts: add insecure-context coverage withcryptomissingrandomUUID.- Keep
apps/web/lib/utils/file-diff.tsunchanged unless its existing guarded fallback needs a test adjustment; it already degrades todjb2Hashwhencrypto.subtleis unavailable.
Frontend — clipboard fallback
- Add
apps/web/lib/utils/copy-to-clipboard.tswith the existing dialog-aware DOM fallback and a promise-returningcopyToClipboard(text)function. - Refactor
apps/web/hooks/use-copy-to-clipboard.tsto use the shared utility, preserving its copied state and timing. - Migrate direct Clipboard API calls in the settings, onboarding, task, diff/editor, review, and share surfaces to the shared utility. Preserve each caller's current success state, toast, and error behavior.
- The audited call sites are
apps/web/app/settings/agents/page.tsx,apps/web/app/settings/agents/[agentId]/profiles/[profileId]/command-preview-card.tsx,apps/web/components/settings/external-mcp-settings.tsx,apps/web/components/automations/trigger-configs/webhook-config.tsx,apps/web/components/task/executor-environment-info.tsx,apps/web/components/task/port-forward-dialog.tsx,apps/web/components/task/simple/OfficeSimplePane.tsx,apps/web/components/task/inspector/annotations-panel.tsx,apps/web/components/task/share/share-dialog.tsx,apps/web/components/task/chat/messages/auth-methods-panel.tsx,apps/web/components/task/chat/messages/tool-edit-message.tsx,apps/web/components/editors/file-actions-dropdown.tsx,apps/web/components/editors/monaco/use-diff-viewer-comments.ts,apps/web/components/editors/monaco/diff-viewer-context-menu.tsx,apps/web/components/editors/monaco/monaco-diff-viewer.tsx,apps/web/components/diff/diff-header-toolbar.tsx,apps/web/components/review/review-diff-toolbar.tsx,apps/web/components/onboarding/step-agents.tsx,apps/web/components/settings/account/api-tokens.tsx,apps/web/components/settings/system/log-viewer.tsx,apps/web/components/settings/system/invite-dialog.tsx, andapps/web/components/settings/ssh-agent-readiness-card.tsx. - Add
apps/web/lib/utils/copy-to-clipboard.test.tscovering modern success, missing API, rejected API, and dialog focus containment. Update the hook test only where its implementation seam changes.
Existing capability audit
apps/web/lib/utils/file-diff.tsalready guardscrypto.subtleand falls back todjb2Hash.- Voice input gates its UI on secure-context/capability checks and catches
capture failures; notification permission actions check
Notificationbefore use; sound creation checksAudioContextbefore construction. - No behavior change is planned for those already guarded paths; their existing tests remain part of focused frontend verification.
Tests
- UUID regression: no
randomUUIDmust not prevent workflow creation, step addition, or layout profile creation. Files listed above; Vitest hook and pure-function tests. - Clipboard regression: missing/rejected Clipboard API uses the DOM fallback without an uncaught rejection. New utility test plus existing hook tests.
- Existing fallbacks: run the file-diff, voice, notification, and sound tests selected by the focused test command where applicable.
E2E and mobile parity
This repair changes shared state/utility behavior, not layout, navigation, touch targets, scrolling, or mobile composition. The existing workflow settings desktop/mobile E2E coverage remains the rendered regression path; no new mobile scenario is required for this data-normalization change. A browser-level insecure-origin smoke run is optional if an isolated HTTP instance is already available.
Risks and out of scope
- The DOM copy fallback depends on
document.execCommand("copy"), which is deprecated but is the compatibility path already used by Kandev. - Fallback UUIDs are not cryptographically secure and must stay limited to client-only identifiers.
- Backend/API contracts, TLS setup, and security-token generation are out of scope.
Implementation waves
Wave 1 (sequential):
Wave 2 (sequential; depends on Task 01):
Verification Results
Task 01 — UUID fallback audit
- Focused Vitest: 4 files, 78 tests passed.
- Web typecheck passed.
- Static search found only the guarded
generateUUID()implementation.
Task 02 — Clipboard fallback migration
- Focused utility/hook Vitest: 3 files, 21 tests passed.
- Broader task-defined Vitest: 360 files, 2,647 tests passed, 4 skipped.
- Web typecheck, targeted ESLint, Prettier, and
i18n:ratchetpassed. - Static search found no direct application Clipboard API calls outside the shared guarded utility.