Files
IronStorage/docs/desktop-audit.md

10 KiB

Desktop parity, platform, and security audit

The Iced application is a presentation adapter over crates/storage. The tables below are the milestone 01/02 coverage record. action.rs is the single desktop action and enablement registry used by menus, shortcuts, direct controls, context controls, Help, and the command palette. A desktop unit test requires every registered action ID to remain present in this document.

Coverage matrix

Area and compatible operation Registered desktop action and menu Direct control, dialog, or view Command palette
Configuration and lock: open configured store open-folder (File) Compact toolbar control and native folder picker; storage validates and persists configuration Yes
Configuration and lock: edit shared settings settings (IronStorage) Labelled Settings form for vault, default key, and inactivity timeout Yes
Configuration and lock: refresh typed tree refresh (View) Sidebar Refresh control Yes
Configuration and lock: lock/unlock lock (Tools) Toolbar Lock control; opening protected content starts storage authentication Lock only; unlock is the protected action being resumed
Base pass: init root or nested recipient policy initialize-store, new-folder (File) Recipient/default-key form and explicit replacement confirmation Yes
Base pass: default/list/ls/list refresh (View) Expandable storage-provided tree with object icons and descendant entry counts Yes for refresh; browsing is direct navigation
Base pass: show and reload open-entry, reload-entry (Entry) Tree activation, typed identity header, structured viewer, Reload control Yes
Base pass: insert/add new-entry (File) New Entry form creates a lossless draft, then the structured editor saves it Yes
Base pass: edit and save edit-entry, save (Entry/File) Compact Edit and Save controls; shared Save/Discard/Cancel guard Yes
Base pass: generate and replace generate-password (Entry) Field Generate control and explicit replacement confirmation Yes
Base pass: authenticated values and clipboard copy-field, copy-edited-field (Entry) Every field is visible while unlocked; compact Copy controls retain the configured cleanup countdown Yes
Base pass: find find (Edit) Name-search form and typed result activation Yes
Base pass: grep search-contents (Edit) Authenticated decrypted-search form and typed result activation Yes
Base pass: mv/rename, cp/copy, rm/remove move-entry, copy-entry, delete-entry (Entry) Sidebar context controls and validated mutation forms; delete is confirmed Yes
KeePass migration: additive KDBX import and quick add import-kdbx (Tools) Native file/key picker, protected password input, explicit confirmation, and storage-owned tree refresh Yes
Pass OTP: code/show and timed copy generate-otp, copy-otp (Entry) Unlocked entry header shows the large code and storage-period countdown bar; the OTP field retains metadata/actions and HOTP confirmation Yes
Pass OTP: insert/add/append and validate import-otp (Entry) URI/QR import form; storage validates, replaces, and commits Yes
Pass OTP: URI terminal/clipboard/QR show-otp-uri, copy-otp-uri, show-otp-qr (Entry) Explicit secret view, timed copy, and storage-provided QR matrix Yes
Pass OTP: remove remove-otp (Entry) Explicit permanent-removal confirmation Yes
Embedded Git: status, history, remote divergence git-status (Tools) Git dashboard renders the storage snapshot and recent history Yes
Embedded Git: fetch/pull git-pull (Tools) Pull progress/cancel control; fetch is the receive phase of the typed pull Yes
Embedded Git: push git-push (Tools) Push progress/cancel control Yes
Embedded Git: sync and conflicts git-sync (Tools) Sync progress plus per-path local/remote conflict choices Yes
Desktop command discovery and pane navigation command-palette, toggle-pane-focus (View) Toolbar search, Tab focus transfer, arrows/Home/End/Enter navigation The palette opens itself by shortcut/control and is intentionally not a result
Desktop text editing undo, redo, cut, paste (Edit) Platform text controls own these standard operations; the shared registry explains why app-level dispatch is disabled Listed with its current availability
Window/application lifecycle about, close-window, quit, minimize (IronStorage/File/Window) Standard native roles on macOS and equivalent in-window actions elsewhere Yes except native-only minimize behavior where the OS owns the role
Help and current shortcuts help (Help) Labelled, scrollable Help view generated from the action registry Yes

The CLI/TUI expose a few terminal-shaped selectors rather than separate domain capabilities. Generic show --qrcode, OTP version output, arbitrary embedded Git plumbing, and shell completion are therefore not duplicate desktop actions. The desktop viewer already renders an ordinary field, OTP version compatibility belongs to storage/CLI metadata, Git initialization and commits occur within typed storage mutations, remote configuration is shared Settings, and desktop command discovery is the palette. Git history and conflict resolution are controls inside git-status rather than separate commands. These are deliberate presentation differences, not storage-feature gaps.

