105 lines
2.9 KiB
Dart
105 lines
2.9 KiB
Dart
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import '../../../core/network/api_client.dart';
|
|
import '../../../core/security/fingerprint_service.dart';
|
|
import 'auth_state.dart';
|
|
|
|
class AuthCubit extends Cubit<AuthState> {
|
|
final ApiClient _apiClient;
|
|
final FingerprintService _fingerprintService;
|
|
|
|
AuthCubit({
|
|
ApiClient? apiClient,
|
|
FingerprintService? fingerprintService,
|
|
}) : _apiClient = apiClient ?? ApiClient(),
|
|
_fingerprintService = fingerprintService ?? FingerprintService(),
|
|
super(AuthInitial());
|
|
|
|
Future<void> checkExistingSession() async {
|
|
try {
|
|
final token = await _fingerprintService.getSessionToken();
|
|
final userId = await _fingerprintService.getUserId();
|
|
final fingerprint = await _fingerprintService.getDeviceFingerprint();
|
|
|
|
if (token != null && userId != null) {
|
|
emit(Authenticated(
|
|
user: {'id': userId, 'full_name': 'عضو أوروك'},
|
|
token: token,
|
|
deviceFingerprint: fingerprint,
|
|
));
|
|
} else {
|
|
emit(Unauthenticated());
|
|
}
|
|
} catch (_) {
|
|
emit(Unauthenticated());
|
|
}
|
|
}
|
|
|
|
Future<void> requestOtp(String phone) async {
|
|
emit(AuthLoading());
|
|
try {
|
|
final response = await _apiClient.post(
|
|
'/api/v1/auth/request-otp',
|
|
body: {'phone': phone},
|
|
requiresAuth: false,
|
|
);
|
|
|
|
final data = response['data'] as Map<String, dynamic>?;
|
|
emit(AuthOtpSent(
|
|
phone: phone,
|
|
mockOtp: data?['mock_otp'] as String?,
|
|
));
|
|
} catch (e) {
|
|
emit(AuthFailure(e.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> verifyOtpAndBindDevice({
|
|
required String phone,
|
|
required String otp,
|
|
String? fullName,
|
|
}) async {
|
|
emit(AuthLoading());
|
|
try {
|
|
final fingerprint = await _fingerprintService.getDeviceFingerprint();
|
|
final model = await _fingerprintService.getDeviceModel();
|
|
|
|
final response = await _apiClient.post(
|
|
'/api/v1/auth/verify-otp',
|
|
body: {
|
|
'phone': phone,
|
|
'otp': otp,
|
|
'device_fingerprint': fingerprint,
|
|
'device_model': model,
|
|
if (fullName != null && fullName.isNotEmpty) 'full_name': fullName,
|
|
},
|
|
requiresAuth: false,
|
|
);
|
|
|
|
final data = response['data'] as Map<String, dynamic>;
|
|
final user = data['user'] as Map<String, dynamic>;
|
|
final token = data['token'] as String;
|
|
final secret = data['device_secret'] as String;
|
|
final userId = user['id'] as int;
|
|
|
|
await _fingerprintService.saveAuthSession(
|
|
userId: userId,
|
|
token: token,
|
|
deviceSecret: secret,
|
|
);
|
|
|
|
emit(Authenticated(
|
|
user: user,
|
|
token: token,
|
|
deviceFingerprint: fingerprint,
|
|
));
|
|
} catch (e) {
|
|
emit(AuthFailure(e.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> logout() async {
|
|
await _fingerprintService.clearSession();
|
|
emit(Unauthenticated());
|
|
}
|
|
}
|