From cf3412b2355dd37b2df2abe721c8f94f733a6e86 Mon Sep 17 00:00:00 2001 From: LC mac Date: Sat, 7 Feb 2026 13:46:02 +0800 Subject: [PATCH] fix(qr): resolve scanner race condition and crashes This commit addresses several issues related to the QR code scanner: - Fixes a build failure by defining stable handlers (`handleRestoreClose`, `handleRestoreError`) for the QRScanner component in `App.tsx` using `useCallback`. - Resolves a race condition that caused an `AbortError` when the scanner was initialized, particularly in React Strict Mode. This was fixed by ensuring all props passed to the scanner are stable. - Implements more robust error handling within the `QRScanner` component to prevent crashes when `null` or `undefined` errors are caught. - Updates documentation (`README.md`, `GEMINI.md`) to version 1.4.5. --- GEMINI.md | 13 ++++++------ README.md | 7 ++++++- src/App.tsx | 39 +++++++++++++++++++++--------------- src/components/QRScanner.tsx | 34 ++++++++++++++++++++++--------- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index 97ce844..357c5bb 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -2,7 +2,7 @@ ## Project Overview -**SeedPGP v1.4.4**: Client-side BIP39 mnemonic encryption webapp +**SeedPGP v1.4.5**: Client-side BIP39 mnemonic encryption webapp **Stack**: Bun + Vite + React + TypeScript + OpenPGP.js + Tailwind CSS **Deploy**: Cloudflare Pages (private repo: `seedpgp-web`) **Live URL**: @@ -300,13 +300,12 @@ await window.runSessionCryptoTest() --- -## Current Version: v1.4.4 +## Current Version: v1.4.5 -**Recent Changes (v1.4.4):** -- Enhanced security documentation with explicit threat model -- Improved README with simple examples and best practices -- Better air-gapped usage guidance for maximum security -- Version bump with security audit improvements +**Recent Changes (v1.4.5):** +- Fixed QR Scanner bugs related to camera initialization and race conditions. +- Improved error handling in the scanner to prevent crashes and provide better feedback. +- Stabilized component props to prevent unnecessary re-renders and fix `AbortError`. **Known Limitations (Critical):** 1. **Browser extensions** can read DOM, memory, keystrokes - use dedicated browser diff --git a/README.md b/README.md index 79da551..b970b94 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# SeedPGP v1.4.4 +# SeedPGP v1.4.5 **Secure BIP39 mnemonic backup using PGP encryption and QR codes** @@ -378,6 +378,11 @@ seedpgp-web/ ## 🔄 Version History +### v1.4.5 (2026-02-07) +- ✅ **Fixed QR Scanner bugs** related to camera initialization and race conditions. +- ✅ **Improved error handling** in the scanner to prevent crashes and provide better feedback. +- ✅ **Stabilized component props** to prevent unnecessary re-renders and fix `AbortError`. + ### v1.4.4 (2026-02-03) - ✅ **Enhanced security documentation** with explicit threat model - ✅ **Improved README** with simple examples and best practices diff --git a/src/App.tsx b/src/App.tsx index 83477d6..c963fd5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -403,14 +403,21 @@ function App() { setShowQRScanner(false); }, []); - const handleRestoreError = useCallback((error: string) => { - setError(error); + const handleRestoreError = useCallback((err: string) => { + setError(err); + setShowQRScanner(false); }, []); + + + + + + return (
- +
- + -

+

{encryptionMode === 'pgp' ? 'Uses PGP keys or password' : 'Uses passphrase only (Krux compatible)'} @@ -576,17 +583,17 @@ function App() { {/* SeedQR Format Toggle */} {encryptionMode === 'seedqr' && (

- + -

+

{seedQrFormat === 'standard' ? 'Numeric format, human-readable.' : 'Compact binary format, smaller QR code.'} @@ -598,7 +605,7 @@ function App() { {encryptionMode === 'krux' && activeTab === 'backup' && ( <>

- +
-

Label for identification (max 252 bytes)

+

Label for identification (max 252 bytes)

- +
-

Higher = more secure but slower (default: 200,000)

+

Higher = more secure but slower (default: 200,000)

)}
- +
-

+

{encryptionMode === 'krux' ? 'Required passphrase for Krux encryption' : 'Symmetric encryption password (SKESK)'} @@ -713,7 +720,7 @@ function App() {

-