Initial commit

This commit is contained in:
dahoud
2025-10-01 01:39:07 +00:00
commit b430bf3b96
826 changed files with 255287 additions and 0 deletions

150
utils/secureStorage.ts Normal file
View File

@@ -0,0 +1,150 @@
/**
* 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;