This commit is contained in:
2025-10-28 00:09:46 +07:00
parent 9ebe7c2919
commit de49f564b1
110 changed files with 15392 additions and 3996 deletions

View 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');
}
}
}