prepare("SELECT * FROM token_verification_admin WHERE phone_number = ? AND token = ? AND expiration_time >= NOW()"); $stmt->execute([$phone, $otp]); if ($stmt->rowCount() === 0) { jsonError("رمز التحقق غير صالح أو منتهي الصلاحية."); exit; } // حذف الرمز بعد استخدامه لمرة واحدة $con->prepare("DELETE FROM token_verification_admin WHERE phone_number = ?")->execute([$phone]); // 2. جلب بيانات المسؤول $stmt = $con->prepare("SELECT * FROM adminUser WHERE phone = ? LIMIT 1"); $stmt->execute([$phone]); $admin = $stmt->fetch(PDO::FETCH_ASSOC); if (!$admin) { jsonError("المسؤول غير موجود."); exit; } // 3. التحقق من البصمة (اختياري لكن مفضل لزيادة الأمان) $fpHash = hash('sha256', $fingerprint); if ($admin['fingerprint_hash'] !== $fpHash) { // إذا كانت البصمة مختلفة، ربما يحاول تسجيل الدخول من جهاز آخر // يمكننا إما المنع أو السماح وتحديث البصمة (حسب السياسة) // هنا سنقوم بالمنع لزيادة الأمان jsonError("عذراً، لا يمكن تسجيل الدخول من هذا الجهاز."); exit; } // 4. إصدار التوكن النهائي $jwtService = new JwtService($redis); $role = $admin['role'] ?? 'admin'; // إلغاء التوكن القديم إذا وجد في Redis (Token Revocation) if ($redis) { $oldJti = $redis->get("active_jti:" . $admin['id']); if ($oldJti) { $jwtService->revokeToken($oldJti, 3600); } } $jwt = $jwtService->generateAccessToken($admin['id'], $role, $audience, $fingerprint); // فك تشفير الاسم للعرض $admin['name'] = $encryptionHelper->decryptData($admin['name']) ?: $admin['name']; unset($admin['password']); printSuccess([ "message" => "Login successful", "admin" => $admin, "jwt" => $jwt, "expires_in" => 3600 ]); } catch (Exception $e) { error_log("[Admin Verify OTP Error] " . $e->getMessage()); jsonError("خطأ في السيرفر: " . $e->getMessage()); }