Commit Graph

232 Commits

Author SHA1 Message Date
adlee-was-taken
4851857070 feat(ext/settings): settings-security.ts three-state recovery QR + devices component
- Add settings-security.ts with renderSecuritySection / teardownSecuritySection
- Three states: amber warning (no QR), green status (QR set up), modal overlay (show/print SVG)
- Device list with inline revoke; passphrase collected via prompt()
- QR payload never written to chrome.storage; only recovery_qr_generated_at timestamp stored
- Add generate_recovery_qr / unwrap_recovery_qr message types to messages.ts + POPUP_ONLY_TYPES
- Add SW handlers in popup-only.ts delegating to wasm_generate_recovery_qr / wasm_unwrap_recovery_qr
- Declare wasm_generate_recovery_qr and wasm_unwrap_recovery_qr in wasm.d.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 21:06:43 -04:00
adlee-was-taken
3021ef9d9f feat(ext/vault): sidebar logo before "Relicario" wordmark
Renders the 16-optimized SVG (icons/relicario-logo-16.svg) inline
before the brand text in .vault-sidebar__header. Sized to 20×20 px
with flex-shrink: 0 so it survives narrow-pane wraps. The header
already had display: flex + gap: 8px, so the layout absorbed the new
element without further changes. Popup surface is untouched (this
override is scoped to .vault-sidebar__header .brand-logo).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 18:53:09 -04:00
adlee-was-taken
4e9d834920 feat(ext/setup): hand off completion to fullscreen vault tab (P2)
After successful device registration (state.configPushed = true), the
wizard now opens vault.html in a new tab and closes the setup tab.
Both create-new and attach-existing flows funnel through the same
finishSetup() handler. Closing the setup tab is best-effort --
chrome.tabs.remove failures don't block the vault open.

Add src/__stubs__/relicario_wasm.stub.ts + vitest.config alias so
setup.ts can be imported in unit tests without the runtime WASM file.
Exclude the stubs dir from the webpack/tsc build in tsconfig.json.
2026-05-02 19:15:35 -04:00
adlee-was-taken
631e9af470 fix(ext/login): constrain lower form sections to .form-grid envelope (P3)
Notes, custom-fields disclosure, attachments disclosure, and form-actions
in fullscreen logins now sit inside a .form-lower wrapper with the same
max-width: 960px; margin: 0 auto envelope as .form-grid above. Removes
the visual rhythm break at the 2-col -> full-width transition.

Popup keeps its current single-column behavior (gated on surface flag).
2026-05-02 19:07:33 -04:00
adlee-was-taken
b2fc56709a feat(ext/settings): Display section with color pickers + swatch + reset
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 19:03:23 -04:00
adlee-was-taken
b928ed407b feat(ext): apply color scheme on popup + vault startup
Import applyColorScheme in popup.ts and vault.ts, await it at boot,
and register a chrome.storage.onChanged listener so live color-picker
changes take effect without a reload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 18:55:28 -04:00
adlee-was-taken
6bca0b3526 feat(ext/popup/item-detail): colorize revealed password field
Add data-field-kind attribute to renderConcealedRow so wireFieldHandlers
can distinguish password fields from other concealed rows (TOTP secrets,
CVV, PIN, private keys). Apply colorizePassword() on reveal when kind is
"password"; plain textContent otherwise. Pass kind through renderSections
for custom-section password fields.
2026-05-02 18:49:56 -04:00
adlee-was-taken
f45c275566 feat(ext/generator): colorize live password preview 2026-05-02 18:49:56 -04:00
adlee-was-taken
3e4312ca6f feat(ext/popup/field-history): colorize revealed password entries
Import colorizePassword and post-process .revealed value cells after
innerHTML render, replacing escaped-HTML text with colored spans via
the valueStore plaintext lookup.
2026-05-02 18:47:12 -04:00
adlee-was-taken
518b41e9cd style(ext): add password-coloring CSS rules + custom property defaults 2026-05-02 17:19:06 -04:00
adlee-was-taken
1de7cda1b0 feat(ext/shared): add colorizePassword utility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:17:05 -04:00
adlee-was-taken
25c9eb52a0 feat(ext/shared): color-scheme storage + applyColorScheme
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 16:49:03 -04:00
adlee-was-taken
2df636e454 fix(ext/login): dispatch input event after regenerate sets password (B1)
Programmatic input.value = newPassword does not fire input events, so
the strength-meter listener at shared/form-affordances/password-tools.ts:65
never re-rates the new value — meter stays stuck on the prior reading.

Extract applyGeneratedPassword(input, value) helper that sets value, type,
then dispatches new InputEvent('input', { bubbles: true }). Vitest covers
the dispatch + a sanity check that bubbling listeners fire.
2026-05-02 16:46:06 -04:00
adlee-was-taken
575343dc19 refactor(ext/vault): event delegation for error-cta + CSS variable consistency 2026-05-02 16:41:39 -04:00
adlee-was-taken
1c641b4911 fix(ext/vault): friendly error block in fullscreen tab (closes B2)
Replaces raw escapeHtml(state.error) renders with lookupErrorCopy()-driven
title/body/CTA blocks. vault_locked specifically gets an 'Unlock vault'
CTA that refocuses the passphrase input. Other CTAs route to setup.html
or chrome.runtime.reload().

