104 lines
2.8 KiB
Dart
104 lines
2.8 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
|
|
import '../models/models.dart';
|
|
import 'api_client.dart';
|
|
|
|
class AuthController extends ChangeNotifier {
|
|
AuthController({FlutterSecureStorage? storage, ApiClient? apiClient})
|
|
: _storage = storage ?? const FlutterSecureStorage(),
|
|
api = apiClient ?? ApiClient();
|
|
|
|
final FlutterSecureStorage _storage;
|
|
final ApiClient api;
|
|
|
|
AppUser? user;
|
|
bool ready = false;
|
|
bool busy = false;
|
|
String? error;
|
|
|
|
Future<void> bootstrap() async {
|
|
try {
|
|
final stored = await _storage.read(key: 'jwt_token');
|
|
if (stored == null || stored.isEmpty) return;
|
|
api.token = stored;
|
|
user = await api.me();
|
|
} catch (_) {
|
|
api.token = null;
|
|
user = null;
|
|
await _storage.delete(key: 'jwt_token');
|
|
} finally {
|
|
ready = true;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> staffLogin(String phone, String password) async {
|
|
await _run(() async {
|
|
final result = await api.staffLogin(phone, password);
|
|
await _storeSession(result.token, result.user);
|
|
});
|
|
}
|
|
|
|
Future<({String requestId, String secret})> startDealerLogin(String phone) async {
|
|
late ({String requestId, String secret}) started;
|
|
await _run(() async {
|
|
started = await api.dealerLogin(phone);
|
|
});
|
|
return started;
|
|
}
|
|
|
|
Future<String> pollDealerLogin(String requestId, String secret) async {
|
|
final status = await api.dealerLoginStatus(requestId, secret);
|
|
if (status.status == 'approved' && status.token != null && status.user != null) {
|
|
await _storeSession(status.token!, status.user!);
|
|
notifyListeners();
|
|
} else if (status.status == 'rejected') {
|
|
error = 'Login was rejected';
|
|
notifyListeners();
|
|
} else if (status.status == 'expired' || status.status == 'consumed') {
|
|
error = 'Login request expired. Try again.';
|
|
notifyListeners();
|
|
}
|
|
return status.status;
|
|
}
|
|
|
|
Future<void> _storeSession(String token, AppUser profile) async {
|
|
api.token = token;
|
|
await _storage.write(key: 'jwt_token', value: token);
|
|
user = profile;
|
|
}
|
|
|
|
Future<void> refreshProfile() async {
|
|
if (api.token == null) return;
|
|
user = await api.me();
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> logout() async {
|
|
api.token = null;
|
|
user = null;
|
|
error = null;
|
|
await _storage.delete(key: 'jwt_token');
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> _run(Future<void> Function() action) async {
|
|
busy = true;
|
|
error = null;
|
|
notifyListeners();
|
|
try {
|
|
await action();
|
|
} on ApiException catch (error) {
|
|
this.error = error.message;
|
|
rethrow;
|
|
} catch (error) {
|
|
this.error = 'Network request failed';
|
|
rethrow;
|
|
} finally {
|
|
busy = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
}
|