Update: 2026-08-08 13:33:53
This commit is contained in:
@@ -147,7 +147,70 @@ try {
|
||||
$stmtUpd = $con->prepare($sqlUpdate);
|
||||
$stmtUpd->bindParam(':id', $matchedRowId, PDO::PARAM_INT);
|
||||
$stmtUpd->execute();
|
||||
jsonSuccess(null, "Your phone number has been verified.");
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// تغيير الجهاز: التحقق وحده لا يكفي. لا بد من ربط بصمة
|
||||
// الجهاز الجديد ثم إصدار توكن driver — وإلا بقي التطبيق
|
||||
// على توكن التسجيل ورجع كل endpoint محمي 403، وهو ما كان
|
||||
// يجعل شاشة OTP "تنجح" ثم لا يعمل شيء بعدها.
|
||||
// ═══════════════════════════════════════════════════════
|
||||
$chk = $con->prepare("SELECT id FROM driver WHERE phone = ? OR (? IS NOT NULL AND phone_bidx = ?)");
|
||||
global $blindIndex;
|
||||
$phoneBidx = $blindIndex ? $blindIndex->index('driver.phone', $phone_number) : null;
|
||||
$chk->execute([$encryptionHelper->encryptData($phone_number), $phoneBidx, $phoneBidx]);
|
||||
$driverRow = $chk->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$driverRow) {
|
||||
jsonSuccess(null, "Your phone number has been verified.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$driverID = (string)$driverRow['id'];
|
||||
|
||||
$fpRaw = filterRequest("fingerprint") ?? filterRequest("fingerPrint") ?? ($_SERVER['HTTP_X_DEVICE_FP'] ?? null);
|
||||
if ($fpRaw === null && function_exists('getallheaders')) {
|
||||
$hdrs = array_change_key_case(getallheaders(), CASE_LOWER);
|
||||
$fpRaw = $hdrs['x-device-fp'] ?? null;
|
||||
}
|
||||
|
||||
if (empty($fpRaw)) {
|
||||
jsonError("Device fingerprint is required to complete device change.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$fpPepper = getenv('FP_PEPPER') ?: '';
|
||||
$fpHashed = !empty($fpPepper) ? hash('sha256', $fpRaw . $fpPepper) : $fpRaw;
|
||||
$fcmToken = filterRequest("token");
|
||||
|
||||
// ربط الجهاز الجديد — نفس الصيغة التي يتوقعها loginJwtDriver.
|
||||
$hasRow = $con->prepare("SELECT id FROM driverToken WHERE captain_id = ?");
|
||||
$hasRow->execute([$driverID]);
|
||||
if ($hasRow->fetch(PDO::FETCH_ASSOC)) {
|
||||
if (!empty($fcmToken)) {
|
||||
$con->prepare("UPDATE driverToken SET fingerPrint = ?, token = ? WHERE captain_id = ?")
|
||||
->execute([$fpHashed, $encryptionHelper->encryptData($fcmToken), $driverID]);
|
||||
} else {
|
||||
$con->prepare("UPDATE driverToken SET fingerPrint = ? WHERE captain_id = ?")
|
||||
->execute([$fpHashed, $driverID]);
|
||||
}
|
||||
} else {
|
||||
$con->prepare("INSERT INTO driverToken (token, fingerPrint, captain_id, created_at) VALUES (?, ?, ?, NOW())")
|
||||
->execute([
|
||||
!empty($fcmToken) ? $encryptionHelper->encryptData($fcmToken) : '',
|
||||
$fpHashed,
|
||||
$driverID,
|
||||
]);
|
||||
}
|
||||
|
||||
$audDriver = filterRequest("aud") ?: filterRequest("audience") ?: (getenv('allowedDriver2') ?: 'driver-app:ios');
|
||||
$jwtSvc = new JwtService($redis);
|
||||
$accessToken = $jwtSvc->generateAccessToken($driverID, 'driver', $audDriver, $fpRaw);
|
||||
|
||||
jsonSuccess([
|
||||
"driverID" => $driverID,
|
||||
"jwt" => $accessToken,
|
||||
"access_token" => $accessToken,
|
||||
], "Your phone number has been verified.");
|
||||
} else {
|
||||
jsonError("Your phone number could not be verified or the code is expired. Please try again.");
|
||||
}
|
||||
|
||||
@@ -78,15 +78,28 @@ try {
|
||||
unauthorizedDriver();
|
||||
}
|
||||
|
||||
$fpPepper = getenv('FP_PEPPER') ?: '';
|
||||
$expectedFp = !empty($fpPepper) ? hash('sha256', $fingerprint . $fpPepper) : $fingerprint;
|
||||
// driverToken.fingerPrint مكتوب بصيغتين حسب آخر endpoint لمسه:
|
||||
// • خام — من verify.php و ride/firebase/addDriver.php
|
||||
// • hash مملّح — من loginJwtWalletDriver.php ومن هنا
|
||||
// القبول على صيغة واحدة فقط كان يرفض كل سائق OTP لم يفتح المحفظة
|
||||
// بعد (401 دائم ⇒ يستحيل ترقية توكن التسجيل). نقبل الاثنتين ثم
|
||||
// نُوحّد الصف على الصيغة المُهشّمة.
|
||||
$fpPepper = getenv('FP_PEPPER') ?: '';
|
||||
$storedFp = $fpRow['fingerPrint'];
|
||||
$hashedFp = !empty($fpPepper) ? hash('sha256', $fingerprint . $fpPepper) : $fingerprint;
|
||||
|
||||
if (!hash_equals($fpRow['fingerPrint'], $expectedFp)) {
|
||||
if (!hash_equals($storedFp, $hashedFp) && !hash_equals($storedFp, $fingerprint)) {
|
||||
securityLog("LoginDriver(OTP): fingerprint mismatch", [
|
||||
'driver_id' => $driver['id'],
|
||||
]);
|
||||
unauthorizedDriver();
|
||||
}
|
||||
|
||||
// توحيد التخزين على الصيغة المُهشّمة (لا نحفظ البصمة الخام).
|
||||
if (!hash_equals($storedFp, $hashedFp)) {
|
||||
$con->prepare('UPDATE driverToken SET fingerPrint = :fp WHERE captain_id = :cid')
|
||||
->execute([':fp' => $hashedFp, ':cid' => $driver['id']]);
|
||||
}
|
||||
// ✅ تم التحقق عبر fingerprint — نتابع لتوليد JWT
|
||||
} else {
|
||||
// ── المسار التقليدي: التحقق عبر password + HMAC ──────────
|
||||
|
||||
Reference in New Issue
Block a user