Refactor wallet setup and improve error handling

**Motivations:**
• Simplify wallet key extraction logic using restoreDevice API
• Improve error handling and logging throughout the application
• Remove unused scanner.js file
• Enhance secure credential management service
• Standardize logging format for better debugging
• Fix storage service error handling

**Modifications:**
• Updated wallet-setup page to use proper wallet key extraction
• Refactored secure-credentials service with better error handling
• Improved storage service with proper error logging
• Enhanced validation modal and device management components
• Updated error utilities and logger with standardized formats
• Removed deprecated scanner.js file
• Fixed birthday-setup and block-sync page error handling
• Updated security-setup page with improved error messages
• Enhanced websocket manager error handling
• Improved prerequisite utils and subscription utils
• Fixed sp-address utils error handling
• Updated encoder worker with better error logging

**Pages affected:**
• device-management component
• validation-modal component
• birthday-setup page
• block-sync page
• pairing page
• security-setup page
• wallet-setup page
• router
• All service files (secure-credentials, secure-key-manager, service, storage, token, websocket-manager)
• All utility files (errors, logger, prerequisites, sp-address, subscription)
• encoder worker
This commit is contained in:
NicolasCantu 2025-10-30 07:40:59 +01:00
parent c9ff430b09
commit 222f92e058
21 changed files with 189 additions and 173 deletions

View File

@ -1,5 +1,6 @@
import Services from '../../services/service';
import { addressToWords } from '../../utils/sp-address.utils';
import { secureLogger } from '../../services/secure-logger';
// Global function declarations
declare global {
@ -51,7 +52,7 @@ export class DeviceManagementComponent extends HTMLElement {
}
}
} catch (error) {
console.error('Error loading device data:', error);
secureLogger.error('Error loading device data', error as Error, { component: 'DeviceManagement' });
}
}
@ -797,7 +798,7 @@ export class DeviceManagementComponent extends HTMLElement {
window.location.reload();
}, 2000);
} catch (error) {
console.error('❌ Erreur lors de la suppression du compte:', error);
secureLogger.error('Erreur lors de la suppression du compte', error as Error, { component: 'DeviceManagement' });
this.showStatus(`❌ Erreur lors de la suppression du compte: ${error}`, 'error');
}
}
@ -834,9 +835,9 @@ export class DeviceManagementComponent extends HTMLElement {
// Add to document body
document.body.appendChild(navContainer);
console.log('✅ Account navigation injected');
secureLogger.info('Account navigation injected', { component: 'DeviceManagement' });
} catch (error) {
console.error('❌ Error injecting account navigation:', error);
secureLogger.error('Error injecting account navigation', error as Error, { component: 'DeviceManagement' });
}
}
}

View File

