Implement clipboard and QR presentation
This commit is contained in:
@@ -26,6 +26,9 @@ key_material = "keys"
|
||||
# accepted and split without launching a shell.
|
||||
editor = ["code", "--wait"]
|
||||
|
||||
# Optional; upstream pass defaults to 45 seconds. Values are limited to 1..300.
|
||||
clipboard_timeout_seconds = 45
|
||||
|
||||
[[git.remotes]]
|
||||
name = "origin"
|
||||
url = "https://git.example.test/alice/password-store.git"
|
||||
@@ -49,6 +52,12 @@ store; duplicate names and duplicate reference pairs are errors.
|
||||
The HTTPS account name is stored inside the protected credential record, not in
|
||||
TOML. OpenPGP passphrases are addressed by the resolved primary fingerprint.
|
||||
|
||||
`clipboard_timeout_seconds` controls the native clipboard presentation lease.
|
||||
It defaults to 45 seconds for upstream `pass` compatibility and must be between
|
||||
1 and 300 seconds. The CLI remains alive for the lease so Linux can serve its
|
||||
selection and every platform can restore or clear the value reliably without a
|
||||
background helper process.
|
||||
|
||||
Passwords, passphrases, tokens, credentials, private keys, and other secret
|
||||
values are forbidden in TOML. Unknown fields are rejected. Parse errors never
|
||||
echo the source line or value, so an accidentally supplied secret is not
|
||||
|
||||
@@ -16,7 +16,9 @@ Normal generation uses the same overwrite decision and `--force` rules as
|
||||
insert. `--in-place` requires an existing entry, decrypts it, replaces only the
|
||||
bytes before its first newline, and preserves that newline and every following
|
||||
byte exactly. The generated password is returned separately as redacted,
|
||||
zeroizing data for typed terminal, clipboard, or QR presentation.
|
||||
zeroizing data for typed terminal, clipboard, or QR presentation. Clipboard and
|
||||
QR channels use the same storage-owned presentation service as `show`, so
|
||||
generated plaintext is never printed for those modes.
|
||||
|
||||
The completed entry is encrypted for the nearest recipient policy and written
|
||||
atomically. Embedded Git receives `Add generated password for ...` only after a
|
||||
|
||||
46
docs/presentation.md
Normal file
46
docs/presentation.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Clipboard and QR presentation
|
||||
|
||||
`crates/storage` owns secret-presentation lifecycle and derived QR data. The
|
||||
CLI receives an already selected `PresentationSecret` or generated password and
|
||||
only writes storage-produced status or terminal-rendering bytes. It never
|
||||
launches `xclip`, `wl-copy`, `pbcopy`, `qrencode`, an image viewer, or a shell.
|
||||
The same byte-oriented APIs are ready for pass-otp code and URI results without
|
||||
placing OTP parsing or calculation in a frontend.
|
||||
|
||||
## Clipboard lifecycle
|
||||
|
||||
The default clipboard lease is 45 seconds, matching upstream `pass`.
|
||||
`clipboard_timeout_seconds` may configure 1 through 300 seconds. Before copying,
|
||||
storage snapshots an existing UTF-8 clipboard value. At lease completion or
|
||||
cancellation it reads the clipboard again:
|
||||
|
||||
- if the copied secret remains current, storage restores the previous text or
|
||||
clears a previous empty/non-text clipboard;
|
||||
- if another application or the user supplied newer contents, storage leaves
|
||||
those contents untouched;
|
||||
- if cleanup cannot be verified or completed, the operation returns a typed
|
||||
cleanup failure rather than claiming success.
|
||||
|
||||
The CLI deliberately remains alive during the lease. This lets X11 and Wayland
|
||||
serve the selection and guarantees cleanup without spawning a daemon or helper.
|
||||
Linux also marks copied text with the commonly supported password-manager hint
|
||||
to discourage clipboard-history retention. macOS uses NSPasteboard, Windows
|
||||
uses the native clipboard, and Linux uses direct X11 or Wayland data-control
|
||||
protocols through the safe `arboard` adapter. Unsupported targets return a
|
||||
typed unavailable result. Tests inject a byte-oriented backend and cover
|
||||
expiry, restore, clear, cancellation, failure, and newer-content races without
|
||||
touching the developer clipboard.
|
||||
|
||||
## QR data
|
||||
|
||||
`QrMatrix` encodes secret bytes with the pure-Rust `qrcode` implementation and
|
||||
returns only dimensions and dark/light module queries. Its module buffer,
|
||||
terminal rendering, and source payload all use zeroizing/redacted storage
|
||||
objects. The terminal renderer supplies the standard four-module quiet zone,
|
||||
square half-block cells, and no plaintext label or payload. Frontends can draw
|
||||
the same matrix natively without regenerating or interpreting it.
|
||||
|
||||
Round-trip tests decode generated password, Unicode, and `otpauth://` matrices
|
||||
with the test-only `rqrr` decoder. Empty and oversized payloads are typed errors,
|
||||
and CLI tests prove `show` and `generate` clipboard/QR modes never emit their
|
||||
plaintext values.
|
||||
@@ -23,6 +23,9 @@ number. Storage selects that line directly from decrypted bytes and returns a
|
||||
`PresentationSecret` containing the logical entry, line, channel, and redacted
|
||||
zeroizing contents. The adapter never parses rendered terminal output, and a
|
||||
missing or empty requested line is an explicit failure.
|
||||
The resulting secret is consumed by the shared presentation service documented
|
||||
in [`presentation.md`](presentation.md); plaintext is not written to CLI output
|
||||
for clipboard or QR requests.
|
||||
|
||||
## Name and plaintext search
|
||||
|
||||
|
||||
Reference in New Issue
Block a user