mirror of
https://github.com/block/buzz.git
synced 2026-11-02 07:22:55 +00:00
**Category:** improvement **User Impact:** Users can create a password-protected key backup, save it locally, and prove that it works before finishing onboarding or signing out. **Problem:** Tyler's NIP-49 foundation made encrypted local backup possible, but the end-to-end ceremony still needed clearer progression, trustworthy verification, and a Settings treatment consistent with the rest of Identity. **Solution:** This stack adds a guided create/download/test flow, verifies the actual saved backup through Rust without returning secret key material, minimizes password lifetime in the webview, and restores warm, plain-language presentation across onboarding and Settings. > [!NOTE] > This PR is intentionally stacked on #2937 (`eva/nip49-local-backup`). Review only the 19 commits in this stack. <details> <summary>File changes</summary> **desktop/src-tauri/src/commands/identity.rs** Adds off-thread verification of NIP-49 backups and returns public identity details only. **desktop/src-tauri/src/commands/identity_key_backup_tests.rs** Covers verification, identity matching, and failure behavior at the command boundary. **desktop/src-tauri/src/egress_guard_tests.rs** Keeps the NIP-49 source inventory aligned with the new verification path. **desktop/src-tauri/src/key_backup.rs** Supports real backup decryption for verification while zeroizing submitted passwords. **desktop/src-tauri/src/key_backup_tests.rs** Exercises valid, wrong-password, damaged, and different-identity backups. **desktop/src-tauri/src/lib.rs** Registers the verification command with the desktop runtime. **desktop/src/features/communities/ui/WelcomeSetup.tsx** Routes community onboarding through the revised backup ceremony. **desktop/src/features/onboarding/lib/encryptedBackup.test.mjs** Covers the hardened backup state model and password-clearing behavior. **desktop/src/features/onboarding/lib/encryptedBackup.ts** Models creation and verification with opaque request correlation and short-lived passwords. **desktop/src/features/onboarding/ui/BackupStep.tsx** Presents the backup choice clearly and advances into the dedicated download step. **desktop/src/features/onboarding/ui/BackupTestFlow.tsx** Adds the polished select-file, enter-password, verification, error, and success experience. **desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx** Connects community onboarding to the updated backup steps. **desktop/src/features/onboarding/ui/DownloadKeyStep.tsx** Adds the dedicated encrypted-backup download step and pre-creation skip escape hatch. **desktop/src/features/onboarding/ui/EncryptedBackupCreator.tsx** Guides password generation, backup creation, native saving, safe retry, and re-download. **desktop/src/features/onboarding/ui/MachineOnboardingFlow.tsx** Sequences chooser, download, exact-file test, and setup progression. **desktop/src/features/onboarding/ui/NostrKeyImportForm.tsx** Aligns encrypted-key import behavior with the backup flow. **desktop/src/features/onboarding/ui/NsecMaskedDisplay.tsx** Improves masked/revealed key presentation and safely wraps long private keys. **desktop/src/features/onboarding/ui/OnboardingChrome.tsx** Supports the revised onboarding layout and transitions. **desktop/src/features/onboarding/ui/SetupStep.tsx** Integrates the completed backup ceremony with final setup. **desktop/src/features/onboarding/ui/onboardingFlowSteps.test.mjs** Updates flow-level assertions for the new step sequence. **desktop/src/features/settings/ui/EncryptedBackupRow.tsx** Adds sibling Create and Test rows that match the surrounding Identity settings rhythm. **desktop/src/features/settings/ui/ProfileSettingsCard.tsx** Places password-backup controls in the Identity card. **desktop/src/features/settings/ui/SignOutSection.tsx** Uses explicit backup self-attestation plus the existing wipe phrase without requiring a raw-key reveal first. **desktop/src/shared/api/tauriIdentity.ts** Exposes typed backup verification to the frontend. **desktop/src/shared/lib/ncryptsecSourceScan.test.mjs** Updates the frontend source allowlist for the verification path. **desktop/src/testing/e2eBridge.ts** Models creation, saving, and verification for browser coverage. **desktop/tests/e2e/onboarding-backup.spec.ts** Covers backup creation, exact-file testing, errors, retries, and completion. **desktop/tests/e2e/onboarding-docked-cta-screenshots.spec.ts** Updates docked CTA visual coverage for the revised progression. **desktop/tests/e2e/onboarding.spec.ts** Keeps broader onboarding coverage aligned with the backup ceremony. **desktop/tests/e2e/profile-nsec-reveal.spec.ts** Covers Settings create/test behavior and updated success copy. **desktop/tests/e2e/signout-confirmation.spec.ts** Covers backup self-attestation, wipe phrase confirmation, and reset behavior. **desktop/tests/helpers/fileDrag.ts** Adds reusable file-drop support for backup test coverage. **desktop/tests/helpers/onboarding.ts** Routes tests through chooser, download, and skip behavior consistently. </details> ## Reproduction steps 1. Start fresh onboarding and choose the password-protected backup path. 2. Continue to **Backup your key**, create a password, save the `.ncryptsec` file, and confirm that **Next** remains gated until testing succeeds. 3. Select that exact file, enter its password, and verify the **Your backup works!** success state. 4. Open **Settings → Identity** and confirm that **Create password backup** and **Test password backup** appear as sibling rows. 5. Test a valid backup, then test wrong-password and different-identity cases to confirm clear, non-secret-bearing outcomes. 6. Open sign out and confirm that backup self-attestation plus typing `wipe all my data` remain required. ## Screenshots ### Onboarding flow | 1. Creating your key | 2. Key created | 3. Create backup password | |---|---|---| | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/fe5ebf60-02ad-4584-8e64-ff137bafac02" /> | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/0b8c7c6c-2ae5-494e-bb81-0a7b47ea1b66" /> | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/9fa8f6c0-832a-46ec-9af8-55dcae0adbb8" /> | | **4. Select the saved backup** | **5. Enter its password** | **6. Verification succeeds** | | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/7ed1528c-6a1f-4411-bd3e-c57413320cdf" /> | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/088ec3ed-2735-4b9a-a0c5-6d176b3f06c5" /> | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/7081ce32-9371-46b2-9692-23ff77c39d35" /> | ### Settings flow | Create and Test tools | Tested backup success | |---|---| | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/978ab672-5510-46d8-9116-6df4f1bda34c" /> | <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/56a1764d-3c3e-40e2-9f4b-962c5e96a36c" /> | ## Verification - Desktop typecheck - Full desktop JS: 3,733/3,733 - `pnpm check` - Rust desktop lib: 1,862 passed, 14 ignored; diagnostic: 3/3 - Focused Playwright: 16/16 with one worker Native save/cancel remains the residual smoke-test risk: browser E2E mocks the KDF/native save-dialog boundary, while real decrypt and identity matching are covered in Rust. --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>