- hypr/apps.lua - hypr/autostart.lua - hypr/envs.lua - hypr/hyprland.lua - hypr/hyprsunset.conf - hypr/input.lua - hypr/looknfeel.lua - hypr/omasettings.lua - hypr/xdph.conf - omarchy/branding/about.txt - omarchy/branding/screensaver.txt - omarchy/extensions/omarchy-menu.jsonc - omarchy/hooks/battery-low.d/play-warning-sound.sample - omarchy/hooks/font-set.d/show-font-notification.sample - omarchy/hooks/post-boot.d/weather.sample - omarchy/hooks/post-update.d/install-voxtype.hook - omarchy/hooks/post-update.d/setup-agent.hook - omarchy/hooks/post-update.d/setup-fingerprint.hook - omarchy/hooks/post-update.d/show-update-notification.sample - omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample - omarchy/hooks/theme-set.d/show-theme-notification.sample - omarchy/shell.json - omarchy/shell.toml - omarchy/theme.name - omarchy/themes/azure-glow/README.md - omarchy/themes/azure-glow/alacritty.toml - omarchy/themes/azure-glow/btop.theme - omarchy/themes/azure-glow/hyprland.conf - omarchy/themes/azure-glow/hyprlock.conf - omarchy/themes/azure-glow/icons.theme - … 269 more
116 lines
4.9 KiB
Markdown
116 lines
4.9 KiB
Markdown
# Spec: Centered SSH Approval Popup
|
|
|
|
Status: implementation approved by the feature request
|
|
|
|
## Objective
|
|
|
|
Add an opt-in SSH authorization surface that appears in the center of the
|
|
active bar output instead of opening the Bitwarden panel. A locked vault first
|
|
shows a clear unlock-required state and the configured unlock controls; after
|
|
unlocking, the same transient surface changes to the existing SSH signing
|
|
approval. The surface disappears as soon as the request is answered,
|
|
cancelled, or expires.
|
|
|
|
## Tech Stack
|
|
|
|
- QML/Qt 6 with Quickshell 0.3.1 and Omarchy 4.0.2.
|
|
- The existing `Panel` root remains the owner of vault, SSH-helper, request,
|
|
deadline, cooldown, and unlock state.
|
|
- A Quickshell `PanelWindow` on the Wayland overlay layer presents the centered
|
|
surface on the bar widget's output.
|
|
- No new dependency or helper protocol message is introduced.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
node tests/ssh-agent-setup.test.js
|
|
node tests/ssh-agent-ui.test.js
|
|
for test_file in tests/*.test.js; do node "$test_file" || exit 1; done
|
|
env -u DISPLAY -u WAYLAND_DISPLAY -u QT_QPA_PLATFORMTHEME \
|
|
QT_QPA_PLATFORM=offscreen /usr/lib/qt6/bin/qmltestrunner -input tests/qml
|
|
mkdir -p /tmp/qs-imports
|
|
ln -sfn /usr/share/omarchy/shell /tmp/qs-imports/qs
|
|
/usr/lib/qt6/bin/qmllint -I /tmp/qs-imports Panel.qml SshApprovalPopup.qml SshApprovalScreen.qml SshUnlockScreen.qml
|
|
omarchy plugin validate .
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
- `Panel.qml`: owns request routing, vault state, unlock actions, and setting
|
|
values.
|
|
- `SshApprovalPopup.qml`: owns only the centered window, focus, and dismissal.
|
|
- `SshApprovalScreen.qml`: reusable authorization content for panel and popup.
|
|
- `SshUnlockScreen.qml`: popup unlock-required status and unlock controls.
|
|
- `BitwardenModel.js` / `manifest.json`: setting contract and safe default.
|
|
- `tests/`: static integration and pure model tests; `tests/qml/`: QML tests.
|
|
|
|
## Code Style
|
|
|
|
Keep presentation declarative and authorization imperative in `Panel.qml`:
|
|
|
|
```qml
|
|
SshApprovalPopup {
|
|
panel: root
|
|
anchorItem: button
|
|
}
|
|
```
|
|
|
|
All request-derived text uses `Text.PlainText`. Use Omarchy spacing, color,
|
|
border, typography, input, and button components rather than custom values.
|
|
|
|
## Testing Strategy
|
|
|
|
- Add failing contract tests for the new setting in both manifest and model.
|
|
- Add failing wiring tests proving popup mode does not call `root.open()`, the
|
|
legacy mode still does, and unlock transitions reuse the same pending
|
|
request.
|
|
- Lint every new QML component against the installed Omarchy imports.
|
|
- Run the full JavaScript and QML suites before handoff.
|
|
- Runtime acceptance requires an enabled development plugin, a locked vault,
|
|
and a real SSH signing request; no real credentials belong in tests or logs.
|
|
|
|
## Boundaries
|
|
|
|
- Always: keep the setting false by default; deny on Escape, outside click,
|
|
cancellation, and timeout; render request metadata as plain text; clear
|
|
transient unlock input when the popup closes.
|
|
- Ask first: changing helper authorization, request deadlines, cooldown rules,
|
|
credential storage, or the SSH control protocol.
|
|
- Never: put session tokens, passwords, private keys, payloads, or signatures
|
|
in popup-local persistent state, command arguments, logs, or fixtures.
|
|
|
|
## Threat Model
|
|
|
|
- Request key/process labels cross from a same-UID client through the helper
|
|
and are untrusted display data. Plain-text rendering prevents markup from
|
|
becoming UI.
|
|
- The overlay is presentation, not an authorization boundary. Existing helper
|
|
request IDs, epochs, deadlines, peer checks, and final authorization checks
|
|
remain authoritative.
|
|
- The desktop lock-state gate remains ahead of both panel and popup prompts.
|
|
- The master password and recovered PIN/fingerprint password continue through
|
|
the existing bounded private-FIFO path and are scrubbed by existing process
|
|
cleanup.
|
|
- A popup must never approve from a bare Enter key; denial is the default
|
|
focused action.
|
|
|
|
## Success Criteria
|
|
|
|
- `sshAgentApprovalPopup` is a boolean setting, disabled by default.
|
|
- With it disabled, SSH unlock and approval requests behave exactly as before.
|
|
- With it enabled, an SSH request does not open or navigate the anchored panel.
|
|
- A locked vault shows why it must be unlocked and offers configured PIN,
|
|
fingerprint, and master-password paths without duplicating auth logic.
|
|
- A successful unlock changes the same centered surface to the signing prompt,
|
|
including key, fingerprint, requesting program, deadline, and grant option.
|
|
- Deny, approve, cancellation, timeout, and outside click remove the surface;
|
|
a panel the user already opened remains where it was.
|
|
- The centered window uses the bar widget's output, stays within the output at
|
|
narrow sizes, follows the Omarchy theme, and is fully keyboard operable.
|
|
|
|
## Open Questions
|
|
|
|
None for implementation. Full account login remains a panel workflow; the
|
|
popup is intentionally limited to a signed-in but locked vault and SSH signing
|
|
authorization.
|