75 lines
1.9 KiB
Dart
75 lines
1.9 KiB
Dart
import "dart:convert";
|
|
import "package:flutter/foundation.dart";
|
|
import "package:shared_preferences/shared_preferences.dart";
|
|
|
|
import "api.dart";
|
|
import "models.dart";
|
|
|
|
const _tokenKey = "cc_token";
|
|
const _userKey = "cc_user";
|
|
|
|
/// Holds session state and persists the token across app restarts.
|
|
class AuthService extends ChangeNotifier {
|
|
final ApiClient api;
|
|
AuthUser? user;
|
|
bool ready = false;
|
|
|
|
/// In-memory (never persisted) app-lock flag. When biometric login is enabled
|
|
/// the app starts/returns locked: the token is still valid but the UI hides
|
|
/// behind a biometric unlock instead of jumping straight to the dashboard.
|
|
bool locked = false;
|
|
|
|
AuthService(this.api) {
|
|
api.onUnauthorized = () => logout();
|
|
}
|
|
|
|
bool get isAuthenticated => api.token != null;
|
|
|
|
void lock() {
|
|
if (!locked && isAuthenticated) {
|
|
locked = true;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
void unlock() {
|
|
if (locked) {
|
|
locked = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> loadFromStorage() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final t = prefs.getString(_tokenKey);
|
|
final u = prefs.getString(_userKey);
|
|
if (t != null) {
|
|
api.token = t;
|
|
if (u != null) user = AuthUser.fromJson(jsonDecode(u));
|
|
}
|
|
ready = true;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> login(String email, String password) async {
|
|
final (token, u) = await api.login(email, password);
|
|
api.token = token;
|
|
user = u;
|
|
locked = false;
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_tokenKey, token);
|
|
await prefs.setString(_userKey, jsonEncode(u.toJson()));
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> logout() async {
|
|
api.token = null;
|
|
user = null;
|
|
locked = false;
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove(_tokenKey);
|
|
await prefs.remove(_userKey);
|
|
notifyListeners();
|
|
}
|
|
}
|