/** * DeviceRepository - Interface pour la gestion des appareils * Sépare la logique métier de l'accès aux données */ import { Device } from '../../pkg/sdk_client'; import { secureLogger } from '../services/secure-logger'; /* eslint-disable no-unused-vars */ export interface DeviceRepository { getDevice(): Promise; saveDevice(_device: Device): Promise; deleteDevice(): Promise; hasDevice(): Promise; getDeviceAddress(): Promise; updateDevice(_device: Partial): Promise; } /* eslint-enable no-unused-vars */ export class DeviceRepositoryImpl implements DeviceRepository { constructor(private database: any) {} // database used via methods async getDevice(): Promise { try { const device = await this.database.get('devices', 'current'); if (device) { secureLogger.debug('Device retrieved from database', { component: 'DeviceRepository', operation: 'getDevice', hasAddress: !!device.sp_wallet?.address }); return this.deserializeDevice(device); } return null; } catch (error) { secureLogger.error('Failed to get device from database', error as Error, { component: 'DeviceRepository', operation: 'getDevice' }); return null; } } async saveDevice(device: Device): Promise { try { const serialized = this.serializeDevice(device); await this.database.put('devices', serialized, 'current'); secureLogger.info('Device saved to database', { component: 'DeviceRepository', operation: 'saveDevice', hasAddress: !!device.sp_wallet?.address }); } catch (error) { secureLogger.error('Failed to save device to database', error as Error, { component: 'DeviceRepository', operation: 'saveDevice' }); throw error; } } async deleteDevice(): Promise { try { await this.database.delete('devices', 'current'); secureLogger.info('Device deleted from database', { component: 'DeviceRepository', operation: 'deleteDevice' }); } catch (error) { secureLogger.error('Failed to delete device from database', error as Error, { component: 'DeviceRepository', operation: 'deleteDevice' }); throw error; } } async hasDevice(): Promise { try { const device = await this.getDevice(); return device !== null; } catch (error) { secureLogger.error('Failed to check if device exists', error as Error, { component: 'DeviceRepository', operation: 'hasDevice' }); return false; } } async getDeviceAddress(): Promise { try { const device = await this.getDevice(); return device?.sp_wallet?.address || null; } catch (error) { secureLogger.error('Failed to get device address', error as Error, { component: 'DeviceRepository', operation: 'getDeviceAddress' }); return null; } } async updateDevice(updates: Partial): Promise { try { const currentDevice = await this.getDevice(); if (!currentDevice) { throw new Error('No device found to update'); } const updatedDevice = { ...currentDevice, ...updates }; await this.saveDevice(updatedDevice); secureLogger.info('Device updated in database', { component: 'DeviceRepository', operation: 'updateDevice', updatedFields: Object.keys(updates) }); } catch (error) { secureLogger.error('Failed to update device', error as Error, { component: 'DeviceRepository', operation: 'updateDevice' }); throw error; } } /** * Sérialise un appareil pour le stockage */ private serializeDevice(device: Device): any { return { ...device, // Ne pas exposer les clés privées dans les logs sp_wallet: device.sp_wallet ? { ...device.sp_wallet, private_key: '[REDACTED]' // Masquer la clé privée } : undefined }; } /** * Désérialise un appareil depuis le stockage */ private deserializeDevice(serialized: any): Device { return { ...serialized, // Restaurer la clé privée si elle existe sp_wallet: serialized.sp_wallet ? { ...serialized.sp_wallet, private_key: serialized.sp_wallet.private_key === '[REDACTED]' ? undefined : serialized.sp_wallet.private_key } : undefined }; } }