Auto-deref at &Zeroizing<[u8;32]> call sites, range pattern in generators,
useless String::into conversions in tests, unused Zeroizing import.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The old Entry/ManifestEntry/Manifest types are gone. CLI/extension
references break and will be fixed by Plans 1B and 1C respectively.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Forever, LastN, and Days policies all covered. Tests verify drop order
(keeps newest), days cutoff, and forever-no-op semantics.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
encrypt_item / decrypt_item / encrypt_manifest / decrypt_manifest /
encrypt_settings / decrypt_settings. All plaintext flows through
Zeroizing so JSON buffers are wiped on drop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AttachmentId is derived from sha256(plaintext) so identical content
deduplicates naturally. Size cap enforced at encrypt time, returning
IdfotoError::AttachmentTooLarge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Avoids from_utf8 panic when Custom contains multi-byte UTF-8 chars
whose individual bytes are independently sampled into the output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Uses rand::distributions::Uniform for unbiased sampling (audit H6).
Safe symbols = !@#$%^&*-_=+ (excludes characters that web forms
commonly reject). Test length capped at 128 (validator upper bound).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same latent bug as TrashRetention/HistoryRetention — serde's
internally-tagged repr cannot merge a newtype primitive payload
into a tag object. Add regression test for Custom round-trip.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ManifestEntry holds the per-item browse summary including derived
icon_hint (Login URL hostname) and attachment_summaries. Search matches
title or tag substring case-insensitively.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
set_field_value() captures old values for Password, Concealed, and Totp
kinds. Soft-delete via trashed_at timestamp; restore clears it. Kind
changes on set_field_value are rejected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parallel kind/value enums with a validate() invariant. Password,
Concealed, and Totp kinds are marked history-tracked so the Item setter
(next task) can decide whether to capture history on update.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Also enables zeroize's `serde` feature so Zeroizing<String> can
round-trip through serde_json.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reviewer note: flatten semantics of serde tag = "type" means no *Core
struct may ever use "type" as a field name.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Clean break from v1 — no migration. Decrypting a v1 blob now returns
IdfotoError::UnsupportedFormatVersion { found: 0x01, expected: 0x02 }.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
derive_master_key now:
- length-prefixes passphrase and image_secret to eliminate concatenation
ambiguity (H1)
- normalizes passphrase to UTF-8 NFC before hashing
- returns Zeroizing<[u8; 32]> so the master key is wiped on drop (H2)
- wraps the intermediate password buffer in Zeroizing for the same reason
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review fixups:
- ItemId/FieldId need impl Default delegating to ::new() to silence
clippy::new_without_default
- FieldId was missing the parallel uniqueness test that ItemId has
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
16-char hex (64-bit) random IDs for items and fields (audit M8).
AttachmentId is sha256(plaintext)[..16] for content-addressing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review flagged that chrono's clock feature requires wasmbind for
WASM builds — without it Utc::now() will fail at runtime in the
idfoto-wasm crate. Also drops the redundant hex entry in
[dev-dependencies] (already in [dependencies]).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
31 bite-sized TDD tasks covering: ID types, time helpers, error rewrite,
crypto fixes (length-prefix KDF, Zeroize, NFC, VERSION_BYTE 0x02), seven
typed cores with per-type modules, Field/FieldKind/FieldValue/Section,
Item envelope with field_history + soft-delete, AttachmentRef + content-
addressed encrypt/decrypt, Manifest with schema_version 2, VaultSettings,
CSPRNG generators with safe charset, BIP39 + zxcvbn strength gate, vault
helpers, retention pruning, full integration test suite.
idfoto-cli is expected to fail compilation at the end of this plan;
Plan 1B fixes it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the Phase 1 design spec for the polymorphic typed-item rewrite (Login,
SecureNote, Identity, Card, Key, Document, TOTP — with sections, custom
fields, attachments, password history, and the security architecture from
the audit baked in from day one). Also adds the initial full-codebase
security audit that informs both Phase 0 remediation and Phase 1 design.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Shared TypeScript source with separate manifests and webpack configs.
Firefox uses background scripts (not service workers) so WASM loading
uses dynamic import instead of initSync.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 tasks: types/messages, service worker handlers, capture content
script with bar/toast prompts, settings popup view, and integration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Experimental feature for auto-detecting login form submissions and
prompting to save/update credentials. Configurable bar or toast
prompt style, off by default, with per-site blacklist.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>