ihm_client/src/services/security-mode.service.ts
NicolasCantu aa95537254 fix: correct TypeScript and ESLint errors
**Motivations :**
- Corriger les erreurs TypeScript qui bloquaient la compilation
- Corriger les erreurs ESLint pour améliorer la qualité du code
- Utiliser les bons formats pour secureLogger.error

**Modifications :**
- Corriger les appels secureLogger.error pour passer error comme 2e paramètre
- Ajouter les imports manquants (Database dans security-mode.service.ts)
- Préfixer les variables non utilisées avec _ pour respecter ESLint
- Corriger les comparaisons BigInt (utiliser BigInt(0) au lieu de 0n)
- Ajouter @ts-expect-error pour PasswordCredential API expérimentale
- Corriger le paramètre services non utilisé dans router.ts

**Pages affectées :**
- src/services/service.ts (comparaisons BigInt, imports)
- src/services/security-mode.service.ts (import Database)
- src/services/secure-credentials.service.ts (secureLogger.error, PasswordCredential)
- src/services/credentials/encryption.service.ts (secureLogger.error, salt type)
- src/router.ts (paramètre _services)
- src/components/device-management/device-management.ts (variable _data)
- src/components/secure-credentials/secure-credentials.ts (variable _error)
- src/components/security-mode-selector/security-mode-selector.ts (paramètre _mode)
- src/components/login-modal/login-modal.js (window globals)
2025-10-29 16:37:28 +01:00

357 lines
10 KiB
TypeScript

