# تحليل تدفق الراكب (Siro Rider) ## من Flutter إلى PHP Backend — تسجيل + دخول + OTP --- ## 1. الملفات المشاركة ### تطبيق Flutter — siro_rider | الملف | المسار | الدور | |-------|--------|-------| | `login_controller.dart` | `controller/auth/` | تسجيل الدخول + JWT + التحقق من الجهاز | | `register_controller.dart` | `controller/auth/` | إنشاء حساب جديد + OTP + SMS | | `otp_controller.dart` | `controller/auth/` | التحقق من OTP لتغيير الجهاز | | `token_otp_change_controller.dart` | `controller/auth/` | إدارة OTP لتغيير التوكن | | `verify_email_controller.dart` | `controller/auth/` | التحقق من الإيميل | | `crud.dart` | `controller/functions/` | HTTP client مع JWT + NetGuard | | `sms_controller.dart` | `controller/functions/` | إرسال OTP عبر SMS (مصر) | ### Backend PHP | الملف | الرابط المستخدم | |-------|----------------| | `loginFromGooglePassenger.php` | `loginFromGooglePassenger` | | `loginFirstTime.php` | `loginFirstTime` | | `login.php` | `loginJwtRider` | | `auth/signup.php` | `signUp` | | `auth/checkPhoneNumberISVerfiedPassenger.php` | `checkPhoneNumberISVerfiedPassenger` | | `auth/otp/request.php` | `sendVerifyOtpMessage` | | `auth/otp/verify.php` | `verifyOtpPassenger` | | `auth/verifyEmail.php` | `verifyEmail` | --- ## 2. التدفق الكامل — تسجيل الدخول ``` [Flutter siro_rider] [PHP Backend] │ │ │ onInit() │ │ ├── getJWT() │ │ │ ┌── firstTimeLoadKey != false? │ │ │ ├── نعم → loginFirstTime.php │ │ │ │ POST { id, password, aud, │ │ │ │ fingerPrint } │ │ │ │ ─────────────────────────────────>│ │ │ │ ← Registration JWT (150s) │ │ │ │ │ │ │ └── لا → login.php (تجديد) │ │ │ POST { id, fingerPrint, aud } │ │ │ ─────────────────────────────────>│ │ │ ← Access JWT (3600s) │ │ │ │ │ ├── isTokenValid() │ │ │ ← يتحقق من exp يدوياً (بدون مكتبة) │ │ │ │ │ │ │ │ loginUsingCredentials(passengerID, email) │ │ GET loginFromGooglePassenger.php │ │ ?email=X&id=Y&platform=Z&appName=W │ │ ─────────────────────────────────────────>│ │ │ 【connect.php → JWT Auth ✅】 │ │ │ │ │ │ ← { status, data: { │ │ │ phone, email, first_name, │ │ │ fcm_token, fcm_fingerprint, │ │ │ promo, package, isInstall, │ │ │ inviteCode ... } } │ │ │ │ │ ├── يخزّن البيانات في GetStorage │ │ ├── يفحص verified = '1'? │ │ │ └── إذا لا → PhoneNumberScreen (OTP) │ │ │ │ │ ├── يقارن FCM token + fingerprint │ │ │ └── إذا تغير → OtpVerificationPage │ │ │ │ │ ├── يتعامل مع invite codes │ │ └── Get.offAll(MapPagePassenger) │ │ │ ``` --- ## 3. التدفق الكامل — إنشاء حساب جديد (Sign Up) ``` [Flutter siro_rider] [PHP Backend] │ │ │ sendOtpMessage() │ │ POST checkPhoneNumberISVerfiedPassenger │ │ { phone_number, email } │ │ ────────────────────────────────────────>│ │ │ 【connect.php → JWT Auth ✅】 │ │ │ │ │ │ ← is_verified=1? │ │ │ │ │ ├── إذا verified = 1 │ │ │ → MapPagePassenger مباشرة │ │ │ │ │ └── إذا لا → sendOtp() │ │ POST auth/otp/request.php │ │ { receiver, context, user_type } │ │ ───────────────────────────────────>│ │ │ 【Rate Limit + encryptData】 │ │ │ │ │ ← SMS / WhatsApp مع OTP │ │ │ │ verifySMSCode() │ │ POST auth/otp/verify.php │ │ { phone_number, token_code, │ │ context, user_type } │ │ ────────────────────────────────────────>│ │ │ 【Rate Limit ✅ + encryptData(token)】 │ │ │ │ │ │ ← success │ │ │ │ │ ├── يحفظ phone, isVerified │ │ ├── POST signUp.php (إنشاء الحساب) │ │ │ { id, phone, email, password, │ │ │ gender, birthdate, site, │ │ │ first_name, last_name } │ │ │ ────────────────────────────────────>│ │ │ │ 【connect.php → JWT Auth ✅】 │ │ │ │ │ │ └── loginUsingCredentials() → الدخول │ │ │ ``` --- ## 4. تدفق OTP — كامل مع التشفير ``` [Flutter] [auth/otp/request.php] [auth/otp/verify.php] │ │ │ │ POST /auth/otp/request.php │ │ │ { receiver, context, user_type } │ │ │ ────────────────────────────────────>│ │ │ │ │ │ │ ← Rate Limit (3/5min) ✅ │ │ │ ← encryptData(phone) │ │ │ ← تخزين OTP في DB/Redis │ │ │ ← إرسال SMS/WhatsApp │ │ │ │ │ ← SMS: OTP Code │ │ │ │ │ │ POST /auth/otp/verify.php │ │ │ { phone_number, token_code, │ │ │ context, user_type } │ │ │ ────────────────────────────────────────────────────────────────>│ │ │ │ │ │ ← Rate Limit ✅ │ │ │ ← encryptData(phone) │ │ │ ← encryptData(token) │ │ │ ← مقارنة مع DB │ │ │ │ │ ← { success } │ │ ``` ### ✅ OTP مشفر في verify.php: ```php // السطر 67 $encryptedToken = $encryptionHelper->encryptData($token_code); ``` --- ## 5. ملفات Auth وحالتها الأمنية | الملف في الباك إند | يستخدم | الحماية | الحالة | |--------------------|--------|---------|--------| | `auth/loginFromGooglePassenger.php` | `connect.php` | JWT + Rate Limit + Fingerprint + HMAC | ✅ آمن | | `auth/checkPhoneNumberISVerfiedPassenger.php` | `connect.php` | JWT + Rate Limit | ✅ آمن | | `auth/signup.php` | `connect.php` | JWT + Rate Limit | ✅ آمن | | `loginFirstTime.php` | `bootstrap.php` | Password + Rate Limit (3/ساعة) + Pepper | ✅ آمن | | `login.php` | `bootstrap.php` | Fingerprint + Rate Limit + Revocation | ✅ آمن | | `auth/otp/request.php` | `bootstrap.php` | Rate Limit + encryptData | ✅ آمن | | `auth/otp/verify.php` | `bootstrap.php` | Rate Limit ✅ + encryptData | ✅ آمن | | `auth/verifyEmail.php` | `connect.php` | JWT + Rate Limit | ✅ آمن | --- ## 6. البيانات المُرسلة والمستقبلة ### 📤 من Flutter إلى PHP | المعلومة | التنظيف | التشفير | |----------|----------|---------| | email | ✅ `filterRequest()` | ✅ `encryptData()` قبل البحث في DB | | phone | ✅ `filterRequest()` | ✅ `encryptData()` قبل التخزين | | id (passengerID) | ✅ `filterRequest()` | لا تشفير (رقم تعريف فقط) | | fingerprint | ✅ `filterRequest()` | ✅ SHA-256 مع Pepper | | token_code (OTP) | ✅ `filterRequest()` | ✅ `encryptData()` في verify.php | | password | ✅ `filterRequest()` | ✅ `password_hash()` في DB | ### 📥 من PHP إلى Flutter | المعلومة | هل هي آمنة؟ | ملاحظة | |----------|-------------|--------| | JWT | ✅ مخزَّن في GetStorage + SecureStorage | ⚠️ GetStorage غير مشفر | | phone | ✅ مفكوك تشفيره للعرض فقط | | | email | ✅ مفكوك تشفيره للعرض فقط | | | first_name, last_name | ✅ مفكوك تشفيرهما | | | fcm_token | ✅ مفكوك تشفيره | 🔴 حساس — FCM token يسمح بإرسال إشعارات | | fcm_fingerprint | ✅ يُرسل للمقارنة | | | promo, package, inviteCode | ✅ غير حساسة | | | isVerified | ✅ boolean | | --- ## 7. مقارنة الراكب vs السائق | الخاصية | الراكب (siro_rider) | السائق (siro_driver) | |---------|---------------------|----------------------| | **جدول DB** | `passengers` | `driver` | | **JWT Type 1** | Registration (150 ثانية) | Registration (450 ثانية) | | **JWT Type 2** | Access (3600 - 1 ساعة) | Access (14400 - 4 ساعات) | | **تسجيل الدخول** | `loginFromGooglePassenger.php` عبر `connect.php` | `loginFromGoogle.php` عبر `connect.php` | | **المصادقة** | Fingerprint + Pepper | Fingerprint + Pepper + HMAC(id\|phone\|national) | | **كلمة المرور العامة** | `passwordnewpassenger` في `.env` | `passwordnewpassenger` في `.env` | | **OTP** | `auth/otp/verify.php` (user_type=passenger) | `auth/otp/verify.php` (user_type=driver) | | **فحص الجهاز** | يقارن FCM token + fingerprint | يقارن driver token + fingerprint | | **Rate Limiting OTP** | ✅ مُضاف (request + verify) | ✅ مُضاف (request + verify) | | **IsVerified شرط** | `verified = '1'` إجباري | `is_verified = '1'` إجباري | --- ## 8. الملخص النهائي | البند | النتيجة | |-------|---------| | **التدفق العام** | ✅ صحيح — Flutter → connect.php (JWT) → معالجة → رد | | **connect.php يحمي** | ✅ loginFromGoogle, checkPhone, signup, verifyEmail | | **JWT + Fingerprint** | ✅ Registration (150s) → Access (1h) مع Pepper | | **Token Revocation** | ✅ عبر Redis في `login.php` | | **OTP مشفر** | ✅ `encryptData(token_code)` في verify.php | | **Rate Limiting** | ✅ على login (5/دقيقة)، OTP request (3/5min)، OTP verify (3/5min) | | **كشف تغيير الجهاز** | ✅ يقارن FCM token + fingerprint → OTP إذا اختلف | | **Timing Attack** | ✅ `usleep()` في login.php | | **تشفير DB** | ✅ جميع PII مشفرة | ### ⚠️ ملاحظة واحدة يُستخدم `GetStorage` لتخزين JWT، وهو غير مشفر. لكنه يُستخدم مع `FlutterSecureStorage` أيضاً. يُفضل الاعتماد على `FlutterSecureStorage` فقط للـ JWT. ### ✅ الخلاصة **تدفق الراكب (Siro Rider) صحيح أمنياً وإجرائياً بالكامل.** - جميع ملفات Auth محمية عبر `connect.php` الحديث (JWT + Rate Limit) - OTP مشفر قبل التخزين والمقارنة - JWT مرتبط بالجهاز عبر Fingerprint + Pepper - كشف تغيير الجهاز عبر FCM + Fingerprint - Rate Limiting على جميع نقاط الدخول