63 Commits
Author SHA1 Message Date
Hamza-Ayed cdd36d4777 Update: 2026-08-07 16:25:34 2026-08-07 16:25:34 +03:00
Hamza-Ayed 9338e76894 Update: 2026-08-07 15:50:04 2026-08-07 15:50:04 +03:00
Hamza-Ayed 67465df000 Update: 2026-08-07 05:56:50 2026-08-07 05:56:50 +03:00
Hamza-Ayed 977d238c84 Update: 2026-08-07 05:03:39 2026-08-07 05:03:39 +03:00
Hamza-Ayed f0ea698ab2 Update: 2026-08-07 02:58:47 2026-08-07 02:58:47 +03:00
Hamza-Ayed e070c2d9a8 Update: 2026-08-07 02:37:30 2026-08-07 02:37:30 +03:00
Hamza-Ayed 70772cf0d2 Update: 2026-08-07 02:32:14 2026-08-07 02:32:15 +03:00
Hamza-Ayed 3081aea802 Update: 2026-08-07 02:19:07 2026-08-07 02:19:07 +03:00
Hamza-Ayed 9830e5f649 Update: 2026-08-07 01:53:09 2026-08-07 01:53:09 +03:00
Hamza-Ayed 5b864e30df Update: 2026-08-07 01:35:27 2026-08-07 01:35:27 +03:00
Hamza-Ayed 0cb1ab0ea3 Update: 2026-08-07 01:06:09 2026-08-07 01:06:09 +03:00
Hamza-Ayed a1104a4695 Update: 2026-08-07 00:57:03 2026-08-07 00:57:03 +03:00
Hamza-Ayed 6e451e8b71 Update: 2026-08-07 00:36:27 2026-08-07 00:36:27 +03:00
Hamza-Ayed 04c214bdf6 Update: 2026-08-03 15:22:47 2026-08-03 15:22:47 +03:00
Hamza-Ayed ec467b01c6 Update: 2026-08-03 11:52:03 2026-08-03 11:52:03 +03:00
Hamza-AyedandClaude Opus 5 ef1240b130 تصحيح مفتاح Redis لموقع السائق: driver:location ← driver:public
الموضعان كانا يقرآن مفتاحاً لا يُكتب في أي مكان في المشروع:
  $redisLocation->hGetAll("driver:location:$driverId")

الكاتب الفعلي هو معالج الدفعات في loction_server/driver_socket.php، وهو
يكتب hmset على driver:profile:{id} و driver:public:{id} معاً بنفس الحقول
(lat/lng/heading/speed/status/updated_at). و driver:public له TTL 86400
بينما driver:profile له 900 فقط، فالعام هو الأنسب للقراءة.

الأثر: كانت حمولة القبول تصل الراكب بلا إحداثيات أولية للسائق، فلا يظهر
الماركر إلا بعد أول تحديث موقع من السوكيت أو الـ polling.

أحد الموضعين ملف getRideOrderID.php الذي أضفته في f66db7db — نسخت النمط
من acceptRide.php فنقلت الخطأ معه.

مثبَّت على الإنتاج: redis-cli --scan --pattern 'driver:*' أرجع
driver:public:<id> فقط، ولا شيء باسم driver:location.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 01:14:26 +03:00
Hamza-AyedandClaude Opus 5 f66db7db42 إضافة getRideOrderID.php المفقود — المسار الاحتياطي لبيانات السائق
تطبيق الراكب يطلب /ride/rides/getRideOrderID.php منذ البداية، والموجود على
السيرفر getRideOrderIDNew.php فقط ⇒ 404 صامت في getUpdatedRideForDriverApply.

هذا يفسّر عرضين ظنّاهما منفصلين:
- الـ polling يسبق الـ FCM فيضبط _isAcceptanceProcessed=true ثم يأخذ 404،
  فيُرفض بعدها payload الـ FCM الذي يحمل driver_info كاملاً
  ("Already processed") ⇒ الرحلة مقبولة بلا معلومات سائق.
- ولأن driverToken يبقى فارغاً، ترد send_fcm.php بـ 400 Missing: target
  ⇒ رسائل الراكب للسائق لا تُرسَل إطلاقاً. (الاتجاه المعاكس كان يعمل بعد
  إصلاح getRideWaiting.php — نفس خطأ التشفير معكوساً.)

getRideOrderIDNew.php لا يصلح بديلاً: داخلي عبر get_connect.php →
validateInternalKey فلا يستطيع التطبيق مناداته، ولا يرجع
ratingCount/completedRides/driverTier.

النقطة الجديدة:
- connect.php (JWT)، والراكب من الـ JWT فقط لا من الطلب (حماية IDOR).
- نفس استعلام acceptRide.php وشكل رده حرفياً حتى يقرأه
  _fillDriverDataLocally بنفس المفاتيح.
- فك تشفير driverToken.token — بلا ذلك يصل التطبيق blob يستخدمه كـ FCM
  target فيرفضه FCM بـ 400.
