Commit Graph

3 Commits

Author SHA1 Message Date
r-zakarya b00da43ab0 feat: PIN unlock + table column picker + edit-position chooser + UX
- PIN unlock: device-local 4-12 digit shortcut, DPAPI-wrapped vault
  key. Three modes (state.unlockMode): pw / pin / pw+pin. PIN
  derives a wrap key via PBKDF2(pin, salt, 100k) and unwraps the
  stored vault key (mirrors the Quick Unlock blob shape).
  Anti-brute-force: 5 wrong attempts wipes the blob. Setup gated by
  master-pw reauth so an unattended unlocked laptop can't be
  backdoored. Master pw rotation clears the PIN blob (key drift).
  loadServerSettings post-sync demotes pin/both -> pw when the local
  blob is missing, so a wiped device re-syncs the correct mode up.
  New unit PM.PinUnlock.pas + cmd://pin/{store,get,clear,status}.
- Table column picker: ⚙ in topbar (table view only), checkbox menu
  for Site/Username/Folder/Updated. Site also drives showSiteOnCards
  so the existing "Show site / URL" toggle in Settings stays in
  sync. NAME column auto-widths (180px min, content max, +32px
  right padding) so column hugs the next one without truncating.
- Editor position chooser (Appearance setting): Slide-over right /
  left / Centered modal. Scoped to #slideover + #settingsPanel so
  the click-outside / pointer-events logic doesn't accidentally
  trap the modal-style empty viewport.
- Confirm before discarding unsaved edits: state.confirmOnUnsaved
  setting (default ON), prompts on X / Esc / click-outside / switch-
  to-other-entry. Also gates Lock vault / Sign out actions when the
  editor is dirty; auto-lock and system-lock paths bypass to avoid
  blocking on an unattended machine.
- Open-in-browser button added to the actions cell of the table
  view (was card-only).
- Entry templates pass folder customization + template id through
  duplicate / export / import / auto-backup roundtrips.
- Folder color + icon now persisted across export/import: payload.
  folders carries name/color/icon; import creates missing folders
  additively (existing local customisation kept).
- Bulk move-to-folder, batch add-tag, single add-tag now re-ship
  the full entry payload so partial PUTs don't silently wipe
  TOTP / custom_fields / kind / template.
- FireDAC: switched ftString -> ftMemo for icon_b64 / custom_fields
  / TOTP / template params and replaced .AsString with .Value so a
  large (~200 KB) DeepSeek favicon no longer gets truncated at the
  default ANSI 4000-char cap.
- Unicode filenames: attachment INSERT now uses ftWideString +
  .AsWideString so non-ANSI filenames round-trip instead of being
  mangled to "?".
- HandleSetEntryIcon cap raised 256 KB -> 512 KB chars to accept
  base64 data URIs produced by max-raw favicon fetches.
- promptDialog + askReauth support inline `error` line + retry-
  with-count loops on doExport reauth and auto-backup password
  setup (5 attempts cap before bailing).
- Recently used moved from Tools to Vault section in the sidebar.
- Auth screen passkey button hidden (Delphi backend stubs WebAuthn).
- Sensitive cmd://favicon/refresh-style buttons in Settings now
  stopPropagation so the document-level "close panel" handler
  doesn't dismiss Settings mid-async during DOM reparenting.
- TEST_PLAN.md: +PIN unlock section.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-29 04:41:39 +01:00
r-zakarya e23a78dda7 feat: entry templates + tag autocomplete + slideover push + robustness bundle
- Entry templates: new vault_entries.template column drives a typed
  sub-kind ('credit-card', 'ssh-key', 'server', 'recovery-codes'). Card
  + table label off the template, badge reads "credit card" instead of
  "note". Templates seed kind=note (no site/password required), use
  custom_fields with optional dropdown options (brand, month/year,
  protocol). Round-tripped across export/import/duplicate/master-pw
  rotation, preserved by partial PUTs via a HasTemplate flag.
- Custom fields: support per-field `options[]` rendering as <select>
  (card brand, expiry MM/YYYY, SSH/server protocol).
- Tags: existing-tag autocomplete dropdown under the chip input,
  filtered against what's already selected.
