<div dir="rtl" lang="ar">

# سير عمل تسجيل الدخول في نظام Siro

## توثيق شامل لتدفق المصادقة للمشرفين (Super Admin / Admin) وموظفي خدمة العملاء (Service Staff)

---

## 📋 فهرس المحتويات

1. [نظرة عامة على النظام](#نظرة-عامة-على-النظام)
2. [المكونات الرئيسية](#المكونات-الرئيسية)
3. [سير عمل تسجيل حساب مشرف جديد](#سير-عمل-تسجيل-حساب-مشرف-جديد)
4. [سير عمل تسجيل الدخول (المشرف - siro_admin)](#سير-عمل-تسجيل-الدخول-المشرف---siro_admin)
5. [سير عمل تسجيل الدخول (موظف الخدمة - siro_service)](#سير-عمل-تسجيل-الدخول-موظف-الخدمة---siro_service)
6. [سير عمل إضافة الموظفين من قبل المشرف العام](#سير-عمل-إضافة-الموظفين-من-قبل-المشرف-العام)
7. [سير عمل تفعيل الحسابات المعلقة](#سير-عمل-تفعيل-الحسابات-المعلقة)
8. [مقارنة بين تدفق siro_admin و siro_service](#مقارنة-بين-تدفق-siro_admin-و-siro_service)
9. [الجوانب الأمنية (Security)](#الجوانب-الأمنية-security)
10. [قائمة الإصلاحات الأمنية المُنفَّذة](#قائمة-الإصلاحات-الأمنية-المنفذة)
11. [الإجراءات الموصى بها للتحسين (Recommendations)](#الإجراءات-الموصى-بها-للتحسين-recommendations)

---

## نظرة عامة على النظام

نظام Siro يستخدم بنية متعددة التطبيقات (Multi-App Architecture):

| التطبيق | الدور | ملفات المصادقة |
|---------|-------|-----------------|
| **siro_admin** | المشرفون (Admin / Super Admin) | `siro_admin/lib/views/auth/login_page.dart`, `otp_helper.dart` |
| **siro_service** | موظفو خدمة العملاء | `siro_service/lib/controller/login_controller.dart` |
| **Backend (PHP)** | الخادم المركزي | `backend/Admin/auth/login.php`, `backend/serviceapp/login.php` |

المبدأ الأساسي: **المصادقة متعددة العوامل (MFA)** تعتمد على:

1. **بصمة الجهاز (Fingerprint)** — يتم إنشاؤها في التطبيق وإرسالها مع كل طلب
2. **كلمة المرور** — مشفرة باستخدام `password_hash`
3. **OTP عبر WhatsApp** — للتحقق الإضافي (للمشرفين حصراً)
4. **JWT** — التوكن النهائي للوصول

---

## المكونات الرئيسية

### تطبيق siro_admin (المشرفون)

| الملف | المسار | الوظيفة |
|-------|--------|---------|
| `login_page.dart` | `siro_admin/lib/views/auth/` | واجهة تسجيل الدخول (كلمة مرور + هاتف اختياري) |
| `register_page.dart` | `siro_admin/lib/views/auth/` | واجهة طلب حساب مشرف جديد |
| `otp_helper.dart` | `siro_admin/lib/controller/auth/` | منطق OTP وجدولة إعادة الدخول (Auto Login) |
| `register_controller.dart` | `siro_admin/lib/controller/auth/` | منطق التسجيل |

### تطبيق siro_service (خدمة العملاء)

| الملف | المسار | الوظيفة |
|-------|--------|---------|
| `login_controller.dart` | `siro_service/lib/controller/` | منطق تسجيل الدخول مع OTP |
| (لا يوجد register) | | التسجيل يتم عبر `backend/serviceapp/register.php` أو عبر `add.php` |

### الباك إند (PHP)

| الملف | المسار | الوظيفة |
|-------|--------|---------|
| `login.php` | `backend/Admin/auth/` | تسجيل دخول المشرف (الخطوة الأولى) |
| `verify_login.php` | `backend/Admin/auth/` | التحقق من OTP للمشرف (الخطوة الثانية) |
| `register.php` | `backend/Admin/auth/` | تسجيل مشرف جديد |
| `login.php` | `backend/serviceapp/` | تسجيل دخول موظف الخدمة |
| `register.php` | `backend/serviceapp/` | تسجيل موظف خدمة جديد |
| `add.php` | `backend/Admin/Staff/` | إضافة موظف/مشرف من قبل المشرف العام |
| `pending.php` | `backend/Admin/Staff/` | جلب الحسابات المعلقة |
| `activate.php` | `backend/Admin/Staff/` | تفعيل الحسابات المعلقة |
| `jwtService.php` | `backend/Admin/jwtService.php` | إصدار JWT لخدمة العملاء (قديم) |
| `JwtService.php` | `backend/core/Auth/` | خدمة JWT الأساسية مع Authentication |

---

## سير عمل تسجيل حساب مشرف جديد

### 📍 يبدأ من تطبيق siro_admin ← `register_page.dart`

```
[المستخدم]                    [التطبيق (Flutter)]                       [الباك إند (PHP)]                [قاعدة البيانات]
    |                              |                                          |                              |
    |── يدخل الاسم، الهاتف،        |                                          |                              |
    |   كلمة المرور                |                                          |                              |
    |─────────────────────────────>|                                          |                              |
    |                              |                                          |                              |
    |                              |── قراءة بصمة الجهاز (fingerprint)        |                              |
    |                              |   من `box.read('fingerprint')`           |                              |
    |                              |                                          |                              |
    |                              |── POST `/Admin/auth/register.php`        |                              |
    |                              |   مع: name, phone, password, fingerprint |                              |
    |                              |──────────────────────────────────────────>|                              |
    |                              |                                          |                              |
    |                              |                                          |── التحقق من القائمة البيضاء  |
    |                              |                                          |   `AUTHORIZED_ADMIN_PHONES`   |
    |                              |                                          |   في متغيرات البيئة (.env)    |
    |                              |                                          |                              |
    |                              |                                          |── التحقق من التكرار:         |
    |                              |                                          |   phone OR fingerprint_hash  |
    |                              |                                          |                              |
    |                              |                                          |── تشفير البيانات:            |
    |                              |                                          |   • name ← encryptData()     |
    |                              |                                          |   • phone ← encryptData()    |
    |                              |                                          |   • fingerprint ← encrypt()  |
    |                              |                                          |   • fingerprint_hash =       |
    |                              |                                          |     SHA-256(fingerprint)     |
    |                              |                                          |   • password ← password_hash |
    |                              |                                          |                              |
    |                              |                                          |── توليد UUID آمن:            |
    |                              |                                          |   bin2hex(random_bytes(16))  |
    |                              |                                          |                              |
    |                              |                                          |── INSERT INTO adminUser      |
    |                              |                                          |   status = 'pending'         |
    |                              |                                          |   role = 'admin'             |
    |                              |                                          |─────────────────────────────>|  (id, fingerprint, fingerprint_hash,
    |                              |                                          |                              |   name, phone, password, role,
    |                              |                                          |                              |   status='pending', created_at)
    |                              |                                          |                              |
    |                              |<── { status: "pending", message: "..." }  |                              |
    |                              |                                          |                              |
    |<── رسالة "تم تقديم الطلب"    |                                          |                              |
```

### ملاحظات أمنية حول التسجيل:

- ✅ القائمة البيضاء (`AUTHORIZED_ADMIN_PHONES`) تمنع أي شخص من التسجيل دون إذن مسبق
- ✅ الاسم والهاتف والبصمة مشفرة في قاعدة البيانات
- ✅ بصمة الجهاز محولة إلى SHA-256 Hash للبحث السريع
- ✅ **`bin2hex(random_bytes(16))`** لتوليد UUID آمن — تم إصلاحه من `rand()`
- 🔴 الحساب ينشأ بحالة `pending` ولا يمكنه الدخول حتى يتم تفعيله يدوياً

---

## سير عمل تسجيل الدخول (المشرف - siro_admin)

### 📍 يبدأ من `login_page.dart` ← `OtpHelper.loginWithPassword()`

#### الخطوة الأولى: إرسال طلب الدخول

```
[المستخدم]            [otp_helper.dart]                  [login.php (Backend)]             [Redis / DB]
    |                       |                                   |                              |
    |── يدخل كلمة المرور    |                                   |                              |
    |   (ورقم الهاتف لأول   |                                   |                              |
    |    مرة)               |                                   |                              |
    |──────────────────────>|                                   |                              |
    |                       |                                   |                              |
    |                       |── POST /Admin/auth/login.php      |                              |
    |                       |   payload: fingerprint,           |                              |
    |                       |   password, phone (اختياري),      |                              |
    |                       |   aud (اختياري), is_renewal       |                              |
    |                       |──────────────────────────────────>|                              |
    |                       |                                   |                              |
    |                       |                                   |── Rate Limiting:             |
    |                       |                                   |   5 محاولات/دقيقة لكل IP    |
    |                       |                                   |                              |
    |                       |                                   |── البحث بـ fingerprint_hash  |
    |                       |                                   |   (SHA-256 للبصمة)           |
    |                       |                                   |                              |
    |                       |      [إذا لم يوجد بالبصمة والهاتف موجود]                          |
    |                       |                                   |── البحث بالهاتف المشفر       |
    |                       |                                   |   (لأول مرة أو جهاز جديد)    |
    |                       |                                   |                              |
    |                       |                                   |── التحقق من status:          |
    |                       |                                   |   • pending → رفض مع رسالة   |
    |                       |                                   |   • suspended → رفض          |
    |                       |                                   |   • rejected → رفض           |
    |                       |                                   |   • active → متابعة          |
    |                       |                                   |                              |
    |                       |                                   |── التحقق من كلمة المرور:     |
    |                       |                                   |   password_verify(password)  |
    |                       |                                   |                              |
```

#### التفرع حسب `is_renewal`:

```
                                   |
                   ┌───────────────┴───────────────┐
                   |                                |
              is_renewal=1                    is_renewal=0 أو missing
           (إعادة دخول تلقائي)                 (تسجيل دخول يدوي)
                   |                                |
                   |                                ├── توليد OTP عشوائي
                   |                                |   (100000-999999) ← 6 أرقام
                   |                                |
                   |                                ├── فك تشفير رقم الهاتف
                   |                                |   ← إرسال OTP عبر WhatsApp
                   |                                |
                   |                                ├── حفظ OTP مشفراً:
                   |                                |   `token_verification_admin`
                   |                                |   (phone مشفر، token مشفر،
                   |                                |    expiration 10 دقائق)
                   |                                |
                   |                                └── رد: { status: "otp_required",
                   |                                        phone: masked }
                   |
                   ├── إلغاء التوكن القديم من Redis
                   |   (Token Revocation)
                   |
                   ├── توليد JWT جديد:
                   |   generateAccessToken(id, role, aud, fingerprint)
                   |
                   └── رد مباشر: { jwt, admin, expires_in }
```

### الخطوة الثانية (عند طلب OTP): التحقق ← `verify_login.php`

```
[otp_helper.dart]              [verify_login.php]                    [DB / Redis]
       |                              |                                  |
       |── POST /Admin/auth/         |                                  |
       |   verify_login.php          |                                  |
       |   payload: otp,             |                                  |
       |   fingerprint, phone        |                                  |
       |────────────────────────────>|                                  |
       |                              |                                  |
       |                              |── Rate Limiting:                |
       |                              |   3 محاولات OTP/5 دقائق لكل IP |
       |                              |                                  |
       |                              |── البحث بالـ fingerprint_hash   |
       |                              |   من جدول adminUser             |
       |                              |                                  |
       |                              |── تشفير OTP المدخل              |
       |                              |   encryptData(otp)              |
       |                              |                                  |
       |                              |── البحث في token_verification:  |
       |                              |   phone_number = encryptedPhone |
       |                              |   AND token = encryptedOtp      |
       |                              |   AND expiration >= NOW()       |
       |                              |                                  |
       |     [غير صالح أو منتهي]      |                                  |
       |<── "رمز التحقق غير صالح"     |                                  |
       |                              |                                  |
       |     [صالح]                   |                                  |
       |                              |── حذف OTP (استخدام لمرة واحدة)  |
       |                              |   DELETE FROM token_verification |
       |                              |                                  |
       |                              |── إلغاء التوكن القديم من Redis   |
       |                              |                                  |
       |                              |── توليد JWT جديد:                |
       |                              |   generateAccessToken(id, role,  |
       |                              |   aud, fingerprint)             |
       |                              |                                  |
       |<── { jwt, admin, expires_in }|                                  |
       |                              |                                  |
       |── حفظ البيانات محلياً:       |                                  |
       |   • JWT ← box.write(jwt)    |                                  |
       |   • admin_id ← box.write    |                                  |
       |   • admin_role ← box.write  |                                  |
       |   • phoneVerified ← true    |                                  |
       |   • admin_password ← حفظ     |                                  |
       |                              |                                  |
       |── Get.offAll(AdminHomePage())|                                  |
```

### مخطط الحالة الكامل للمشرف (State Machine):

```
                        ┌───────────┐
                        │  Pending  │  ← بعد التسجيل، بحاجة تفعيل
                        └─────┬─────┘
                              │ Activate.php (يتطلب JWT مع role=admin)
                              ▼
                     ┌─────────────────┐
                     │     Active      │  ← يمكنه تسجيل الدخول
                     └────────┬────────┘
                              │
                    ┌─────────┴──────────┐
                    │                    │
                    ▼                    ▼
             ┌───────────┐        ┌───────────┐
             │ Suspended │        │ Rejected  │
             └───────────┘        └───────────┘
```

---

## سير عمل تسجيل الدخول (موظف الخدمة - siro_service)

### 📍 يبدأ من `login_controller.dart` ← `login()`

```
[LoginController]             [serviceapp/login.php]                [DB / Redis]
       |                              |                                  |
       |── قراءة البصمة من            |                                  |
       |   box.read(fingerprint)      |                                  |
       |                              |                                  |
       |── POST /serviceapp/login.php |                                  |
       |   payload: fingerprint,      |                                  |
       |   password, email,           |                                  |
       |   aud = "service"            |                                  |
       |────────────────────────────>|                                  |
       |                              |                                  |
       |                              |── Rate Limiting:                |
       |                              |   5 محاولات/دقيقة لكل IP       |
       |                              |                                  |
       |                              |── البحث بـ fingerprint_hash      |
       |                              |   في `users` WHERE user_type     |
       |                              |   = 'service'                    |
       |                              |                                  |
       |      [إذا لم يوجد, والإيميل موجود]                               |
       |                              |── البحث بالإيميل المشفر         |
       |                              |                                  |
       |                              |── التحقق من status:             |
       |                              |   • pending → "قيد المراجعة"    |
       |                              |   • suspended → "معلق"          |
       |                              |   • approved → متابعة           |
       |                              |                                  |
       |                              |── التحقق من كلمة المرور         |
       |                              |                                  |
       |                              |── فك تشفير البيانات للعرض:      |
       |                              |   first_name, last_name,        |
       |                              |   email, phone                  |
       |                              |                                  |
       |                              |── إدارة التوكنات:               |
       |                              |   1. البحث عن توكن موجود في     |
       |                              |      Redis (active_token)       |
       |                              |   2. إذا وجد وصالح ← استخدامه   |
       |                              |   3. إذا لم يوجد ← إلغاء القديم |
       |                              |      وتوليد جديد                |
       |                              |                                  |
       |                              |── توليد HMAC Key:               |
       |                              |   hmac = hash_hmac(sha256,      |
       |                              |   userId, SECRET_KEY_HMAC)      |
       |                              |                                  |
       |<── { message, data, jwt,     |                                  |
       |      hmac, expires_in }      |                                  |
       |                              |                                  |
       |── إرسال OTP:                 |                                  |
       |   POST /auth/otp/request.php |                                  |
       |   payload: receiver=phone,   |                                  |
       |   user_type='service'        |                                  |
       |                              |                                  |
       |── عرض Dialog OTP             |                                  |
       |                              |                                  |
       |── التحقق من OTP:             |                                  |
       |   POST /auth/otp/verify.php  |                                  |
       |   payload: phone_number,     |                                  |
       |   token_code, user_type      |                                  |
       |                              |                                  |
       |── حفظ JWT + HMAC محلياً      |                                  |
       |                              |                                  |
       |── Get.offAll(Main())         |                                  |
```

---

## سير عمل إضافة الموظفين من قبل المشرف العام

### 📍 `backend/Admin/Staff/add.php`

يستخدم هذا الملف لإضافة موظفين جدد من قبل المشرف العام (Super Admin أو Admin فقط).

```
                    ┌─────────────────────────────────────┐
                    │  add.php                            │
                    │                                     │
                    │  ✅ JWT Authentication:              │
                    │     $jwtService = new JwtService     │
                    │     $auth = $jwtService->authenticate│
                    │     $authRole = $auth->role          │
                    │     if role ≠ super_admin || admin → │
                    │         رفض الطلب                    │
                    └──────────────────┬──────────────────┘
                                       │
                         ──────────────┼──────────────
                     role='admin'      │      role='service'
                                       │
             ┌─────────────────────────┴──────────────────────────┐
             ▼                                                     ▼
     ┌────────────────┐                               ┌──────────────────┐
     │  adminUser     │                               │     users        │
     │  table         │                               │  table           │
     ├────────────────┤                               ├──────────────────┤
     │ id (bin2hex)   │                               │ id (bin2hex)     │
     │ fingerprint    │                               │ fingerprint      │
     │ fingerprint_   │                               │ fingerprint_hash │
     │ hash           │                               │ phone (مشفر)      │
     │ name (مشفر)    │                               │ email (مشفر)      │
     │ phone (مشفر)   │                               │ gender           │
     │ password       │                               │ password         │
     │ role 'admin'   │                               │ birthdate        │
     │ created_at     │                               │ user_type        │
     └────────────────┘                               │ 'service'         │
                                                      │ first_name (مشفر) │
                                                      │ last_name         │
                                                      │ site              │
                                                      │ created_at        │
                                                      └──────────────────┘
```

### 🔐 آلية التحقق في add.php (بعد الإصلاح):

```php
$jwtService = new JwtService($redis);
$auth = $jwtService->authenticate();    // يقرأ Bearer token من Authorization header
$authRole = $auth->role ?? '';          // يستخرج الدور من JWT payload
if ($authRole !== 'super_admin' && $authRole !== 'admin') {
    jsonError("غير مصرح لك. فقط المشرفون يمكنهم إضافة موظفين.");
    exit;
}
```

### نقاط مهمة في add.php:

- ✅ `bin2hex(random_bytes(16))` لتوليد UUID آمن
- ✅ البيانات الحساسة مشفرة قبل الحفظ
- ✅ `fingerprint` اختياري — يمكن إضافة موظف بدون بصمة مسبقة
- ✅ **التحقق من JWT Authentication** مطلوب قبل الإضافة

---

## سير عمل تفعيل الحسابات المعلقة

### 📍 `pending.php` → `activate.php`

#### استعراض الحسابات المعلقة:

```
[pending.php]                    [قاعدة البيانات]
      │                                │
      │── SELECT FROM adminUser        │
      │   WHERE status='pending'       │
      │                                │
      │── SELECT FROM users            │
      │   WHERE status='pending'       │
      │   AND user_type='service'      │
      │                                │
      │── فك تشفير الأسماء والأرقام    │
      │                                │
      │── دمج النتائج (array_merge)    │
      │                                │
      │<── { data: [all_pending] }     │
```

#### تفعيل حساب:

```
[activate.php]                   [قاعدة البيانات]
      │                                │
      │── التحقق من JWT:               │
      │   $jwtService = new JwtService  │
      │   $auth = $jwtService->authenticate│
      │   $authRole = $auth->role       │
      │   if ≠ super_admin && ≠ admin → │
      │       رفض                       │
      │                                │
      │── POST مع: user_id, type       │
      │                                │
      │   type='admin':                │
      │   UPDATE adminUser             │
      │   SET status='active'          │
      │   WHERE id=user_id             │
      │   AND status='pending'         │
      │                                │
      │   type='service':              │
      │   UPDATE users                 │
      │   SET status='approved'        │
      │   WHERE id=user_id             │
      │   AND status='pending'         │
      │   AND user_type='service'      │
      │                                │
      │<── "تم التفعيل بنجاح"          │
```

### 🔐 آلية التحقق في activate.php (بعد الإصلاح):

```php
$jwtService = new JwtService($redis);
$auth = $jwtService->authenticate();
$authRole = $auth->role ?? '';
if ($authRole !== 'super_admin' && $authRole !== 'admin') {
    jsonError("غير مصرح لك. فقط المشرف العام يمكنه تفعيل الحسابات.");
    exit;
}
```

---

## مقارنة بين تدفق siro_admin و siro_service

| الخاصية | siro_admin (المشرف) | siro_service (خدمة العملاء) |
|---------|---------------------|-----------------------------|
| **جدول البيانات** | `adminUser` | `users` |
| **مفتاح البحث** | بصمة الجهاز ← الهاتف | بصمة الجهاز ← الإيميل |
| **آلية OTP** | OTP عبر WhatsApp كخطوة قبل JWT | JWT يصدر أولاً ثم OTP كخطوة تأكيد |
| **Auto Login** | Yes (is_renewal=1) + JWT غير منتهي | Yes (كلمة مرور مخزنة) |
| **إلغاء التوكن القديم** | قبل إصدار الجديد (Redis) | قبل إصدار الجديد (Redis) |
| **عدد أرقام OTP** | 6 أرقام (مُحسَّن) | لا يوجد OTP مدمج بالـ login |
| **HMAC Key** | غير مستخدم | يستخدم للتوافق مع CRUD |
| **نوع التسجيل** | تسجيل ذاتي + قائمة بيضاء | إضافة يدوية أو تسجيل ذاتي |
| **الحالة عند الإنشاء** | `pending` | `pending` / `active` |

---

## الجوانب الأمنية (Security)

### ✅ نقاط القوة

1. **تشفير البيانات الحساسة** — جميع PII (الاسم، الهاتف، الإيميل، البصمة) مشفرة في قاعدة البيانات بواسطة `encryptData()`
2. **بصمة الجهاز (Fingerprint)** — ربط الحساب بجهاز معين يمنع الوصول من أجهزة غير معروفة
3. **إلغاء التوكن (Token Revocation)** — التوكن القديم يُلغى قبل إصدار الجديد عبر Redis
4. **OTP لمدة محدودة** — صلاحية 10 دقائق فقط للرمز
5. **استخدام لمرة واحدة** — OTP يُحذف بعد التحقق
6. **القائمة البيضاء** — التسجيل الذاتي مقيد بأرقام مصرح بها من `.env`
7. **Hash للبصمة** — `SHA-256` للبحث السريع دون تخزين البصمة كما هي
8. **قناع رقم الهاتف** — في الاستجابة، يظهر فقط `07XX***XXX`
9. **UUID آمن** — `bin2hex(random_bytes(16))` بدلاً من `rand()` (تم الإصلاح)
10. **JWT Authentication** — لملفي add.php و activate.php (تم الإصلاح)
11. **Rate Limiting** — على login و OTP (تم الإضافة)

### ✅ الإصلاحات الأمنية المُنفَّذة

| # | الثغرة | الملف | الحالة |
|---|--------|-------|--------|
| 1 | `rand()` لتوليد ID (ضعيف) | `Admin/auth/register.php` | ✅ تم الاستبدال بـ `bin2hex(random_bytes(16))` |
| 2 | التحقق من الصلاحيات معلق (Commented Out) | `Admin/Staff/add.php` | ✅ تم التفعيل عبر `JwtService::authenticate()` |
| 3 | لا يوجد تحقق من صلاحية المشرف العام | `Admin/Staff/activate.php` | ✅ تم إضافة JWT + التحقق من role |
| 4 | لا يوجد Rate Limiting على login | `Admin/auth/login.php` | ✅ تم الإضافة (5 محاولات/دقيقة) |
| 5 | لا يوجد Rate Limiting على login | `serviceapp/login.php` | ✅ تم الإضافة (5 محاولات/دقيقة) |
| 6 | لا يوجد Rate Limiting على OTP | `Admin/auth/verify_login.php` | ✅ تم الإضافة (3 محاولات/5 دقائق) |
| 7 | OTP 5 أرقام (ضعيف) | `Admin/auth/login.php` | ✅ تم الرفع إلى 6 أرقام (100000-999999) |

### ❌ الثغرات المتبقية (لم تُعالَج بعد)

| الثغرة | الموقع | التأثير |
|--------|--------|---------|
| **كلمات مرور plain text (قديمة)** | `Admin/jwtService.php` (السطر 49) | دعم كلمات المرور غير المشفرة للتوافق القديم |
| **JWT Service مكرر** | `Admin/jwtService.php` و `core/Auth/JwtService.php` | يوجد ملفان باسم JwtService بوظائف مختلفة |
| **Auto Login بدون OTP** | `Admin/auth/login.php` مع `is_renewal=1` | إذا سُرقت البصمة وكلمة المرور، يمكن الدخول بدون OTP |
| **كشف البصمة في الأخطاء** | `otp_helper.dart` | لا يوجد تدقيق كافٍ في التقاط الأخطاء |

---

## قائمة الإصلاحات الأمنية المُنفَّذة

### 1. ✅ `Admin/auth/register.php` — استبدال ID الضعيف

**قبل الإصلاح:**
```php
$uniqueId = rand(100000000, 999999999); // غير آمن، قد يتكرر
```

**بعد الإصلاح:**
```php
$uniqueId = bin2hex(random_bytes(16)); // UUID آمن (32 حرف hex عشوائي)
```

### 2. ✅ `Admin/Staff/add.php` — تفعيل التحقق من الصلاحيات

**قبل الإصلاح:**
```php
// التحقق معلق (Commented Out)
// $auth = JwtService::authenticate($redis);
// if ($auth['role'] !== 'super_admin' && $auth['role'] !== 'admin') { ... }
```

**بعد الإصلاح:**
```php
$jwtService = new JwtService($redis);
$auth = $jwtService->authenticate();
$authRole = $auth->role ?? '';
if ($authRole !== 'super_admin' && $authRole !== 'admin') {
    jsonError("غير مصرح لك. فقط المشرفون يمكنهم إضافة موظفين.");
    exit;
}
```

### 3. ✅ `Admin/Staff/activate.php` — إضافة JWT Authentication

**قبل الإصلاح:**
```php
// يجب التأكد من صلاحيات الـ Super Admin هنا
// (عادةً يتم التحقق من التوكن أو الـ Session)
```

**بعد الإصلاح:**
```php
$jwtService = new JwtService($redis);
$auth = $jwtService->authenticate();
$authRole = $auth->role ?? '';
if ($authRole !== 'super_admin' && $authRole !== 'admin') {
    jsonError("غير مصرح لك. فقط المشرف العام يمكنه تفعيل الحسابات.");
    exit;
}
```

### 4. ✅ `Admin/auth/login.php` — إضافة Rate Limiting + رفع OTP إلى 6 أرقام

```php
// Rate Limiting قبل بدء المعالجة
$rateLimiter = new RateLimiter($redis);
$rateLimiter->enforce(RateLimiter::identifier(), 'login');

// ... لاحقاً عند توليد OTP ...
$otp = rand(100000, 999999); // 6 أرقام بدلاً من 5
```

### 5. ✅ `serviceapp/login.php` — إضافة Rate Limiting

```php
$rateLimiter = new RateLimiter($redis);
$rateLimiter->enforce(RateLimiter::identifier(), 'login');
```

### 6. ✅ `Admin/auth/verify_login.php` — إضافة Rate Limiting لـ OTP

```php
$rateLimiter = new RateLimiter($redis);
$rateLimiter->enforce(RateLimiter::identifier(), 'otp'); // 3 محاولات/5 دقائق
```

---

## خلاصة

```mermaid
graph TD
    subgraph "siro_admin (تطبيق المشرف)"
        A[Login Page] --> B[OtpHelper.loginWithPassword]
        B --> C{is_renewal?}
        C -->|نعم| D[JWT مباشر]
        C -->|لا| E[طلب OTP - 6 أرقام]
        E --> F[Verify OTP - Rate Limited]
        F --> G[JWT نهائي]
    end

    subgraph "Backend PHP - مؤمَّن"
        H[Admin/auth/login.php] --> RL1[Rate Limiter ✅]
        RL1 --> I[بحث بالبصمة/هاتف]
        I --> J[فحص الحالة]
        J --> K[التحقق من كلمة المرور]
        K --> L[توليد OTP 6-digits ✅ / JWT]
        M[verify_login.php] --> RL2[Rate Limiter (OTP) ✅]
        RL2 --> N[التحقق من OTP]
        N --> O[إصدار JWT]
        P[add.php] --> AUTH1[JWT Authentication ✅]
        Q[activate.php] --> AUTH2[JWT Authentication ✅]
    end

    subgraph "siro_service (تطبيق الخدمة)"
        R[LoginController.login] --> S[serviceapp/login.php]
        S --> RL3[Rate Limiter ✅]
        RL3 --> T[JWT + HMAC]
        T --> U[OTP للتأكيد]
        U --> V[تسجيل دخول نهائي]
    end

    B --> H
    F --> M
    R --> S
```

النظام مبني على أساس أمني قوي مع تشفير متعدد الطبقات. تم إصلاح 7 ثغرات أمنية:

1. **UUID آمن** بدلاً من `rand()` في تسجيل المشرفين
2. **JWT Authentication** في add.php — يمنع أي شخص غير مصرح له من إضافة موظفين
3. **JWT Authentication** في activate.php — يضمن أن المشرف العام فقط هو من يمكنه التفعيل
4. **Rate Limiting** (5 محاولات/دقيقة) على login.php للمشرفين
5. **Rate Limiting** (5 محاولات/دقيقة) على login.php لخدمة العملاء
6. **Rate Limiting** (3 محاولات/5 دقائق) على verify_login.php (OTP)
7. **رفع OTP إلى 6 أرقام** لزيادة صعوبة التخمين

---

> **تاريخ التوثيق:** 12 يونيو 2026  
> **آخر تحديث:** 12 يونيو 2026 (تم تنفيذ الإصلاحات)  
> **الإصدار:** 2.0  
> **المراجعة القادمة:** —  
> **المعنيون:** فريق التطوير — Siro

</div>