Skip to content

test(crypto): add recovery + rotation coverage (rotation had zero tests) - #222

Merged
h4yfans merged 1 commit into
mainfrom
debt/1.6-recovery-rotation-tests
Apr 15, 2026
Merged

test(crypto): add recovery + rotation coverage (rotation had zero tests)#222
h4yfans merged 1 commit into
mainfrom
debt/1.6-recovery-rotation-tests

Conversation

@h4yfans

@h4yfans h4yfans commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Closes Phase 1 §1.6 of .claude/plans/tech-debt-remediation.md.

Summary

Dedicated coverage for recovery.ts (55L) + rotation.ts (339L). Rotation had zero tests prior to this PR — highest-risk unit in Phase 1.

New files

  • recovery.test.ts (207L) — 14 tests across 5 exports. Real bip39 wordlist + real libsodium. Covers generateRecoveryPhrase (24-word BIP-39, valid checksum, 64-byte seed, uniqueness), validateRecoveryPhrase (valid/bad-checksum/non-wordlist/empty), phraseToSeed determinism, recoverMasterKeyFromPhrase roundtrip vs deriveMasterKey, validateKeyVerifier.

  • rotation.test.ts (779L) — 13 tests across all rotation exports. Real crypto end-to-end.

    • rewrapItemKey — file-key recovery via new vault key; encryptedData/dataNonce/signerDeviceId/originalId/clock/stateVector/deletedAt survive; new signature verifies; malformed key-nonce throws.
    • rewrapCrdtSnapshot — Yjs body byte-identical pre/post, wrapped-key region differs, file key recovered matches, new signature verifies.
    • performKeyRotation — happy path (phases: preparing → re-encrypting → finalizing → complete), processedItems monotonic to totalItems, pause+resume once, pushed items signed under new vault key, server keys + master-key store invoked.
    • Early-return: null token / null signing keys / null vault key.
    • Mid-rotation failure: malformed keyNonce on item index 1 → pushItems excludes failing id, error matches "Rotation aborted: 1 items failed re-wrap", server keys NOT advanced, sync resumed.
    • Server-rejected push item; CRDT snapshot rewrap failure; unexpected dep throw still resumes sync.

Note on mid-rotation semantics

The spec envisioned "items 0..N-1 kept new key, N..end kept old key". The actual rotation.ts:238-269,301-305 catches per-item rewrap errors and aborts at the post-loop guard with Rotation aborted: N items failed re-wrap. This PR tests the real behavior; the safety post-conditions that matter (server keys NOT updated, master key NOT stored, sync resumed) are asserted.

Test plan

  • pnpm --filter desktop test --project main src/main/crypto/recovery.test.ts src/main/crypto/rotation.test.ts — 0 failures
  • per-file coverage on both ≥ 95%
  • pnpm typecheck:node && pnpm typecheck:web clean
  • pnpm lint clean

🤖 Generated with Claude Code

@h4yfans
h4yfans merged commit 9f0f36d into main Apr 15, 2026
2 checks passed
h4yfans added a commit that referenced this pull request May 6, 2026
@h4yfans
h4yfans deleted the debt/1.6-recovery-rotation-tests branch May 6, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant