ihm_client/src/workers/encoder.worker.ts
NicolasCantu bf680ab6dd ci: docker_tag=pbkdf2-credentials
🔐 Implémentation PBKDF2 avec credentials navigateur

 Fonctionnalités ajoutées:
- SecureCredentialsService avec PBKDF2 (100k itérations)
- Chiffrement AES-GCM des clés spend/scan
- Interface utilisateur complète pour gestion credentials
- Tests unitaires complets
- Architecture modulaire avec EventBus
- Gestion mémoire optimisée
- Performance monitoring
- Web Workers pour encodage asynchrone

🛡️ Sécurité:
- Dérivation PBKDF2 avec salt unique
- Chiffrement AES-GCM des clés sensibles
- Validation force mot de passe
- Stockage sécurisé IndexedDB + WebAuthn
- Logging sécurisé sans exposition données

🔧 Corrections:
- Erreur 500 résolue (clé dupliquée package.json)
- Configuration Vite simplifiée
- Dépendances manquantes corrigées

📊 Améliorations:
- Architecture découplée avec repositories
- Services spécialisés (PairingService, etc.)
- Monitoring performance et mémoire
- Tests avec couverture complète
- Documentation technique détaillée
2025-10-23 12:51:49 +02:00

124 lines
2.7 KiB
TypeScript

/**
* Encoder Worker - Web Worker pour l'encodage asynchrone
* Traite les données lourdes sans bloquer le thread principal
*/
export interface EncoderMessage {
type: 'encode' | 'decode';
data: any;
id: string;
}
export interface EncoderResponse {
type: 'success' | 'error';
result?: any;
error?: string;
id: string;
}
// Écouter les messages du thread principal
self.addEventListener('message', async (event: MessageEvent<EncoderMessage>) => {
const { type, data, id } = event.data;
try {
let result: any;
switch (type) {
case 'encode':
result = await encodeData(data);
break;
case 'decode':
result = await decodeData(data);
break;
default:
throw new Error(`Unknown message type: ${type}`);
}
// Envoyer la réponse
const response: EncoderResponse = {
type: 'success',
result,
id
};
self.postMessage(response);
} catch (error) {
// Envoyer l'erreur
const response: EncoderResponse = {
type: 'error',
error: error instanceof Error ? error.message : 'Unknown error',
id
};
self.postMessage(response);
}
});
/**
* Encode les données de manière asynchrone
*/
async function encodeData(data: any): Promise<any> {
// Simuler un encodage lourd
await new Promise(resolve => setTimeout(resolve, 100));
if (typeof data === 'string') {
return btoa(data);
}
if (data instanceof ArrayBuffer) {
const uint8Array = new Uint8Array(data);
return Array.from(uint8Array).map(byte => byte.toString(16).padStart(2, '0')).join('');
}
if (data instanceof Uint8Array) {
return Array.from(data).map(byte => byte.toString(16).padStart(2, '0')).join('');
}
if (typeof data === 'object') {
return JSON.stringify(data);
}
return data;
}
/**
* Décode les données de manière asynchrone
*/
async function decodeData(data: any): Promise<any> {
// Simuler un décodage lourd
await new Promise(resolve => setTimeout(resolve, 50));
if (typeof data === 'string') {
try {
// Essayer de décoder en base64
return atob(data);
} catch {
// Essayer de décoder en hex
const bytes = [];
for (let i = 0; i < data.length; i += 2) {
bytes.push(parseInt(data.substr(i, 2), 16));
}
return new Uint8Array(bytes);
}
}
if (typeof data === 'object') {
try {
return JSON.parse(data);
} catch {
return data;
}
}
return data;
}
// Gérer les erreurs non capturées
self.addEventListener('error', (error) => {
console.error('Encoder worker error:', error);
});
self.addEventListener('unhandledrejection', (event) => {
console.error('Encoder worker unhandled rejection:', event.reason);
});