Closes B2; concludes P4.
2026-05-02 16:37:16 -04:00
adlee-was-taken
214e1e49f8 test(ext/shared): pin fallback title assertion in error-copy test 2026-05-02 16:30:09 -04:00
adlee-was-taken
648dcf386e feat(ext/shared): centralize error-message copy in ERROR_COPY map
Replaces the popup's regex-chain humanizeError with a total lookup over
every error code returned by extension/src/service-worker/router/. A
generated test discovers codes via grep so the registry can't drift.
The popup keeps its small set of regex translators for Rust/serde error
phrasing that doesn't go through the router's error vocabulary.

Subsumes B2 — fullscreen consumer lands in the next commit.
2026-05-02 16:26:01 -04:00
adlee-was-taken
f1c615c0ed feat(ext/vault): fullscreen form header with dirty-state subtitle
Title left ('new login' / 'edit login'), subtitle below cycles between
'no changes' and 'unsaved · esc to cancel' on input events. Right side
shows the platform-aware save hint ('⌘+S to save' / 'Ctrl+S to save').
The actual ⌘+S keymap arrives in Phase 3 — this is a visual hint only.
2026-05-02 15:06:42 -04:00
adlee-was-taken
b270dfedb4 feat(ext/vault): sticky save bar in fullscreen forms
The form pane gets a flex column layout: scrollable content above,
sticky save bar at bottom. Bar uses translucent fill with backdrop-blur
and a 24px gradient fade so content scrolls under it. Save / cancel
buttons reuse the form's existing handlers via externalActions flag.
2026-05-02 15:05:09 -04:00
adlee-was-taken
a28b456191 feat(ext/login): add surface flag for two-column fullscreen form
renderForm() takes an optional { surface: 'popup' | 'fullscreen' }
parameter. When 'fullscreen', the Identity and Credentials field
groups render as glass cards inside a .form-grid (two columns,
stacks at <=720px). Popup keeps its single-column layout.
2026-05-02 15:01:35 -04:00
adlee-was-taken
058a49f68b style(ext/vault): apply .surface-backdrop to fullscreen body
Subtle radial top-glow + grid texture behind the existing vault shell.
No layout changes — existing panes sit above the backdrop's ::before.
2026-05-02 14:55:37 -04:00
adlee-was-taken
97e351fa61 feat(ext/setup): apply polish vocabulary to setup wizard
- Wraps setup content in .surface-backdrop
- Each wizard step gets a .glass card
- Mode-picker cards become glass cards
- 'next' / 'continue' buttons get the ▸ glyph
- Migrate from .btn .btn-primary to the new .btn-primary class
2026-05-02 14:52:14 -04:00
adlee-was-taken
7371eff0bb feat(ext/popup): polish unlock view with logo lockup + glass card
Restructures the unlock screen so the form sits in a glass card with
a primary 'unlock vault' button. Logo, brand, and tagline are grouped
as a lockup. Open-vault and settings are demoted to secondary buttons.
Body gets the .surface-backdrop wrapper.
2026-05-02 14:21:04 -04:00
adlee-was-taken
308ef2c974 feat(ext): add GLYPH_NEXT and replace ASCII arrows with ▸
Replaces the ASCII rightwards arrow → with U+25B8 ▸ in settings-vault
buttons. Matches the existing ▾/▸ disclosure-glyph family.
2026-05-02 14:17:55 -04:00
adlee-was-taken
60d7c074c3 style(ext): add .btn-primary and .btn-secondary classes
Two-tier button hierarchy. .btn-primary uses patina gold fill; .btn-secondary
is a ghost button with muted border. Existing .btn class kept for
backwards compatibility.
2026-05-02 13:33:18 -04:00
adlee-was-taken
91536ee50d style(ext): add .glass card class
Translucent fill, soft border, inner highlight, drop shadow. Used for
the unlock card, setup step cards, and form section panels.
2026-05-02 13:32:55 -04:00
adlee-was-taken
da61529de6 style(ext): add .surface-backdrop class
Subtle radial top-glow + 18px grid texture. Used as the backdrop for
the login popup, setup wizard, and fullscreen vault shell.
2026-05-02 13:32:39 -04:00
adlee-was-taken
7370f119ee style(ext/vault): add patina palette tokens
Mirrors popup/styles.css token block so the two surfaces share a
consistent color vocabulary.
2026-05-02 13:31:33 -04:00
adlee-was-taken
479e5848f5 style(ext/popup): add patina palette tokens
Replaces bright amber #d2ab43 with patina gold #a88a4a as the new base.
Keeps --accent as alias for backwards compatibility. Adds --bg-card
and --border-soft for upcoming glass card class.
2026-05-02 13:29:22 -04:00
adlee-was-taken
d6d07a19c1 docs(spec): expand Phase 2B to polish foundation + form layout
Bundles patina palette shift, logo update (translucent gradient gem),
glass-card vocabulary across login/setup/fullscreen, and the original
two-column form layout. Updates relicario-logo.svg and -16.svg to the
patina palette.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 13:19:54 -04:00
adlee-was-taken
d0047e751f fix(ext): capitalize Relicario in Firefox manifest, bump to 0.2.0
The Chrome manifest was already updated; the Firefox manifest still
showed lowercase 'relicario' as the extension name and was pinned at
0.1.0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 13:02:01 -04:00
adlee-was-taken
c67d484152 feat(extension): update devices UI for new auth model
- Show revoked devices in collapsible section with strikethrough styling
- Fetch revoked.json via new list_revoked message + router case
- Registration flow uses register_device WASM API (private keys internal)
- Display revoked_by and timestamp for each revoked entry
- Update setup wizard to use new register_device API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 12:29:31 -04:00
adlee-was-taken
520f6ec72c feat(extension): update devices.ts for revoked.json + deploy keys
- Add createDeployKey/deleteDeployKey to GiteaHost
- Add RevokedEntry interface and readRevoked() to devices.ts
- Update revokeDevice() to write revoked.json alongside devices.json
- Update router to use new register_device WASM API (private keys internal)
- Pass revokedBy device name when revoking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 12:27:14 -04:00
adlee-was-taken
9845febb74 feat(extension): update wasm.d.ts for secure device API
New WASM bindings that keep private keys internal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 12:26:13 -04:00
adlee-was-taken
315967f4a1 Merge feature/fullscreen-ux-phase-2a: smart-input affordances
Phase 2A of the fullscreen UX redesign — 8 form-level smart-input
affordances (URL fill-from-tab + hostname chip, group autocomplete,
password reveal + strength bar, TOTP live preview + QR decode, notes
monospace toggle), shared between popup and fullscreen vault tabs via
the new extension/src/shared/form-affordances/ module set.

