From 3628199a5b6bf06e3656ca71a1a70dddc875886c Mon Sep 17 00:00:00 2001 From: Jason Tudisco Date: Sun, 27 Sep 2026 09:49:10 -0600 Subject: [PATCH] fix(kez-chat): show recovery phrase as words, never hex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recovery reveal (Getting Started and Settings) fell back to the 64-char hex seed whenever the phrase wasn't in the session — which happened after every Face ID / passkey unlock (PRF only recovers the seed) and for accounts created before 12-word phrases. - Phrase stored but not in session: Getting Started asks for the passphrase once and decrypts it. - No stored phrase (legacy / hex-restored): show the seed's exact 24-word encoding, which Restore accepts. - Settings alert lists words numbered one per line. - README: document passkey unlock as per-browser and how the recovery phrase is shown. Co-Authored-By: Claude Opus 5.5 --- kez-chat/README.md | 18 +++- kez-chat/web/src/routes/Settings.svelte | 17 ++-- kez-chat/web/src/routes/Welcome.svelte | 107 ++++++++++++++++++------ 3 files changed, 109 insertions(+), 33 deletions(-) diff --git a/kez-chat/README.md b/kez-chat/README.md index eeae984..927948b 100644 --- a/kez-chat/README.md +++ b/kez-chat/README.md @@ -42,7 +42,8 @@ can verify those links themselves, without trusting anyone. - **Push notifications** that tell the push provider nothing — the payload is empty. - **Unlock with Face ID / Touch ID / Windows Hello / a security key** - (WebAuthn passkeys), or a passphrase. + (WebAuthn passkeys), or a passphrase. Passkey unlock is per-browser; + on a new or wiped browser you restore with your recovery phrase. - **Your relays, your choice.** Reorder, add, or remove nostr relays in Settings. @@ -89,6 +90,21 @@ WebCrypto key, keeps you signed in while the PWA is backgrounded, so push notifications stay useful. **Lock** ends it; **Forget this account** wipes the device. +Passkey unlock is a local convenience, not a login: the passkey-encrypted +seed lives only in this browser's IndexedDB, and nothing is stored on the +server. If the browser forgets you (storage cleared, new device), sign +back in with **Restore** and your recovery phrase (or the 64-hex seed). + +**Showing your recovery phrase** (Getting Started, or Settings → reveal) +displays it as a numbered word list: + +- 12 words for accounts created with a phrase. After a passkey unlock + the phrase isn't in memory (the passkey only unlocks the seed), so the + app asks for your passphrase once to decrypt it. +- 24 words for older accounts created before 12-word phrases (or restored + from a hex seed). Their seed has no 12-word form, but its exact 24-word + encoding restores the same account. + Your **handle** (`you@kez.lat`) is registered with the chat-server by a request signed with your identity key. It's a public directory: handle → public key. diff --git a/kez-chat/web/src/routes/Settings.svelte b/kez-chat/web/src/routes/Settings.svelte index 14d41e3..bae1a9e 100644 --- a/kez-chat/web/src/routes/Settings.svelte +++ b/kez-chat/web/src/routes/Settings.svelte @@ -1,7 +1,6 @@