diff --git a/backend/loginJwtDriver.php b/backend/loginJwtDriver.php
index fdd87e9..0e895b3 100644
--- a/backend/loginJwtDriver.php
+++ b/backend/loginJwtDriver.php
@@ -53,48 +53,82 @@ try {
$stmt->execute([':id' => $id]);
$driver = $stmt->fetch();
- if (!$driver || empty($driver['password'])) {
+ if (!$driver) {
unauthorizedDriver();
}
- $decPhone = !empty($driver['phone']) ? $encryptionHelper->decryptData($driver['phone']) : null;
- $decNat = !empty($driver['national_number']) ? $encryptionHelper->decryptData($driver['national_number']) : null;
-
- if (empty($decPhone)) {
- securityLog("LoginDriver failed: phone decryption returned null", [
- 'driver_id' => $driver['id'] ?? 'unknown',
- ]);
- unauthorizedDriver();
- }
-
- // ── المحاولة الأولى: طريقة جديدة (قيم خام) ─────────────
- $newParts = [
- $driver['id'],
- trim($decPhone),
- ];
- if (!empty($decNat)) {
- $newParts[] = trim($decNat);
- }
- $newString = implode('|', $newParts);
- $newSecret = hash_hmac('sha256', $newString, $pepper, true);
-
- if (password_verify($newSecret, $driver['password'])) {
- // ✅ صح - طريقة جديدة
- } else {
- // ── المحاولة الثانية: طريقة قديمة (قيم مشفرة) للتوافق ─
- $oldParts = [
- $driver['id'],
- $driver['phone'],
- ];
- if (!empty($driver['national_number'])) {
- $oldParts[] = $driver['national_number'];
- }
- $oldString = implode('|', $oldParts);
- $oldSecret = hash_hmac('sha256', $oldString, $pepper, true);
-
- if (!password_verify($oldSecret, $driver['password'])) {
+ // ── مسار السائقين المسجلين عبر OTP (بدون password في DB) ──
+ if (empty($driver['password'])) {
+ // التحقق من هوية السائق عبر fingerprint المخزن في driverToken
+ if (empty($fingerprint)) {
+ securityLog("LoginDriver(OTP): no fingerprint sent", [
+ 'driver_id' => $driver['id'],
+ ]);
unauthorizedDriver();
}
+
+ $stmtFp = $con->prepare('SELECT fingerPrint FROM driverToken WHERE captain_id = :id LIMIT 1');
+ $stmtFp->execute([':id' => $driver['id']]);
+ $fpRow = $stmtFp->fetch();
+
+ if (!$fpRow || empty($fpRow['fingerPrint'])) {
+ securityLog("LoginDriver(OTP): no stored fingerprint found", [
+ 'driver_id' => $driver['id'],
+ ]);
+ unauthorizedDriver();
+ }
+
+ $fpPepper = getenv('FP_PEPPER') ?: '';
+ $expectedFp = !empty($fpPepper) ? hash('sha256', $fingerprint . $fpPepper) : $fingerprint;
+
+ if (!hash_equals($fpRow['fingerPrint'], $expectedFp)) {
+ securityLog("LoginDriver(OTP): fingerprint mismatch", [
+ 'driver_id' => $driver['id'],
+ ]);
+ unauthorizedDriver();
+ }
+ // ✅ تم التحقق عبر fingerprint — نتابع لتوليد JWT
+ } else {
+ // ── المسار التقليدي: التحقق عبر password + HMAC ──────────
+ $decPhone = !empty($driver['phone']) ? $encryptionHelper->decryptData($driver['phone']) : null;
+ $decNat = !empty($driver['national_number']) ? $encryptionHelper->decryptData($driver['national_number']) : null;
+
+ if (empty($decPhone)) {
+ securityLog("LoginDriver failed: phone decryption returned null", [
+ 'driver_id' => $driver['id'] ?? 'unknown',
+ ]);
+ unauthorizedDriver();
+ }
+
+ // ── المحاولة الأولى: طريقة جديدة (قيم خام) ─────────────
+ $newParts = [
+ $driver['id'],
+ trim($decPhone),
+ ];
+ if (!empty($decNat)) {
+ $newParts[] = trim($decNat);
+ }
+ $newString = implode('|', $newParts);
+ $newSecret = hash_hmac('sha256', $newString, $pepper, true);
+
+ if (password_verify($newSecret, $driver['password'])) {
+ // ✅ صح - طريقة جديدة
+ } else {
+ // ── المحاولة الثانية: طريقة قديمة (قيم مشفرة) للتوافق ─
+ $oldParts = [
+ $driver['id'],
+ $driver['phone'],
+ ];
+ if (!empty($driver['national_number'])) {
+ $oldParts[] = $driver['national_number'];
+ }
+ $oldString = implode('|', $oldParts);
+ $oldSecret = hash_hmac('sha256', $oldString, $pepper, true);
+
+ if (!password_verify($oldSecret, $driver['password'])) {
+ unauthorizedDriver();
+ }
+ }
}
$limiter->reset(RateLimiter::identifier(), 'login');
diff --git a/intaleq_driver/android/app/src/main/res/values-ar/strings.xml b/intaleq_driver/android/app/src/main/res/values-ar/strings.xml
index af58dc9..936c54b 100755
--- a/intaleq_driver/android/app/src/main/res/values-ar/strings.xml
+++ b/intaleq_driver/android/app/src/main/res/values-ar/strings.xml
@@ -4,5 +4,5 @@
تشغيل التطبيق على هذا الجهاز.
إغلاق التطبيق
الجهاز آمن. الاستمرار بشكل طبيعي.
- سيرو درايفر
+ انطلق كابتن
\ No newline at end of file
diff --git a/intaleq_driver/lib/controller/auth/captin/login_captin_controller.dart b/intaleq_driver/lib/controller/auth/captin/login_captin_controller.dart
index e4e1dfd..bb68ad7 100755
--- a/intaleq_driver/lib/controller/auth/captin/login_captin_controller.dart
+++ b/intaleq_driver/lib/controller/auth/captin/login_captin_controller.dart
@@ -376,7 +376,6 @@ class LoginDriverController extends GetxController {
var payload = {
'id': driverId,
- 'password': box.read(BoxName.emailDriver),
'aud': '${AK.allowed}$dev',
'fingerPrint': box.read(BoxName.deviceFingerprint) ??
await DeviceHelper.getDeviceFingerprint(),
@@ -750,11 +749,7 @@ class LoginDriverController extends GetxController {
var d = jsonDecoeded['data'][0];
var jwt = jsonDecoeded['jwt'];
- // حفظ التوكن أولاً
- // ⚠️ لازم يُخزَّن خام (بدون c()) — CRUD._getJwt() بيقرأه مباشرة
- // ويحطه بـ Authorization، ولو كان مشفّر بصير كل طلب 401 → حلقة تجديد
if (jwt != null) {
- box.write(BoxName.jwt, jwt);
await storage.write(key: BoxName.jwt, value: jwt.toString());
}
diff --git a/intaleq_driver/lib/controller/auth/syria/registration_controller.dart b/intaleq_driver/lib/controller/auth/syria/registration_controller.dart
index 21398b2..ad6b563 100644
--- a/intaleq_driver/lib/controller/auth/syria/registration_controller.dart
+++ b/intaleq_driver/lib/controller/auth/syria/registration_controller.dart
@@ -371,8 +371,7 @@ class RegistrationController extends GetxController {
final uri = Uri.parse(currentUrl);
final request = http.MultipartRequest('POST', uri);
- final _jwt = box.read(BoxName.jwt);
- final String _token = _jwt != null ? r(_jwt).split(AppInformation.addd)[0] : '';
+ final String _token = await storage.read(key: BoxName.jwt) ?? '';
String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
String nonce = timestamp;
@@ -581,8 +580,8 @@ class RegistrationController extends GetxController {
try {
// ترويسات مشتركة
- final _jwt = box.read(BoxName.jwt);
- final bearer = 'Bearer ${_jwt != null ? r(_jwt).split(AppInformation.addd)[0] : ''}';
+ final String _jwtToken = await storage.read(key: BoxName.jwt) ?? '';
+ final bearer = 'Bearer $_jwtToken';
final hmac = '${box.read(BoxName.hmac)}';
String fingerPrint =
diff --git a/intaleq_driver/lib/controller/firebase/firbase_messge.dart b/intaleq_driver/lib/controller/firebase/firbase_messge.dart
index 83f6408..6d5a150 100755
--- a/intaleq_driver/lib/controller/firebase/firbase_messge.dart
+++ b/intaleq_driver/lib/controller/firebase/firbase_messge.dart
@@ -233,7 +233,7 @@ class FirebaseMessagesController extends GetxController {
case 'token change':
case 'TOKEN_CHANGE':
- box.remove(BoxName.jwt);
+ await storage.delete(key: BoxName.jwt);
break;
case 'face detect':
diff --git a/intaleq_driver/lib/controller/functions/gemeni.dart b/intaleq_driver/lib/controller/functions/gemeni.dart
index db62068..4a251a1 100755
--- a/intaleq_driver/lib/controller/functions/gemeni.dart
+++ b/intaleq_driver/lib/controller/functions/gemeni.dart
@@ -479,8 +479,7 @@ class AI extends GetxController {
bool isLoadingVehicleFrontSy = false;
bool isLoadingVehicleBackSy = false;
Future sendToAI(String type, {required File imageFile}) async {
- final _jwt = box.read(BoxName.jwt);
- final String _token = _jwt != null ? r(_jwt).split(AppInformation.addd)[0] : '';
+ final String _token = await storage.read(key: BoxName.jwt) ?? '';
final headers = {
'Authorization': 'Bearer $_token',
'X-HMAC-Auth': '${box.read(BoxName.hmac)}',
diff --git a/intaleq_driver/lib/controller/functions/ocr_controller.dart b/intaleq_driver/lib/controller/functions/ocr_controller.dart
index 78bce3d..147aada 100755
--- a/intaleq_driver/lib/controller/functions/ocr_controller.dart
+++ b/intaleq_driver/lib/controller/functions/ocr_controller.dart
@@ -488,7 +488,7 @@ class ScanDocumentsByApi extends GetxController {
update();
final String token =
- box.read(BoxName.jwt)?.toString().split(AppInformation.addd)[0] ?? '';
+ await storage.read(key: BoxName.jwt) ?? '';
final String fingerPrint =
box.read(BoxName.deviceFingerprint)?.toString() ?? '';
final String driverID = box.read(BoxName.driverID).toString();
diff --git a/intaleq_driver/lib/controller/functions/upload_image.dart b/intaleq_driver/lib/controller/functions/upload_image.dart
index 36c9f00..f241696 100755
--- a/intaleq_driver/lib/controller/functions/upload_image.dart
+++ b/intaleq_driver/lib/controller/functions/upload_image.dart
@@ -312,8 +312,7 @@ class ImageController extends GetxController {
required String filename,
required String methodLabel,
}) async {
- final jwt = box.read(BoxName.jwt);
- final String token = jwt != null ? r(jwt).split(AppInformation.addd)[0] : '';
+ final String token = await storage.read(key: BoxName.jwt) ?? '';
final String fingerPrint = box.read(BoxName.deviceFingerprint)?.toString() ?? '';
final int fileSizeBytes = await file.length();
diff --git a/intaleq_driver/lib/controller/home/profile/complaint_controller.dart b/intaleq_driver/lib/controller/home/profile/complaint_controller.dart
index 01a9a75..7d7266f 100644
--- a/intaleq_driver/lib/controller/home/profile/complaint_controller.dart
+++ b/intaleq_driver/lib/controller/home/profile/complaint_controller.dart
@@ -87,8 +87,7 @@ class ComplaintController extends GetxController {
var uri = Uri.parse(AppLink.uploadAudio);
var request = http.MultipartRequest('POST', uri);
- final jwt = box.read(BoxName.jwt);
- String token = jwt != null ? r(jwt).toString().split(Env.addd)[0] : '';
+ String token = await storage.read(key: BoxName.jwt) ?? '';
final String fingerPrint = box.read(BoxName.deviceFingerprint)?.toString() ?? '';
var mimeType = lookupMimeType(audioFile.path);
diff --git a/intaleq_rider/android/app/src/main/res/values-ar/strings.xml b/intaleq_rider/android/app/src/main/res/values-ar/strings.xml
index 7a82743..6268edf 100644
--- a/intaleq_rider/android/app/src/main/res/values-ar/strings.xml
+++ b/intaleq_rider/android/app/src/main/res/values-ar/strings.xml
@@ -4,5 +4,5 @@
تشغيل التطبيق على هذا الجهاز.
إغلاق التطبيق
الجهاز آمن. الاستمرار بشكل طبيعي.
- سيرو
+ انطلق
\ No newline at end of file