fill
This commit is contained in:
198
lib/core/storage/secure_storage.dart
Normal file
198
lib/core/storage/secure_storage.dart
Normal file
@@ -0,0 +1,198 @@
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
/// Secure storage service for managing sensitive data like tokens
|
||||
///
|
||||
/// Uses FlutterSecureStorage to encrypt and store data securely on the device.
|
||||
/// This ensures tokens and other sensitive information are protected.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// final storage = SecureStorage();
|
||||
///
|
||||
/// // Save token
|
||||
/// await storage.saveAccessToken('your_token_here');
|
||||
///
|
||||
/// // Read token
|
||||
/// final token = await storage.getAccessToken();
|
||||
///
|
||||
/// // Clear all data
|
||||
/// await storage.clearAll();
|
||||
/// ```
|
||||
class SecureStorage {
|
||||
// Private constructor for singleton pattern
|
||||
SecureStorage._();
|
||||
|
||||
/// Singleton instance
|
||||
static final SecureStorage _instance = SecureStorage._();
|
||||
|
||||
/// Factory constructor returns singleton instance
|
||||
factory SecureStorage() => _instance;
|
||||
|
||||
/// FlutterSecureStorage instance with default options
|
||||
static const FlutterSecureStorage _storage = FlutterSecureStorage(
|
||||
aOptions: AndroidOptions(
|
||||
encryptedSharedPreferences: true,
|
||||
),
|
||||
iOptions: IOSOptions(
|
||||
accessibility: KeychainAccessibility.first_unlock,
|
||||
),
|
||||
);
|
||||
|
||||
// ==================== Storage Keys ====================
|
||||
|
||||
/// Key for storing access token
|
||||
static const String _accessTokenKey = 'access_token';
|
||||
|
||||
/// Key for storing refresh token
|
||||
static const String _refreshTokenKey = 'refresh_token';
|
||||
|
||||
/// Key for storing user ID
|
||||
static const String _userIdKey = 'user_id';
|
||||
|
||||
/// Key for storing username
|
||||
static const String _usernameKey = 'username';
|
||||
|
||||
// ==================== Token Management ====================
|
||||
|
||||
/// Save access token securely
|
||||
Future<void> saveAccessToken(String token) async {
|
||||
try {
|
||||
await _storage.write(key: _accessTokenKey, value: token);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to save access token: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get access token
|
||||
Future<String?> getAccessToken() async {
|
||||
try {
|
||||
return await _storage.read(key: _accessTokenKey);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to read access token: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Save refresh token securely
|
||||
Future<void> saveRefreshToken(String token) async {
|
||||
try {
|
||||
await _storage.write(key: _refreshTokenKey, value: token);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to save refresh token: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get refresh token
|
||||
Future<String?> getRefreshToken() async {
|
||||
try {
|
||||
return await _storage.read(key: _refreshTokenKey);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to read refresh token: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Save user ID
|
||||
Future<void> saveUserId(String userId) async {
|
||||
try {
|
||||
await _storage.write(key: _userIdKey, value: userId);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to save user ID: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get user ID
|
||||
Future<String?> getUserId() async {
|
||||
try {
|
||||
return await _storage.read(key: _userIdKey);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to read user ID: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Save username
|
||||
Future<void> saveUsername(String username) async {
|
||||
try {
|
||||
await _storage.write(key: _usernameKey, value: username);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to save username: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get username
|
||||
Future<String?> getUsername() async {
|
||||
try {
|
||||
return await _storage.read(key: _usernameKey);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to read username: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if user is authenticated (has valid access token)
|
||||
Future<bool> isAuthenticated() async {
|
||||
final token = await getAccessToken();
|
||||
return token != null && token.isNotEmpty;
|
||||
}
|
||||
|
||||
/// Clear all stored data (logout)
|
||||
Future<void> clearAll() async {
|
||||
try {
|
||||
await _storage.deleteAll();
|
||||
} catch (e) {
|
||||
throw Exception('Failed to clear storage: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear only auth tokens
|
||||
Future<void> clearTokens() async {
|
||||
try {
|
||||
await _storage.delete(key: _accessTokenKey);
|
||||
await _storage.delete(key: _refreshTokenKey);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to clear tokens: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all stored keys (useful for debugging)
|
||||
Future<Map<String, String>> readAll() async {
|
||||
try {
|
||||
return await _storage.readAll();
|
||||
} catch (e) {
|
||||
throw Exception('Failed to read all data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if storage contains a specific key
|
||||
Future<bool> containsKey(String key) async {
|
||||
try {
|
||||
return await _storage.containsKey(key: key);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to check key: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Write custom key-value pair
|
||||
Future<void> write(String key, String value) async {
|
||||
try {
|
||||
await _storage.write(key: key, value: value);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to write data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Read custom key
|
||||
Future<String?> read(String key) async {
|
||||
try {
|
||||
return await _storage.read(key: key);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to read data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete custom key
|
||||
Future<void> delete(String key) async {
|
||||
try {
|
||||
await _storage.delete(key: key);
|
||||
} catch (e) {
|
||||
throw Exception('Failed to delete data: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user