- Search history: per-query X for individual delete + 1s debounced
  commit (no Enter required).
- Slideover: clicking outside closes again (drag-selection respected
  via mousedown origin tracker), Esc closes, X closes. App shell is
  pushed left by 420px when the panel is open so the table / pagination
  / sort / search stay visible and interactive.
- Export/import: JSON now round-trips custom_fields, attachments
  (decrypted to base64, re-encrypted under current key on restore),
  icon_b64, and template. CSV warning lists what's not included.
- Auto-backup: same payload shape as user-driven export.
- Notes: import (JSON + CSV) accepts kind=note with empty site,
  preserves title/template/custom_fields. CSV parser detects kind/
  template columns.
- Bulk-import response returns `ids[]` parallel to input so the
  client can map back to new entry IDs (drives attachment restore).
- Move-to-folder bugs fixed: moveEntryToFolder, batchMoveToFolder,
  addTag, batchAddTag were all silently wiping TOTP / custom_fields
  / kind / template via partial PUT. Now re-ship full payload.
- Master-pw rotation: server mints a fresh session token + csrf so
  the very next request after rotation no longer ESessionRejects.
  Client adopts the new pair. Attachments are re-encrypted client-side
  during rotation (GET old → decrypt with old key → encrypt with new
  → PUT). New endpoints: GET /attachments/all, PUT /attachments/:id.
- Duplicate: carries icon_b64 + template + attachments to the copy.
- HandleCreateEntry: accepts icon_b64.
- FireDAC param fix: all blob/icon/custom_fields params use ftMemo +
  .Value assignment so SQLite TEXT no longer truncates to 4000 chars
  (deepseek's 200+ KB favicon was being wiped on lock/unlock).
- HandleSetEntryIcon cap: 262144 → 524288 chars (base64 of a 256 KB
  raw fetch overflows the old cap, fails silently in saveEntryIcon).
- Native save dialog: surfaces server errors instead of swallowing.
- Modals: reauth (export) + backup-password prompt support inline
  error display, retry up to 5 attempts, then hard-stop.
- Keyboard cursor (j/k): bootstraps to current page, auto-paginates
  when the cursor crosses a page boundary, Enter opens slideover.
- Slideover focuses Title on edit-open so j/k → Enter → type Just
  Works.
- TOTP tool: Esc closes the modal.
- App version + launch mode (auto/manual): exposed via bridge,
  surfaced in Settings → Account. Autostart launches suppress the
  first-time tray balloon.
- Passkey button hidden (Delphi backend stubs WebAuthn at 501).
- TEST_PLAN.md captured for regression coverage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-26 21:20:07 +01:00
Zaki fa7ea191be feat: native save + auto-backup + folder customization + attachments + UX bundle
- File: native Save As dialog via Bridge.saveFile (replaces WebView2
  browser download popup) for encrypted JSON + CSV exports.
- Auto-backup: silent periodic encrypted JSON to a chosen folder,
  user-set interval + retention, separate DPAPI-stored password, runs
  5s after unlock if due. New file/* bridge cmds (folder/pick,
  file/write, file/listMatch, file/delete).
- Folders: per-folder color + icon (8-swatch palette, 8 icon presets),
  drag-reorder via HTML5 DnD with insert-line indicators, edit pencil
  on hover. New POST /folders/reorder + PUT /folders/{name}. Folder
  chip on cards inherits custom icon + color.
- Recently used: vault_entries.accessed_at + POST /entries/{id}/touch
  (debounced 2s), sidebar Tools entry showing top-10 by accessed_at.
- Encrypted attachments: per-entry file storage (5MB cap), AES-GCM
  with vault key, native Save As download, paperclip upload in
  slideover. New entry_attachments table + PM.Handler.Attachments.
- Password expiry: vault_entries.password_changed_at (conditional bump
  via SQL CASE only when ciphertext differs), passwordExpiryDays
  setting, "Aged" badge on cards + matching Filters chip.
- Recovery: Print button on generated code modal (A4 printable sheet
  via @media print, code in 32px monospace + instructions).
- Audit log viewer (sidebar Tools, GET /audit with pagination cursor).
- Plaintext CSV export + Filters dropdown with 9 predicates.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-21 23:12:06 +01:00