Skip to content

fix: copy resource names over HTTP - #1465

Merged
nadaverell merged 3 commits into
skyhook-io:mainfrom
CBOSSX:bugfix/insecure-http-copy-20260820T042803Z
Aug 23, 2026
Merged

fix: copy resource names over HTTP#1465
nadaverell merged 3 commits into
skyhook-io:mainfrom
CBOSSX:bugfix/insecure-http-copy-20260820T042803Z

Conversation

@CBOSSX

@CBOSSX CBOSSX commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Description

Resource-name copy buttons now keep the modern Clipboard API as the primary path and fall back to a hidden textarea copy command when that API is unavailable or denied. This makes the reported button work when Radar is served from a plain-HTTP hostname or IP address, and the success icon only appears after a copy path succeeds.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

How has this been tested?

  • npm test --workspace @skyhook-io/k8s-ui -- src/utils/clipboard.test.ts (3 passed)
  • npm test --workspace @skyhook-io/k8s-ui (146 files; 2549 passed, 1 skipped)
  • npm run tsc --workspace @skyhook-io/radar-app
  • npm run lint --workspace @skyhook-io/radar-app (0 errors)
  • make lint
  • make build

The regression covers an unavailable Clipboard API, a rejected Clipboard API, and the successful modern path. The standalone k8s-ui TypeScript command still reports the same nine test-only diagnostics on the exact upstream base SHA and on this patch; the production Radar Web type check and full build pass.

  • Tested locally with minikube/kind
  • Tested against a remote cluster
  • Added/updated unit tests

Checklist

  • My code follows the project's coding standards
  • I have performed a self-review of my code
  • I have added comments where necessary
  • My changes generate no new warnings
  • Any dependent changes have been merged

Related issues

Fixes #1269

Regression evidence

  • Before: npm test --workspace @skyhook-io/k8s-ui -- src/utils/clipboard.test.ts exited 1 with the test present and production files unchanged from 7ffa6e2959371818a1aa45123efa1b8b68ff419a.
  • After: the same command exited 0 with all 3 cases passing.

Scope

  • 4 files changed, +100 / -2 lines
  • No dependency or generated-file changes

Note

Medium Risk
Touches a global document.execCommand monkey-patch used by the desktop WebView and Monaco copy/cut. Behavior is covered by unit tests but remains environment-sensitive.

Overview
Resource-name copy now works when Radar is served over plain HTTP (no Clipboard API). copyText tries navigator.clipboard.writeText first, then a hidden-textarea execCommand('copy') fallback, and the checkmark only shows if a path actually succeeds.

The Wails clipboard shim is extracted to wails-clipboard.ts. Its execCommand patch now hijacks copy/cut only when Monaco has a virtual selection; other callers (including copyText) go through the native command and get its real return value instead of a fabricated success.

Reviewed by Cursor Bugbot for commit d460d13. Bugbot is set up for automated code reviews on this repo. Configure here.

The Wails clipboard shim replaced document.execCommand globally and routed
every copy/cut through navigator.clipboard.writeText, returning true without
observing the result. On insecure origins — where navigator.clipboard does not
exist — that defeated the hidden-textarea fallback copyText relies on and
fabricated a success result. Only Monaco's virtual selection needs the hijack;
everything else now delegates to the native command and reports its real
return value.

Extracted the shim from main.tsx into an installable module so the delegation
matrix is unit-testable, including copyText running against the patched
document.
textarea.select() moves focus to the hidden aria-hidden element and remove()
then drops focus to body. Return it to the previously focused element, but
only when the textarea still owns focus (a copy handler may have focused
something else), only when that element is still connected, and without
scrolling it into view.
@nadaverell

Copy link
Copy Markdown
Contributor

Thanks @CBOSSX - copyText is exactly the right shape, keeping it as-is, tests included.

While verifying over a real plain-HTTP origin I hit a collision with the desktop entrypoint: web/src/main.tsx monkey-patches document.execCommand for the Wails webview, which swallowed the hidden-textarea fallback and made it report success without copying. Fixed it in a new commit so the patch now only hijacks Monaco's virtual selection and delegates everything else to the native command with its real return value - plus a small commit restoring focus after the fallback.

Verified end-to-end on http://<LAN-IP> (no navigator.clipboard, the exact #1269 setup) and in the desktop app - clipboard actually receives the text in both.

I'll migrate the ~30 other writeText call sites to copyText in a follow-up. Nice find and a clean patch!

@nadaverell
nadaverell merged commit 235e844 into skyhook-io:main Aug 23, 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.

Can't copy anything?

2 participants