uttrflow / uttrflow/uttrflow-swift

A picture copied with the concealed marker is saved and shown like any other picture, and the secrets doc never says pictures go unchecked

Open
#662 0 comments 0 reactions 0 assignees View on GitHub
area:clipboard bug good first issue P0 security
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

`PasteboardWatcher.newClip` checks the writer's markers first. Transient and auto-generated copies are dropped (`Sources/UttrflowClipboard/PasteboardWatcher.swift:103-104`). The concealed marker is honoured only on the text branch: `markers.contains(.concealed) ? ClipClassification(kind: .secret, …)` (`:126-128`).

A picture is handled earlier, and there `markers` is never consulted (`:109-115`):

```swift
if copied == nil, let picture = source.image() {
return NoticedClip(clip: Clip(text: "", kind: .image, …), picture: picture)
}
```

So a picture copied with `org.nspasteboard.ConcealedType` is written to `Application Support/Uttrflow/Images/` (`ClipboardStore.keep`, `Sources/UttrflowClipboard/ClipboardStore.swift:198-212`) and drawn as a normal thumbnail in the panel. Secret detection is text-only, so a screenshot of a key, a recovery-code sheet or a card is never hidden either. Nothing can read it, and that limit is reasonable.

The Home page promises: "Card numbers, keys and passwords from a password manager stay hidden until you ask" (`Sources/UttrflowUX/HomePresentation.swift:324-326`). `Docs/clipboard-secrets.md` describes the markers (`:114-118`) and the text rules, but never mentions pictures.

## Why it matters

Some password managers and authenticator apps copy QR codes or card images. The concealed marker is the only signal the app gets that the writer considers a copy secret, and pictures ignore it. People who screenshot credentials are not warned that the panel shows them.

## Acceptance criteria

- A picture carrying `ConcealedType` is either not recorded, or recorded with a flag that makes the panel draw it masked until revealed, like a secret text clip. Pick the one that matches #483's decision on storing secrets.
- `Docs/clipboard-secrets.md` gains a short "Pictures" section: pictures are not scanned for secrets, how a concealed picture is handled, and how long pictures are kept.
- A test in `Tests/UttrflowClipboardTests` (the watcher tests use a fake pasteboard source) copies a concealed picture and asserts the chosen behaviour.

## Where to start

- `Sources/UttrflowClipboard/PasteboardWatcher.swift` (`newClip`), `PasteboardMarkers.swift`, and `Docs/clipboard-secrets.md`.
- Extend `Tests/UttrflowClipboardTests/PasteboardWatcherTests.swift` (and `PasteboardMarkersTests.swift`).
- Run `make verify`. See `CONTRIBUTING.md`.
- Size: small. Not recording the picture is a two-line guard plus a test; masking needs a field on `Clip`.

Contributor guide

Open the contributing guide

Research direction

Start with #483 to determine whether concealed pictures should be dropped or stored as masked clips, then inspect PasteboardWatcher.swift newClip, PasteboardMarkers.swift, and the existing Clip handling. Extend PasteboardWatcherTests.swift and, if needed, PasteboardMarkersTests.swift; update Docs/clipboard-secrets.md. The work is done when the chosen behavior is tested for a concealed picture, the picture rules and retention are documented, and make verify passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
desktop, documentation, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.