11/**
22 * EncryptionProvider Component
33 *
4- * Wraps protected routes to handle encryption initialization,
5- * setup prompt, and unlock flow.
6- * Encryption is optional - the app loads normally while checking encryption status .
4+ * Initializes encryption silently in the background.
5+ * Does NOT block the UI — encryption unlock happens on-demand
6+ * when a user accesses an encrypted note or tries to encrypt one .
77 */
88
99import { useEffect , useState } from 'react' ;
1010import { useEncryption } from '../hooks/useEncryption' ;
11- import EncryptionSetup from './EncryptionSetup ' ;
11+ import { useUnlockModal } from '../hooks/useUnlockModal ' ;
1212import UnlockPrompt from './UnlockPrompt' ;
1313
1414interface EncryptionProviderProps {
@@ -17,78 +17,33 @@ interface EncryptionProviderProps {
1717
1818export default function EncryptionProvider ( { children } : EncryptionProviderProps ) {
1919 const {
20- isInitialized,
21- needsSetup,
22- needsUnlock,
23- keyData,
2420 initializeEncryption,
21+ keyData,
2522 } = useEncryption ( ) ;
2623
27- const [ showSetup , setShowSetup ] = useState ( false ) ;
28- const [ setupSkipped , setSetupSkipped ] = useState ( false ) ;
29- const [ encryptionChecked , setEncryptionChecked ] = useState ( false ) ;
24+ const { isOpen, close, resolve } = useUnlockModal ( ) ;
3025
31- // Initialize encryption on mount (non-blocking)
26+ // Initialize encryption silently on mount (non-blocking)
3227 useEffect ( ( ) => {
33- const checkEncryption = async ( ) => {
34- try {
35- await initializeEncryption ( ) ;
36- } catch {
37- // Encryption check failed - continue without encryption
38- } finally {
39- setEncryptionChecked ( true ) ;
40- }
41- } ;
42- checkEncryption ( ) ;
28+ initializeEncryption ( ) . catch ( ( ) => {
29+ // Encryption check failed - continue without encryption
30+ } ) ;
4331 } , [ initializeEncryption ] ) ;
4432
45- // Show setup if needed and not skipped (only after encryption check completes)
46- useEffect ( ( ) => {
47- if ( encryptionChecked && needsSetup && ! setupSkipped ) {
48- setShowSetup ( true ) ;
49- }
50- } , [ encryptionChecked , needsSetup , setupSkipped ] ) ;
51-
52- const handleSetupComplete = ( ) => {
53- setShowSetup ( false ) ;
54- } ;
55-
56- const handleSetupSkip = ( ) => {
57- setSetupSkipped ( true ) ;
58- setShowSetup ( false ) ;
59- } ;
60-
61- const handleUnlock = ( ) => {
62- // Encryption unlocked - continue to app
63- } ;
64-
65- // Wait only for crypto store initialization (synchronous)
66- if ( ! isInitialized ) {
67- return null ;
68- }
69-
70- // Show setup wizard if needed
71- if ( showSetup && needsSetup ) {
72- return (
73- < EncryptionSetup
74- onComplete = { handleSetupComplete }
75- onSkip = { handleSetupSkip }
76- />
77- ) ;
78- }
79-
80- // Show unlock prompt if needed
81- if ( encryptionChecked && needsUnlock && keyData ) {
82- return (
83- < UnlockPrompt
84- encryptedPrivateKey = { keyData . encryptedPrivateKey }
85- salt = { keyData . salt }
86- publicKey = { keyData . publicKey }
87- onUnlock = { handleUnlock }
88- />
89- ) ;
90- }
91-
92- // Render children (the protected content)
93- return < > { children } </ > ;
33+ return (
34+ < >
35+ { children }
36+
37+ { /* On-demand unlock modal */ }
38+ { isOpen && keyData && (
39+ < UnlockPrompt
40+ encryptedPrivateKey = { keyData . encryptedPrivateKey }
41+ salt = { keyData . salt }
42+ publicKey = { keyData . publicKey }
43+ onUnlock = { resolve }
44+ onCancel = { close }
45+ />
46+ ) }
47+ </ >
48+ ) ;
9449}
0 commit comments