'failure', 'error_code' => 'REGION_MISMATCH', 'message' => "Region mismatch: Request host '$requestHost' does not match server domain '$appDomain'." ])); } } require_once __DIR__ . '/functions.php'; // 1. Rate Limiting and JWT Authentication $limiter = new RateLimiter($redis); $limiter->enforce(RateLimiter::identifier(), 'api'); $jwtService = new JwtService($redis); $decoded = $jwtService->authenticate(); // متغيرات مساعدة للمطور $user_id = $decoded->user_id ?? null; $role = $decoded->role ?? 'passenger'; // ============================================================ // 2. بوّابة صلاحيات افتراضية لمسار /Admin // ============================================================ // النموذج السابق كان «آمن إن تذكّرت»: كل نقطة تحت Admin/ تفحص الدور بنفسها، // ومن يُغفل الفحص يصبح مكشوفاً. وقد وُجد فعلاً أن getPassengerDetails.php // و getPassengerDetailsByPassengerID.php و getPassengerbyEmail.php كانت بلا // أي فحص، فكان أي حامل JWT صالح — بما فيه راكب عادي — يقرأ بيانات ركّاب // مفكوكة التشفير. // // هنا نقلب النموذج إلى «آمن افتراضاً»: كل ملف تحت Admin/ يمرّ عبر connect.php // يتطلب دور admin أو super_admin، ما لم يكن في قائمة استثناء صريحة. // // نقاط تسجيل الدخول (Admin/auth/*, jwtService.php) لا تستدعي connect.php // أصلاً، فلا تتأثر بهذه البوّابة ولا يمكن أن تُقفل على نفسها. $adminDir = realpath(__DIR__ . '/Admin'); $script = realpath($_SERVER['SCRIPT_FILENAME'] ?? ''); if ($adminDir && $script && str_starts_with($script, $adminDir . DIRECTORY_SEPARATOR)) { // نقاط تحت Admin/ تستدعيها تطبيقات الجوال بأدوار غير إدارية. // تم التحقق من مواضع الاستدعاء الفعلية في siro_rider و siro_driver: // errorApp.php → التطبيقان يبلّغان عن الأخطاء // sendEmailToDrivertransaction.php → تطبيق السائق // بقية روابط Admin/ المعرّفة في التطبيقين غير مستدعاة إطلاقاً. $adminGateExempt = [ 'errorApp.php', 'sendEmailToDrivertransaction.php', ]; if (!in_array(basename($script), $adminGateExempt, true) && $role !== 'admin' && $role !== 'super_admin' ) { securityLog('Admin gate blocked non-admin request', [ 'script' => basename($script), 'role' => $role, 'user_id' => $user_id ?? 'unknown', 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown', ]); http_response_code(403); exit(json_encode([ 'status' => 'failure', 'message' => 'Forbidden. Admin access required.', ], JSON_UNESCAPED_UNICODE)); } } // 3. Database Connection try { $con = Database::get('main'); } catch (Exception $e) { http_response_code(500); exit(json_encode(['error' => 'Database connection failed'])); }