diff --git a/src/components/security-mode-selector/security-mode-selector.html b/src/components/security-mode-selector/security-mode-selector.html index 4ff8e20..ff1eaff 100644 --- a/src/components/security-mode-selector/security-mode-selector.html +++ b/src/components/security-mode-selector/security-mode-selector.html @@ -39,23 +39,6 @@ - -
-
-
🌐
-
Navigateur
-
Moyennement sécurisé
-
-
- Utilise les fonctionnalités de sécurité du navigateur -
-
- ✅ WebAuthn standard - ⚠ DĂ©pendant du navigateur - ⚠ Moins sĂ©curisĂ© que les options OS -
-
-
diff --git a/src/components/security-mode-selector/security-mode-selector.ts b/src/components/security-mode-selector/security-mode-selector.ts index 954c1ea..f62463a 100644 --- a/src/components/security-mode-selector/security-mode-selector.ts +++ b/src/components/security-mode-selector/security-mode-selector.ts @@ -3,7 +3,7 @@ * Permet Ă  l'utilisateur de choisir comment sĂ©curiser ses clĂ©s privĂ©es */ -export type SecurityMode = 'proton-pass' | 'os' | 'browser' | '2fa' | 'none'; +export type SecurityMode = 'proton-pass' | 'os' | '2fa' | 'none'; export interface SecurityModeConfig { mode: SecurityMode; @@ -151,14 +151,6 @@ export class SecurityModeSelector { requiresConfirmation: false, warnings: [] }, - { - mode: 'browser', - name: 'Navigateur', - description: 'Utilise les fonctionnalitĂ©s de sĂ©curitĂ© du navigateur', - securityLevel: 'medium', - requiresConfirmation: false, - warnings: [] - }, { mode: '2fa', name: 'Application 2FA', @@ -219,11 +211,6 @@ export class SecurityModeSelector { '✅ Chiffrement matĂ©riel', '✅ Protection par mot de passe' ], - 'browser': [ - '✅ WebAuthn standard', - '⚠ DĂ©pendant du navigateur', - '⚠ Moins sĂ©curisĂ© que les options OS' - ], '2fa': [], 'none': [] }; diff --git a/src/pages/birthday-setup/birthday-setup.ts b/src/pages/birthday-setup/birthday-setup.ts index 0513b32..6e28cff 100644 --- a/src/pages/birthday-setup/birthday-setup.ts +++ b/src/pages/birthday-setup/birthday-setup.ts @@ -106,7 +106,9 @@ document.addEventListener('DOMContentLoaded', async () => { continueBtn.addEventListener('click', () => { console.log('🏠 Redirecting to main application...'); // Rediriger vers l'application principale - window.location.href = '/'; + console.log('🎂 Birthday setup completed, checking storage state...'); + const { checkStorageStateAndNavigate } = await import('../../router'); + await checkStorageStateAndNavigate(); }); function updateStatus(message: string, type: 'loading' | 'success' | 'error') { diff --git a/src/pages/home/home.ts b/src/pages/home/home.ts index 87e3350..9d59879 100755 --- a/src/pages/home/home.ts +++ b/src/pages/home/home.ts @@ -537,22 +537,13 @@ async function showSecurityModeSelector(): Promise {
Utilise l'authentificateur intégré de votre systÚme
-
+
- 🌐 - Navigateur - Moyennement sĂ©curisĂ© + 🔐 + OTP (code Ă  usage unique) + SĂ©curisĂ©
-
Utilise les fonctionnalités de sécurité du navigateur
-
- -
-
- đŸ“± - Application 2FA - ⚠ Non sĂ©curisĂ© -
-
Stockage en clair avec authentification 2FA
+
Code OTP généré par Proton Pass, Google Authenticator, etc.
diff --git a/src/pages/security-setup/security-setup.html b/src/pages/security-setup/security-setup.html index 95cbcca..946c62d 100644 --- a/src/pages/security-setup/security-setup.html +++ b/src/pages/security-setup/security-setup.html @@ -122,11 +122,6 @@
Utilise l'authentification biométrique de votre systÚme
-
-
🌐 Navigateur
-
Sauvegarde dans le gestionnaire de mots de passe du navigateur
-
-
🔐 OTP (code à usage unique)
Code OTP généré par Proton Pass, Google Authenticator, etc.
diff --git a/src/pages/security-setup/security-setup.ts b/src/pages/security-setup/security-setup.ts index 800fd90..993f315 100644 --- a/src/pages/security-setup/security-setup.ts +++ b/src/pages/security-setup/security-setup.ts @@ -89,7 +89,9 @@ document.addEventListener('DOMContentLoaded', async () => { console.log('✅ PBKDF2 key generated and stored securely'); // Rediriger vers la page de gĂ©nĂ©ration du wallet - window.location.href = '/src/pages/wallet-setup/wallet-setup.html'; + console.log('🔐 Security setup completed, checking storage state...'); + const { checkStorageStateAndNavigate } = await import('../../router'); + await checkStorageStateAndNavigate(); } catch (error) { console.error('❌ PBKDF2 key generation failed:', error); diff --git a/src/pages/wallet-setup/wallet-setup.html b/src/pages/wallet-setup/wallet-setup.html index dc47dbe..0eac0d4 100644 --- a/src/pages/wallet-setup/wallet-setup.html +++ b/src/pages/wallet-setup/wallet-setup.html @@ -112,7 +112,7 @@
- +
diff --git a/src/pages/wallet-setup/wallet-setup.ts b/src/pages/wallet-setup/wallet-setup.ts index 78261f3..cc61f26 100644 --- a/src/pages/wallet-setup/wallet-setup.ts +++ b/src/pages/wallet-setup/wallet-setup.ts @@ -142,8 +142,8 @@ document.addEventListener('DOMContentLoaded', async () => { console.log('🔍 Testing all security modes to find a PBKDF2 key...'); // Tester tous les modes de sĂ©curitĂ© pour trouver une clĂ© PBKDF2 valide - const allSecurityModes: Array<'browser' | 'otp' | 'password' | 'none' | 'os' | 'proton-pass'> = - ['browser', 'otp', 'password', 'none', 'os', 'proton-pass']; + const allSecurityModes: Array<'otp' | 'password' | 'none' | 'os' | 'proton-pass'> = + ['otp', 'password', 'none', 'os', 'proton-pass']; let currentMode: string | null = null; @@ -466,6 +466,8 @@ document.addEventListener('DOMContentLoaded', async () => { // Gestion du bouton continuer continueBtn.addEventListener('click', () => { console.log('🔗 Redirecting to pairing page...'); - window.location.href = '/src/pages/birthday-setup/birthday-setup.html'; + console.log('💰 Wallet setup completed, checking storage state...'); + const { checkStorageStateAndNavigate } = await import('../../router'); + await checkStorageStateAndNavigate(); }); }); \ No newline at end of file diff --git a/src/router.ts b/src/router.ts index 2869a57..06141bd 100755 --- a/src/router.ts +++ b/src/router.ts @@ -17,10 +17,90 @@ const routes: { [key: string]: string } = { account: '/src/pages/account/account.html', chat: '/src/pages/chat/chat.html', signature: '/src/pages/signature/signature.html', + 'security-setup': '/src/pages/security-setup/security-setup.html', + 'wallet-setup': '/src/pages/wallet-setup/wallet-setup.html', + 'birthday-setup': '/src/pages/birthday-setup/birthday-setup.html', }; export let currentRoute = ''; +/** + * VĂ©rifie l'Ă©tat du storage et dĂ©termine quelle page afficher selon l'Ă©tat actuel + * Logique de progression : + * - Si pairing → account + * - Si date anniversaire → pairing + * - Si wallet → birthday-setup + * - Si pbkdf2 → wallet-setup + * - Sinon → security-setup + */ +export async function checkStorageStateAndNavigate(): Promise { + console.log('🔍 Checking storage state to determine next step...'); + + try { + // VĂ©rifier l'Ă©tat du pairing + const services = await Services.getInstance(); + const isPaired = services.isPaired(); + + if (isPaired) { + console.log('✅ Device is paired, navigating to account page'); + await navigate('account'); + return; + } + + // VĂ©rifier si la date anniversaire est configurĂ©e (wallet avec birthday > 0) + const device = await services.getDeviceFromDatabase(); + if (device && device.sp_wallet && device.sp_wallet.birthday > 0) { + console.log('🎂 Birthday is configured, navigating to pairing'); + await navigate('home'); // Pour l'instant, rediriger vers home pour le pairing + return; + } + + // VĂ©rifier si le wallet existe (mĂȘme avec birthday = 0) + if (device && device.sp_wallet) { + console.log('💰 Wallet exists but birthday not set, navigating to birthday-setup'); + await navigate('birthday-setup'); + return; + } + + // VĂ©rifier si une clĂ© PBKDF2 existe + const { SecureCredentialsService } = await import('./services/secure-credentials.service'); + const secureCredentialsService = SecureCredentialsService.getInstance(); + + const allSecurityModes: Array<'otp' | 'password' | 'none' | 'os' | 'proton-pass'> = + ['otp', 'password', 'none', 'os', 'proton-pass']; + + let hasPBKDF2Key = false; + for (const mode of allSecurityModes) { + try { + const key = await secureCredentialsService.retrievePBKDF2Key(mode); + if (key) { + hasPBKDF2Key = true; + console.log(`🔐 PBKDF2 key found for mode: ${mode}`); + break; + } + } catch (error) { + // Mode non disponible, continuer + } + } + + if (hasPBKDF2Key) { + console.log('🔐 PBKDF2 key exists, navigating to wallet-setup'); + await navigate('wallet-setup'); + return; + } + + // Aucune clĂ© PBKDF2 trouvĂ©e, commencer par la configuration de sĂ©curitĂ© + console.log('🔐 No PBKDF2 key found, navigating to security-setup'); + await navigate('security-setup'); + + } catch (error) { + console.error('❌ Error checking storage state:', error); + // En cas d'erreur, commencer par la configuration de sĂ©curitĂ© + console.log('🔐 Error occurred, defaulting to security-setup'); + await navigate('security-setup'); + } +} + export async function navigate(path: string) { console.log('🧭 Navigate called with path:', path); cleanSubscriptions(); @@ -77,6 +157,12 @@ async function handleLocation(path: string) { } catch (error) { console.error('❌ Failed to initialize home page:', error); } + } else if (path === 'security-setup' || path === 'wallet-setup' || path === 'birthday-setup') { + console.log('📍 Processing setup route:', path); + + // Pour les pages de setup, rediriger directement vers la page HTML + window.location.href = routeHtml; + return; } else { console.log('📍 Processing other route:', path); const html = await fetch(routeHtml).then(data => data.text()); @@ -138,108 +224,19 @@ export async function init(): Promise { try { console.log('🚀 Starting application initialization...'); - // ÉTAPE 1: GESTION DE LA SÉCURITÉ (clĂ©s de sĂ©curitĂ©) - EN PREMIER - console.log('🔐 Step 1: Security key management...'); - const securityConfigured = await handleSecurityKeyManagement(); - - if (!securityConfigured) { - console.log('🔐 Security not configured, redirecting to home for setup...'); - // Naviguer directement vers home pour la configuration de sĂ©curitĂ© - handleLocation('home'); - return; - } - - // ÉTAPE 2: INITIALISATION DES SERVICES (seulement aprĂšs la sĂ©curitĂ©) - console.log('🔧 Step 2: Initializing services...'); + // Initialiser les services de base + console.log('🔧 Initializing basic services...'); const services = await Services.getInstance(); (window as any).myService = services; const db = await Database.getInstance(); - // Register service worker and wait for it to be ready + // Register service worker console.log('đŸ“± Registering service worker...'); await db.registerServiceWorker('/src/service-workers/database.worker.js'); - // ÉTAPE 3: CONNEXION AUX RELAIS (pour la hauteur de blocs) - console.log('🌐 Step 3: Connecting to relays for block height...'); - try { - console.log('🌐 Connecting to relays...'); - services.updateUserStatus('🌐 Connecting to blockchain relays...'); - await services.connectAllRelays(); - console.log('✅ Relays connected successfully'); - services.updateUserStatus('✅ Connected to blockchain relays'); - - // CRITICAL: Wait for handshake to be processed and block height to be set - console.log('⏳ Waiting for relay handshake to complete...'); - services.updateUserStatus('⏳ Waiting for blockchain synchronization...'); - await services.waitForBlockHeight(); - console.log('✅ Block height received from relay'); - services.updateUserStatus('✅ Blockchain synchronized'); - } catch (error) { - console.warn('⚠ Failed to connect to some relays:', error); - console.log('🔄 Continuing despite relay connection issues...'); - services.updateUserStatus('⚠ Some relays unavailable, continuing...'); - } - - // ÉTAPE 4: GÉNÉRATION/CHARGEMENT DU WALLET - console.log('💰 Step 4: Wallet generation/loading...'); - const device = await services.getDeviceFromDatabase(); - console.log('🚀 ~ device:', device); - - if (!device) { - // No wallet exists, create new account - console.log('🔍 No existing wallet found, creating new account...'); - services.updateUserStatus('🔍 Creating new secure wallet...'); - await services.createNewDevice(); - services.updateUserStatus('✅ New wallet created successfully'); - } else { - // Wallet exists, restore it and check pairing - console.log('🔍 Existing wallet found, restoring account...'); - services.updateUserStatus('🔍 Restoring existing wallet...'); - services.restoreDevice(device); - services.updateUserStatus('✅ Wallet restored successfully'); - } - - // CRITICAL: Now that block height is set, synchronize wallet - console.log('🔄 Synchronizing wallet with blockchain...'); - services.updateUserStatus('🔄 Synchronizing wallet with blockchain...'); - await services.updateDeviceBlockHeight(); - console.log('✅ Wallet synchronization completed'); - services.updateUserStatus('✅ Wallet synchronized successfully'); - - // ÉTAPE 5: HANDSHAKE - console.log('đŸ€ Step 5: Performing handshake...'); - await performHandshake(services); - - // ÉTAPE 6: PAIRING - console.log('🔗 Step 6: Device pairing...'); - await handlePairing(services); - - // ÉTAPE 7: ÉCOUTE DES PROCESSUS - console.log('👂 Step 7: Starting process listening...'); - await startProcessListening(services); - - // We register all the event listeners if we run in an iframe - if (window.self !== window.top) { - console.log('đŸ–Œïž Registering iframe listeners...'); - await registerAllListeners(); - - // Add iframe mode class for styling - document.body.classList.add('iframe-mode'); - } - - // Navigate to appropriate page based on pairing status - const isPaired = services.isPaired(); - console.log('🔍 Device pairing status:', isPaired ? 'Paired' : 'Not paired'); - - if (isPaired) { - console.log('✅ Device is paired, navigating to account page...'); - await navigate('account'); - console.log('✅ Navigation to account completed'); - } else { - console.log('⚠ Device not paired, navigating to home page...'); - await navigate('home'); - console.log('✅ Navigation to home completed'); - } + // VĂ©rifier l'Ă©tat du storage et naviguer vers la page appropriĂ©e + console.log('🔍 Checking storage state and navigating to appropriate page...'); + await checkStorageStateAndNavigate(); console.log('✅ Application initialization completed successfully'); } catch (error) { @@ -254,8 +251,8 @@ export async function init(): Promise { alert('⚠ Insufficient memory for WebAssembly. Please refresh the page or close other tabs.'); } - console.log('🔄 Falling back to home page...'); - await navigate('home'); + console.log('🔄 Falling back to security-setup...'); + await navigate('security-setup'); } } diff --git a/src/services/credentials/encryption.service.ts b/src/services/credentials/encryption.service.ts index bbaa8b7..c514211 100644 --- a/src/services/credentials/encryption.service.ts +++ b/src/services/credentials/encryption.service.ts @@ -264,47 +264,4 @@ export class EncryptionService { } - /** - * WARNING: DEPRECATED - This method does NOT encrypt, only base64 encoding - * Use encryptWithPassword or WebAuthn key encryption instead - */ - async encryptWithWebAuthn( - credentials: CredentialData, - credentialId: string - ): Promise { - secureLogger.error('encryptWithWebAuthn is deprecated and does NOT encrypt data', new Error('Use encryptWithPassword or WebAuthn encryption')); - - const data = JSON.stringify({ - spendKey: credentials.spendKey, - scanKey: credentials.scanKey, - timestamp: credentials.timestamp - }); - - // WARNING: Only base64 encoding, no encryption - DO NOT USE FOR SENSITIVE DATA - const encoded = btoa(data); - return encoded; - } - - /** - * WARNING: DEPRECATED - This method does NOT decrypt, only base64 decoding - * Use decryptWithPassword or WebAuthn key decryption instead - */ - async decryptWithWebAuthn( - encryptedData: string, - credentialId: string - ): Promise { - secureLogger.error('decryptWithWebAuthn is deprecated and does NOT decrypt data', new Error('Use decryptWithPassword or WebAuthn decryption')); - - // WARNING: Only base64 decoding, no decryption - DO NOT USE FOR SENSITIVE DATA - const decoded = atob(encryptedData); - const data = JSON.parse(decoded); - - return { - spendKey: data.spendKey, - scanKey: data.scanKey, - salt: new Uint8Array(0), - iterations: 0, - timestamp: data.timestamp - }; - } } diff --git a/src/services/credentials/storage.service.ts b/src/services/credentials/storage.service.ts index 13a437f..4ed166c 100644 --- a/src/services/credentials/storage.service.ts +++ b/src/services/credentials/storage.service.ts @@ -20,77 +20,6 @@ export class StorageService { return StorageService.instance; } - /** - * Stocke une clĂ© dans le gestionnaire de mots de passe du navigateur - */ - async storeKeyInBrowser(key: string): Promise { - try { - secureLogger.info('Storing key in browser password manager', { - component: 'StorageService', - operation: 'storeKeyInBrowser' - }); - - // IMPORTANT: Ne jamais stocker la clĂ© PBKDF2 en clair ! - // Utiliser l'API Credential Management pour stocker comme mot de passe - // Le navigateur chiffrera automatiquement le mot de passe - const credential = new PasswordCredential({ - id: 'lecoffre-pbkdf2-key', - password: key, // Le navigateur chiffre automatiquement ce mot de passe - name: 'LeCoffre PBKDF2 Key' - }); - - await navigator.credentials.store(credential); - - secureLogger.info('Key stored in browser password manager successfully (encrypted by browser)', { - component: 'StorageService', - operation: 'storeKeyInBrowser' - }); - - } catch (error) { - secureLogger.error('Failed to store key in browser password manager', { - component: 'StorageService', - operation: 'storeKeyInBrowser', - error: error instanceof Error ? error.message : String(error) - }); - throw error; - } - } - - - /** - * Stocke un wallet chiffrĂ© - */ - async storeEncryptedWallet(encryptedWallet: string): Promise { - try { - secureLogger.info('Storing encrypted wallet', { - component: 'StorageService', - operation: 'storeEncryptedWallet' - }); - - const db = await this.openDatabase(); - const transaction = db.transaction([this.storeName], 'readwrite'); - const store = transaction.objectStore(this.storeName); - - await new Promise((resolve, reject) => { - const request = store.put(encryptedWallet, 'encrypted-wallet'); - request.onsuccess = () => resolve(); - request.onerror = () => reject(request.error); - }); - - secureLogger.info('Encrypted wallet stored successfully', { - component: 'StorageService', - operation: 'storeEncryptedWallet' - }); - } catch (error) { - secureLogger.error('Failed to store encrypted wallet', { - component: 'StorageService', - operation: 'storeEncryptedWallet', - error: error instanceof Error ? error.message : String(error) - }); - throw error; - } - } - /** * Stocke une clĂ© en clair (non recommandĂ©) */ @@ -126,31 +55,6 @@ export class StorageService { } } - /** - * RĂ©cupĂšre une clĂ© depuis le gestionnaire de mots de passe du navigateur - */ - async retrieveKeyFromBrowser(): Promise { - try { - const credentials = await navigator.credentials.get({ - password: true, - mediation: 'required' as CredentialMediationRequirement - }); - - if (credentials && 'password' in credentials) { - return credentials.password || null; - } - - return null; - } catch (error) { - secureLogger.error('Failed to retrieve key from browser', { - component: 'StorageService', - operation: 'retrieveKeyFromBrowser', - error: error instanceof Error ? error.message : String(error) - }); - return null; - } - } - /** * RĂ©cupĂšre une clĂ© en clair depuis IndexedDB */ diff --git a/src/services/secure-credentials.service.ts b/src/services/secure-credentials.service.ts index d21687a..14d9d79 100644 --- a/src/services/secure-credentials.service.ts +++ b/src/services/secure-credentials.service.ts @@ -58,11 +58,11 @@ export class SecureCredentialsService { let currentMode = await this.securityModeService.getCurrentMode(); if (!currentMode) { - secureLogger.warn('No security mode selected, using default mode: browser', { + secureLogger.warn('No security mode selected, using default mode: none', { component: 'SecureCredentialsService', operation: 'generateSecureCredentials' }); - currentMode = 'browser'; + currentMode = 'none'; await this.securityModeService.setSecurityMode(currentMode); } @@ -83,8 +83,6 @@ export class SecureCredentialsService { } else if (modeConfig.implementation.useEncryption) { if (currentMode === 'password') { return this.generatePasswordCredentials(password, _options); - } else if (currentMode === 'browser') { - return this.generateBrowserCredentials(password, _options); } else { return this.generateEncryptedCredentials(password, _options); } @@ -113,10 +111,6 @@ export class SecureCredentialsService { // RĂ©cupĂ©rer la clĂ© chiffrĂ©e avec WebAuthn return await webAuthnService.retrieveKeyWithWebAuthn(securityMode); - case 'browser': - // RĂ©cupĂ©rer la clĂ© du gestionnaire de mots de passe - return await storageService.retrieveKeyFromBrowser(); - case 'otp': // RĂ©cupĂ©rer la clĂ© en clair (l'OTP protĂšge l'accĂšs) return await storageService.retrievePlainKey(); @@ -126,8 +120,15 @@ export class SecureCredentialsService { return await storageService.retrieveEncryptedKey(); case 'none': - // RĂ©cupĂ©rer la clĂ© en clair - return await storageService.retrievePlainKey(); + // RĂ©cupĂ©rer la clĂ© chiffrĂ©e avec la clĂ© en dur + const encryptedData = await storageService.retrieveEncryptedKey(); + if (encryptedData) { + const { EncryptionService } = await import('./encryption.service'); + const encryptionService = EncryptionService.getInstance(); + const hardcodedKey = '4NK_DEFAULT_ENCRYPTION_KEY_NOT_SECURE'; + return await encryptionService.decrypt(encryptedData, hardcodedKey); + } + return null; default: return null; @@ -182,12 +183,6 @@ export class SecureCredentialsService { await webAuthnService.storeKeyWithWebAuthn(pbkdf2Key, securityMode); break; - case 'browser': - // Stocker dans le gestionnaire de mots de passe du navigateur - console.log('🔐 Storing PBKDF2 key in browser password manager...'); - await storageService.storeKeyInBrowser(pbkdf2Key); - break; - case 'otp': // GĂ©nĂ©rer un secret OTP pour l'authentification (pas de chiffrement) console.log('🔐 Setting up OTP authentication for PBKDF2 key...'); @@ -208,9 +203,11 @@ export class SecureCredentialsService { break; case 'none': - // Stockage en clair (non recommandĂ©) - console.log('⚠ Storing PBKDF2 key in plain text (not recommended)...'); - await storageService.storePlainKey(pbkdf2Key); + // Chiffrer avec une clĂ© dĂ©terminĂ©e en dur (non sĂ©curisĂ©) + console.log('⚠ Storing PBKDF2 key with hardcoded encryption (not recommended)...'); + const hardcodedKey = '4NK_DEFAULT_ENCRYPTION_KEY_NOT_SECURE'; + const encryptedKeyNone = await encryptionService.encrypt(pbkdf2Key, hardcodedKey); + await storageService.storeEncryptedKey(encryptedKeyNone, securityMode); break; default: @@ -347,57 +344,6 @@ export class SecureCredentialsService { } } - /** - * GĂ©nĂšre des credentials pour le navigateur - */ - private async generateBrowserCredentials( - password: string, - _options: CredentialOptions = {} - ): Promise { - try { - secureLogger.info('Generating browser-saved credentials', { - component: 'SecureCredentialsService', - operation: 'generateBrowserCredentials' - }); - - // Import dynamique du service - const { EncryptionService } = await import('./encryption.service'); - const encryptionService = EncryptionService.getInstance(); - - // GĂ©nĂ©rer des clĂ©s alĂ©atoires - const keys = encryptionService.generateRandomKeys(); - - // CrĂ©er un formulaire temporaire pour dĂ©clencher la sauvegarde du navigateur - const form = document.createElement('form'); - form.style.cssText = 'position: absolute; left: -9999px; top: -9999px;'; - form.innerHTML = ` - - - - `; - - document.body.appendChild(form); - const submitEvent = new Event('submit', { bubbles: true, cancelable: true }); - form.dispatchEvent(submitEvent); - await new Promise(resolve => setTimeout(resolve, 1000)); - document.body.removeChild(form); - - return { - spendKey: keys.spendKey, - scanKey: keys.scanKey, - salt: new Uint8Array(0), - iterations: 0, - timestamp: Date.now() - }; - } catch (error) { - secureLogger.error('Failed to generate browser credentials', error as Error, { - component: 'SecureCredentialsService', - operation: 'generateBrowserCredentials' - }); - throw error; - } - } - /** * GĂ©nĂšre des credentials chiffrĂ©s */ diff --git a/src/services/security-mode.service.ts b/src/services/security-mode.service.ts index 164f567..5f20d79 100644 --- a/src/services/security-mode.service.ts +++ b/src/services/security-mode.service.ts @@ -6,7 +6,7 @@ import { secureLogger } from './secure-logger'; -export type SecurityMode = 'proton-pass' | 'os' | 'browser' | 'otp' | '2fa' | 'password' | 'none'; +export type SecurityMode = 'proton-pass' | 'os' | 'otp' | '2fa' | 'password' | 'none'; export interface SecurityModeConfig { mode: SecurityMode; @@ -20,6 +20,8 @@ export interface SecurityModeConfig { useEncryption: boolean; usePlatformAuth: boolean; storageType: 'encrypted' | 'plain' | 'hybrid'; + requiresOTP?: boolean; + requiresPassword?: boolean; }; } @@ -124,20 +126,6 @@ export class SecurityModeService { storageType: 'encrypted' } }, - 'browser': { - mode: 'browser', - name: 'Navigateur', - description: 'Utilise les fonctionnalitĂ©s de sĂ©curitĂ© du navigateur', - securityLevel: 'medium', - requiresConfirmation: false, - warnings: [], - implementation: { - useWebAuthn: true, - useEncryption: true, - usePlatformAuth: false, - storageType: 'encrypted' - } - }, 'otp': { mode: 'otp', name: 'OTP (Proton Pass Compatible)', @@ -193,19 +181,20 @@ export class SecurityModeService { 'none': { mode: 'none', name: 'Aucune SĂ©curitĂ©', - description: 'Stockage en clair sans aucune protection', + description: 'Chiffrement avec une clĂ© dĂ©terminĂ©e en dur (non sĂ©curisĂ©)', securityLevel: 'critical', requiresConfirmation: true, warnings: [ - '🚹 ClĂ©s stockĂ©es en clair', + '🚹 ClĂ© de chiffrement en dur', '🚹 AccĂšs non protĂ©gĂ©', '🚹 RISQUE ÉLEVÉ' ], implementation: { useWebAuthn: false, - useEncryption: false, + useEncryption: true, usePlatformAuth: false, - storageType: 'plain' + storageType: 'encrypted', + requiresPassword: false } } }; @@ -244,14 +233,14 @@ export class SecurityModeService { * RĂ©cupĂšre tous les modes disponibles */ public getAvailableModes(): SecurityMode[] { - return ['proton-pass', 'os', 'browser', '2fa', 'none']; + return ['proton-pass', 'os', 'otp', '2fa', 'password', 'none']; } /** * RĂ©cupĂšre les modes recommandĂ©s (sĂ©curisĂ©s) */ public getRecommendedModes(): SecurityMode[] { - return ['proton-pass', 'os', 'browser']; + return ['proton-pass', 'os', 'otp']; } /** diff --git a/src/services/service.ts b/src/services/service.ts index 4d57a9b..030bb19 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -1841,16 +1841,16 @@ export default class Services { if (dbRes['encrypted_device']) { // New encrypted format - need to decrypt console.log('🔐 Wallet found in encrypted format, decrypting...'); - + // Get the PBKDF2 key based on security mode const { SecureCredentialsService } = await import('./secure-credentials.service'); const secureCredentialsService = SecureCredentialsService.getInstance(); - + // Get all security modes to find which one works - const allSecurityModes = ['browser', 'otp', 'password', 'none', 'os', 'proton-pass']; + const allSecurityModes = ['otp', 'password', 'none', 'os', 'proton-pass']; let pbkdf2Key: string | null = null; let workingMode: string | null = null; - + for (const mode of allSecurityModes) { try { const key = await secureCredentialsService.retrievePBKDF2Key(mode as any); @@ -1863,20 +1863,20 @@ export default class Services { // Continue to next mode } } - + if (!pbkdf2Key) { throw new Error('Failed to retrieve PBKDF2 key - cannot decrypt wallet'); } - + // Decrypt the device const { EncryptionService } = await import('./encryption.service'); const encryptionService = EncryptionService.getInstance(); - + const decryptedDeviceString = await encryptionService.decrypt( dbRes['encrypted_device'], pbkdf2Key ); - + const decryptedDevice = JSON.parse(decryptedDeviceString); console.log('✅ Wallet decrypted successfully'); return decryptedDevice;