58 lines
1.7 KiB
Dart
58 lines
1.7 KiB
Dart
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
/// Stores the auth token in secure storage and falls back to SharedPreferences
|
|
/// so debug builds and platforms without a working keyring still persist.
|
|
class TokenStorageService {
|
|
TokenStorageService._internal();
|
|
|
|
static final TokenStorageService _instance = TokenStorageService._internal();
|
|
|
|
factory TokenStorageService() => _instance;
|
|
|
|
static const _tokenKey = 'auth_token';
|
|
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
|
|
|
|
Future<SharedPreferences> get _prefs async =>
|
|
await SharedPreferences.getInstance();
|
|
|
|
Future<void> setToken(String token) async {
|
|
try {
|
|
await _secureStorage.write(key: _tokenKey, value: token);
|
|
} catch (_) {
|
|
// ignore secure storage failures in debug/unsupported environments
|
|
}
|
|
final prefs = await _prefs;
|
|
await prefs.setString(_tokenKey, token);
|
|
}
|
|
|
|
Future<String?> getToken() async {
|
|
try {
|
|
final secured = await _secureStorage.read(key: _tokenKey);
|
|
if (secured != null && secured.isNotEmpty) {
|
|
return secured;
|
|
}
|
|
} catch (_) {
|
|
// ignore and fall back
|
|
}
|
|
final prefs = await _prefs;
|
|
final token = prefs.getString(_tokenKey);
|
|
return (token == null || token.isEmpty) ? null : token;
|
|
}
|
|
|
|
Future<void> clearToken() async {
|
|
try {
|
|
await _secureStorage.delete(key: _tokenKey);
|
|
} catch (_) {
|
|
// ignore
|
|
}
|
|
final prefs = await _prefs;
|
|
await prefs.remove(_tokenKey);
|
|
}
|
|
|
|
Future<bool> hasToken() async {
|
|
final token = await getToken();
|
|
return token != null && token.isNotEmpty;
|
|
}
|
|
}
|