/**
* SecurityModeService - Gestion des modes de sécurisation
* Gère le stockage et la récupération du mode de sécurisation choisi par l'utilisateur
* NOTE: Le mode de sécurité est stocké uniquement avec la clé PBKDF2, pas dans un store séparé
*/
import { secureLogger } from './secure-logger';
import Database from './database.service';
export type SecurityMode = 'proton-pass' | 'os' | 'otp' | '2fa' | 'password' | 'none';
export interface SecurityModeConfig {
mode: SecurityMode;
name: string;
description: string;
securityLevel: 'high' | 'medium' | 'low' | 'critical';
requiresConfirmation: boolean;
warnings: string[];
implementation: {
useWebAuthn: boolean;
useEncryption: boolean;
usePlatformAuth: boolean;
storageType: 'encrypted' | 'plain' | 'hybrid';
requiresOTP?: boolean;
requiresPassword?: boolean;
};
}
export class SecurityModeService {
private static instance: SecurityModeService;
private currentMode: SecurityMode | null = null;
private constructor() {
// N'instancier pas Database ici, il sera récupéré via getInstance() quand nécessaire
}
public static getInstance(): SecurityModeService {
if (!SecurityModeService.instance) {
SecurityModeService.instance = new SecurityModeService();
}
return SecurityModeService.instance;
}
/**
* Récupère le mode de sécurisation actuel
* NOTE: Le mode est stocké uniquement en mémoire, dérivé de la clé PBKDF2 stockée
*/
public async getCurrentMode(): Promise<SecurityMode | null> {
if (this.currentMode) {
return this.currentMode;
}
// Le mode de sécurité n'est pas stocké en base, il est dérivé de la clé PBKDF2
// Ici on retourne null si aucun mode n'est en mémoire
// Le mode sera défini lors de la génération de la clé PBKDF2
secureLogger.info('No security mode in memory (will be set when PBKDF2 key is generated)', {
component: 'SecurityModeService',
operation: 'getCurrentMode'
});
return null;
}
/**
* Définit le mode de sécurisation
* NOTE: Le mode de sécurité est stocké uniquement avec la clé PBKDF2, pas dans un store séparé
*/
public async setSecurityMode(mode: SecurityMode): Promise<void> {
try {
const modeConfig = this.getSecurityModeConfig(mode);
// Stocker uniquement en mémoire
this.currentMode = mode;
secureLogger.info('Security mode set successfully', {
component: 'SecurityModeService',
operation: 'setSecurityMode',
mode,
securityLevel: modeConfig.securityLevel
});
// Émettre un événement pour notifier les autres services
window.dispatchEvent(new CustomEvent('securityModeChanged', {
detail: { mode, config: modeConfig }
}));
} catch (error) {
secureLogger.error('Failed to set security mode', error as Error, {
component: 'SecurityModeService',
operation: 'setSecurityMode',
mode
});
// NE PAS FAIRE DE FALLBACK - échouer complètement
throw error;
}
}
/**
* Récupère la configuration d'un mode de sécurisation
*/
public getSecurityModeConfig(mode: SecurityMode): SecurityModeConfig {
const configs: Record<SecurityMode, SecurityModeConfig> = {
'proton-pass': {
mode: 'proton-pass',
name: 'Proton Pass',
description: 'Utilise Proton Pass pour l\'authentification biométrique et la gestion des clés',
securityLevel: 'high',
requiresConfirmation: false,
warnings: [],
implementation: {
useWebAuthn: true,
useEncryption: true,
usePlatformAuth: true,
storageType: 'encrypted'
}
},
'os': {
mode: 'os',
name: 'Authentificateur OS',
description: 'Utilise l\'authentificateur intégré de votre système d\'exploitation',
securityLevel: 'high',
requiresConfirmation: false,
warnings: [],
implementation: {
useWebAuthn: true,
useEncryption: true,
usePlatformAuth: true,
storageType: 'encrypted'
}
},
'otp': {
mode: 'otp',
name: 'OTP (Proton Pass Compatible)',
description: 'Utilise un code OTP généré par une application compatible (Proton Pass, Google Authenticator, etc.)',
securityLevel: 'high',
requiresConfirmation: false,
warnings: [],
implementation: {
useWebAuthn: false,
useEncryption: true,
usePlatformAuth: false,
storageType: 'encrypted',
requiresOTP: true
}
},
'2fa': {
mode: '2fa',
name: 'Application 2FA',
description: 'Stockage en clair avec authentification par application 2FA',
securityLevel: 'low',
requiresConfirmation: true,
warnings: [
'⚠️ Clés stockées en clair',
'⚠️ Risque de compromission',
'⚠️ Non recommandé pour des données sensibles'
],
implementation: {
useWebAuthn: false,
useEncryption: false,
usePlatformAuth: false,
storageType: 'plain'
}
},
'password': {
mode: 'password',
name: 'Mot de Passe (Non Sauvegardé)',
description: 'Vos clés sont chiffrées avec un mot de passe que vous devez saisir à chaque utilisation',
securityLevel: 'low',
requiresConfirmation: true,
warnings: [
'⚠️ Le mot de passe n\'est PAS sauvegardé',
'⚠️ NON récupérable en cas d\'oubli',
'⚠️ À saisir à chaque utilisation'
],
implementation: {
useWebAuthn: false,
useEncryption: true,
usePlatformAuth: false,
storageType: 'encrypted',
requiresPassword: true
}
},
'none': {
mode: 'none',
name: 'Aucune Sécurité',
description: 'Chiffrement avec une clé déterminée en dur (non sécurisé)',
securityLevel: 'critical',
requiresConfirmation: true,
warnings: [
'🚨 Clé de chiffrement en dur',
'🚨 Accès non protégé',
'🚨 RISQUE ÉLEVÉ'
],
implementation: {
useWebAuthn: false,
useEncryption: true,
usePlatformAuth: false,
storageType: 'encrypted',
requiresPassword: false
}
}
};
return configs[mode];
}
/**
* Vérifie si un mode nécessite une confirmation
*/
public requiresConfirmation(mode: SecurityMode): boolean {
const config = this.getSecurityModeConfig(mode);
return config.requiresConfirmation;
}
/**
* Récupère les avertissements pour un mode
*/
public getWarnings(mode: SecurityMode): string[] {
const config = this.getSecurityModeConfig(mode);
return config.warnings;
}
/**
* Vérifie si le mode actuel est sécurisé
*/
public async isCurrentModeSecure(): Promise<boolean> {
const currentMode = await this.getCurrentMode();
if (!currentMode) {return false;}
const config = this.getSecurityModeConfig(currentMode);
return config.securityLevel === 'high' || config.securityLevel === 'medium';
}
/**
* Récupère tous les modes disponibles
*/
public getAvailableModes(): SecurityMode[] {
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', 'otp'];
}
/**
* Récupère les modes non recommandés (non sécurisés)
*/
public getNonRecommendedModes(): SecurityMode[] {
return ['2fa', 'none'];
}
/**
* Vérifie si un mode utilise WebAuthn
*/
public usesWebAuthn(mode: SecurityMode): boolean {
const config = this.getSecurityModeConfig(mode);
return config.implementation.useWebAuthn;
}
/**
* Vérifie si un mode utilise le chiffrement
*/
public usesEncryption(mode: SecurityMode): boolean {
const config = this.getSecurityModeConfig(mode);
return config.implementation.useEncryption;
}
/**
* Vérifie si un mode utilise l'authentificateur de plateforme
*/
public usesPlatformAuth(mode: SecurityMode): boolean {
const config = this.getSecurityModeConfig(mode);
return config.implementation.usePlatformAuth;
}
/**
* Récupère le type de stockage pour un mode
*/
public getStorageType(mode: SecurityMode): 'encrypted' | 'plain' | 'hybrid' {
const config = this.getSecurityModeConfig(mode);
return config.implementation.storageType;
}
/**
* Réinitialise le mode de sécurisation
*/
public async resetSecurityMode(): Promise<void> {
try {
const database = await Database.getInstance();
await database.deleteObject('security_settings', 'current_mode');
this.currentMode = null;
secureLogger.info('Security mode reset', {
component: 'SecurityModeService',
operation: 'resetSecurityMode'
});
} catch (error) {
secureLogger.error('Failed to reset security mode', error as Error, {
component: 'SecurityModeService',
operation: 'resetSecurityMode'
});
throw error;
}
}
/**
* Récupère l'historique des modes de sécurisation
*/
public async getSecurityModeHistory(): Promise<any[]> {
try {
const database = await Database.getInstance();
const history = await database.getObject('security_settings', 'mode_history') || [];
return history;
} catch (error) {
secureLogger.error('Failed to retrieve security mode history', error as Error, {
component: 'SecurityModeService',
operation: 'getSecurityModeHistory'
});
return [];
}
}
/**
* Ajoute une entrée à l'historique des modes
*/
private async addToHistory(mode: SecurityMode): Promise<void> {
try {
const history = await this.getSecurityModeHistory();
history.unshift({
mode,
timestamp: Date.now(),
config: this.getSecurityModeConfig(mode)
});
// Garder seulement les 10 dernières entrées
if (history.length > 10) {
history.splice(10);
}
const database = await Database.getInstance();
await database.addObject({
storeName: 'security_settings',
key: 'mode_history',
object: history
});
} catch (error) {
secureLogger.error('Failed to add to security mode history', error as Error, {
component: 'SecurityModeService',
operation: 'addToHistory',
mode
});
}
}
}