Plan B Phase 8 — three #[wasm_bindgen] exports for the parsers migrated
in Phase 7, mirrored in extension/src/wasm.d.ts under "Pure parsers
(no session needed)". snake_case JS naming consistent with every
existing export; SessionHandle not required.
- parse_month_year(s) → { month, year } via js_value_for
- base32_decode_lenient(s) → Uint8Array
- guess_mime(filename) → string
Tests in session_tests mod cover the OK paths; error-path / JsValue
serialization can't be tested natively (JsError construction panics
off-wasm) and is covered in core (time::tests + base32::tests).
Plan C will wire SW message handlers consuming these exports in a
future round; this commit delivers only the seam.
Includes simplify-feedback fixes:
- relicario-core lib.rs module-list mentions base32 and mime
- item_types/totp.rs neighbour comment unified to ///-style block
cargo test --workspace: green
cargo clippy --workspace: silent
cargo build -p relicario-wasm --target wasm32-unknown-unknown: clean
cd extension && npm run test: 17 pre-existing failures only (baseline)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 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>
The wasm-bindgen binding for generate_device_keypair uses
serde-wasm-bindgen and returns a plain JsValue (object), not a JSON
string. Two consumers were calling JSON.parse on it, causing the
runtime error 'SyntaxError: "[object Object]" is not valid JSON' which
broke device registration end-to-end.
Fixes:
- wasm.d.ts: return type now { public_key_hex; private_key_base64 }
matching the rate_passphrase pattern (also a JsValue-returning
binding).
- popup-only.ts (register_this_device handler) and setup.ts (initial
device wire-up): drop JSON.parse, use the object directly.
- router.test.ts: pin the contract — mock generate_device_keypair as a
function returning an object (matching real binding behavior) and
assert register_this_device returns ok and forwards the public key.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add default_vault_settings_json() to the hand-written wasm.d.ts
declarations, then use it in attachStep3New to encrypt and push
settings.enc after manifest.enc during new-vault creation. Wizard-
created vaults now have all four files the SW expects (salt,
params.json, manifest.enc, settings.enc), preventing the
get_vault_settings 404 on first unlock.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New step 4 after vault creation: enter device name (defaults to
"Chrome on Linux" based on detected browser/OS). Generates ed25519
keypair, stores private key in chrome.storage.local, registers
device with vault. Wizard is now 5 steps (was 4).
Also adds generate_device_keypair() to wasm.d.ts type declarations.
Co-Authored-By: Claude <noreply@anthropic.com>
Replaces the ad-hoc char-class passphraseStrength() with a 5-segment
bar backed by a SW round-trip to rate_passphrase (zxcvbn). Input
handler debounces 150ms so we don't hammer the worker per keystroke.
The create-vault button is disabled unless the last score is ≥ 3
(zxcvbn's "safely unguessable" threshold), and the handler re-rates
synchronously on click as defence-in-depth. Label flips between "Too
weak" (red) and "Strong enough" (green).
Also:
- rewrites the vault-creation path to use the typed-item unlock +
manifest_encrypt APIs (derive_master_key/encrypt_manifest are gone);
the new initial manifest is { schema_version: 2, items: {} }.
- wasm.d.ts is now a pure `declare module 'relicario-wasm'` block;
tsconfig's stale `paths` alias is removed.
- @ts-nocheck removed from setup.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add initSync named export (Chrome MV3 service worker path — can't use
dynamic import()), and correct TotpCode.expires_at from number to bigint
to match the u64 wasm-bindgen output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Maps serialize as JS objects, not Maps — what the extension popup
expects. Also ships hand-written TS declarations for the bridge
(consumed by Plan 1C).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Manifest, package.json, tsconfig, webpack config, popup HTML shell,
WASM type declarations, and .gitignore entries for the Chrome MV3 extension.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>