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.
13-task plan to land patina palette, polish vocabulary (.surface-backdrop,
.glass, .btn-primary/secondary, ▸ arrow glyph), restructured login popup,
setup wizard polish, two-column login form, sticky save bar, and dirty-
state header subtitle.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
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>
Two-column CSS Grid for login forms, sticky save bar, and dirty-state
header subtitle. Other item types stay single-column with the polish
applied. Stacks to single column at <=720px viewport.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 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>
- register_device() generates signing + deploy keypairs via core device
module, stores them in DEVICE_STATE (once_cell Lazy<Mutex>), and
returns only public keys to JS
- sign_for_git() signs data using the internal signing key
- get_device_info() returns name and public keys; returns null if not
registered
- clear_device() zeroes and drops device state (logout / re-registration)
- Removed generate_device_keypair() which exposed raw private key bytes
Fixes audit I5: private key material no longer crosses the WASM boundary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
- Remove device from devices.json
- Append to revoked.json with timestamp and revoked_by
- Delete Gitea deploy key (best-effort, warns if env vars missing)
- Always commit both devices.json and revoked.json together
- Print revoked signing public key for audit confirmation
- Guard against revoking the current device (would lose push access)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- verify-commit command checks signature against devices.json
- generate-hook outputs installable pre-receive script
- Foundation for server-side enforcement
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
OpenSSH-format keypair generation, signing, and verification.
Foundation for device authentication.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Clarifies what AEAD protects (tampering) vs. what it doesn't (deletion,
rollback). Documents that git history is the audit trail and device
authentication is the mitigation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
per_vault_soft_cap_bytes and per_vault_hard_cap_bytes were defined in
VaultSettings but never checked. Now enforced in cmd_attach with
warning at soft cap, error at hard cap.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Control characters (newlines, tabs) in item titles corrupted git log
output. Now strips control chars and truncates to 50 chars.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Crafted .relbak files with IDs like "../../.bashrc" could escape the
target directory. Now validates that item/attachment IDs are hex-only
via is_valid() before any fs::write.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
RELICARIO_TEST_PASSPHRASE and friends were checked in production code,
exposing the passphrase via /proc/<pid>/environ and shell history.
Now only compiled into debug binaries via cfg(debug_assertions) helper
functions. Release builds compile the helpers to return None, so the
env var names are absent from the release binary (verified via strings).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HOTP requires incrementing and persisting the counter after each use.
Without vault-save machinery in compute_totp_code, HOTP would desync
immediately. Now returns HotpNotSupported error.
TOTP and Steam codes continue to work.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- AttachmentId now uses 16 bytes of SHA-256 (128 bits) instead of 8,
requiring ~2^64 work for birthday collision instead of ~2^32.
- Added is_valid() to ItemId and AttachmentId for path traversal
prevention during backup restore.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backup KDF was passing raw passphrase bytes to Argon2id without NFC
normalization, causing cross-platform restore failures for non-ASCII
passphrases (macOS NFD vs Linux NFC).
Now matches derive_master_key behavior from crypto.rs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Codifies the casual-style flourish (1-2 Spanish words/idioms per reply
with [translation] brackets) as a project-level preference so it
survives memory-system refactors. Replies only — never in code, files,
or commit messages.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
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>