CLI parity:
- relicario rate <passphrase> (zxcvbn score / guess estimate)
- relicario completions <SHELL> (bash/zsh/fish via clap_complete)
- --group <TAB> dynamic enumeration via .relicario/groups.cache
  (plaintext leak surface; opt out with RELICARIO_NO_GROUPS_CACHE=1)
- --totp-qr <path> on add login + edit (rqrr decode)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 22:37:18 -04:00
adlee-was-taken
b450ecd1cc ext(login): wire 8 smart-input affordances into renderForm()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 22:32:14 -04:00
adlee-was-taken
e6eb698c4c ext(affordances): wireNotesMonoToggle with chrome.storage.local persistence 2026-05-01 22:23:56 -04:00
adlee-was-taken
bd8102c9ad ext(affordances): wireTotpQr (jsqr lazy-load) for QR -> otpauth:// fill
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 22:14:05 -04:00
adlee-was-taken
c91b31a7ca ext(affordances): wireTotpPreview live ticker 2026-05-01 19:56:55 -04:00
adlee-was-taken
bb8b86f0d5 ext(sw): add preview_totp_from_secret popup handler 2026-05-01 19:55:24 -04:00
adlee-was-taken
7bd1a9dd7d ext(affordances): wirePasswordStrength via scheduleRate
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 19:50:18 -04:00
adlee-was-taken
026b94092e ext(affordances): wirePasswordReveal toggle 2026-05-01 19:48:32 -04:00
adlee-was-taken
e452d8df02 ext(affordances): wireGroupAutocomplete via <datalist> 2026-05-01 18:09:33 -04:00
adlee-was-taken
5fbdd30a19 ext(sw): add list_groups popup handler 2026-05-01 18:08:34 -04:00
adlee-was-taken
61dbb4d3a3 ext(affordances): wireHostnameChip with debounced URL parse 2026-05-01 18:06:15 -04:00
adlee-was-taken
8eff96da9d ext(affordances): tighten FillFromTabOpts.sendMessage return type 2026-05-01 17:54:57 -04:00
adlee-was-taken
39ae2ecbf3 style: capitalize "Relicario" in prose / UI / CLI help
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>
2026-05-01 17:29:10 -04:00
adlee-was-taken
4be0bcff83 ext(affordances): wireFillFromTab + .glyph-btn CSS 2026-05-01 17:07:01 -04:00
adlee-was-taken
918fdef519 ext(sw): expand active-tab URL filter; isolate chrome stub in tests
Expand get_active_tab_url protocol filter regex to include view-source:,
data:, devtools:, and other browser-internal/extension contexts that would
misbehave if autofilled. Add third regression test for view-source: URLs.

Wrap get_active_tab_url tests in dedicated describe block with beforeEach/
afterEach to snapshot/restore globalThis.chrome, preventing stub leakage
between tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 17:01:36 -04:00
adlee-was-taken
f872ab5183 ext(sw): add get_active_tab_url popup handler 2026-05-01 16:57:18 -04:00