@ -1,13 +1,14 @@
import ModalService from '../../services/modal.service';
import { secureLogger } from '../../services/secure-logger';
async function validate() {
console.log('==> VALIDATE');
secureLogger.debug('Validation modal triggered', { component: 'ValidationModal' });
const modalservice = await ModalService.getInstance();
modalservice.closeValidationModal();
}
export async function initValidationModal(processDiffs: any) {
console.log('🚀 ~ initValidationModal ~ processDiffs:', processDiffs);
secureLogger.debug('Initializing validation modal', { component: 'ValidationModal', data: processDiffs });
for (const diff of processDiffs.diffs) {
let diffs = '';
for (const value of diff) {

View File

@ -16,8 +16,8 @@ document.addEventListener('DOMContentLoaded', async () => {
isInitializing = true;
secureLogger.info('🎂 Birthday setup page loaded', { component: 'BirthdaySetup' });
console.log('🔍 Current URL:', window.location.href);
console.log('🔍 Referrer:', document.referrer);
secureLogger.debug(`Current URL: ${window.location.href}`, { component: 'BirthdaySetup' });
secureLogger.debug(`Referrer: ${document.referrer}`, { component: 'BirthdaySetup' });
const status = document.getElementById('status') as HTMLDivElement;
const progressBar = document.getElementById('progressBar') as HTMLDivElement;
@ -31,7 +31,7 @@ document.addEventListener('DOMContentLoaded', async () => {
try {
secureLogger.info('🔄 Importing services...', { component: 'BirthdaySetup' });
const serviceModule = await import('../../services/service');
console.log('✅ Service module imported:', Object.keys(serviceModule));
secureLogger.debug(`Service module imported: ${Object.keys(serviceModule)}`, { component: 'BirthdaySetup' });
// La classe Services est exportée par défaut
const Services = serviceModule.default;
@ -84,7 +84,7 @@ document.addEventListener('DOMContentLoaded', async () => {
// Vérifier que le wallet contient bien les données attendues
if (wallet.sp_wallet?.birthday !== undefined) {
console.log('✅ Wallet found in database with birthday:', wallet.sp_wallet.birthday);
secureLogger.info(`Wallet found in database with birthday: ${wallet.sp_wallet.birthday}`, { component: 'BirthdaySetup' });
} else {
throw new Error('Wallet found but missing required data (sp_wallet or birthday)');
}
@ -127,8 +127,8 @@ document.addEventListener('DOMContentLoaded', async () => {
// Vérifier que les relais sont connectés et que le handshake a été reçu
const currentBlockHeight = services.getCurrentBlockHeight();
if (currentBlockHeight !== -1 && currentBlockHeight > 0) {
console.log('✅ Relays connected successfully, chain_tip:', currentBlockHeight);
console.log('✅ Communication handshake completed, chain_tip:', currentBlockHeight);
secureLogger.info(`Relays connected successfully, chain_tip: ${currentBlockHeight}`, { component: 'BirthdaySetup' });
secureLogger.info(`Communication handshake completed, chain_tip: ${currentBlockHeight}`, { component: 'BirthdaySetup' });
} else {
throw new Error('Handshake not received or chain_tip not set');
}
@ -146,11 +146,14 @@ document.addEventListener('DOMContentLoaded', async () => {
secureLogger.info('🔄 Verifying birthday update...', { component: 'BirthdaySetup' });
const updatedWallet = await services.getDeviceFromDatabase();
if (updatedWallet?.sp_wallet?.birthday && updatedWallet.sp_wallet.birthday > 0) {
console.log('✅ Birthday updated successfully:', updatedWallet.sp_wallet.birthday);
secureLogger.info(`Birthday updated successfully: ${updatedWallet.sp_wallet.birthday}`, { component: 'BirthdaySetup' });
} else {
console.error('❌ Birthday update verification failed:', {
birthday: updatedWallet?.sp_wallet?.birthday,
hasSpWallet: !!updatedWallet?.sp_wallet
secureLogger.error('Birthday update verification failed', new Error('Verification failed'), {
component: 'BirthdaySetup',
data: {
birthday: updatedWallet?.sp_wallet?.birthday,
hasSpWallet: !!updatedWallet?.sp_wallet
}
});
throw new Error(`Birthday update verification failed: expected birthday > 0, got ${updatedWallet?.sp_wallet?.birthday}`);
}
@ -170,13 +173,13 @@ document.addEventListener('DOMContentLoaded', async () => {
}, 1000);
} catch (error) {
console.error('❌ Services not available:', error);
secureLogger.error('Services not available', error as Error, { component: 'BirthdaySetup' });
updateStatus('❌ Erreur: Services non disponibles', 'error');
throw error;
}
} catch (error) {
console.error('❌ Error during birthday setup:', error);
secureLogger.error('Error during birthday setup', error as Error, { component: 'BirthdaySetup' });
updateStatus('❌ Erreur lors de la configuration de la date anniversaire', 'error');
} finally {
isInitializing = false;

View File

@ -91,7 +91,7 @@ document.addEventListener("DOMContentLoaded", async () => {
break;
} catch (error) {
attempts++;
console.log(`⚠️ Services initialization failed (attempt ${attempts}/${maxAttempts}):`, error);
secureLogger.warn(`Services initialization failed (attempt ${attempts}/${maxAttempts})`, error as Error, { component: 'BlockSync' });
if (attempts >= maxAttempts) {
throw new Error('Failed to initialize services after maximum attempts');
}
@ -214,14 +214,14 @@ document.addEventListener("DOMContentLoaded", async () => {
} catch (error) {
// Restaurer la fonction console.log originale en cas d'erreur
console.log = originalConsoleLog;
console.error('❌ Error during block scan:', error);
secureLogger.error('Error during block scan', error as Error, { component: 'BlockSync' });
updateStatus(`❌ Erreur lors de la synchronisation: ${(error as Error).message}`, 'error');
updateSyncItem('blocksToScan', 'Erreur', 'error');
throw error;
}
} catch (error) {
console.error('❌ Error in block sync page:', error);
secureLogger.error('Error in block sync page', error as Error, { component: 'BlockSync' });
updateStatus(`❌ Erreur: ${(error as Error).message}`, 'error');
// Rediriger vers la page appropriée selon l'erreur

View File

@ -90,7 +90,7 @@ document.addEventListener('DOMContentLoaded', async () => {
// Vérifier que le wallet contient bien les données attendues
if (wallet.sp_wallet?.birthday !== undefined) {
console.log('✅ Wallet found in database with birthday:', wallet.sp_wallet.birthday);
secureLogger.info(`Wallet found in database with birthday: ${wallet.sp_wallet.birthday}`, { component: 'Pairing' });
} else {
throw new Error('Wallet found but missing required data (sp_wallet or birthday)');
}
@ -153,7 +153,7 @@ document.addEventListener('DOMContentLoaded', async () => {
secureLogger.info('✅ Pairing page initialization completed', { component: 'PairingPage' });
} catch (error) {
console.error('❌ Error initializing pairing page:', error);
secureLogger.error('Error initializing pairing page', error as Error, { component: 'Pairing' });
updateStatus(`❌ Erreur: ${(error as Error).message}`, 'error');
// Si l'erreur est liée aux prérequis, rediriger vers la page appropriée

View File

@ -14,7 +14,7 @@ document.addEventListener('DOMContentLoaded', async () => {
// Initialiser la base de données avec la configuration complète
try {
secureLogger.debug('🔍 Initializing database ${DATABASE_CONFIG.name} version ${DATABASE_CONFIG.version}...', { component: 'SecuritySetup' });
secureLogger.debug(`🔍 Initializing database ${DATABASE_CONFIG.name} version ${DATABASE_CONFIG.version}...`, { component: 'SecuritySetup' });
await openDatabase();
secureLogger.info('✅ Database initialized successfully', { component: 'SecuritySetup' });
} catch (error) {
@ -62,7 +62,7 @@ document.addEventListener('DOMContentLoaded', async () => {
}
try {
console.log('🔐 Processing security mode:', selectedMode);
secureLogger.info(`Processing security mode: ${selectedMode}`, { component: 'SecuritySetup' });
// Sauvegarder le mode de sécurité
const { SecurityModeService } = await import('../../services/security-mode.service');
@ -71,7 +71,7 @@ document.addEventListener('DOMContentLoaded', async () => {
secureLogger.info('✅ Security mode saved successfully', { component: 'SecuritySetup' });
console.log('🔐 Generating PBKDF2 key for security mode:', selectedMode);
secureLogger.info(`Generating PBKDF2 key for security mode: ${selectedMode}`, { component: 'SecuritySetup' });
// Désactiver le bouton pendant la génération
continueBtn.disabled = true;
@ -82,7 +82,7 @@ document.addEventListener('DOMContentLoaded', async () => {
const { SecureCredentialsService } = await import('../../services/secure-credentials.service');
const secureCredentialsService = SecureCredentialsService.getInstance();
console.log('🔐 Generating PBKDF2 key with security mode:', selectedMode);
secureLogger.info(`Generating PBKDF2 key with security mode: ${selectedMode}`, { component: 'SecuritySetup' });
// Générer la clé PBKDF2 et la stocker selon le mode
// IMPORTANT: Cette opération doit être directe (pas de délai) pour que WebAuthn fonctionne
@ -94,7 +94,7 @@ document.addEventListener('DOMContentLoaded', async () => {
window.location.href = '/src/pages/wallet-setup/wallet-setup.html';
} catch (error) {
console.error('❌ PBKDF2 key generation failed:', error);
secureLogger.error('PBKDF2 key generation failed', error as Error, { component: 'SecuritySetup' });
alert('Erreur lors de la génération de la clé de sécurité. Veuillez réessayer.');
// Réactiver le bouton
@ -103,7 +103,7 @@ document.addEventListener('DOMContentLoaded', async () => {
}
} catch (error) {
console.error('❌ Error processing security mode:', error);
secureLogger.error('Error processing security mode', error as Error, { component: 'SecuritySetup' });
alert('Erreur lors du traitement du mode de sécurité');
// Réactiver le bouton

View File

@ -69,7 +69,7 @@ document.addEventListener('DOMContentLoaded', async () => {
}
const currentMode = pbkdf2KeyResult.mode;
console.log('✅ Prerequisites verified: PBKDF2 key found in pbkdf2keys store for mode:', currentMode);
secureLogger.info(`Prerequisites verified: PBKDF2 key found in pbkdf2keys store for mode: ${currentMode}`, { component: 'WalletSetup' });
// Étape 1.5: Vérifier si un wallet existe déjà
updateStatus('🔍 Vérification du wallet existant...', 'loading');
@ -135,7 +135,7 @@ document.addEventListener('DOMContentLoaded', async () => {
await Promise.all(cacheNames.map(name => caches.delete(name)));
secureLogger.info('🧹 Caches cleared', { component: 'WalletSetup' });
} catch (e) {
console.warn('⚠️ Cache cleanup error:', e);
secureLogger.warn('Cache cleanup error', e as Error, { component: 'WalletSetup' });
}
}
@ -159,7 +159,7 @@ document.addEventListener('DOMContentLoaded', async () => {
try {
secureLogger.info('🔄 Importing services...', { component: 'WalletSetup' });
const serviceModule = await import('../../services/service');
console.log('✅ Service module imported:', Object.keys(serviceModule));
secureLogger.debug(`Service module imported: ${Object.keys(serviceModule)}`, { component: 'WalletSetup' });
// La classe Services est exportée par défaut
const Services = serviceModule.default;
@ -182,7 +182,7 @@ document.addEventListener('DOMContentLoaded', async () => {
break;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.log(`Services not ready yet (attempt ${attempts + 1}/${maxAttempts}):`, errorMessage);
secureLogger.debug(`Services not ready yet (attempt ${attempts + 1}/${maxAttempts}): ${errorMessage}`, { component: 'WalletSetup' });
// Si c'est une erreur de mémoire, arrêter immédiatement
if (errorMessage.includes('Out of memory') || errorMessage.includes('insufficient memory')) {
@ -208,7 +208,7 @@ document.addEventListener('DOMContentLoaded', async () => {
}
}
} catch (error) {
console.error('❌ Services not available:', error);
secureLogger.error('Services not available', error as Error, { component: 'WalletSetup' });
throw error;
}
@ -221,7 +221,7 @@ document.addEventListener('DOMContentLoaded', async () => {
// Le mode de sécurité a déjà été trouvé dans la vérification des prérequis
// currentMode est déjà défini et vérifié
console.log('🔐 Using security mode for wallet encryption:', currentMode);
secureLogger.info(`Using security mode for wallet encryption: ${currentMode}`, { component: 'WalletSetup' });
// Générer un wallet temporaire avec état birthday_waiting
const { EncryptionService } = await import('../../services/encryption.service');
@ -237,14 +237,14 @@ document.addEventListener('DOMContentLoaded', async () => {
created_at: new Date().toISOString()
};
console.log('🔐 Wallet data generated:', walletData);
secureLogger.debug('Wallet data generated', { component: 'WalletSetup', data: walletData });
// Récupérer la clé PBKDF2 existante pour le mode détecté
// IMPORTANT: Ne PAS générer de nouvelle clé, utiliser celle qui existe
console.log('🔐 Retrieving existing PBKDF2 key for security mode:', currentMode);
secureLogger.info(`Retrieving existing PBKDF2 key for security mode: ${currentMode}`, { component: 'WalletSetup' });
const pbkdf2Key = pbkdf2KeyResult.key;
if (!pbkdf2Key) {
console.error('❌ CRITICAL: Failed to retrieve PBKDF2 key for mode:', currentMode);
secureLogger.error(`CRITICAL: Failed to retrieve PBKDF2 key for mode: ${currentMode}`, { component: 'WalletSetup' });
updateStatus('❌ Erreur: Impossible de récupérer la clé de chiffrement.', 'error');
throw new Error('CRITICAL: Failed to retrieve PBKDF2 key');
}
@ -256,21 +256,21 @@ document.addEventListener('DOMContentLoaded', async () => {
pbkdf2Key
);
secureLogger.info('🔐 Wallet encrypted with PBKDF2 key', { component: 'WalletSetup' });
console.log('🔐 Encrypted wallet data:', encryptedWallet);
secureLogger.debug('Encrypted wallet data', { component: 'WalletSetup', data: encryptedWallet });
// Ouvrir la base de données 4nk existante sans la modifier
console.log(`🔍 Opening IndexedDB database "${DATABASE_CONFIG.name}" version ${DATABASE_CONFIG.version}...`);
secureLogger.info(`Opening IndexedDB database "${DATABASE_CONFIG.name}" version ${DATABASE_CONFIG.version}...`, { component: 'WalletSetup' });
const db = await new Promise<IDBDatabase>((resolve, reject) => {
const request = indexedDB.open(DATABASE_CONFIG.name, DATABASE_CONFIG.version); // Utiliser la version centralisée
request.onerror = () => {
console.error('❌ Failed to open IndexedDB:', request.error);
secureLogger.error('Failed to open IndexedDB', request.error as Error, { component: 'WalletSetup' });
reject(request.error);
};
request.onsuccess = () => {
secureLogger.info('✅ IndexedDB opened successfully', { component: 'WalletSetup' });
console.log('🔍 Database name:', request.result.name);
console.log('🔍 Database version:', request.result.version);
console.log('🔍 Available stores:', Array.from(request.result.objectStoreNames));
secureLogger.debug(`Database name: ${request.result.name}`, { component: 'WalletSetup' });
secureLogger.debug(`Database version: ${request.result.version}`, { component: 'WalletSetup' });
secureLogger.debug(`Available stores: ${Array.from(request.result.objectStoreNames)}`, { component: 'WalletSetup' });
resolve(request.result);
};
request.onupgradeneeded = () => {
@ -299,26 +299,29 @@ document.addEventListener('DOMContentLoaded', async () => {
// We set birthday later when we have the chain tip from relay
secureLogger.info('🔧 Creating new device with birthday 0...', { component: 'WalletSetup' });
const spAddress = await services.sdkClient.create_new_device(0, 'signet');
console.log('✅ Device created with address:', spAddress);
secureLogger.info(`Device created with address: ${spAddress}`, { component: 'WalletSetup' });
// Force wallet generation to ensure keys are created
secureLogger.info('🔧 Forcing wallet generation...', { component: 'WalletSetup' });
try {
const wallet = await services.sdkClient.dump_wallet();
console.log('✅ Wallet generated:', JSON.stringify(wallet));
secureLogger.debug('Wallet generated', { component: 'WalletSetup', data: wallet });
} catch (walletError) {
console.warn('⚠️ Wallet generation failed:', walletError);
secureLogger.warn('Wallet generation failed', walletError as Error, { component: 'WalletSetup' });
}
// Récupérer le device créé par le SDK
const device = services.dumpDeviceFromMemory();
console.log('🔍 Device structure from SDK:', {
hasSpWallet: !!device.sp_wallet,
hasSpClient: !!device.sp_client,
spClientKeys: device.sp_client ? Object.keys(device.sp_client) : 'none'
secureLogger.debug('Device structure from SDK', {
component: 'WalletSetup',
data: {
hasSpWallet: !!device.sp_wallet,
hasSpClient: !!device.sp_client,
spClientKeys: device.sp_client ? Object.keys(device.sp_client) : 'none'
}
});
secureLogger.debug('🔍 Opening transaction for ${DATABASE_CONFIG.stores.wallet.name} store...', { component: 'WalletSetup' });
secureLogger.debug(`Opening transaction for ${DATABASE_CONFIG.stores.wallet.name} store...`, { component: 'WalletSetup' });
// CRITICAL: Chiffrer TOUS les données du wallet avant stockage
// Le device contient des données sensibles (sp_wallet) qui ne doivent JAMAIS être en clair
@ -330,7 +333,7 @@ document.addEventListener('DOMContentLoaded', async () => {
await new Promise<void>((resolve, reject) => {
const transaction = db.transaction([DATABASE_CONFIG.stores.wallet.name], 'readwrite');
const store = transaction.objectStore(DATABASE_CONFIG.stores.wallet.name);
console.log('🔍 Store opened:', store.name);
secureLogger.debug(`Store opened: ${store.name}`, { component: 'WalletSetup' });
// Stocker UNIQUEMENT des données chiffrées - aucun wallet en clair
const walletObject = {
@ -340,34 +343,40 @@ document.addEventListener('DOMContentLoaded', async () => {
};
secureLogger.debug('🔍 Attempting to save encrypted wallet object', { component: 'WalletSetup' });
console.log('🔐 Object contains only encrypted data:', {
hasEncryptedDevice: !!walletObject.encrypted_device,
hasEncryptedWallet: !!walletObject.encrypted_wallet,
// Ne pas logger le contenu chiffré
secureLogger.debug('Object contains only encrypted data', {
component: 'WalletSetup',
data: {
hasEncryptedDevice: !!walletObject.encrypted_device,
hasEncryptedWallet: !!walletObject.encrypted_wallet
// Ne pas logger le contenu chiffré
}
});
// Le store utilise des clés in-line (keyPath: 'pre_id'), ne pas fournir de clé explicite
const request = store.put(walletObject);
request.onsuccess = () => {
secureLogger.info('✅ Wallet saved in IndexedDB with correct format', { component: 'WalletSetup' });
console.log('🔍 Saved wallet object:', walletObject);
secureLogger.debug('Saved wallet object', { component: 'WalletSetup', data: walletObject });
resolve();
};
request.onerror = () => {
console.error('❌ Failed to save wallet in IndexedDB:', request.error);
secureLogger.error('Failed to save wallet in IndexedDB', request.error as Error, { component: 'WalletSetup' });
reject(request.error);
};
transaction.oncomplete = () => {
secureLogger.info('✅ Transaction completed successfully', { component: 'WalletSetup' });
console.log('🔍 Transaction completed for store:', store.name);
secureLogger.debug(`Transaction completed for store: ${store.name}`, { component: 'WalletSetup' });
};
transaction.onerror = () => {
console.error('❌ Transaction failed:', transaction.error);
console.error('🔍 Transaction error details:', {
error: transaction.error,
store: store.name,
mode: transaction.mode
secureLogger.error('Transaction failed', transaction.error as Error, { component: 'WalletSetup' });
secureLogger.error('Transaction error details', new Error('Transaction failed'), {
component: 'WalletSetup',
data: {
error: transaction.error,
store: store.name,
mode: transaction.mode
}
});
reject(transaction.error);
};
@ -380,19 +389,22 @@ document.addEventListener('DOMContentLoaded', async () => {
const verificationRequest = store.get('1');
verificationRequest.onsuccess = () => {
console.log('🔍 Verification result structure:', verificationRequest.result ? {
hasPreId: !!verificationRequest.result.pre_id,
hasEncryptedDevice: !!verificationRequest.result.encrypted_device,
hasEncryptedWallet: !!verificationRequest.result.encrypted_wallet,
hasDeviceInClear: !!verificationRequest.result.device // DEVRAIT ÊTRE NULL
} : 'null');
secureLogger.debug('Verification result structure', {
component: 'WalletSetup',
data: verificationRequest.result ? {
hasPreId: !!verificationRequest.result.pre_id,
hasEncryptedDevice: !!verificationRequest.result.encrypted_device,
hasEncryptedWallet: !!verificationRequest.result.encrypted_wallet,
hasDeviceInClear: !!verificationRequest.result.device // DEVRAIT ÊTRE NULL
} : 'null'
});
if (verificationRequest.result) {
console.log('✅ Wallet verification: Found in IndexedDB with key "1"');
secureLogger.info('Wallet verification: Found in IndexedDB with key "1"', { component: 'WalletSetup' });
// Vérifier qu'il n'y a AUCUN wallet en clair
if (verificationRequest.result.device) {
secureLogger.error('CRITICAL: Device in clear found in database! This should be encrypted.', { component: 'WalletSetup' });
secureLogger.error('CRITICAL: Device in clear found in database! This should be encrypted.', { component: 'WalletSetup' });
reject(new Error('Security violation: wallet stored in clear'));
return;
}
@ -407,19 +419,19 @@ document.addEventListener('DOMContentLoaded', async () => {
secureLogger.info('✅ Wallet stored correctly: only encrypted data present', { component: 'WalletSetup' });
resolve();
} else {
console.error('❌ Wallet verification: Not found in IndexedDB with key "1"');
secureLogger.error('Wallet verification: Not found in IndexedDB with key "1"', { component: 'WalletSetup' });
reject(new Error('Wallet not found after save'));
}
};
verificationRequest.onerror = () => {
console.error('❌ Wallet verification failed:', verificationRequest.error);
secureLogger.error('Wallet verification failed', verificationRequest.error as Error, { component: 'WalletSetup' });
reject(verificationRequest.error);
};
});
// Le mode de sécurité est déjà stocké via la clé PBKDF2 dans le store pbkdf2keys
// Pas besoin de le stocker séparément
console.log('🔐 Security mode is implicitly stored via PBKDF2 key:', currentMode);
secureLogger.info(`Security mode is implicitly stored via PBKDF2 key: ${currentMode}`, { component: 'WalletSetup' });
// Vérification finale : s'assurer que le wallet est bien dans IndexedDB
secureLogger.debug('🔍 Final verification: checking wallet in IndexedDB...', { component: 'WalletSetup' });

View File

@ -1098,7 +1098,7 @@ async function handlePairing4WordsCreate(_event: MessageEvent) {
// Pairing creation initiated - no response needed
} catch (error) {
const errorMsg = `Error creating 4 words pairing: ${error}`;
console.error(errorMsg);
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
}
@ -1121,7 +1121,7 @@ async function handlePairing4WordsJoin(event: MessageEvent) {
// Pairing join initiated - no response needed
} catch (error) {
const errorMsg = `Error joining 4 words pairing: ${error}`;
console.error(errorMsg);
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
}

View File

@ -1,17 +0,0 @@
function onScanSuccess(decodedText, decodedResult) {
// handle the scanned code as you like, for example:
console.log(`Code matched = ${decodedText}`, decodedResult);
}
function onScanFailure(error) {
// handle scan failure, usually better to ignore and keep scanning.
// for example:
console.warn(`Code scan error = ${error}`);
}
let html5QrcodeScanner = new Html5QrcodeScanner(
'reader',
{ fps: 10, qrbox: { width: 250, height: 250 } },
/* verbose= */ false
);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);

View File

@ -277,28 +277,28 @@ export class SecureCredentialsService {
// Essayer d'abord de récupérer une clé existante
const existingKey = await this.retrievePBKDF2Key(securityMode);
if (existingKey) {
console.log('🔐 Existing PBKDF2 key found:', existingKey.substring(0, 8) + '...');
secureLogger.debug(`Existing PBKDF2 key found: ${existingKey.substring(0, 8)}...`, { component: 'SecureCredentials' });
return existingKey;
}
// Générer une nouvelle clé PBKDF2 si aucune n'existe
const pbkdf2Key = encryptionService.generateRandomKey();
console.log('🔐 New PBKDF2 key generated:', pbkdf2Key.substring(0, 8) + '...');
secureLogger.info(`New PBKDF2 key generated: ${pbkdf2Key.substring(0, 8)}...`, { component: 'SecureCredentials' });
// Stocker la clé selon le mode de sécurité
switch (securityMode) {
case 'proton-pass':
case 'os':
// Stocker avec WebAuthn (authentification biométrique)
console.log('🔐 Storing PBKDF2 key with WebAuthn authentication...');
secureLogger.info('Storing PBKDF2 key with WebAuthn authentication...', { component: 'SecureCredentials' });
await webAuthnService.storeKeyWithWebAuthn(pbkdf2Key, securityMode);
break;
case 'otp':
// Générer un secret OTP pour l'authentification (pas de chiffrement)
console.log('🔐 Setting up OTP authentication for PBKDF2 key...');
secureLogger.info('Setting up OTP authentication for PBKDF2 key...', { component: 'SecureCredentials' });
const otpSecret = await this.generateOTPSecret();
console.log('🔐 OTP Secret generated:', otpSecret);
secureLogger.debug(`OTP Secret generated: ${otpSecret}`, { component: 'SecureCredentials' });
// Stocker la clé PBKDF2 en clair dans pbkdf2keys (l'OTP protège l'accès, pas le stockage)
await this.storePBKDF2KeyInStore(pbkdf2Key, securityMode);
// Afficher le QR code pour l'utilisateur
@ -307,7 +307,7 @@ export class SecureCredentialsService {
case 'password':
// Utiliser l'API Credential Management du navigateur
console.log('🔐 Storing PBKDF2 key with browser password manager...');
secureLogger.info('Storing PBKDF2 key with browser password manager...', { component: 'SecureCredentials' });
const userPassword = await this.promptForPasswordWithBrowser();
const encryptedKey = await encryptionService.encrypt(pbkdf2Key, userPassword);
await this.storePBKDF2KeyInStore(encryptedKey, securityMode);
@ -315,7 +315,7 @@ export class SecureCredentialsService {
case 'none':
// Chiffrer avec une clé déterminée en dur (non sécurisé)
console.log('⚠️ Storing PBKDF2 key with hardcoded encryption (not recommended)...');
secureLogger.warn('Storing PBKDF2 key with hardcoded encryption (not recommended)...', { component: 'SecureCredentials' });
const hardcodedKey = '4NK_DEFAULT_ENCRYPTION_KEY_NOT_SECURE';
const encryptedKeyNone = await encryptionService.encrypt(pbkdf2Key, hardcodedKey);
await this.storePBKDF2KeyInStore(encryptedKeyNone, securityMode);
@ -482,7 +482,7 @@ export class SecureCredentialsService {
// Dumper le wallet pour récupérer les vraies clés
const wallet = await services.dumpWallet();
console.log('🔑 Wallet dumped for credentials extraction:', typeof wallet);
secureLogger.debug(`Wallet dumped for credentials extraction: ${typeof wallet}`, { component: 'SecureCredentials' });
// Parse le wallet JSON
const walletObj = typeof wallet === 'string' ? JSON.parse(wallet) : wallet;
@ -499,20 +499,23 @@ export class SecureCredentialsService {
scanKeyStr = walletObj.scan_sk;
}
console.log('🔑 Extracted keys from wallet:', {
has_spend_key: !!spendKeyStr,
has_scan_key: !!scanKeyStr,
spend_key_length: spendKeyStr.length,
scan_key_length: scanKeyStr.length
secureLogger.debug('Extracted keys from wallet', {
component: 'SecureCredentials',
data: {
has_spend_key: !!spendKeyStr,
has_scan_key: !!scanKeyStr,
spend_key_length: spendKeyStr.length,
scan_key_length: scanKeyStr.length
}
});
if (!spendKeyStr || !scanKeyStr) {
throw new Error('Failed to extract keys from wallet SDK');
}
} catch (error) {
console.error('❌ Failed to extract keys from wallet SDK:', error);
secureLogger.error('Failed to extract keys from wallet SDK', error as Error, { component: 'SecureCredentials' });
// Fallback: générer des clés aléatoires si extraction échoue
console.warn('⚠️ Fallback: generating random keys');
secureLogger.warn('Fallback: generating random keys', { component: 'SecureCredentials' });
const keys = encryptionService.generateRandomKeys();
spendKeyStr = keys.spendKey;
scanKeyStr = keys.scanKey;
@ -845,8 +848,8 @@ export class SecureCredentialsService {
const account = '4NK Security';
const qrUrl = `otpauth://totp/${encodeURIComponent(account)}?secret=${secret}&issuer=${encodeURIComponent(issuer)}`;
console.log('🔐 OTP QR Code URL:', qrUrl);
console.log('🔐 Manual secret:', secret);
secureLogger.info(`OTP QR Code URL: ${qrUrl}`, { component: 'SecureCredentials' });
secureLogger.info(`Manual secret: ${secret}`, { component: 'SecureCredentials' });
// Afficher une alerte avec les instructions
alert(`🔐 Configuration OTP terminée !
@ -1013,7 +1016,7 @@ QR Code URL: ${qrUrl}`);
private async promptForPasswordWithBrowser(): Promise<string> {
// Vérifier si l'API Credential Management est disponible
if (!navigator.credentials) {
console.warn('⚠️ Credential Management API not available, falling back to modal');
secureLogger.warn('Credential Management API not available, falling back to modal', { component: 'SecureCredentials' });
return this.promptForPassword();
}
@ -1028,11 +1031,11 @@ QR Code URL: ${qrUrl}`);
if (existingCredential?.type === 'password') {
// @ts-ignore - PasswordCredential API may not be in TypeScript definitions
const passwordCredential = existingCredential as any;
console.log('🔐 Retrieved existing password from browser');
secureLogger.info('Retrieved existing password from browser', { component: 'SecureCredentials' });
return passwordCredential.password;
}
} catch (error) {
console.log('🔐 No existing password found, will create new one');
secureLogger.info('No existing password found, will create new one', { component: 'SecureCredentials' });
}
// Si aucun mot de passe existant, créer un nouveau
@ -1118,10 +1121,10 @@ QR Code URL: ${qrUrl}`);
});
await navigator.credentials.store(credential);
console.log('🔐 Password saved to browser password manager');
secureLogger.info('Password saved to browser password manager', { component: 'SecureCredentials' });
}
} catch (error) {
console.warn('⚠️ Failed to save password to browser:', error);
secureLogger.warn('Failed to save password to browser', error as Error, { component: 'SecureCredentials' });
// Continuer même si la sauvegarde échoue
}
@ -1162,7 +1165,7 @@ QR Code URL: ${qrUrl}`);
// Récupérer le mot de passe depuis le gestionnaire de mots de passe du navigateur
const password = await this.getPasswordFromBrowser();
if (!password) {
console.warn('⚠️ No password found in browser, falling back to manual input');
secureLogger.warn('No password found in browser, falling back to manual input', { component: 'SecureCredentials' });
return null;
}
@ -1185,7 +1188,7 @@ QR Code URL: ${qrUrl}`);
private async getPasswordFromBrowser(): Promise<string | null> {
// Vérifier si l'API Credential Management est disponible
if (!navigator.credentials) {
console.warn('⚠️ Credential Management API not available');
secureLogger.warn('Credential Management API not available', { component: 'SecureCredentials' });
return null;
}
@ -1199,11 +1202,11 @@ QR Code URL: ${qrUrl}`);
if (credential?.type === 'password') {
// @ts-ignore - PasswordCredential API may not be in TypeScript definitions
const passwordCredential = credential as any;
console.log('🔐 Retrieved password from browser password manager');
secureLogger.info('Retrieved password from browser password manager', { component: 'SecureCredentials' });
return passwordCredential.password;
}
} catch (error) {
console.log('🔐 No password found in browser password manager');
secureLogger.info('No password found in browser password manager', { component: 'SecureCredentials' });
}
return null;

View File

@ -2,6 +2,8 @@
* SecureKeyManager - Gestion sécurisée des clés privées
* Chiffre les clés privées avant stockage et les déchiffre à la demande
*/
import { secureLogger } from './secure-logger';
export class SecureKeyManager {
private keyStore: CryptoKey | null = null;
private salt: Uint8Array;
@ -19,9 +21,9 @@ export class SecureKeyManager {
const derivedKey = await this.deriveKey(password);
this.keyStore = derivedKey;
this.isInitialized = true;
console.log('🔐 SecureKeyManager initialized');
secureLogger.info('SecureKeyManager initialized', { component: 'SecureKeyManager' });
} catch (error) {
console.error('❌ Failed to initialize SecureKeyManager:', error);
secureLogger.error('Failed to initialize SecureKeyManager', error as Error, { component: 'SecureKeyManager' });
throw new Error('Failed to initialize secure key manager');
}
}
@ -52,9 +54,9 @@ export class SecureKeyManager {
// Stocker dans IndexedDB de manière sécurisée
await this.storeEncryptedData(encryptedData);
console.log('🔐 Private key stored securely');
secureLogger.info('Private key stored securely', { component: 'SecureKeyManager' });
} catch (error) {
console.error('❌ Failed to store private key:', error);
secureLogger.error('Failed to store private key', error as Error, { component: 'SecureKeyManager' });
throw new Error('Failed to store private key securely');
}
}
@ -79,7 +81,7 @@ export class SecureKeyManager {
return new TextDecoder().decode(decrypted);
} catch (error) {
console.error('❌ Failed to retrieve private key:', error);
secureLogger.error('Failed to retrieve private key', error as Error, { component: 'SecureKeyManager' });
return null;
}
}
@ -92,9 +94,9 @@ export class SecureKeyManager {
await this.clearEncryptedData();
this.keyStore = null;
this.isInitialized = false;
console.log('🔐 All keys cleared');
secureLogger.info('All keys cleared', { component: 'SecureKeyManager' });
} catch (error) {
console.error('❌ Failed to clear keys:', error);
secureLogger.error('Failed to clear keys', error as Error, { component: 'SecureKeyManager' });
}
}

View File

@ -197,7 +197,7 @@ export default class Services {
// More aggressive cleanup
secureLogger.debug('🔍 Debugging memory usage...', { component: 'Service' });
secureLogger.info('📦 Document elements:', { component: 'Service', data: document.querySelectorAll('*' }).length);
secureLogger.debug(`Document elements: ${document.querySelectorAll('*').length}`, { component: 'Service' });
// Multiple garbage collections
if (window.gc) {

View File

@ -1,4 +1,5 @@
import axios, { AxiosResponse } from 'axios';
import { secureLogger } from './secure-logger';
export async function storeData(
servers: string[],
@ -28,10 +29,10 @@ export async function storeData(
// Test first that data is not already stored
const testResponse = await testData(url, key);
if (testResponse) {
console.log('Data already stored:', key);
secureLogger.debug(`Data already stored: ${key}`, { component: 'StorageService' });
continue;
} else {
console.log('Data not stored for server:', key, server);
secureLogger.debug(`Data not stored for server: ${key} on ${server}`, { component: 'StorageService' });
}
// Send the encrypted ArrayBuffer as the raw request body.
@ -40,9 +41,9 @@ export async function storeData(
'Content-Type': 'application/octet-stream',
},
});
console.log('Data stored successfully:', key);
secureLogger.info(`Data stored successfully: ${key}`, { component: 'StorageService' });
if (response.status !== 200) {
console.error('Received response status', response.status);
secureLogger.error(`Received response status: ${response.status}`, { component: 'StorageService' });
continue;
}
return response;
@ -50,7 +51,7 @@ export async function storeData(
if (axios.isAxiosError(error) && error.response?.status === 409) {
return null;
}
console.error('Error storing data:', error);
secureLogger.error('Error storing data', error as Error, { component: 'StorageService' });
}
}
return null;
@ -64,7 +65,7 @@ export async function retrieveData(servers: string[], key: string): Promise<Arra
? `${server}/retrieve/${key}` // Relative path - use as-is for proxy
: new URL(`${server}/retrieve/${key}`).toString(); // Absolute URL - construct properly
console.log('Retrieving data', key, ' from:', url);
secureLogger.debug(`Retrieving data ${key} from: ${url}`, { component: 'StorageService' });
// When fetching the data from the server:
const response = await axios.get(url, {
responseType: 'arraybuffer',
@ -75,30 +76,30 @@ export async function retrieveData(servers: string[], key: string): Promise<Arra
if (response.data instanceof ArrayBuffer) {
return response.data;
} else {
console.error('Server returned non-ArrayBuffer data:', typeof response.data);
secureLogger.error(`Server returned non-ArrayBuffer data: ${typeof response.data}`, { component: 'StorageService' });
continue;
}
} else {
console.error(`Server ${server} returned status ${response.status}`);
secureLogger.error(`Server ${server} returned status ${response.status}`, { component: 'StorageService' });
continue;
}
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.status === 404) {
console.log(`Data not found on server ${server} for key ${key}`);
secureLogger.info(`Data not found on server ${server} for key ${key}`, { component: 'StorageService' });
continue; // Try next server
} else if (error.response?.status) {
console.error(
`Server ${server} error ${error.response.status}:`,
error.response.statusText
secureLogger.error(
`Server ${server} error ${error.response.status}: ${error.response.statusText}`,
{ component: 'StorageService' }
);
continue;
} else {
console.error(`Network error connecting to ${server}:`, (error as Error).message);
secureLogger.error(`Network error connecting to ${server}: ${(error as Error).message}`, { component: 'StorageService' });
continue;
}
} else {
console.error(`Unexpected error retrieving data from ${server}:`, error);
secureLogger.error(`Unexpected error retrieving data from ${server}`, error as Error, { component: 'StorageService' });
continue;
}
}
@ -110,13 +111,13 @@ export async function testData(url: string, _key: string): Promise<boolean | nul
try {
const response = await axios.get(url);
if (response.status !== 200) {
console.error(`Test response status: ${response.status}`);
secureLogger.error(`Test response status: ${response.status}`, { component: 'StorageService' });
return false;
}
return true;
} catch (error) {
console.error('Error testing data:', error);
secureLogger.error('Error testing data', error as Error, { component: 'StorageService' });
return null;
}
}

View File

@ -1,4 +1,5 @@
import * as jose from 'jose';
import { secureLogger } from './secure-logger';
interface TokenPair {
accessToken: string;
@ -47,11 +48,11 @@ export default class TokenService {
return payload.origin === origin;
} catch (error: any) {
if (error?.code === 'ERR_JWT_EXPIRED') {
console.log('Token expiré');
secureLogger.info('Token expiré', { component: 'TokenService' });
return false;
}
console.error('Erreur de validation du token:', error);
secureLogger.error('Erreur de validation du token', error as Error, { component: 'TokenService' });
return false;
}
}
@ -80,7 +81,7 @@ export default class TokenService {
return newAccessToken;
} catch (error) {
console.error('Erreur lors du refresh du token:', error);
secureLogger.error('Erreur lors du refresh du token', error as Error, { component: 'TokenService' });
return null;
}
}

View File

@ -2,6 +2,8 @@
* WebSocketManager - Gestion robuste des connexions WebSocket
* Gère la reconnexion automatique, la queue des messages et la gestion d'erreurs
*/
import { secureLogger } from './secure-logger';
export interface WebSocketConfig {
url: string;
reconnectAttempts?: number;
@ -172,7 +174,7 @@ export class WebSocketManager {
try {
callback(data);
} catch (error) {
console.error(`Error in WebSocket event listener for ${event}:`, error);
secureLogger.error(`Error in WebSocket event listener for ${event}`, error as Error, { component: 'WebSocketManager' });
}
});
}

View File

@ -4,6 +4,7 @@
*/
import { logger } from './logger';
import { secureLogger } from '../services/secure-logger';
export enum ErrorCode {
// Erreurs de pairing
@ -223,7 +224,7 @@ export class ErrorHandler {
try {
callback(error);
} catch (callbackError) {
console.error('Error in error callback:', callbackError);
secureLogger.error('Error in error callback', callbackError as Error, { component: 'ErrorHandler' });
}
});

View File

@ -3,6 +3,8 @@
* Fournit des logs cohérents avec différents niveaux et contextes
*/
import { secureLogger } from '../services/secure-logger';
export enum LogLevel {
DEBUG = 0,
INFO = 1,
@ -86,18 +88,18 @@ class Logger {
switch (entry.level) {
case LogLevel.DEBUG:
console.debug(logMessage);
secureLogger.debug(logMessage, { component: 'Logger' });
break;
case LogLevel.INFO:
console.info(logMessage);
secureLogger.info(logMessage, { component: 'Logger' });
break;
case LogLevel.WARN:
console.warn(logMessage);
secureLogger.warn(logMessage, { component: 'Logger' });
break;
case LogLevel.ERROR:
console.error(logMessage);
secureLogger.error(logMessage, { component: 'Logger' });
if (entry.stack) {
console.error(entry.stack);
secureLogger.error(entry.stack, { component: 'Logger' });
}
break;
}

View File

@ -5,6 +5,7 @@
import { SecureCredentialsService } from '../services/secure-credentials.service';
import { DeviceReaderService } from '../services/device-reader.service';
import { secureLogger } from '../services/secure-logger';
export type SecurityMode = 'none' | 'otp' | 'password' | 'os' | 'proton-pass';
@ -23,13 +24,13 @@ export async function checkPBKDF2Key(): Promise<{ key: string; mode: SecurityMod
if (hasKey) {
const key = await secureCredentialsService.retrievePBKDF2Key(mode);
if (key) {
console.log(`PBKDF2 key found in pbkdf2keys store for security mode: ${mode}`);
secureLogger.info(`PBKDF2 key found in pbkdf2keys store for security mode: ${mode}`, { component: 'PrerequisitesUtils' });
return { key, mode };
}
}
} catch (error) {
// Continue to next mode
console.log(`⚠️ No PBKDF2 key found in pbkdf2keys store for mode ${mode}`);
secureLogger.warn(`No PBKDF2 key found in pbkdf2keys store for mode ${mode}`, { component: 'PrerequisitesUtils' });
}
}
@ -52,18 +53,18 @@ export async function checkWalletWithRetries(
const wallet = await deviceReader.getDeviceFromDatabase();
if (wallet) {
if (attempt > 0) {
console.log(`Wallet found after ${attempt + 1} attempts`);
secureLogger.info(`Wallet found after ${attempt + 1} attempts`, { component: 'PrerequisitesUtils' });
}
return wallet;
}
if (attempt < maxAttempts - 1) {
console.log(`⚠️ Wallet not found, waiting for database synchronization (attempt ${attempt + 1}/${maxAttempts})...`);
secureLogger.warn(`Wallet not found, waiting for database synchronization (attempt ${attempt + 1}/${maxAttempts})...`, { component: 'PrerequisitesUtils' });
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
console.log(`⚠️ Wallet still not found after ${maxAttempts} attempts`);
secureLogger.warn(`Wallet still not found after ${maxAttempts} attempts`, { component: 'PrerequisitesUtils' });
return null;
}
@ -80,4 +81,3 @@ export async function checkAllPrerequisites(): Promise<{
return { pbkdf2Key, wallet };
}

View File

@ -2772,7 +2772,7 @@ export async function prepareAndSendPairingTx(): Promise<void> {
// Register device as paired
// Enregistre l'appareil dans le processus de pairing
console.log(`🔐 Pairing 4NK: Enregistrement de l'appareil dans le processus de pairing...`);
secureLogger.info('Pairing 4NK: Enregistrement de l\'appareil dans le processus de pairing...', { component: 'SPAddressUtils' });
service.pairDevice(pairingId, [creatorAddress]);
// Handle API return
@ -2789,15 +2789,15 @@ export async function prepareAndSendPairingTx(): Promise<void> {
// Approve change
// Approbation du changement d'état du processus (nécessaire pour le quorum)
console.log(`🔐 Pairing 4NK: Approbation du changement d'état du processus...`);
secureLogger.info('Pairing 4NK: Approbation du changement d\'état du processus...', { component: 'SPAddressUtils' });
const approveChangeReturn = await service.approveChange(pairingId, stateId);
console.log(`🔐 Pairing 4NK: Résultat de l'approbation:`, approveChangeReturn);
secureLogger.debug('Pairing 4NK: Résultat de l\'approbation', { component: 'SPAddressUtils', data: approveChangeReturn });
await service.handleApiReturn(approveChangeReturn);
secureLogger.info('🔐 Pairing 4NK: Changement approuvé avec succès', { component: 'SPAddressUtils' });
// Wait for pairing commitment
// Attente du commit du processus sur la blockchain (rend l'identité vérifiable)
console.log(`🔐 Pairing 4NK: Attente du commit du processus de pairing sur la blockchain (création d'identité vérifiable)...`);
secureLogger.info('Pairing 4NK: Attente du commit du processus de pairing sur la blockchain (création d\'identité vérifiable)...', { component: 'SPAddressUtils' });
await service.waitForPairingCommitment(pairingId);
secureLogger.info('🔐 Pairing 4NK: Commit du processus de pairing reçu (identité numérique vérifiable créée)', { component: 'SPAddressUtils' });
@ -2822,10 +2822,10 @@ export async function prepareAndSendPairingTx(): Promise<void> {
// Vérifier que l'appareil est maintenant appairé
const isPaired = service.isPaired();
console.log(`🔐 Pairing 4NK: Statut d'appairage après confirmation: ${isPaired ? 'Appairé ✅' : 'Non appairé ⚠️'}`);
secureLogger.info(`Pairing 4NK: Statut d'appairage après confirmation: ${isPaired ? 'Appairé ✅' : 'Non appairé ⚠️'}`, { component: 'SPAddressUtils' });
if (!isPaired) {
console.warn(`⚠️ Pairing 4NK: L'appareil n'est pas détecté comme appairé après confirmation`);
secureLogger.warn('Pairing 4NK: L\'appareil n\'est pas détecté comme appairé après confirmation', { component: 'SPAddressUtils' });
}
// Étape suivante : Récupération et déchiffrement des processus
@ -2850,7 +2850,7 @@ export async function prepareAndSendPairingTx(): Promise<void> {
const lastCommitedState = service.getLastCommitedState(process);
if (!lastCommitedState) {
console.log(` Pairing 4NK: Processus ${processId} n'a pas encore d'état commité`);
secureLogger.info(`Pairing 4NK: Processus ${processId} n'a pas encore d'état commité`, { component: 'SPAddressUtils' });
continue;
}
@ -2871,19 +2871,19 @@ export async function prepareAndSendPairingTx(): Promise<void> {
const decryptedAttribute = await service.decryptAttribute(processId, lastCommitedState, attribute);
if (decryptedAttribute) {
decryptedCount++;
console.log(`Pairing 4NK: Attribut "${attribute}" déchiffré avec succès pour le processus ${processId}`);
secureLogger.info(`Pairing 4NK: Attribut "${attribute}" déchiffré avec succès pour le processus ${processId}`, { component: 'SPAddressUtils' });
} else {
console.log(` Pairing 4NK: Attribut "${attribute}" non accessible ou clé manquante pour le processus ${processId}`);
secureLogger.info(`Pairing 4NK: Attribut "${attribute}" non accessible ou clé manquante pour le processus ${processId}`, { component: 'SPAddressUtils' });
}
} catch (decryptError) {
console.warn(`⚠️ Pairing 4NK: Erreur lors du déchiffrement de l'attribut "${attribute}" pour le processus ${processId}:`, decryptError);
secureLogger.warn(`Pairing 4NK: Erreur lors du déchiffrement de l'attribut "${attribute}" pour le processus ${processId}`, decryptError as Error, { component: 'SPAddressUtils' });
}
}
if (decryptedCount > 0) {
secureLogger.info('✅ Pairing 4NK: ${decryptedCount} attribut(s) déchiffré(s) pour le processus ${processId}', { component: 'SPAddressUtils' });
} else {
console.log(` Pairing 4NK: Aucun attribut déchiffré pour le processus ${processId} (normal si pas d'attributs privés ou pas d'accès)`);
secureLogger.info(`Pairing 4NK: Aucun attribut déchiffré pour le processus ${processId} (normal si pas d'attributs privés ou pas d'accès)`, { component: 'SPAddressUtils' });
}
} catch (processError) {
secureLogger.warn('⚠️ Pairing 4NK: Erreur lors du traitement du processus ${processId}:', { component: 'SPAddressUtils', data: processError });

View File

@ -1,3 +1,5 @@
import { secureLogger } from '../services/secure-logger';
let subscriptions: {
element: Element | Document;
event: any;
@ -5,7 +7,7 @@ let subscriptions: {
}[] = [];
export function cleanSubscriptions(): void {
console.log('🚀 ~ cleanSubscriptions ~ sub:', subscriptions);
secureLogger.debug('Cleaning subscriptions', { component: 'SubscriptionUtils', data: subscriptions });
for (const sub of subscriptions) {
const el = sub.element;
const eventHandler = sub.eventHandler;

View File

@ -115,9 +115,11 @@ async function decodeData(data: any): Promise<any> {
// Gérer les erreurs non capturées
self.addEventListener('error', (error) => {
// Note: secureLogger not available in worker context
console.error('Encoder worker error:', error);
});
self.addEventListener('unhandledrejection', (event) => {
// Note: secureLogger not available in worker context
console.error('Encoder worker unhandled rejection:', event.reason);
});