Brand name uses capital R in user-facing text — extension UI strings, CLI clap help / descriptions / error prose, markdown docs. Lowercase preserved for the binary command, crate names, npm package, file paths, env vars, and code identifiers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.4 KiB
Vault Tab UI + Session Timeout — Design Spec
Date: 2026-04-27
Scope: New vault.html full-tab UI, shared session timeout, popup↔vault navigation
Problem
Chrome extension popups close when focus leaves them (e.g., file picker dialogs). The popup is also too cramped for complex operations like editing identity/card items, managing attachments, or bulk vault operations. Currently we work around this with popOutToTab() which opens popup.html in a tab — a hack that reuses popup-sized UI in a full window.
Additionally, there's no session timeout — users must re-enter their passphrase every time they interact with the extension.
Design
Two entry points, one shared core
popup.html— quick access: search, copy, autofill, add login/secure_note (without attachments)vault.html— full "desktop" UI in a browser tab: sidebar + detail pane, handles everything including attachments, bulk operations, trash, devices, settings, field history
Both talk to the same service worker, share the same WASM session handle and unlock state.
vault.html layout
Sidebar + detail pane, similar to 1Password's desktop app:
┌──────────────────────────────────────────────────┐
│ 🔒 Relicario [lock] [settings] │
├────────────────┬─────────────────────────────────┤
│ [search...] │ │
│ │ (detail view for selected │
│ ── logins ── │ item, or form when │
│ GitHub 🔑 │ adding/editing) │
│ AWS 🔑 │ │
│ │ │
│ ── notes ── │ │
│ Recovery 📝 │ │
│ │ │
│ │ │
│ │ │
├────────────────┤ │
│ 🗑 trash │ │
│ 📱 devices │ │
│ ⚙ settings │ │
└────────────────┴─────────────────────────────────┘
- Left sidebar (~240px): vault name/lock status at top, search input, item list grouped by type, nav links at bottom (trash, devices, settings)
- Right pane: detail view for selected item, or add/edit form. Empty state when nothing selected.
- URL hash tracks current selection (
#item/abc123,#add/login,#trash, etc.) for browser back/forward
Session timeout
Lives in the service worker, not in any UI. Shared across popup and vault tab.
Timer logic — new session-timer.ts module alongside existing session.ts:
- Holds a
setTimeoutID, reads config fromchrome.storage.local - Resets on every message routed through the SW (any popup or vault tab interaction)
- When it fires: calls
clearCurrent()to zero the WASM handle, then broadcasts{ type: 'session_expired' }viachrome.runtime.sendMessage - Both popup and vault tab listen for this broadcast and show the lock screen
Config shape in chrome.storage.local:
{ "session_timeout": { "mode": "inactivity", "minutes": 15 } }
or:
{ "session_timeout": { "mode": "every_time" } }
Default: { mode: 'inactivity', minutes: 15 }. This is a per-device setting (stored in chrome.storage.local, not in the encrypted vault) since different devices have different risk profiles.
UI for timeout config: In a "device settings" section, a simple toggle:
- "Lock after inactivity" with a minutes dropdown (5, 15, 30, 60)
- "Lock every time" (current behavior)
Changing the setting sends an update_session_config message to the SW which immediately applies the new timer.
Navigation between popup and vault
Popup → vault:
- "Open vault" link on the lock screen and item list toolbar
Shift+Fkeydown listener in popup — opens/focuses the vault tab- When navigating from popup with context (e.g., viewing an item), pass item ID via URL:
vault.html#item/abc123 popOutToTab()now redirects tovault.htmlinstead ofpopup.htmlfor types that need it
Global shortcut:
chrome.commandsmanifest entry (default unbound, user configures inchrome://extensions/shortcuts)- SW listener opens or focuses existing vault tab
Vault → popup:
- Not needed — vault tab is the superset
Shared components
Form renderers (login, secure-note, identity, card, key, totp, document), field helpers, attachments disclosure, generator panel are currently in popup/components/. These get moved to shared/components/ so both entry points can import them.
The popup wrappers conditionally hide attachments (via isInTab()); the vault versions always show everything.
Keyboard shortcuts
| Key | Context | Action |
|---|---|---|
/ |
Popup list, vault sidebar | Focus search |
+ |
Popup list, vault sidebar | New item |
↑↓ |
Popup list, vault sidebar | Navigate items |
Enter |
Popup list, vault sidebar | Open selected item |
Escape |
Popup | Close popup |
Escape |
Vault form/detail | Back to list |
Shift+F |
Popup | Open/focus vault tab |
| Global | Anywhere in Chrome | Open/focus vault tab (user-configured) |
New files
extension/
├── src/
│ ├── vault/
│ │ ├── vault.ts # Entry point, state management, hash routing
│ │ ├── vault-shell.ts # Layout container, sidebar/pane split
│ │ ├── vault-sidebar.ts # Search, grouped item list, nav links
│ │ └── vault-pane.ts # Detail/form/settings renderer
│ ├── shared/
│ │ └── components/ # Moved from popup/components/
│ │ ├── types/ # login.ts, secure-note.ts, etc.
│ │ ├── fields.ts
│ │ ├── attachments-disclosure.ts
│ │ └── generator-panel.ts
│ ├── service-worker/
│ │ └── session-timer.ts # Inactivity timeout logic
│ └── popup/
│ └── components/ # Thin wrappers that import from shared/
├── vault.html # New entry point
└── vault.css # Vault-specific layout styles (imports shared)
What stays in popup
The popup keeps its stacked-view navigation and compact layout. It imports form/detail components from shared/ but wraps them in popup-specific chrome (back buttons, condensed headers). Login and secure_note forms render inline in the popup (without attachments); all other types redirect to vault.html.
Messages
New message types:
update_session_config— popup/vault → SW, updates timeout settingsget_session_config— popup/vault → SW, reads current timeout settings
New broadcast:
session_expired— SW → all extension views, triggers lock screen
Out of scope
- Grouping/tagging/export features (future work, mentioned as eventual goal)
- Mobile-style responsive layout for vault tab
- Theme customization
- Multi-vault support