Update: 2026-05-06 04:02:34
This commit is contained in:
@@ -5,6 +5,8 @@ import 'dart:io';
|
||||
import '../../../core/network/dio_client.dart';
|
||||
import '../../../core/storage/secure_storage.dart';
|
||||
import '../../../app/routes/app_pages.dart';
|
||||
import '../../../core/utils/logger.dart';
|
||||
import '../../../core/utils/app_snackbar.dart';
|
||||
|
||||
class AuthController extends GetxController {
|
||||
final Dio _dio = DioClient().client;
|
||||
@@ -23,10 +25,13 @@ class AuthController extends GetxController {
|
||||
});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
AppLogger.print('OTP Request Success: ${response.data}');
|
||||
AppSnackbar.showSuccess('نجاح', 'تم إرسال رمز التحقق بنجاح');
|
||||
Get.toNamed(AppRoutes.OTP_VERIFY);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
Get.snackbar('خطأ', e.response?.data['message'] ?? 'فشل الاتصال بالخادم');
|
||||
} on DioException catch (e, stackTrace) {
|
||||
AppLogger.error('OTP Request Failed', e.response?.data, stackTrace);
|
||||
AppSnackbar.showError('خطأ', e.response?.data['message'] ?? 'فشل الاتصال بالخادم');
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
@@ -61,17 +66,21 @@ class AuthController extends GetxController {
|
||||
});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
AppLogger.print('OTP Verify Success. Tokens received.');
|
||||
final data = response.data['data'];
|
||||
|
||||
// Save secure data
|
||||
await _storage.saveToken(data['access_token']);
|
||||
await _storage.saveDeviceSecret(data['device_secret']);
|
||||
|
||||
// Navigate to Dashboard or Biometric Setup
|
||||
Get.offAllNamed(AppRoutes.DASHBOARD);
|
||||
AppSnackbar.showSuccess('مرحباً بك', 'تم تسجيل الدخول بنجاح');
|
||||
|
||||
// Navigate to Biometric Setup
|
||||
Get.offAllNamed(AppRoutes.BIOMETRIC_SETUP);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
Get.snackbar('خطأ', e.response?.data['message'] ?? 'رمز التحقق غير صحيح');
|
||||
} on DioException catch (e, stackTrace) {
|
||||
AppLogger.error('OTP Verify Failed', e.response?.data, stackTrace);
|
||||
AppSnackbar.showError('خطأ', e.response?.data['message'] ?? 'رمز التحقق غير صحيح');
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
import '../../../core/storage/secure_storage.dart';
|
||||
import '../../../app/routes/app_pages.dart';
|
||||
import '../../../core/utils/logger.dart';
|
||||
import '../../../core/utils/app_snackbar.dart';
|
||||
|
||||
class BiometricController extends GetxController {
|
||||
final LocalAuthentication auth = LocalAuthentication();
|
||||
final SecureStorage _storage = SecureStorage();
|
||||
|
||||
var isBiometricAvailable = false.obs;
|
||||
var isAuthenticating = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
checkBiometrics();
|
||||
}
|
||||
|
||||
Future<void> checkBiometrics() async {
|
||||
try {
|
||||
final canCheck = await auth.canCheckBiometrics;
|
||||
final isSupported = await auth.isDeviceSupported();
|
||||
isBiometricAvailable.value = canCheck || isSupported;
|
||||
AppLogger.print('Biometrics available: ${isBiometricAvailable.value}');
|
||||
} catch (e, stackTrace) {
|
||||
isBiometricAvailable.value = false;
|
||||
AppLogger.error('Failed to check biometrics support', e, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> authenticateAndGoToDashboard() async {
|
||||
// Ensure we have checked biometric status first
|
||||
await checkBiometrics();
|
||||
|
||||
if (!isBiometricAvailable.value) {
|
||||
AppLogger.print('Biometrics not available, going directly to dashboard.');
|
||||
Get.offAllNamed(AppRoutes.DASHBOARD);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
isAuthenticating.value = true;
|
||||
bool authenticated = await auth.authenticate(
|
||||
localizedReason: 'الرجاء التحقق من هويتك للوصول إلى مُصادَق',
|
||||
options: const AuthenticationOptions(
|
||||
stickyAuth: true,
|
||||
biometricOnly: false, // Allows PIN/Pattern fallback
|
||||
),
|
||||
);
|
||||
|
||||
if (authenticated) {
|
||||
AppLogger.print('Biometric authentication successful!');
|
||||
Get.offAllNamed(AppRoutes.DASHBOARD);
|
||||
} else {
|
||||
AppLogger.print('Biometric authentication cancelled or failed.');
|
||||
AppSnackbar.showWarning('فشل التحقق', 'لم نتمكن من التحقق من هويتك أو قمت بإلغاء العملية');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
AppLogger.error('Error during biometric auth', e, stackTrace);
|
||||
AppSnackbar.showError('خطأ', 'حدث خطأ غير متوقع أثناء قراءة البصمة: $e');
|
||||
} finally {
|
||||
isAuthenticating.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
void skipBiometricSetup() {
|
||||
AppLogger.print('Skipped biometric setup.');
|
||||
Get.offAllNamed(AppRoutes.DASHBOARD);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user