// Version: 1.0.0 | Created: 2026-04-01 // Typed wrapper around flutter_secure_storage. // All token read/write operations go through this class — never call // flutter_secure_storage directly from feature code. import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../config/app_config.dart'; part 'secure_storage.g.dart'; /// Provides a configured [SecureStorage] instance. @Riverpod(keepAlive: true) SecureStorage secureStorage(Ref ref) => const SecureStorage(); /// Typed wrapper around [FlutterSecureStorage]. /// /// Uses AES encryption on Android and Keychain on iOS. /// On Web, data is stored in localStorage with encryption — acceptable for /// access tokens but NOT for E2EE private keys (Phase 2 concern). class SecureStorage { const SecureStorage(); static const FlutterSecureStorage _storage = FlutterSecureStorage( aOptions: AndroidOptions(encryptedSharedPreferences: true), ); Future saveCredentials({ required String accessToken, required String userId, required String deviceId, }) async { await _storage.write( key: AppConfig.storageKeyAccessToken, value: accessToken, ); await _storage.write(key: AppConfig.storageKeyUserId, value: userId); await _storage.write(key: AppConfig.storageKeyDeviceId, value: deviceId); await _storage.write( key: AppConfig.storageKeyHomeserver, value: AppConfig.matrixBaseUrl, ); } Future loadCredentials() async { final accessToken = await _storage.read( key: AppConfig.storageKeyAccessToken, ); final userId = await _storage.read(key: AppConfig.storageKeyUserId); final deviceId = await _storage.read(key: AppConfig.storageKeyDeviceId); if (accessToken == null || userId == null || deviceId == null) { return null; } return StoredCredentials( accessToken: accessToken, userId: userId, deviceId: deviceId, ); } Future clearCredentials() async { await _storage.delete(key: AppConfig.storageKeyAccessToken); await _storage.delete(key: AppConfig.storageKeyUserId); await _storage.delete(key: AppConfig.storageKeyDeviceId); await _storage.delete(key: AppConfig.storageKeyHomeserver); } } /// Holds the credentials retrieved from secure storage. class StoredCredentials { const StoredCredentials({ required this.accessToken, required this.userId, required this.deviceId, }); final String accessToken; final String userId; final String deviceId; }