Skip to content

fix: make enabling/disabling E2E encryption non-destructive - #141

Merged
fjbarrett merged 1 commit into
mainfrom
fix/encryption-lifecycle-safety
Jun 15, 2026
Merged

fix: make enabling/disabling E2E encryption non-destructive#141
fjbarrett merged 1 commit into
mainfrom
fix/encryption-lifecycle-safety

Conversation

@fjbarrett

Copy link
Copy Markdown
Owner

Summary

  • Disable decrypts + rewrites every note as plaintext (with a confirm) before dropping the salt — no more permanently orphaned ciphertext.
  • Enable backfills existing plaintext notes so coverage is real (passes the existing title so metadata isn't regenerated from ciphertext).
  • Lockout escape: the unlock dialog gets "Forgot your passphrase?" → reset, so a forgotten passphrase no longer bricks the app.
  • Salt POST returns the effective stored salt (a double-setup can't derive against a salt the server didn't keep).
  • base64 chunks the spread (no RangeError on large notes).
  • update() skips title/summary regeneration when a title is explicitly passed (used by the backfill/rewrite loops).

Test plan

  • Enable encryption with existing notes → all bodies become enc:… server-side; UI still readable
  • Disable → confirm → notes are plaintext again on the server; titles intact
  • Lock (refresh), click "Forgot your passphrase?" → app is usable again
  • Large note encrypts/decrypts without error
  • tsc clean, 35 tests pass

Several sharp edges from the encryption PR:

- Disabling now decrypts every note and rewrites it as plaintext (with a
  confirm) before dropping the salt, instead of orphaning the ciphertext.
- Enabling backfills existing plaintext notes so "Enabled" really covers
  them; the existing title is passed through so metadata isn't regenerated
  from ciphertext.
- The locked-out unlock dialog gets a "Forgot your passphrase?" reset so a
  forgotten passphrase no longer bricks the whole app.
- Salt POST returns the effective stored salt, so a double-setup can't
  derive a key against a salt the server never kept.
- bytesToBase64 chunks the spread to avoid a RangeError on large notes.

update() skips title/summary regeneration when a title is passed, which
the backfill/rewrite loops rely on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
keep Ready Ready Preview, Comment Jun 15, 2026 11:41pm

@fjbarrett
fjbarrett merged commit efcbff8 into main Jun 15, 2026
1 check was pending
@fjbarrett
fjbarrett deleted the fix/encryption-lifecycle-safety branch June 15, 2026 23:41
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