From 16b4829a6d30cbb0fb2d0862700468df60659412 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Thu, 6 Aug 2026 22:54:36 +0300 Subject: [PATCH] Update: 2026-08-06 22:54:35 --- backend/loginJwtDriver.php | 108 ++++++++++++------ .../app/src/main/res/values-ar/strings.xml | 2 +- .../auth/captin/login_captin_controller.dart | 5 - .../auth/syria/registration_controller.dart | 7 +- .../controller/firebase/firbase_messge.dart | 2 +- .../lib/controller/functions/gemeni.dart | 3 +- .../controller/functions/ocr_controller.dart | 2 +- .../controller/functions/upload_image.dart | 3 +- .../home/profile/complaint_controller.dart | 3 +- .../app/src/main/res/values-ar/strings.xml | 2 +- 10 files changed, 81 insertions(+), 56 deletions(-) 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