- تفادي تصادم المفاتيح: getUpdatedRideForDriverApply يقرأ
  passengerName + last_name كاسم الراكب، فلقب السائق نُقل إلى
  driver_last_name واسم الراكب الحقيقي يُرجَّع في مكانه.
- ride DB هو المرجع مع fallback على primary، ورحلة بلا سائق ترد success
  لا failure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 16:18:02 +03:00
Hamza-AyedandClaude Opus 5 143146c1b4 إصلاح سوكيت الراكب وتوحيد مسارات الإشعارات
سوكيت الراكب (سبب عدم ظهور معلومات السائق عند القبول):
- تطبيق الراكب كان يرسل id فقط بلا jwt، و passenger_socket.php يرفض أي
  اتصال بلا jwt ⇒ الراكب لا ينضم لغرفته أبداً ولا يستلم ride_status_change
  ولا driver_location_update. تظهر حالة القبول عبر الـ polling فقط بينما
  driver_info يصل بالسوكيت وحده. (سوكيت السائق يعتبر الـ jwt اختيارياً،
  ومن هنا جاء التباين بين التطبيقين.)
- cancelled_by_driver كان يسقط من switch حالات الراكب فيبقى معلّقاً بعد
  إلغاء السائق.
- حماية socket (late) من القراءة قبل التهيئة عند الانسحاب بلا jwt.

الإشعارات والرسائل (سبب "مرات توصل ومرات لا"):
- جدول tokens يخزّن توكن الراكب مشفّراً، و getRideWaiting.php كان يرجعه
  بلا فك تشفير ⇒ من يقبل من قائمة السوق يحمل blob مشفّراً يستخدمه كـ FCM
  target فيرفضه FCM بـ 400: لا إشعار قبول ولا رسائل. ومن يقبل من الـ
  dispatch/FCM يحمل نصاً صريحاً فتعمل. الفرق كان في طريقة القبول.
- acceptRide.php يحلّ التوكن من القاعدة دائماً ولا يثق بالعميل (أصحّ أمنياً).
- market_new_ride كان لا يحمل passengerId ولا الإحداثيات فتصل "null"؛
  أُضيفت بلا أي PII لأن الحمولة تُبَثّ لكل سائق قريب لا للفائز فقط.
- send_fcm.php: مهلة على OAuth (كان يعلّق حتى مهلة PHP فتُسقط الرسالة
  بصمت)، توحيد ding→default لأندرويد، وحقن title/body/tone في data
  مطابقةً لـ FcmService.
- تطبيق السائق يقرأ title/body من data أولاً مثل الراكب، ولا يعرض فقاعة
  فارغة للرسائل الصامتة.

السوكيت والإعدادات:
- forwardLocationToPassengerSocket كان يقرأ lat/lng والحمولة فيها
  latitude/longitude ⇒ المسافة تخرج ضخمة والـ throttle معطّل تماماً
  فيُعاد التوجيه مع كل نبضة GPS.
- notifyPassengerOnRideServer كان يرجع null بصمت مطلق عند حجب العنوان.
- العنوان الافتراضي لسيرفر الموقع كان nginx/loction_server/driver_socket.php
  وهو ديمون Workerman لا يُخدَم عبر nginx ⇒ صار socket_driver:2021.
  (LOCATION_API_URL بقي على nginx لأن api_get_nearby.php سكربت عادي.)
- ride_server/passenger_socket.php (النسخة التي يشغّلها Docker) كانت ناقصة
  كل كود مواصلاتي الموجود في passenger_server/ ⇒ نُقل مع REDIS_HOST.
- .env.example: ALLOWED_SOCKET_URLS يغطّي أسماء حاويات Docker، وإضافة
  PASSENGER_SOCKET_INTERNAL_URL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 15:47:23 +03:00
Hamza-Ayed 2bacb1b9e1 تحديث شامل للوحة التحكم وإضافة كافة الميزات للـ WebSidebar 2026-07-26 03:22:47 +03:00
Hamza-Ayed 474c212bcb refactor: migrate amount fields to decimal and implement location service restriction for unsupported regions 2026-07-24 15:08:37 +03:00
Hamza-Ayed 12a1cbc98c Update: 2026-07-23 20:15:22 2026-07-23 20:15:22 +03:00
Hamza-Ayed c35b350b31 Update: 2026-07-23 16:56:57 2026-07-23 16:56:58 +03:00
Hamza-Ayed e5bf70fddb Update: 2026-07-23 02:14:58 2026-07-23 02:14:58 +03:00
Hamza-Ayed 8ec0ac2942 Update: 2026-07-22 01:35:37 2026-07-22 01:35:37 +03:00
Hamza-Ayed 540e77984b Update: 2026-07-22 00:44:11 2026-07-22 00:44:11 +03:00
Hamza-Ayed bec8089fd1 Update: 2026-07-22 00:42:09 2026-07-22 00:42:09 +03:00
Hamza-Ayed 16101927e1 Update: 2026-07-22 00:39:28 2026-07-22 00:39:28 +03:00
Hamza-Ayed 58222fbf81 Update: 2026-07-22 00:37:03 2026-07-22 00:37:03 +03:00
Hamza-Ayed bcab0ea221 Update: 2026-07-22 00:36:04 2026-07-22 00:36:05 +03:00
Hamza-Ayed b18fd027b6 Update: 2026-07-10 03:04:06 2026-07-10 03:04:06 +03:00
Hamza-Ayed a526dae042 Update: 2026-07-09 04:13:14 2026-07-09 04:13:14 +03:00
Hamza-Ayed 70718946f5 Update: 2026-07-09 03:41:48 2026-07-09 03:41:48 +03:00
Hamza-Ayed 7dff7b6973 Update: 2026-07-09 01:55:25 2026-07-09 01:55:25 +03:00
Hamza-Ayed 628e169552 Update: 2026-07-07 04:57:50 2026-07-07 04:57:51 +03:00
Hamza-Ayed d6ab09c19b Update: 2026-07-06 18:23:46 2026-07-06 18:23:46 +03:00
Hamza-Ayed 3e0b4cbf64 Update: 2026-07-04 18:43:56 2026-07-04 18:43:57 +03:00
Hamza-Ayed 5ce6c00905 Update: 2026-07-03 01:48:00 2026-07-03 01:48:00 +03:00
Hamza-Ayed 8f59189832 Update: 2026-07-02 17:46:29 2026-07-02 17:46:29 +03:00
Hamza-Ayed 6876d9bc54 Update: 2026-07-02 17:44:58 2026-07-02 17:44:59 +03:00
Hamza-Ayed 5d14493ff4 Update: 2026-07-02 16:52:25 2026-07-02 16:52:25 +03:00
Hamza-Ayed 75e6fc42d7 Update: 2026-07-02 15:35:12 2026-07-02 15:35:12 +03:00
Hamza-Ayed 43e3f8c939 Fix: update destination limits to 3 and sync with Redis 2026-06-27 17:49:03 +03:00
Hamza-Ayed 72afd11a57 Update: 2026-06-26 04:24:20 2026-06-26 04:24:20 +03:00
Hamza-Ayed da9e6eb981 Update: 2026-06-26 04:04:03 2026-06-26 04:04:04 +03:00
Hamza-Ayed 6fcc4a0649 Update: 2026-06-26 00:36:22 2026-06-26 00:36:22 +03:00
Hamza-Ayed e73be65a72 Update: 2026-06-21 18:58:05 2026-06-21 18:58:13 +03:00
Hamza-Ayed b2fae9ec66 Update: 2026-06-21 02:07:00 2026-06-21 02:07:00 +03:00
Hamza-Ayed a8748cf4c9 Fix #22: Medium-severity fixes (M-01 through M-07)
M-01: Host header injection - replaced HTTP_HOST with APP_DOMAIN
M-02: Unauthenticated CRUD - ownership checks on carDrivers add/delete
M-03: MD5 tracking token - replaced md5() with hash_hmac sha256
M-04: Webhook SMS - absolute log path instead of relative
M-05: Weak 3-digit OTP - already noted as requirement (Fix #5)
M-06: Redis without auth - added password + prefix to cancel_ride_by_driver
M-07: SSRF bypass - str_ends_with -> strict equality in allowlist
2026-06-17 07:58:21 +03:00
Hamza-Ayed 3543fdd2cd Fix #21: High-severity fixes (H-01 through H-06)
H-01: Egypt document uploads - added path traversal prevention (basename),
       replaced HTTP_HOST with APP_DOMAIN env var
H-02: 7 remaining hardcoded /home/siro-api/ paths replaced with env vars
       (ENV_FILE_PATH, INTERNAL_SOCKET_KEY_PATH, WEBHOOK_SECRET_KEY_PATH)
H-03: serviceapp/updateDriver.php - added ownership check (user_id must match
       driverID or user must be admin); non-admins blocked from changing
       password/status/email/phone
H-04: ggg.php - replaced weak client-supplied phone auth with proper admin
       JWT authentication via JwtService
H-05: Static IV fallback in encrypt_decrypt.php already documented as legacy
H-06: Wallet shared password noted as design limitation (mitigated by
       fingerprint verification + short token TTL)
- Also fixed functions.php log message (removed hardcoded path)
2026-06-17 07:56:57 +03:00
Hamza-Ayed 72eeb24cd7 Fix #18: Exception leak remediation across 87 PHP files
- Replaced all client-facing $e->getMessage() with generic error messages
- Added error_log() with filename prefix to all catch blocks
- Covered jsonError(), echo, and json_encode() response patterns
- Also fixed 2 remaining display_errors=1 and add_invoice.php leak
- Script-assisted fix for 75 files, manual fix for 12 remaining edge cases
2026-06-17 07:48:31 +03:00