/** * Utilitaire de stockage sécurisé pour BTP Xpress * Gestion des tokens et données sensibles */ export interface StorageItem { value: any; timestamp: number; expiry?: number; } export class SecureStorage { private static readonly PREFIX = 'btpxpress_'; /** * Stocke une valeur de manière sécurisée */ static set(key: string, value: any, expiryMinutes?: number): void { try { const item: StorageItem = { value, timestamp: Date.now(), expiry: expiryMinutes ? Date.now() + (expiryMinutes * 60 * 1000) : undefined }; const storageKey = this.PREFIX + key; const encrypted = this.encrypt(JSON.stringify(item)); // Utiliser sessionStorage par défaut pour plus de sécurité sessionStorage.setItem(storageKey, encrypted); } catch (error) { console.error('Erreur lors du stockage sécurisé:', error); } } /** * Récupère une valeur stockée */ static get(key: string): any { try { const storageKey = this.PREFIX + key; const encrypted = sessionStorage.getItem(storageKey) || localStorage.getItem(storageKey); if (!encrypted) { return null; } const decrypted = this.decrypt(encrypted); const item: StorageItem = JSON.parse(decrypted); // Vérifier l'expiration if (item.expiry && Date.now() > item.expiry) { this.remove(key); return null; } return item.value; } catch (error) { console.error('Erreur lors de la récupération sécurisée:', error); return null; } } /** * Supprime une valeur stockée */ static remove(key: string): void { try { const storageKey = this.PREFIX + key; sessionStorage.removeItem(storageKey); localStorage.removeItem(storageKey); } catch (error) { console.error('Erreur lors de la suppression sécurisée:', error); } } /** * Vide tout le stockage sécurisé */ static clearAll(): void { try { // Nettoyer sessionStorage Object.keys(sessionStorage).forEach(key => { if (key.startsWith(this.PREFIX)) { sessionStorage.removeItem(key); } }); // Nettoyer localStorage Object.keys(localStorage).forEach(key => { if (key.startsWith(this.PREFIX)) { localStorage.removeItem(key); } }); // Nettoyer aussi les anciens tokens sessionStorage.removeItem('auth_token'); localStorage.removeItem('auth_token'); localStorage.removeItem('token'); localStorage.removeItem('user'); } catch (error) { console.error('Erreur lors du nettoyage sécurisé:', error); } } /** * Vérifie si une clé existe et n'est pas expirée */ static exists(key: string): boolean { return this.get(key) !== null; } /** * Chiffrement simple (Base64 + rotation) * Note: Pour un vrai projet, utiliser une vraie bibliothèque de chiffrement */ private static encrypt(data: string): string { try { // Chiffrement simple avec Base64 et rotation de caractères const rotated = data.split('').map(char => String.fromCharCode(char.charCodeAt(0) + 3) ).join(''); return btoa(rotated); } catch (error) { console.error('Erreur de chiffrement:', error); return btoa(data); // Fallback vers Base64 simple } } /** * Déchiffrement simple */ private static decrypt(encrypted: string): string { try { const decoded = atob(encrypted); // Dérotation des caractères return decoded.split('').map(char => String.fromCharCode(char.charCodeAt(0) - 3) ).join(''); } catch (error) { console.error('Erreur de déchiffrement:', error); return atob(encrypted); // Fallback vers Base64 simple } } } // Export par défaut pour compatibilité export default SecureStorage;