Interaction and accessibility evidence

  • Keyboard-only operation uses Tab between panes, arrows/Home/End/Enter within trees, fields, menus, and palette results, Escape to dismiss, and registered accelerators. The same controls are mouse/touch activatable; sidebar context actions also accept a secondary click.
  • Both panes are independently scrollable, the divider is resizable, action rows wrap, long names and storage-grouped multiline values are retained, and the supported narrow window floor is 480 by 360 logical pixels. Iced/winit applies native display scaling before layout.
  • Compact toolbar controls use one 16-by-16 vector icon system with descriptive delayed tooltips and registered shortcuts. Focused/selected rows use the theme's primary contrast pair; field labels remain visible as a non-colour cue.
  • The app implements no animation or motion-driven state transition. The one- second subscription updates lease, OTP, Git, and clipboard presentation state without moving focus or renewing authentication, so reduced-motion mode has no additional transition to disable.
  • Iced 0.14 does not expose a stable application API for supplying a native screen-reader accessibility tree. Controls therefore have complete visible labels and deterministic keyboard focus, but native screen-reader role/name integration is an explicit framework limitation rather than a silent stub.

Platform menu and workflow smoke contract

conventional_shortcuts_resolve_on_every_supported_platform executes the Command-versus-Control mapping for macOS, Linux, and Windows on every test host. The macOS-only native adapter test verifies its native accelerators. Linux and Windows use the same action registry through the in-window menu, so its labels, enablement, palette dispatch, and workflow state tests are platform-neutral.

Native equivalent runners use stable Rust and run from the repository root:

cargo test --package ironstorage-desktop --all-targets
cargo check --package ironstorage-desktop --all-targets
cargo run --package ironstorage-desktop

For the final smoke step on each native host:

Platform Menu/accelerator smoke Primary workflow smoke
macOS System App/File/Edit/View/Entry/Tools/Window/Help menus; Command-O/S/F/K/L, Tab, F1 Open a test vault, unlock/view/edit/save, search, Git refresh, OTP code/copy, lock, close
Linux In-window menus; Ctrl-O/S/F/K/L, Tab, F1 Same sequence under X11 or Wayland with the desktop portal available
Windows In-window menus; Ctrl-O/S/F/K/L, Tab, F1 Same sequence with the native folder picker and Windows secure store available

The automated state tests use temporary real encrypted stores and cover the same primary workflows without retaining a GUI password or starting a helper. Native picker, clipboard, secure-store, and actual screen-reader integration remain native-host smoke checks because CI cannot emulate those OS services.

Security and architecture audit

Risk Enforced behavior and executable evidence
Plaintext lifetime and persistence Entry/OTP values use storage SecretBytes or zeroizing edit buffers. Lock, expiry, vault switch, and stale completion paths drop the editor and sensitive presentation state. The source audit rejects desktop filesystem writes.
Authenticated values, errors, and diagnostics Storage supplies sensitivity and redacted typed errors. Viewer/editor tests require every field to remain visible until lock or lease expiry; malformed and non-UTF-8 fields remain lossless. Desktop messages are not Debug, and the source audit rejects print/debug/log-style output.
Clipboard NativeClipboardManager owns timeout and replacement-safe cleanup. Desktop state shows a live remaining-seconds value, cancels cleanup on lock, and ignores stale completions.
Authentication expiry Storage authentication leases own the clock and policy. Passive ticks, rendering, pointer movement, and window events do not renew activity; deterministic tests cover expiry during protected state.
Dirty documents and conflicts Every entry/vault/window/Git worktree replacement routes through one Save/Discard/Cancel decision. Failed saves and conflicts keep the complete draft.
Background and window lifecycle Generation counters reject stale asynchronous results. Lock cancels Git/clipboard work and clears OTP, QR, URI, entry, and editor state. Close and quit use the same dirty guard.
Repository and domain ownership The executable source audit rejects repository/Git construction, process launch, OTP/QR parsing, filesystem writes, unsafe blocks, and non-HTTPS literals in production desktop modules. The folder picker may read only a user-selected QR image; all password-store I/O remains in crates/storage.

Run the complete repository gate after the desktop-specific checks:

cargo fmt --all -- --check
RUSTFLAGS="-D warnings" cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace