0a3372c151892cac5df18b1637b136a5db66b5a3
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
39406d712e |
feat: Ctrl+Shift+Q quick-search-fill + Edge browser directive
Ctrl+Shift+Q quick-search + autofill
- New global hotkey: capture the foreground HWND, restore the window
if hidden, pop the quick-search modal in "fill mode". On pick, the
password is SendInput'd into the saved HWND — no clipboard touch.
- hide_after flag added to cmd://autofill/execute: when set (tray-mode
hotkey), Delphi MinimizeToTray's *after* SendInput completes. Hiding
before SendInput would trip Win10/11 anti-focus-stealing rules and
block focus handoff to the target.
- Quick-search modal hint text adapts to fill vs copy mode.
- Esc / close in fill mode sends cmd://autofill/cancel so a stale
HWND doesn't get reused by an unrelated Ctrl+Shift+L later.
Compile-time browser engine switch
- {.$DEFINE USE_EDGE_BROWSER} in UMainForm.pas selects between
TTMSFNCWebBrowser (default, cross-platform abstraction) and
TTMSFNCEdgeWebBrowser (Windows-only WebView2 wrapper). Both
inherit from TTMSFNCCustomWebBrowser so the bridge cmd:// glue is
unchanged; the field type is a conditional alias TWebBrowserClass.
- WebBrowser is created dynamically in FormCreate so neither variant
needs a second .fmx. Events are wired BEFORE Parent assignment so
OnInitialized doesn't race the WebView2 async init on fast/pre-warmed
Edge installs (was silently missing the disable-context-menu /
disable-accelerator-keys calls).
- Native context menu disabled by assigning an empty PopupMenu1 (works
for both backends, unlike OnGetContextMenu which is publish-gated
via {$IFNDEF FNCLIB} on TTMSFNCWebBrowser).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
f047fba9a3 |
feat: tray quick-search + privacy hardening + race fixes
Quick search from tray - New "Quick search…" entry in the tray context menu (between Open and Lock vault). - Compact modal with live-filtered top-8 entries, arrow keys / Enter to copy the password (Shift+Enter copies the username instead), Esc to dismiss. Each row shows the favicon when cached. - Locked vault → focus the master password input instead of opening the modal (same pattern as the locked-autofill-hotkey path). - Window-state restore: Delphi remembers whether the window was hidden before the menu was opened and tells JS via the Bridge.openQuickSearch(wasHidden) arg. After the copy (or cancel) we hide back to the tray so the previously-foreground app comes back and Ctrl+V drops the password in. Tray notifications toggle - New Settings → Security "Show tray notifications" toggle. Gates Shell_NotifyIcon NIF_INFO balloons (currently only the "still running in the tray" first-time popup). Default ON, synced via settings_json so it follows the user across devices. - PM.Bridge.ShowNotifications exposed as a public property; JS pushes the value on every settings sync. Privacy: WebView2 phone-home killed - WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS set in the unit initialization section (before the TMS WebBrowser instantiates its CoreWebView2Environment). Disables: background networking, sync, component updates, breakpad/crashpad, domain reliability, client-side phishing detection, experiments, UMA upload, MediaRouter, OptimizationHints, SafeBrowsing enhanced, autofill server, privacy sandbox APIs. Verified via Resource Monitor: only 127.0.0.1 connections remain (plus DDG when favicons are on). Fixes - Blank-window-on-launch race: the 1.5 s navigation timer assumes WebView2 finishes init in time, but on slow machines Edge Chromium needs 2-3 s and the Navigate() call is silently dropped. WebBrowserInitialized now also navigates if a URL is still pending — first to run wins. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
40b3154a34 |
feat: MFA tools, single-instance, tray polish, prefs persistence
Session highlights:
- feat(prefs): DPAPI-backed key/value store (PM.UserPrefs) — fixes
rememberedUsername being lost across reboots due to the random
ephemeral HTTP port changing the localStorage origin every launch.
Bridge cmd://prefs/{get,set} round-trips through Delphi.
- feat(tray): icon visible from startup (NIM_ADD at constructor, not
at first minimize). Tray context menu themed via uxtheme!135
SetPreferredAppMode so it follows the app's dark/light setting.
- feat(single-instance): named mutex + RegisterWindowMessage broadcast.
Second launch posts WM_PMSHOW to HWND_BROADCAST and exits; the
running bridge restores the window from tray. Mutex lives in Local\
namespace so distinct Windows users can still each run one.
- feat(mfa): Authenticator sidebar view (live TOTP codes for every
entry with a secret) + standalone TOTP generator modal (paste
base32 / otpauth:// URI, or generate a random 20-byte secret).
- feat(sidebar): Folders / Tags / Tools sections collapsible with
chevron toggle. Badge counts stay visible when collapsed. State
persisted in settings_json (synced across devices).
- feat(autofill): hotkey when vault is locked now restores the app
and focuses the master password input instead of no-op'ing
silently. Cleaner UX for the common "I hit Ctrl+Shift+L but the
vault was locked" path.
- feat(quick-unlock): when enabled, skip lockVault on Windows lock /
sleep. Rationale: the DPAPI blob already gates access via the
Windows account, so re-locking on top of the OS lock is redundant.
Idle auto-lock still fires (separate opt-in).
- fix(quick-unlock): re-sync state.quickUnlockEnabled from DPAPI
source-of-truth at boot, instead of trusting (now-volatile)
localStorage.
- docs: CLAUDE.md updated with all new modules, bridge commands,
and the port-ephemeral pitfall.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
506aee7e6f |
feat: Delphi backend + JS↔Delphi bridge (clipboard, tray, auto-lock)
Introduces the Delphi 12 FMX backend (PMServer) that hosts the embedded
WebView2 vault on 127.0.0.1, and a native bridge between JS and Delphi
that wires three privacy-focused features:
1. Secure clipboard
Copying a password registers the Win32 "ExcludeClipboardContentFromMonitorProcessing"
format alongside CF_UNICODETEXT, so Win+V clipboard history never sees
the value. Auto-clears after 30s via TTimer. Bridge.copySecure() in
app.js routes all password/username/secret copy paths through the
native layer when running inside the Delphi WebView2 (falls back to
navigator.clipboard for the PHP standalone).
2. Tray icon (X-to-tray when server running)
Closing the dev panel hides both the form HWND and the TFMAppClass
per-process proxy window that owns the FMX taskbar entry — the form's
HWND alone is not the taskbar-visible one in FMX (took some iteration
to discover). Tray menu: Open, Lock vault, Quit. Clipboard is force-
cleared on minimize as extra safety. First-time minimize fires a
balloon notification so the user knows the app is still running.
3. Auto-lock on Windows session lock (Win+L)
wtsapi32.dll!WTSRegisterSessionNotification on a dedicated message-only
window. On WM_WTSSESSION_CHANGE / WTS_SESSION_LOCK, the bridge calls
ExecuteJavaScript('lockVault()'). Same path used by the tray "Lock vault"
menu item.
Bridge architecture:
- JS → Delphi via cmd:// URLs intercepted in OnBeforeNavigate
(pattern lifted from DeskInsight Monaco). Currently exposes
cmd://clipboard/copy?text=...&clear=... and cmd://clipboard/clear.
- Delphi → JS via TTMSFNCWebBrowser.ExecuteJavaScript with guarded
calls (typeof check) so the bridge degrades cleanly if app.js isn't
loaded yet.
Files:
- Source/PM.Bridge.pas (new) — TSecureClipboard + TPMBridge
- UMainForm.pas/.fmx — bridge wiring, FormCloseQuery intercept, tray
callbacks (BridgeTrayRestore / BridgeLockRequest / BridgeQuit)
- js/app.js — Bridge object, 5 navigator.clipboard sites migrated to
Bridge.copySecure with PHP-compatible fallback, Bridge.onTrayRestore
handler that resets the auto-lock timer
.gitignore extended with Delphi build artifacts (*.dcu, Win32/, Win64/,
__history/, __recovery/, *.identcache, *.dsk, *.local, etc.) so source
checkouts stay clean.
|