Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .env.example +178 -0
- .github/ISSUE_TEMPLATE/bug_report.md +60 -0
- .github/ISSUE_TEMPLATE/feature_request.md +40 -0
- .github/ISSUE_TEMPLATE/security_report.md +63 -0
- .github/pull_request_template.md +68 -0
- .gitignore +307 -0
- CHANGELOG.md +199 -0
- CODE_OF_CONDUCT.md +265 -0
- CONTRIBUTING.md +183 -0
- CONTRIBUTING_NEW.md +18 -0
- LICENSE +51 -0
- MANIFEST.txt +34 -0
- Makefile +273 -0
- README.md +95 -0
- SECURITY.md +254 -0
- VIDEO_SCRIPT.md +175 -0
- assets/README.md +296 -0
- assets/architecture.svg +152 -0
- assets/banner.svg +95 -0
- assets/dashboard.svg +227 -0
- assets/discord-alert.svg +93 -0
- assets/icon-ai.svg +19 -0
- assets/icon-alerts.svg +12 -0
- assets/icon-realtime.svg +13 -0
- assets/icon-scan.svg +17 -0
- assets/logo.svg +88 -0
- assets/slack-alert.svg +90 -0
- assets/video-thumbnail.svg +98 -0
- dashboard/index.html +1696 -0
- dashboard/public/data/latest.json +435 -0
- development-report.md +265 -0
- diagrams/system-architecture.mmd +80 -0
- docker-compose.yml +234 -0
- docs/api/openapi.yaml +633 -0
- docs/configuration.md +430 -0
- google7cceda004d653872.html +1 -0
- graphics/data-analysis-icon.svg +130 -0
- graphics/monitoring-icon.svg +64 -0
- graphics/shield-icon.svg +92 -0
- index.html +1724 -0
- public/data/latest.json +435 -0
- requirements.txt +106 -0
- robots.txt +4 -0
- scripts/aggregate_results.py +414 -0
- scripts/backup.sh +344 -0
- scripts/generate_report.py +175 -0
- scripts/maintenance.sh +445 -0
- scripts/security_scanner.py +55 -0
- scripts/upgrade.sh +443 -0
- setup-guide.html +823 -0
.env.example
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# إعدادات بيئة نظام الحارس التلقائي
|
| 2 |
+
# Auto Guardian System Environment Configuration
|
| 3 |
+
# ==============================================
|
| 4 |
+
|
| 5 |
+
# IMPORTANT: هذا ملف نموذجي. انسخه إلى .env وأضف قيمك الفعلية.
|
| 6 |
+
# cp .env.example .env
|
| 7 |
+
|
| 8 |
+
# ===============================
|
| 9 |
+
# إعدادات الوضع العام
|
| 10 |
+
# ===============================
|
| 11 |
+
|
| 12 |
+
# وضع التشغيل: development, testing, production
|
| 13 |
+
mode: development
|
| 14 |
+
|
| 15 |
+
# مستوى التسجيل: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
| 16 |
+
log_level: INFO
|
| 17 |
+
|
| 18 |
+
# المنطقة الزمنية (استخدم تنسيق tzdata)
|
| 19 |
+
timezone: UTC
|
| 20 |
+
|
| 21 |
+
# ===============================
|
| 22 |
+
# إعدادات API والخادم
|
| 23 |
+
# ===============================
|
| 24 |
+
|
| 25 |
+
# عنوان واجهة برمجة التطبيقات
|
| 26 |
+
api_host: "0.0.0.0"
|
| 27 |
+
api_port: 8000
|
| 28 |
+
|
| 29 |
+
# مفتاح سري لتوقيع الرموز (تغييره في الإنتاج!)
|
| 30 |
+
secret_key: "your-super-secret-key-change-this-in-production"
|
| 31 |
+
|
| 32 |
+
# فترة انتهاء رمز JWT (بالساعات)
|
| 33 |
+
jwt_expiration_hours: 24
|
| 34 |
+
|
| 35 |
+
# تفعيل HTTPS في الإنتاج
|
| 36 |
+
use_https: false
|
| 37 |
+
|
| 38 |
+
# مسار ملف الشهادة (للإنتاج فقط)
|
| 39 |
+
ssl_cert: ""
|
| 40 |
+
ssl_key: ""
|
| 41 |
+
|
| 42 |
+
# ===============================
|
| 43 |
+
# إعدادات المراقبة
|
| 44 |
+
# ===============================
|
| 45 |
+
|
| 46 |
+
# تفعيل المراقبة
|
| 47 |
+
monitoring_enabled: true
|
| 48 |
+
|
| 49 |
+
# الفاصل الزمني للفحص (بالثواني)
|
| 50 |
+
scan_interval: 5
|
| 51 |
+
|
| 52 |
+
# مصادر السجلات للمراقبة (مفصولة بفواصل)
|
| 53 |
+
log_sources:
|
| 54 |
+
- /var/log/auth.log
|
| 55 |
+
- /var/log/syslog
|
| 56 |
+
|
| 57 |
+
# تفعيل الفحص العميق
|
| 58 |
+
deep_scan: false
|
| 59 |
+
|
| 60 |
+
# ===============================
|
| 61 |
+
# إعدادات الحظر
|
| 62 |
+
# ===============================
|
| 63 |
+
|
| 64 |
+
# تفعيل الحظر التلقائي
|
| 65 |
+
blocking_enabled: true
|
| 66 |
+
|
| 67 |
+
# عدد المحاولات قبل الحظر
|
| 68 |
+
block_threshold: 5
|
| 69 |
+
|
| 70 |
+
# الفترة الزمنية للمحاولات (بالثواني)
|
| 71 |
+
block_timewindow: 60
|
| 72 |
+
|
| 73 |
+
# تفعيل IPTables للحظر
|
| 74 |
+
use_iptables: true
|
| 75 |
+
|
| 76 |
+
# تفعيل الجدار الناري (firewalld)
|
| 77 |
+
use_firewalld: false
|
| 78 |
+
|
| 79 |
+
# قائمة العناوكات المسموح بها (لا تُحظر)
|
| 80 |
+
whitelist_ips: []
|
| 81 |
+
|
| 82 |
+
# قائمة العناوكات المحظورة دائماً
|
| 83 |
+
blacklist_ips: []
|
| 84 |
+
|
| 85 |
+
# ===============================
|
| 86 |
+
# إعدادات الإشعارات
|
| 87 |
+
# ===============================
|
| 88 |
+
|
| 89 |
+
# تفعيل الإشعارات
|
| 90 |
+
notifications_enabled: true
|
| 91 |
+
|
| 92 |
+
# ---- Slack ----
|
| 93 |
+
slack_enabled: false
|
| 94 |
+
slack_webhook_url: ""
|
| 95 |
+
slack_channel: "security-alerts"
|
| 96 |
+
slack_username: "Auto-Guardian"
|
| 97 |
+
slack_icon_emoji: ":shield:"
|
| 98 |
+
|
| 99 |
+
# ---- Discord ----
|
| 100 |
+
discord_enabled: false
|
| 101 |
+
discord_webhook_url: ""
|
| 102 |
+
discord_username: "Auto-Guardian"
|
| 103 |
+
|
| 104 |
+
# ---- البريد الإلكتروني ----
|
| 105 |
+
email_enabled: false
|
| 106 |
+
email_smtp_host: "smtp.gmail.com"
|
| 107 |
+
email_smtp_port: 587
|
| 108 |
+
email_use_tls: true
|
| 109 |
+
email_username: ""
|
| 110 |
+
email_password: ""
|
| 111 |
+
email_from: "noreply@autoguardian.local"
|
| 112 |
+
email_to: []
|
| 113 |
+
|
| 114 |
+
# ===============================
|
| 115 |
+
# إعدادات Prometheus
|
| 116 |
+
# ===============================
|
| 117 |
+
|
| 118 |
+
# تفعيل Prometheus
|
| 119 |
+
prometheus_enabled: true
|
| 120 |
+
|
| 121 |
+
# منفذ Prometheus
|
| 122 |
+
prometheus_port: 9090
|
| 123 |
+
|
| 124 |
+
# تفعيل مسار /metrics
|
| 125 |
+
prometheus_metrics_path: "/metrics"
|
| 126 |
+
|
| 127 |
+
# ===============================
|
| 128 |
+
# إعدادات التخزين
|
| 129 |
+
# ===============================
|
| 130 |
+
|
| 131 |
+
# مسار مجلد السجلات
|
| 132 |
+
log_path: "logs/"
|
| 133 |
+
|
| 134 |
+
# مسار مجلد البيانات
|
| 135 |
+
data_path: "data/"
|
| 136 |
+
|
| 137 |
+
# تفعيل قاعدة البيانات
|
| 138 |
+
database_enabled: false
|
| 139 |
+
database_url: "sqlite:///data/autoguardian.db"
|
| 140 |
+
|
| 141 |
+
# ===============================
|
| 142 |
+
# إعدادات الأمان
|
| 143 |
+
# ===============================
|
| 144 |
+
|
| 145 |
+
# تفعيل التحقق من التحديثات الأمنية
|
| 146 |
+
security_checks: true
|
| 147 |
+
|
| 148 |
+
# فترة التحقق من التحديثات (بالساعات)
|
| 149 |
+
security_check_interval: 24
|
| 150 |
+
|
| 151 |
+
# تفعيل تسجيل جميع الإجراءات
|
| 152 |
+
audit_logging: true
|
| 153 |
+
|
| 154 |
+
# مسار ملف سجل التدقيق
|
| 155 |
+
audit_log_path: "logs/audit.log"
|
| 156 |
+
|
| 157 |
+
# ===============================
|
| 158 |
+
# إعدادات Docker
|
| 159 |
+
# ===============================
|
| 160 |
+
|
| 161 |
+
# اسم الحاوية في Docker
|
| 162 |
+
docker_container_name: "auto-guardian-system"
|
| 163 |
+
|
| 164 |
+
# الشبكة في Docker
|
| 165 |
+
docker_network: "security-network"
|
| 166 |
+
|
| 167 |
+
# ===============================
|
| 168 |
+
# إعدادات خارجية (اختياري)
|
| 169 |
+
# ===============================
|
| 170 |
+
|
| 171 |
+
# Cloudflare API (لحظر العناوكات على الحافة)
|
| 172 |
+
cloudflare_enabled: false
|
| 173 |
+
cloudflare_api_token: ""
|
| 174 |
+
cloudflare_zone_id: ""
|
| 175 |
+
|
| 176 |
+
#바이러스 보호 API
|
| 177 |
+
virustotal_enabled: false
|
| 178 |
+
virustotal_api_key: ""
|
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: "\U0001F41B الإبلاغ عن خطأ"
|
| 3 |
+
about: الإبلاغ عن خطأ أو مشكلة في نظام الحارس التلقائي
|
| 4 |
+
title: "[BUG] "
|
| 5 |
+
labels: "bug"
|
| 6 |
+
assignees: ""
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## وصف المشكلة
|
| 10 |
+
|
| 11 |
+
[وصف واضح ومختصر للمشكلة. ما الذي حدث؟ ما كان يجب أن يحدث؟]
|
| 12 |
+
|
| 13 |
+
## خطوات إعادة الإنتاج
|
| 14 |
+
|
| 15 |
+
يرجى تقديم خطوات واضحة ومحددة لإعادة إنتاج المشكلة:
|
| 16 |
+
|
| 17 |
+
1. [الخطوة الأولى]
|
| 18 |
+
2. [الخطوة الثانية]
|
| 19 |
+
3. [الخطوة الثالثة]
|
| 20 |
+
...
|
| 21 |
+
|
| 22 |
+
## السلوك المتوقع
|
| 23 |
+
|
| 24 |
+
[وصف لما كنت تتوقع أن يحدث]
|
| 25 |
+
|
| 26 |
+
## السلوك الفعلي
|
| 27 |
+
|
| 28 |
+
[وصف لما حدث فعلاً]
|
| 29 |
+
|
| 30 |
+
## بيئة التشغيل
|
| 31 |
+
|
| 32 |
+
يرجى تحديد بيئتك:
|
| 33 |
+
|
| 34 |
+
- **نظام التشغيل:** [مثل: Ubuntu 20.04 LTS / Debian 11 / CentOS 8]
|
| 35 |
+
- **إصدار Python:** [مثل: Python 3.9.0]
|
| 36 |
+
- **إصدار النظام:** [مثل: v1.2.0]
|
| 37 |
+
- **طريقة التثبيت:** [Docker / PIP / Git]
|
| 38 |
+
- **إعدادات مخصصة:** [إن وُجدت]
|
| 39 |
+
|
| 40 |
+
## لقطات الشاشة أو السجلات
|
| 41 |
+
|
| 42 |
+
[إذا كانت هناك لقطات شاشة أو سجلات ذات صلة، يرجى إرفاقها هنا]
|
| 43 |
+
|
| 44 |
+
```
|
| 45 |
+
[أضف السجلات هنا إن كانت مفيدة]
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
## معلومات إضافية
|
| 49 |
+
|
| 50 |
+
[أي معلومات إضافية قد تكون مفيدة لتشخيص المشكلة، مثل:]
|
| 51 |
+
- الأوامر التي استخدمتها
|
| 52 |
+
- التغييرات الأخيرة التي أجريتها
|
| 53 |
+
- معلومات أخرى ذات صلة
|
| 54 |
+
|
| 55 |
+
---
|
| 56 |
+
|
| 57 |
+
**قبل إرسال التقرير:**
|
| 58 |
+
- [ ] تأكد من أن المشكلة لم تُبلَّغ من قبل (ابحث في Issues الموجودة)
|
| 59 |
+
- [ ] جرب تحديث النظام إلى أحدث إصدار
|
| 60 |
+
- [ ] راجع التوثيق للتأكد من أنك تستخدم النظام بشكل صحيح
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: "\U0001F4A1 طلب ميزة"
|
| 3 |
+
about: اقتراح ميزة جديدة أو تحسين لنظام الحارس التلقائي
|
| 4 |
+
title: "[FEATURE] "
|
| 5 |
+
labels: "enhancement"
|
| 6 |
+
assignees: ""
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## وصف الميزة المقترحة
|
| 10 |
+
|
| 11 |
+
[وصف واضح ومختصر للميزة التي تقترحها. ما الذي يجب أن يفعله النظام؟]
|
| 12 |
+
|
| 13 |
+
## المشكلة التي تحلها هذه الميزة
|
| 14 |
+
|
| 15 |
+
[كيف ستساعد هذه الميزة المستخدمين؟ ما هي المشكلة التي تحلها؟]
|
| 16 |
+
|
| 17 |
+
## الحل المقترح
|
| 18 |
+
|
| 19 |
+
[وصف لكيفية تنفيذ الميزة المقترحة إن أمكن. يمكنك إضافة:]
|
| 20 |
+
- واجهة المستخدم المقترحة
|
| 21 |
+
- التغييرات التقنية المطلوبة
|
| 22 |
+
- أي API endpoints جديدة إن وُجدت
|
| 23 |
+
|
| 24 |
+
## البدائل المدروسة
|
| 25 |
+
|
| 26 |
+
[هل فكرت في طرق بديلة لتنفيذ هذه الميزة؟ ما هي إيجابيات وسلبيات كل طريقة؟]
|
| 27 |
+
|
| 28 |
+
## معلومات إضافية
|
| 29 |
+
|
| 30 |
+
[أي موارد، أمثلة، أو مراجع ذات صلة:]
|
| 31 |
+
- المشاريع المماثلة التي تحتوي على هذه الميزة
|
| 32 |
+
- وثائق ذات صلة
|
| 33 |
+
- أي أفكار أخرى
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
**قبل إرسال طلب الميزة:**
|
| 38 |
+
- [ ] تأكد من أن الميزة لم تُطلب من قبل (ابحث في Issues الموجودة)
|
| 39 |
+
- [ ] فكر فيما إذا كانت الميزة تتوافق مع أهداف المشروع
|
| 40 |
+
- [ ] كن مستعداً لمناقشة التفاصيل والمقايضات
|
.github/ISSUE_TEMPLATE/security_report.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: "\U0001F512 الإبلاغ عن ثغرة أمنية"
|
| 3 |
+
about: الإبلاغ عن ثغرة أمنية أو مشكلة أمان في نظام الحارس التلقائي
|
| 4 |
+
title: "[SECURITY] "
|
| 5 |
+
labels: "security"
|
| 6 |
+
assignees: ""
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## وصف الثغرة
|
| 10 |
+
|
| 11 |
+
[وصف واضح ومختصر للثغرة الأمنية المكتشفة. لا تكشف التفاصيل التقنية الكاملة هنا.]
|
| 12 |
+
|
| 13 |
+
## نوع الثغرة
|
| 14 |
+
|
| 15 |
+
[حدد نوع الثغرة:]
|
| 16 |
+
- [ ] تنفيذ كود عن بُعد (RCE)
|
| 17 |
+
- [ ] رفع امتيازات
|
| 18 |
+
- [ ] تجاوز المصادقة
|
| 19 |
+
- [ ] حقن SQL
|
| 20 |
+
- [ ] Cross-Site Scripting (XSS)
|
| 21 |
+
- [ ] حقن أوامر
|
| 22 |
+
- [ ] كشف معلومات حساسة
|
| 23 |
+
- [ ] أخرى: __________
|
| 24 |
+
|
| 25 |
+
## مستوى الخطورة
|
| 26 |
+
|
| 27 |
+
[تقديرك لمستوى خطورة الثغرة:]
|
| 28 |
+
- [ ] حرجة - يمكن استغلالها بسهولة ولها تأثير كبير
|
| 29 |
+
- [ ] عالية - يمكن استغلالها ولها تأثير كبير
|
| 30 |
+
- [ ] متوسطة - يصعب استغلالها أو لها تأثير محدود
|
| 31 |
+
- [ ] منخفضة - يصعب استغلالها ولها تأثير محدود جداً
|
| 32 |
+
|
| 33 |
+
## خطوات إعادة الإنتاج
|
| 34 |
+
|
| 35 |
+
1. [الخطوة الأولى]
|
| 36 |
+
2. [الخطوة الثانية]
|
| 37 |
+
3. [...]
|
| 38 |
+
|
| 39 |
+
(لا تكشف تفاصيل الاستغلال الكاملة هنا)
|
| 40 |
+
|
| 41 |
+
## التأثير المحتمل
|
| 42 |
+
|
| 43 |
+
[ما هو التأثير المحتمل لهذه الثغرة؟]
|
| 44 |
+
|
| 45 |
+
## معلومات إضافية
|
| 46 |
+
|
| 47 |
+
[أي معلومات إضافية قد تكون مفيدة:]
|
| 48 |
+
- بيئة الاختبار
|
| 49 |
+
- أدوات المستخدم
|
| 50 |
+
- إصدارات البرامج ذات الصلة
|
| 51 |
+
|
| 52 |
+
---
|
| 53 |
+
|
| 54 |
+
## للاتصال المباشر
|
| 55 |
+
|
| 56 |
+
للإبلاغ عن الثغرات بشكل خاص، يرجى الاتصال مباشرة:
|
| 57 |
+
|
| 58 |
+
- **البريد الإلكتروني:** security@autoguardian.local
|
| 59 |
+
- **مستوى الاستجابة:** نعد بالرد خلال 48 ساعة
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
**ملاحظة:** نتبع مبدأ الإبلاغ المسؤول. لن نتخذ أي إجراء قانوني ضد الباحثين الأمنيين الذين يبلغون عن الثغرات بشكل مسؤول وفقاً لسياسة الأمن الخاصة بنا.
|
.github/pull_request_template.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## وصف التغييرات
|
| 2 |
+
|
| 3 |
+
[وصف موجز وواضح لما يفعله طلب الدمج هذا. ما هي التغييرات التي أجريتها؟]
|
| 4 |
+
|
| 5 |
+
## نوع التغيير
|
| 6 |
+
|
| 7 |
+
- [ ] **إصلاح خطأ (Bug Fix)** - إصلاح مشكلة في الكود الموجود
|
| 8 |
+
- [ ] **ميزة جديدة (New Feature)** - إضافة وظيفة جديدة
|
| 9 |
+
- [ ] **تحسين (Enhancement)** - تحسين أو توسيع ميزة موجودة
|
| 10 |
+
- [ ] **تغيير في التوثيق (Documentation)** - تغييرات في التوثيق فقط
|
| 11 |
+
- [ ] **إعادة هيكلة (Refactoring)** - تغيير في بنية الكود دون تغيير الوظيفة
|
| 12 |
+
- [ ] **اختبارات (Tests)** - إضافة أو تعديل اختبارات
|
| 13 |
+
- [ ] **بناء (Build)** - تغييرات في أدوات البناء أو التكوين
|
| 14 |
+
- [ ] **أخرى:** ____________
|
| 15 |
+
|
| 16 |
+
## التحقق من الصحة
|
| 17 |
+
|
| 18 |
+
قبل إرسال طلب الدمج، يرجى التأكد من:
|
| 19 |
+
|
| 20 |
+
- [ ] **الاختبارات:** اجتازت جميع الاختبارات الموجودة (`pytest` يمر بنجاح)
|
| 21 |
+
- [ ] **الاختبارات الجديدة:** أضفت اختبارات للوظائف الجديدة (إن وُجدت)
|
| 22 |
+
- [ ] **جودة الكود:** التزمت بمعايير كتابة الكود (`black`, `flake8`, `isort`)
|
| 23 |
+
- [ ] **التوثيق:** حدّثت التوثيق إذا قمت بتغيير واجهة برمجة التطبيقات
|
| 24 |
+
- [ ] **التعارضات:** لا توجد تعارضات مع الفرع الرئيسي
|
| 25 |
+
- [ ] **الفحص:** اجتاز فحص GitHub Actions بنجاح
|
| 26 |
+
|
| 27 |
+
## الحالات المُختبرة
|
| 28 |
+
|
| 29 |
+
[اشرح الحالات التي اختبرتها يدوياً:]
|
| 30 |
+
- [ ] الحالة الأولى: [...]
|
| 31 |
+
- [ ] الحالة الثانية: [...]
|
| 32 |
+
- [ ] ...
|
| 33 |
+
|
| 34 |
+
## لقطات الشاشة
|
| 35 |
+
|
| 36 |
+
[إذا كانت التغييرات مرئية (واجهة مستخدم، رسومات، إلخ)، أضف لقطات شاشة توضح قبل وبعد:]
|
| 37 |
+
|
| 38 |
+
## قائمة المهام المنجزة
|
| 39 |
+
|
| 40 |
+
- [ ] المهمة الأولى المنجزة
|
| 41 |
+
- [ ] المهمة الثانية المنجزة
|
| 42 |
+
- [ ] ...
|
| 43 |
+
|
| 44 |
+
## المراجع ذات الصلة
|
| 45 |
+
|
| 46 |
+
[أي مراجع ذات صلة:]
|
| 47 |
+
- Issues ذات صلة: #123, #456
|
| 48 |
+
- Pull Requests ذات صلة: #789
|
| 49 |
+
- وثائق ذات صلة: [...]
|
| 50 |
+
- مناقشات: [...]
|
| 51 |
+
|
| 52 |
+
## معلومات إضافية
|
| 53 |
+
|
| 54 |
+
[أي معلومات إضافية قد تكون مفيدة للمراجعين:]
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## للتواصل
|
| 59 |
+
|
| 60 |
+
- **البريد الإلكتروني:** [بريدك الإلكتروني]
|
| 61 |
+
- **GitHub:** [@اسم_المستخدم]
|
| 62 |
+
|
| 63 |
+
---
|
| 64 |
+
|
| 65 |
+
**قبل إرسال طلب الدمج:**
|
| 66 |
+
- [ ] تأكد من أن عنوان الطلب واضح ومختصر
|
| 67 |
+
- [ ] راجع طلب الدمج للتأكد من أنه يحتوي على جميع المعلومات اللازمة
|
| 68 |
+
- [ ] تأكد من أن الكود يتبع معايير المشروع
|
.gitignore
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# إعدادات استبعاد Git
|
| 2 |
+
# Git Ignore Configuration for Auto Guardian System
|
| 3 |
+
# ==================================================
|
| 4 |
+
|
| 5 |
+
# ===============================
|
| 6 |
+
# Python
|
| 7 |
+
# ===============================
|
| 8 |
+
|
| 9 |
+
# Byte-compiled / optimized / DLL files
|
| 10 |
+
__pycache__/
|
| 11 |
+
*.py[cod]
|
| 12 |
+
*$py.class
|
| 13 |
+
*.so
|
| 14 |
+
.Python
|
| 15 |
+
build/
|
| 16 |
+
develop-eggs/
|
| 17 |
+
dist/
|
| 18 |
+
downloads/
|
| 19 |
+
eggs/
|
| 20 |
+
.eggs/
|
| 21 |
+
lib/
|
| 22 |
+
lib64/
|
| 23 |
+
parts/
|
| 24 |
+
sdist/
|
| 25 |
+
var/
|
| 26 |
+
wheels/
|
| 27 |
+
pip-wheel-metadata/
|
| 28 |
+
share/python-wheels/
|
| 29 |
+
*.egg-info/
|
| 30 |
+
.installed.cfg
|
| 31 |
+
*.egg
|
| 32 |
+
MANIFEST
|
| 33 |
+
|
| 34 |
+
# Virtual Environments
|
| 35 |
+
venv/
|
| 36 |
+
ENV/
|
| 37 |
+
env/
|
| 38 |
+
.venv/
|
| 39 |
+
env.bak/
|
| 40 |
+
venv.bak/
|
| 41 |
+
|
| 42 |
+
# PyInstaller
|
| 43 |
+
*.manifest
|
| 44 |
+
*.spec
|
| 45 |
+
|
| 46 |
+
# Installer logs
|
| 47 |
+
pip-log.txt
|
| 48 |
+
pip-delete-this-directory.txt
|
| 49 |
+
|
| 50 |
+
# Unit test / coverage reports
|
| 51 |
+
htmlcov/
|
| 52 |
+
.tox/
|
| 53 |
+
.nox/
|
| 54 |
+
.coverage
|
| 55 |
+
.coverage.*
|
| 56 |
+
.cache
|
| 57 |
+
*.cover
|
| 58 |
+
*.py,cover
|
| 59 |
+
.hypothesis/
|
| 60 |
+
.pytest_cache/
|
| 61 |
+
coveragereport/
|
| 62 |
+
|
| 63 |
+
# Translations
|
| 64 |
+
*.mo
|
| 65 |
+
*.pot
|
| 66 |
+
|
| 67 |
+
# Django stuff:
|
| 68 |
+
*.log
|
| 69 |
+
local_settings.py
|
| 70 |
+
db.sqlite3
|
| 71 |
+
db.sqlite3-journal
|
| 72 |
+
|
| 73 |
+
# Flask stuff:
|
| 74 |
+
instance/
|
| 75 |
+
.webassets-cache
|
| 76 |
+
|
| 77 |
+
# Scrapy stuff:
|
| 78 |
+
.scrapy
|
| 79 |
+
|
| 80 |
+
# Sphinx documentation
|
| 81 |
+
docs/_build/
|
| 82 |
+
|
| 83 |
+
# PyBuilder
|
| 84 |
+
target/
|
| 85 |
+
|
| 86 |
+
# Jupyter Notebook
|
| 87 |
+
.ipynb_checkpoints
|
| 88 |
+
|
| 89 |
+
# IPython
|
| 90 |
+
profile_default/
|
| 91 |
+
ipython_config.py
|
| 92 |
+
|
| 93 |
+
# pyenv
|
| 94 |
+
.python-version
|
| 95 |
+
|
| 96 |
+
# pipenv
|
| 97 |
+
Pipfile.lock
|
| 98 |
+
|
| 99 |
+
# poetry
|
| 100 |
+
poetry.lock
|
| 101 |
+
|
| 102 |
+
# PEP 582
|
| 103 |
+
__pypackages__/
|
| 104 |
+
|
| 105 |
+
# Celery stuff
|
| 106 |
+
celerybeat-schedule
|
| 107 |
+
celerybeat.pid
|
| 108 |
+
|
| 109 |
+
# SageMath parsed files
|
| 110 |
+
*.sage.py
|
| 111 |
+
|
| 112 |
+
# Environments
|
| 113 |
+
.env
|
| 114 |
+
.env.local
|
| 115 |
+
.env.*.local
|
| 116 |
+
.venv
|
| 117 |
+
env/
|
| 118 |
+
venv/
|
| 119 |
+
ENV/
|
| 120 |
+
env.bak/
|
| 121 |
+
venv.bak/
|
| 122 |
+
|
| 123 |
+
# Spyder project settings
|
| 124 |
+
.spyderproject
|
| 125 |
+
.spyproject
|
| 126 |
+
|
| 127 |
+
# Rope project settings
|
| 128 |
+
.ropeproject
|
| 129 |
+
|
| 130 |
+
# mkdocs documentation
|
| 131 |
+
/site
|
| 132 |
+
|
| 133 |
+
# mypy
|
| 134 |
+
.mypy_cache/
|
| 135 |
+
.dmypy.json
|
| 136 |
+
dmypy.json
|
| 137 |
+
|
| 138 |
+
# Pyre type checker
|
| 139 |
+
.pyre/
|
| 140 |
+
|
| 141 |
+
# ===============================
|
| 142 |
+
# IDEs and Editors
|
| 143 |
+
# ===============================
|
| 144 |
+
|
| 145 |
+
# VS Code
|
| 146 |
+
.vscode/
|
| 147 |
+
!.vscode/settings.json
|
| 148 |
+
!.vscode/tasks.json
|
| 149 |
+
!.vscode/launch.json
|
| 150 |
+
!.vscode/extensions.json
|
| 151 |
+
|
| 152 |
+
# JetBrains
|
| 153 |
+
.idea/
|
| 154 |
+
*.swp
|
| 155 |
+
*.swo
|
| 156 |
+
*~
|
| 157 |
+
.DS_Store
|
| 158 |
+
Thumbs.db
|
| 159 |
+
|
| 160 |
+
# Vim
|
| 161 |
+
[._]*.s[a-w][a-z]
|
| 162 |
+
[._]swa
|
| 163 |
+
*.un~
|
| 164 |
+
|
| 165 |
+
# Emacs
|
| 166 |
+
*~
|
| 167 |
+
\#*\#
|
| 168 |
+
/.emacs.desktop
|
| 169 |
+
/.emacs.desktop.lock
|
| 170 |
+
*.elc
|
| 171 |
+
auto-save-list
|
| 172 |
+
tramp
|
| 173 |
+
.\#*
|
| 174 |
+
|
| 175 |
+
# ===============================
|
| 176 |
+
# OS Files
|
| 177 |
+
# ===============================
|
| 178 |
+
|
| 179 |
+
# macOS
|
| 180 |
+
.DS_Store
|
| 181 |
+
.DS_Store?
|
| 182 |
+
._*
|
| 183 |
+
.Spotlight-V100
|
| 184 |
+
.Trashes
|
| 185 |
+
ehthumbs.db
|
| 186 |
+
Thumbs.db
|
| 187 |
+
|
| 188 |
+
# Linux
|
| 189 |
+
.nfs*
|
| 190 |
+
*~
|
| 191 |
+
|
| 192 |
+
# Windows
|
| 193 |
+
Thumbs.db:encryptable
|
| 194 |
+
ehthumbs.db
|
| 195 |
+
*.lnk
|
| 196 |
+
|
| 197 |
+
# ===============================
|
| 198 |
+
# Logs and Data
|
| 199 |
+
# ===============================
|
| 200 |
+
|
| 201 |
+
*.log
|
| 202 |
+
logs/
|
| 203 |
+
*.log.*
|
| 204 |
+
*.sqlite3
|
| 205 |
+
*.db
|
| 206 |
+
*.sqlite3-journal
|
| 207 |
+
|
| 208 |
+
# Session data
|
| 209 |
+
*.session.vim
|
| 210 |
+
|
| 211 |
+
# Temporary files
|
| 212 |
+
*.tmp
|
| 213 |
+
*.bak
|
| 214 |
+
*.backup
|
| 215 |
+
*~
|
| 216 |
+
\#*\#
|
| 217 |
+
._*
|
| 218 |
+
|
| 219 |
+
# Backup files
|
| 220 |
+
*.bak
|
| 221 |
+
*.backup
|
| 222 |
+
*~
|
| 223 |
+
.*.swp
|
| 224 |
+
*.swo
|
| 225 |
+
|
| 226 |
+
# ===============================
|
| 227 |
+
# Security
|
| 228 |
+
# ===============================
|
| 229 |
+
|
| 230 |
+
*.pem
|
| 231 |
+
*.key
|
| 232 |
+
*.crt
|
| 233 |
+
*.pub
|
| 234 |
+
!public.pem
|
| 235 |
+
|
| 236 |
+
# SSH
|
| 237 |
+
~/.ssh/id_rsa
|
| 238 |
+
~/.ssh/id_rsa.pub
|
| 239 |
+
~/.ssh/known_hosts
|
| 240 |
+
|
| 241 |
+
# GPG
|
| 242 |
+
~/.gnupg/
|
| 243 |
+
|
| 244 |
+
# Secrets
|
| 245 |
+
secrets.json
|
| 246 |
+
credentials.json
|
| 247 |
+
token.json
|
| 248 |
+
|
| 249 |
+
# ===============================
|
| 250 |
+
# Testing
|
| 251 |
+
# ===============================
|
| 252 |
+
|
| 253 |
+
.pytest_cache/
|
| 254 |
+
.hypothesis/
|
| 255 |
+
.coverage.*
|
| 256 |
+
htmlcov/
|
| 257 |
+
|
| 258 |
+
# Test data
|
| 259 |
+
tests/data/*
|
| 260 |
+
!tests/data/.gitkeep
|
| 261 |
+
|
| 262 |
+
# ===============================
|
| 263 |
+
# Build
|
| 264 |
+
# ===============================
|
| 265 |
+
|
| 266 |
+
build/
|
| 267 |
+
dist/
|
| 268 |
+
*.egg-info/
|
| 269 |
+
*.whl
|
| 270 |
+
*.pyz
|
| 271 |
+
*.tar.gz
|
| 272 |
+
|
| 273 |
+
# Docker
|
| 274 |
+
.docker/
|
| 275 |
+
|
| 276 |
+
# ===============================
|
| 277 |
+
# Documentation
|
| 278 |
+
# ===============================
|
| 279 |
+
|
| 280 |
+
docs/_build/
|
| 281 |
+
docs/.doctrees/
|
| 282 |
+
|
| 283 |
+
# Translation
|
| 284 |
+
locale/
|
| 285 |
+
|
| 286 |
+
# ===============================
|
| 287 |
+
# Temporary
|
| 288 |
+
# ===============================
|
| 289 |
+
|
| 290 |
+
.temp/
|
| 291 |
+
tmp/
|
| 292 |
+
temp/
|
| 293 |
+
*.temp
|
| 294 |
+
*.tmp
|
| 295 |
+
|
| 296 |
+
# Cache
|
| 297 |
+
.cache/
|
| 298 |
+
.ruff_cache/
|
| 299 |
+
.mypy_cache/
|
| 300 |
+
.pytest_cache/
|
| 301 |
+
|
| 302 |
+
# ===============================
|
| 303 |
+
# Third-party
|
| 304 |
+
# ===============================
|
| 305 |
+
|
| 306 |
+
node_modules/
|
| 307 |
+
bower_components/
|
CHANGELOG.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# سجل التغييرات
|
| 2 |
+
|
| 3 |
+
<div align="center">
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+
**نظام ذكي لحماية الخوادم من التهديدات الإلكترونية**
|
| 8 |
+
|
| 9 |
+
</div>
|
| 10 |
+
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
## مقدمة
|
| 14 |
+
|
| 15 |
+
ملف سجل التغييرات هذا يوثق جميع الإصدارات والتحديثات الرئيسية لنظام الحارس التلقائي. يُرجى قراءة هذا الملف بانتظام للاطلاع على جديد المشروع والتحسينات المضافة.
|
| 16 |
+
|
| 17 |
+
نتبع تنسيق [Keep a Changelog](https://keepachangelog.com/) الموصى به لمشاريع مفتوحة المصدر.
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## جدول المحتويات
|
| 22 |
+
|
| 23 |
+
- [الإصدار 1.3.0 - التطوير النشط](#الإصدار-130---التطوير-النشط)
|
| 24 |
+
- [الإصدار 1.2.0 - تكامل المنصات](#الإصدار-120---تكامل-المنصات)
|
| 25 |
+
- [الإصدار 1.1.0 - تحسين الأداء](#الإصدار-110---تحسين-الأداء)
|
| 26 |
+
- [الإصدار 1.0.0 - الإطلاق الأولي](#الإصدار-100---الإطلاق-الأولي)
|
| 27 |
+
- [غير مُصدر](#غير-مُصدر)
|
| 28 |
+
|
| 29 |
+
---
|
| 30 |
+
|
| 31 |
+
## الإصدار 1.3.0 - التطوير النشط
|
| 32 |
+
|
| 33 |
+
**تاريخ الإصدار:** قيد التطوير
|
| 34 |
+
|
| 35 |
+
### المضاف
|
| 36 |
+
|
| 37 |
+
- دعم Docker Compose للنشر السريع
|
| 38 |
+
- إضافة ملف Makefile لتسهيل مهام التطوير
|
| 39 |
+
- دعم تنسيق CodeQL للفحص الأمني المتقدم
|
| 40 |
+
- إضافة ملف .editorconfig للتنسيق المتسق
|
| 41 |
+
- دعم اللغة الإنجليزية (i18n)
|
| 42 |
+
- إضافة نظام المقاييس Prometheus
|
| 43 |
+
- لوحة مراقبة تفاعلية للمراحل الأربع
|
| 44 |
+
- أمثلة عملية لحالات الاستخدام المختلفة
|
| 45 |
+
|
| 46 |
+
### المُحسّن
|
| 47 |
+
|
| 48 |
+
- تحديث التوثيق الشامل مع رسومات توضيحية
|
| 49 |
+
- تحسين هيكل ملف README.md
|
| 50 |
+
- إضافة قسم المساهمة المجتمعية
|
| 51 |
+
- إضافة خارطة طريق مستقبلية
|
| 52 |
+
- تحسين أمثلة الكود والتوثيق التقني
|
| 53 |
+
|
| 54 |
+
### المُصحح
|
| 55 |
+
|
| 56 |
+
- إصلاح مشكلة عرض المخططات على الشاشات الصغيرة
|
| 57 |
+
- تحسين التوافق مع GitHub Pages
|
| 58 |
+
|
| 59 |
+
### الأمان
|
| 60 |
+
|
| 61 |
+
- إضافة ملف SECURITY.md لسياسة الإبلاغ عن الثغرات
|
| 62 |
+
- تحديث مدونة السلوك
|
| 63 |
+
|
| 64 |
+
---
|
| 65 |
+
|
| 66 |
+
## الإصدار 1.2.0 - تكامل المنصات
|
| 67 |
+
|
| 68 |
+
**تاريخ الإصدار:** 2024-10-15
|
| 69 |
+
|
| 70 |
+
### المضاف
|
| 71 |
+
|
| 72 |
+
- دعم إشعارات Slack المتكامل
|
| 73 |
+
- دعم إشعارات Discord عبر Webhooks
|
| 74 |
+
- نظام تنبيهات متعدد المنصات
|
| 75 |
+
- قابلية تخصيص محتوى الإشعارات
|
| 76 |
+
- دعم الرموز التعبيرية في الإشعارات
|
| 77 |
+
|
| 78 |
+
### المُحسّن
|
| 79 |
+
|
| 80 |
+
- تحسين سرعة إرسال الإشعارات بنسبة 60%
|
| 81 |
+
- إضافة قوالب رسائل جاهزة
|
| 82 |
+
- تحسين معالجة الأخطاء في نظام الإشعارات
|
| 83 |
+
- إضافة خيارات التخصيص المتقدمة
|
| 84 |
+
|
| 85 |
+
### المُصحح
|
| 86 |
+
|
| 87 |
+
- إصلاح مشكلة الاتصال بـ Slack Webhooks
|
| 88 |
+
- حل مشكلة تأخر إشعارات Discord
|
| 89 |
+
- إصلاح مشكلة الأحرف العربية في الإشعارات
|
| 90 |
+
|
| 91 |
+
---
|
| 92 |
+
|
| 93 |
+
## الإصدار 1.1.0 - تحسين الأداء
|
| 94 |
+
|
| 95 |
+
**تاريخ الإصدار:** 2024-09-28
|
| 96 |
+
|
| 97 |
+
### المضاف
|
| 98 |
+
|
| 99 |
+
- وضع الفحص المُحسّن لاستخدام أقل للذاكرة
|
| 100 |
+
- دعم التخزين المؤقت للنتائج
|
| 101 |
+
- وضع التشغيل الليلي لتوفير الموارد
|
| 102 |
+
- نظام التقارير الدورية الآلي
|
| 103 |
+
|
| 104 |
+
### المُحسّن
|
| 105 |
+
|
| 106 |
+
- تحسين استهلاك الذاكرة بنسبة 40%
|
| 107 |
+
- تسريع عملية الفحص بنسبة 35%
|
| 108 |
+
- تحسين دقة اكتشاف التهديدات
|
| 109 |
+
- تقليل الإيجابيات الكاذبة بنسبة 25%
|
| 110 |
+
|
| 111 |
+
### المُصحح
|
| 112 |
+
|
| 113 |
+
- إصلاح تسرب الذاكرة في وضع التشغيل الطويل
|
| 114 |
+
- حل مشكلة التحديث في الوقت الفعلي
|
| 115 |
+
- إصلاح مشكلة قراءة السجلات المشفرة
|
| 116 |
+
|
| 117 |
+
---
|
| 118 |
+
|
| 119 |
+
## الإصدار 1.0.0 - الإطلاق الأولي
|
| 120 |
+
|
| 121 |
+
**تاريخ الإصدار:** 2024-09-01
|
| 122 |
+
|
| 123 |
+
### المضاف
|
| 124 |
+
|
| 125 |
+
- نظام المراقبة اللحظية للسجلات
|
| 126 |
+
- محلل أنماط التهديدات المتقدم
|
| 127 |
+
- التكامل مع IPTables للحظر التلقائي
|
| 128 |
+
- دعم بروتوكول SSH لمراقبة الاختراقات
|
| 129 |
+
- دعم اكتشاف المسح الضوئي للمنافذ
|
| 130 |
+
- نظام تنبيهات عبر Webhooks
|
| 131 |
+
- واجهة سطر أوامر سهلة الاستخدام
|
| 132 |
+
- ملف README.md التوثيقي
|
| 133 |
+
- رخصة MIT مفتوحة المصدر
|
| 134 |
+
|
| 135 |
+
### المميزات الرئيسية
|
| 136 |
+
|
| 137 |
+
- ✅ مراقبة 24/7 لسجلات النظام
|
| 138 |
+
- ✅ كشف تلقائي للتهديدات
|
| 139 |
+
- ✅ حظر فوري للعناوات المشبوهة
|
| 140 |
+
- ✅ إشعارات فورية عبر Slack/Discord
|
| 141 |
+
- ✅ دعم متعدد للغات البرمجة
|
| 142 |
+
- ✅ بوابة جودة للكود
|
| 143 |
+
|
| 144 |
+
### التقنيات المدعومة
|
| 145 |
+
|
| 146 |
+
| اللغة | الأدوات المدعومة |
|
| 147 |
+
|-------|------------------|
|
| 148 |
+
| Python | Flake8, Pylint, Black |
|
| 149 |
+
| JavaScript/TypeScript | ESLint, Prettier |
|
| 150 |
+
| YAML | Custom parser |
|
| 151 |
+
| Java | Checkstyle (قريباً) |
|
| 152 |
+
| Go | golint (قريباً) |
|
| 153 |
+
| Rust | clippy (قريباً) |
|
| 154 |
+
|
| 155 |
+
---
|
| 156 |
+
|
| 157 |
+
## غير مُصدر
|
| 158 |
+
|
| 159 |
+
### قيد التطوير
|
| 160 |
+
|
| 161 |
+
- [ ] دعم إشعارات البريد الإلكتروني (SMTP)
|
| 162 |
+
- [ ] لوحة ويب لإدارة العناورات المحظورة
|
| 163 |
+
- [ ] دعم Docker للنشر السريع
|
| 164 |
+
- [ ] إدارة قائمة السماح (Whitelist)
|
| 165 |
+
- [ ] تكامل مع Cloudflare
|
| 166 |
+
- [ ] تقارير أمان دورية
|
| 167 |
+
- [ ] وضع التعلم الآلي للتهديدات الجديدة
|
| 168 |
+
- [ ] واجهة REST API
|
| 169 |
+
- [ ] دعم IPv6 الكامل
|
| 170 |
+
- [ ] اختبارات أداء متقدمة
|
| 171 |
+
|
| 172 |
+
---
|
| 173 |
+
|
| 174 |
+
## كيفية المساهمة
|
| 175 |
+
|
| 176 |
+
إذا كنت تريد المساهمة في تطوير المشروع، يمكنك:
|
| 177 |
+
|
| 178 |
+
1. استنساخ المستودر وإنشاء فرع جديد
|
| 179 |
+
2. إضافة ميزات أو إصلاح أخطاء
|
| 180 |
+
3. تحديث هذا الملف بالشكل المناسب
|
| 181 |
+
4. إرسال طلب دمج للمراجعة
|
| 182 |
+
|
| 183 |
+
راجع ملف [CONTRIBUTING.md](CONTRIBUTING.md) للمزيد من التفاصيل.
|
| 184 |
+
|
| 185 |
+
---
|
| 186 |
+
|
| 187 |
+
## إخلاء المسؤولية
|
| 188 |
+
|
| 189 |
+
نظام الحارس التلقائي يُقدم "كما هو" دون أي ضمانات. المستخدم مسؤول عن اختبار النظام في بيئة آمنة قبل نشره على الإنتاج.
|
| 190 |
+
|
| 191 |
+
---
|
| 192 |
+
|
| 193 |
+
<div align="center">
|
| 194 |
+
|
| 195 |
+
**صُنع بـ ❤️ بواسطة عبد الإله عثمان غويث**
|
| 196 |
+
|
| 197 |
+
*آخر تحديث: 2024-10-13*
|
| 198 |
+
|
| 199 |
+
</div>
|
CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# مدونة سلوك المجتمع
|
| 2 |
+
|
| 3 |
+
<div align="center">
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+
**نظام ذكي لحماية الخوادم من التهديدات الإلكترونية**
|
| 8 |
+
|
| 9 |
+
</div>
|
| 10 |
+
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
## مقدمة
|
| 14 |
+
|
| 15 |
+
نرحب بجميع الأفراد الذين يشاركون في مجتمعات نظام الحارس التلقائي سواء كانوا مطورين أو مستخدمين أو مساهمين أو زواراً. ملتزمون بتوفير بيئة مرحبية وآمنة للجميع، بغض النظر عن العمر أو الهوية أو الخبرة.
|
| 16 |
+
|
| 17 |
+
هذا المستند يوضح توقعاتنا السلوكية والآداب التي يجب على جميع المشاركين الالتزام بها. إذا لم توافق على هذه المدونة، نأسف لإبلاغك بأنك لا تستطيع المشاركة في مجتمعاتنا.
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## قيمنا
|
| 22 |
+
|
| 23 |
+
نؤمن بأن مجتمعاً متنوعاً ومتشملاً يُنتج برمجيات أفضل وأكثر أماناً. نلتزم بقيم الاحترام المتبادل والتعاون البنّاء والتعلم المستمر والتطوير المفتوح. نرحب بوجهات النظر المختلفة ونعتبرها ثروة حقيقية تُثري المشروع وتُحسّنه.
|
| 24 |
+
|
| 25 |
+
نهدف لخلق بيئة يشعر فيها الجميع بالأمان للمساهمة والإبداع والتعلم. نشجع على طرح الأسئلة والمشاركة في النقاشات وتقديم الآراء المختلفة حتى لو كانت مخالفة للرأي السائد. الاحترام لا يعني الموافقة، بل يعني التعامل بلباقة مع الاختلافات.
|
| 26 |
+
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
## معايير السلوك
|
| 30 |
+
|
| 31 |
+
### السلوك المتوقع
|
| 32 |
+
|
| 33 |
+
نشجع ونُقدّر السلوكيات التالية من جميع المشاركين:
|
| 34 |
+
|
| 35 |
+
**الاحترام واللطف:**
|
| 36 |
+
|
| 37 |
+
التعامل مع الآخرين بلطف واحترام في جميع التفاعلات. استخدام لغة welcome ومرحبة في النقاشات. الاعتراف بجهل الآخرين وتوجيههم بلطف دون السخرية أو الازدراء. الرد على الأسئلة والأسئلة الجديدة بصبر وود.
|
| 38 |
+
|
| 39 |
+
**الانفتاح والتشمل:**
|
| 40 |
+
|
| 41 |
+
الانفتاح على الأفكار والآراء الجديدة المختلفة عن أفكارك. الترحيب بالمساهمين الجدد ومساعدتهم على البدء. تقديم النقد بشكل بناء ومفيد. الاعتراف بجهود الآخرين وتقديرها.
|
| 42 |
+
|
| 43 |
+
**المسؤولية والمصداقية:**
|
| 44 |
+
|
| 45 |
+
الالتزام بالوعود والالتزامات المتفق عليها. الاعتراف بالأخطاء وتعلم منها. طلب المساعدة عند الحاجة دون خجل. مشاركة المعرفة مع الآخرين بشكل سخي.
|
| 46 |
+
|
| 47 |
+
**التركيز على الهدف:**
|
| 48 |
+
|
| 49 |
+
الانتباه للموضوع الأساسي في النقاشات. تقديم معلومات دقيقة ومفيدة. البقاء هادئاً في حالات الاختلاف. السعي للحلول بدلاً من إلقاء اللوم.
|
| 50 |
+
|
| 51 |
+
### السلوك غير المقبول
|
| 52 |
+
|
| 53 |
+
السلوكيات التالية غير مقبولة في مجتمعاتنا:
|
| 54 |
+
|
| 55 |
+
**التحرش والتمييز:**
|
| 56 |
+
|
| 57 |
+
التحرش يشمل التعليقات اللفظية أو المكتوبة المتعلقة بالجنس أو التوجه الجنسي أو الهوية أو الإعاقة أو المظهر الجسدي أو العرق أو الدين. التمييز على أي أساس مرفوض تماماً. لا مكان للتحرش أو التمييز في مجتمعنا.
|
| 58 |
+
|
| 59 |
+
**الهجمات الشخصية والشتم:**
|
| 60 |
+
|
| 61 |
+
الهجمات الشخصية والشتائم لا مكان لها في نقاشاتنا. لا يجوز إهانة الآخرين أو السخرية منهم أو مضايقتهم. النقد يجب أن يكون لل الأفكار لا للأشخاص. تجنب استخدام لغة عدوانية أو هجومية.
|
| 62 |
+
|
| 63 |
+
**الإعلانات غير المرغوبة:**
|
| 64 |
+
|
| 65 |
+
نشر محتوى غير مرغوب فيه مثل الإعلانات أو المواد التجارية أو رسائل السبام غير مسموح به. لا يجوز نشر روابط لمواقع خبيثة أو محتوى غير أخلاقي. الترويج للمنتجات يجب أن يكون في القنوات المخصصة.
|
| 66 |
+
|
| 67 |
+
**انتهاك الخصوصية:**
|
| 68 |
+
|
| 69 |
+
نشر معلومات شخصية للآخرين دون إذنهم غير مسموح. مشاركة بيانات حساسة أو أسرار. تصوير أو تسجيل المحادثات بدون موافقة.
|
| 70 |
+
|
| 71 |
+
---
|
| 72 |
+
|
| 73 |
+
## المسؤوليات
|
| 74 |
+
|
| 75 |
+
### مسؤوليات المشرفين
|
| 76 |
+
|
| 77 |
+
المشرفين على القنوات والمسودات مسؤولون عن:
|
| 78 |
+
|
| 79 |
+
**تطبيق المدونة:**
|
| 80 |
+
|
| 81 |
+
تطبيق هذه المدونة بشكل عادل ومتسق على جميع ال��شاركين. اتخاذ إجراءات فورية عند الإبلاغ عن سلوك غير مقبول. الحفاظ على سجلات للإجراءات المتخذة.
|
| 82 |
+
|
| 83 |
+
**الدعم والإرشاد:**
|
| 84 |
+
|
| 85 |
+
توجيه المشاركين الجدد حول قواعد المجتمع. تقديم الدعم للمتضررين من السلوك غير المقبول. الإجابة على الأسئلة وتوضيح الغموض.
|
| 86 |
+
|
| 87 |
+
**اتخاذ القرارات:**
|
| 88 |
+
|
| 89 |
+
تقييم البلاغات واتخاذ قرارات مناسبة. استشارة الفريق الأكبر في الحالات المعقدة. البقاء موضوعيين وتجنب التحيز.
|
| 90 |
+
|
| 91 |
+
### مسؤوليات المشاركين
|
| 92 |
+
|
| 93 |
+
جميع المشاركين مسؤولون عن:
|
| 94 |
+
|
| 95 |
+
- الالتزام بهذه المدونة في جميع التفاعلات
|
| 96 |
+
- الإبلاغ عن السلوك غير المقبول عند witnessed
|
| 97 |
+
- التعاون مع المشرفين في التحقيقات
|
| 98 |
+
- احترام قرارات المشرفين
|
| 99 |
+
|
| 100 |
+
---
|
| 101 |
+
|
| 102 |
+
## نطاق التطبيق
|
| 103 |
+
|
| 104 |
+
هذه المدونة تنطبق على جميع مساحات المشروع:
|
| 105 |
+
|
| 106 |
+
**مساحات GitHub:**
|
| 107 |
+
|
| 108 |
+
- جميع المستودرات والـ Issues و Pull Requests
|
| 109 |
+
- التعليقات على الـ Issues و PRs
|
| 110 |
+
- النقاشات (Discussions)
|
| 111 |
+
- Wiki
|
| 112 |
+
|
| 113 |
+
**قنوات التواصل:**
|
| 114 |
+
|
| 115 |
+
- منتديات النقاش والمحادثات
|
| 116 |
+
- البريد الإلكتروني المتعلق بالمشروع
|
| 117 |
+
- قنوات Discord أو Slack المخصصة
|
| 118 |
+
- وسائل التواصل الاجتماعي
|
| 119 |
+
|
| 120 |
+
**الفعاليات:**
|
| 121 |
+
|
| 122 |
+
- المؤتمرات واللقاءات المادية
|
| 123 |
+
- ورش العمل والدورات
|
| 124 |
+
- الفعاليات الافتراضية
|
| 125 |
+
|
| 126 |
+
**التمثيل:**
|
| 127 |
+
|
| 128 |
+
حتى خارج المساحات الرسمية، إذا كان الشخص يمثل المشروع، يتوقع منه الالتزام بهذه المدونة.
|
| 129 |
+
|
| 130 |
+
---
|
| 131 |
+
|
| 132 |
+
## الإبلاغ عن المخالفات
|
| 133 |
+
|
| 134 |
+
### كيفية الإبلاغ
|
| 135 |
+
|
| 136 |
+
إذا witnessت أو experienced سلوكاً لا يتوافق مع هذه المدونة، يُرجى الإبلاغ عنه فوراً:
|
| 137 |
+
|
| 138 |
+
**الخيار 1: الإبلاغ للمشرف مباشرة**
|
| 139 |
+
|
| 140 |
+
إذا كنت في قناة تواصل، تواصل مع أحد المشرفين مباشرة عبر رسالة خاصة. المشرفون يظهرون بأدوار أو علامات مميزة في القنوات.
|
| 141 |
+
|
| 142 |
+
**الخيار 2: فتح Issue**
|
| 143 |
+
|
| 144 |
+
في GitHub، يمكنك فتح Issue جديد في مستودع المشروع مع وضع علامة "Kind: community-health" لوصف الموقف.
|
| 145 |
+
|
| 146 |
+
**الخيار 3: البريد الإلكتروني**
|
| 147 |
+
|
| 148 |
+
إرسال بريد إلكتروني لمشرف المشروع على:
|
| 149 |
+
|
| 150 |
+
```
|
| 151 |
+
support@autoguardian.local
|
| 152 |
+
```
|
| 153 |
+
|
| 154 |
+
### ماذا يجب أن يتضمن البلاغ
|
| 155 |
+
|
| 156 |
+
للمساعدة في التحقيق السريع، يُفضل أن يتضمن البلاغ:
|
| 157 |
+
|
| 158 |
+
- وصف واضح للسلوك المخالف
|
| 159 |
+
- السياق الذي حدث فيه السلوك (الرابط، القناة، التاريخ)
|
| 160 |
+
- الهوية أو أسماء الأشخاص المعنيين
|
| 161 |
+
- أي أدلة متاحة (لقطات شاشة، سجلات)
|
| 162 |
+
- معلومات الاتصال الخاصة بك (اختياري)
|
| 163 |
+
|
| 164 |
+
### السرية والخصوصية
|
| 165 |
+
|
| 166 |
+
نأخذ البلاغات بجدية تامة. جميع البلاغات ستُعامل بسرية تامة. لن نكشف هوية المُبلّغ لأي شخص خارج فريق التحقيق. الانتقام من المُبلّغين ممنوع تماماً وسيُعتبر انتهاكاً منفصلاً لهذه المدونة.
|
| 167 |
+
|
| 168 |
+
---
|
| 169 |
+
|
| 170 |
+
## إجراءات التطبيق
|
| 171 |
+
|
| 172 |
+
### المستوى الأول: التنبيه
|
| 173 |
+
|
| 174 |
+
عند ملاحظة سلوك غير مقبول لأول مرة:
|
| 175 |
+
|
| 176 |
+
- مشرف يتواصل مع الشخص بشكل خاص
|
| 177 |
+
- توضيح المخالفة بلباقة
|
| 178 |
+
- طلب التوقف عن السلوك
|
| 179 |
+
- تسجيل الحادثة
|
| 180 |
+
|
| 181 |
+
### المستوى الثاني: التحذير
|
| 182 |
+
|
| 183 |
+
إذا استمر السلوك أو كان أكثر خطورة:
|
| 184 |
+
|
| 185 |
+
- تحذير رسمي مكتوب
|
| 186 |
+
- تعليق مؤقت من المشاركة
|
| 187 |
+
- فترة مراجعة (عادةً أسبوع)
|
| 188 |
+
- توثيق كامل للحادثة
|
| 189 |
+
|
| 190 |
+
### المستوى الثالث: الحظر
|
| 191 |
+
|
| 192 |
+
في حالات السلوك الشديد الخطورة أو المتكرر:
|
| 193 |
+
|
| 194 |
+
- حظر دائم من جميع قنوات المشروع
|
| 195 |
+
- رفض Pull Requests و Issues
|
| 196 |
+
- إبلاغ المؤسسات ذات الصلة إذا لزم الأمر
|
| 197 |
+
- نشر ملخص الحادثة (بدون أسماء) إذا كان ذلك مفيداً للسلامة
|
| 198 |
+
|
| 199 |
+
---
|
| 200 |
+
|
| 201 |
+
## الاستثناءات
|
| 202 |
+
|
| 203 |
+
هناك استثناءات محدودة لهذه المدونة:
|
| 204 |
+
|
| 205 |
+
**الاستثناء الأول: التوازن**
|
| 206 |
+
|
| 207 |
+
قد نتجنب اتخاذ إجراءات ضد سلوك يحمي التوازن في المناقشات، مثل نقد مشروع أو منتج بشكل مشروع أو الإشارة إلى أخطاء فعلية في عمل شخص ما.
|
| 208 |
+
|
| 209 |
+
**الاست��ناء الثاني: الخصوصية**
|
| 210 |
+
|
| 211 |
+
نحترم خصوصية الأفراد، لذا قد نتجنب بعض الإجراءات إذا كانت ستُعرّض شخصاً للخطر.
|
| 212 |
+
|
| 213 |
+
**الاستثناء الثالث: التوظيف**
|
| 214 |
+
|
| 215 |
+
نوفر مساحة للتوظيف والنقاشات المهنية المتعلقة بالأمن السيبراني، حتى لو تضمنت محتوى تقنياً عن الاختراقات.
|
| 216 |
+
|
| 217 |
+
---
|
| 218 |
+
|
| 219 |
+
## الاعتراف والتحضير
|
| 220 |
+
|
| 221 |
+
هذه المدونة مستوحاة من:
|
| 222 |
+
|
| 223 |
+
- [Contributor Covenant](https://www.contributor-covenant.org/) الإصدار 2.1
|
| 224 |
+
- [Django Code of Conduct](https://www.djangoproject.com/conduct/)
|
| 225 |
+
- [Python Community Code of Conduct](https://www.python.org/community/conduct/)
|
| 226 |
+
- [Ubuntu Code of Conduct](https://ubuntu.com/community/ethos/code-of-conduct)
|
| 227 |
+
|
| 228 |
+
---
|
| 229 |
+
|
| 230 |
+
## الأسئلة الشائعة
|
| 231 |
+
|
| 232 |
+
**س: ماذا لو اعتقدت أن الحظر غير عادل؟**
|
| 233 |
+
|
| 234 |
+
ج: يمكنك طلب مراجعة القرار من خلال إرسال بريد إلكتروني للفريق التنفيذي. سنراجع القرار ونرد خلال 7 أيام عمل.
|
| 235 |
+
|
| 236 |
+
**س: هل يمكنني البقاء مجهولاً عند الإبلاغ؟**
|
| 237 |
+
|
| 238 |
+
ج: نعم، يمكنك تقديم بلاغ مجهول الهوية. ومع ذلك، قد تحد من قدرتنا على التواصل معك للمتابعة.
|
| 239 |
+
|
| 240 |
+
**س: ماذا لو كنت ضحية تحرش من مشرف؟**
|
| 241 |
+
|
| 242 |
+
ج: يمكنك الإبلاغ مباشرة عبر البريد الإلكتروني للفريق التنفيذي. سنضمن مراجعة مستقلة من مشرفين آخرين.
|
| 243 |
+
|
| 244 |
+
**س: هل تنطبق هذه المدونة على التوظيف؟**
|
| 245 |
+
|
| 246 |
+
ج: نعم، تنطبق على جميع جوانب المشاركة في المشروع بما في ذلك فرص العمل.
|
| 247 |
+
|
| 248 |
+
---
|
| 249 |
+
|
| 250 |
+
## التواصل
|
| 251 |
+
|
| 252 |
+
للأسئلة حول هذه المدونة:
|
| 253 |
+
|
| 254 |
+
- **البريد الإلكتروني:** support@autoguardian.local
|
| 255 |
+
- **GitHub:** [Open an Issue](https://github.com/AbdulElahOthmanGwaith/auto-guardian-system/issues/new)
|
| 256 |
+
|
| 257 |
+
---
|
| 258 |
+
|
| 259 |
+
<div align="center">
|
| 260 |
+
|
| 261 |
+
**شكراً لالتزامك بخلق مجتمع welcome وآمن! 🌟**
|
| 262 |
+
|
| 263 |
+
*صُنع بـ ❤️ بواسطة عبد الإله عثمان غويث*
|
| 264 |
+
|
| 265 |
+
</div>
|
CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# دليل المساهمة في نظام Auto-Guardian
|
| 2 |
+
|
| 3 |
+
شكرًا لاهتمامك بالمساهمة في تطوير نظام Auto-Guardian! نرحب بجميع المساهمات التي تساعد في تحسين هذا المشروع مفتوح المصدر.
|
| 4 |
+
|
| 5 |
+
## فهرس المحتوى
|
| 6 |
+
|
| 7 |
+
1. [كيفية المساهمة](#كيفية-المساهمة)
|
| 8 |
+
2. [إعداد بيئة التطوير](#إعداد-بيئة-التطوير)
|
| 9 |
+
3. [قواعد كتابة الكود](#قواعد-كتابة-الكود)
|
| 10 |
+
4. [عملية تقديم Pull Request](#عملية-تقديم-pull-request)
|
| 11 |
+
5. [إرشادات الأمان](#إرشادات-الأمان)
|
| 12 |
+
6. [التواصل والدعم](#التواصل-والدعم)
|
| 13 |
+
|
| 14 |
+
## كيفية المساهمة
|
| 15 |
+
|
| 16 |
+
هناك عدة طرق للمساهمة في تطوير النظام:
|
| 17 |
+
|
| 18 |
+
- **الإبلاغ عن الأخطاء**: إذا وجدت خطأ في النظام، يُرجى فتح Issue جديدة مع وصف مفصل للمشكلة وكيفية إعادة إنتاجها.
|
| 19 |
+
- **اقتراح الميزات**: نرحب باقتراحاتك لتحسين النظام. يُرجى فتح Issue جديدة في قسم Feature Requests.
|
| 20 |
+
- **تحسين الوثائق**: إذا وجدت أي أخطاء في الوثائق أو أردت تحسينها، يُرجى تقديم مساهمتك.
|
| 21 |
+
- **كتابة الكود**: يمكنك حل أي Issue مفتوح وتقديم Pull Request.
|
| 22 |
+
- **مراجعة الكود**: ساعد في مراجعة Pull Requests الأخرى وتقديم ملاحظات بنّاءة.
|
| 23 |
+
|
| 24 |
+
## إعداد بيئة التطوير
|
| 25 |
+
|
| 26 |
+
### المتطلبات الأساسية
|
| 27 |
+
|
| 28 |
+
قبل البدء، تأكد من تثبيت المتطلبات التالية:
|
| 29 |
+
|
| 30 |
+
```
|
| 31 |
+
Python >= 3.11
|
| 32 |
+
Node.js >= 20
|
| 33 |
+
Go >= 1.21
|
| 34 |
+
Rust (أحدث إصدار ثابت)
|
| 35 |
+
Git
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
### خطوات الإعداد
|
| 39 |
+
|
| 40 |
+
1. **استنساخ المستودع**:
|
| 41 |
+
|
| 42 |
+
```bash
|
| 43 |
+
git clone https://github.com/yourusername/auto-guardian.git
|
| 44 |
+
cd auto-guardian
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
2. **تثبيت تبعيات Python**:
|
| 48 |
+
|
| 49 |
+
```bash
|
| 50 |
+
pip install -r requirements.txt
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
3. **تثبيت تبعيات Node.js**:
|
| 54 |
+
|
| 55 |
+
```bash
|
| 56 |
+
npm install
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
4. **تشغيل الفحوصات محليًا**:
|
| 60 |
+
|
| 61 |
+
```bash
|
| 62 |
+
# فحص Python
|
| 63 |
+
bandit -r scripts/
|
| 64 |
+
pylint scripts/
|
| 65 |
+
|
| 66 |
+
# فحص JavaScript
|
| 67 |
+
npx eslint .
|
| 68 |
+
|
| 69 |
+
# فحص Go
|
| 70 |
+
gosec ./...
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
## قواعد كتابة الكود
|
| 74 |
+
|
| 75 |
+
### معايير كود Python
|
| 76 |
+
|
| 77 |
+
- اتبع أسلوب PEP 8 لكتابة الكود.
|
| 78 |
+
- استخدم أسماء متغيرات واضحة ومعبرة.
|
| 79 |
+
- أضف docstrings لجميع الدوال والكلاسات.
|
| 80 |
+
- استخدم type hints حيثما أمكن.
|
| 81 |
+
- احتفظ بطول السطر أقل من 120 حرفًا.
|
| 82 |
+
|
| 83 |
+
### معايير كود JavaScript/TypeScript
|
| 84 |
+
|
| 85 |
+
- اتبع معايير ESLint المعرفة في `.eslintrc.json`.
|
| 86 |
+
- استخدم `const` و `let` بدلاً من `var`.
|
| 87 |
+
- استخدم arrow functions حيثما أمكن.
|
| 88 |
+
- أضف أنواع TypeScript لجميع الدوال والمتغيرات.
|
| 89 |
+
|
| 90 |
+
### معايير كود Go
|
| 91 |
+
|
| 92 |
+
- اتبع معايير Go الرسمية.
|
| 93 |
+
- استخدم `gofmt` لتنسيق الكود.
|
| 94 |
+
- أضف توثيق لجميع الدوال العامة.
|
| 95 |
+
- استخدم go vet للفحص.
|
| 96 |
+
|
| 97 |
+
### معايير كود Rust
|
| 98 |
+
|
| 99 |
+
- اتبع معايير Rust الرسمية.
|
| 100 |
+
- استخدم `cargo fmt` لتنسيق الكود.
|
| 101 |
+
- أضف توثيق للدوال العامة.
|
| 102 |
+
- تحقق من السلامة مع `cargo clippy`.
|
| 103 |
+
|
| 104 |
+
## عملية تقديم Pull Request
|
| 105 |
+
|
| 106 |
+
### الخطوة 1: إنشاء Fork
|
| 107 |
+
|
| 108 |
+
انتقل إلى صفحة المستودع على GitHub وأنشئ Fork الخاص بك.
|
| 109 |
+
|
| 110 |
+
### الخطوة 2: إنشاء فرع جديد
|
| 111 |
+
|
| 112 |
+
```bash
|
| 113 |
+
git checkout -b feature/your-feature-name
|
| 114 |
+
```
|
| 115 |
+
|
| 116 |
+
### الخطوة 3: إجراء التغييرات
|
| 117 |
+
|
| 118 |
+
قم بإجراء التغييرات المطلوبة على الكود أو الوثائق.
|
| 119 |
+
|
| 120 |
+
### الخطوة 4: اختبار التغييرات
|
| 121 |
+
|
| 122 |
+
```bash
|
| 123 |
+
# تشغيل جميع الفحوصات
|
| 124 |
+
python -m pytest
|
| 125 |
+
npm test
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
### الخطوة 5: إنشاء Commit
|
| 129 |
+
|
| 130 |
+
```bash
|
| 131 |
+
git add .
|
| 132 |
+
git commit -m "إضافة: وصف موجز للتغييرات"
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
### الخطوة 6: رفع الفرع
|
| 136 |
+
|
| 137 |
+
```bash
|
| 138 |
+
git push origin feature/your-feature-name
|
| 139 |
+
```
|
| 140 |
+
|
| 141 |
+
### الخطوة 7: إنشاء Pull Request
|
| 142 |
+
|
| 143 |
+
انتقل إلى صفحة GitHub وأنشئ Pull Request جديدًا. تأكد من:
|
| 144 |
+
|
| 145 |
+
- وصف التغييرات بشكل واضح.
|
| 146 |
+
- ربط أي Issue ذي صلة.
|
| 147 |
+
- إرفاق لقطات شاشة إذا كانت التغييرات مرئية.
|
| 148 |
+
- اجتياز جميع الفحوصات الآلية.
|
| 149 |
+
|
| 150 |
+
## إرشادات الأمان
|
| 151 |
+
|
| 152 |
+
### الإبلاغ عن الثغرات الأمنية
|
| 153 |
+
|
| 154 |
+
إذا اكتشفت ثغرة أمنية في النظام، يُرجى عدم فتح Issue علني. بدلاً من ذلك:
|
| 155 |
+
|
| 156 |
+
1. أرسل بريدًا إلكترونيًا إلى: security@example.com
|
| 157 |
+
2. وصف الثغرة بتفصيل.
|
| 158 |
+
3. أخبرنا إذا كنت تريد أن يتم الإشارة إليك في شكر المساهمين.
|
| 159 |
+
|
| 160 |
+
### أفضل الممارسات الأمنية
|
| 161 |
+
|
| 162 |
+
- لا تقم أبدًا بتنفيذ كود غير موثوق.
|
| 163 |
+
- تحقق من جميع المدخلات قبل معالجتها.
|
| 164 |
+
- استخدم HTTPS للاتصالات الآمنة.
|
| 165 |
+
- لا تخزن بيانات حساسة في الكود.
|
| 166 |
+
|
| 167 |
+
## التواصل والدعم
|
| 168 |
+
|
| 169 |
+
### الحصول على المساعدة
|
| 170 |
+
|
| 171 |
+
- **الأسئلة الشائعة**: راجع قسم FAQ في الوثائق.
|
| 172 |
+
- **المجتمع**: انضم إلى Discord server الخاص بالمشروع.
|
| 173 |
+
- **الدعم**: افتح Issue مع تصنيف "question".
|
| 174 |
+
|
| 175 |
+
### ساعات العمل
|
| 176 |
+
|
| 177 |
+
نحاول الرد على جميع الاستفسارات خلال 48 ساعة عمل.
|
| 178 |
+
|
| 179 |
+
---
|
| 180 |
+
|
| 181 |
+
## شكر خاص
|
| 182 |
+
|
| 183 |
+
نشكر جميع المساهمين الذين ساعدوا في تطوير هذا المشروع! 🙏
|
CONTRIBUTING_NEW.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# المساهمة في Auto-Guardian | Contributing to Auto-Guardian
|
| 2 |
+
|
| 3 |
+
نحن نرحب بمساهماتكم! إليكم كيف يمكنك البدء:
|
| 4 |
+
|
| 5 |
+
## 🚀 كيف تساهم؟
|
| 6 |
+
1. قم بعمل **Fork** للمستودع.
|
| 7 |
+
2. أنشئ فرعاً جديداً لميزتك (`git checkout -b feature/AmazingFeature`).
|
| 8 |
+
3. قم بعمل **Commit** لتغييراتك (`git commit -m 'Add some AmazingFeature'`).
|
| 9 |
+
4. قم بعمل **Push** للفرع (`git push origin feature/AmazingFeature`).
|
| 10 |
+
5. افتح **Pull Request**.
|
| 11 |
+
|
| 12 |
+
## 🛡️ معايير الكود
|
| 13 |
+
- تأكد من أن الكود يتبع معايير PEP8 بالنسبة لـ Python.
|
| 14 |
+
- قم بتحديث التوثيق إذا قمت بإضافة ميزات جديدة.
|
| 15 |
+
- تأكد من تشغيل الفحص الأمني قبل الإرسال.
|
| 16 |
+
|
| 17 |
+
## 📧 التواصل
|
| 18 |
+
إذا كان لديك أي استفسار، يمكنك فتح Issue في المستودع.
|
LICENSE
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ترخيص MIT للنظام الآلي للحارس
|
| 2 |
+
|
| 3 |
+
## حقوق النشر (c) 2024 Auto-Guardian Team
|
| 4 |
+
|
| 5 |
+
يُمنح هنا إذنًا مجانيًا لأي شخص يحصل على نسخة من هذا البرنامج والوثائق ذات الصلة ("البرنامج") للتعامل في البرنامج دون قيود، بما في ذلك دون حصر حقوق استخدام ونسخ وتعديل ودمج ونشر وتوزيع وترخيص من الباطن وبيع نسخ من البرنامج، والأشخاص الذين يُسمح لهم بالبرنامج مُلزمون بالقيام بذلك بشرط استيفاء الشروط التالية:
|
| 6 |
+
|
| 7 |
+
يجب تضمين إشعار حقوق النشر أعلاه وإشعار الإذن هذا في جميع النسخ أو الأجزاء الجوهرية من البرنامج.
|
| 8 |
+
|
| 9 |
+
**البرنامج يُقدم "كما هو" دون أي ضمانات صريحة أو ضمنية، بما في ذلك على سبيل المثال لا الحصر ضمانات القابلية للتسويق والملاءمة لغرض معين. في أي حال من الأحوال لا يكون المؤلفون أو أصحاب حقوق النشر مسؤولين عن أي مطالبات أو أضرار أو مسؤوليات أخرى، سواء كانت في عقد أو مسؤولية تقصيرية أو غير ذلك، تنشأ عن أو تتعلق بالبرنامج أو استخدامه أو التعاملات الأخرى فيه.**
|
| 10 |
+
|
| 11 |
+
##_permissions المطلوب للتشغيل:
|
| 12 |
+
|
| 13 |
+
يطلب هذا البرنامج الإذونات التالية للعمل بشكل صحيح:
|
| 14 |
+
|
| 15 |
+
```
|
| 16 |
+
permissions:
|
| 17 |
+
contents: read # قراءة محتوى المستودع
|
| 18 |
+
pages: write # نشر صفحات الويب
|
| 19 |
+
id-token: write # المصادقة على GitHub Actions
|
| 20 |
+
issues: write # إنشاء التقارير
|
| 21 |
+
pull-requests: write # التعليق على طلبات السحب
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
## المتطلبات الأساسية:
|
| 25 |
+
|
| 26 |
+
- Python 3.11 أو أحدث
|
| 27 |
+
- Node.js 20 أو أحدث
|
| 28 |
+
- Go 1.21 أو أحدث (لأدوات فحص Go)
|
| 29 |
+
- Rust stable (لأدوات فحص Rust)
|
| 30 |
+
|
| 31 |
+
## التبعيات:
|
| 32 |
+
|
| 33 |
+
- **Bandit**: لفحص أمان Python
|
| 34 |
+
- **Pylint**: لفحص جودة كود Python
|
| 35 |
+
- **ESLint**: لفحص أمان وجودة JavaScript/TypeScript
|
| 36 |
+
- **Gosec**: لفحص أمان Go
|
| 37 |
+
- **Cargo Audit**: لفحص أمان Rust
|
| 38 |
+
|
| 39 |
+
## بيان عدم الضمان:
|
| 40 |
+
|
| 41 |
+
هذا البرنامج موزع تحت ترخيص MIT. لا يُمنح هذا البرنامج أي ضمانات، سواء كانت صريحة أو ضمنية، بما في ذلك على سبيل المثال لا الحصر ضمانات القابلية للتسويق والملاءمة لغرض معين. لا يتحمل المؤلفون أو موزعو البرنامج أي مسؤولية عن أي أضرار مباشرة أو غير مباشرة أو عرضية أو خاصة أو تبعية ناتجة عن استخدام البرنامج أو عدم القدرة على استخدامه.
|
| 42 |
+
|
| 43 |
+
## الموافقة:
|
| 44 |
+
|
| 45 |
+
باستخدام هذا البرنامج، فإنك توافق على شروط هذا الترخيص.
|
| 46 |
+
|
| 47 |
+
---
|
| 48 |
+
|
| 49 |
+
**للتواصل والدعم:**
|
| 50 |
+
- المستودع: https://github.com/yourusername/auto-guardian
|
| 51 |
+
- المشاكل: https://github.com/yourusername/auto-guardian/issues
|
MANIFEST.txt
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MANIFEST - Auto Guardian System Documentation Package
|
| 2 |
+
# =========================================
|
| 3 |
+
|
| 4 |
+
Generated: 2026-01-13 05:02:17
|
| 5 |
+
Version: 1.3.0
|
| 6 |
+
|
| 7 |
+
Files Included:
|
| 8 |
+
--------------
|
| 9 |
+
1. README.md - الملف التعريفي الرئيسي
|
| 10 |
+
2. CHANGELOG.md - سجل التغييرات
|
| 11 |
+
3. SECURITY.md - سياسة الأمان
|
| 12 |
+
4. CODE_OF_CONDUCT.md - مدونة السلوك
|
| 13 |
+
5. CONTRIBUTING.md - دليل المساهمة
|
| 14 |
+
6. docker-compose.yml - تكوين Docker Compose
|
| 15 |
+
7. Makefile - أوامر التطوير
|
| 16 |
+
8. .editorconfig - إعدادات المحرر
|
| 17 |
+
9. assets/ - ملفات الوسائط (SVG)
|
| 18 |
+
|
| 19 |
+
How to Use:
|
| 20 |
+
----------
|
| 21 |
+
1. استخرج الملفات من الأرشيف
|
| 22 |
+
2. انسخ الملفات إلى مجلد المشروع الرئيسي
|
| 23 |
+
3. استخدم الأمر `make help` للحصول على قائمة الأوامر
|
| 24 |
+
4. راجع CONTRIBUTING.md للمشاركة في التطوير
|
| 25 |
+
|
| 26 |
+
Verification:
|
| 27 |
+
------------
|
| 28 |
+
Run `python verify.py` to verify all files are valid.
|
| 29 |
+
|
| 30 |
+
For more information, visit:
|
| 31 |
+
https://github.com/AbdulElahOthmanGwaith/auto-guardian-system
|
| 32 |
+
|
| 33 |
+
---
|
| 34 |
+
Generated by Auto Guardian System Documentation Generator
|
Makefile
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Makefile لنظام الحارس التلقائي
|
| 2 |
+
# Auto Guardian System Makefile
|
| 3 |
+
|
| 4 |
+
# إعدادات افتراضية
|
| 5 |
+
SHELL := /bin/bash
|
| 6 |
+
PYTHON := python3
|
| 7 |
+
PIP := pip3
|
| 8 |
+
VENV := venv
|
| 9 |
+
VENV_ACTIVATE := $(VENV)/bin/activate
|
| 10 |
+
|
| 11 |
+
# المسارات
|
| 12 |
+
SRC := src
|
| 13 |
+
TESTS := tests
|
| 14 |
+
CONFIG := config
|
| 15 |
+
DOCS := docs
|
| 16 |
+
ASSETS := assets
|
| 17 |
+
|
| 18 |
+
# ملفات مهمة
|
| 19 |
+
REQUIREMENTS := requirements.txt
|
| 20 |
+
README := README.md
|
| 21 |
+
DOCKER_COMPOSE := docker-compose.yml
|
| 22 |
+
|
| 23 |
+
# ألوان للطباعة
|
| 24 |
+
GREEN := \033[0;32m
|
| 25 |
+
BLUE := \033[0;34m
|
| 26 |
+
YELLOW := \033[1;33m
|
| 27 |
+
RED := \033[0;31m
|
| 28 |
+
NC := \033[0m # No Color
|
| 29 |
+
|
| 30 |
+
# دوال مساعدة
|
| 31 |
+
define print_status
|
| 32 |
+
@echo -e "$(BLUE)[INFO]$(NC) $(1)"
|
| 33 |
+
endef
|
| 34 |
+
|
| 35 |
+
define print_success
|
| 36 |
+
@echo -e "$(GREEN)[SUCCESS]$(NC) $(1)"
|
| 37 |
+
endef
|
| 38 |
+
|
| 39 |
+
define print_warning
|
| 40 |
+
@echo -e "$(YELLOW)[WARNING]$(NC) $(1)"
|
| 41 |
+
endef
|
| 42 |
+
|
| 43 |
+
define print_error
|
| 44 |
+
@echo -e "$(RED)[ERROR]$(NC) $(1)"
|
| 45 |
+
endef
|
| 46 |
+
|
| 47 |
+
.PHONY: help install dev-install test test-cov lint format check clean clean-pyc clean-build clean-docker docker-build docker-run docker-stop docker-logs logs zip upload docs docs-serve
|
| 48 |
+
|
| 49 |
+
# ========================================
|
| 50 |
+
# الهدف الافتراضي - عرض المساعدة
|
| 51 |
+
# ========================================
|
| 52 |
+
help:
|
| 53 |
+
@echo ""
|
| 54 |
+
@echo -e "$(GREEN)╔════════════════════════════════════════════════════════════╗$(NC)"
|
| 55 |
+
@echo -e "$(GREEN)║ نظام الحارس التلقائي - أوامر التطوير ║$(NC)"
|
| 56 |
+
@echo -e "$(GREEN)╚════════════════════════════════════════════════════════════╝$(NC)"
|
| 57 |
+
@echo ""
|
| 58 |
+
@echo "الأوامر المتاحة:"
|
| 59 |
+
@echo ""
|
| 60 |
+
@echo " $(GREEN)التثبيت والإعداد$(NC)"
|
| 61 |
+
@echo " make install - تثبيت التبعيات الأساسية"
|
| 62 |
+
@echo " make dev-install - تثبيت التبعيات مع أدوات التطوير"
|
| 63 |
+
@echo " make update - تحديث التبعيات"
|
| 64 |
+
@echo ""
|
| 65 |
+
@echo " $(GREEN)الاختبارات$(NC)"
|
| 66 |
+
@echo " make test - تشغيل جميع الاختبارات"
|
| 67 |
+
@echo " make test-coverage - تشغيل الاختبارات مع تقرير التغطية"
|
| 68 |
+
@echo " make test-unit - تشغيل اختبارات الوحدة فقط"
|
| 69 |
+
@echo " make test-integration - تشغيل اختبارات التكامل"
|
| 70 |
+
@echo ""
|
| 71 |
+
@echo " $(GREEN)جودة الكود$(NC)"
|
| 72 |
+
@echo " make lint - فحص الكود باستخدام linters"
|
| 73 |
+
@echo " make format - تنسيق الكود تلقائياً"
|
| 74 |
+
@echo " make check - التحقق من جودة الكود"
|
| 75 |
+
@echo ""
|
| 76 |
+
@echo " $(GREEN)التنظيف$(NC)"
|
| 77 |
+
@echo " make clean - تنظيف ملفات البناء"
|
| 78 |
+
@echo " make clean-pyc - تنظيف ملفات Python المؤقتة"
|
| 79 |
+
@echo " clean-all - تنظيف كل شيء"
|
| 80 |
+
@echo ""
|
| 81 |
+
@echo " $(GREEN)Docker$(NC)"
|
| 82 |
+
@echo " make docker-build - بناء صورة Docker"
|
| 83 |
+
@echo " make docker-run - تشغيل الحاويات"
|
| 84 |
+
@echo " make docker-stop - إيقاف الحاويات"
|
| 85 |
+
@echo " make docker-logs - عرض سجلات Docker"
|
| 86 |
+
@echo ""
|
| 87 |
+
@echo " $(GREEN)النظام$(NC)"
|
| 88 |
+
@echo " make run - تشغيل النظام"
|
| 89 |
+
@echo " make logs - عرض سجلات النظام"
|
| 90 |
+
@echo ""
|
| 91 |
+
@echo " $(GREEN)الأرشفة$(NC)"
|
| 92 |
+
@echo " make zip - إنشاء ملف ZIP للمشروع"
|
| 93 |
+
@echo ""
|
| 94 |
+
@echo " $(GREEN)التوثيق$(NC)"
|
| 95 |
+
@echo " make docs - بناء التوثيق"
|
| 96 |
+
@echo " make docs-serve - عرض التوثيق محلياً"
|
| 97 |
+
@echo ""
|
| 98 |
+
@echo "للحصول على تفاصيل إضافية، راجع ملف CONTRIBUTING.md"
|
| 99 |
+
@echo ""
|
| 100 |
+
|
| 101 |
+
# ========================================
|
| 102 |
+
# قسم التثبيت
|
| 103 |
+
# ========================================
|
| 104 |
+
install:
|
| 105 |
+
$(call print_status,"جاري تثبيت التبعيات...")
|
| 106 |
+
@if [ ! -f $(REQUIREMENTS) ]; then $(call print_error,"ملف requirements.txt غير موجود"); exit 1; fi
|
| 107 |
+
$(PIP) install -r $(REQUIREMENTS)
|
| 108 |
+
$(call print_success,"تم تثبيت التبعيات بنجاح")
|
| 109 |
+
|
| 110 |
+
dev-install: install
|
| 111 |
+
$(call print_status,"جاري تثبيت أدوات التطوير...")
|
| 112 |
+
$(PIP) install pytest pytest-cov pytest-mock pytest-cov coveralls
|
| 113 |
+
$(PIP) install black flake8 mypy isort pre-commit
|
| 114 |
+
$(PIP) install sphinx sphinx-rtd-theme
|
| 115 |
+
$(call print_success,"تم تثبيت أدوات التطوير")
|
| 116 |
+
|
| 117 |
+
update:
|
| 118 |
+
$(call print_status,"جاري تحديث التبعيات...")
|
| 119 |
+
$(PIP) install --upgrade -r $(REQUIREMENTS)
|
| 120 |
+
$(call print_success,"تم تحديث التبعيات")
|
| 121 |
+
|
| 122 |
+
# ========================================
|
| 123 |
+
# قسم الاختبارات
|
| 124 |
+
# ========================================
|
| 125 |
+
test:
|
| 126 |
+
$(call print_status,"جاري تشغيل الاختبارات...")
|
| 127 |
+
@if [ ! -d "$(TESTS)" ]; then $(call print_error,"مجلد الاختبارات غير موجود"); exit 1; fi
|
| 128 |
+
$(PYTHON) -m pytest $(TESTS) -v --tb=short
|
| 129 |
+
$(call print_success,"اكتمل تشغيل الاختبارات")
|
| 130 |
+
|
| 131 |
+
test-coverage:
|
| 132 |
+
$(call print_status,"جاري تشغيل الاختبارات مع التغطية...")
|
| 133 |
+
$(PYTHON) -m pytest $(TESTS) --cov=$(SRC) --cov-report=html --cov-report=term-missing
|
| 134 |
+
$(call print_success,"تم إنشاء تقرير التغطية في مجلد htmlcov/")
|
| 135 |
+
|
| 136 |
+
test-unit:
|
| 137 |
+
$(call print_status,"جاري تشغيل اختبارات الوحدة...")
|
| 138 |
+
$(PYTHON) -m pytest $(TESTS)/test_*.py -v
|
| 139 |
+
|
| 140 |
+
test-integration:
|
| 141 |
+
$(call print_status,"جاري تشغيل اختبارات التكامل...")
|
| 142 |
+
$(PYTHON) -m pytest $(TESTS)/test_*integration*.py -v -s
|
| 143 |
+
|
| 144 |
+
# ========================================
|
| 145 |
+
# قسم جودة الكود
|
| 146 |
+
# ========================================
|
| 147 |
+
lint:
|
| 148 |
+
$(call print_status,"جاري فحص الكود...")
|
| 149 |
+
@echo "--- Flake8 ---"
|
| 150 |
+
@flake8 $(SRC) --max-line-length=100 --extend-ignore=E203
|
| 151 |
+
@echo "--- Mypy ---"
|
| 152 |
+
@mypy $(SRC) --ignore-missing-imports --strict-optional
|
| 153 |
+
$(call print_success,"اكتمل فحص الكود")
|
| 154 |
+
|
| 155 |
+
format:
|
| 156 |
+
$(call print_status,"جاري تنسيق الكود...")
|
| 157 |
+
@echo "--- Black ---"
|
| 158 |
+
@black $(SRC) $(TESTS) --line-length 100
|
| 159 |
+
@echo "--- isort ---"
|
| 160 |
+
@isort $(SRC) $(TESTS) --profile black
|
| 161 |
+
$(call print_success,"تم تنسيق الكود")
|
| 162 |
+
|
| 163 |
+
check:
|
| 164 |
+
$(call print_status,"جاري التحقق من جودة الكود...")
|
| 165 |
+
@echo "--- التحقق من التنسيق ---"
|
| 166 |
+
@black --check $(SRC) $(TESTS) --line-length 100
|
| 167 |
+
@echo "--- التحقق من الاستيرادات ---"
|
| 168 |
+
@isort --check-only $(SRC) $(TESTS) --profile black
|
| 169 |
+
@echo "--- Flake8 ---"
|
| 170 |
+
@flake8 $(SRC) --max-line-length=100 --extend-ignore=E203
|
| 171 |
+
$(call print_success,"اجتاز جميع فحوصات الجودة")
|
| 172 |
+
|
| 173 |
+
# ========================================
|
| 174 |
+
# قسم التنظيف
|
| 175 |
+
# ========================================
|
| 176 |
+
clean:
|
| 177 |
+
$(call print_status,"جاري تنظيف ملفات البناء...")
|
| 178 |
+
@rm -rf build/ dist/ *.egg-info/
|
| 179 |
+
@rm -rf htmlcov/ .coverage .coverage.*
|
| 180 |
+
$(call print_success,"تم تنظيف ملفات البناء")
|
| 181 |
+
|
| 182 |
+
clean-pyc:
|
| 183 |
+
$(call print_status,"جاري تنظيف ملفات Python المؤقتة...")
|
| 184 |
+
@find . -type d -name __pycache__ -exec rm -rf {} +
|
| 185 |
+
@find . -type f -name "*.pyc" -delete
|
| 186 |
+
@find . -type f -name ".pyc" -delete
|
| 187 |
+
@rm -rf $(VENV)
|
| 188 |
+
$(call print_success,"تم تنظيف ملفات Python")
|
| 189 |
+
|
| 190 |
+
clean-all: clean clean-pyc
|
| 191 |
+
$(call print_status,"جاري تنظيف كل شيء...")
|
| 192 |
+
@rm -rf logs/*.log
|
| 193 |
+
@rm -rf .hypothesis/
|
| 194 |
+
$(call print_success,"تم تنظيف كل شيء")
|
| 195 |
+
|
| 196 |
+
# ========================================
|
| 197 |
+
# قسم Docker
|
| 198 |
+
# ========================================
|
| 199 |
+
docker-build:
|
| 200 |
+
$(call print_status,"جاري بناء صورة Docker...")
|
| 201 |
+
@if [ ! -f "Dockerfile" ]; then $(call print_error,"ملف Dockerfile غير موجود"); exit 1; fi
|
| 202 |
+
docker-compose build
|
| 203 |
+
$(call print_success,"تم بناء الصورة")
|
| 204 |
+
|
| 205 |
+
docker-run:
|
| 206 |
+
$(call print_status,"جاري تشغيل الحاويات...")
|
| 207 |
+
@if [ ! -f "$(DOCKER_COMPOSE)" ]; then $(call print_error,"ملف docker-compose.yml غير موجود"); exit 1; fi
|
| 208 |
+
docker-compose up -d
|
| 209 |
+
$(call print_success,"تم تشغيل الحاويات. الخدمات متاحة على:")
|
| 210 |
+
@echo " - النظام الرئيسي: http://localhost:8000"
|
| 211 |
+
@echo " - Prometheus: http://localhost:9090"
|
| 212 |
+
@echo " - Grafana: http://localhost:3000"
|
| 213 |
+
|
| 214 |
+
docker-stop:
|
| 215 |
+
$(call print_status,"جاري إيقاف الحاويات...")
|
| 216 |
+
docker-compose down
|
| 217 |
+
$(call print_success,"تم إيقاف الحاويات")
|
| 218 |
+
|
| 219 |
+
docker-logs:
|
| 220 |
+
$(call print_status,"جاري عرض السجلات...")
|
| 221 |
+
docker-compose logs -f auto-guardian
|
| 222 |
+
|
| 223 |
+
# ========================================
|
| 224 |
+
# قسم تشغيل النظام
|
| 225 |
+
# ========================================
|
| 226 |
+
run:
|
| 227 |
+
$(call print_status,"جاري تشغيل نظام الحارس التلقائي...")
|
| 228 |
+
$(PYTHON) -m $(SRC).main
|
| 229 |
+
$(call print_success,"تم تشغيل النظام")
|
| 230 |
+
|
| 231 |
+
logs:
|
| 232 |
+
$(call print_status,"جاري عرض سجلات النظام...")
|
| 233 |
+
@if [ -d "logs" ]; then tail -f logs/*.log; else $(call print_warning,"مجلد السجلات غير موجود"); fi
|
| 234 |
+
|
| 235 |
+
# ========================================
|
| 236 |
+
# قسم الأرشفة
|
| 237 |
+
# ========================================
|
| 238 |
+
zip:
|
| 239 |
+
$(call print_status,"جاري إنشاء ملف ZIP...")
|
| 240 |
+
@VERSION=$$(git describe --tags 2>/dev/null || echo "1.3.0"); \
|
| 241 |
+
FILENAME="auto-guardian-system-$${VERSION}.zip"; \
|
| 242 |
+
if [ -f "$$FILENAME" ]; then rm "$$FILENAME"; fi \
|
| 243 |
+
zip -r "$$FILENAME" . \
|
| 244 |
+
--exclude="*.git*" \
|
| 245 |
+
--exclude="*.pyc" \
|
| 246 |
+
--exclude="__pycache__/*" \
|
| 247 |
+
--exclude="*.egg-info/*" \
|
| 248 |
+
--exclude="build/*" \
|
| 249 |
+
--exclude="dist/*" \
|
| 250 |
+
--exclude="htmlcov/*" \
|
| 251 |
+
--exclude=".hypothesis/*" \
|
| 252 |
+
--exclude="venv/*" \
|
| 253 |
+
--exclude="node_modules/*" \
|
| 254 |
+
--exclude=".DS_Store" \
|
| 255 |
+
--exclude="*.log" \
|
| 256 |
+
--exclude="logs/*" \
|
| 257 |
+
--exclude="backups/*"
|
| 258 |
+
$(call print_success,"تم إنشاء الملف: $$FILENAME")
|
| 259 |
+
@ls -lh "$$FILENAME"
|
| 260 |
+
|
| 261 |
+
# ========================================
|
| 262 |
+
# قسم التوثيق
|
| 263 |
+
# ========================================
|
| 264 |
+
docs:
|
| 265 |
+
$(call print_status,"جاري بناء التوثيق...")
|
| 266 |
+
@if [ ! -d "$(DOCS)" ]; then $(call print_error,"مجلد التوثيق غير موجود"); exit 1; fi
|
| 267 |
+
$(PYTHON) -m sphinx -b html $(DOCS) $(DOCS)/_build/html
|
| 268 |
+
$(call print_success,"تم بناء التوثيق في $(DOCS)/_build/html/")
|
| 269 |
+
|
| 270 |
+
docs-serve:
|
| 271 |
+
$(call print_status,"جاري تشغيل خادم التوثيق...")
|
| 272 |
+
@if [ ! -d "$(DOCS)/_build/html" ]; then make docs; fi
|
| 273 |
+
$(PYTHON) -m http.server 8080 -d $(DOCS)/_build/html
|
README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🛡️ Auto-Guardian Security System | نظام الحارس التلقائي للأمن
|
| 2 |
+
|
| 3 |
+
<div align="center">
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+

|
| 8 |
+

|
| 9 |
+

|
| 10 |
+

|
| 11 |
+
|
| 12 |
+
**نظام متكامل لفحص الكود البرمائي وكشف الثغرات الأمنية بشكل تلقائي**
|
| 13 |
+
|
| 14 |
+
*Automated Code Security Scanning and Vulnerability Detection System*
|
| 15 |
+
|
| 16 |
+
</div>
|
| 17 |
+
|
| 18 |
+
---
|
| 19 |
+
|
| 20 |
+
## 📋 نظرة عامة | Overview
|
| 21 |
+
|
| 22 |
+
**نظام Auto-Guardian** هو أداة متكاملة مصممة لتعزيز الأمان في مشاريع البرمجة من خلال فحص الكود آلياً واكتشاف الثغرات الأمنية قبل دمجها في الكود الرئيسي. يجمع النظام بين قوة أدوات التحليل الثابت (Static Analysis) وسهولة الاستخدام من خلال لوحة تحكم ويب متجاوبة تدعم اللغتين العربية والإنجليزية.
|
| 23 |
+
|
| 24 |
+
يهدف هذا المشروع إلى تمكين فرق التطوير من تبني ممارسات **DevSecOps** بسهولة، حيث يتم دمج الفحص الأمني تلقائياً ضمن دورة حياة التطوير. يوفر النظام تقارير تفصيلية عن الثغرات المكتشفة مع تصنيفها حسب مستوى الخطورة، مما يساعد المطورين على تحديد أولويات الإصلاح بكفاءة عالية.
|
| 25 |
+
|
| 26 |
+
---
|
| 27 |
+
|
| 28 |
+
## ✨ الميزات الرئيسية | Key Features
|
| 29 |
+
|
| 30 |
+
### 🔍 الفحص الأمني الآلي | Automated Security Scanning
|
| 31 |
+
يستخدم النظام مجموعة متكاملة من أدوات التحليل الأمني للكشف عن الثغرات الشائعة في الكود البرمجي. يدعم النظام فحص مشاريع **Python** و **JavaScript** و **Java** وغيرها من اللغات الشائعة.
|
| 32 |
+
|
| 33 |
+
### 📊 لوحة تحكم تفاعلية | Interactive Dashboard
|
| 34 |
+
توفر لوحة التحكم واجهة ويب متجاوبة بالكامل تعرض إحصائيات الأمان بشكل لحظي ومباشر. تدعم اللوحة اللغتين العربية والإنجليزية مع دعم كامل للاتجاه من اليمين لليسار (RTL).
|
| 35 |
+
|
| 36 |
+
### 🛠️ ملحقات النظام | System Extras
|
| 37 |
+
يتضمن المشروع مجموعة واسعة من الملحقات والأدوات الإضافية:
|
| 38 |
+
- **Docker Support**: حاويات جاهزة للتشغيل باستخدام `docker-compose`.
|
| 39 |
+
- **API Documentation**: توثيق كامل للواجهة البرمجية بصيغة `OpenAPI`.
|
| 40 |
+
- **Management Scripts**: سكربتات للنسخ الاحتياطي والصيانة والترقية.
|
| 41 |
+
- **Security Templates**: قوالب جاهزة لبلاغات الثغرات وطلبات السحب.
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
## 🏗️ هيكل المشروع | Project Structure
|
| 46 |
+
|
| 47 |
+
```
|
| 48 |
+
Auto-Guardian-Core/
|
| 49 |
+
├── 📄 index.html # لوحة التحكم الرئيسية (GitHub Pages)
|
| 50 |
+
├── 📄 docker-compose.yml # إعدادات Docker
|
| 51 |
+
├── 📄 requirements.txt # متطلبات Python
|
| 52 |
+
├── 📂 scripts/ # سكربتات الإدارة والفحص
|
| 53 |
+
│ ├── 📄 security_scanner.py # فحص أمني متقدم (جديد)
|
| 54 |
+
│ ├── 📄 backup.sh # النسخ الاحتياطي
|
| 55 |
+
│ ├── 📄 maintenance.sh # الصيانة
|
| 56 |
+
│ └── 📄 upgrade.sh # الترقية
|
| 57 |
+
├── 📄 robots.txt # ملفات SEO لمحركات البحث
|
| 58 |
+
├── 📄 sitemap.xml # خريطة الموقع لمحركات البحث
|
| 59 |
+
├── 📄 structured-data.json # البيانات المنظمة (JSON-LD)
|
| 60 |
+
├── 📂 docs/ # التوثيق التقني
|
| 61 |
+
│ ├── 📂 api/ # توثيق OpenAPI
|
| 62 |
+
│ └── 📄 configuration.md # إعدادات النظام
|
| 63 |
+
├── 📂 assets/ # الأصول المرئية والشعارات
|
| 64 |
+
└── 📂 .github/ # قوالب GitHub
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
---
|
| 68 |
+
|
| 69 |
+
## 🚀 البدء السريع | Quick Start
|
| 70 |
+
|
| 71 |
+
### التشغيل عبر Docker (موصى به)
|
| 72 |
+
```bash
|
| 73 |
+
docker-compose up -d
|
| 74 |
+
```
|
| 75 |
+
|
| 76 |
+
### التشغيل المحلي
|
| 77 |
+
```bash
|
| 78 |
+
pip install -r requirements.txt
|
| 79 |
+
python -m http.server 8000
|
| 80 |
+
```
|
| 81 |
+
|
| 82 |
+
---
|
| 83 |
+
|
| 84 |
+
## 📝 الترخيص | License
|
| 85 |
+
هذا المشروع مرخص تحت **رخصة MIT**. راجع ملف [LICENSE](LICENSE) لمزيد من التفاصيل.
|
| 86 |
+
|
| 87 |
+
---
|
| 88 |
+
|
| 89 |
+
<div align="center">
|
| 90 |
+
|
| 91 |
+
**صُنع بـ ❤️ بواسطة Auto-Guardian Team**
|
| 92 |
+
|
| 93 |
+
[المستودع الرئيسي](https://github.com/AbdulElahOthmanGwaith/Auto-Guardian-Core) | [لوحة التحكم المباشرة](https://abdulelahothmangwaith.github.io/Auto-Guardian-Core/)
|
| 94 |
+
|
| 95 |
+
</div>
|
SECURITY.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# سياسة الأمان لنظام الحارس التلقائي
|
| 2 |
+
|
| 3 |
+
<div align="center">
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+
**نظام ذكي لحماية الخوادم من التهديدات الإلكترونية**
|
| 8 |
+
|
| 9 |
+
</div>
|
| 10 |
+
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
## مقدمة
|
| 14 |
+
|
| 15 |
+
نحن نأخذ الأمان على محمل الجد في نظام الحارس التلقائي. نظراً لطبيعة المشروع كحل أمني، ندرك أهمية الحفاظ على أعلى معايير الأمان في تطويرنا ourselves. يوضح هذا المستند كيفية الإبلاغ عن الثغرات الأمنية discovered في نظامنا.
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## versions المدعومة
|
| 20 |
+
|
| 21 |
+
نحن ندعم أحدث إصدارين رئيسيين من نظام الحارس التلقائي مع تحديثات الأمان. الإصدارات القديمة قد لا تستقبل تصحيحات الأمان.
|
| 22 |
+
|
| 23 |
+
| الإصدار | حالة الدعم | آخر تحديث |
|
| 24 |
+
|---------|------------|-----------|
|
| 25 |
+
| 1.3.x | ✅ نشط | الحالي |
|
| 26 |
+
| 1.2.x | ⚠️ صيانة | 2024-10-15 |
|
| 27 |
+
| 1.1.x | ❌ غير مدعوم | 2024-09-28 |
|
| 28 |
+
| 1.0.x | ❌ غير مدعوم | 2024-09-01 |
|
| 29 |
+
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
## الإبلاغ عن الثغرات
|
| 33 |
+
|
| 34 |
+
### كيف تُبلّغ عن ثغرة
|
| 35 |
+
|
| 36 |
+
نحن نشجع الباحثين الأمنيين على الإبلاغ بشكل مسؤول عن الثغرات التي يكتشفونها. لمساعدتنا في معالجة الثغرات بأسرع وقت ممكن، يُرجى اتباع الخطوات التالية:
|
| 37 |
+
|
| 38 |
+
**الخطوة 1:** لا تشارك الثغرة مع أي شخص آخر
|
| 39 |
+
|
| 40 |
+
**الخطوة 2:** جمع معلومات كافية عن الثغرة
|
| 41 |
+
|
| 42 |
+
جمع أكبر قدر ممكن من المعلومات عن الثغرة المكتشفة، بما في ذلك الخطوات المتكررة لإعادة إنتاجها، والبيئة التي تم فيها اكتشاف الثغرة، وتأثيرها المحتمل على النظام. كلما كانت المعلومات أكثر تفصيلاً، كان بإمكاننا معالجة الثغرة بشكل أسرع وأفضل.
|
| 43 |
+
|
| 44 |
+
**الخطوة 3:** إرسال التقرير عبر قناة آمنة
|
| 45 |
+
|
| 46 |
+
إرسال تقرير مفصل يتضمن وصفاً واضحاً للثغرة، وخطوات إعادة الإنتاج، وإثبات المفهوم (PoC) إن أمكن ذلك. يرجى تضمين معلومات الاتصال الخاصة بك حتى نتمكن من التواصل معك.
|
| 47 |
+
|
| 48 |
+
### قنوات الإبلاغ
|
| 49 |
+
|
| 50 |
+
**البريد الإلكتروني (المُفضّل):**
|
| 51 |
+
|
| 52 |
+
```
|
| 53 |
+
security@autoguardian.local
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
يرجى تشفير الرسائل باستخدام مفتاح PGP العام الخاص بنا:
|
| 57 |
+
|
| 58 |
+
```
|
| 59 |
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
| 60 |
+
|
| 61 |
+
mQINBF...
|
| 62 |
+
-----END PGP PUBLIC KEY BLOCK-----
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
**GitHub Security Advisories:**
|
| 66 |
+
|
| 67 |
+
يمكنك أيضاً استخدام [GitHub Security Advisories](https://github.com/AbdulElahOthmanGwaith/auto-guardian-system/security/advisories/new) للإبلاغ عن الثغرات بشكل خاص.
|
| 68 |
+
|
| 69 |
+
---
|
| 70 |
+
|
| 71 |
+
## ما نطلبه منك
|
| 72 |
+
|
| 73 |
+
### المسؤولة من الإبلاغ
|
| 74 |
+
|
| 75 |
+
نطلب من الباحثين الأمنيين الالتزام بالممارسات التالية:
|
| 76 |
+
|
| 77 |
+
- **عدم التأثير على المستخدمين:** لا تُشغّل هجمات حقيقية على مستخدمي النظام أو على البنية التحتية دون إذن صريح. استخدم بيئات الاختبار فقط.
|
| 78 |
+
|
| 79 |
+
- **عدم الوصول إلى بيانات غير مصرح بها:** لا تحاول الوصول إلى بيانات لا تملك حق الوصول إليها، بما في ذلك بيانات المستخدمين أو البيانات الشخصية.
|
| 80 |
+
|
| 81 |
+
- **الإبلاغ الفوري:** بعد اكتشاف الثغرة، أبلغنا فوراً ولا تنتظر نشرها علناً أو مشاركتها مع أطراف ثالثة.
|
| 82 |
+
|
| 83 |
+
- **منحنا وقتاً كافياً:** امنحنا وقتاً كافياً لتحليل الثغرة وتطوير ونشر التصحيح قبل أي إفصاح عام. نطلب عادةً 90 يوماً كحد أدنى.
|
| 84 |
+
|
| 85 |
+
### ما نعدك به
|
| 86 |
+
|
| 87 |
+
نحن نلتزم بما يلي تجاه الباحثين الأمنيين:
|
| 88 |
+
|
| 89 |
+
- **الاستجابة السريعة:** سنرد على تقريرك خلال 48 ساعة من استلامه.
|
| 90 |
+
|
| 91 |
+
- **عدم الملاحقة القانونية:** إذا التزمت بإرشادات الإبلاغ المسؤول، لن نتخذ أي إجراء قانوني ضدك.
|
| 92 |
+
|
| 93 |
+
- **الاعتراف:** إذا أردت ذلك، سنعترف بجهودك في ملف CHANGELOG وفي صفحة الشكر على الموقع.
|
| 94 |
+
|
| 95 |
+
- **مكافآت:** للنثريات الحرجة، قد نقدم مكافآت مالية أو اعتراف خاص حسب تقديرنا.
|
| 96 |
+
|
| 97 |
+
---
|
| 98 |
+
|
| 99 |
+
## فئات الثغرات التي نبحث عنها
|
| 100 |
+
|
| 101 |
+
نحن مهتمون بشكل خاص بالثغرات في المجالات التالية:
|
| 102 |
+
|
| 103 |
+
### الثغرات الحرجة (Critical)
|
| 104 |
+
|
| 105 |
+
هذ�� الثغرات تتطلب اهتماماً فورياً وعالياً الأولوية:
|
| 106 |
+
|
| 107 |
+
- **تنفيذ كود عن بُعد (RCE):** أي ثغرة تسمح للمهاجم بتنفيذ أكواد خبيثة على الخادم
|
| 108 |
+
- **رفع الامتيازات:** أي ثغرة تسمح للمهاجم بالحصول على صلاحيات أعلى
|
| 109 |
+
- **التح绕过 المصادقة:** أي ثغرة تسمح بالوصول غير المصرح به
|
| 110 |
+
- **حقن قاعدة البيانات:** ثغرات SQL Injection التي قد تؤدي لسرقة البيانات
|
| 111 |
+
|
| 112 |
+
### الثغرات العالية (High)
|
| 113 |
+
|
| 114 |
+
هذه الثغرات تؤثر بشكل كبير على أمان النظام:
|
| 115 |
+
|
| 116 |
+
- **حقن الأوامر:** ثغرات Command Injection
|
| 117 |
+
- **كشف البيانات الحساسة:** كشف معلومات حساسة في الاستجابات
|
| 118 |
+
- **هجوم القوة الغاشمة:** نقاط ضعف تسمح بتهديدات القوة الغاشمة
|
| 119 |
+
- **إدارة الجلسات:** ثغرات في إدارة رموز الوصول
|
| 120 |
+
|
| 121 |
+
### الثغرات المتوسطة (Medium)
|
| 122 |
+
|
| 123 |
+
هذه الثغرات لها تأثير محدود ولكنها تحتاج معالجة:
|
| 124 |
+
|
| 125 |
+
- **Cross-Site Scripting (XSS):** في أي واجهات ويب
|
| 126 |
+
- **Cross-Site Request Forgery (CSRF):** في نماذج التقديم
|
| 127 |
+
- **تسريب المعلومات:** كشف معلومات تقنية غير ضرورية
|
| 128 |
+
|
| 129 |
+
### الثغرات المنخفضة (Low)
|
| 130 |
+
|
| 131 |
+
هذه ملاحظات تحسينية:
|
| 132 |
+
|
| 133 |
+
- تكوينات غير مثالية
|
| 134 |
+
- توصيات أمان عامة
|
| 135 |
+
- تحسينات في الممارسات
|
| 136 |
+
|
| 137 |
+
---
|
| 138 |
+
|
| 139 |
+
## عملية المعالجة
|
| 140 |
+
|
| 141 |
+
### الخطوات التي نتبعها
|
| 142 |
+
|
| 143 |
+
عند استلام تقرير عن ثغرة أمنية، نتبع الخطوات التالية:
|
| 144 |
+
|
| 145 |
+
**المرحلة الأولى - الاستلام والتأكيد (1-3 أيام)**
|
| 146 |
+
|
| 147 |
+
فور استلام تقرير الثغرة، نقوم بالخطوات التالية: أولاً، نرسل إشعاراً بالاستلام للباحث الأمني. ثانياً، نقيّم الثغرة ونحدد مستوى خطورتها. ثالثاً، نُعيّن فريقاً لمعالجة الثغرة. رابعاً، نُبلغ الباحث الأمني بالجدول الزمني المتوقع.
|
| 148 |
+
|
| 149 |
+
**المرحلة الثانية - التطوير والاختبار (7-30 يوماً)**
|
| 150 |
+
|
| 151 |
+
نعمل على تطوير وتصحيح الثغرة مع المراحل التالية: تطوير التصحيح مع مراعاة عدم إدخال ثغرات جديدة، وكتابة اختبارات للتحقق من فعالية التصحيح، وإجراء اختبارات أمنية إضافية، ومراجعة الكود من قبل مطور آخر.
|
| 152 |
+
|
| 153 |
+
**المرحلة الثالثة - النشر والإفصاح (14-45 يوماً)**
|
| 154 |
+
|
| 155 |
+
نقوم بإصدار التصحيح مع المراحل التالية: اختبار التصحيح في بيئة الإنتاج، ونشر تحديث جديد عبر القنوات الرسمية، وإصدار إشعار أمني للمستخدمين، وتحديث وثائق الأمان إذا لزم الأمر.
|
| 156 |
+
|
| 157 |
+
### الجدول الزمني المعياري
|
| 158 |
+
|
| 159 |
+
| نوع الثغرة | وقت الاستجابة | وقت الإصلاح |
|
| 160 |
+
|------------|---------------|-------------|
|
| 161 |
+
| حرجة | 24 ساعة | 7 أيام |
|
| 162 |
+
| عالية | 48 ساعة | 14 يوماً |
|
| 163 |
+
| متوسطة | 72 ساعة | 30 يوماً |
|
| 164 |
+
| منخفضة | أسبوع | 45 يوماً |
|
| 165 |
+
|
| 166 |
+
---
|
| 167 |
+
|
| 168 |
+
## إعدادات الأمان الموصى بها
|
| 169 |
+
|
| 170 |
+
### متطلبات النظام
|
| 171 |
+
|
| 172 |
+
لضمان أمان النظام، تأكد من:
|
| 173 |
+
|
| 174 |
+
**نظام التشغيل:**
|
| 175 |
+
|
| 176 |
+
- Ubuntu 20.04 LTS أو أحدث
|
| 177 |
+
- Debian 11 أو أحدث
|
| 178 |
+
- CentOS 8 أو أحدث
|
| 179 |
+
|
| 180 |
+
**متطلبات Python:**
|
| 181 |
+
|
| 182 |
+
- Python 3.8 أو أحدث
|
| 183 |
+
- بيئة افتراضية معزولة
|
| 184 |
+
- إدارة حزم آمنة
|
| 185 |
+
|
| 186 |
+
**الشبكة:**
|
| 187 |
+
|
| 188 |
+
- جدار حماية مُكوّن
|
| 189 |
+
- SSH مع المصادقة بالمفاتيح فقط
|
| 190 |
+
- عدم فتح منافذ غير ضرورية
|
| 191 |
+
|
| 192 |
+
### إعدادات الإنتاج الموصى بها
|
| 193 |
+
|
| 194 |
+
```yaml
|
| 195 |
+
# إعدادات الأمان في config/settings.yaml
|
| 196 |
+
|
| 197 |
+
security:
|
| 198 |
+
# تفعيل التحقق من التحديثات
|
| 199 |
+
check_updates: true
|
| 200 |
+
|
| 201 |
+
# فترة التحقق (بالساعات)
|
| 202 |
+
check_interval: 24
|
| 203 |
+
|
| 204 |
+
# تفعيل HTTPS فقط
|
| 205 |
+
force_https: true
|
| 206 |
+
|
| 207 |
+
# فترة انتهاء جلسة API (بالساعات)
|
| 208 |
+
api_token_expiry: 24
|
| 209 |
+
|
| 210 |
+
# تفعيل تسجيل جميع الإجراءات
|
| 211 |
+
audit_logging: true
|
| 212 |
+
```
|
| 213 |
+
|
| 214 |
+
---
|
| 215 |
+
|
| 216 |
+
## الموارد الأمنية
|
| 217 |
+
|
| 218 |
+
### روابط مفيدة
|
| 219 |
+
|
| 220 |
+
- [دليل OWASP](https://owasp.org/) - أفضل ممارسات أمان التطبيقات
|
| 221 |
+
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks) - إعدادات أمان النظام
|
| 222 |
+
- [NIST Cybersecurity](https://www.nist.gov/cyberframework) - إطار أمان NIST
|
| 223 |
+
|
| 224 |
+
---
|
| 225 |
+
|
| 226 |
+
## شكر وتقدير
|
| 227 |
+
|
| 228 |
+
نود أن نشكر جميع الباحثين الأمنيين الذين ساهموا في تحسين أمان نظام الحارس التلقائي. إذا ساهمت في اكتشاف ثغرة أمنية وتم إصلاحها، يمكنك طلب إضافتك لقائمة الشكر أدناه:
|
| 229 |
+
|
| 230 |
+
| الباحث | الثغرة | التاريخ |
|
| 231 |
+
|--------|--------|---------|
|
| 232 |
+
| - | - | - |
|
| 233 |
+
|
| 234 |
+
*هل تريد أن تُضاف لقائمة الشكر؟ أخبرنا في تقريرك.*
|
| 235 |
+
|
| 236 |
+
---
|
| 237 |
+
|
| 238 |
+
## التواصل
|
| 239 |
+
|
| 240 |
+
للأسئلة المتعلقة بالأمان:
|
| 241 |
+
|
| 242 |
+
- **البريد الإلكتروني:** security@autoguardian.local
|
| 243 |
+
- **GitHub:** [Security Advisories](https://github.com/AbdulElahOthmanGwaith/auto-guardian-system/security/advisories)
|
| 244 |
+
- **الموقع:** [autoguardian.local](https://autoguardian.local)
|
| 245 |
+
|
| 246 |
+
---
|
| 247 |
+
|
| 248 |
+
<div align="center">
|
| 249 |
+
|
| 250 |
+
**شكراً للمساهمة في جعل الإنترنت أكثر أماناً! 🛡️**
|
| 251 |
+
|
| 252 |
+
*صُنع بـ ❤️ بواسطة عبد الإله عثمان غويث*
|
| 253 |
+
|
| 254 |
+
</div>
|
VIDEO_SCRIPT.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🎬 Auto-Guardian Video Production Guide
|
| 2 |
+
|
| 3 |
+
## نظرة عامة | Overview
|
| 4 |
+
|
| 5 |
+
هذا الملف يحتوي على سيناريو كامل احترافي لفيديو توضيحي (Demo Video) لمدة 90 ثانية لنظام Auto-Guardian. يمكن استخدام هذا السيناريو لإنشاء فيديو احترافي باستخدام أدوات مثل:
|
| 6 |
+
- **Canva**: لإنشاء الرسوم المتحركة
|
| 7 |
+
- **OBS Studio**: لتسجيل الشاشة
|
| 8 |
+
- **DaVinci Resolve**: للتحرير المتقدم
|
| 9 |
+
- **CapCut**: للهواتف المحمولة
|
| 10 |
+
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
## 🎥 سيناريو الفيديو | Video Script
|
| 14 |
+
|
| 15 |
+
### المشهد 1: المقدمة_hook (0:00 - 0:10)
|
| 16 |
+
|
| 17 |
+
| الوقت | العنصر البصري | الصوت/Narration |
|
| 18 |
+
|-------|--------------|-----------------|
|
| 19 |
+
| 0:00-0:03 | شاشة سوداء مع صوت نقرات لوحة مفاتيح سريعة | (صمت، تركيز) |
|
| 20 |
+
| 0:03-0:06 | عرض سريع لنافذة محرر أكواد مع أسطر حمراء (أخطاء أمنية) | "في عالم البرمجة، كل سطر كود هو بوابة محتملة للاختراق" |
|
| 21 |
+
| 0:06-0:10 | تحوّل سلس إلى شعار Auto-Guardian مع تأثير توهج | "لكن ماذا لو كان لديك حارس آلي يكتشف كل تهديد قبل وقوعه؟" |
|
| 22 |
+
|
| 23 |
+
### المشهد 2: تعريف النظام (0:10 - 0:25)
|
| 24 |
+
|
| 25 |
+
| الوقت | العنصر البصري | الصوت/Narration |
|
| 26 |
+
|-------|--------------|-----------------|
|
| 27 |
+
| 0:10-0:15 | عرض شعار Auto-Guardian مع نبض توهّج أخضر | "أهلاً بكم في Auto-Guardian" |
|
| 28 |
+
| 0:15-0:20 | عرض سريع للوحة التحكم الرئيسية (شاشة عريضة) | "نظام فحص أمان الكود البرمجي الآلي" |
|
| 29 |
+
| 0:20-0:25 | إحصائيات متحركة (1,247 تهديد محظور، 99.9% نجاح) | "المزايا التي يحتاجها كل مطور" |
|
| 30 |
+
|
| 31 |
+
### المشهد 3: كيف يعمل (0:25 - 0:50)
|
| 32 |
+
|
| 33 |
+
| الوقت | العنصر البصري | الصوت/Narration |
|
| 34 |
+
|-------|--------------|-----------------|
|
| 35 |
+
| 0:25-0:32 | رسم توضيحي متحرك: كود → فحص → اكتشاف ثغرة | "أولاً، يقوم النظام بفحص الكود تلقائياً" |
|
| 36 |
+
| 0:32-0:38 | عرض أدوات الفحص (Bandit, ESLint, Trivy) | "باستخدام أحدث أدوات التحليل الأمني" |
|
| 37 |
+
| 0:38-0:45 | تصفية المشاكل حسب الخطورة (حرجة، عالية، متوسطة) | "يصنّف الثغرات حسب مستوى خطورتها" |
|
| 38 |
+
| 0:45-0:50 | عرض قائمة المشاكل مع تفاصيل الملف والسطر | "مع تحديد دقيق لموقع المشكلة" |
|
| 39 |
+
|
| 40 |
+
### المشهد 4: لوحة التحكم (0:50 - 1:10)
|
| 41 |
+
|
| 42 |
+
| الوقت | العنصر البصري | الصوت/Narration |
|
| 43 |
+
|-------|--------------|-----------------|
|
| 44 |
+
| 0:50-0:56 | عرض المخططات البيانية (خطية ودائرية) | "لوحة تحكم تفاعلية تعرض كل شيء" |
|
| 45 |
+
| 0:56-1:02 | تصفح المستودعات النشطة وحالتها | "ومراقبة جميع مشاريعك في مكان واحد" |
|
| 46 |
+
| 1:02-1:07 | التفاعل مع القائمة الجانبية والقائمة على الهاتف | "تصميم متجاوب يعمل على كل الأجهزة" |
|
| 47 |
+
| 1:07-1:10 | فتح صفحة الإعدادات وتخصيص الخيارات | "وخيارات تخصيص متقدمة" |
|
| 48 |
+
|
| 49 |
+
### المشهد 5: CI/CD Integration (1:10 - 1:25)
|
| 50 |
+
|
| 51 |
+
| الوقت | العنصر البصري | الصوت/Narration |
|
| 52 |
+
|-------|--------------|-----------------|
|
| 53 |
+
| 1:10-1:15 | عرض GitHub Actions workflow | "لكن الأمر لا يتوقف هنا" |
|
| 54 |
+
| 1:15-1:20 | فحص تلقائي لـ Pull Request + تعليق بالنتيجة | "يتكامل مع GitHub Actions لفحص كل طلب دمج" |
|
| 55 |
+
| 1:20-1:25 | عرض تقرير الفحص مع نتائج المرور/الفشل | "ممنوع مرور الكود غير الآمن أبداً" |
|
| 56 |
+
|
| 57 |
+
### المشهد 6: الختام (1:25 - 1:30)
|
| 58 |
+
|
| 59 |
+
| الوقت | العنصر البصري | الصوت/Narration |
|
| 60 |
+
|-------|--------------|-----------------|
|
| 61 |
+
| 1:25-1:27 | عرض رابط GitHub وعداد النجوم | "Open Source ومجاني تماماً" |
|
| 62 |
+
| 1:27-1:29 | زر "Star" يتزايد + زر "Deploy Now" | "ساعدنا في جعل الإنترنت أكثر أماناً" |
|
| 63 |
+
| 1:29-1:30 | شعار Auto-Guardian مع معلومات التواصل | "تفضلوا بزيارة مستودعنا على GitHub" |
|
| 64 |
+
|
| 65 |
+
---
|
| 66 |
+
|
| 67 |
+
## 🎨 إرشادات الإنتاج | Production Guidelines
|
| 68 |
+
|
| 69 |
+
### ألوان العلامة التجارية | Brand Colors
|
| 70 |
+
|
| 71 |
+
| الاستخدام | اللون | الكود |
|
| 72 |
+
|----------|-------|-------|
|
| 73 |
+
| الأساسي | أزرق كهربائي | `#3B82F6` |
|
| 74 |
+
| Secondary | بنفسجي | `#8B5CF6` |
|
| 75 |
+
| نجاح | أخضر | `#10B981` |
|
| 76 |
+
| خطر | أحمر | `#EF4444` |
|
| 77 |
+
| تحذير | برتقالي | `#F59E0B` |
|
| 78 |
+
| الخلفية | أزرق داكن | `#0F172A` |
|
| 79 |
+
|
| 80 |
+
### الخطوط | Typography
|
| 81 |
+
|
| 82 |
+
- **العناوين الرئيسية**: Arial Bold, 48-64px
|
| 83 |
+
- **النصوص الفرعية**: Arial Regular, 18-24px
|
| 84 |
+
- **الأزرار والشارات**: Arial Bold, 12-14px
|
| 85 |
+
|
| 86 |
+
### المؤثرات الصوتية | Sound Effects
|
| 87 |
+
|
| 88 |
+
| المشهد | المؤثر |
|
| 89 |
+
|--------|--------|
|
| 90 |
+
| البداية | نقرات لوحة مفاتيح (Typewriter clicks) |
|
| 91 |
+
| انتقال للمشهد | Whoosh سريعة |
|
| 92 |
+
| اكتشاف ثغرة | Alert sound (نغمة قصيرة) |
|
| 93 |
+
| نجاح الفحص | Success chime |
|
| 94 |
+
| الختام | موسيقى تشجيعية خفيفة (Uplifting music) |
|
| 95 |
+
|
| 96 |
+
### سرعة الانتقال | Pacing
|
| 97 |
+
|
| 98 |
+
- **المشاهد السريعة (دقيقة)**: 0:00-0:10
|
| 99 |
+
- **المشهد التعريفي**: 0:10-0:25 (بطيء نسبياً)
|
| 100 |
+
- **الشرح التقني**: 0:25-0:50 (متوسط)
|
| 101 |
+
- **العرض التفاعلي**: 0:50-1:10 (بطيء للتفاعل)
|
| 102 |
+
- **التكامل**: 1:10-1:25 (سريع)
|
| 103 |
+
- **الختام**: 1:25-1:30 (رسمي)
|
| 104 |
+
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
## 📦 الأصول الجاهزة | Ready-to-Use Assets
|
| 108 |
+
|
| 109 |
+
تم إنشاء الأصول التالية في مجلد `assets/`:
|
| 110 |
+
|
| 111 |
+
```
|
| 112 |
+
assets/
|
| 113 |
+
├── 📄 logo.svg # شعار المشروع (512x512)
|
| 114 |
+
├── 📄 architecture.svg # رسم هيكل النظام (800x400)
|
| 115 |
+
├── 📄 icon-realtime.svg # أيقونة الوقت الحقيقي (64x64)
|
| 116 |
+
├── 📄 icon-ai.svg # أيقونة الذكاء الاصطناعي (64x64)
|
| 117 |
+
├── 📄 icon-alerts.svg # أيقونة التنبيهات (64x64)
|
| 118 |
+
├── 📄 icon-scan.svg # أيقونة الفحص (64x64)
|
| 119 |
+
└── 📄 video-thumbnail.svg # صورة الفيديو المصغرة (1280x720)
|
| 120 |
+
```
|
| 121 |
+
|
| 122 |
+
---
|
| 123 |
+
|
| 124 |
+
## 🔗 الروابط المطلوبة | Required Links
|
| 125 |
+
|
| 126 |
+
لإكمال الفيديو، ستحتاج إلى:
|
| 127 |
+
|
| 128 |
+
1. **رابط لوحة التحكم**: https://c6q1wmkpsakh.space.minimax.io
|
| 129 |
+
2. **رابط المستودع**: https://github.com/[username]/[repo-name]
|
| 130 |
+
3. **رابط المشروع**: [رابط ZIP المرفوع]
|
| 131 |
+
|
| 132 |
+
---
|
| 133 |
+
|
| 134 |
+
## 💡 نصائح للتسجيل
|
| 135 |
+
|
| 136 |
+
### لتسجيل الشاشة (OBS Studio):
|
| 137 |
+
|
| 138 |
+
```
|
| 139 |
+
1. إنشاء مشهد جديد
|
| 140 |
+
2. إضافة مصدر "Window Capture"
|
| 141 |
+
3. اختيار نافذة المتصفح
|
| 142 |
+
4. ضبط الدقة: 1920x1080
|
| 143 |
+
5. معدل الإطارات: 30fps
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
### للنصArabic Voiceover:
|
| 147 |
+
|
| 148 |
+
- استخدم ميكروفون جيد الجودة
|
| 149 |
+
- تحدث بوضوح وبوتيرة متوسطة
|
| 150 |
+
- أضف pauses عند الانتقال بين المشاهد
|
| 151 |
+
- استخدم نبرة واثقة ومهنية
|
| 152 |
+
|
| 153 |
+
---
|
| 154 |
+
|
| 155 |
+
## 📊 الجدول الزمني المقترح
|
| 156 |
+
|
| 157 |
+
| المرحلة | الوقت | الأنشطة |
|
| 158 |
+
|---------|-------|---------|
|
| 159 |
+
| التحضير | 30 دقيقة | قراءة السيناريو، تجهيز الأصول |
|
| 160 |
+
| التسجيل | 1-2 ساعة | تسجيل الشاشة، الصوت، المؤثرات |
|
| 161 |
+
| المونتاج | 2-3 ساعات | تجميع المشاهد، إضافة التأثيرات |
|
| 162 |
+
| المراجعة | 30 دقيقة | مشاهدة، تعديلات نهائية |
|
| 163 |
+
| **الإجمالي** | **4-6 ساعات** | فيديو نهائي احترافي |
|
| 164 |
+
|
| 165 |
+
---
|
| 166 |
+
|
| 167 |
+
## 📞 الدعم | Support
|
| 168 |
+
|
| 169 |
+
للمساعدة في إنتاج الفيديو:
|
| 170 |
+
- راجع قسم [Contributing](../CONTRIBUTING.md) في المشروع
|
| 171 |
+
- أو أضف Issue في المستودع مع وسم "video-production"
|
| 172 |
+
|
| 173 |
+
---
|
| 174 |
+
|
| 175 |
+
*صُنع بح ❤️ لفريق Auto-Guardian*
|
assets/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# مجلد الوسائط - assets
|
| 2 |
+
|
| 3 |
+
<div align="center">
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+
**نظام ذكي لحماية الخوادم من التهديدات الإلكترونية**
|
| 8 |
+
|
| 9 |
+
</div>
|
| 10 |
+
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
## مقدمة
|
| 14 |
+
|
| 15 |
+
يحتوي هذا المجلد على جميع ملفات الوسائط والرسوم التوضيحية المستخدمة في مشروع نظام الحارس التلقائي. جميع الملفات مصممة بتنسيق SVG (Scalable Vector Graphics) لضمان جودة عالية على جميع الشاشات.
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## قائمة الملفات
|
| 20 |
+
|
| 21 |
+
| الملف | الوصف | الأبعاد | الاستخدام |
|
| 22 |
+
|-------|-------|---------|-----------|
|
| 23 |
+
| `banner.svg` | البانر الرئيسي للمشروع | 1200×400 | رأس ملف README.md |
|
| 24 |
+
| `dashboard.svg` | لوحة التحكم التوضيحية | 800×600 | قسم لقطات الشاشة |
|
| 25 |
+
| `slack-alert.svg` | نموذج تنبيه Slack | 600×400 | قسم لقطات الشاشة |
|
| 26 |
+
| `discord-alert.svg` | نموذج تنبيه Discord | 600×400 | قسم لقطات الشاشة |
|
| 27 |
+
|
| 28 |
+
---
|
| 29 |
+
|
| 30 |
+
## تفاصيل الملفات
|
| 31 |
+
|
| 32 |
+
### banner.svg
|
| 33 |
+
|
| 34 |
+
البانر الرئيسي للمشروع الذي يظهر في أعلى ملف README.md.
|
| 35 |
+
|
| 36 |
+
**المكونات:**
|
| 37 |
+
|
| 38 |
+
- خلفية تدرجية زرقاء داكنة تعكس الطابع الأمني والتقني
|
| 39 |
+
- أيقونة درع أمان في الجانب الأيسر
|
| 40 |
+
- خطوط شبكية خفيفة في الخلفية
|
| 41 |
+
- عنوان المشروع بالعربية والإنجليزية
|
| 42 |
+
- شارات الترخيص والتقنيات المستخدمة
|
| 43 |
+
- رابط المستودع في الأسفل
|
| 44 |
+
|
| 45 |
+
**مواصفات التصميم:**
|
| 46 |
+
|
| 47 |
+
```
|
| 48 |
+
العرض: 1200 بكسل
|
| 49 |
+
الارتفاع: 400 بكسل
|
| 50 |
+
التنسيق: SVG متجهي
|
| 51 |
+
الحجم: ~10 KB
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
### dashboard.svg
|
| 57 |
+
|
| 58 |
+
لوحة تحكم تفاعلية تعرض الحالة الأمنية للنظام.
|
| 59 |
+
|
| 60 |
+
**المكونات:**
|
| 61 |
+
|
| 62 |
+
- رأس مع الشعار والمعلومات
|
| 63 |
+
- أربع بطاقات إحصائية رئيسية
|
| 64 |
+
- التهديدات المحظورة (أحمر)
|
| 65 |
+
- معدل النجاح (أخضر)
|
| 66 |
+
- المشكلات المفتوحة (برتقالي)
|
| 67 |
+
- زمن الاستجابة (أزرق)
|
| 68 |
+
- مخطط دائري لتوزيع المشاكل
|
| 69 |
+
- رسم بياني خطي لنشاط الفحص
|
| 70 |
+
- جدول المشاكل الحديثة
|
| 71 |
+
|
| 72 |
+
**مواصفات التصميم:**
|
| 73 |
+
|
| 74 |
+
```
|
| 75 |
+
العرض: 800 بكسل
|
| 76 |
+
الارتفاع: 600 بكسل
|
| 77 |
+
التنسيق: SVG متجهي
|
| 78 |
+
الحجم: ~25 KB
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
---
|
| 82 |
+
|
| 83 |
+
### slack-alert.svg
|
| 84 |
+
|
| 85 |
+
نموذج لرسالة تنبيه كما تظهر في منصة Slack.
|
| 86 |
+
|
| 87 |
+
**المكونات:**
|
| 88 |
+
|
| 89 |
+
- رأس القناة مع أيقونة #
|
| 90 |
+
- معلومات البوت (Auto-Guardian)
|
| 91 |
+
- صندوق تنبيه باللون الأحمر
|
| 92 |
+
- تفاصيل الهجوم (المصدر، المنفذ، عدد المحاولات)
|
| 93 |
+
- حالة "تم الحظر" باللون الأخضر
|
| 94 |
+
- أزرار التفاعل
|
| 95 |
+
|
| 96 |
+
**مواصفات التصميم:**
|
| 97 |
+
|
| 98 |
+
```
|
| 99 |
+
العرض: 600 بكسل
|
| 100 |
+
الارتفاع: 400 بكسل
|
| 101 |
+
التنسيق: SVG متجهي
|
| 102 |
+
الحجم: ~15 KB
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
### discord-alert.svg
|
| 108 |
+
|
| 109 |
+
نموذج لرسالة إشعار بتنسيق Discord Embed.
|
| 110 |
+
|
| 111 |
+
**المكونات:**
|
| 112 |
+
|
| 113 |
+
- رأس الرسالة مع أيقونة البوت
|
| 114 |
+
- شريط لون الخطورة
|
| 115 |
+
- عنوان ووصف التهديد
|
| 116 |
+
- حقول منظمة للمعلومات
|
| 117 |
+
- طابع زمني
|
| 118 |
+
- أزرار التفاعل
|
| 119 |
+
|
| 120 |
+
**مواصفات التصميم:**
|
| 121 |
+
|
| 122 |
+
```
|
| 123 |
+
العرض: 600 بكسل
|
| 124 |
+
الارتفاع: 400 بكسل
|
| 125 |
+
التنسيق: SVG متجهي
|
| 126 |
+
الحجم: ~15 KB
|
| 127 |
+
```
|
| 128 |
+
|
| 129 |
+
---
|
| 130 |
+
|
| 131 |
+
## لماذا نستخدم SVG؟
|
| 132 |
+
|
| 133 |
+
### مميزات تنسيق SVG
|
| 134 |
+
|
| 135 |
+
**جودة متجاوبة:**
|
| 136 |
+
|
| 137 |
+
ملفات SVG هي ملفات متجهية، مما يعني أنها يمكن تكبيرها إلى أي حجم دون فقدان الجودة. هذا مثالي للشاشات عالية الدقة (Retina) والأجهزة المختلفة.
|
| 138 |
+
|
| 139 |
+
**حجم صغير:**
|
| 140 |
+
|
| 141 |
+
ملفات SVG عادة ما تكون أصغر بكثير من ملفات PNG المكافئة، مما يساعد في سرعة تحميل صفحات الويب وتحسين أداء الموقع.
|
| 142 |
+
|
| 143 |
+
**سهولة التعديل:**
|
| 144 |
+
|
| 145 |
+
يمكن تعديل ألوان ونصوص وأي عنصر في ملف SVG باستخدام أي محرر نصوص بسيط. لا تحتاج لبرنامج تصميم متقدم لإجراء تعديلات بسيطة.
|
| 146 |
+
|
| 147 |
+
**دعم GitHub:**
|
| 148 |
+
|
| 149 |
+
GitHub يعرض ملفات SVG مباشرة في Markdown، مما يعني أنها ستظهر تلقائياً في ملف README.md دون الحاجة لاستضافة خارجية.
|
| 150 |
+
|
| 151 |
+
---
|
| 152 |
+
|
| 153 |
+
## كيفية إضافة صور جديدة
|
| 154 |
+
|
| 155 |
+
### الخطوة 1: إنشاء التصميم
|
| 156 |
+
|
| 157 |
+
يمكنك استخدام أحد البرامج التالية لإنشاء رسومات متجهة:
|
| 158 |
+
|
| 159 |
+
| البرنامج | النوع | السعر |
|
| 160 |
+
|----------|-------|-------|
|
| 161 |
+
| Inkscape | مفتوح المصدر | مجاني |
|
| 162 |
+
| Figma | ويب | مجاني |
|
| 163 |
+
| Canva | ويب | مجاني/مدفوع |
|
| 164 |
+
| Adobe Illustrator | سطح مكتب | مدفوع |
|
| 165 |
+
|
| 166 |
+
### الخطوة 2: التصدير
|
| 167 |
+
|
| 168 |
+
عند تصدير التصميم:
|
| 169 |
+
|
| 170 |
+
1. اختر تنسيق SVG
|
| 171 |
+
2. تأكد من إزالة البيانات الوصفية غير الضرورية
|
| 172 |
+
3. استخدم الإعدادات الموصى بها:
|
| 173 |
+
- عدم تضمين صور نقطية (PNG/JPG)
|
| 174 |
+
- استخدام خطوط قياسية أو تضمين الخطوط
|
| 175 |
+
- الحفاظ على الأبعاد المناسبة
|
| 176 |
+
|
| 177 |
+
### الخطوة 3: التحقق
|
| 178 |
+
|
| 179 |
+
قبل إضافة الملف، تحقق من:
|
| 180 |
+
|
| 181 |
+
- الملف يعمل بشكل صحيح عند فتحه في المتصفح
|
| 182 |
+
- النص قابل للقراءة على الخلفيات المختلفة
|
| 183 |
+
- الأبعاد مناسبة للاستخدام المقصود
|
| 184 |
+
- حجم الملف معقول (أقل من 100 KB)
|
| 185 |
+
|
| 186 |
+
### الخطوة 4: الإضافة
|
| 187 |
+
|
| 188 |
+
لإضافة صورة جديدة:
|
| 189 |
+
|
| 190 |
+
```bash
|
| 191 |
+
# نسخ الصورة إلى مجلد assets
|
| 192 |
+
cp new-image.svg assets/
|
| 193 |
+
|
| 194 |
+
# إضافة إلى Git
|
| 195 |
+
git add assets/new-image.svg
|
| 196 |
+
|
| 197 |
+
# إنشاء التزام
|
| 198 |
+
git commit -m "docs: إضافة صورة توضيحية جديدة"
|
| 199 |
+
|
| 200 |
+
# رفع إلى GitHub
|
| 201 |
+
git push origin main
|
| 202 |
+
```
|
| 203 |
+
|
| 204 |
+
---
|
| 205 |
+
|
| 206 |
+
## معايير التصميم
|
| 207 |
+
|
| 208 |
+
### الألوان المستخدمة
|
| 209 |
+
|
| 210 |
+
| الاستخدام | اللون | الكود |
|
| 211 |
+
|-----------|-------|-------|
|
| 212 |
+
| الرئيسي | أزرق داكن | #1a365d |
|
| 213 |
+
| الثانوية | أزرق متوسط | #2b6cb0 |
|
| 214 |
+
| التأكيد | أزرق فاتح | #4299e1 |
|
| 215 |
+
| الخطورة الحرجة | أحمر | #e01e5a |
|
| 216 |
+
| النجاح | أخضر | #48bb78 |
|
| 217 |
+
| التحذير | برتقالي | #f59e0b |
|
| 218 |
+
| النص الفاتح | أبيض/رمادي فاتح | #ffffff / #d1d5db |
|
| 219 |
+
| النص الغامق | رمادي | #374151 |
|
| 220 |
+
|
| 221 |
+
### الخطوط
|
| 222 |
+
|
| 223 |
+
نستخدم خطوطاً قياسية لضمان التوافق:
|
| 224 |
+
|
| 225 |
+
- **العربية:** Noto Sans Arabic, Arial, Tahoma
|
| 226 |
+
- **الإنجليزية:** Arial, Roboto, Open Sans
|
| 227 |
+
- **الكود:** Monaco, Consolas, Courier New
|
| 228 |
+
|
| 229 |
+
---
|
| 230 |
+
|
| 231 |
+
## نصائح للصيانة
|
| 232 |
+
|
| 233 |
+
### فحص الملفات
|
| 234 |
+
|
| 235 |
+
```bash
|
| 236 |
+
# التحقق من وجود جميع الملفات
|
| 237 |
+
ls -la assets/
|
| 238 |
+
|
| 239 |
+
# التحقق من حجم الملفات
|
| 240 |
+
du -h assets/*
|
| 241 |
+
|
| 242 |
+
# التحقق من صحة SVG
|
| 243 |
+
python3 -c "
|
| 244 |
+
import xml.etree.ElementTree as ET
|
| 245 |
+
for f in ['banner.svg', 'dashboard.svg', 'slack-alert.svg', 'discord-alert.svg']:
|
| 246 |
+
try:
|
| 247 |
+
ET.parse(f'assets/{f}')
|
| 248 |
+
print(f'✓ {f} - صالح')
|
| 249 |
+
except Exception as e:
|
| 250 |
+
print(f'✗ {f} - خطأ: {e}')
|
| 251 |
+
"
|
| 252 |
+
```
|
| 253 |
+
|
| 254 |
+
### ضغط الصور
|
| 255 |
+
|
| 256 |
+
إذا كانت الملفات كبيرة جداً، يمكنك ضغطها:
|
| 257 |
+
|
| 258 |
+
```bash
|
| 259 |
+
# باستخدام svgo (أداة Node.js)
|
| 260 |
+
npx svgo assets/*.svg
|
| 261 |
+
|
| 262 |
+
# أو باستخدام أدوات أخرى متاحة
|
| 263 |
+
```
|
| 264 |
+
|
| 265 |
+
---
|
| 266 |
+
|
| 267 |
+
## الموارد الإضافية
|
| 268 |
+
|
| 269 |
+
### أدوات مفيدة
|
| 270 |
+
|
| 271 |
+
- [SVGOMG](https://jakearchibald.github.io/svgomg/) - ضغط SVG عبر الويب
|
| 272 |
+
- [SVG Preview](https://www.svgviewer.dev/) - عرض SVG عبر الويب
|
| 273 |
+
- [Inkscape](https://inkscape.org/) - محرر SVG مجاني
|
| 274 |
+
- [Boxy SVG](https://boxy-svg.com/) - محرر SVG على الويب
|
| 275 |
+
|
| 276 |
+
### مراجع التصميم
|
| 277 |
+
|
| 278 |
+
- [Material Design Icons](https://fonts.google.com/icons) - أيقونات Material
|
| 279 |
+
- [Font Awesome](https://fontawesome.com/) - أيقونات شاملة
|
| 280 |
+
- [Heroicons](https://heroicons.com/) - أيقونات SVG
|
| 281 |
+
|
| 282 |
+
---
|
| 283 |
+
|
| 284 |
+
## التحديثات
|
| 285 |
+
|
| 286 |
+
| التاريخ | التغيير | بواسطة |
|
| 287 |
+
|---------|---------|--------|
|
| 288 |
+
| 2024-10-13 | إضافة جميع الصور الأولية | AbdulElah Othman |
|
| 289 |
+
|
| 290 |
+
---
|
| 291 |
+
|
| 292 |
+
<div align="center">
|
| 293 |
+
|
| 294 |
+
**صُنع بـ ❤️ بواسطة عبد الإله عثمان غويث**
|
| 295 |
+
|
| 296 |
+
</div>
|
assets/architecture.svg
ADDED
|
|
assets/banner.svg
ADDED
|
|
assets/dashboard.svg
ADDED
|
|
assets/discord-alert.svg
ADDED
|
|
assets/icon-ai.svg
ADDED
|
|
assets/icon-alerts.svg
ADDED
|
|
assets/icon-realtime.svg
ADDED
|
|
assets/icon-scan.svg
ADDED
|
|
assets/logo.svg
ADDED
|
|
assets/slack-alert.svg
ADDED
|
|
assets/video-thumbnail.svg
ADDED
|
|
dashboard/index.html
ADDED
|
@@ -0,0 +1,1696 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ar" dir="rtl">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Auto-Guardian Dashboard</title>
|
| 7 |
+
<style>
|
| 8 |
+
* {
|
| 9 |
+
margin: 0;
|
| 10 |
+
padding: 0;
|
| 11 |
+
box-sizing: border-box;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
:root {
|
| 15 |
+
--primary: #0F172A;
|
| 16 |
+
--secondary: #3B82F6;
|
| 17 |
+
--success: #10B981;
|
| 18 |
+
--danger: #EF4444;
|
| 19 |
+
--warning: #F59E0B;
|
| 20 |
+
--bg: #F8FAFC;
|
| 21 |
+
--card-bg: #FFFFFF;
|
| 22 |
+
--text: #1E293B;
|
| 23 |
+
--text-muted: #64748B;
|
| 24 |
+
--border: #E2E8F0;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
body {
|
| 28 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 29 |
+
background-color: var(--bg);
|
| 30 |
+
color: var(--text);
|
| 31 |
+
min-height: 100vh;
|
| 32 |
+
overflow-x: hidden;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.dashboard {
|
| 36 |
+
display: flex;
|
| 37 |
+
flex-direction: row;
|
| 38 |
+
min-height: 100vh;
|
| 39 |
+
width: 100%;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
/* Sidebar */
|
| 43 |
+
.sidebar {
|
| 44 |
+
background: var(--primary);
|
| 45 |
+
color: white;
|
| 46 |
+
padding: 20px 0;
|
| 47 |
+
width: 240px;
|
| 48 |
+
height: 100vh;
|
| 49 |
+
overflow-y: auto;
|
| 50 |
+
flex-shrink: 0;
|
| 51 |
+
position: sticky;
|
| 52 |
+
top: 0;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.logo {
|
| 56 |
+
padding: 20px;
|
| 57 |
+
text-align: center;
|
| 58 |
+
border-bottom: 1px solid rgba(255,255,255,0.1);
|
| 59 |
+
margin-bottom: 20px;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.logo h1 {
|
| 63 |
+
font-size: 20px;
|
| 64 |
+
font-weight: 700;
|
| 65 |
+
color: var(--secondary);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.logo span {
|
| 69 |
+
font-size: 12px;
|
| 70 |
+
color: var(--text-muted);
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.nav-menu {
|
| 74 |
+
list-style: none;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.nav-item {
|
| 78 |
+
padding: 12px 20px;
|
| 79 |
+
display: flex;
|
| 80 |
+
align-items: center;
|
| 81 |
+
gap: 12px;
|
| 82 |
+
cursor: pointer;
|
| 83 |
+
transition: all 0.3s ease;
|
| 84 |
+
border-right: 3px solid transparent;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.nav-item:hover, .nav-item.active {
|
| 88 |
+
background: rgba(59, 130, 246, 0.1);
|
| 89 |
+
border-right-color: var(--secondary);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.nav-item svg {
|
| 93 |
+
width: 20px;
|
| 94 |
+
height: 20px;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.nav-item span {
|
| 98 |
+
font-size: 14px;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
/* Main Content */
|
| 102 |
+
.main-content {
|
| 103 |
+
flex: 1;
|
| 104 |
+
padding: 20px 30px;
|
| 105 |
+
min-width: 0;
|
| 106 |
+
overflow-x: hidden;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
/* Header */
|
| 110 |
+
.header {
|
| 111 |
+
display: flex;
|
| 112 |
+
justify-content: space-between;
|
| 113 |
+
align-items: center;
|
| 114 |
+
margin-bottom: 30px;
|
| 115 |
+
flex-wrap: wrap;
|
| 116 |
+
gap: 15px;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.header h2 {
|
| 120 |
+
font-size: 24px;
|
| 121 |
+
font-weight: 600;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.header-actions {
|
| 125 |
+
display: flex;
|
| 126 |
+
gap: 12px;
|
| 127 |
+
align-items: center;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.search-box {
|
| 131 |
+
display: flex;
|
| 132 |
+
align-items: center;
|
| 133 |
+
background: var(--card-bg);
|
| 134 |
+
border: 1px solid var(--border);
|
| 135 |
+
border-radius: 8px;
|
| 136 |
+
padding: 8px 16px;
|
| 137 |
+
gap: 8px;
|
| 138 |
+
position: relative;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
.search-box:hover {
|
| 142 |
+
border-color: var(--secondary);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.search-box input {
|
| 146 |
+
border: none;
|
| 147 |
+
outline: none;
|
| 148 |
+
font-size: 14px;
|
| 149 |
+
width: 150px;
|
| 150 |
+
background: transparent;
|
| 151 |
+
flex: 1;
|
| 152 |
+
min-width: 100px;
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
.search-results {
|
| 156 |
+
display: none;
|
| 157 |
+
position: absolute;
|
| 158 |
+
top: 100%;
|
| 159 |
+
left: 0;
|
| 160 |
+
right: 0;
|
| 161 |
+
background: white;
|
| 162 |
+
border: 1px solid var(--border);
|
| 163 |
+
border-radius: 8px;
|
| 164 |
+
margin-top: 8px;
|
| 165 |
+
max-height: 300px;
|
| 166 |
+
overflow-y: auto;
|
| 167 |
+
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
|
| 168 |
+
z-index: 100;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.search-results.active {
|
| 172 |
+
display: block;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
.search-result-item {
|
| 176 |
+
padding: 12px 16px;
|
| 177 |
+
border-bottom: 1px solid var(--border);
|
| 178 |
+
cursor: pointer;
|
| 179 |
+
transition: background 0.3s ease;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.search-result-item:hover {
|
| 183 |
+
background: var(--bg);
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
.search-result-item:last-child {
|
| 187 |
+
border-bottom: none;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
.notification-btn {
|
| 191 |
+
position: relative;
|
| 192 |
+
background: var(--card-bg);
|
| 193 |
+
border: 1px solid var(--border);
|
| 194 |
+
border-radius: 8px;
|
| 195 |
+
padding: 8px 12px;
|
| 196 |
+
cursor: pointer;
|
| 197 |
+
transition: all 0.3s ease;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.notification-btn:hover {
|
| 201 |
+
border-color: var(--secondary);
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
.notification-badge {
|
| 205 |
+
position: absolute;
|
| 206 |
+
top: -5px;
|
| 207 |
+
right: -5px;
|
| 208 |
+
background: var(--danger);
|
| 209 |
+
color: white;
|
| 210 |
+
font-size: 10px;
|
| 211 |
+
padding: 2px 6px;
|
| 212 |
+
border-radius: 10px;
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
/* Settings Panel */
|
| 216 |
+
.settings-panel {
|
| 217 |
+
display: none;
|
| 218 |
+
position: fixed;
|
| 219 |
+
top: 0;
|
| 220 |
+
left: 0;
|
| 221 |
+
width: 100%;
|
| 222 |
+
height: 100%;
|
| 223 |
+
background: rgba(0,0,0,0.5);
|
| 224 |
+
z-index: 1000;
|
| 225 |
+
justify-content: center;
|
| 226 |
+
align-items: center;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.settings-panel.active {
|
| 230 |
+
display: flex;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
.settings-content {
|
| 234 |
+
background: white;
|
| 235 |
+
border-radius: 16px;
|
| 236 |
+
padding: 30px;
|
| 237 |
+
width: 90%;
|
| 238 |
+
max-width: 500px;
|
| 239 |
+
max-height: 80vh;
|
| 240 |
+
overflow-y: auto;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
.settings-header {
|
| 244 |
+
display: flex;
|
| 245 |
+
justify-content: space-between;
|
| 246 |
+
align-items: center;
|
| 247 |
+
margin-bottom: 24px;
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
.settings-header h3 {
|
| 251 |
+
font-size: 20px;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
.close-btn {
|
| 255 |
+
background: none;
|
| 256 |
+
border: none;
|
| 257 |
+
font-size: 24px;
|
| 258 |
+
cursor: pointer;
|
| 259 |
+
color: var(--text-muted);
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
.setting-item {
|
| 263 |
+
margin-bottom: 20px;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
.setting-label {
|
| 267 |
+
display: block;
|
| 268 |
+
font-size: 14px;
|
| 269 |
+
font-weight: 500;
|
| 270 |
+
margin-bottom: 8px;
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
.setting-description {
|
| 274 |
+
font-size: 12px;
|
| 275 |
+
color: var(--text-muted);
|
| 276 |
+
margin-bottom: 8px;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
.setting-input {
|
| 280 |
+
width: 100%;
|
| 281 |
+
padding: 10px 14px;
|
| 282 |
+
border: 1px solid var(--border);
|
| 283 |
+
border-radius: 8px;
|
| 284 |
+
font-size: 14px;
|
| 285 |
+
transition: all 0.3s ease;
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
.setting-input:focus {
|
| 289 |
+
outline: none;
|
| 290 |
+
border-color: var(--secondary);
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
.setting-select {
|
| 294 |
+
width: 100%;
|
| 295 |
+
padding: 10px 14px;
|
| 296 |
+
border: 1px solid var(--border);
|
| 297 |
+
border-radius: 8px;
|
| 298 |
+
font-size: 14px;
|
| 299 |
+
background: white;
|
| 300 |
+
cursor: pointer;
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
.setting-toggle {
|
| 304 |
+
display: flex;
|
| 305 |
+
align-items: center;
|
| 306 |
+
gap: 12px;
|
| 307 |
+
cursor: pointer;
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
.toggle-switch {
|
| 311 |
+
position: relative;
|
| 312 |
+
width: 50px;
|
| 313 |
+
height: 26px;
|
| 314 |
+
background: var(--border);
|
| 315 |
+
border-radius: 13px;
|
| 316 |
+
transition: all 0.3s ease;
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
.toggle-switch.active {
|
| 320 |
+
background: var(--secondary);
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
.toggle-switch::after {
|
| 324 |
+
content: '';
|
| 325 |
+
position: absolute;
|
| 326 |
+
width: 22px;
|
| 327 |
+
height: 22px;
|
| 328 |
+
background: white;
|
| 329 |
+
border-radius: 50%;
|
| 330 |
+
top: 2px;
|
| 331 |
+
left: 2px;
|
| 332 |
+
transition: all 0.3s ease;
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
.toggle-switch.active::after {
|
| 336 |
+
left: 26px;
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
.save-btn {
|
| 340 |
+
width: 100%;
|
| 341 |
+
padding: 12px;
|
| 342 |
+
background: var(--secondary);
|
| 343 |
+
color: white;
|
| 344 |
+
border: none;
|
| 345 |
+
border-radius: 8px;
|
| 346 |
+
font-size: 14px;
|
| 347 |
+
font-weight: 500;
|
| 348 |
+
cursor: pointer;
|
| 349 |
+
transition: all 0.3s ease;
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
.save-btn:hover {
|
| 353 |
+
background: var(--primary);
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
/* Stats Grid */
|
| 357 |
+
.stats-grid {
|
| 358 |
+
display: grid;
|
| 359 |
+
grid-template-columns: repeat(4, 1fr);
|
| 360 |
+
gap: 20px;
|
| 361 |
+
margin-bottom: 30px;
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
.stat-card {
|
| 365 |
+
background: var(--card-bg);
|
| 366 |
+
border-radius: 12px;
|
| 367 |
+
padding: 20px;
|
| 368 |
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
| 369 |
+
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
| 370 |
+
cursor: pointer;
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
.stat-card:hover {
|
| 374 |
+
transform: translateY(-2px);
|
| 375 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
.stat-header {
|
| 379 |
+
display: flex;
|
| 380 |
+
justify-content: space-between;
|
| 381 |
+
align-items: flex-start;
|
| 382 |
+
margin-bottom: 12px;
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
.stat-icon {
|
| 386 |
+
width: 40px;
|
| 387 |
+
height: 40px;
|
| 388 |
+
border-radius: 10px;
|
| 389 |
+
display: flex;
|
| 390 |
+
align-items: center;
|
| 391 |
+
justify-content: center;
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
.stat-icon.blue { background: rgba(59, 130, 246, 0.1); color: var(--secondary); }
|
| 395 |
+
.stat-icon.green { background: rgba(16, 185, 129, 0.1); color: var(--success); }
|
| 396 |
+
.stat-icon.red { background: rgba(239, 68, 68, 0.1); color: var(--danger); }
|
| 397 |
+
.stat-icon.yellow { background: rgba(245, 158, 11, 0.1); color: var(--warning); }
|
| 398 |
+
|
| 399 |
+
.stat-trend {
|
| 400 |
+
font-size: 12px;
|
| 401 |
+
display: flex;
|
| 402 |
+
align-items: center;
|
| 403 |
+
gap: 4px;
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
.stat-trend.up { color: var(--success); }
|
| 407 |
+
.stat-trend.down { color: var(--danger); }
|
| 408 |
+
|
| 409 |
+
.stat-value {
|
| 410 |
+
font-size: 28px;
|
| 411 |
+
font-weight: 700;
|
| 412 |
+
margin-bottom: 4px;
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
.stat-label {
|
| 416 |
+
font-size: 13px;
|
| 417 |
+
color: var(--text-muted);
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
/* Charts Section */
|
| 421 |
+
.charts-section {
|
| 422 |
+
display: grid;
|
| 423 |
+
grid-template-columns: 2fr 1fr;
|
| 424 |
+
gap: 20px;
|
| 425 |
+
margin-bottom: 30px;
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
.chart-card {
|
| 429 |
+
background: var(--card-bg);
|
| 430 |
+
border-radius: 12px;
|
| 431 |
+
padding: 20px;
|
| 432 |
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
.chart-header {
|
| 436 |
+
display: flex;
|
| 437 |
+
justify-content: space-between;
|
| 438 |
+
align-items: center;
|
| 439 |
+
margin-bottom: 20px;
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
.chart-title {
|
| 443 |
+
font-size: 16px;
|
| 444 |
+
font-weight: 600;
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
.chart-tabs {
|
| 448 |
+
display: flex;
|
| 449 |
+
gap: 8px;
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
.chart-tab {
|
| 453 |
+
padding: 6px 12px;
|
| 454 |
+
border-radius: 6px;
|
| 455 |
+
font-size: 12px;
|
| 456 |
+
cursor: pointer;
|
| 457 |
+
background: var(--bg);
|
| 458 |
+
border: none;
|
| 459 |
+
transition: all 0.3s ease;
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
.chart-tab.active {
|
| 463 |
+
background: var(--secondary);
|
| 464 |
+
color: white;
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
.chart-tab:hover:not(.active) {
|
| 468 |
+
background: var(--border);
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
/* Area Chart */
|
| 472 |
+
.area-chart {
|
| 473 |
+
height: 250px;
|
| 474 |
+
position: relative;
|
| 475 |
+
}
|
| 476 |
+
|
| 477 |
+
.chart-svg {
|
| 478 |
+
width: 100%;
|
| 479 |
+
height: 100%;
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
/* Donut Chart */
|
| 483 |
+
.donut-chart {
|
| 484 |
+
display: flex;
|
| 485 |
+
align-items: center;
|
| 486 |
+
justify-content: center;
|
| 487 |
+
gap: 30px;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
.donut-svg {
|
| 491 |
+
width: 180px;
|
| 492 |
+
height: 180px;
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
.donut-legend {
|
| 496 |
+
display: flex;
|
| 497 |
+
flex-direction: column;
|
| 498 |
+
gap: 12px;
|
| 499 |
+
}
|
| 500 |
+
|
| 501 |
+
.legend-item {
|
| 502 |
+
display: flex;
|
| 503 |
+
align-items: center;
|
| 504 |
+
gap: 8px;
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
+
.legend-color {
|
| 508 |
+
width: 12px;
|
| 509 |
+
height: 12px;
|
| 510 |
+
border-radius: 3px;
|
| 511 |
+
}
|
| 512 |
+
|
| 513 |
+
.legend-label {
|
| 514 |
+
font-size: 13px;
|
| 515 |
+
color: var(--text-muted);
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
.legend-value {
|
| 519 |
+
font-size: 14px;
|
| 520 |
+
font-weight: 600;
|
| 521 |
+
margin-right: auto;
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
/* Activity Section */
|
| 525 |
+
.activity-section {
|
| 526 |
+
display: grid;
|
| 527 |
+
grid-template-columns: 1fr 1fr;
|
| 528 |
+
gap: 20px;
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
.activity-card {
|
| 532 |
+
background: var(--card-bg);
|
| 533 |
+
border-radius: 12px;
|
| 534 |
+
padding: 20px;
|
| 535 |
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
| 536 |
+
}
|
| 537 |
+
|
| 538 |
+
.activity-header {
|
| 539 |
+
display: flex;
|
| 540 |
+
justify-content: space-between;
|
| 541 |
+
align-items: center;
|
| 542 |
+
margin-bottom: 16px;
|
| 543 |
+
}
|
| 544 |
+
|
| 545 |
+
.activity-title {
|
| 546 |
+
font-size: 16px;
|
| 547 |
+
font-weight: 600;
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
.view-all {
|
| 551 |
+
font-size: 13px;
|
| 552 |
+
color: var(--secondary);
|
| 553 |
+
cursor: pointer;
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
.view-all:hover {
|
| 557 |
+
text-decoration: underline;
|
| 558 |
+
}
|
| 559 |
+
|
| 560 |
+
/* Issues List */
|
| 561 |
+
.issues-list {
|
| 562 |
+
display: flex;
|
| 563 |
+
flex-direction: column;
|
| 564 |
+
gap: 12px;
|
| 565 |
+
}
|
| 566 |
+
|
| 567 |
+
.issue-item {
|
| 568 |
+
display: flex;
|
| 569 |
+
align-items: center;
|
| 570 |
+
gap: 12px;
|
| 571 |
+
padding: 12px;
|
| 572 |
+
background: var(--bg);
|
| 573 |
+
border-radius: 8px;
|
| 574 |
+
transition: all 0.3s ease;
|
| 575 |
+
cursor: pointer;
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
.issue-item:hover {
|
| 579 |
+
background: rgba(59, 130, 246, 0.05);
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
.issue-icon {
|
| 583 |
+
width: 32px;
|
| 584 |
+
height: 32px;
|
| 585 |
+
border-radius: 8px;
|
| 586 |
+
display: flex;
|
| 587 |
+
align-items: center;
|
| 588 |
+
justify-content: center;
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
.issue-content {
|
| 592 |
+
flex: 1;
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
.issue-title {
|
| 596 |
+
font-size: 13px;
|
| 597 |
+
font-weight: 500;
|
| 598 |
+
margin-bottom: 2px;
|
| 599 |
+
}
|
| 600 |
+
|
| 601 |
+
.issue-meta {
|
| 602 |
+
font-size: 11px;
|
| 603 |
+
color: var(--text-muted);
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
.issue-badge {
|
| 607 |
+
padding: 4px 10px;
|
| 608 |
+
border-radius: 20px;
|
| 609 |
+
font-size: 11px;
|
| 610 |
+
font-weight: 500;
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
.badge-critical { background: rgba(239, 68, 68, 0.1); color: var(--danger); }
|
| 614 |
+
.badge-warning { background: rgba(245, 158, 11, 0.1); color: var(--warning); }
|
| 615 |
+
.badge-info { background: rgba(59, 130, 246, 0.1); color: var(--secondary); }
|
| 616 |
+
.badge-success { background: rgba(16, 185, 129, 0.1); color: var(--success); }
|
| 617 |
+
|
| 618 |
+
/* Repositories List */
|
| 619 |
+
.repos-list {
|
| 620 |
+
display: flex;
|
| 621 |
+
flex-direction: column;
|
| 622 |
+
gap: 12px;
|
| 623 |
+
}
|
| 624 |
+
|
| 625 |
+
.repo-item {
|
| 626 |
+
display: flex;
|
| 627 |
+
align-items: center;
|
| 628 |
+
gap: 12px;
|
| 629 |
+
padding: 12px;
|
| 630 |
+
background: var(--bg);
|
| 631 |
+
border-radius: 8px;
|
| 632 |
+
transition: all 0.3s ease;
|
| 633 |
+
cursor: pointer;
|
| 634 |
+
}
|
| 635 |
+
|
| 636 |
+
.repo-item:hover {
|
| 637 |
+
background: rgba(59, 130, 246, 0.05);
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
.repo-icon {
|
| 641 |
+
width: 36px;
|
| 642 |
+
height: 36px;
|
| 643 |
+
border-radius: 8px;
|
| 644 |
+
background: var(--primary);
|
| 645 |
+
display: flex;
|
| 646 |
+
align-items: center;
|
| 647 |
+
justify-content: center;
|
| 648 |
+
color: white;
|
| 649 |
+
}
|
| 650 |
+
|
| 651 |
+
.repo-content {
|
| 652 |
+
flex: 1;
|
| 653 |
+
}
|
| 654 |
+
|
| 655 |
+
.repo-name {
|
| 656 |
+
font-size: 13px;
|
| 657 |
+
font-weight: 500;
|
| 658 |
+
margin-bottom: 2px;
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
.repo-stats {
|
| 662 |
+
display: flex;
|
| 663 |
+
gap: 12px;
|
| 664 |
+
font-size: 11px;
|
| 665 |
+
color: var(--text-muted);
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
.repo-status {
|
| 669 |
+
display: flex;
|
| 670 |
+
align-items: center;
|
| 671 |
+
gap: 4px;
|
| 672 |
+
font-size: 12px;
|
| 673 |
+
}
|
| 674 |
+
|
| 675 |
+
.status-dot {
|
| 676 |
+
width: 8px;
|
| 677 |
+
height: 8px;
|
| 678 |
+
border-radius: 50%;
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
.status-dot.active { background: var(--success); }
|
| 682 |
+
.status-dot.warning { background: var(--warning); }
|
| 683 |
+
.status-dot.error { background: var(--danger); }
|
| 684 |
+
|
| 685 |
+
/* Toast Notifications */
|
| 686 |
+
.toast-container {
|
| 687 |
+
position: fixed;
|
| 688 |
+
top: 20px;
|
| 689 |
+
left: 50%;
|
| 690 |
+
transform: translateX(-50%);
|
| 691 |
+
z-index: 2000;
|
| 692 |
+
display: flex;
|
| 693 |
+
flex-direction: column;
|
| 694 |
+
gap: 10px;
|
| 695 |
+
}
|
| 696 |
+
|
| 697 |
+
.toast {
|
| 698 |
+
padding: 14px 20px;
|
| 699 |
+
background: var(--primary);
|
| 700 |
+
color: white;
|
| 701 |
+
border-radius: 10px;
|
| 702 |
+
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
|
| 703 |
+
display: flex;
|
| 704 |
+
align-items: center;
|
| 705 |
+
gap: 10px;
|
| 706 |
+
animation: slideIn 0.3s ease, fadeOut 0.3s ease 2.7s;
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
.toast.success { background: var(--success); }
|
| 710 |
+
.toast.error { background: var(--danger); }
|
| 711 |
+
.toast.warning { background: var(--warning); }
|
| 712 |
+
.toast.info { background: var(--secondary); }
|
| 713 |
+
|
| 714 |
+
@keyframes slideIn {
|
| 715 |
+
from { transform: translateY(-20px); opacity: 0; }
|
| 716 |
+
to { transform: translateY(0); opacity: 1; }
|
| 717 |
+
}
|
| 718 |
+
|
| 719 |
+
@keyframes fadeOut {
|
| 720 |
+
from { opacity: 1; }
|
| 721 |
+
to { opacity: 0; }
|
| 722 |
+
}
|
| 723 |
+
|
| 724 |
+
/* Responsive */
|
| 725 |
+
@media (max-width: 1200px) {
|
| 726 |
+
.stats-grid {
|
| 727 |
+
grid-template-columns: repeat(2, 1fr);
|
| 728 |
+
}
|
| 729 |
+
.charts-section {
|
| 730 |
+
grid-template-columns: 1fr;
|
| 731 |
+
}
|
| 732 |
+
.activity-section {
|
| 733 |
+
grid-template-columns: 1fr;
|
| 734 |
+
}
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
@media (max-width: 992px) {
|
| 738 |
+
.sidebar {
|
| 739 |
+
position: fixed;
|
| 740 |
+
right: -240px;
|
| 741 |
+
top: 0;
|
| 742 |
+
z-index: 1000;
|
| 743 |
+
transition: right 0.3s ease;
|
| 744 |
+
box-shadow: -4px 0 20px rgba(0,0,0,0.1);
|
| 745 |
+
}
|
| 746 |
+
|
| 747 |
+
.sidebar.active {
|
| 748 |
+
right: 0;
|
| 749 |
+
}
|
| 750 |
+
|
| 751 |
+
.sidebar-overlay {
|
| 752 |
+
display: none;
|
| 753 |
+
position: fixed;
|
| 754 |
+
top: 0;
|
| 755 |
+
left: 0;
|
| 756 |
+
width: 100%;
|
| 757 |
+
height: 100%;
|
| 758 |
+
background: rgba(0,0,0,0.5);
|
| 759 |
+
z-index: 999;
|
| 760 |
+
}
|
| 761 |
+
|
| 762 |
+
.sidebar-overlay.active {
|
| 763 |
+
display: block;
|
| 764 |
+
}
|
| 765 |
+
|
| 766 |
+
.main-content {
|
| 767 |
+
width: 100%;
|
| 768 |
+
padding: 15px 20px;
|
| 769 |
+
}
|
| 770 |
+
|
| 771 |
+
.mobile-menu-btn {
|
| 772 |
+
display: flex !important;
|
| 773 |
+
}
|
| 774 |
+
|
| 775 |
+
.header-actions {
|
| 776 |
+
gap: 8px;
|
| 777 |
+
}
|
| 778 |
+
|
| 779 |
+
.search-box {
|
| 780 |
+
min-width: 120px;
|
| 781 |
+
}
|
| 782 |
+
|
| 783 |
+
.search-box input {
|
| 784 |
+
width: 80px;
|
| 785 |
+
}
|
| 786 |
+
}
|
| 787 |
+
|
| 788 |
+
@media (max-width: 768px) {
|
| 789 |
+
.dashboard {
|
| 790 |
+
flex-direction: column;
|
| 791 |
+
}
|
| 792 |
+
|
| 793 |
+
.stats-grid {
|
| 794 |
+
grid-template-columns: 1fr;
|
| 795 |
+
gap: 12px;
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
.stat-card {
|
| 799 |
+
padding: 15px;
|
| 800 |
+
display: flex;
|
| 801 |
+
align-items: center;
|
| 802 |
+
justify-content: space-between;
|
| 803 |
+
flex-wrap: wrap;
|
| 804 |
+
}
|
| 805 |
+
|
| 806 |
+
.stat-header {
|
| 807 |
+
margin-bottom: 0;
|
| 808 |
+
width: auto;
|
| 809 |
+
}
|
| 810 |
+
|
| 811 |
+
.stat-value {
|
| 812 |
+
font-size: 24px;
|
| 813 |
+
text-align: left;
|
| 814 |
+
}
|
| 815 |
+
|
| 816 |
+
.stat-label {
|
| 817 |
+
text-align: left;
|
| 818 |
+
width: 100%;
|
| 819 |
+
}
|
| 820 |
+
|
| 821 |
+
.charts-section {
|
| 822 |
+
gap: 15px;
|
| 823 |
+
margin-bottom: 20px;
|
| 824 |
+
}
|
| 825 |
+
|
| 826 |
+
.chart-card {
|
| 827 |
+
padding: 15px;
|
| 828 |
+
}
|
| 829 |
+
|
| 830 |
+
.area-chart {
|
| 831 |
+
height: 200px;
|
| 832 |
+
}
|
| 833 |
+
|
| 834 |
+
.donut-chart {
|
| 835 |
+
flex-direction: column;
|
| 836 |
+
gap: 15px;
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
.donut-svg {
|
| 840 |
+
width: 150px;
|
| 841 |
+
height: 150px;
|
| 842 |
+
}
|
| 843 |
+
|
| 844 |
+
.activity-section {
|
| 845 |
+
gap: 15px;
|
| 846 |
+
}
|
| 847 |
+
|
| 848 |
+
.activity-card {
|
| 849 |
+
padding: 15px;
|
| 850 |
+
}
|
| 851 |
+
|
| 852 |
+
.header {
|
| 853 |
+
margin-bottom: 20px;
|
| 854 |
+
}
|
| 855 |
+
|
| 856 |
+
.header h2 {
|
| 857 |
+
font-size: 20px;
|
| 858 |
+
width: 100%;
|
| 859 |
+
}
|
| 860 |
+
|
| 861 |
+
.header-actions {
|
| 862 |
+
width: 100%;
|
| 863 |
+
justify-content: space-between;
|
| 864 |
+
}
|
| 865 |
+
|
| 866 |
+
.search-box {
|
| 867 |
+
flex: 1;
|
| 868 |
+
min-width: 0;
|
| 869 |
+
}
|
| 870 |
+
|
| 871 |
+
.search-box input {
|
| 872 |
+
width: 100%;
|
| 873 |
+
}
|
| 874 |
+
|
| 875 |
+
.notification-btn {
|
| 876 |
+
padding: 8px;
|
| 877 |
+
}
|
| 878 |
+
}
|
| 879 |
+
|
| 880 |
+
@media (max-width: 480px) {
|
| 881 |
+
.stat-card {
|
| 882 |
+
padding: 12px;
|
| 883 |
+
}
|
| 884 |
+
|
| 885 |
+
.stat-icon {
|
| 886 |
+
width: 36px;
|
| 887 |
+
height: 36px;
|
| 888 |
+
}
|
| 889 |
+
|
| 890 |
+
.stat-value {
|
| 891 |
+
font-size: 20px;
|
| 892 |
+
}
|
| 893 |
+
|
| 894 |
+
.stat-label {
|
| 895 |
+
font-size: 12px;
|
| 896 |
+
}
|
| 897 |
+
|
| 898 |
+
.chart-title {
|
| 899 |
+
font-size: 14px;
|
| 900 |
+
}
|
| 901 |
+
|
| 902 |
+
.chart-tabs {
|
| 903 |
+
gap: 4px;
|
| 904 |
+
}
|
| 905 |
+
|
| 906 |
+
.chart-tab {
|
| 907 |
+
padding: 4px 8px;
|
| 908 |
+
font-size: 11px;
|
| 909 |
+
}
|
| 910 |
+
|
| 911 |
+
.issue-item, .repo-item {
|
| 912 |
+
padding: 10px;
|
| 913 |
+
}
|
| 914 |
+
|
| 915 |
+
.issue-icon {
|
| 916 |
+
width: 28px;
|
| 917 |
+
height: 28px;
|
| 918 |
+
}
|
| 919 |
+
|
| 920 |
+
.issue-title {
|
| 921 |
+
font-size: 12px;
|
| 922 |
+
}
|
| 923 |
+
|
| 924 |
+
.issue-meta {
|
| 925 |
+
font-size: 10px;
|
| 926 |
+
}
|
| 927 |
+
}
|
| 928 |
+
|
| 929 |
+
/* Mobile Menu Button */
|
| 930 |
+
.mobile-menu-btn {
|
| 931 |
+
display: none;
|
| 932 |
+
position: fixed;
|
| 933 |
+
bottom: 20px;
|
| 934 |
+
left: 20px;
|
| 935 |
+
width: 50px;
|
| 936 |
+
height: 50px;
|
| 937 |
+
border-radius: 50%;
|
| 938 |
+
background: var(--secondary);
|
| 939 |
+
color: white;
|
| 940 |
+
border: none;
|
| 941 |
+
cursor: pointer;
|
| 942 |
+
z-index: 1001;
|
| 943 |
+
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4);
|
| 944 |
+
align-items: center;
|
| 945 |
+
justify-content: center;
|
| 946 |
+
transition: all 0.3s ease;
|
| 947 |
+
}
|
| 948 |
+
|
| 949 |
+
.mobile-menu-btn:hover {
|
| 950 |
+
transform: scale(1.1);
|
| 951 |
+
background: var(--primary);
|
| 952 |
+
}
|
| 953 |
+
|
| 954 |
+
.mobile-menu-btn svg {
|
| 955 |
+
width: 24px;
|
| 956 |
+
height: 24px;
|
| 957 |
+
}
|
| 958 |
+
|
| 959 |
+
/* Sidebar Overlay */
|
| 960 |
+
.sidebar-overlay {
|
| 961 |
+
display: none;
|
| 962 |
+
}
|
| 963 |
+
</style>
|
| 964 |
+
</head>
|
| 965 |
+
<body>
|
| 966 |
+
<div class="dashboard">
|
| 967 |
+
<!-- Sidebar Overlay -->
|
| 968 |
+
<div class="sidebar-overlay" id="sidebarOverlay" onclick="toggleMobileMenu()"></div>
|
| 969 |
+
|
| 970 |
+
<!-- Sidebar -->
|
| 971 |
+
<aside class="sidebar" id="sidebar">
|
| 972 |
+
<div class="logo">
|
| 973 |
+
<h1>Auto-Guardian</h1>
|
| 974 |
+
<span>Security Dashboard</span>
|
| 975 |
+
</div>
|
| 976 |
+
<ul class="nav-menu">
|
| 977 |
+
<li class="nav-item active" data-view="dashboard">
|
| 978 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 979 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/>
|
| 980 |
+
</svg>
|
| 981 |
+
<span>لوحة التحكم</span>
|
| 982 |
+
</li>
|
| 983 |
+
<li class="nav-item" data-view="protection">
|
| 984 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 985 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
|
| 986 |
+
</svg>
|
| 987 |
+
<span>الحماية</span>
|
| 988 |
+
</li>
|
| 989 |
+
<li class="nav-item" data-view="analysis">
|
| 990 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 991 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"/>
|
| 992 |
+
</svg>
|
| 993 |
+
<span>الفحص والتحليل</span>
|
| 994 |
+
</li>
|
| 995 |
+
<li class="nav-item" data-view="reports">
|
| 996 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 997 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
| 998 |
+
</svg>
|
| 999 |
+
<span>التقارير</span>
|
| 1000 |
+
</li>
|
| 1001 |
+
<li class="nav-item" data-view="settings" id="settingsNavItem">
|
| 1002 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1003 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
| 1004 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
| 1005 |
+
</svg>
|
| 1006 |
+
<span>الإعدادات</span>
|
| 1007 |
+
</li>
|
| 1008 |
+
<li class="nav-item" data-view="help">
|
| 1009 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1010 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 1011 |
+
</svg>
|
| 1012 |
+
<span>المساعدة</span>
|
| 1013 |
+
</li>
|
| 1014 |
+
</ul>
|
| 1015 |
+
</aside>
|
| 1016 |
+
|
| 1017 |
+
<!-- Mobile Menu Button -->
|
| 1018 |
+
<button class="mobile-menu-btn" id="mobileMenuBtn" onclick="toggleMobileMenu()">
|
| 1019 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1020 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
| 1021 |
+
</svg>
|
| 1022 |
+
</button>
|
| 1023 |
+
|
| 1024 |
+
<!-- Main Content -->
|
| 1025 |
+
<main class="main-content">
|
| 1026 |
+
<!-- Header -->
|
| 1027 |
+
<header class="header">
|
| 1028 |
+
<h2>لوحة تحكم Auto-Guardian</h2>
|
| 1029 |
+
<div class="header-actions">
|
| 1030 |
+
<div class="search-box" id="searchBox">
|
| 1031 |
+
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1032 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
| 1033 |
+
</svg>
|
| 1034 |
+
<input type="text" placeholder="بحث..." id="searchInput">
|
| 1035 |
+
<div class="search-results" id="searchResults"></div>
|
| 1036 |
+
</div>
|
| 1037 |
+
<button class="notification-btn" id="notificationBtn">
|
| 1038 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1039 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
| 1040 |
+
</svg>
|
| 1041 |
+
<span class="notification-badge" id="notificationBadge">5</span>
|
| 1042 |
+
</button>
|
| 1043 |
+
</div>
|
| 1044 |
+
</header>
|
| 1045 |
+
|
| 1046 |
+
<!-- Stats Grid -->
|
| 1047 |
+
<div class="stats-grid">
|
| 1048 |
+
<div class="stat-card" onclick="filterIssues('critical')">
|
| 1049 |
+
<div class="stat-header">
|
| 1050 |
+
<div class="stat-icon blue">
|
| 1051 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1052 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
|
| 1053 |
+
</svg>
|
| 1054 |
+
</div>
|
| 1055 |
+
<span class="stat-trend up" id="trendCritical">↑ 12%</span>
|
| 1056 |
+
</div>
|
| 1057 |
+
<div class="stat-value" id="statThreats">1,247</div>
|
| 1058 |
+
<div class="stat-label">التهديدات المحظورة</div>
|
| 1059 |
+
</div>
|
| 1060 |
+
|
| 1061 |
+
<div class="stat-card">
|
| 1062 |
+
<div class="stat-header">
|
| 1063 |
+
<div class="stat-icon green">
|
| 1064 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1065 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 1066 |
+
</svg>
|
| 1067 |
+
</div>
|
| 1068 |
+
<span class="stat-trend up" id="trendSuccess">↑ 8%</span>
|
| 1069 |
+
</div>
|
| 1070 |
+
<div class="stat-value" id="statSuccess">99.9%</div>
|
| 1071 |
+
<div class="stat-label">معدل النجاح</div>
|
| 1072 |
+
</div>
|
| 1073 |
+
|
| 1074 |
+
<div class="stat-card" onclick="filterIssues('open')">
|
| 1075 |
+
<div class="stat-header">
|
| 1076 |
+
<div class="stat-icon red">
|
| 1077 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1078 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 1079 |
+
</svg>
|
| 1080 |
+
</div>
|
| 1081 |
+
<span class="stat-trend down" id="trendOpen">↓ 3%</span>
|
| 1082 |
+
</div>
|
| 1083 |
+
<div class="stat-value" id="statOpen">23</div>
|
| 1084 |
+
<div class="stat-label">المشكلات المفتوحة</div>
|
| 1085 |
+
</div>
|
| 1086 |
+
|
| 1087 |
+
<div class="stat-card">
|
| 1088 |
+
<div class="stat-header">
|
| 1089 |
+
<div class="stat-icon yellow">
|
| 1090 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1091 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
| 1092 |
+
</svg>
|
| 1093 |
+
</div>
|
| 1094 |
+
<span class="stat-trend up" id="trendResponse">↑ 15%</span>
|
| 1095 |
+
</div>
|
| 1096 |
+
<div class="stat-value" id="statResponse">0.3s</div>
|
| 1097 |
+
<div class="stat-label">زمن الاستجابة</div>
|
| 1098 |
+
</div>
|
| 1099 |
+
</div>
|
| 1100 |
+
|
| 1101 |
+
<!-- Charts Section -->
|
| 1102 |
+
<div class="charts-section">
|
| 1103 |
+
<div class="chart-card">
|
| 1104 |
+
<div class="chart-header">
|
| 1105 |
+
<h3 class="chart-title">نشاط الفحص والأمان</h3>
|
| 1106 |
+
<div class="chart-tabs">
|
| 1107 |
+
<button class="chart-tab" data-period="day" onclick="changePeriod('day')">24 ساعة</button>
|
| 1108 |
+
<button class="chart-tab active" data-period="week" onclick="changePeriod('week')">أسبوع</button>
|
| 1109 |
+
<button class="chart-tab" data-period="month" onclick="changePeriod('month')">شهر</button>
|
| 1110 |
+
</div>
|
| 1111 |
+
</div>
|
| 1112 |
+
<div class="area-chart">
|
| 1113 |
+
<svg class="chart-svg" viewBox="0 0 800 250" id="mainChart">
|
| 1114 |
+
<!-- Grid lines -->
|
| 1115 |
+
<line x1="50" y1="30" x2="750" y2="30" stroke="#E2E8F0" stroke-width="1"/>
|
| 1116 |
+
<line x1="50" y1="80" x2="750" y2="80" stroke="#E2E8F0" stroke-width="1"/>
|
| 1117 |
+
<line x1="50" y1="130" x2="750" y2="130" stroke="#E2E8F0" stroke-width="1"/>
|
| 1118 |
+
<line x1="50" y1="180" x2="750" y2="180" stroke="#E2E8F0" stroke-width="1"/>
|
| 1119 |
+
|
| 1120 |
+
<!-- Area gradient -->
|
| 1121 |
+
<defs>
|
| 1122 |
+
<linearGradient id="areaGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
| 1123 |
+
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.3"/>
|
| 1124 |
+
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0.05"/>
|
| 1125 |
+
</linearGradient>
|
| 1126 |
+
</defs>
|
| 1127 |
+
|
| 1128 |
+
<!-- Area path -->
|
| 1129 |
+
<path d="M50,180 L100,150 L150,160 L200,120 L250,140 L300,100 L350,110 L400,70 L450,90 L500,60 L550,80 L600,50 L650,65 L700,40 L750,55 L750,180 Z" fill="url(#areaGradient)"/>
|
| 1130 |
+
|
| 1131 |
+
<!-- Line -->
|
| 1132 |
+
<path d="M50,180 L100,150 L150,160 L200,120 L250,140 L300,100 L350,110 L400,70 L450,90 L500,60 L550,80 L600,50 L650,65 L700,40 L750,55" fill="none" stroke="#3B82F6" stroke-width="3" stroke-linecap="round"/>
|
| 1133 |
+
|
| 1134 |
+
<!-- Data points -->
|
| 1135 |
+
<circle cx="100" cy="150" r="5" fill="#3B82F6" class="chart-point" data-value="45"/>
|
| 1136 |
+
<circle cx="200" cy="120" r="5" fill="#3B82F6" class="chart-point" data-value="60"/>
|
| 1137 |
+
<circle cx="300" cy="100" r="5" fill="#3B82F6" class="chart-point" data-value="70"/>
|
| 1138 |
+
<circle cx="400" cy="70" r="5" fill="#3B82F6" class="chart-point" data-value="85"/>
|
| 1139 |
+
<circle cx="500" cy="60" r="5" fill="#3B82F6" class="chart-point" data-value="90"/>
|
| 1140 |
+
<circle cx="600" cy="50" r="5" fill="#3B82F6" class="chart-point" data-value="95"/>
|
| 1141 |
+
<circle cx="700" cy="40" r="5" fill="#3B82F6" class="chart-point" data-value="100"/>
|
| 1142 |
+
|
| 1143 |
+
<!-- Labels -->
|
| 1144 |
+
<text x="50" y="200" fill="#64748B" font-size="11">السبت</text>
|
| 1145 |
+
<text x="150" y="200" fill="#64748B" font-size="11">الأحد</text>
|
| 1146 |
+
<text x="250" y="200" fill="#64748B" font-size="11">الاثنين</text>
|
| 1147 |
+
<text x="350" y="200" fill="#64748B" font-size="11">الثلاثاء</text>
|
| 1148 |
+
<text x="450" y="200" fill="#64748B" font-size="11">الأربعاء</text>
|
| 1149 |
+
<text x="550" y="200" fill="#64748B" font-size="11">الخميس</text>
|
| 1150 |
+
<text x="650" y="200" fill="#64748B" font-size="11">الجمعة</text>
|
| 1151 |
+
|
| 1152 |
+
<!-- Y-axis labels -->
|
| 1153 |
+
<text x="45" y="35" text-anchor="end" fill="#64748B" font-size="10">100</text>
|
| 1154 |
+
<text x="45" y="85" text-anchor="end" fill="#64748B" font-size="10">75</text>
|
| 1155 |
+
<text x="45" y="135" text-anchor="end" fill="#64748B" font-size="10">50</text>
|
| 1156 |
+
<text x="45" y="185" text-anchor="end" fill="#64748B" font-size="10">25</text>
|
| 1157 |
+
</svg>
|
| 1158 |
+
</div>
|
| 1159 |
+
</div>
|
| 1160 |
+
|
| 1161 |
+
<div class="chart-card">
|
| 1162 |
+
<div class="chart-header">
|
| 1163 |
+
<h3 class="chart-title">توزيع المشكلات</h3>
|
| 1164 |
+
</div>
|
| 1165 |
+
<div class="donut-chart">
|
| 1166 |
+
<svg class="donut-svg" viewBox="0 0 180 180">
|
| 1167 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#E2E8F0" stroke-width="25"/>
|
| 1168 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#EF4444" stroke-width="25" stroke-dasharray="110 308" stroke-dashoffset="0" transform="rotate(-90 90 90)"/>
|
| 1169 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#F59E0B" stroke-width="25" stroke-dasharray="88 308" stroke-dashoffset="-110" transform="rotate(-90 90 90)"/>
|
| 1170 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#3B82F6" stroke-width="25" stroke-dasharray="66 308" stroke-dashoffset="-198" transform="rotate(-90 90 90)"/>
|
| 1171 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#10B981" stroke-width="25" stroke-dasharray="44 308" stroke-dashoffset="-264" transform="rotate(-90 90 90)"/>
|
| 1172 |
+
<text x="90" y="85" text-anchor="middle" font-size="24" font-weight="bold" fill="#0F172A" id="donutTotal">23</text>
|
| 1173 |
+
<text x="90" y="105" text-anchor="middle" font-size="12" fill="#64748B">إجمالي</text>
|
| 1174 |
+
</svg>
|
| 1175 |
+
<div class="donut-legend">
|
| 1176 |
+
<div class="legend-item">
|
| 1177 |
+
<div class="legend-color" style="background:#EF4444"></div>
|
| 1178 |
+
<span class="legend-label">ح��جة</span>
|
| 1179 |
+
<span class="legend-value" id="legendCritical">5</span>
|
| 1180 |
+
</div>
|
| 1181 |
+
<div class="legend-item">
|
| 1182 |
+
<div class="legend-color" style="background:#F59E0B"></div>
|
| 1183 |
+
<span class="legend-label">عالية</span>
|
| 1184 |
+
<span class="legend-value" id="legendHigh">7</span>
|
| 1185 |
+
</div>
|
| 1186 |
+
<div class="legend-item">
|
| 1187 |
+
<div class="legend-color" style="background:#3B82F6"></div>
|
| 1188 |
+
<span class="legend-label">متوسطة</span>
|
| 1189 |
+
<span class="legend-value" id="legendMedium">6</span>
|
| 1190 |
+
</div>
|
| 1191 |
+
<div class="legend-item">
|
| 1192 |
+
<div class="legend-color" style="background:#10B981"></div>
|
| 1193 |
+
<span class="legend-label">منخفضة</span>
|
| 1194 |
+
<span class="legend-value" id="legendLow">5</span>
|
| 1195 |
+
</div>
|
| 1196 |
+
</div>
|
| 1197 |
+
</div>
|
| 1198 |
+
</div>
|
| 1199 |
+
</div>
|
| 1200 |
+
|
| 1201 |
+
<!-- Activity Section -->
|
| 1202 |
+
<div class="activity-section">
|
| 1203 |
+
<div class="activity-card">
|
| 1204 |
+
<div class="activity-header">
|
| 1205 |
+
<h3 class="activity-title">أحدث المشكلات</h3>
|
| 1206 |
+
<span class="view-all" onclick="filterIssues('all')">عرض الكل →</span>
|
| 1207 |
+
</div>
|
| 1208 |
+
<div class="issues-list" id="issuesList">
|
| 1209 |
+
<!-- Issues will be populated by JavaScript -->
|
| 1210 |
+
</div>
|
| 1211 |
+
</div>
|
| 1212 |
+
|
| 1213 |
+
<div class="activity-card">
|
| 1214 |
+
<div class="activity-header">
|
| 1215 |
+
<h3 class="activity-title">المستودعات النشطة</h3>
|
| 1216 |
+
<span class="view-all">عرض الكل →</span>
|
| 1217 |
+
</div>
|
| 1218 |
+
<div class="repos-list" id="reposList">
|
| 1219 |
+
<!-- Repositories will be populated by JavaScript -->
|
| 1220 |
+
</div>
|
| 1221 |
+
</div>
|
| 1222 |
+
</div>
|
| 1223 |
+
</main>
|
| 1224 |
+
</div>
|
| 1225 |
+
|
| 1226 |
+
<!-- Settings Panel -->
|
| 1227 |
+
<div class="settings-panel" id="settingsPanel">
|
| 1228 |
+
<div class="settings-content">
|
| 1229 |
+
<div class="settings-header">
|
| 1230 |
+
<h3>⚙️ الإعدادات</h3>
|
| 1231 |
+
<button class="close-btn" onclick="closeSettings()">×</button>
|
| 1232 |
+
</div>
|
| 1233 |
+
|
| 1234 |
+
<div class="setting-item">
|
| 1235 |
+
<label class="setting-label">اسم المستخدم</label>
|
| 1236 |
+
<input type="text" class="setting-input" id="settingUsername" placeholder="أدخل اسم المستخدم">
|
| 1237 |
+
</div>
|
| 1238 |
+
|
| 1239 |
+
<div class="setting-item">
|
| 1240 |
+
<label class="setting-label">البريد الإلكتروني</label>
|
| 1241 |
+
<input type="email" class="setting-input" id="settingEmail" placeholder="أدخل البريد الإلكتروني">
|
| 1242 |
+
</div>
|
| 1243 |
+
|
| 1244 |
+
<div class="setting-item">
|
| 1245 |
+
<label class="setting-label">لغة الواجهة</label>
|
| 1246 |
+
<select class="setting-select" id="settingLanguage">
|
| 1247 |
+
<option value="ar">العربية</option>
|
| 1248 |
+
<option value="en">English</option>
|
| 1249 |
+
</select>
|
| 1250 |
+
</div>
|
| 1251 |
+
|
| 1252 |
+
<div class="setting-item">
|
| 1253 |
+
<label class="setting-label">السمة</label>
|
| 1254 |
+
<select class="setting-select" id="settingTheme">
|
| 1255 |
+
<option value="light">فاتحة</option>
|
| 1256 |
+
<option value="dark">داكنة</option>
|
| 1257 |
+
<option value="auto">تلقائي</option>
|
| 1258 |
+
</select>
|
| 1259 |
+
</div>
|
| 1260 |
+
|
| 1261 |
+
<div class="setting-item">
|
| 1262 |
+
<label class="setting-label">فحص تلقائي عند الحفظ</label>
|
| 1263 |
+
<div class="setting-toggle" onclick="toggleSetting('autoScan')">
|
| 1264 |
+
<div class="toggle-switch" id="toggleAutoScan"></div>
|
| 1265 |
+
<span>تشغيل</span>
|
| 1266 |
+
</div>
|
| 1267 |
+
<p class="setting-description">إجراء فحص تلقائي للكود عند حفظ الملفات</p>
|
| 1268 |
+
</div>
|
| 1269 |
+
|
| 1270 |
+
<div class="setting-item">
|
| 1271 |
+
<label class="setting-label">إشعارات المشاكل الحرجة</label>
|
| 1272 |
+
<div class="setting-toggle" onclick="toggleSetting('criticalAlerts')">
|
| 1273 |
+
<div class="toggle-switch" id="toggleCriticalAlerts"></div>
|
| 1274 |
+
<span>تشغيل</span>
|
| 1275 |
+
</div>
|
| 1276 |
+
<p class="setting-description">إرسال إشعارات فورية للمشاكل الأمنية الحرجة</p>
|
| 1277 |
+
</div>
|
| 1278 |
+
|
| 1279 |
+
<div class="setting-item">
|
| 1280 |
+
<label class="setting-label">الإصلاح التلقائي الآمن</label>
|
| 1281 |
+
<div class="setting-toggle" onclick="toggleSetting('autoFix')">
|
| 1282 |
+
<div class="toggle-switch" id="toggleAutoFix"></div>
|
| 1283 |
+
<span>تشغيل</span>
|
| 1284 |
+
</div>
|
| 1285 |
+
<p class="setting-description">إصلاح المشاكل الآمنة تلقائياً دون تدخل</p>
|
| 1286 |
+
</div>
|
| 1287 |
+
|
| 1288 |
+
<button class="save-btn" onclick="saveSettings()">💾 حفظ الإعدادات</button>
|
| 1289 |
+
</div>
|
| 1290 |
+
</div>
|
| 1291 |
+
|
| 1292 |
+
<!-- Toast Container -->
|
| 1293 |
+
<div class="toast-container" id="toastContainer"></div>
|
| 1294 |
+
|
| 1295 |
+
<script>
|
| 1296 |
+
// Data
|
| 1297 |
+
let currentData = {
|
| 1298 |
+
threats: 1247,
|
| 1299 |
+
successRate: 99.9,
|
| 1300 |
+
openIssues: 23,
|
| 1301 |
+
responseTime: 0.3,
|
| 1302 |
+
issues: [],
|
| 1303 |
+
repos: []
|
| 1304 |
+
};
|
| 1305 |
+
|
| 1306 |
+
let settings = {
|
| 1307 |
+
username: '',
|
| 1308 |
+
email: '',
|
| 1309 |
+
language: 'ar',
|
| 1310 |
+
theme: 'light',
|
| 1311 |
+
autoScan: true,
|
| 1312 |
+
criticalAlerts: true,
|
| 1313 |
+
autoFix: true
|
| 1314 |
+
};
|
| 1315 |
+
|
| 1316 |
+
// Sample Data
|
| 1317 |
+
const sampleIssues = [
|
| 1318 |
+
{ id: 1, title: 'ثغرة أمنية في وحدة المصادقة', file: 'auth-module.py', time: 'قبل 5 دقائق', severity: 'critical' },
|
| 1319 |
+
{ id: 2, title: 'فشل في اختبارات الأداء', file: 'performance_test.py', time: 'قبل 23 دقيقة', severity: 'warning' },
|
| 1320 |
+
{ id: 3, title: 'تحذير في تنسيق الكود', file: 'main_controller.dart', time: 'قبل ساعة', severity: 'info' },
|
| 1321 |
+
{ id: 4, title: 'تم إصلاح مشكلة التنسيق تلقائياً', file: 'utils_helper.js', time: 'قبل ساعتين', severity: 'success' },
|
| 1322 |
+
{ id: 5, title: 'مشكلة في اتصال قاعدة البيانات', file: 'db_connection.java', time: 'قبل ساعتين', severity: 'critical' },
|
| 1323 |
+
{ id: 6, title: 'تحذير: استخدام دالة قديمة', file: 'legacy_code.py', time: 'قبل 3 ساعات', severity: 'warning' }
|
| 1324 |
+
];
|
| 1325 |
+
|
| 1326 |
+
const sampleRepos = [
|
| 1327 |
+
{ id: 1, name: 'auto-guardian-system', stars: 124, pullRequests: 45, bugs: 3, status: 'active' },
|
| 1328 |
+
{ id: 2, name: 'payment-gateway-api', stars: 89, pullRequests: 32, bugs: 5, status: 'warning' },
|
| 1329 |
+
{ id: 3, name: 'user-management-service', stars: 56, pullRequests: 18, bugs: 1, status: 'active' },
|
| 1330 |
+
{ id: 4, name: 'data-analytics-platform', stars: 234, pullRequests: 67, bugs: 8, status: 'error' }
|
| 1331 |
+
];
|
| 1332 |
+
|
| 1333 |
+
// Initialize
|
| 1334 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 1335 |
+
loadSettings();
|
| 1336 |
+
loadData();
|
| 1337 |
+
renderIssues();
|
| 1338 |
+
renderRepos();
|
| 1339 |
+
setupEventListeners();
|
| 1340 |
+
setupMobileMenu();
|
| 1341 |
+
showToast('🎉 مرحباً بك في Auto-Guardian!', 'success');
|
| 1342 |
+
});
|
| 1343 |
+
|
| 1344 |
+
// Setup Mobile Menu
|
| 1345 |
+
function setupMobileMenu() {
|
| 1346 |
+
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
|
| 1347 |
+
if (mobileMenuBtn) {
|
| 1348 |
+
// Show/hide mobile menu button based on screen size
|
| 1349 |
+
const checkScreenSize = () => {
|
| 1350 |
+
if (window.innerWidth <= 992) {
|
| 1351 |
+
mobileMenuBtn.style.display = 'flex';
|
| 1352 |
+
} else {
|
| 1353 |
+
mobileMenuBtn.style.display = 'none';
|
| 1354 |
+
closeMobileMenu();
|
| 1355 |
+
}
|
| 1356 |
+
};
|
| 1357 |
+
|
| 1358 |
+
checkScreenSize();
|
| 1359 |
+
window.addEventListener('resize', checkScreenSize);
|
| 1360 |
+
}
|
| 1361 |
+
}
|
| 1362 |
+
|
| 1363 |
+
// Toggle Mobile Menu
|
| 1364 |
+
function toggleMobileMenu() {
|
| 1365 |
+
const sidebar = document.getElementById('sidebar');
|
| 1366 |
+
const overlay = document.getElementById('sidebarOverlay');
|
| 1367 |
+
|
| 1368 |
+
if (sidebar && overlay) {
|
| 1369 |
+
sidebar.classList.toggle('active');
|
| 1370 |
+
overlay.classList.toggle('active');
|
| 1371 |
+
}
|
| 1372 |
+
}
|
| 1373 |
+
|
| 1374 |
+
// Close Mobile Menu
|
| 1375 |
+
function closeMobileMenu() {
|
| 1376 |
+
const sidebar = document.getElementById('sidebar');
|
| 1377 |
+
const overlay = document.getElementById('sidebarOverlay');
|
| 1378 |
+
|
| 1379 |
+
if (sidebar) {
|
| 1380 |
+
sidebar.classList.remove('active');
|
| 1381 |
+
}
|
| 1382 |
+
if (overlay) {
|
| 1383 |
+
overlay.classList.remove('active');
|
| 1384 |
+
}
|
| 1385 |
+
}
|
| 1386 |
+
|
| 1387 |
+
// Load Settings from LocalStorage
|
| 1388 |
+
function loadSettings() {
|
| 1389 |
+
const saved = localStorage.getItem('autoGuardianSettings');
|
| 1390 |
+
if (saved) {
|
| 1391 |
+
settings = JSON.parse(saved);
|
| 1392 |
+
}
|
| 1393 |
+
|
| 1394 |
+
// Update UI
|
| 1395 |
+
document.getElementById('settingUsername').value = settings.username || '';
|
| 1396 |
+
document.getElementById('settingEmail').value = settings.email || '';
|
| 1397 |
+
document.getElementById('settingLanguage').value = settings.language || 'ar';
|
| 1398 |
+
document.getElementById('settingTheme').value = settings.theme || 'light';
|
| 1399 |
+
updateToggle('toggleAutoScan', settings.autoScan);
|
| 1400 |
+
updateToggle('toggleCriticalAlerts', settings.criticalAlerts);
|
| 1401 |
+
updateToggle('toggleAutoFix', settings.autoFix);
|
| 1402 |
+
}
|
| 1403 |
+
|
| 1404 |
+
// Save Settings to LocalStorage
|
| 1405 |
+
function saveSettings() {
|
| 1406 |
+
settings.username = document.getElementById('settingUsername').value;
|
| 1407 |
+
settings.email = document.getElementById('settingEmail').value;
|
| 1408 |
+
settings.language = document.getElementById('settingLanguage').value;
|
| 1409 |
+
settings.theme = document.getElementById('settingTheme').value;
|
| 1410 |
+
|
| 1411 |
+
localStorage.setItem('autoGuardianSettings', JSON.stringify(settings));
|
| 1412 |
+
closeSettings();
|
| 1413 |
+
showToast('✅ تم حفظ الإعدادات بنجاح!', 'success');
|
| 1414 |
+
}
|
| 1415 |
+
|
| 1416 |
+
// Update toggle UI
|
| 1417 |
+
function updateToggle(id, value) {
|
| 1418 |
+
const toggle = document.getElementById(id);
|
| 1419 |
+
if (value) {
|
| 1420 |
+
toggle.classList.add('active');
|
| 1421 |
+
} else {
|
| 1422 |
+
toggle.classList.remove('active');
|
| 1423 |
+
}
|
| 1424 |
+
}
|
| 1425 |
+
|
| 1426 |
+
// Toggle setting
|
| 1427 |
+
function toggleSetting(setting) {
|
| 1428 |
+
settings[setting] = !settings[setting];
|
| 1429 |
+
updateToggle('toggle' + setting.charAt(0).toUpperCase() + setting.slice(1), settings[setting]);
|
| 1430 |
+
showToast(`⚙️ تم ${settings[setting] ? 'تفعيل' : 'تعطيل'} ${setting}`, 'info');
|
| 1431 |
+
}
|
| 1432 |
+
|
| 1433 |
+
// Load Data
|
| 1434 |
+
function loadData() {
|
| 1435 |
+
currentData.issues = sampleIssues;
|
| 1436 |
+
currentData.repos = sampleRepos;
|
| 1437 |
+
|
| 1438 |
+
// Randomize some values
|
| 1439 |
+
currentData.threats = Math.floor(Math.random() * 2000) + 500;
|
| 1440 |
+
currentData.openIssues = Math.floor(Math.random() * 30) + 10;
|
| 1441 |
+
currentData.responseTime = (Math.random() * 0.5 + 0.1).toFixed(1);
|
| 1442 |
+
|
| 1443 |
+
updateStatsUI();
|
| 1444 |
+
}
|
| 1445 |
+
|
| 1446 |
+
// Update Stats UI
|
| 1447 |
+
function updateStatsUI() {
|
| 1448 |
+
document.getElementById('statThreats').textContent = currentData.threats.toLocaleString();
|
| 1449 |
+
document.getElementById('statSuccess').textContent = currentData.successRate + '%';
|
| 1450 |
+
document.getElementById('statOpen').textContent = currentData.openIssues;
|
| 1451 |
+
document.getElementById('statResponse').textContent = currentData.responseTime + 's';
|
| 1452 |
+
|
| 1453 |
+
// Update legend
|
| 1454 |
+
const critical = currentData.issues.filter(i => i.severity === 'critical').length;
|
| 1455 |
+
const warning = currentData.issues.filter(i => i.severity === 'warning').length;
|
| 1456 |
+
const info = currentData.issues.filter(i => i.severity === 'info').length;
|
| 1457 |
+
const success = currentData.issues.filter(i => i.severity === 'success').length;
|
| 1458 |
+
|
| 1459 |
+
document.getElementById('legendCritical').textContent = critical;
|
| 1460 |
+
document.getElementById('legendHigh').textContent = warning;
|
| 1461 |
+
document.getElementById('legendMedium').textContent = info;
|
| 1462 |
+
document.getElementById('legendLow').textContent = success;
|
| 1463 |
+
document.getElementById('donutTotal').textContent = currentData.issues.length;
|
| 1464 |
+
}
|
| 1465 |
+
|
| 1466 |
+
// Render Issues
|
| 1467 |
+
function renderIssues(issues = currentData.issues) {
|
| 1468 |
+
const container = document.getElementById('issuesList');
|
| 1469 |
+
container.innerHTML = '';
|
| 1470 |
+
|
| 1471 |
+
issues.forEach(issue => {
|
| 1472 |
+
const severityClass = issue.severity === 'critical' ? 'badge-critical' :
|
| 1473 |
+
issue.severity === 'warning' ? 'badge-warning' :
|
| 1474 |
+
issue.severity === 'info' ? 'badge-info' : 'badge-success';
|
| 1475 |
+
|
| 1476 |
+
const severityLabel = issue.severity === 'critical' ? 'حرجة' :
|
| 1477 |
+
issue.severity === 'warning' ? 'عالية' :
|
| 1478 |
+
issue.severity === 'info' ? 'متوسطة' : 'تم الإصلاح';
|
| 1479 |
+
|
| 1480 |
+
const iconSvg = issue.severity === 'critical' ?
|
| 1481 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>' :
|
| 1482 |
+
issue.severity === 'warning' ?
|
| 1483 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' :
|
| 1484 |
+
issue.severity === 'success' ?
|
| 1485 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' :
|
| 1486 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>';
|
| 1487 |
+
|
| 1488 |
+
const html = `
|
| 1489 |
+
<div class="issue-item" onclick="showIssueDetails(${issue.id})">
|
| 1490 |
+
<div class="issue-icon" style="background: rgba(${issue.severity === 'critical' ? '239, 68, 68' : issue.severity === 'warning' ? '245, 158, 11' : issue.severity === 'success' ? '16, 185, 129' : '59, 130, 246'}, 0.1); color: ${issue.severity === 'critical' ? '#EF4444' : issue.severity === 'warning' ? '#F59E0B' : issue.severity === 'success' ? '#10B981' : '#3B82F6'};">
|
| 1491 |
+
${iconSvg}
|
| 1492 |
+
</div>
|
| 1493 |
+
<div class="issue-content">
|
| 1494 |
+
<div class="issue-title">${issue.title}</div>
|
| 1495 |
+
<div class="issue-meta">${issue.file} • ${issue.time}</div>
|
| 1496 |
+
</div>
|
| 1497 |
+
<span class="issue-badge ${severityClass}">${severityLabel}</span>
|
| 1498 |
+
</div>
|
| 1499 |
+
`;
|
| 1500 |
+
container.innerHTML += html;
|
| 1501 |
+
});
|
| 1502 |
+
}
|
| 1503 |
+
|
| 1504 |
+
// Render Repositories
|
| 1505 |
+
function renderRepos(repos = currentData.repos) {
|
| 1506 |
+
const container = document.getElementById('reposList');
|
| 1507 |
+
container.innerHTML = '';
|
| 1508 |
+
|
| 1509 |
+
repos.forEach(repo => {
|
| 1510 |
+
const statusClass = repo.status === 'active' ? 'active' : repo.status === 'warning' ? 'warning' : 'error';
|
| 1511 |
+
const statusLabel = repo.status === 'active' ? 'نشط' : repo.status === 'warning' ? 'يحتاج مراجعة' : 'مشاكل';
|
| 1512 |
+
const statusColor = repo.status === 'active' ? '#10B981' : repo.status === 'warning' ? '#F59E0B' : '#EF4444';
|
| 1513 |
+
|
| 1514 |
+
const html = `
|
| 1515 |
+
<div class="repo-item">
|
| 1516 |
+
<div class="repo-icon">
|
| 1517 |
+
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1518 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/>
|
| 1519 |
+
</svg>
|
| 1520 |
+
</div>
|
| 1521 |
+
<div class="repo-content">
|
| 1522 |
+
<div class="repo-name">${repo.name}</div>
|
| 1523 |
+
<div class="repo-stats">
|
| 1524 |
+
<span>⭐ ${repo.stars}</span>
|
| 1525 |
+
<span>🔀 ${repo.pullRequests}</span>
|
| 1526 |
+
<span>🐛 ${repo.bugs}</span>
|
| 1527 |
+
</div>
|
| 1528 |
+
</div>
|
| 1529 |
+
<div class="repo-status">
|
| 1530 |
+
<span class="status-dot ${statusClass}"></span>
|
| 1531 |
+
<span style="color: ${statusColor};">${statusLabel}</span>
|
| 1532 |
+
</div>
|
| 1533 |
+
</div>
|
| 1534 |
+
`;
|
| 1535 |
+
container.innerHTML += html;
|
| 1536 |
+
});
|
| 1537 |
+
}
|
| 1538 |
+
|
| 1539 |
+
// Filter Issues
|
| 1540 |
+
function filterIssues(type) {
|
| 1541 |
+
let filtered = currentData.issues;
|
| 1542 |
+
|
| 1543 |
+
if (type === 'critical') {
|
| 1544 |
+
filtered = currentData.issues.filter(i => i.severity === 'critical');
|
| 1545 |
+
showToast(`🔍 عرض ${filtered.length} مشكلة حرجة`, 'info');
|
| 1546 |
+
} else if (type === 'open') {
|
| 1547 |
+
filtered = currentData.issues.filter(i => i.severity !== 'success');
|
| 1548 |
+
showToast(`🔍 عرض ${filtered.length} مشكلة مفتوحة`, 'info');
|
| 1549 |
+
} else if (type === 'all') {
|
| 1550 |
+
showToast(`🔍 عرض ${filtered.length} مشكلة`, 'info');
|
| 1551 |
+
}
|
| 1552 |
+
|
| 1553 |
+
renderIssues(filtered);
|
| 1554 |
+
}
|
| 1555 |
+
|
| 1556 |
+
// Show Issue Details
|
| 1557 |
+
function showIssueDetails(id) {
|
| 1558 |
+
const issue = currentData.issues.find(i => i.id === id);
|
| 1559 |
+
if (issue) {
|
| 1560 |
+
showToast(`📋 ${issue.title} - ${issue.file}`, 'info');
|
| 1561 |
+
}
|
| 1562 |
+
}
|
| 1563 |
+
|
| 1564 |
+
// Change Chart Period
|
| 1565 |
+
function changePeriod(period) {
|
| 1566 |
+
// Update active tab
|
| 1567 |
+
document.querySelectorAll('.chart-tab').forEach(tab => {
|
| 1568 |
+
tab.classList.remove('active');
|
| 1569 |
+
if (tab.dataset.period === period) {
|
| 1570 |
+
tab.classList.add('active');
|
| 1571 |
+
}
|
| 1572 |
+
});
|
| 1573 |
+
|
| 1574 |
+
// Update chart data based on period
|
| 1575 |
+
showToast(`📊 عرض بيانات ${period === 'day' ? '24 ساعة' : period === 'week' ? 'أسبوع' : 'شهر'}`, 'info');
|
| 1576 |
+
|
| 1577 |
+
// Simulate data update
|
| 1578 |
+
const randomFactor = period === 'day' ? 1 : period === 'week' ? 7 : 30;
|
| 1579 |
+
currentData.threats = Math.floor(Math.random() * 2000 * randomFactor) + 500;
|
| 1580 |
+
updateStatsUI();
|
| 1581 |
+
}
|
| 1582 |
+
|
| 1583 |
+
// Search Functionality
|
| 1584 |
+
function setupEventListeners() {
|
| 1585 |
+
// Navigation
|
| 1586 |
+
document.querySelectorAll('.nav-item').forEach(item => {
|
| 1587 |
+
item.addEventListener('click', function() {
|
| 1588 |
+
const view = this.dataset.view;
|
| 1589 |
+
|
| 1590 |
+
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
|
| 1591 |
+
this.classList.add('active');
|
| 1592 |
+
|
| 1593 |
+
// Close mobile menu when navigating
|
| 1594 |
+
closeMobileMenu();
|
| 1595 |
+
|
| 1596 |
+
if (view === 'settings') {
|
| 1597 |
+
openSettings();
|
| 1598 |
+
} else if (view === 'help') {
|
| 1599 |
+
showToast('📖 المساعدة: استخدم القائمة للتنقل بين الأقسام', 'info');
|
| 1600 |
+
} else {
|
| 1601 |
+
showToast(`📂 الانتقال إلى ${this.querySelector('span').textContent}`, 'info');
|
| 1602 |
+
}
|
| 1603 |
+
});
|
| 1604 |
+
});
|
| 1605 |
+
|
| 1606 |
+
// Search
|
| 1607 |
+
const searchInput = document.getElementById('searchInput');
|
| 1608 |
+
const searchResults = document.getElementById('searchResults');
|
| 1609 |
+
|
| 1610 |
+
searchInput.addEventListener('input', function() {
|
| 1611 |
+
const query = this.value.toLowerCase();
|
| 1612 |
+
|
| 1613 |
+
if (query.length < 2) {
|
| 1614 |
+
searchResults.classList.remove('active');
|
| 1615 |
+
return;
|
| 1616 |
+
}
|
| 1617 |
+
|
| 1618 |
+
// Search in issues and repos
|
| 1619 |
+
const results = [];
|
| 1620 |
+
|
| 1621 |
+
currentData.issues.forEach(issue => {
|
| 1622 |
+
if (issue.title.toLowerCase().includes(query) || issue.file.toLowerCase().includes(query)) {
|
| 1623 |
+
results.push({ type: 'issue', title: issue.title, subtitle: issue.file });
|
| 1624 |
+
}
|
| 1625 |
+
});
|
| 1626 |
+
|
| 1627 |
+
currentData.repos.forEach(repo => {
|
| 1628 |
+
if (repo.name.toLowerCase().includes(query)) {
|
| 1629 |
+
results.push({ type: 'repo', title: repo.name, subtitle: `⭐ ${repo.stars} | 🔀 ${repo.pullRequests}` });
|
| 1630 |
+
}
|
| 1631 |
+
});
|
| 1632 |
+
|
| 1633 |
+
if (results.length > 0) {
|
| 1634 |
+
searchResults.innerHTML = results.map(r => `
|
| 1635 |
+
<div class="search-result-item">
|
| 1636 |
+
<div style="font-weight: 500;">${r.title}</div>
|
| 1637 |
+
<div style="font-size: 12px; color: var(--text-muted);">${r.subtitle}</div>
|
| 1638 |
+
</div>
|
| 1639 |
+
`).join('');
|
| 1640 |
+
searchResults.classList.add('active');
|
| 1641 |
+
} else {
|
| 1642 |
+
searchResults.innerHTML = '<div class="search-result-item">لا توجد نتائج</div>';
|
| 1643 |
+
searchResults.classList.add('active');
|
| 1644 |
+
}
|
| 1645 |
+
});
|
| 1646 |
+
|
| 1647 |
+
searchInput.addEventListener('blur', function() {
|
| 1648 |
+
setTimeout(() => {
|
| 1649 |
+
searchResults.classList.remove('active');
|
| 1650 |
+
}, 200);
|
| 1651 |
+
});
|
| 1652 |
+
|
| 1653 |
+
searchInput.addEventListener('focus', function() {
|
| 1654 |
+
if (this.value.length >= 2) {
|
| 1655 |
+
searchResults.classList.add('active');
|
| 1656 |
+
}
|
| 1657 |
+
});
|
| 1658 |
+
|
| 1659 |
+
// Notification button
|
| 1660 |
+
document.getElementById('notificationBtn').addEventListener('click', function() {
|
| 1661 |
+
showToast('🔔 الإشعارات: 5 إشعارات جديدة', 'info');
|
| 1662 |
+
document.getElementById('notificationBadge').textContent = '0';
|
| 1663 |
+
});
|
| 1664 |
+
}
|
| 1665 |
+
|
| 1666 |
+
// Settings Panel
|
| 1667 |
+
function openSettings() {
|
| 1668 |
+
document.getElementById('settingsPanel').classList.add('active');
|
| 1669 |
+
}
|
| 1670 |
+
|
| 1671 |
+
function closeSettings() {
|
| 1672 |
+
document.getElementById('settingsPanel').classList.remove('active');
|
| 1673 |
+
}
|
| 1674 |
+
|
| 1675 |
+
// Toast Notifications
|
| 1676 |
+
function showToast(message, type = 'info') {
|
| 1677 |
+
const container = document.getElementById('toastContainer');
|
| 1678 |
+
const toast = document.createElement('div');
|
| 1679 |
+
toast.className = `toast ${type}`;
|
| 1680 |
+
toast.innerHTML = message;
|
| 1681 |
+
container.appendChild(toast);
|
| 1682 |
+
|
| 1683 |
+
setTimeout(() => {
|
| 1684 |
+
toast.remove();
|
| 1685 |
+
}, 3000);
|
| 1686 |
+
}
|
| 1687 |
+
|
| 1688 |
+
// Close settings on outside click
|
| 1689 |
+
document.getElementById('settingsPanel').addEventListener('click', function(e) {
|
| 1690 |
+
if (e.target === this) {
|
| 1691 |
+
closeSettings();
|
| 1692 |
+
}
|
| 1693 |
+
});
|
| 1694 |
+
</script>
|
| 1695 |
+
</body>
|
| 1696 |
+
</html>
|
dashboard/public/data/latest.json
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"metadata": {
|
| 3 |
+
"timestamp": "2026-01-13T02:00:00.000Z",
|
| 4 |
+
"version": "1.0.0",
|
| 5 |
+
"tool": "auto-guardian",
|
| 6 |
+
"git": {
|
| 7 |
+
"commit_sha": "abc1234",
|
| 8 |
+
"branch": "main",
|
| 9 |
+
"workflow": "auto-guardian-scan"
|
| 10 |
+
}
|
| 11 |
+
},
|
| 12 |
+
"summary": {
|
| 13 |
+
"total_issues": 23,
|
| 14 |
+
"critical_issues": 2,
|
| 15 |
+
"high_issues": 5,
|
| 16 |
+
"medium_issues": 8,
|
| 17 |
+
"low_issues": 6,
|
| 18 |
+
"info_issues": 2,
|
| 19 |
+
"files_scanned": 15,
|
| 20 |
+
"security_score": 78,
|
| 21 |
+
"grade": "C"
|
| 22 |
+
},
|
| 23 |
+
"languages": {
|
| 24 |
+
"detected": ["python", "javascript", "typescript", "go"],
|
| 25 |
+
"lines_of_code": {
|
| 26 |
+
"python": 2450,
|
| 27 |
+
"javascript": 1890,
|
| 28 |
+
"typescript": 2100,
|
| 29 |
+
"go": 1200
|
| 30 |
+
},
|
| 31 |
+
"tools_used": {
|
| 32 |
+
"bandit": { "issues": 8, "status": "completed" },
|
| 33 |
+
"pylint": { "issues": 5, "status": "completed" },
|
| 34 |
+
"eslint": { "issues": 6, "status": "completed" },
|
| 35 |
+
"gosec": { "issues": 4, "status": "completed" }
|
| 36 |
+
}
|
| 37 |
+
},
|
| 38 |
+
"findings": [
|
| 39 |
+
{
|
| 40 |
+
"tool": "bandit",
|
| 41 |
+
"tool_name": "Bandit",
|
| 42 |
+
"severity": "CRITICAL",
|
| 43 |
+
"severity_level": 1,
|
| 44 |
+
"file": "src/authentication.py",
|
| 45 |
+
"line": 45,
|
| 46 |
+
"column": 20,
|
| 47 |
+
"rule_id": "B105",
|
| 48 |
+
"rule_name": "hardcoded_password",
|
| 49 |
+
"message": "Possible hardcoded password: 'admin123'",
|
| 50 |
+
"description": "Hardcoded password detected. This is a security vulnerability as passwords should be stored in environment variables or secure configuration files.",
|
| 51 |
+
"confidence": "HIGH",
|
| 52 |
+
"remediation": "Use environment variables or a secrets manager to store credentials. Example: os.environ.get('DB_PASSWORD')",
|
| 53 |
+
"code_snippet": "password = 'admin123' # This is insecure!",
|
| 54 |
+
"language": "python"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"tool": "gosec",
|
| 58 |
+
"tool_name": "Gosec",
|
| 59 |
+
"severity": "CRITICAL",
|
| 60 |
+
"severity_level": 1,
|
| 61 |
+
"file": "internal/api/handler.go",
|
| 62 |
+
"line": 89,
|
| 63 |
+
"column": 15,
|
| 64 |
+
"rule_id": "G104",
|
| 65 |
+
"rule_name": "Error check skipped",
|
| 66 |
+
"message": "Errors unhandled.",
|
| 67 |
+
"description": "Errors are being ignored without proper handling, which could lead to silent failures and security issues.",
|
| 68 |
+
"confidence": "HIGH",
|
| 69 |
+
"remediation": "Always handle errors properly using if err != nil { return err } pattern",
|
| 70 |
+
"code_snippet": "_ = json.Unmarshal(data, &obj) // Error ignored!",
|
| 71 |
+
"language": "go"
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"tool": "eslint",
|
| 75 |
+
"tool_name": "ESLint",
|
| 76 |
+
"severity": "HIGH",
|
| 77 |
+
"severity_level": 2,
|
| 78 |
+
"file": "src/utils/auth.js",
|
| 79 |
+
"line": 12,
|
| 80 |
+
"column": 18,
|
| 81 |
+
"rule_id": "security/detect-object-injection",
|
| 82 |
+
"rule_name": "Object Injection",
|
| 83 |
+
"message": "Avoid objects with unknown properties, object injection is possible.",
|
| 84 |
+
"description": "Object injection can lead to prototype pollution vulnerabilities if user input is used as object keys.",
|
| 85 |
+
"confidence": "HIGH",
|
| 86 |
+
"remediation": "Validate and sanitize user input before using it to access object properties",
|
| 87 |
+
"code_snippet": "const value = userData[userKey]; // Potential injection!",
|
| 88 |
+
"language": "javascript"
|
| 89 |
+
},
|
| 90 |
+
{
|
| 91 |
+
"tool": "bandit",
|
| 92 |
+
"tool_name": "Bandit",
|
| 93 |
+
"severity": "HIGH",
|
| 94 |
+
"severity_level": 2,
|
| 95 |
+
"file": "src/database/connection.py",
|
| 96 |
+
"line": 67,
|
| 97 |
+
"column": 25,
|
| 98 |
+
"rule_id": "B501",
|
| 99 |
+
"rule_name": "SQL statement with parameters",
|
| 100 |
+
"message": "Possible SQL injection: VALUES ('%s')",
|
| 101 |
+
"description": "SQL injection vulnerability detected. String formatting used to build SQL query could allow attackers to manipulate queries.",
|
| 102 |
+
"confidence": "HIGH",
|
| 103 |
+
"remediation": "Use parameterized queries or ORM methods instead of string formatting. Example: cursor.execute('SELECT * FROM users WHERE id = ?', (user_id,))",
|
| 104 |
+
"code_snippet": "query = f\"SELECT * FROM users WHERE id = '{user_id}'\"",
|
| 105 |
+
"language": "python"
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"tool": "gosec",
|
| 109 |
+
"tool_name": "Gosec",
|
| 110 |
+
"severity": "HIGH",
|
| 111 |
+
"severity_level": 2,
|
| 112 |
+
"file": "cmd/server/main.go",
|
| 113 |
+
"line": 234,
|
| 114 |
+
"column": 10,
|
| 115 |
+
"rule_id": "G107",
|
| 116 |
+
"rule_name": "HTTP absolute path traversal",
|
| 117 |
+
"message": "HTTP absolute path traversal",
|
| 118 |
+
"description": "Path traversal vulnerability detected. User input used directly in file paths without validation.",
|
| 119 |
+
"confidence": "HIGH",
|
| 120 |
+
"remediation": "Validate and sanitize file paths, use filepath.Clean and check for paths outside the allowed directory",
|
| 121 |
+
"code_snippet": "filePath := r.URL.Path + filename",
|
| 122 |
+
"language": "go"
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"tool": "eslint",
|
| 126 |
+
"tool_name": "ESLint",
|
| 127 |
+
"severity": "HIGH",
|
| 128 |
+
"severity_level": 2,
|
| 129 |
+
"file": "src/config/loader.ts",
|
| 130 |
+
"line": 28,
|
| 131 |
+
"column": 22,
|
| 132 |
+
"rule_id": "no-sync",
|
| 133 |
+
"rule_name": "Synchronous Operations",
|
| 134 |
+
"message": "Unexpected sync operation. Use asynchronous operations instead.",
|
| 135 |
+
"description": "Synchronous file operations can block the event loop and cause performance issues in Node.js applications.",
|
| 136 |
+
"confidence": "MEDIUM",
|
| 137 |
+
"remediation": "Use fs.promises.readFile() or fs.readFileSync() is acceptable but document why",
|
| 138 |
+
"code_snippet": "const config = fs.readFileSync(configPath, 'utf8');",
|
| 139 |
+
"language": "typescript"
|
| 140 |
+
},
|
| 141 |
+
{
|
| 142 |
+
"tool": "pylint",
|
| 143 |
+
"tool_name": "Pylint",
|
| 144 |
+
"severity": "HIGH",
|
| 145 |
+
"severity_level": 2,
|
| 146 |
+
"file": "src/api/routes.py",
|
| 147 |
+
"line": 156,
|
| 148 |
+
"column": 8,
|
| 149 |
+
"rule_id": "C0115",
|
| 150 |
+
"rule_name": "Missing function docstring",
|
| 151 |
+
"message": "Missing function or method docstring",
|
| 152 |
+
"description": "Public functions should have docstrings documenting their purpose, parameters, and return values.",
|
| 153 |
+
"confidence": "HIGH",
|
| 154 |
+
"remediation": "Add a docstring following Google or NumPy style format",
|
| 155 |
+
"code_snippet": "def process_data(input_data):\n # Missing docstring\n return transform(input_data)",
|
| 156 |
+
"language": "python"
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"tool": "bandit",
|
| 160 |
+
"tool_name": "Bandit",
|
| 161 |
+
"severity": "MEDIUM",
|
| 162 |
+
"severity_level": 3,
|
| 163 |
+
"file": "src/utils/helpers.py",
|
| 164 |
+
"line": 23,
|
| 165 |
+
"column": 15,
|
| 166 |
+
"rule_id": "B403",
|
| 167 |
+
"rule_name": "Consider possible security implications of pickle module",
|
| 168 |
+
"message": "Consider possible security implications of pickle module.",
|
| 169 |
+
"description": "The pickle module is not secure. Untrusted data can be crafted to execute arbitrary code.",
|
| 170 |
+
"confidence": "HIGH",
|
| 171 |
+
"remediation": "Use JSON or other safe serialization formats instead of pickle",
|
| 172 |
+
"code_snippet": "import pickle # Security risk!",
|
| 173 |
+
"language": "python"
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"tool": "eslint",
|
| 177 |
+
"tool_name": "ESLint",
|
| 178 |
+
"severity": "MEDIUM",
|
| 179 |
+
"severity_level": 3,
|
| 180 |
+
"file": "src/services/api.js",
|
| 181 |
+
"line": 45,
|
| 182 |
+
"column": 13,
|
| 183 |
+
"rule_id": "no-console",
|
| 184 |
+
"rule_name": "Console Log",
|
| 185 |
+
"message": "Unexpected console statement.",
|
| 186 |
+
"description": "Console statements should be removed in production code as they may expose sensitive information.",
|
| 187 |
+
"confidence": "HIGH",
|
| 188 |
+
"remediation": "Remove console.log statements or use a proper logging library with configurable log levels",
|
| 189 |
+
"code_snippet": "console.log('User data:', user); // Remove in production",
|
| 190 |
+
"language": "javascript"
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"tool": "pylint",
|
| 194 |
+
"tool_name": "Pylint",
|
| 195 |
+
"severity": "MEDIUM",
|
| 196 |
+
"severity_level": 3,
|
| 197 |
+
"file": "src/utils/validators.py",
|
| 198 |
+
"line": 78,
|
| 199 |
+
"column": 12,
|
| 200 |
+
"rule_id": "W0612",
|
| 201 |
+
"rule_name": "Unused variable",
|
| 202 |
+
"message": "Unused variable 'unused_param'",
|
| 203 |
+
"description": "Unused variables should be removed to keep code clean and maintainable.",
|
| 204 |
+
"confidence": "HIGH",
|
| 205 |
+
"remediation": "Remove unused variables or prefix with underscore to indicate intentional non-use",
|
| 206 |
+
"code_snippet": "def process(a, b, unused_param): # 'unused_param' is never used\n return a * 2",
|
| 207 |
+
"language": "python"
|
| 208 |
+
},
|
| 209 |
+
{
|
| 210 |
+
"tool": "gosec",
|
| 211 |
+
"tool_name": "Gosec",
|
| 212 |
+
"severity": "MEDIUM",
|
| 213 |
+
"severity_level": 3,
|
| 214 |
+
"file": "internal/utils/crypto.go",
|
| 215 |
+
"line": 112,
|
| 216 |
+
"column": 8,
|
| 217 |
+
"rule_id": "G401",
|
| 218 |
+
"rule_name": "Use of weak cryptographic primitive",
|
| 219 |
+
"message": "Use of weak cryptographic primitive (MD5 or SHA1)",
|
| 220 |
+
"description": "MD5 and SHA1 are considered cryptographically broken. Use SHA-256 or better.",
|
| 221 |
+
"confidence": "HIGH",
|
| 222 |
+
"remediation": "Use crypto/sha256 or higher instead of MD5/SHA1",
|
| 223 |
+
"code_snippet": "hash := md5.Sum([]byte(data)) // Use SHA-256!",
|
| 224 |
+
"language": "go"
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"tool": "eslint",
|
| 228 |
+
"tool_name": "ESLint",
|
| 229 |
+
"severity": "MEDIUM",
|
| 230 |
+
"severity_level": 3,
|
| 231 |
+
"file": "src/components/UserForm.jsx",
|
| 232 |
+
"line": 89,
|
| 233 |
+
"column": 15,
|
| 234 |
+
"rule_id": "react/no-danger",
|
| 235 |
+
"rule_name": "Dangerous Props",
|
| 236 |
+
"message": "Dangerous use of dangerouslySetInnerHTML",
|
| 237 |
+
"description": "Using dangerouslySetInnerHTML can expose XSS vulnerabilities if the content is not properly sanitized.",
|
| 238 |
+
"confidence": "HIGH",
|
| 239 |
+
"remediation": "Avoid using dangerouslySetInnerHTML or ensure content is sanitized with a library like DOMPurify",
|
| 240 |
+
"code_snippet": "<div dangerouslySetInnerHTML={{ __html: userContent }} />",
|
| 241 |
+
"language": "javascript"
|
| 242 |
+
},
|
| 243 |
+
{
|
| 244 |
+
"tool": "pylint",
|
| 245 |
+
"tool_name": "Pylint",
|
| 246 |
+
"severity": "MEDIUM",
|
| 247 |
+
"severity_level": 3,
|
| 248 |
+
"file": "src/api/middleware.py",
|
| 249 |
+
"line": 34,
|
| 250 |
+
"column": 4,
|
| 251 |
+
"rule_id": "R0913",
|
| 252 |
+
"rule_name": "Too many arguments",
|
| 253 |
+
"message": "Too many arguments (6/5)",
|
| 254 |
+
"description": "Functions with more than 5 arguments are difficult to maintain and use. Consider refactoring.",
|
| 255 |
+
"confidence": "MEDIUM",
|
| 256 |
+
"remediation": "Group related parameters into a configuration object or class",
|
| 257 |
+
"code_snippet": "def create_user(name, email, password, role, department, manager): pass # Too many!",
|
| 258 |
+
"language": "python"
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"tool": "gosec",
|
| 262 |
+
"tool_name": "Gosec",
|
| 263 |
+
"severity": "MEDIUM",
|
| 264 |
+
"severity_level": 3,
|
| 265 |
+
"file": "internal/api/middleware.go",
|
| 266 |
+
"line": 56,
|
| 267 |
+
"column": 12,
|
| 268 |
+
"rule_id": "G304",
|
| 269 |
+
"rule_name": "File path traversal",
|
| 270 |
+
"message": "File path traversal detected",
|
| 271 |
+
"description": "User input used directly in file path without proper validation could allow path traversal attacks.",
|
| 272 |
+
"confidence": "HIGH",
|
| 273 |
+
"remediation": "Validate file paths and ensure they are within the allowed directory using filepath.Clean and path verification",
|
| 274 |
+
"code_snippet": "file, _ := os.Open(userProvidedPath)",
|
| 275 |
+
"language": "go"
|
| 276 |
+
},
|
| 277 |
+
{
|
| 278 |
+
"tool": "eslint",
|
| 279 |
+
"tool_name": "ESLint",
|
| 280 |
+
"severity": "MEDIUM",
|
| 281 |
+
"severity_level": 3,
|
| 282 |
+
"file": "src/utils/api.js",
|
| 283 |
+
"line": 156,
|
| 284 |
+
"column": 9,
|
| 285 |
+
"rule_id": "no-underscore-dangle",
|
| 286 |
+
"rule_name": "Underscore Dangle",
|
| 287 |
+
"message": "Unexpected dangling '_' in 'fetch_url_'",
|
| 288 |
+
"description": "Variable names with trailing underscores are unconventional and may confuse developers.",
|
| 289 |
+
"confidence": "MEDIUM",
|
| 290 |
+
"remediation": "Use conventional naming without trailing underscores",
|
| 291 |
+
"code_snippet": "const fetch_url_ = 'https://api.example.com';",
|
| 292 |
+
"language": "javascript"
|
| 293 |
+
},
|
| 294 |
+
{
|
| 295 |
+
"tool": "bandit",
|
| 296 |
+
"tool_name": "Bandit",
|
| 297 |
+
"severity": "LOW",
|
| 298 |
+
"severity_level": 4,
|
| 299 |
+
"file": "tests/test_sample.py",
|
| 300 |
+
"line": 12,
|
| 301 |
+
"column": 10,
|
| 302 |
+
"rule_id": "B101",
|
| 303 |
+
"rule_name": "Assert used",
|
| 304 |
+
"message": "Use of assert detected",
|
| 305 |
+
"description": "Assert statements should not be used in production code as they can be disabled with Python's -O flag.",
|
| 306 |
+
"confidence": "HIGH",
|
| 307 |
+
"remediation": "Use unittest assertions or raise exceptions instead of assert",
|
| 308 |
+
"code_snippet": "assert result == expected, 'Test failed'",
|
| 309 |
+
"language": "python"
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"tool": "pylint",
|
| 313 |
+
"tool_name": "Pylint",
|
| 314 |
+
"severity": "LOW",
|
| 315 |
+
"severity_level": 4,
|
| 316 |
+
"file": "src/config/settings.py",
|
| 317 |
+
"line": 8,
|
| 318 |
+
"column": 0,
|
| 319 |
+
"rule_id": "C0114",
|
| 320 |
+
"rule_name": "Missing module docstring",
|
| 321 |
+
"message": "Missing module docstring",
|
| 322 |
+
"description": "Module-level docstrings should be present at the top of each file.",
|
| 323 |
+
"confidence": "HIGH",
|
| 324 |
+
"remediation": "Add a module docstring describing the purpose of this module",
|
| 325 |
+
"code_snippet": "# Module content starts here without docstring",
|
| 326 |
+
"language": "python"
|
| 327 |
+
},
|
| 328 |
+
{
|
| 329 |
+
"tool": "eslint",
|
| 330 |
+
"tool_name": "ESLint",
|
| 331 |
+
"severity": "LOW",
|
| 332 |
+
"severity_level": 4,
|
| 333 |
+
"file": "src/index.js",
|
| 334 |
+
"line": 3,
|
| 335 |
+
"column": 8,
|
| 336 |
+
"rule_id": "no-unused-vars",
|
| 337 |
+
"rule_name": "Unused Variables",
|
| 338 |
+
"message": "'React' is defined but never used.",
|
| 339 |
+
"description": "Unused variables increase code complexity and should be removed.",
|
| 340 |
+
"confidence": "HIGH",
|
| 341 |
+
"remediation": "Remove the unused import or use the variable",
|
| 342 |
+
"code_snippet": "import React from 'react'; // React is not used directly",
|
| 343 |
+
"language": "javascript"
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"tool": "gosec",
|
| 347 |
+
"tool_name": "Gosec",
|
| 348 |
+
"severity": "LOW",
|
| 349 |
+
"severity_level": 4,
|
| 350 |
+
"file": "internal/config/loader.go",
|
| 351 |
+
"line": 23,
|
| 352 |
+
"column": 6,
|
| 353 |
+
"rule_id": "G108",
|
| 354 |
+
"rule_name": "Performance regression detected",
|
| 355 |
+
"message": "Benchmark result indicates potential performance regression",
|
| 356 |
+
"description": "The function shows potential performance issues based on benchmark comparison.",
|
| 357 |
+
"confidence": "MEDIUM",
|
| 358 |
+
"remediation": "Review the function for potential optimizations like caching, reducing allocations, or algorithmic improvements",
|
| 359 |
+
"code_snippet": "// Consider adding caching for repeated calls",
|
| 360 |
+
"language": "go"
|
| 361 |
+
},
|
| 362 |
+
{
|
| 363 |
+
"tool": "pylint",
|
| 364 |
+
"tool_name": "Pylint",
|
| 365 |
+
"severity": "LOW",
|
| 366 |
+
"severity_level": 4,
|
| 367 |
+
"file": "src/utils/constants.py",
|
| 368 |
+
"line": 5,
|
| 369 |
+
"column": 0,
|
| 370 |
+
"rule_id": "C0103",
|
| 371 |
+
"rule_name": "Invalid constant name",
|
| 372 |
+
"message": "Constant name \"MAX_SIZE\" doesn't conform to UPPER_CASE naming style",
|
| 373 |
+
"description": "Constants should be named in UPPER_CASE with underscores.",
|
| 374 |
+
"confidence": "HIGH",
|
| 375 |
+
"remediation": "Rename the constant to use UPPER_CASE format",
|
| 376 |
+
"code_snippet": "max_size = 100 # Should be MAX_SIZE = 100",
|
| 377 |
+
"language": "python"
|
| 378 |
+
},
|
| 379 |
+
{
|
| 380 |
+
"tool": "eslint",
|
| 381 |
+
"tool_name": "ESLint",
|
| 382 |
+
"severity": "LOW",
|
| 383 |
+
"severity_level": 4,
|
| 384 |
+
"file": "src/styles/main.css",
|
| 385 |
+
"line": 1,
|
| 386 |
+
"column": 1,
|
| 387 |
+
"rule_id": "no-irregular-whitespace",
|
| 388 |
+
"rule_name": "Irregular Whitespace",
|
| 389 |
+
"message": "Irregular whitespace not allowed.",
|
| 390 |
+
"description": "Irregular whitespace characters can cause rendering issues and are typically typos.",
|
| 391 |
+
"confidence": "HIGH",
|
| 392 |
+
"remediation": "Remove any irregular whitespace characters from the file",
|
| 393 |
+
"code_snippet": " \t /* Space at beginning of file */",
|
| 394 |
+
"language": "javascript"
|
| 395 |
+
},
|
| 396 |
+
{
|
| 397 |
+
"tool": "bandit",
|
| 398 |
+
"tool_name": "Bandit",
|
| 399 |
+
"severity": "INFO",
|
| 400 |
+
"severity_level": 5,
|
| 401 |
+
"file": "setup.py",
|
| 402 |
+
"line": 15,
|
| 403 |
+
"column": 7,
|
| 404 |
+
"rule_id": "B602",
|
| 405 |
+
"rule_name": "Subprocess call with shell=True",
|
| 406 |
+
"message": "subprocess call with shell=True identified",
|
| 407 |
+
"description": "Using shell=True in subprocess allows shell injection attacks. Consider using shell=False.",
|
| 408 |
+
"confidence": "MEDIUM",
|
| 409 |
+
"remediation": "Use shell=False and pass arguments as a list to prevent shell injection",
|
| 410 |
+
"code_snippet": "subprocess.run(f'ls {directory}', shell=True) # Risky!",
|
| 411 |
+
"language": "python"
|
| 412 |
+
},
|
| 413 |
+
{
|
| 414 |
+
"tool": "pylint",
|
| 415 |
+
"tool_name": "Pylint",
|
| 416 |
+
"severity": "INFO",
|
| 417 |
+
"severity_level": 5,
|
| 418 |
+
"file": "src/main.py",
|
| 419 |
+
"line": 1,
|
| 420 |
+
"column": 1,
|
| 421 |
+
"rule_id": "C0111",
|
| 422 |
+
"rule_name": "Missing function docstring",
|
| 423 |
+
"message": "Missing function or method docstring (missing-docstring)",
|
| 424 |
+
"description": "Function docstrings help developers understand the purpose and usage of functions.",
|
| 425 |
+
"confidence": "MEDIUM",
|
| 426 |
+
"remediation": "Add a docstring explaining what the function does, its parameters, and return value",
|
| 427 |
+
"code_snippet": "def main(): # Missing docstring\n run_app()",
|
| 428 |
+
"language": "python"
|
| 429 |
+
}
|
| 430 |
+
],
|
| 431 |
+
"trends": {
|
| 432 |
+
"previous_scan": null,
|
| 433 |
+
"improvement": null
|
| 434 |
+
}
|
| 435 |
+
}
|
development-report.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# تقرير تطوير مشروع Auto-Guardian
|
| 2 |
+
## هندسة الأمان المؤتمت للأجيال القادمة
|
| 3 |
+
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
## الملخص التنفيذي
|
| 7 |
+
|
| 8 |
+
يمثل مشروع Auto-Guardian نقلة نوعية في مجال أتمتة جودة البرمجيات وأمانها، حيث يجمع بين تقنيات التحليل المتقدمة والذكاء الاصطناعي لتقديم نظام شامل لحماية المستودعات البرمجية. يهدف هذا التقرير إلى توثيق التطورات المقترحة والمخطط لها للمشروع، مع التركيز على تعزيز قدرات النظام الحالية وتوسيع نطاق خدماته ليشمل قاعدة أوسع من المستخدمين والمطورين.
|
| 9 |
+
|
| 10 |
+
يعالج النظام الحالي فجوة حقيقية في السوق، حيث تعاني معظم الفرق البرمجية من غياب آليات موحدة وفعالة لمراقبة جودة الكود وأمانه بشكل آلي ومستمر. من خلال تقديم مجموعة متكاملة من الأدوات والخدمات، يسعى Auto-Guardian إلى سد هذه الفجوة وتمكين الفرق من التركيز على الابتكار بدلاً من المهام الروتينية المتعلقة بالصيانة والفحص.
|
| 11 |
+
|
| 12 |
+
تشمل التحديثات المقترحة في هذا التقرير إضافة ميزات متقدمة تعتمد على الذكاء الاصطناعي، وتطوير واجهات مستخدم أكثر حداثة وسهولة في الاستخدام، وتوسيع دعم اللغات والمنصات، وتعزيز قدرات التكامل مع أدوات التطوير الشائعة. كما يتضمن التقرير خططاً لتوفير لوحة تحكم مركزية وإمكانية التشغيل على مستوى المؤسسات.
|
| 13 |
+
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
## المقدمة
|
| 17 |
+
|
| 18 |
+
### السياق والخلفية
|
| 19 |
+
|
| 20 |
+
في عالم تطوير البرمجيات الحديث، أصبحت جودة الكود وأمانه من أهم العوامل التي تحدد نجاح المشاريع والorganizations. مع تزايد تعقيد المشاريع البرمجية وتنوع التقنيات المستخدمة، يجد المطورون أنفسهم أمام تحدٍّ كبير في الحفاظ على معايير الجودة والأمان بشكل يدوي. هذا التحدي يستهلك وقتاً وجهداً كبيرين، ويفتح الباب أمام أخطاء قد تكون مكلفة.
|
| 21 |
+
|
| 22 |
+
تشير الدراسات إلى أن تكلفة إصلاح الأخطاء البرمجية تزداد بشكل كبير كلما تأخر اكتشافها في دورة التطوير. في المراحل المبكرة من التطوير، قد لا تتجاوز تكلفة الإصلاح بضع ساعات من العمل، بينما في مرحلة الإنتاج قد تصل إلى أيام أو أسابيع، ناهيك عن الأضرار المحتملة للسمعة والثقة. هذا الواقع يجعل الاستثمار في أدوات الفحص الآلي ضرورة ملحة وليس ترفاً.
|
| 23 |
+
|
| 24 |
+
### الحاجة إلى الأتمتة
|
| 25 |
+
|
| 26 |
+
توفر أتمتة عمليات فحص الجودة والأمان العديد من المزايا التي لا يمكن تحقيقها يدوياً. أولاً، تضمن الأتمتة الاتساق في تطبيق المعايير عبر جميع التغييرات، بغض النظر عن حجم الفريق أو عدد المشاريع. ثانياً، توفر سرعة التنفيذ التي تسمح بفحص الكود في وقت قياسي مقارنة بالفحص اليدوي. ثالثاً، تقلل من العبء على المطورين,使他们 يستطيعون التركيز على المهام الإبداعية والتصميمية. وأخيراً، توفر توثيقاً دقيقاً لجميع المشكلات المكتشفة والإجراءات المتخذة.
|
| 27 |
+
|
| 28 |
+
يهدف مشروع Auto-Guardian إلى تقديم هذه الفوائد بشكل متكامل وميسر، مع التركيز على سهولة الاستخدام والتكامل مع سير العمل اليومي للفرق البرمجية. يتبنى المشروع فلسفة توفير الرؤية والأتمتة دون تعقيد، مما يجعله مناسباً للفرق بمختلف أحجامها ومستويات خبرتها.
|
| 29 |
+
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
## الهندسة التقنية
|
| 33 |
+
|
| 34 |
+
### نظرة عامة على البنية
|
| 35 |
+
|
| 36 |
+
تعتمد بنية Auto-Guardian على تصميم متعدد الطبقات يوفر المرونة والقابلية للتوسع. تتكون البنية من خمس طبقات رئيسية تعمل بشكل متكامل لتقديم خدمات شاملة للفحص والحماية. يتيح هذا التصميم فصل المسؤوليات بين المكونات المختلفة، مما يسهل عملية الصيانة والتطوير المستقبلي.
|
| 37 |
+
|
| 38 |
+
تتضمن الطبقة الأول�� واجهة المستخدم التي تشمل لوحة التحكم الويب وواجهة سطر الأوامر، بالإضافة إلى التكامل مع بيئات التطوير المتكاملة. توفر هذه الطبقة نقاط وصول متعددة تناسب مختلف احتياجات المستخدمين، من المطورين الأفراد إلى فرق المؤسسات الكبيرة. تدعم الواجهات الحديثة تقنيات الاستجابة الكاملة، مما يضمن تجربة مستخدم متسقة عبر جميع الأجهزة.
|
| 39 |
+
|
| 40 |
+
تأتي بعد ذلك طبقة البوابة التي تتولى إدارة الطلبات والمصادقة. تعمل هذه الطبقة كنقطة دخول موحدة لجميع الطلبات، وتضمن تطبيق سياسات الأمان والوصول بشكل مركزي. تستخدم البوابة تقنيات التخزين المؤقت لتحسين الأداء وتقليل الحمل على الطبقات الخلفية.
|
| 41 |
+
|
| 42 |
+
### محركات التحليل
|
| 43 |
+
|
| 44 |
+
يشكل محرك التحليل قلب النظام، حيث يتولى مسؤولية فحص الكود واكتشاف المشكلات. يعتمد المحرك على مجموعة متنوعة من الأدوات المتخصصة التي تغطي جوانب مختلفة من الجودة والأمان. تشمل هذه الأدوات أدوات التنسيق اللغوي مثل ESLint وFlake8 وPylint، وماسحات الأمان مثل Bandit وSecurityScanner، ومحركات فحص الأنواع، وأدوات تحليل الأداء.
|
| 45 |
+
|
| 46 |
+
يتضمن المحرك منطقاً ذكياً لدمج نتائج الفحص من مختلف الأدوات وتصفيتها وتوجيهها. يستخدم هذا المنطق قواعد قابلة للتخصيص لتحديد أولويات المشكلات وتجنب التكرار. كما يوفر إمكانية إضافة قواعد مخصصة تلبي احتياجات محددة للمشاريع والفرق.
|
| 47 |
+
|
| 48 |
+
### نظام الإصلاح التلقائي
|
| 49 |
+
|
| 50 |
+
يمثل نظام الإصلاح التلقائي أحد أهم مميزات Auto-Guardian، حيث يتجاوز مجرد اكتشاف المشكلات إلى إصلاحها تلقائياً عندما يكون ذلك آمناً وممكناً. يشمل الإصلاح التلقائي مشاكل التنسيق وأنماط الكود السيئة وإصلاحات الأمان البسيطة. يتبع النظام نهجاً متحفظاً في الإصلاح التلقائي، حيث لا يقوم بإصلاح إلا المشكلات التي لديه ثقة عالية في صحة الإصلاح.
|
| 51 |
+
|
| 52 |
+
يتم توثيق جميع الإصلاحات التلقائية في سجل مفصل يتيح للمطورين مراجعة التغييرات ومراجعتها. يمكن تكوين النظام لإرسال طلبات مراجعة للإصلاحات التي تتطلب موافقة بشرية، مما يوفر التوازن بين الأتمتة والرقابة.
|
| 53 |
+
|
| 54 |
+
### طبقة التخزين والإشعارات
|
| 55 |
+
|
| 56 |
+
توفر طبقة التخزين استمرارية البيانات وإمكانية تتبع التاريخ. تستخدم قاعدة بيانات علائقية لتخزين نتائج الفحص والإعدادات، مع دعم للنسخ الاحتياطي والاستعادة. تتضمن الطبقة أيضاً نظام تخزين مؤقت لتحسين أداء الاستعلامات المتكررة.
|
| 57 |
+
|
| 58 |
+
يتولى نظام الإشعارات مهمة التواصل مع المستخدمين حول حالة الفحص والمشاكل المكتشفة. يدعم النظام قنوات إشعار متعددة تشمل البريد الإلكتروني والرسائل الفورية عبر Slack وDiscord، بالإضافة إلى إشعارات داخل منصة GitHub نفسها. يمكن للمستخدمين تخصيص تفضيلات الإشعارات لكل مشروع على حدة.
|
| 59 |
+
|
| 60 |
+
### المخطط البياني للبنية
|
| 61 |
+
|
| 62 |
+
```mermaid
|
| 63 |
+
graph TD
|
| 64 |
+
subgraph User_Layer["طبقة المستخدم"]
|
| 65 |
+
User["المستخدمون والمطورون"]
|
| 66 |
+
Admin["المسؤولون"]
|
| 67 |
+
end
|
| 68 |
+
|
| 69 |
+
subgraph Gateway_Layer["طبقة البوابة"]
|
| 70 |
+
API["API Gateway"]
|
| 71 |
+
Auth["خدمة المصادقة"]
|
| 72 |
+
end
|
| 73 |
+
|
| 74 |
+
subgraph Core_Layer["طبقة المحرك الرئيسي"]
|
| 75 |
+
Analyzer["محلل الكود"]
|
| 76 |
+
Scanner["ماسح الأمان"]
|
| 77 |
+
Fixer["محرك الإصلاح التلقائي"]
|
| 78 |
+
Quality["بوابة الجودة"]
|
| 79 |
+
end
|
| 80 |
+
|
| 81 |
+
subgraph Agents_Layer["طبقة العملاء"]
|
| 82 |
+
Linters["أدوات التنسيق"]
|
| 83 |
+
Security["فحوصات الأمان"]
|
| 84 |
+
Tests["محركات الاختبار"]
|
| 85 |
+
TypeCheck["فحص الأنواع"]
|
| 86 |
+
end
|
| 87 |
+
|
| 88 |
+
subgraph Storage_Layer["طبقة التخزين"]
|
| 89 |
+
DB["قاعدة البيانات"]
|
| 90 |
+
Cache["التخزين المؤقت"]
|
| 91 |
+
Logs["سجلات النظام"]
|
| 92 |
+
end
|
| 93 |
+
|
| 94 |
+
subgraph Notification_Layer["طبقة التنبيهات"]
|
| 95 |
+
Alerts["نظام التنبيهات"]
|
| 96 |
+
Slack["Slack"]
|
| 97 |
+
Email["البريد الإلكتروني"]
|
| 98 |
+
Discord["Discord"]
|
| 99 |
+
end
|
| 100 |
+
|
| 101 |
+
%% Connections
|
| 102 |
+
User --> API
|
| 103 |
+
Admin --> API
|
| 104 |
+
API --> Auth
|
| 105 |
+
Auth --> Analyzer
|
| 106 |
+
Auth --> Scanner
|
| 107 |
+
|
| 108 |
+
Analyzer --> Linters
|
| 109 |
+
Analyzer --> TypeCheck
|
| 110 |
+
Scanner --> Security
|
| 111 |
+
|
| 112 |
+
Linters --> Quality
|
| 113 |
+
Security --> Quality
|
| 114 |
+
Tests --> Quality
|
| 115 |
+
TypeCheck --> Quality
|
| 116 |
+
|
| 117 |
+
Analyzer --> DB
|
| 118 |
+
Scanner --> DB
|
| 119 |
+
Quality --> DB
|
| 120 |
+
|
| 121 |
+
DB --> Cache
|
| 122 |
+
Quality --> Alerts
|
| 123 |
+
Alerts --> Slack
|
| 124 |
+
Alerts --> Email
|
| 125 |
+
Alerts --> Discord
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
---
|
| 129 |
+
|
| 130 |
+
## الميزات الأساسية
|
| 131 |
+
|
| 132 |
+
### المراقبة الحية
|
| 133 |
+
|
| 134 |
+
توفر ميزة المراقبة الحية رؤية فورية لحالة جميع المشاريع والمراقبة المستمرة للتغييرات. تعرض لوحة التحكم الرئيسية ملخصاً شاملاً يتضمن عدد التهديدات المحظورة ومعدل نجاح الفحوصات وزمن الاستجابة والمشكلات المفتوحة. يتم تحديث هذه المعلومات في الوقت الفعلي، مما يمكّن الفرق من الاستجابة السريعة لأي مشكلات.
|
| 135 |
+
|
| 136 |
+
تشمل المراقبة الحية أيضاً رسوماً بيانية توضح اتجاهات الجودة والأمان عبر الزمن. تتيح هذه الرسوم تحديد الأنماط والمشكلات المتكررة التي قد تشير إلى حاجة لتدريب إضافي أو تغييرات في العمليات. كما توفر تنبيهات فورية للمشكلات الحرجة التي تتطلب اهتماماً فورياً.
|
| 137 |
+
|
| 138 |
+
### الحماية الآلية
|
| 139 |
+
|
| 140 |
+
تتجاوز الحماية الآلية مجرد الاكتشاف إلى منع المشكلات قبل وصولها إلى الكود الأساسي. من خلال بوابة الجودة، يتولى النظام فحص جميع طلبات السحب والتحقق من استيفائها للمعايير المحددة. يتم حظر طلبات السحب التي تفشل في الفحص من الدمج، مما يضمن أن الكود الجديد يلتزم بمعايير الجودة.
|
| 141 |
+
|
| 142 |
+
تتضمن الحماية الآلية أيضاً ميزات استباقية مثل تحليل التبعيات ومراقبة الثغرات الأمنية المعروفة. عند اكتشاف ثغرة في إحدى المكتبات المستخدمة، يُعلم النظام الفريق فوراً ويقترح تحديثات آمنة. كما يوفر تقارير دورية عن حالة الأمان والتوصيات للتحسين.
|
| 143 |
+
|
| 144 |
+
### تحليل البيانات
|
| 145 |
+
|
| 146 |
+
يوفر النظام قدرات متقدمة في تحليل البيانات لاستخراج رؤى قيمة من نتائج الفحص. تشمل هذه القدرات تتبع مؤشرات الأداء الرئيسية مثل عدد المشكلات المكتشفة ومعدل الإصلاح ومتوسط وقت الاستجابة. تتيح واجهة التحليل تصفية البيانات حسب المشروع واللغة ونوع المشكلة ومستوى الخطورة.
|
| 147 |
+
|
| 148 |
+
تشمل القدرات التحليلية أيضاً رسم خرائط للتبعيات بين المشاريع وتحديد المخاطر المحتملة للتغييرات. من خلال تحليل تأثير التغييرات، يمكن للنظام تحديد المشاريع والمكونات الأكثر تأثراً بأي تغيير، مما يساعد في تقييم المخاطر وتخطيط الاختبارات.
|
| 149 |
+
|
| 150 |
+
### التقارير الذكية
|
| 151 |
+
|
| 152 |
+
يولد النظام تقارير متنوعة تناسب احتياجات مختلفة. تشمل التقارير المتاحة التقارير التنفيذية للإدارة التي تلخص الحالة العامة وتوجهات الجودة، والتقارير التفصيلية للفنيين التي تتضمن معلومات دقيقة عن كل مشكلة والإجراءات المقترحة لحلها. كما تتوفر تقارير مطابقة للمعايير التنظيمية مثل OWASP وISO 27001.
|
| 153 |
+
|
| 154 |
+
يمكن تخصيص التقارير وتصديرها بصيغ متعددة تشمل PDF وExcel وHTML. يدعم النظام أيضاً التصدير الآلي للتقارير عبر البريد الإلكتروني أو تخزينها في منصات مشاركة الملفات. كما يتضمن إمكانية جدولة التقارير الدورية لتوليدها وإرسالها تلقائياً.
|
| 155 |
+
|
| 156 |
+
---
|
| 157 |
+
|
| 158 |
+
## التحديات والحلول
|
| 159 |
+
|
| 160 |
+
### التعامل مع البيانات الضخمة
|
| 161 |
+
|
| 162 |
+
يواجه النظام تحدياً في معالجة كميات كبيرة من البيانات الناتجة عن فحص المشاريع الكبيرة والمتكررة. يتضمن ذلك ملايين الأسطر من الكود ونتائج آل��ف الفحوصات. للتعامل مع هذا التحدي، يعتمد النظام على استراتيجية تخزين مؤقت ذكية تحتفظ بالنتائج الأخيرة وتتجاهل البيانات الأقل استخداماً.
|
| 163 |
+
|
| 164 |
+
كما يستخدم النظام تقنيات المعالجة المتوازية لتوزيع الأحمال عبر خوادم متعددة. يتضمن ذلك تقسيم المشاريع الكبيرة إلى أجزاء أصغر يمكن معالجتها بشكل متوازٍ، ثم تجميع النتائج في النهاية. هذا النهج يقلل زمن الفالجة بشكل كبير ويحسن استجابة النظام.
|
| 165 |
+
|
| 166 |
+
### التوازن بين الدقة والإنتاجية
|
| 167 |
+
|
| 168 |
+
يمثل تحقيق التوازن بين شمولية الفحص وسرعة التنفيذ تحدياً مستمراً. الفحص الأكثر شمولية يستغرق وقتاً أطول، مما قد يؤثر على تجربة المطورين وسرعة دورات التطوير. للتعامل مع هذا، يستخدم النظام نهجاً تكيفياً يحدد مستوى الفحص بناءً على حجم التغييرات وسياقها.
|
| 169 |
+
|
| 170 |
+
في حالة التغييرات الصغيرة، يمكن إجراء فحص خفيف يركز على المناطق المتأثرة فقط. أما التغييرات الكبيرة فتتطلب فحصاً شاملاً. كما يوفر النظام خيارات للمستخدمين لتحديد أولويات الفحص وتخصيص الموارد وفقاً لاحتياجاتهم.
|
| 171 |
+
|
| 172 |
+
### التقليل من الإيجابيات الكاذبة
|
| 173 |
+
|
| 174 |
+
تعد الإيجابيات الكاذبة، أي الإبلاغ عن مشكلات غير حقيقية، من أكبر تحديات أنظمة الفحص الآلي. العدد الكبير من التنبيهات الخاطئة يؤدي إلى إرهاق المطورين وتقليل ثقتهم في النظام. للتعامل مع هذا التحدي، يعتمد النظام على آليات تعلم مستمرة تحسن دقة الاكتشاف بناءً على ملاحظات المستخدمين.
|
| 175 |
+
|
| 176 |
+
يتضمن النظام أيضاً قواعد ذكية لتصفية التنبيهات بناءً على السياق وتاريخ المشروع. عند اكتشاف أنماط متكررة من التنبيهات التي يتجاهلها المطورون، يتعلم النظام منها ويعدل قواعده وفقاً لذلك. كما يوفر واجهة سهلة للمستخدمين للإبلاغ عن التنبيهات الخاطئة مباشرة.
|
| 177 |
+
|
| 178 |
+
---
|
| 179 |
+
|
| 180 |
+
## خارطة الطريق
|
| 181 |
+
|
| 182 |
+
### المرحلة الأولى: تعزيز الأساس (الربع القادم)
|
| 183 |
+
|
| 184 |
+
تركز هذه المرحلة على تحسين قدرات النظام الحالية وتعزيز استقراره. يشمل ذلك تحسين أداء محركات الفحص بنسبة لا تقل عن ثلاثين بالمئة، وإضافة دعم للغات جديدة تشمل Rust وKotlin. كما تتضمن تحسين واجهة المستخدم وإضافة ميزات طلبها المجتمع.
|
| 185 |
+
|
| 186 |
+
من الأهداف الرئيسية في هذه المرحلة تطوير نظام الإصلاح التلقائي ليشمل أنواعاً إضافية من المشكلات. يتضمن ذلك إصلاح مشاكل الأمان البسيطة وإعادة هيكلة أنماط الكود السيئة. كما سيتم تحسين التكامل مع منصات CI/CD الشائعة لتسهيل عملية التبني.
|
| 187 |
+
|
| 188 |
+
### المرحلة الثانية: الذكاء الاصطناعي (الربع الثاني)
|
| 189 |
+
|
| 190 |
+
تمثل هذه المرحلة نقلة نوعية في قدرات النظام من خلال دمج تقنيات الذكاء الاصطناعي. سيتضمن ذلك نموذجاً متقدماً لتحليل الكود يمكنه فهم السياق وتقديم اقتراحات ذكية. كما سيتم تطوير نظام تنبؤي يحدد المشاكل المحتملة قبل حدوثها.
|
| 191 |
+
|
| 192 |
+
تشمل التطبيقات الأخرى للذكاء الاصطناعي تحسين تصنيف المشكلات وتحديد الأنماط في أخطاء الفريق. كما سيتم تطوير مساعد ذكي يقترح حلولاً للمشاكل بناءً على المعرفة المتراكمة من مشاريع مماثلة. هذا سيقلل بشكل كبير وقت حل المشاكل ويحسن جودة الحلول.
|
| 193 |
+
|
| 194 |
+
### المرحلة الثالثة: منصة المؤسسات (الربع الثالث)
|
| 195 |
+
|
| 196 |
+
تركز هذه المرحلة على تلبية احتياجات المؤسسات الكبيرة من خلال تطوير منصة متعددة المستأجرين. سيتضمن ذلك لوحات تحكم مركزية تتيح للمسؤولين إدارة جميع مشاريع المؤسسة من مكان واحد، مع صلاحيات متدرجة وإمكانية تخصيص واسعة.
|
| 197 |
+
|
| 198 |
+
كما تتضمن هذه المرحلة تطوير واجهات برمجة تطبي��ات متقدمة للتكامل مع أنظمة المؤسسات القائمة. يشمل ذلك التكامل مع أنظمة إدارة الهوية والوصول وأنظمة المراقبة والتتبع. كما سيتم توفير خيارات نشر مرنة تشمل النشر السحابي والخاص.
|
| 199 |
+
|
| 200 |
+
### المرحلة الرابعة: النظام البيئي (الربع الرابع)
|
| 201 |
+
|
| 202 |
+
تهدف هذه المرحلة إلى بناء نظام بيئي متكامل حول Auto-Guardian. يتضمن ذلك إطلاق منصة للمكونات الإضافية تتيح للمجتمع تطوير إضافات توسع قدرات النظام. كما سيتم إنشاء marketplace للتكاملات والمكونات الإضافية.
|
| 203 |
+
|
| 204 |
+
تشمل الأهداف الأخرى في هذه المرحلة تطوير برنامج شراكات مع مزودي خدمات الحوسبة السحابية وأدوات التطوير. كما سيتم إطلاق برنامج شهادات للمطورين المتخصصين في استخدام النظام، مما يعزز القيمة المهنية للمستخدمين.
|
| 205 |
+
|
| 206 |
+
---
|
| 207 |
+
|
| 208 |
+
## واجهة المستخدم المصممة
|
| 209 |
+
|
| 210 |
+
### لوحة التحكم الرئيسية
|
| 211 |
+
|
| 212 |
+
تم تصميم لوحة تحكم حديثة وسهلة الاستخدام توفر رؤية شاملة لحالة النظام. تتضمن اللوحة أقساماً واضحة لعرض الإحصائيات الرئيسية والرسوم البيانية النشاط الأخير والمستودعات النشطة. يعتمد التصميم على مبدأ البطاقات التي تسهل قراءة المعلومات وتجعلها قابلة للفحص السريع.
|
| 213 |
+
|
| 214 |
+
تتميز اللوحة بنظام ألوان متناسق يعكس هوية النظام البصرية. تستخدم الألوان الكحلية والزرقاء لإعطاء انطباع بالأمان والموثوقية، مع استخدام الأخضر للإشارة إلى النجاح والأحمر للتنبيهات. التصميم متجاوب ويعمل بشكل ممتاز على مختلف أحجام الشاشات.
|
| 215 |
+
|
| 216 |
+
### الرسوم البيانية التوضيحية
|
| 217 |
+
|
| 218 |
+
تم إنشاء مجموعة من الرسوم البيانية التوضيحية التي تجسد مفاهيم النظام الرئيسية. تتضمن هذه الرسوم أيقونة المراقبة الحية التي تظهر رقصة مسح رادارية توضح عملية الفحص المستمرة، وأيقونة الحماية الآلية التي تجمع بين رمز الدرع والتروس لترمز إلى الحماية الذكية، وأيقونة تحليل البيانات التي توضح تدفق البيانات والتحليل المتصاعد.
|
| 219 |
+
|
| 220 |
+
جميع الرسوم البيانية مصممة بأسلوب مسطح عصري يتناسب مع الهوية البصرية للنظام. تستخدم ألوان متناسقة وعناصر هندسية ناعمة تجعل المعلومات سهلة الفهم والجذابة بصرياً. يمكن استخدام هذه الرسوم في الوثائق والعروض التقديمية والمواد التسويقية.
|
| 221 |
+
|
| 222 |
+
### الفيديو التوضيحي
|
| 223 |
+
|
| 224 |
+
تم إعداد سيناريو مفصل لفيديو توضيحي يمتد من ستين إلى تسعين ثانية. يتبع الفيديو هيكلاً واضحاً يبدأ بإثارة المشكلة ويعرض الحل ثم يستعرض الميزات وينتهي بدعوة للعمل. يتضمن السيناريو تفاصيل دقيقة للمشاهد والرسوم المتحركة والتعليق الصوتي.
|
| 225 |
+
|
| 226 |
+
تم تصميم الفيديو ليكون جذاباً ومهماً، مع التركيز على تقديم رسالة واضحة ومؤثرة. يتضمن السيناريو ترجمة إنجليزية كاملة لجعل المحتوى متاحاً لجمهور أوسع. كما يتضمن مواصفات تقنية للإنتاج تشمل الألوان والخطوط والمؤثرات الصوتية.
|
| 227 |
+
|
| 228 |
+
---
|
| 229 |
+
|
| 230 |
+
## المعايير والسياسات
|
| 231 |
+
|
| 232 |
+
### معايير جودة الكود
|
| 233 |
+
|
| 234 |
+
يلتزم النظام بمجموعة شاملة من معايير جودة الكود التي تغطي جوانب متعددة من البرمجيات. تشمل هذه المعايير معايير التنسيق التي تحدد أسلوب الكتابة المتسق، ومعايير الوثائق التي تضمن توفر تعليقات كافية، ومعايير الأمان التي تمنع الأنماط غير الآمنة، ومعايير الأداء التي تضمن الكفاءة.
|
| 235 |
+
|
| 236 |
+
يمكن تخصيص هذه المعايير لكل مشروع على حدة، مع توفير قوالب جاهزة لأنواع المشاريع الشائعة. يتضمن النظام أيضاً أدوات لفرض المعايير تلقائياً ومنع الكود الذي لا يلتزم بها من الوصول إلى الكود الأساسي.
|
| 237 |
+
|
| 238 |
+
### سياسات الأمان
|
| 239 |
+
|
| 240 |
+
تت��نى النظام سياسات أمان صارمة لحماية البيانات والأنظمة. تتضمن هذه السياسات تشفير البيانات في حالة السكون والنقل، واستخدام المصادقة متعددة العوامل، وتطبيق مبدأ الحد الأدنى من الصلاحيات. كما تتضمن سياسات للتعامل مع الثغرات الأمنية المكتشفة.
|
| 241 |
+
|
| 242 |
+
يلتزم النظام بمتطلبات اللوائح العالمية لحماية البيانات مثل GDPR، مع توفير أدوات للامتثال ومراجعة الوصول. كما يتضمن سجلات تدقيق شاملة لجميع العمليات الحساسة، مما يتيح المراجعة والتتبع عند الحاجة.
|
| 243 |
+
|
| 244 |
+
---
|
| 245 |
+
|
| 246 |
+
## الخاتمة
|
| 247 |
+
|
| 248 |
+
يمثل مشروع Auto-Guardian خطوة مهمة نحو أتمتة جودة البرمجيات وأمانها بشكل شامل ومتكامل. من خلال الجمع بين أدوات الفحص المتقدمة والذكاء الاصطناعي، يوفر النظام قدرة غير مسبوقة على اكتشاف المشكلات وإصلاحها تلقائياً. كما يضمن تصميمه المتعدد الطبقات المرونة والقابلية للتوسع لتلبية احتياجات الفرق بمختلف أحجامها.
|
| 249 |
+
|
| 250 |
+
توفر خارطة الطريق الموضحة في هذا التقرير رؤية واضحة لمسار تطوير المشروع في المستقبل القريب. من خلال المراحل الأربع المحددة، سيتحول النظام تدريجياً من أداة فحص بسيطة إلى منصة متكاملة لإدارة جودة البرمجيات على مستوى المؤسسات. سيتيح ذلك للفرق تبني النظام تدريجياً والتمتع بمزاياه المتزايدة مع نمو احتياجاتهم.
|
| 251 |
+
|
| 252 |
+
ندعو المطورين والمساهمين للانضمام إلى مشروع Auto-Guardian والمساهمة في تطويره. سواء من خلال الإبلاغ عن المشاكل أو اقتراح ميزات جديدة أو كتابة وثائق أو تطوير إضافات، كل مساهمة تساعد في جعل النظام أفضل للجميع. معاً، يمكننا بناء مستقبل يكون فيه كل كود آمناً وعالي الجودة.
|
| 253 |
+
|
| 254 |
+
---
|
| 255 |
+
|
| 256 |
+
## المراجع والروابط
|
| 257 |
+
|
| 258 |
+
- **المستودع الرئيسي:** github.com/AbdulElahOthmanGwaith/auto-guardian-system
|
| 259 |
+
- **الموقع الرسمي:** autoguardian.dev
|
| 260 |
+
- **التوثيق:** docs.autoguardian.dev
|
| 261 |
+
- **الدعم:** support@autoguardian.dev
|
| 262 |
+
|
| 263 |
+
---
|
| 264 |
+
|
| 265 |
+
*نهاية التقرير*
|
diagrams/system-architecture.mmd
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Auto-Guardian System Architecture Diagram
|
| 2 |
+
// Generated for Auto-Guardian Enhancement Project
|
| 3 |
+
|
| 4 |
+
graph TD
|
| 5 |
+
subgraph User_Layer["طبقة المستخدم"]
|
| 6 |
+
User["المستخدمون والمطورون"]
|
| 7 |
+
Admin["المسؤولون"]
|
| 8 |
+
end
|
| 9 |
+
|
| 10 |
+
subgraph Gateway_Layer["طبقة البوابة"]
|
| 11 |
+
API["API Gateway"]
|
| 12 |
+
Auth["خدمة المصادقة"]
|
| 13 |
+
end
|
| 14 |
+
|
| 15 |
+
subgraph Core_Layer["طبقة المحرك الرئيسي"]
|
| 16 |
+
Analyzer["محلل الكود"]
|
| 17 |
+
Scanner["ماسح الأمان"]
|
| 18 |
+
Fixer["محرك الإصلاح التلقائي"]
|
| 19 |
+
Quality["بوابة الجودة"]
|
| 20 |
+
end
|
| 21 |
+
|
| 22 |
+
subgraph Agents_Layer["طبقة العملاء"]
|
| 23 |
+
Linters["أدوات التنسيق"]
|
| 24 |
+
Security["فحوصات الأمان"]
|
| 25 |
+
Tests["محركات الاختبار"]
|
| 26 |
+
TypeCheck["فحص الأنواع"]
|
| 27 |
+
end
|
| 28 |
+
|
| 29 |
+
subgraph Storage_Layer["طبقة التخزين"]
|
| 30 |
+
DB["قاعدة البيانات"]
|
| 31 |
+
Cache["التخزين المؤقت"]
|
| 32 |
+
Logs["سجلات النظام"]
|
| 33 |
+
end
|
| 34 |
+
|
| 35 |
+
subgraph Notification_Layer["طبقة التنبيهات"]
|
| 36 |
+
Alerts["نظام التنبيهات"]
|
| 37 |
+
Slack["Slack"]
|
| 38 |
+
Email["البريد الإلكتروني"]
|
| 39 |
+
Discord["Discord"]
|
| 40 |
+
end
|
| 41 |
+
|
| 42 |
+
%% Connections
|
| 43 |
+
User --> API
|
| 44 |
+
Admin --> API
|
| 45 |
+
API --> Auth
|
| 46 |
+
Auth --> Analyzer
|
| 47 |
+
Auth --> Scanner
|
| 48 |
+
|
| 49 |
+
Analyzer --> Linters
|
| 50 |
+
Analyzer --> TypeCheck
|
| 51 |
+
Scanner --> Security
|
| 52 |
+
|
| 53 |
+
Linters --> Quality
|
| 54 |
+
Security --> Quality
|
| 55 |
+
Tests --> Quality
|
| 56 |
+
TypeCheck --> Quality
|
| 57 |
+
|
| 58 |
+
Analyzer --> DB
|
| 59 |
+
Scanner --> DB
|
| 60 |
+
Quality --> DB
|
| 61 |
+
|
| 62 |
+
DB --> Cache
|
| 63 |
+
Quality --> Alerts
|
| 64 |
+
Alerts --> Slack
|
| 65 |
+
Alerts --> Email
|
| 66 |
+
Alerts --> Discord
|
| 67 |
+
|
| 68 |
+
%% Styling
|
| 69 |
+
classDef primary fill:#0F172A,stroke:#3B82F6,stroke-width:2px,color:#fff
|
| 70 |
+
classDef secondary fill:#3B82F6,stroke:#0F172A,stroke-width:2px,color:#fff
|
| 71 |
+
classDef accent fill:#10B981,stroke:#0F172A,stroke-width:2px,color:#fff
|
| 72 |
+
classDef alert fill:#EF4444,stroke:#0F172A,stroke-width:2px,color:#fff
|
| 73 |
+
classDef storage fill:#64748B,stroke:#0F172A,stroke-width:2px,color:#fff
|
| 74 |
+
|
| 75 |
+
class User,Admin primary
|
| 76 |
+
class API,Auth secondary
|
| 77 |
+
class Analyzer,Scanner,Fixer,Quality secondary
|
| 78 |
+
class Linters,Security,Tests,TypeCheck accent
|
| 79 |
+
class DB,Cache,Logs storage
|
| 80 |
+
class Alerts,Slack,Email,Discord alert
|
docker-compose.yml
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version: '3.8'
|
| 2 |
+
|
| 3 |
+
services:
|
| 4 |
+
# ========================================
|
| 5 |
+
# خدمة نظام الحارس التلقائي الرئيسية
|
| 6 |
+
# ========================================
|
| 7 |
+
auto-guardian:
|
| 8 |
+
build:
|
| 9 |
+
context: .
|
| 10 |
+
dockerfile: Dockerfile
|
| 11 |
+
container_name: auto-guardian-system
|
| 12 |
+
restart: unless-stopped
|
| 13 |
+
privileged: true
|
| 14 |
+
volumes:
|
| 15 |
+
# مجلد السجلات
|
| 16 |
+
- ./logs:/app/logs:rw
|
| 17 |
+
|
| 18 |
+
# مجلد الإعدادات
|
| 19 |
+
- ./config:/app/config:rw
|
| 20 |
+
|
| 21 |
+
# قراءة سجلات النظام (للمراقبة)
|
| 22 |
+
- /var/log/auth.log:/var/log/auth.log:ro
|
| 23 |
+
- /var/log/syslog:/var/log/syslog:ro
|
| 24 |
+
- /var/log/nginx/access.log:/var/log/nginx/access.log:ro
|
| 25 |
+
|
| 26 |
+
# حالة IPTables (للتشغيل المحلي)
|
| 27 |
+
- /lib/modules:/lib/modules:ro
|
| 28 |
+
|
| 29 |
+
environment:
|
| 30 |
+
# إعدادات البيئة
|
| 31 |
+
- TZ=UTC
|
| 32 |
+
- PYTHONUNBUFFERED=1
|
| 33 |
+
- LOG_LEVEL=INFO
|
| 34 |
+
|
| 35 |
+
# إعدادات التطبيق
|
| 36 |
+
- AG_MODE=docker
|
| 37 |
+
- AG_CONFIG_PATH=/app/config/settings.yaml
|
| 38 |
+
- AG_LOG_PATH=/app/logs
|
| 39 |
+
|
| 40 |
+
# إعدادات API
|
| 41 |
+
- AG_API_HOST=0.0.0.0
|
| 42 |
+
- AG_API_PORT=8000
|
| 43 |
+
|
| 44 |
+
# إعدادات الإشعارات
|
| 45 |
+
- AG_NOTIFICATIONS_ENABLED=true
|
| 46 |
+
- AG_SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-}
|
| 47 |
+
- AG_DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL:-}
|
| 48 |
+
|
| 49 |
+
networks:
|
| 50 |
+
- security-network
|
| 51 |
+
ports:
|
| 52 |
+
- "8000:8000"
|
| 53 |
+
|
| 54 |
+
healthcheck:
|
| 55 |
+
test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8000/health')"]
|
| 56 |
+
interval: 30s
|
| 57 |
+
timeout: 10s
|
| 58 |
+
retries: 3
|
| 59 |
+
start_period: 10s
|
| 60 |
+
|
| 61 |
+
labels:
|
| 62 |
+
- "com.autoguardian.version=1.3.0"
|
| 63 |
+
- "com.autoguardian.service=auto-guardian"
|
| 64 |
+
|
| 65 |
+
logging:
|
| 66 |
+
driver: json-file
|
| 67 |
+
options:
|
| 68 |
+
max-size: "100m"
|
| 69 |
+
max-file: "5"
|
| 70 |
+
|
| 71 |
+
# ========================================
|
| 72 |
+
# خدمة Prometheus للمراقبة
|
| 73 |
+
# ========================================
|
| 74 |
+
prometheus:
|
| 75 |
+
image: prom/prometheus:v2.48.0
|
| 76 |
+
container_name: prometheus
|
| 77 |
+
restart: unless-stopped
|
| 78 |
+
volumes:
|
| 79 |
+
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
| 80 |
+
- prometheus-data:/prometheus
|
| 81 |
+
command:
|
| 82 |
+
- '--config.file=/etc/prometheus/prometheus.yml'
|
| 83 |
+
- '--storage.tsdb.path=/prometheus'
|
| 84 |
+
- '--storage.tsdb.retention.time=15d'
|
| 85 |
+
- '--web.enable-lifecycle'
|
| 86 |
+
- '--web.enable-admin-api'
|
| 87 |
+
networks:
|
| 88 |
+
- security-network
|
| 89 |
+
ports:
|
| 90 |
+
- "9090:9090"
|
| 91 |
+
healthcheck:
|
| 92 |
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy"]
|
| 93 |
+
interval: 30s
|
| 94 |
+
timeout: 10s
|
| 95 |
+
retries: 3
|
| 96 |
+
labels:
|
| 97 |
+
- "com.autoguardian.service=prometheus"
|
| 98 |
+
|
| 99 |
+
# ========================================
|
| 100 |
+
# خدمة Grafana للوحات المراقبة
|
| 101 |
+
# ========================================
|
| 102 |
+
grafana:
|
| 103 |
+
image: grafana/grafana:10.2.0
|
| 104 |
+
container_name: grafana
|
| 105 |
+
restart: unless-stopped
|
| 106 |
+
environment:
|
| 107 |
+
# إعدادات Grafana
|
| 108 |
+
- GF_SECURITY_ADMIN_USER=${GRAFANA_USER:-admin}
|
| 109 |
+
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-autoguardian}
|
| 110 |
+
- GF_USERS_ALLOW_SIGN_UP=false
|
| 111 |
+
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
|
| 112 |
+
|
| 113 |
+
# إعدادات SMTP (لإرسال التنبيهات)
|
| 114 |
+
- GF_SMTP_ENABLED=${GRAFANA_SMTP_ENABLED:-false}
|
| 115 |
+
- GF_SMTP_HOST=${GRAFANA_SMTP_HOST:-}
|
| 116 |
+
- GF_SMTP_USER=${GRAFANA_SMTP_USER:-}
|
| 117 |
+
- GF_SMTP_PASSWORD=${GRAFANA_SMTP_PASSWORD:-}
|
| 118 |
+
|
| 119 |
+
volumes:
|
| 120 |
+
- grafana-data:/var/lib/grafana
|
| 121 |
+
- ./grafana/provisioning:/etc/grafana/provisioning:ro
|
| 122 |
+
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
|
| 123 |
+
|
| 124 |
+
networks:
|
| 125 |
+
- security-network
|
| 126 |
+
ports:
|
| 127 |
+
- "3000:3000"
|
| 128 |
+
depends_on:
|
| 129 |
+
- prometheus
|
| 130 |
+
healthcheck:
|
| 131 |
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/api/health"]
|
| 132 |
+
interval: 30s
|
| 133 |
+
timeout: 10s
|
| 134 |
+
retries: 3
|
| 135 |
+
labels:
|
| 136 |
+
- "com.autoguardian.service=grafana"
|
| 137 |
+
|
| 138 |
+
logging:
|
| 139 |
+
driver: json-file
|
| 140 |
+
options:
|
| 141 |
+
max-size: "50m"
|
| 142 |
+
max-file: "3"
|
| 143 |
+
|
| 144 |
+
# ========================================
|
| 145 |
+
# خدمة التنبيهات (قائمة الانتظار)
|
| 146 |
+
# ========================================
|
| 147 |
+
alerts-worker:
|
| 148 |
+
build:
|
| 149 |
+
context: .
|
| 150 |
+
dockerfile: Dockerfile
|
| 151 |
+
container_name: alerts-worker
|
| 152 |
+
restart: unless-stopped
|
| 153 |
+
command: ["python", "-m", "src.notifiers.worker"]
|
| 154 |
+
volumes:
|
| 155 |
+
- ./logs:/app/logs:rw
|
| 156 |
+
- ./config:/app/config:rw
|
| 157 |
+
environment:
|
| 158 |
+
- TZ=UTC
|
| 159 |
+
- PYTHONUNBUFFERED=1
|
| 160 |
+
- AG_MODE=worker
|
| 161 |
+
- AG_CONFIG_PATH=/app/config/settings.yaml
|
| 162 |
+
- AG_REDIS_URL=redis://redis:6379/0
|
| 163 |
+
networks:
|
| 164 |
+
- security-network
|
| 165 |
+
depends_on:
|
| 166 |
+
redis:
|
| 167 |
+
condition: service_healthy
|
| 168 |
+
profiles:
|
| 169 |
+
- production
|
| 170 |
+
|
| 171 |
+
# ========================================
|
| 172 |
+
# خدمة Redis للتخزين المؤقت والرسائل
|
| 173 |
+
# ========================================
|
| 174 |
+
redis:
|
| 175 |
+
image: redis:7-alpine
|
| 176 |
+
container_name: redis
|
| 177 |
+
restart: unless-stopped
|
| 178 |
+
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
|
| 179 |
+
volumes:
|
| 180 |
+
- redis-data:/data
|
| 181 |
+
networks:
|
| 182 |
+
- security-network
|
| 183 |
+
ports:
|
| 184 |
+
- "6379:6379"
|
| 185 |
+
healthcheck:
|
| 186 |
+
test: ["CMD", "redis-cli", "ping"]
|
| 187 |
+
interval: 10s
|
| 188 |
+
timeout: 5s
|
| 189 |
+
retries: 3
|
| 190 |
+
labels:
|
| 191 |
+
- "com.autoguardian.service=redis"
|
| 192 |
+
|
| 193 |
+
# ========================================
|
| 194 |
+
# خدمة Nginx كوكيل عكسي (اختياري)
|
| 195 |
+
# ========================================
|
| 196 |
+
nginx:
|
| 197 |
+
image: nginx:alpine
|
| 198 |
+
container_name: nginx-proxy
|
| 199 |
+
restart: unless-stopped
|
| 200 |
+
volumes:
|
| 201 |
+
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
| 202 |
+
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
| 203 |
+
- ./nginx/html:/usr/share/nginx/html:ro
|
| 204 |
+
networks:
|
| 205 |
+
- security-network
|
| 206 |
+
ports:
|
| 207 |
+
- "80:80"
|
| 208 |
+
- "443:443"
|
| 209 |
+
depends_on:
|
| 210 |
+
- auto-guardian
|
| 211 |
+
- grafana
|
| 212 |
+
profiles:
|
| 213 |
+
- production
|
| 214 |
+
|
| 215 |
+
# ========================================
|
| 216 |
+
# تعريف الشبكات
|
| 217 |
+
# ========================================
|
| 218 |
+
networks:
|
| 219 |
+
security-network:
|
| 220 |
+
driver: bridge
|
| 221 |
+
ipam:
|
| 222 |
+
config:
|
| 223 |
+
- subnet: 172.28.0.0/16
|
| 224 |
+
|
| 225 |
+
# ========================================
|
| 226 |
+
# تعريف المجلدات المستمرة
|
| 227 |
+
# ========================================
|
| 228 |
+
volumes:
|
| 229 |
+
prometheus-data:
|
| 230 |
+
driver: local
|
| 231 |
+
grafana-data:
|
| 232 |
+
driver: local
|
| 233 |
+
redis-data:
|
| 234 |
+
driver: local
|
docs/api/openapi.yaml
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# توثيق واجهة برمجة التطبيقات (API)
|
| 2 |
+
# API Documentation for Auto Guardian System
|
| 3 |
+
# ==========================================
|
| 4 |
+
|
| 5 |
+
openapi: 3.0.3
|
| 6 |
+
info:
|
| 7 |
+
title: "نظام الحارس التلقائي - واجهة برمجة التطبيقات"
|
| 8 |
+
description: |
|
| 9 |
+
واجهة برمجة تطبيقات نظام الحارس التلقائي للمراقبة الأمنية وإدارة التهديدات.
|
| 10 |
+
|
| 11 |
+
## نظرة عامة
|
| 12 |
+
|
| 13 |
+
توفر هذه الواجهة مجموعة من النقاط الطرفية للتحقق من حالة النظام، وإدارة التهديدات المحظورة، وإرسال التنبيهات، ومراقبة الأداء.
|
| 14 |
+
|
| 15 |
+
## المصادقة
|
| 16 |
+
|
| 17 |
+
تستخدم الواجهة مصادقة JWT. للحصول على رمز الوصول، استخدم نقطة نهاية `/api/v1/auth/token`.
|
| 18 |
+
|
| 19 |
+
## الإصدار
|
| 20 |
+
|
| 21 |
+
- **الإصدار الحالي:** 1.3.0
|
| 22 |
+
- **آخر تحديث:** 2024-10-13
|
| 23 |
+
|
| 24 |
+
## الدعم
|
| 25 |
+
|
| 26 |
+
للمشاكل والاستفسارات: support@autoguardian.local
|
| 27 |
+
version: "1.3.0"
|
| 28 |
+
contact:
|
| 29 |
+
name: "الدعم الفني"
|
| 30 |
+
email: "support@autoguardian.local"
|
| 31 |
+
url: "https://github.com/AbdulElahOthmanGwaith/auto-guardian-system"
|
| 32 |
+
license:
|
| 33 |
+
name: "MIT License"
|
| 34 |
+
url: "https://opensource.org/licenses/MIT"
|
| 35 |
+
|
| 36 |
+
servers:
|
| 37 |
+
- url: http://localhost:8000/api/v1
|
| 38 |
+
description: "خادم التطوير المحلي"
|
| 39 |
+
- url: https://api.autoguardian.local/api/v1
|
| 40 |
+
description: "خادم الإنتاج"
|
| 41 |
+
|
| 42 |
+
tags:
|
| 43 |
+
- name: "الصحة"
|
| 44 |
+
description: "نقاط نهاية فحص حالة النظام"
|
| 45 |
+
- name: "التهديدات"
|
| 46 |
+
description: "إدارة التهديدات الأمنية"
|
| 47 |
+
- name: "العناوكات المحظورة"
|
| 48 |
+
description: "إدارة العناوكات المحظورة"
|
| 49 |
+
- name: "التنبيهات"
|
| 50 |
+
description: "إدارة التنبيهات والإشعارات"
|
| 51 |
+
- name: "المراقبة"
|
| 52 |
+
description: "مراقبة الأداء والإحصائيات"
|
| 53 |
+
- name: "المصادقة"
|
| 54 |
+
description: "المصادقة وإدارة الرموز"
|
| 55 |
+
|
| 56 |
+
paths:
|
| 57 |
+
# ========================================
|
| 58 |
+
# قسم الصحة
|
| 59 |
+
# ========================================
|
| 60 |
+
|
| 61 |
+
/health:
|
| 62 |
+
get:
|
| 63 |
+
tags:
|
| 64 |
+
- "الصحة"
|
| 65 |
+
summary: "فحص حالة النظام"
|
| 66 |
+
description: "إرجاع حالة النظام العامة ومعلومات الإصدار"
|
| 67 |
+
operationId: "getHealth"
|
| 68 |
+
responses:
|
| 69 |
+
"200":
|
| 70 |
+
description: "النظام يعمل بشكل صحيح"
|
| 71 |
+
content:
|
| 72 |
+
application/json:
|
| 73 |
+
schema:
|
| 74 |
+
$ref: "#/components/schemas/HealthResponse"
|
| 75 |
+
example:
|
| 76 |
+
status: "healthy"
|
| 77 |
+
version: "1.3.0"
|
| 78 |
+
uptime: "2d 5h 30m"
|
| 79 |
+
timestamp: "2024-10-13T10:30:00Z"
|
| 80 |
+
"503":
|
| 81 |
+
description: "النظام لا يعمل بشكل صحيح"
|
| 82 |
+
content:
|
| 83 |
+
application/json:
|
| 84 |
+
schema:
|
| 85 |
+
$ref: "#/components/schemas/HealthResponse"
|
| 86 |
+
example:
|
| 87 |
+
status: "unhealthy"
|
| 88 |
+
version: "1.3.0"
|
| 89 |
+
error: "Database connection failed"
|
| 90 |
+
|
| 91 |
+
/health/detailed:
|
| 92 |
+
get:
|
| 93 |
+
tags:
|
| 94 |
+
- "الصحة"
|
| 95 |
+
summary: "فحص تفصيلي للحالة"
|
| 96 |
+
description: "إرجاع حالة مفصلة لجميع مكونات النظام"
|
| 97 |
+
operationId: "getDetailedHealth"
|
| 98 |
+
responses:
|
| 99 |
+
"200":
|
| 100 |
+
description: "حالة تفصيلية للنظام"
|
| 101 |
+
content:
|
| 102 |
+
application/json:
|
| 103 |
+
schema:
|
| 104 |
+
type: "object"
|
| 105 |
+
properties:
|
| 106 |
+
status:
|
| 107 |
+
type: "string"
|
| 108 |
+
components:
|
| 109 |
+
type: "object"
|
| 110 |
+
properties:
|
| 111 |
+
database:
|
| 112 |
+
type: "object"
|
| 113 |
+
properties:
|
| 114 |
+
status:
|
| 115 |
+
type: "string"
|
| 116 |
+
latency_ms:
|
| 117 |
+
type: "number"
|
| 118 |
+
monitoring:
|
| 119 |
+
type: "object"
|
| 120 |
+
properties:
|
| 121 |
+
status:
|
| 122 |
+
type: "string"
|
| 123 |
+
active_sources:
|
| 124 |
+
type: "integer"
|
| 125 |
+
notifications:
|
| 126 |
+
type: "object"
|
| 127 |
+
properties:
|
| 128 |
+
status:
|
| 129 |
+
type: "string"
|
| 130 |
+
channels:
|
| 131 |
+
type: "array"
|
| 132 |
+
items:
|
| 133 |
+
type: "string"
|
| 134 |
+
timestamp:
|
| 135 |
+
type: "string"
|
| 136 |
+
format: "date-time"
|
| 137 |
+
|
| 138 |
+
# ========================================
|
| 139 |
+
# قسم التهديدات
|
| 140 |
+
# ========================================
|
| 141 |
+
|
| 142 |
+
/threats:
|
| 143 |
+
get:
|
| 144 |
+
tags:
|
| 145 |
+
- "التهديدات"
|
| 146 |
+
summary: "قائمة التهديدات"
|
| 147 |
+
description: "استرجاع قائمة التهديدات المكتشفة مع إمكانية التصفية"
|
| 148 |
+
operationId: "listThreats"
|
| 149 |
+
parameters:
|
| 150 |
+
- name: "status"
|
| 151 |
+
in: "query"
|
| 152 |
+
schema:
|
| 153 |
+
type: "string"
|
| 154 |
+
enum: [blocked, active, ignored, all]
|
| 155 |
+
description: "تصفية حسب الحالة"
|
| 156 |
+
- name: "severity"
|
| 157 |
+
in: "query"
|
| 158 |
+
schema:
|
| 159 |
+
type: "string"
|
| 160 |
+
enum: [critical, high, medium, low, all]
|
| 161 |
+
description: "تصفية حسب الخطورة"
|
| 162 |
+
- name: "limit"
|
| 163 |
+
in: "query"
|
| 164 |
+
schema:
|
| 165 |
+
type: "integer"
|
| 166 |
+
default: 50
|
| 167 |
+
maximum: 100
|
| 168 |
+
description: "عدد النتائج المطلوبة"
|
| 169 |
+
- name: "offset"
|
| 170 |
+
in: "query"
|
| 171 |
+
schema:
|
| 172 |
+
type: "integer"
|
| 173 |
+
default: 0
|
| 174 |
+
description: "رقم البداية"
|
| 175 |
+
responses:
|
| 176 |
+
"200":
|
| 177 |
+
description: "قائمة التهديدات"
|
| 178 |
+
content:
|
| 179 |
+
application/json:
|
| 180 |
+
schema:
|
| 181 |
+
type: "object"
|
| 182 |
+
properties:
|
| 183 |
+
total:
|
| 184 |
+
type: "integer"
|
| 185 |
+
limit:
|
| 186 |
+
type: "integer"
|
| 187 |
+
offset:
|
| 188 |
+
type: "integer"
|
| 189 |
+
threats:
|
| 190 |
+
type: "array"
|
| 191 |
+
items:
|
| 192 |
+
$ref: "#/components/schemas/Threat"
|
| 193 |
+
"400":
|
| 194 |
+
description: "طلب غير صالح"
|
| 195 |
+
|
| 196 |
+
post:
|
| 197 |
+
tags:
|
| 198 |
+
- "التهديدات"
|
| 199 |
+
summary: "إضافة تهديد يدوي"
|
| 200 |
+
description: "إضافة تهديد جديد يدوياً إلى النظام"
|
| 201 |
+
operationId: "createThreat"
|
| 202 |
+
requestBody:
|
| 203 |
+
required: true
|
| 204 |
+
content:
|
| 205 |
+
application/json:
|
| 206 |
+
schema:
|
| 207 |
+
$ref: "#/components/schemas/ThreatCreate"
|
| 208 |
+
responses:
|
| 209 |
+
"201":
|
| 210 |
+
description: "تم إنشاء التهديد بنجاح"
|
| 211 |
+
"400":
|
| 212 |
+
description: "بيانات غير صالحة"
|
| 213 |
+
|
| 214 |
+
/threats/{threat_id}:
|
| 215 |
+
get:
|
| 216 |
+
tags:
|
| 217 |
+
- "التهديدات"
|
| 218 |
+
summary: "تفاصيل تهديد"
|
| 219 |
+
description: "استرجاع تفاصيل تهديد محدد"
|
| 220 |
+
operationId: "getThreat"
|
| 221 |
+
parameters:
|
| 222 |
+
- name: "threat_id"
|
| 223 |
+
in: "path"
|
| 224 |
+
required: true
|
| 225 |
+
schema:
|
| 226 |
+
type: "string"
|
| 227 |
+
responses:
|
| 228 |
+
"200":
|
| 229 |
+
description: "تفاصيل التهديد"
|
| 230 |
+
content:
|
| 231 |
+
application/json:
|
| 232 |
+
schema:
|
| 233 |
+
$ref: "#/components/schemas/Threat"
|
| 234 |
+
"404":
|
| 235 |
+
description: "التهديد غير موجود"
|
| 236 |
+
|
| 237 |
+
delete:
|
| 238 |
+
tags:
|
| 239 |
+
- "التهديدات"
|
| 240 |
+
summary: "حذف تهديد"
|
| 241 |
+
description: "حذف تهديد محدد"
|
| 242 |
+
operationId: "deleteThreat"
|
| 243 |
+
parameters:
|
| 244 |
+
- name: "threat_id"
|
| 245 |
+
in: "path"
|
| 246 |
+
required: true
|
| 247 |
+
schema:
|
| 248 |
+
type: "string"
|
| 249 |
+
responses:
|
| 250 |
+
"204":
|
| 251 |
+
description: "تم حذف التهديد بنجاح"
|
| 252 |
+
"404":
|
| 253 |
+
description: "التهديد غير موجود"
|
| 254 |
+
|
| 255 |
+
# ========================================
|
| 256 |
+
# قسم العناوكات المحظورة
|
| 257 |
+
# ========================================
|
| 258 |
+
|
| 259 |
+
/blocked-ips:
|
| 260 |
+
get:
|
| 261 |
+
tags:
|
| 262 |
+
- "العناوكات المحظورة"
|
| 263 |
+
summary: "قائمة العناوكات المحظورة"
|
| 264 |
+
description: "استرجاع قائمة العناوكات المحظورة"
|
| 265 |
+
operationId: "listBlockedIPs"
|
| 266 |
+
parameters:
|
| 267 |
+
- name: "active"
|
| 268 |
+
in: "query"
|
| 269 |
+
schema:
|
| 270 |
+
type: "boolean"
|
| 271 |
+
description: "تصفية للعناوكات النشطة فقط"
|
| 272 |
+
- name: "limit"
|
| 273 |
+
in: "query"
|
| 274 |
+
schema:
|
| 275 |
+
type: "integer"
|
| 276 |
+
default: 50
|
| 277 |
+
responses:
|
| 278 |
+
"200":
|
| 279 |
+
description: "قائمة العناوكات المحظورة"
|
| 280 |
+
content:
|
| 281 |
+
application/json:
|
| 282 |
+
schema:
|
| 283 |
+
type: "object"
|
| 284 |
+
properties:
|
| 285 |
+
total:
|
| 286 |
+
type: "integer"
|
| 287 |
+
blocked_ips:
|
| 288 |
+
type: "array"
|
| 289 |
+
items:
|
| 290 |
+
$ref: "#/components/schemas/BlockedIP"
|
| 291 |
+
|
| 292 |
+
post:
|
| 293 |
+
tags:
|
| 294 |
+
- "العناوكات المحظورة"
|
| 295 |
+
summary: "حظر عنوان"
|
| 296 |
+
description: "حظر عنوان IP جديد"
|
| 297 |
+
operationId: "blockIP"
|
| 298 |
+
requestBody:
|
| 299 |
+
required: true
|
| 300 |
+
content:
|
| 301 |
+
application/json:
|
| 302 |
+
schema:
|
| 303 |
+
type: "object"
|
| 304 |
+
required:
|
| 305 |
+
- "ip"
|
| 306 |
+
- "reason"
|
| 307 |
+
properties:
|
| 308 |
+
ip:
|
| 309 |
+
type: "string"
|
| 310 |
+
format: "ipv4"
|
| 311 |
+
example: "192.168.1.100"
|
| 312 |
+
reason:
|
| 313 |
+
type: "string"
|
| 314 |
+
example: "Brute force attack detected"
|
| 315 |
+
duration:
|
| 316 |
+
type: "integer"
|
| 317 |
+
description: "مدة الحظر بالدقائق (0 = دائم)"
|
| 318 |
+
default: 0
|
| 319 |
+
responses:
|
| 320 |
+
"201":
|
| 321 |
+
description: "تم حظر العنوان بنجاح"
|
| 322 |
+
"400":
|
| 323 |
+
description: "بيانات غير صالحة"
|
| 324 |
+
|
| 325 |
+
/blocked-ips/{ip}:
|
| 326 |
+
delete:
|
| 327 |
+
tags:
|
| 328 |
+
- "العناوكات المحظورة"
|
| 329 |
+
summary: "إلغاء حظر عنوان"
|
| 330 |
+
description: "إلغاء حظر عنوان IP محدد"
|
| 331 |
+
operationId: "unblockIP"
|
| 332 |
+
parameters:
|
| 333 |
+
- name: "ip"
|
| 334 |
+
in: "path"
|
| 335 |
+
required: true
|
| 336 |
+
schema:
|
| 337 |
+
type: "string"
|
| 338 |
+
responses:
|
| 339 |
+
"204":
|
| 340 |
+
description: "تم إلغاء الحظر بنجاح"
|
| 341 |
+
"404":
|
| 342 |
+
description: "العنوان غير موجود"
|
| 343 |
+
|
| 344 |
+
# ========================================
|
| 345 |
+
# قسم التنبيهات
|
| 346 |
+
# ========================================
|
| 347 |
+
|
| 348 |
+
/alerts:
|
| 349 |
+
get:
|
| 350 |
+
tags:
|
| 351 |
+
- "التنبيهات"
|
| 352 |
+
summary: "قائمة التنبيهات"
|
| 353 |
+
description: "استرجاع قائمة التنبيهات المرسلة"
|
| 354 |
+
operationId: "listAlerts"
|
| 355 |
+
parameters:
|
| 356 |
+
- name: "read"
|
| 357 |
+
in: "query"
|
| 358 |
+
schema:
|
| 359 |
+
type: "boolean"
|
| 360 |
+
description: "تصفية للرسائل المقروءة/غير المقروءة"
|
| 361 |
+
- name: "limit"
|
| 362 |
+
in: "query"
|
| 363 |
+
schema:
|
| 364 |
+
type: "integer"
|
| 365 |
+
default: 50
|
| 366 |
+
responses:
|
| 367 |
+
"200":
|
| 368 |
+
description: "قائمة التنبيهات"
|
| 369 |
+
|
| 370 |
+
post:
|
| 371 |
+
tags:
|
| 372 |
+
- "التنبيهات"
|
| 373 |
+
summary: "إرسال تنبيه"
|
| 374 |
+
description: "إرسال تنبيه يدوي عبر جميع القنوات المفعلة"
|
| 375 |
+
operationId: "sendAlert"
|
| 376 |
+
requestBody:
|
| 377 |
+
required: true
|
| 378 |
+
content:
|
| 379 |
+
application/json:
|
| 380 |
+
schema:
|
| 381 |
+
type: "object"
|
| 382 |
+
required:
|
| 383 |
+
- "title"
|
| 384 |
+
- "message"
|
| 385 |
+
- "severity"
|
| 386 |
+
properties:
|
| 387 |
+
title:
|
| 388 |
+
type: "string"
|
| 389 |
+
example: "تهديد أمني جديد"
|
| 390 |
+
message:
|
| 391 |
+
type: "string"
|
| 392 |
+
example: "اكتشاف محاولة اختراق"
|
| 393 |
+
severity:
|
| 394 |
+
type: "string"
|
| 395 |
+
enum: [critical, high, medium, low]
|
| 396 |
+
channels:
|
| 397 |
+
type: "array"
|
| 398 |
+
items:
|
| 399 |
+
type: "string"
|
| 400 |
+
enum: [slack, discord, email]
|
| 401 |
+
responses:
|
| 402 |
+
"202":
|
| 403 |
+
description: "تم قبول طلب الإرسال"
|
| 404 |
+
"400":
|
| 405 |
+
description: "بيانات غير صالحة"
|
| 406 |
+
|
| 407 |
+
/alerts/stats:
|
| 408 |
+
get:
|
| 409 |
+
tags:
|
| 410 |
+
- "التنبيهات"
|
| 411 |
+
summary: "إحصائيات التنبيهات"
|
| 412 |
+
description: "استرجاع إحصائيات التنبيهات"
|
| 413 |
+
operationId: "getAlertStats"
|
| 414 |
+
responses:
|
| 415 |
+
"200":
|
| 416 |
+
description: "إحصائيات التنبيهات"
|
| 417 |
+
content:
|
| 418 |
+
application/json:
|
| 419 |
+
schema:
|
| 420 |
+
type: "object"
|
| 421 |
+
properties:
|
| 422 |
+
total_sent:
|
| 423 |
+
type: "integer"
|
| 424 |
+
by_channel:
|
| 425 |
+
type: "object"
|
| 426 |
+
by_severity:
|
| 427 |
+
type: "object"
|
| 428 |
+
|
| 429 |
+
# ========================================
|
| 430 |
+
# قسم المراقبة
|
| 431 |
+
# ========================================
|
| 432 |
+
|
| 433 |
+
/monitoring/stats:
|
| 434 |
+
get:
|
| 435 |
+
tags:
|
| 436 |
+
- "المراقبة"
|
| 437 |
+
summary: "إحصائيات المراقبة"
|
| 438 |
+
description: "استرجاع إحصائيات المراقبة والأمان"
|
| 439 |
+
operationId: "getMonitoringStats"
|
| 440 |
+
responses:
|
| 441 |
+
"200":
|
| 442 |
+
description: "إحصائيات المراقبة"
|
| 443 |
+
content:
|
| 444 |
+
application/json:
|
| 445 |
+
schema:
|
| 446 |
+
$ref: "#/components/schemas/MonitoringStats"
|
| 447 |
+
|
| 448 |
+
/monitoring/logs:
|
| 449 |
+
get:
|
| 450 |
+
tags:
|
| 451 |
+
- "المراقبة"
|
| 452 |
+
summary: "سجلات النظام"
|
| 453 |
+
description: "استرجاع سجلات النظام"
|
| 454 |
+
operationId: "getSystemLogs"
|
| 455 |
+
parameters:
|
| 456 |
+
- name: "level"
|
| 457 |
+
in: "query"
|
| 458 |
+
schema:
|
| 459 |
+
type: "string"
|
| 460 |
+
enum: [DEBUG, INFO, WARNING, ERROR]
|
| 461 |
+
- name: "limit"
|
| 462 |
+
in: "query"
|
| 463 |
+
schema:
|
| 464 |
+
type: "integer"
|
| 465 |
+
default: 100
|
| 466 |
+
responses:
|
| 467 |
+
"200":
|
| 468 |
+
description: "سجلات النظام"
|
| 469 |
+
|
| 470 |
+
# ========================================
|
| 471 |
+
# قسم المصادقة
|
| 472 |
+
# ========================================
|
| 473 |
+
|
| 474 |
+
/auth/token:
|
| 475 |
+
post:
|
| 476 |
+
tags:
|
| 477 |
+
- "المصادقة"
|
| 478 |
+
summary: "الحصول على رمز الوصول"
|
| 479 |
+
description: "الحصول على رمز JWT للوصول إلى API"
|
| 480 |
+
operationId: "getToken"
|
| 481 |
+
requestBody:
|
| 482 |
+
required: true
|
| 483 |
+
content:
|
| 484 |
+
application/json:
|
| 485 |
+
schema:
|
| 486 |
+
type: "object"
|
| 487 |
+
required:
|
| 488 |
+
- "username"
|
| 489 |
+
- "password"
|
| 490 |
+
properties:
|
| 491 |
+
username:
|
| 492 |
+
type: "string"
|
| 493 |
+
password:
|
| 494 |
+
type: "string"
|
| 495 |
+
format: "password"
|
| 496 |
+
responses:
|
| 497 |
+
"200":
|
| 498 |
+
description: "رمز الوصول"
|
| 499 |
+
content:
|
| 500 |
+
application/json:
|
| 501 |
+
schema:
|
| 502 |
+
type: "object"
|
| 503 |
+
properties:
|
| 504 |
+
access_token:
|
| 505 |
+
type: "string"
|
| 506 |
+
token_type:
|
| 507 |
+
type: "string"
|
| 508 |
+
example: "bearer"
|
| 509 |
+
expires_in:
|
| 510 |
+
type: "integer"
|
| 511 |
+
"401":
|
| 512 |
+
description: "بيانات اعتماد غير صالحة"
|
| 513 |
+
|
| 514 |
+
# ========================================
|
| 515 |
+
# المخططات (Schemas)
|
| 516 |
+
# ========================================
|
| 517 |
+
|
| 518 |
+
components:
|
| 519 |
+
schemas:
|
| 520 |
+
HealthResponse:
|
| 521 |
+
type: "object"
|
| 522 |
+
properties:
|
| 523 |
+
status:
|
| 524 |
+
type: "string"
|
| 525 |
+
enum: [healthy, unhealthy, degraded]
|
| 526 |
+
example: "healthy"
|
| 527 |
+
version:
|
| 528 |
+
type: "string"
|
| 529 |
+
example: "1.3.0"
|
| 530 |
+
uptime:
|
| 531 |
+
type: "string"
|
| 532 |
+
example: "2d 5h 30m"
|
| 533 |
+
timestamp:
|
| 534 |
+
type: "string"
|
| 535 |
+
format: "date-time"
|
| 536 |
+
example: "2024-10-13T10:30:00Z"
|
| 537 |
+
error:
|
| 538 |
+
type: "string"
|
| 539 |
+
description: "رسالة الخطأ إن وجد"
|
| 540 |
+
|
| 541 |
+
Threat:
|
| 542 |
+
type: "object"
|
| 543 |
+
properties:
|
| 544 |
+
id:
|
| 545 |
+
type: "string"
|
| 546 |
+
format: "uuid"
|
| 547 |
+
type:
|
| 548 |
+
type: "string"
|
| 549 |
+
example: "brute_force"
|
| 550 |
+
source_ip:
|
| 551 |
+
type: "string"
|
| 552 |
+
format: "ipv4"
|
| 553 |
+
target_port:
|
| 554 |
+
type: "integer"
|
| 555 |
+
severity:
|
| 556 |
+
type: "string"
|
| 557 |
+
enum: [critical, high, medium, low]
|
| 558 |
+
status:
|
| 559 |
+
type: "string"
|
| 560 |
+
enum: [blocked, active, ignored]
|
| 561 |
+
timestamp:
|
| 562 |
+
type: "string"
|
| 563 |
+
format: "date-time"
|
| 564 |
+
details:
|
| 565 |
+
type: "string"
|
| 566 |
+
actions:
|
| 567 |
+
type: "array"
|
| 568 |
+
items:
|
| 569 |
+
type: "string"
|
| 570 |
+
|
| 571 |
+
ThreatCreate:
|
| 572 |
+
type: "object"
|
| 573 |
+
required:
|
| 574 |
+
- "type"
|
| 575 |
+
- "source_ip"
|
| 576 |
+
- "severity"
|
| 577 |
+
- "details"
|
| 578 |
+
properties:
|
| 579 |
+
type:
|
| 580 |
+
type: "string"
|
| 581 |
+
source_ip:
|
| 582 |
+
type: "string"
|
| 583 |
+
format: "ipv4"
|
| 584 |
+
target_port:
|
| 585 |
+
type: "integer"
|
| 586 |
+
severity:
|
| 587 |
+
type: "string"
|
| 588 |
+
enum: [critical, high, medium, low]
|
| 589 |
+
details:
|
| 590 |
+
type: "string"
|
| 591 |
+
|
| 592 |
+
BlockedIP:
|
| 593 |
+
type: "object"
|
| 594 |
+
properties:
|
| 595 |
+
ip:
|
| 596 |
+
type: "string"
|
| 597 |
+
format: "ipv4"
|
| 598 |
+
reason:
|
| 599 |
+
type: "string"
|
| 600 |
+
blocked_at:
|
| 601 |
+
type: "string"
|
| 602 |
+
format: "date-time"
|
| 603 |
+
expires_at:
|
| 604 |
+
type: "string"
|
| 605 |
+
format: "date-time"
|
| 606 |
+
active:
|
| 607 |
+
type: "boolean"
|
| 608 |
+
block_count:
|
| 609 |
+
type: "integer"
|
| 610 |
+
|
| 611 |
+
MonitoringStats:
|
| 612 |
+
type: "object"
|
| 613 |
+
properties:
|
| 614 |
+
threats_blocked:
|
| 615 |
+
type: "integer"
|
| 616 |
+
example: 1369
|
| 617 |
+
success_rate:
|
| 618 |
+
type: "number"
|
| 619 |
+
format: "float"
|
| 620 |
+
example: 99.9
|
| 621 |
+
open_issues:
|
| 622 |
+
type: "integer"
|
| 623 |
+
example: 12
|
| 624 |
+
response_time_ms:
|
| 625 |
+
type: "number"
|
| 626 |
+
format: "float"
|
| 627 |
+
example: 100.0
|
| 628 |
+
|
| 629 |
+
securitySchemes:
|
| 630 |
+
bearerAuth:
|
| 631 |
+
type: "http"
|
| 632 |
+
scheme: "bearer"
|
| 633 |
+
bearerFormat: "JWT"
|
docs/configuration.md
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# دليل إعدادات نظام الحارس التلقائي
|
| 2 |
+
# Auto Guardian System Configuration Guide
|
| 3 |
+
# ==========================================
|
| 4 |
+
|
| 5 |
+
## نظرة عامة
|
| 6 |
+
|
| 7 |
+
يحتوي ملف `config/settings.yaml` على جميع إعدادات نظام الحارس التلقائي. هذا الدليل يشرح كل خيار بالتفصيل مع أمثلة عملية. يُرجى قراءة هذا الدليل بعناية قبل تعديل الإعدادات.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## هيكل ملف الإعدادات
|
| 12 |
+
|
| 13 |
+
```
|
| 14 |
+
config/
|
| 15 |
+
├── settings.yaml # الإعدادات الرئيسية
|
| 16 |
+
├── rules.yaml # قواعد الكشف عن التهديدات
|
| 17 |
+
├── alerts.yaml # قوالب التنبيهات
|
| 18 |
+
└── whitelist.yaml # قائمة العناوكات المسموح بها
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
+
## القسم الأول: الإعدادات العامة
|
| 24 |
+
|
| 25 |
+
```yaml
|
| 26 |
+
# config/settings.yaml - القسم العام
|
| 27 |
+
|
| 28 |
+
general:
|
| 29 |
+
# وضع التشغيل: development, testing, production
|
| 30 |
+
mode: development
|
| 31 |
+
|
| 32 |
+
# مستوى التسجيل: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
| 33 |
+
log_level: INFO
|
| 34 |
+
|
| 35 |
+
# المنطقة الزمنية (استخدم تنسيق tzdata)
|
| 36 |
+
timezone: UTC
|
| 37 |
+
|
| 38 |
+
# مسار ملفات السجلات
|
| 39 |
+
log_path: logs/
|
| 40 |
+
|
| 41 |
+
# تفعيل وضع التحسينات (Production فقط)
|
| 42 |
+
optimizations: false
|
| 43 |
+
```
|
| 44 |
+
|
| 45 |
+
### شرح الخيارات
|
| 46 |
+
|
| 47 |
+
| الخيار | القيم الممكنة | الافتراضي | الوصف |
|
| 48 |
+
|--------|---------------|-----------|-------|
|
| 49 |
+
| mode | development, testing, production | development | يحدد بيئة التشغيل |
|
| 50 |
+
| log_level | DEBUG, INFO, WARNING, ERROR, CRITICAL | INFO | يتحكم في كمية السجلات |
|
| 51 |
+
| timezone | أي منطقة زمنية صالحة | UTC | المنطقة الزمنية للسجلات |
|
| 52 |
+
| log_path | مسار مجلد | logs/ | مكان تخزين السجلات |
|
| 53 |
+
| optimizations | true, false | false | تفعيل تحسينات الأداء |
|
| 54 |
+
|
| 55 |
+
---
|
| 56 |
+
|
| 57 |
+
## القسم الثاني: إعدادات المراقبة
|
| 58 |
+
|
| 59 |
+
```yaml
|
| 60 |
+
# config/settings.yaml - قسم المراقبة
|
| 61 |
+
|
| 62 |
+
monitoring:
|
| 63 |
+
# تفعيل المراقبة
|
| 64 |
+
enabled: true
|
| 65 |
+
|
| 66 |
+
# مصادر السجلات للمراقبة
|
| 67 |
+
log_sources:
|
| 68 |
+
- /var/log/auth.log # سجلات المصادقة
|
| 69 |
+
- /var/log/syslog # سجلات النظام العامة
|
| 70 |
+
- /var/log/nginx/access.log # سجلات خادم الويب
|
| 71 |
+
|
| 72 |
+
# الفاصل الزمني للفحص (بالثواني)
|
| 73 |
+
scan_interval: 5
|
| 74 |
+
|
| 75 |
+
# تفعيل الفحص العميق (أبطأ لكنه أكثر دقة)
|
| 76 |
+
deep_scan: false
|
| 77 |
+
|
| 78 |
+
# الأنماط المشبوهة للكشف (قاعدة منفصلة)
|
| 79 |
+
patterns_file: config/rules.yaml
|
| 80 |
+
|
| 81 |
+
# تفعيل المراقبة في الوقت الفعلي
|
| 82 |
+
realtime_monitoring: true
|
| 83 |
+
|
| 84 |
+
# حجم ذاكرة التخزين المؤقت للأحداث
|
| 85 |
+
event_buffer_size: 1000
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
### شرح الخيارات
|
| 89 |
+
|
| 90 |
+
| الخيار | القيم الممكنة | الافتراضي | الوصف |
|
| 91 |
+
|--------|---------------|-----------|-------|
|
| 92 |
+
| enabled | true, false | true | تفعيل أو إلغاء المراقبة |
|
| 93 |
+
| log_sources | قائمة مسارات | - | مصادر السجلات للمراقبة |
|
| 94 |
+
| scan_interval | رقم (ثواني) | 5 | الفاصل بين عمليات الفحص |
|
| 95 |
+
| deep_scan | true, false | false | فحص أعمق وأدق |
|
| 96 |
+
| realtime_monitoring | true, false | true | مراقبة في الوقت الفعلي |
|
| 97 |
+
| event_buffer_size | رقم | 1000 | حجم التخزين المؤقت |
|
| 98 |
+
|
| 99 |
+
---
|
| 100 |
+
|
| 101 |
+
## القسم الثالث: قواعد الكشف
|
| 102 |
+
|
| 103 |
+
```yaml
|
| 104 |
+
# config/rules.yaml - قواعد الكشف
|
| 105 |
+
|
| 106 |
+
# أنماط هجوم القوة الغاشبة
|
| 107 |
+
brute_force:
|
| 108 |
+
enabled: true
|
| 109 |
+
threshold: 5 # عدد المحاولات
|
| 110 |
+
time_window: 60 # بالم seconds
|
| 111 |
+
ports: [22, 2222] # المنافذ المستهدفة
|
| 112 |
+
|
| 113 |
+
# أنماط المسح الضوئي للمنافذ
|
| 114 |
+
port_scan:
|
| 115 |
+
enabled: true
|
| 116 |
+
min_ports: 3 # الحد الأدنى للمنافذ
|
| 117 |
+
time_window: 30 # بالم seconds
|
| 118 |
+
severity: high
|
| 119 |
+
|
| 120 |
+
# أنماط حقن SQL
|
| 121 |
+
sql_injection:
|
| 122 |
+
enabled: true
|
| 123 |
+
severity: critical
|
| 124 |
+
auto_block: true
|
| 125 |
+
|
| 126 |
+
# أنماط XSS
|
| 127 |
+
xss:
|
| 128 |
+
enabled: true
|
| 129 |
+
severity: high
|
| 130 |
+
auto_block: false
|
| 131 |
+
|
| 132 |
+
# أنماط الوصول غير المصرح به
|
| 133 |
+
unauthorized_access:
|
| 134 |
+
enabled: true
|
| 135 |
+
severity: critical
|
| 136 |
+
auto_block: true
|
| 137 |
+
```
|
| 138 |
+
|
| 139 |
+
---
|
| 140 |
+
|
| 141 |
+
## القسم الرابع: إعدادات الحظر
|
| 142 |
+
|
| 143 |
+
```yaml
|
| 144 |
+
# config/settings.yaml - قسم الحظر
|
| 145 |
+
|
| 146 |
+
blocking:
|
| 147 |
+
# تفعيل الحظر التلقائي
|
| 148 |
+
enabled: true
|
| 149 |
+
|
| 150 |
+
# عدد المحاولات قبل الحظر
|
| 151 |
+
threshold: 5
|
| 152 |
+
|
| 153 |
+
# الفترة الزمنية للمحاولات (بالثواني)
|
| 154 |
+
time_window: 60
|
| 155 |
+
|
| 156 |
+
# تفعيل IPTables للحظر
|
| 157 |
+
use_iptables: true
|
| 158 |
+
|
| 159 |
+
# تفعيل firewalld للحظر
|
| 160 |
+
use_firewalld: false
|
| 161 |
+
|
| 162 |
+
# تفعيل الحظر في Cloudflare
|
| 163 |
+
use_cloudflare: false
|
| 164 |
+
|
| 165 |
+
# قائمة السماح (عناوكات لا تُحظر)
|
| 166 |
+
whitelist:
|
| 167 |
+
- 127.0.0.1
|
| 168 |
+
- 192.168.1.1
|
| 169 |
+
- 10.0.0.1
|
| 170 |
+
|
| 171 |
+
# قائمة الحظر الدائم
|
| 172 |
+
blacklist: []
|
| 173 |
+
|
| 174 |
+
# مدة الحظر الافتراضية (بالدقائق، 0 = دائم)
|
| 175 |
+
default_duration: 0
|
| 176 |
+
|
| 177 |
+
# إرسال إشعار عند الحظر
|
| 178 |
+
notify_on_block: true
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
### شرح الخيارات
|
| 182 |
+
|
| 183 |
+
| الخيار | القيم الممكنة | الافتراضي | الوصف |
|
| 184 |
+
|--------|---------------|-----------|-------|
|
| 185 |
+
| enabled | true, false | true | تفعيل الحظر التلقائي |
|
| 186 |
+
| threshold | رقم | 5 | عدد المحاولات قبل الحظر |
|
| 187 |
+
| time_window | رقم (ثواني) | 60 | الفترة الزمنية |
|
| 188 |
+
| use_iptables | true, false | true | استخدام IPTables |
|
| 189 |
+
| whitelist | قائمة IPs | [] | عناوين لا تُحظر |
|
| 190 |
+
| default_duration | رقم (دقائق) | 0 | مدة الحظر الافتراضية |
|
| 191 |
+
|
| 192 |
+
---
|
| 193 |
+
|
| 194 |
+
## القسم الخامس: إعدادات الإشعارات
|
| 195 |
+
|
| 196 |
+
```yaml
|
| 197 |
+
# config/settings.yaml - قسم الإشعارات
|
| 198 |
+
|
| 199 |
+
notifications:
|
| 200 |
+
# تفعيل الإشعارات
|
| 201 |
+
enabled: true
|
| 202 |
+
|
| 203 |
+
# عنوان المرسل
|
| 204 |
+
sender_name: "Auto-Guardian System"
|
| 205 |
+
|
| 206 |
+
# ---- Slack ----
|
| 207 |
+
slack:
|
| 208 |
+
enabled: false
|
| 209 |
+
webhook_url: ""
|
| 210 |
+
channel: "security-alerts"
|
| 211 |
+
username: "Auto-Guardian"
|
| 212 |
+
icon_emoji: ":shield:"
|
| 213 |
+
|
| 214 |
+
# ---- Discord ----
|
| 215 |
+
discord:
|
| 216 |
+
enabled: false
|
| 217 |
+
webhook_url: ""
|
| 218 |
+
username: "Auto-Guardian"
|
| 219 |
+
avatar_url: ""
|
| 220 |
+
|
| 221 |
+
# ---- البريد الإلكتروني ----
|
| 222 |
+
email:
|
| 223 |
+
enabled: false
|
| 224 |
+
smtp_host: "smtp.gmail.com"
|
| 225 |
+
smtp_port: 587
|
| 226 |
+
use_tls: true
|
| 227 |
+
username: ""
|
| 228 |
+
password: ""
|
| 229 |
+
from_address: "noreply@autoguardian.local"
|
| 230 |
+
to_addresses:
|
| 231 |
+
- "admin@example.com"
|
| 232 |
+
|
| 233 |
+
# ---- عام ----
|
| 234 |
+
# تفعيل الإشعارات للتهديدات الحرجة فقط
|
| 235 |
+
critical_only: false
|
| 236 |
+
|
| 237 |
+
# وقت عدم الإرسال (بالساعات، 0 = نش)
|
| 238 |
+
quietط دائماً_hours: 0
|
| 239 |
+
```
|
| 240 |
+
|
| 241 |
+
---
|
| 242 |
+
|
| 243 |
+
## القسم السادس: إعدادات Prometheus
|
| 244 |
+
|
| 245 |
+
```yaml
|
| 246 |
+
# config/settings.yaml - قسم Prometheus
|
| 247 |
+
|
| 248 |
+
prometheus:
|
| 249 |
+
# تفعيل Prometheus
|
| 250 |
+
enabled: true
|
| 251 |
+
|
| 252 |
+
# منفذ الاستماع
|
| 253 |
+
port: 9090
|
| 254 |
+
|
| 255 |
+
# مسار /metrics
|
| 256 |
+
metrics_path: /metrics
|
| 257 |
+
|
| 258 |
+
# تفعيل جمع السجلات
|
| 259 |
+
include_logs: true
|
| 260 |
+
|
| 261 |
+
# تضمين معلومات النظام
|
| 262 |
+
include_system_info: true
|
| 263 |
+
|
| 264 |
+
# تضمين معلومات التهديدات
|
| 265 |
+
include_threat_info: true
|
| 266 |
+
```
|
| 267 |
+
|
| 268 |
+
### مقاييس Prometheus المتاحة
|
| 269 |
+
|
| 270 |
+
| المقياس | النوع | الوصف |
|
| 271 |
+
|---------|-------|-------|
|
| 272 |
+
| autoguardian_threats_total | Counter | إجمالي التهديدات |
|
| 273 |
+
| autoguardian_blocked_ips | Gauge | عدد العناوكات المحظورة |
|
| 274 |
+
| autoguardian_blocked_ips_active | Gauge | العناوكات النشطة |
|
| 275 |
+
| autoguardian_success_rate | Gauge | معدل النجاح |
|
| 276 |
+
| autoguardian_response_time_seconds | Histogram | زمن الاستجابة |
|
| 277 |
+
| autoguardian_alerts_sent | Counter | التنبيهات المرسلة |
|
| 278 |
+
|
| 279 |
+
---
|
| 280 |
+
|
| 281 |
+
## القسم السابع: إعدادات الأمان
|
| 282 |
+
|
| 283 |
+
```yaml
|
| 284 |
+
# config/settings.yaml - قسم الأمان
|
| 285 |
+
|
| 286 |
+
security:
|
| 287 |
+
# تفعيل التحقق من التحديثات الأمنية
|
| 288 |
+
security_checks: true
|
| 289 |
+
|
| 290 |
+
# فترة التحقق من التحديثات (بالساعات)
|
| 291 |
+
check_interval: 24
|
| 292 |
+
|
| 293 |
+
# تفعيل تسجيل التدقيق
|
| 294 |
+
audit_logging: true
|
| 295 |
+
|
| 296 |
+
# مسار ملف سجل التدقيق
|
| 297 |
+
audit_log_path: logs/audit.log
|
| 298 |
+
|
| 299 |
+
# تفعيل HTTPS
|
| 300 |
+
use_https: false
|
| 301 |
+
|
| 302 |
+
# ملف الشهادة (للإنتاج)
|
| 303 |
+
ssl_cert: ""
|
| 304 |
+
ssl_key: ""
|
| 305 |
+
|
| 306 |
+
# فترة انتهاء الجلسة (بالساعات)
|
| 307 |
+
session_timeout: 24
|
| 308 |
+
```
|
| 309 |
+
|
| 310 |
+
---
|
| 311 |
+
|
| 312 |
+
## أمثلة التكوين
|
| 313 |
+
|
| 314 |
+
### تكوين التطوير
|
| 315 |
+
|
| 316 |
+
```yaml
|
| 317 |
+
# config/settings.yaml - وضع التطوير
|
| 318 |
+
|
| 319 |
+
general:
|
| 320 |
+
mode: development
|
| 321 |
+
log_level: DEBUG
|
| 322 |
+
timezone: UTC
|
| 323 |
+
|
| 324 |
+
monitoring:
|
| 325 |
+
enabled: true
|
| 326 |
+
scan_interval: 5
|
| 327 |
+
deep_scan: false
|
| 328 |
+
|
| 329 |
+
blocking:
|
| 330 |
+
enabled: false # لا تحظر في التطوير
|
| 331 |
+
|
| 332 |
+
notifications:
|
| 333 |
+
enabled: false # لا ترسل إشعارات في التطوير
|
| 334 |
+
|
| 335 |
+
prometheus:
|
| 336 |
+
enabled: false
|
| 337 |
+
```
|
| 338 |
+
|
| 339 |
+
### تكوين الإنتاج
|
| 340 |
+
|
| 341 |
+
```yaml
|
| 342 |
+
# config/settings.yaml - وضع الإنتاج
|
| 343 |
+
|
| 344 |
+
general:
|
| 345 |
+
mode: production
|
| 346 |
+
log_level: WARNING
|
| 347 |
+
timezone: Asia/Riyadh
|
| 348 |
+
|
| 349 |
+
monitoring:
|
| 350 |
+
enabled: true
|
| 351 |
+
scan_interval: 1
|
| 352 |
+
deep_scan: true
|
| 353 |
+
|
| 354 |
+
blocking:
|
| 355 |
+
enabled: true
|
| 356 |
+
threshold: 3
|
| 357 |
+
time_window: 30
|
| 358 |
+
use_iptables: true
|
| 359 |
+
default_duration: 360 # 6 ساعات
|
| 360 |
+
|
| 361 |
+
notifications:
|
| 362 |
+
enabled: true
|
| 363 |
+
slack:
|
| 364 |
+
enabled: true
|
| 365 |
+
webhook_url: ${SLACK_WEBHOOK_URL}
|
| 366 |
+
discord:
|
| 367 |
+
enabled: true
|
| 368 |
+
webhook_url: ${DISCORD_WEBHOOK_URL}
|
| 369 |
+
|
| 370 |
+
prometheus:
|
| 371 |
+
enabled: true
|
| 372 |
+
port: 9090
|
| 373 |
+
|
| 374 |
+
security:
|
| 375 |
+
security_checks: true
|
| 376 |
+
audit_logging: true
|
| 377 |
+
use_https: true
|
| 378 |
+
ssl_cert: /etc/ssl/certs/cert.pem
|
| 379 |
+
ssl_key: /etc/ssl/private/key.pem
|
| 380 |
+
session_timeout: 8
|
| 381 |
+
```
|
| 382 |
+
|
| 383 |
+
---
|
| 384 |
+
|
| 385 |
+
## متغيرات البيئة
|
| 386 |
+
|
| 387 |
+
يمكن تجاوز إعدادات YAML باستخدام متغيرات البيئة:
|
| 388 |
+
|
| 389 |
+
| متغير البيئة | المقابل في YAML |
|
| 390 |
+
|--------------|-----------------|
|
| 391 |
+
| AG_MODE | general.mode |
|
| 392 |
+
| AG_LOG_LEVEL | general.log_level |
|
| 393 |
+
| AG_BLOCKING_ENABLED | blocking.enabled |
|
| 394 |
+
| AG_SLACK_WEBHOOK_URL | notifications.slack.webhook_url |
|
| 395 |
+
| AG_PROMETHEUS_PORT | prometheus.port |
|
| 396 |
+
|
| 397 |
+
مثال:
|
| 398 |
+
|
| 399 |
+
```bash
|
| 400 |
+
export AG_MODE=production
|
| 401 |
+
export AG_LOG_LEVEL=WARNING
|
| 402 |
+
export AG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
|
| 403 |
+
```
|
| 404 |
+
|
| 405 |
+
---
|
| 406 |
+
|
| 407 |
+
## التحقق من الإعدادات
|
| 408 |
+
|
| 409 |
+
للتحقق من صحة ملف الإعدادات:
|
| 410 |
+
|
| 411 |
+
```bash
|
| 412 |
+
python -c "
|
| 413 |
+
import yaml
|
| 414 |
+
with open('config/settings.yaml') as f:
|
| 415 |
+
config = yaml.safe_load(f)
|
| 416 |
+
print('✅ الإعدادات صالحة')
|
| 417 |
+
print(f'وضع التشغيل: {config[\"general\"][\"mode\"]}')
|
| 418 |
+
print(f'المسار: {config[\"monitoring\"][\"enabled\"]}')
|
| 419 |
+
"
|
| 420 |
+
```
|
| 421 |
+
|
| 422 |
+
---
|
| 423 |
+
|
| 424 |
+
## الدعم
|
| 425 |
+
|
| 426 |
+
للمساعدة في الإعدادات:
|
| 427 |
+
|
| 428 |
+
- **المستندات:** راجع التوثيق الكامل
|
| 429 |
+
- **GitHub Issues:** أبلغ عن مشكلة
|
| 430 |
+
- **البريد:** support@autoguardian.local
|
google7cceda004d653872.html
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
google-site-verification: google7cceda004d653872.html
|
graphics/data-analysis-icon.svg
ADDED
|
|
graphics/monitoring-icon.svg
ADDED
|
|
graphics/shield-icon.svg
ADDED
|
|
index.html
ADDED
|
@@ -0,0 +1,1724 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ar" dir="rtl">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Auto-Guardian Dashboard</title>
|
| 7 |
+
<meta name="google-site-verification" content="google7cceda004d653872" />
|
| 8 |
+
<meta name="description" content="Auto-Guardian: A comprehensive security and monitoring system dashboard for modern infrastructure. Automated security monitoring and protection core system." />
|
| 9 |
+
<meta name="keywords" content="security, monitoring, automation, guardian, dashboard, infrastructure, protection" />
|
| 10 |
+
<meta name="author" content="Abdulelah Othman Gwaith" />
|
| 11 |
+
<meta property="og:title" content="Auto-Guardian Dashboard" />
|
| 12 |
+
<meta property="og:description" content="Automated security monitoring and protection core system." />
|
| 13 |
+
<meta property="og:url" content="https://abdulelahothmangwaith.github.io/Auto-Guardian-Core/" />
|
| 14 |
+
<meta property="og:type" content="website" />
|
| 15 |
+
<script type="application/ld+json">
|
| 16 |
+
{
|
| 17 |
+
"@context": "https://schema.org",
|
| 18 |
+
"@type": "SoftwareApplication",
|
| 19 |
+
"name": "Auto-Guardian-Core",
|
| 20 |
+
"operatingSystem": "Linux, Windows, macOS",
|
| 21 |
+
"applicationCategory": "SecurityApplication",
|
| 22 |
+
"offers": {
|
| 23 |
+
"@type": "Offer",
|
| 24 |
+
"price": "0",
|
| 25 |
+
"priceCurrency": "USD"
|
| 26 |
+
},
|
| 27 |
+
"author": {
|
| 28 |
+
"@type": "Person",
|
| 29 |
+
"name": "Abdulelah Othman Gwaith"
|
| 30 |
+
},
|
| 31 |
+
"description": "An automated security monitoring and protection core system designed for modern infrastructure.",
|
| 32 |
+
"url": "https://abdulelahothmangwaith.github.io/Auto-Guardian-Core/"
|
| 33 |
+
}
|
| 34 |
+
</script>
|
| 35 |
+
<style>
|
| 36 |
+
* {
|
| 37 |
+
margin: 0;
|
| 38 |
+
padding: 0;
|
| 39 |
+
box-sizing: border-box;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
:root {
|
| 43 |
+
--primary: #0F172A;
|
| 44 |
+
--secondary: #3B82F6;
|
| 45 |
+
--success: #10B981;
|
| 46 |
+
--danger: #EF4444;
|
| 47 |
+
--warning: #F59E0B;
|
| 48 |
+
--bg: #F8FAFC;
|
| 49 |
+
--card-bg: #FFFFFF;
|
| 50 |
+
--text: #1E293B;
|
| 51 |
+
--text-muted: #64748B;
|
| 52 |
+
--border: #E2E8F0;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
body {
|
| 56 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 57 |
+
background-color: var(--bg);
|
| 58 |
+
color: var(--text);
|
| 59 |
+
min-height: 100vh;
|
| 60 |
+
overflow-x: hidden;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
.dashboard {
|
| 64 |
+
display: flex;
|
| 65 |
+
flex-direction: row;
|
| 66 |
+
min-height: 100vh;
|
| 67 |
+
width: 100%;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
/* Sidebar */
|
| 71 |
+
.sidebar {
|
| 72 |
+
background: var(--primary);
|
| 73 |
+
color: white;
|
| 74 |
+
padding: 20px 0;
|
| 75 |
+
width: 240px;
|
| 76 |
+
height: 100vh;
|
| 77 |
+
overflow-y: auto;
|
| 78 |
+
flex-shrink: 0;
|
| 79 |
+
position: sticky;
|
| 80 |
+
top: 0;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
.logo {
|
| 84 |
+
padding: 20px;
|
| 85 |
+
text-align: center;
|
| 86 |
+
border-bottom: 1px solid rgba(255,255,255,0.1);
|
| 87 |
+
margin-bottom: 20px;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.logo h1 {
|
| 91 |
+
font-size: 20px;
|
| 92 |
+
font-weight: 700;
|
| 93 |
+
color: var(--secondary);
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
.logo span {
|
| 97 |
+
font-size: 12px;
|
| 98 |
+
color: var(--text-muted);
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.nav-menu {
|
| 102 |
+
list-style: none;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
.nav-item {
|
| 106 |
+
padding: 12px 20px;
|
| 107 |
+
display: flex;
|
| 108 |
+
align-items: center;
|
| 109 |
+
gap: 12px;
|
| 110 |
+
cursor: pointer;
|
| 111 |
+
transition: all 0.3s ease;
|
| 112 |
+
border-right: 3px solid transparent;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
.nav-item:hover, .nav-item.active {
|
| 116 |
+
background: rgba(59, 130, 246, 0.1);
|
| 117 |
+
border-right-color: var(--secondary);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
.nav-item svg {
|
| 121 |
+
width: 20px;
|
| 122 |
+
height: 20px;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.nav-item span {
|
| 126 |
+
font-size: 14px;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
/* Main Content */
|
| 130 |
+
.main-content {
|
| 131 |
+
flex: 1;
|
| 132 |
+
padding: 20px 30px;
|
| 133 |
+
min-width: 0;
|
| 134 |
+
overflow-x: hidden;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
/* Header */
|
| 138 |
+
.header {
|
| 139 |
+
display: flex;
|
| 140 |
+
justify-content: space-between;
|
| 141 |
+
align-items: center;
|
| 142 |
+
margin-bottom: 30px;
|
| 143 |
+
flex-wrap: wrap;
|
| 144 |
+
gap: 15px;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.header h2 {
|
| 148 |
+
font-size: 24px;
|
| 149 |
+
font-weight: 600;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.header-actions {
|
| 153 |
+
display: flex;
|
| 154 |
+
gap: 12px;
|
| 155 |
+
align-items: center;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
.search-box {
|
| 159 |
+
display: flex;
|
| 160 |
+
align-items: center;
|
| 161 |
+
background: var(--card-bg);
|
| 162 |
+
border: 1px solid var(--border);
|
| 163 |
+
border-radius: 8px;
|
| 164 |
+
padding: 8px 16px;
|
| 165 |
+
gap: 8px;
|
| 166 |
+
position: relative;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
.search-box:hover {
|
| 170 |
+
border-color: var(--secondary);
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
.search-box input {
|
| 174 |
+
border: none;
|
| 175 |
+
outline: none;
|
| 176 |
+
font-size: 14px;
|
| 177 |
+
width: 150px;
|
| 178 |
+
background: transparent;
|
| 179 |
+
flex: 1;
|
| 180 |
+
min-width: 100px;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
.search-results {
|
| 184 |
+
display: none;
|
| 185 |
+
position: absolute;
|
| 186 |
+
top: 100%;
|
| 187 |
+
left: 0;
|
| 188 |
+
right: 0;
|
| 189 |
+
background: white;
|
| 190 |
+
border: 1px solid var(--border);
|
| 191 |
+
border-radius: 8px;
|
| 192 |
+
margin-top: 8px;
|
| 193 |
+
max-height: 300px;
|
| 194 |
+
overflow-y: auto;
|
| 195 |
+
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
|
| 196 |
+
z-index: 100;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
.search-results.active {
|
| 200 |
+
display: block;
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
.search-result-item {
|
| 204 |
+
padding: 12px 16px;
|
| 205 |
+
border-bottom: 1px solid var(--border);
|
| 206 |
+
cursor: pointer;
|
| 207 |
+
transition: background 0.3s ease;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.search-result-item:hover {
|
| 211 |
+
background: var(--bg);
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
.search-result-item:last-child {
|
| 215 |
+
border-bottom: none;
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
.notification-btn {
|
| 219 |
+
position: relative;
|
| 220 |
+
background: var(--card-bg);
|
| 221 |
+
border: 1px solid var(--border);
|
| 222 |
+
border-radius: 8px;
|
| 223 |
+
padding: 8px 12px;
|
| 224 |
+
cursor: pointer;
|
| 225 |
+
transition: all 0.3s ease;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
.notification-btn:hover {
|
| 229 |
+
border-color: var(--secondary);
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
.notification-badge {
|
| 233 |
+
position: absolute;
|
| 234 |
+
top: -5px;
|
| 235 |
+
right: -5px;
|
| 236 |
+
background: var(--danger);
|
| 237 |
+
color: white;
|
| 238 |
+
font-size: 10px;
|
| 239 |
+
padding: 2px 6px;
|
| 240 |
+
border-radius: 10px;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
/* Settings Panel */
|
| 244 |
+
.settings-panel {
|
| 245 |
+
display: none;
|
| 246 |
+
position: fixed;
|
| 247 |
+
top: 0;
|
| 248 |
+
left: 0;
|
| 249 |
+
width: 100%;
|
| 250 |
+
height: 100%;
|
| 251 |
+
background: rgba(0,0,0,0.5);
|
| 252 |
+
z-index: 1000;
|
| 253 |
+
justify-content: center;
|
| 254 |
+
align-items: center;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
.settings-panel.active {
|
| 258 |
+
display: flex;
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
.settings-content {
|
| 262 |
+
background: white;
|
| 263 |
+
border-radius: 16px;
|
| 264 |
+
padding: 30px;
|
| 265 |
+
width: 90%;
|
| 266 |
+
max-width: 500px;
|
| 267 |
+
max-height: 80vh;
|
| 268 |
+
overflow-y: auto;
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
.settings-header {
|
| 272 |
+
display: flex;
|
| 273 |
+
justify-content: space-between;
|
| 274 |
+
align-items: center;
|
| 275 |
+
margin-bottom: 24px;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.settings-header h3 {
|
| 279 |
+
font-size: 20px;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
.close-btn {
|
| 283 |
+
background: none;
|
| 284 |
+
border: none;
|
| 285 |
+
font-size: 24px;
|
| 286 |
+
cursor: pointer;
|
| 287 |
+
color: var(--text-muted);
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
.setting-item {
|
| 291 |
+
margin-bottom: 20px;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
.setting-label {
|
| 295 |
+
display: block;
|
| 296 |
+
font-size: 14px;
|
| 297 |
+
font-weight: 500;
|
| 298 |
+
margin-bottom: 8px;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
.setting-description {
|
| 302 |
+
font-size: 12px;
|
| 303 |
+
color: var(--text-muted);
|
| 304 |
+
margin-bottom: 8px;
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
.setting-input {
|
| 308 |
+
width: 100%;
|
| 309 |
+
padding: 10px 14px;
|
| 310 |
+
border: 1px solid var(--border);
|
| 311 |
+
border-radius: 8px;
|
| 312 |
+
font-size: 14px;
|
| 313 |
+
transition: all 0.3s ease;
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
.setting-input:focus {
|
| 317 |
+
outline: none;
|
| 318 |
+
border-color: var(--secondary);
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
.setting-select {
|
| 322 |
+
width: 100%;
|
| 323 |
+
padding: 10px 14px;
|
| 324 |
+
border: 1px solid var(--border);
|
| 325 |
+
border-radius: 8px;
|
| 326 |
+
font-size: 14px;
|
| 327 |
+
background: white;
|
| 328 |
+
cursor: pointer;
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
.setting-toggle {
|
| 332 |
+
display: flex;
|
| 333 |
+
align-items: center;
|
| 334 |
+
gap: 12px;
|
| 335 |
+
cursor: pointer;
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
.toggle-switch {
|
| 339 |
+
position: relative;
|
| 340 |
+
width: 50px;
|
| 341 |
+
height: 26px;
|
| 342 |
+
background: var(--border);
|
| 343 |
+
border-radius: 13px;
|
| 344 |
+
transition: all 0.3s ease;
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
.toggle-switch.active {
|
| 348 |
+
background: var(--secondary);
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
.toggle-switch::after {
|
| 352 |
+
content: '';
|
| 353 |
+
position: absolute;
|
| 354 |
+
width: 22px;
|
| 355 |
+
height: 22px;
|
| 356 |
+
background: white;
|
| 357 |
+
border-radius: 50%;
|
| 358 |
+
top: 2px;
|
| 359 |
+
left: 2px;
|
| 360 |
+
transition: all 0.3s ease;
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
.toggle-switch.active::after {
|
| 364 |
+
left: 26px;
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
.save-btn {
|
| 368 |
+
width: 100%;
|
| 369 |
+
padding: 12px;
|
| 370 |
+
background: var(--secondary);
|
| 371 |
+
color: white;
|
| 372 |
+
border: none;
|
| 373 |
+
border-radius: 8px;
|
| 374 |
+
font-size: 14px;
|
| 375 |
+
font-weight: 500;
|
| 376 |
+
cursor: pointer;
|
| 377 |
+
transition: all 0.3s ease;
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
.save-btn:hover {
|
| 381 |
+
background: var(--primary);
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
/* Stats Grid */
|
| 385 |
+
.stats-grid {
|
| 386 |
+
display: grid;
|
| 387 |
+
grid-template-columns: repeat(4, 1fr);
|
| 388 |
+
gap: 20px;
|
| 389 |
+
margin-bottom: 30px;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.stat-card {
|
| 393 |
+
background: var(--card-bg);
|
| 394 |
+
border-radius: 12px;
|
| 395 |
+
padding: 20px;
|
| 396 |
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
| 397 |
+
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
| 398 |
+
cursor: pointer;
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
.stat-card:hover {
|
| 402 |
+
transform: translateY(-2px);
|
| 403 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
.stat-header {
|
| 407 |
+
display: flex;
|
| 408 |
+
justify-content: space-between;
|
| 409 |
+
align-items: flex-start;
|
| 410 |
+
margin-bottom: 12px;
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
.stat-icon {
|
| 414 |
+
width: 40px;
|
| 415 |
+
height: 40px;
|
| 416 |
+
border-radius: 10px;
|
| 417 |
+
display: flex;
|
| 418 |
+
align-items: center;
|
| 419 |
+
justify-content: center;
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
.stat-icon.blue { background: rgba(59, 130, 246, 0.1); color: var(--secondary); }
|
| 423 |
+
.stat-icon.green { background: rgba(16, 185, 129, 0.1); color: var(--success); }
|
| 424 |
+
.stat-icon.red { background: rgba(239, 68, 68, 0.1); color: var(--danger); }
|
| 425 |
+
.stat-icon.yellow { background: rgba(245, 158, 11, 0.1); color: var(--warning); }
|
| 426 |
+
|
| 427 |
+
.stat-trend {
|
| 428 |
+
font-size: 12px;
|
| 429 |
+
display: flex;
|
| 430 |
+
align-items: center;
|
| 431 |
+
gap: 4px;
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
.stat-trend.up { color: var(--success); }
|
| 435 |
+
.stat-trend.down { color: var(--danger); }
|
| 436 |
+
|
| 437 |
+
.stat-value {
|
| 438 |
+
font-size: 28px;
|
| 439 |
+
font-weight: 700;
|
| 440 |
+
margin-bottom: 4px;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
.stat-label {
|
| 444 |
+
font-size: 13px;
|
| 445 |
+
color: var(--text-muted);
|
| 446 |
+
}
|
| 447 |
+
|
| 448 |
+
/* Charts Section */
|
| 449 |
+
.charts-section {
|
| 450 |
+
display: grid;
|
| 451 |
+
grid-template-columns: 2fr 1fr;
|
| 452 |
+
gap: 20px;
|
| 453 |
+
margin-bottom: 30px;
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
.chart-card {
|
| 457 |
+
background: var(--card-bg);
|
| 458 |
+
border-radius: 12px;
|
| 459 |
+
padding: 20px;
|
| 460 |
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
| 461 |
+
}
|
| 462 |
+
|
| 463 |
+
.chart-header {
|
| 464 |
+
display: flex;
|
| 465 |
+
justify-content: space-between;
|
| 466 |
+
align-items: center;
|
| 467 |
+
margin-bottom: 20px;
|
| 468 |
+
}
|
| 469 |
+
|
| 470 |
+
.chart-title {
|
| 471 |
+
font-size: 16px;
|
| 472 |
+
font-weight: 600;
|
| 473 |
+
}
|
| 474 |
+
|
| 475 |
+
.chart-tabs {
|
| 476 |
+
display: flex;
|
| 477 |
+
gap: 8px;
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
.chart-tab {
|
| 481 |
+
padding: 6px 12px;
|
| 482 |
+
border-radius: 6px;
|
| 483 |
+
font-size: 12px;
|
| 484 |
+
cursor: pointer;
|
| 485 |
+
background: var(--bg);
|
| 486 |
+
border: none;
|
| 487 |
+
transition: all 0.3s ease;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
.chart-tab.active {
|
| 491 |
+
background: var(--secondary);
|
| 492 |
+
color: white;
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
.chart-tab:hover:not(.active) {
|
| 496 |
+
background: var(--border);
|
| 497 |
+
}
|
| 498 |
+
|
| 499 |
+
/* Area Chart */
|
| 500 |
+
.area-chart {
|
| 501 |
+
height: 250px;
|
| 502 |
+
position: relative;
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
.chart-svg {
|
| 506 |
+
width: 100%;
|
| 507 |
+
height: 100%;
|
| 508 |
+
}
|
| 509 |
+
|
| 510 |
+
/* Donut Chart */
|
| 511 |
+
.donut-chart {
|
| 512 |
+
display: flex;
|
| 513 |
+
align-items: center;
|
| 514 |
+
justify-content: center;
|
| 515 |
+
gap: 30px;
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
.donut-svg {
|
| 519 |
+
width: 180px;
|
| 520 |
+
height: 180px;
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
.donut-legend {
|
| 524 |
+
display: flex;
|
| 525 |
+
flex-direction: column;
|
| 526 |
+
gap: 12px;
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
.legend-item {
|
| 530 |
+
display: flex;
|
| 531 |
+
align-items: center;
|
| 532 |
+
gap: 8px;
|
| 533 |
+
}
|
| 534 |
+
|
| 535 |
+
.legend-color {
|
| 536 |
+
width: 12px;
|
| 537 |
+
height: 12px;
|
| 538 |
+
border-radius: 3px;
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
.legend-label {
|
| 542 |
+
font-size: 13px;
|
| 543 |
+
color: var(--text-muted);
|
| 544 |
+
}
|
| 545 |
+
|
| 546 |
+
.legend-value {
|
| 547 |
+
font-size: 14px;
|
| 548 |
+
font-weight: 600;
|
| 549 |
+
margin-right: auto;
|
| 550 |
+
}
|
| 551 |
+
|
| 552 |
+
/* Activity Section */
|
| 553 |
+
.activity-section {
|
| 554 |
+
display: grid;
|
| 555 |
+
grid-template-columns: 1fr 1fr;
|
| 556 |
+
gap: 20px;
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
.activity-card {
|
| 560 |
+
background: var(--card-bg);
|
| 561 |
+
border-radius: 12px;
|
| 562 |
+
padding: 20px;
|
| 563 |
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
| 564 |
+
}
|
| 565 |
+
|
| 566 |
+
.activity-header {
|
| 567 |
+
display: flex;
|
| 568 |
+
justify-content: space-between;
|
| 569 |
+
align-items: center;
|
| 570 |
+
margin-bottom: 16px;
|
| 571 |
+
}
|
| 572 |
+
|
| 573 |
+
.activity-title {
|
| 574 |
+
font-size: 16px;
|
| 575 |
+
font-weight: 600;
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
.view-all {
|
| 579 |
+
font-size: 13px;
|
| 580 |
+
color: var(--secondary);
|
| 581 |
+
cursor: pointer;
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
.view-all:hover {
|
| 585 |
+
text-decoration: underline;
|
| 586 |
+
}
|
| 587 |
+
|
| 588 |
+
/* Issues List */
|
| 589 |
+
.issues-list {
|
| 590 |
+
display: flex;
|
| 591 |
+
flex-direction: column;
|
| 592 |
+
gap: 12px;
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
.issue-item {
|
| 596 |
+
display: flex;
|
| 597 |
+
align-items: center;
|
| 598 |
+
gap: 12px;
|
| 599 |
+
padding: 12px;
|
| 600 |
+
background: var(--bg);
|
| 601 |
+
border-radius: 8px;
|
| 602 |
+
transition: all 0.3s ease;
|
| 603 |
+
cursor: pointer;
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
.issue-item:hover {
|
| 607 |
+
background: rgba(59, 130, 246, 0.05);
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
.issue-icon {
|
| 611 |
+
width: 32px;
|
| 612 |
+
height: 32px;
|
| 613 |
+
border-radius: 8px;
|
| 614 |
+
display: flex;
|
| 615 |
+
align-items: center;
|
| 616 |
+
justify-content: center;
|
| 617 |
+
}
|
| 618 |
+
|
| 619 |
+
.issue-content {
|
| 620 |
+
flex: 1;
|
| 621 |
+
}
|
| 622 |
+
|
| 623 |
+
.issue-title {
|
| 624 |
+
font-size: 13px;
|
| 625 |
+
font-weight: 500;
|
| 626 |
+
margin-bottom: 2px;
|
| 627 |
+
}
|
| 628 |
+
|
| 629 |
+
.issue-meta {
|
| 630 |
+
font-size: 11px;
|
| 631 |
+
color: var(--text-muted);
|
| 632 |
+
}
|
| 633 |
+
|
| 634 |
+
.issue-badge {
|
| 635 |
+
padding: 4px 10px;
|
| 636 |
+
border-radius: 20px;
|
| 637 |
+
font-size: 11px;
|
| 638 |
+
font-weight: 500;
|
| 639 |
+
}
|
| 640 |
+
|
| 641 |
+
.badge-critical { background: rgba(239, 68, 68, 0.1); color: var(--danger); }
|
| 642 |
+
.badge-warning { background: rgba(245, 158, 11, 0.1); color: var(--warning); }
|
| 643 |
+
.badge-info { background: rgba(59, 130, 246, 0.1); color: var(--secondary); }
|
| 644 |
+
.badge-success { background: rgba(16, 185, 129, 0.1); color: var(--success); }
|
| 645 |
+
|
| 646 |
+
/* Repositories List */
|
| 647 |
+
.repos-list {
|
| 648 |
+
display: flex;
|
| 649 |
+
flex-direction: column;
|
| 650 |
+
gap: 12px;
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
.repo-item {
|
| 654 |
+
display: flex;
|
| 655 |
+
align-items: center;
|
| 656 |
+
gap: 12px;
|
| 657 |
+
padding: 12px;
|
| 658 |
+
background: var(--bg);
|
| 659 |
+
border-radius: 8px;
|
| 660 |
+
transition: all 0.3s ease;
|
| 661 |
+
cursor: pointer;
|
| 662 |
+
}
|
| 663 |
+
|
| 664 |
+
.repo-item:hover {
|
| 665 |
+
background: rgba(59, 130, 246, 0.05);
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
.repo-icon {
|
| 669 |
+
width: 36px;
|
| 670 |
+
height: 36px;
|
| 671 |
+
border-radius: 8px;
|
| 672 |
+
background: var(--primary);
|
| 673 |
+
display: flex;
|
| 674 |
+
align-items: center;
|
| 675 |
+
justify-content: center;
|
| 676 |
+
color: white;
|
| 677 |
+
}
|
| 678 |
+
|
| 679 |
+
.repo-content {
|
| 680 |
+
flex: 1;
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
.repo-name {
|
| 684 |
+
font-size: 13px;
|
| 685 |
+
font-weight: 500;
|
| 686 |
+
margin-bottom: 2px;
|
| 687 |
+
}
|
| 688 |
+
|
| 689 |
+
.repo-stats {
|
| 690 |
+
display: flex;
|
| 691 |
+
gap: 12px;
|
| 692 |
+
font-size: 11px;
|
| 693 |
+
color: var(--text-muted);
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
+
.repo-status {
|
| 697 |
+
display: flex;
|
| 698 |
+
align-items: center;
|
| 699 |
+
gap: 4px;
|
| 700 |
+
font-size: 12px;
|
| 701 |
+
}
|
| 702 |
+
|
| 703 |
+
.status-dot {
|
| 704 |
+
width: 8px;
|
| 705 |
+
height: 8px;
|
| 706 |
+
border-radius: 50%;
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
.status-dot.active { background: var(--success); }
|
| 710 |
+
.status-dot.warning { background: var(--warning); }
|
| 711 |
+
.status-dot.error { background: var(--danger); }
|
| 712 |
+
|
| 713 |
+
/* Toast Notifications */
|
| 714 |
+
.toast-container {
|
| 715 |
+
position: fixed;
|
| 716 |
+
top: 20px;
|
| 717 |
+
left: 50%;
|
| 718 |
+
transform: translateX(-50%);
|
| 719 |
+
z-index: 2000;
|
| 720 |
+
display: flex;
|
| 721 |
+
flex-direction: column;
|
| 722 |
+
gap: 10px;
|
| 723 |
+
}
|
| 724 |
+
|
| 725 |
+
.toast {
|
| 726 |
+
padding: 14px 20px;
|
| 727 |
+
background: var(--primary);
|
| 728 |
+
color: white;
|
| 729 |
+
border-radius: 10px;
|
| 730 |
+
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
|
| 731 |
+
display: flex;
|
| 732 |
+
align-items: center;
|
| 733 |
+
gap: 10px;
|
| 734 |
+
animation: slideIn 0.3s ease, fadeOut 0.3s ease 2.7s;
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
.toast.success { background: var(--success); }
|
| 738 |
+
.toast.error { background: var(--danger); }
|
| 739 |
+
.toast.warning { background: var(--warning); }
|
| 740 |
+
.toast.info { background: var(--secondary); }
|
| 741 |
+
|
| 742 |
+
@keyframes slideIn {
|
| 743 |
+
from { transform: translateY(-20px); opacity: 0; }
|
| 744 |
+
to { transform: translateY(0); opacity: 1; }
|
| 745 |
+
}
|
| 746 |
+
|
| 747 |
+
@keyframes fadeOut {
|
| 748 |
+
from { opacity: 1; }
|
| 749 |
+
to { opacity: 0; }
|
| 750 |
+
}
|
| 751 |
+
|
| 752 |
+
/* Responsive */
|
| 753 |
+
@media (max-width: 1200px) {
|
| 754 |
+
.stats-grid {
|
| 755 |
+
grid-template-columns: repeat(2, 1fr);
|
| 756 |
+
}
|
| 757 |
+
.charts-section {
|
| 758 |
+
grid-template-columns: 1fr;
|
| 759 |
+
}
|
| 760 |
+
.activity-section {
|
| 761 |
+
grid-template-columns: 1fr;
|
| 762 |
+
}
|
| 763 |
+
}
|
| 764 |
+
|
| 765 |
+
@media (max-width: 992px) {
|
| 766 |
+
.sidebar {
|
| 767 |
+
position: fixed;
|
| 768 |
+
right: -240px;
|
| 769 |
+
top: 0;
|
| 770 |
+
z-index: 1000;
|
| 771 |
+
transition: right 0.3s ease;
|
| 772 |
+
box-shadow: -4px 0 20px rgba(0,0,0,0.1);
|
| 773 |
+
}
|
| 774 |
+
|
| 775 |
+
.sidebar.active {
|
| 776 |
+
right: 0;
|
| 777 |
+
}
|
| 778 |
+
|
| 779 |
+
.sidebar-overlay {
|
| 780 |
+
display: none;
|
| 781 |
+
position: fixed;
|
| 782 |
+
top: 0;
|
| 783 |
+
left: 0;
|
| 784 |
+
width: 100%;
|
| 785 |
+
height: 100%;
|
| 786 |
+
background: rgba(0,0,0,0.5);
|
| 787 |
+
z-index: 999;
|
| 788 |
+
}
|
| 789 |
+
|
| 790 |
+
.sidebar-overlay.active {
|
| 791 |
+
display: block;
|
| 792 |
+
}
|
| 793 |
+
|
| 794 |
+
.main-content {
|
| 795 |
+
width: 100%;
|
| 796 |
+
padding: 15px 20px;
|
| 797 |
+
}
|
| 798 |
+
|
| 799 |
+
.mobile-menu-btn {
|
| 800 |
+
display: flex !important;
|
| 801 |
+
}
|
| 802 |
+
|
| 803 |
+
.header-actions {
|
| 804 |
+
gap: 8px;
|
| 805 |
+
}
|
| 806 |
+
|
| 807 |
+
.search-box {
|
| 808 |
+
min-width: 120px;
|
| 809 |
+
}
|
| 810 |
+
|
| 811 |
+
.search-box input {
|
| 812 |
+
width: 80px;
|
| 813 |
+
}
|
| 814 |
+
}
|
| 815 |
+
|
| 816 |
+
@media (max-width: 768px) {
|
| 817 |
+
.dashboard {
|
| 818 |
+
flex-direction: column;
|
| 819 |
+
}
|
| 820 |
+
|
| 821 |
+
.stats-grid {
|
| 822 |
+
grid-template-columns: 1fr;
|
| 823 |
+
gap: 12px;
|
| 824 |
+
}
|
| 825 |
+
|
| 826 |
+
.stat-card {
|
| 827 |
+
padding: 15px;
|
| 828 |
+
display: flex;
|
| 829 |
+
align-items: center;
|
| 830 |
+
justify-content: space-between;
|
| 831 |
+
flex-wrap: wrap;
|
| 832 |
+
}
|
| 833 |
+
|
| 834 |
+
.stat-header {
|
| 835 |
+
margin-bottom: 0;
|
| 836 |
+
width: auto;
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
.stat-value {
|
| 840 |
+
font-size: 24px;
|
| 841 |
+
text-align: left;
|
| 842 |
+
}
|
| 843 |
+
|
| 844 |
+
.stat-label {
|
| 845 |
+
text-align: left;
|
| 846 |
+
width: 100%;
|
| 847 |
+
}
|
| 848 |
+
|
| 849 |
+
.charts-section {
|
| 850 |
+
gap: 15px;
|
| 851 |
+
margin-bottom: 20px;
|
| 852 |
+
}
|
| 853 |
+
|
| 854 |
+
.chart-card {
|
| 855 |
+
padding: 15px;
|
| 856 |
+
}
|
| 857 |
+
|
| 858 |
+
.area-chart {
|
| 859 |
+
height: 200px;
|
| 860 |
+
}
|
| 861 |
+
|
| 862 |
+
.donut-chart {
|
| 863 |
+
flex-direction: column;
|
| 864 |
+
gap: 15px;
|
| 865 |
+
}
|
| 866 |
+
|
| 867 |
+
.donut-svg {
|
| 868 |
+
width: 150px;
|
| 869 |
+
height: 150px;
|
| 870 |
+
}
|
| 871 |
+
|
| 872 |
+
.activity-section {
|
| 873 |
+
gap: 15px;
|
| 874 |
+
}
|
| 875 |
+
|
| 876 |
+
.activity-card {
|
| 877 |
+
padding: 15px;
|
| 878 |
+
}
|
| 879 |
+
|
| 880 |
+
.header {
|
| 881 |
+
margin-bottom: 20px;
|
| 882 |
+
}
|
| 883 |
+
|
| 884 |
+
.header h2 {
|
| 885 |
+
font-size: 20px;
|
| 886 |
+
width: 100%;
|
| 887 |
+
}
|
| 888 |
+
|
| 889 |
+
.header-actions {
|
| 890 |
+
width: 100%;
|
| 891 |
+
justify-content: space-between;
|
| 892 |
+
}
|
| 893 |
+
|
| 894 |
+
.search-box {
|
| 895 |
+
flex: 1;
|
| 896 |
+
min-width: 0;
|
| 897 |
+
}
|
| 898 |
+
|
| 899 |
+
.search-box input {
|
| 900 |
+
width: 100%;
|
| 901 |
+
}
|
| 902 |
+
|
| 903 |
+
.notification-btn {
|
| 904 |
+
padding: 8px;
|
| 905 |
+
}
|
| 906 |
+
}
|
| 907 |
+
|
| 908 |
+
@media (max-width: 480px) {
|
| 909 |
+
.stat-card {
|
| 910 |
+
padding: 12px;
|
| 911 |
+
}
|
| 912 |
+
|
| 913 |
+
.stat-icon {
|
| 914 |
+
width: 36px;
|
| 915 |
+
height: 36px;
|
| 916 |
+
}
|
| 917 |
+
|
| 918 |
+
.stat-value {
|
| 919 |
+
font-size: 20px;
|
| 920 |
+
}
|
| 921 |
+
|
| 922 |
+
.stat-label {
|
| 923 |
+
font-size: 12px;
|
| 924 |
+
}
|
| 925 |
+
|
| 926 |
+
.chart-title {
|
| 927 |
+
font-size: 14px;
|
| 928 |
+
}
|
| 929 |
+
|
| 930 |
+
.chart-tabs {
|
| 931 |
+
gap: 4px;
|
| 932 |
+
}
|
| 933 |
+
|
| 934 |
+
.chart-tab {
|
| 935 |
+
padding: 4px 8px;
|
| 936 |
+
font-size: 11px;
|
| 937 |
+
}
|
| 938 |
+
|
| 939 |
+
.issue-item, .repo-item {
|
| 940 |
+
padding: 10px;
|
| 941 |
+
}
|
| 942 |
+
|
| 943 |
+
.issue-icon {
|
| 944 |
+
width: 28px;
|
| 945 |
+
height: 28px;
|
| 946 |
+
}
|
| 947 |
+
|
| 948 |
+
.issue-title {
|
| 949 |
+
font-size: 12px;
|
| 950 |
+
}
|
| 951 |
+
|
| 952 |
+
.issue-meta {
|
| 953 |
+
font-size: 10px;
|
| 954 |
+
}
|
| 955 |
+
}
|
| 956 |
+
|
| 957 |
+
/* Mobile Menu Button */
|
| 958 |
+
.mobile-menu-btn {
|
| 959 |
+
display: none;
|
| 960 |
+
position: fixed;
|
| 961 |
+
bottom: 20px;
|
| 962 |
+
left: 20px;
|
| 963 |
+
width: 50px;
|
| 964 |
+
height: 50px;
|
| 965 |
+
border-radius: 50%;
|
| 966 |
+
background: var(--secondary);
|
| 967 |
+
color: white;
|
| 968 |
+
border: none;
|
| 969 |
+
cursor: pointer;
|
| 970 |
+
z-index: 1001;
|
| 971 |
+
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.4);
|
| 972 |
+
align-items: center;
|
| 973 |
+
justify-content: center;
|
| 974 |
+
transition: all 0.3s ease;
|
| 975 |
+
}
|
| 976 |
+
|
| 977 |
+
.mobile-menu-btn:hover {
|
| 978 |
+
transform: scale(1.1);
|
| 979 |
+
background: var(--primary);
|
| 980 |
+
}
|
| 981 |
+
|
| 982 |
+
.mobile-menu-btn svg {
|
| 983 |
+
width: 24px;
|
| 984 |
+
height: 24px;
|
| 985 |
+
}
|
| 986 |
+
|
| 987 |
+
/* Sidebar Overlay */
|
| 988 |
+
.sidebar-overlay {
|
| 989 |
+
display: none;
|
| 990 |
+
}
|
| 991 |
+
</style>
|
| 992 |
+
</head>
|
| 993 |
+
<body>
|
| 994 |
+
<div class="dashboard">
|
| 995 |
+
<!-- Sidebar Overlay -->
|
| 996 |
+
<div class="sidebar-overlay" id="sidebarOverlay" onclick="toggleMobileMenu()"></div>
|
| 997 |
+
|
| 998 |
+
<!-- Sidebar -->
|
| 999 |
+
<aside class="sidebar" id="sidebar">
|
| 1000 |
+
<div class="logo">
|
| 1001 |
+
<h1>Auto-Guardian</h1>
|
| 1002 |
+
<span>Security Dashboard</span>
|
| 1003 |
+
</div>
|
| 1004 |
+
<ul class="nav-menu">
|
| 1005 |
+
<li class="nav-item active" data-view="dashboard">
|
| 1006 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1007 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/>
|
| 1008 |
+
</svg>
|
| 1009 |
+
<span>لوحة التحكم</span>
|
| 1010 |
+
</li>
|
| 1011 |
+
<li class="nav-item" data-view="protection">
|
| 1012 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1013 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
|
| 1014 |
+
</svg>
|
| 1015 |
+
<span>الحماية</span>
|
| 1016 |
+
</li>
|
| 1017 |
+
<li class="nav-item" data-view="analysis">
|
| 1018 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1019 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"/>
|
| 1020 |
+
</svg>
|
| 1021 |
+
<span>الفحص والتحليل</span>
|
| 1022 |
+
</li>
|
| 1023 |
+
<li class="nav-item" data-view="reports">
|
| 1024 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1025 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
| 1026 |
+
</svg>
|
| 1027 |
+
<span>التقارير</span>
|
| 1028 |
+
</li>
|
| 1029 |
+
<li class="nav-item" data-view="settings" id="settingsNavItem">
|
| 1030 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1031 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
| 1032 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
| 1033 |
+
</svg>
|
| 1034 |
+
<span>الإعدادات</span>
|
| 1035 |
+
</li>
|
| 1036 |
+
<li class="nav-item" data-view="help">
|
| 1037 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1038 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 1039 |
+
</svg>
|
| 1040 |
+
<span>المساعدة</span>
|
| 1041 |
+
</li>
|
| 1042 |
+
</ul>
|
| 1043 |
+
</aside>
|
| 1044 |
+
|
| 1045 |
+
<!-- Mobile Menu Button -->
|
| 1046 |
+
<button class="mobile-menu-btn" id="mobileMenuBtn" onclick="toggleMobileMenu()">
|
| 1047 |
+
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1048 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
| 1049 |
+
</svg>
|
| 1050 |
+
</button>
|
| 1051 |
+
|
| 1052 |
+
<!-- Main Content -->
|
| 1053 |
+
<main class="main-content">
|
| 1054 |
+
<!-- Header -->
|
| 1055 |
+
<header class="header">
|
| 1056 |
+
<h2>لوحة تحكم Auto-Guardian</h2>
|
| 1057 |
+
<div class="header-actions">
|
| 1058 |
+
<div class="search-box" id="searchBox">
|
| 1059 |
+
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1060 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
| 1061 |
+
</svg>
|
| 1062 |
+
<input type="text" placeholder="بحث..." id="searchInput">
|
| 1063 |
+
<div class="search-results" id="searchResults"></div>
|
| 1064 |
+
</div>
|
| 1065 |
+
<button class="notification-btn" id="notificationBtn">
|
| 1066 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1067 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
| 1068 |
+
</svg>
|
| 1069 |
+
<span class="notification-badge" id="notificationBadge">5</span>
|
| 1070 |
+
</button>
|
| 1071 |
+
</div>
|
| 1072 |
+
</header>
|
| 1073 |
+
|
| 1074 |
+
<!-- Stats Grid -->
|
| 1075 |
+
<div class="stats-grid">
|
| 1076 |
+
<div class="stat-card" onclick="filterIssues('critical')">
|
| 1077 |
+
<div class="stat-header">
|
| 1078 |
+
<div class="stat-icon blue">
|
| 1079 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1080 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
|
| 1081 |
+
</svg>
|
| 1082 |
+
</div>
|
| 1083 |
+
<span class="stat-trend up" id="trendCritical">↑ 12%</span>
|
| 1084 |
+
</div>
|
| 1085 |
+
<div class="stat-value" id="statThreats">1,247</div>
|
| 1086 |
+
<div class="stat-label">التهديدات المحظورة</div>
|
| 1087 |
+
</div>
|
| 1088 |
+
|
| 1089 |
+
<div class="stat-card">
|
| 1090 |
+
<div class="stat-header">
|
| 1091 |
+
<div class="stat-icon green">
|
| 1092 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1093 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 1094 |
+
</svg>
|
| 1095 |
+
</div>
|
| 1096 |
+
<span class="stat-trend up" id="trendSuccess">↑ 8%</span>
|
| 1097 |
+
</div>
|
| 1098 |
+
<div class="stat-value" id="statSuccess">99.9%</div>
|
| 1099 |
+
<div class="stat-label">معدل النجاح</div>
|
| 1100 |
+
</div>
|
| 1101 |
+
|
| 1102 |
+
<div class="stat-card" onclick="filterIssues('open')">
|
| 1103 |
+
<div class="stat-header">
|
| 1104 |
+
<div class="stat-icon red">
|
| 1105 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1106 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 1107 |
+
</svg>
|
| 1108 |
+
</div>
|
| 1109 |
+
<span class="stat-trend down" id="trendOpen">↓ 3%</span>
|
| 1110 |
+
</div>
|
| 1111 |
+
<div class="stat-value" id="statOpen">23</div>
|
| 1112 |
+
<div class="stat-label">المشكلات المفتوحة</div>
|
| 1113 |
+
</div>
|
| 1114 |
+
|
| 1115 |
+
<div class="stat-card">
|
| 1116 |
+
<div class="stat-header">
|
| 1117 |
+
<div class="stat-icon yellow">
|
| 1118 |
+
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1119 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
| 1120 |
+
</svg>
|
| 1121 |
+
</div>
|
| 1122 |
+
<span class="stat-trend up" id="trendResponse">↑ 15%</span>
|
| 1123 |
+
</div>
|
| 1124 |
+
<div class="stat-value" id="statResponse">0.3s</div>
|
| 1125 |
+
<div class="stat-label">زمن الاستجابة</div>
|
| 1126 |
+
</div>
|
| 1127 |
+
</div>
|
| 1128 |
+
|
| 1129 |
+
<!-- Charts Section -->
|
| 1130 |
+
<div class="charts-section">
|
| 1131 |
+
<div class="chart-card">
|
| 1132 |
+
<div class="chart-header">
|
| 1133 |
+
<h3 class="chart-title">نشاط الفحص والأمان</h3>
|
| 1134 |
+
<div class="chart-tabs">
|
| 1135 |
+
<button class="chart-tab" data-period="day" onclick="changePeriod('day')">24 ساعة</button>
|
| 1136 |
+
<button class="chart-tab active" data-period="week" onclick="changePeriod('week')">أسبوع</button>
|
| 1137 |
+
<button class="chart-tab" data-period="month" onclick="changePeriod('month')">شهر</button>
|
| 1138 |
+
</div>
|
| 1139 |
+
</div>
|
| 1140 |
+
<div class="area-chart">
|
| 1141 |
+
<svg class="chart-svg" viewBox="0 0 800 250" id="mainChart">
|
| 1142 |
+
<!-- Grid lines -->
|
| 1143 |
+
<line x1="50" y1="30" x2="750" y2="30" stroke="#E2E8F0" stroke-width="1"/>
|
| 1144 |
+
<line x1="50" y1="80" x2="750" y2="80" stroke="#E2E8F0" stroke-width="1"/>
|
| 1145 |
+
<line x1="50" y1="130" x2="750" y2="130" stroke="#E2E8F0" stroke-width="1"/>
|
| 1146 |
+
<line x1="50" y1="180" x2="750" y2="180" stroke="#E2E8F0" stroke-width="1"/>
|
| 1147 |
+
|
| 1148 |
+
<!-- Area gradient -->
|
| 1149 |
+
<defs>
|
| 1150 |
+
<linearGradient id="areaGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
| 1151 |
+
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.3"/>
|
| 1152 |
+
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0.05"/>
|
| 1153 |
+
</linearGradient>
|
| 1154 |
+
</defs>
|
| 1155 |
+
|
| 1156 |
+
<!-- Area path -->
|
| 1157 |
+
<path d="M50,180 L100,150 L150,160 L200,120 L250,140 L300,100 L350,110 L400,70 L450,90 L500,60 L550,80 L600,50 L650,65 L700,40 L750,55 L750,180 Z" fill="url(#areaGradient)"/>
|
| 1158 |
+
|
| 1159 |
+
<!-- Line -->
|
| 1160 |
+
<path d="M50,180 L100,150 L150,160 L200,120 L250,140 L300,100 L350,110 L400,70 L450,90 L500,60 L550,80 L600,50 L650,65 L700,40 L750,55" fill="none" stroke="#3B82F6" stroke-width="3" stroke-linecap="round"/>
|
| 1161 |
+
|
| 1162 |
+
<!-- Data points -->
|
| 1163 |
+
<circle cx="100" cy="150" r="5" fill="#3B82F6" class="chart-point" data-value="45"/>
|
| 1164 |
+
<circle cx="200" cy="120" r="5" fill="#3B82F6" class="chart-point" data-value="60"/>
|
| 1165 |
+
<circle cx="300" cy="100" r="5" fill="#3B82F6" class="chart-point" data-value="70"/>
|
| 1166 |
+
<circle cx="400" cy="70" r="5" fill="#3B82F6" class="chart-point" data-value="85"/>
|
| 1167 |
+
<circle cx="500" cy="60" r="5" fill="#3B82F6" class="chart-point" data-value="90"/>
|
| 1168 |
+
<circle cx="600" cy="50" r="5" fill="#3B82F6" class="chart-point" data-value="95"/>
|
| 1169 |
+
<circle cx="700" cy="40" r="5" fill="#3B82F6" class="chart-point" data-value="100"/>
|
| 1170 |
+
|
| 1171 |
+
<!-- Labels -->
|
| 1172 |
+
<text x="50" y="200" fill="#64748B" font-size="11">السبت</text>
|
| 1173 |
+
<text x="150" y="200" fill="#64748B" font-size="11">الأحد</text>
|
| 1174 |
+
<text x="250" y="200" fill="#64748B" font-size="11">الاثنين</text>
|
| 1175 |
+
<text x="350" y="200" fill="#64748B" font-size="11">الثلاثاء</text>
|
| 1176 |
+
<text x="450" y="200" fill="#64748B" font-size="11">الأربعاء</text>
|
| 1177 |
+
<text x="550" y="200" fill="#64748B" font-size="11">الخميس</text>
|
| 1178 |
+
<text x="650" y="200" fill="#64748B" font-size="11">الجمعة</text>
|
| 1179 |
+
|
| 1180 |
+
<!-- Y-axis labels -->
|
| 1181 |
+
<text x="45" y="35" text-anchor="end" fill="#64748B" font-size="10">100</text>
|
| 1182 |
+
<text x="45" y="85" text-anchor="end" fill="#64748B" font-size="10">75</text>
|
| 1183 |
+
<text x="45" y="135" text-anchor="end" fill="#64748B" font-size="10">50</text>
|
| 1184 |
+
<text x="45" y="185" text-anchor="end" fill="#64748B" font-size="10">25</text>
|
| 1185 |
+
</svg>
|
| 1186 |
+
</div>
|
| 1187 |
+
</div>
|
| 1188 |
+
|
| 1189 |
+
<div class="chart-card">
|
| 1190 |
+
<div class="chart-header">
|
| 1191 |
+
<h3 class="chart-title">توزيع المشكلات</h3>
|
| 1192 |
+
</div>
|
| 1193 |
+
<div class="donut-chart">
|
| 1194 |
+
<svg class="donut-svg" viewBox="0 0 180 180">
|
| 1195 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#E2E8F0" stroke-width="25"/>
|
| 1196 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#EF4444" stroke-width="25" stroke-dasharray="110 308" stroke-dashoffset="0" transform="rotate(-90 90 90)"/>
|
| 1197 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#F59E0B" stroke-width="25" stroke-dasharray="88 308" stroke-dashoffset="-110" transform="rotate(-90 90 90)"/>
|
| 1198 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#3B82F6" stroke-width="25" stroke-dasharray="66 308" stroke-dashoffset="-198" transform="rotate(-90 90 90)"/>
|
| 1199 |
+
<circle cx="90" cy="90" r="70" fill="none" stroke="#10B981" stroke-width="25" stroke-dasharray="44 308" stroke-dashoffset="-264" transform="rotate(-90 90 90)"/>
|
| 1200 |
+
<text x="90" y="85" text-anchor="middle" font-size="24" font-weight="bold" fill="#0F172A" id="donutTotal">23</text>
|
| 1201 |
+
<text x="90" y="105" text-anchor="middle" font-size="12" fill="#64748B">إجمالي</text>
|
| 1202 |
+
</svg>
|
| 1203 |
+
<div class="donut-legend">
|
| 1204 |
+
<div class="legend-item">
|
| 1205 |
+
<div class="legend-color" style="background:#EF4444"></div>
|
| 1206 |
+
<span class="legend-label">حرجة</span>
|
| 1207 |
+
<span class="legend-value" id="legendCritical">5</span>
|
| 1208 |
+
</div>
|
| 1209 |
+
<div class="legend-item">
|
| 1210 |
+
<div class="legend-color" style="background:#F59E0B"></div>
|
| 1211 |
+
<span class="legend-label">عالية</span>
|
| 1212 |
+
<span class="legend-value" id="legendHigh">7</span>
|
| 1213 |
+
</div>
|
| 1214 |
+
<div class="legend-item">
|
| 1215 |
+
<div class="legend-color" style="background:#3B82F6"></div>
|
| 1216 |
+
<span class="legend-label">متوسطة</span>
|
| 1217 |
+
<span class="legend-value" id="legendMedium">6</span>
|
| 1218 |
+
</div>
|
| 1219 |
+
<div class="legend-item">
|
| 1220 |
+
<div class="legend-color" style="background:#10B981"></div>
|
| 1221 |
+
<span class="legend-label">منخفضة</span>
|
| 1222 |
+
<span class="legend-value" id="legendLow">5</span>
|
| 1223 |
+
</div>
|
| 1224 |
+
</div>
|
| 1225 |
+
</div>
|
| 1226 |
+
</div>
|
| 1227 |
+
</div>
|
| 1228 |
+
|
| 1229 |
+
<!-- Activity Section -->
|
| 1230 |
+
<div class="activity-section">
|
| 1231 |
+
<div class="activity-card">
|
| 1232 |
+
<div class="activity-header">
|
| 1233 |
+
<h3 class="activity-title">أحدث المشكلات</h3>
|
| 1234 |
+
<span class="view-all" onclick="filterIssues('all')">عرض الكل →</span>
|
| 1235 |
+
</div>
|
| 1236 |
+
<div class="issues-list" id="issuesList">
|
| 1237 |
+
<!-- Issues will be populated by JavaScript -->
|
| 1238 |
+
</div>
|
| 1239 |
+
</div>
|
| 1240 |
+
|
| 1241 |
+
<div class="activity-card">
|
| 1242 |
+
<div class="activity-header">
|
| 1243 |
+
<h3 class="activity-title">المستودعات النشطة</h3>
|
| 1244 |
+
<span class="view-all">عرض الكل →</span>
|
| 1245 |
+
</div>
|
| 1246 |
+
<div class="repos-list" id="reposList">
|
| 1247 |
+
<!-- Repositories will be populated by JavaScript -->
|
| 1248 |
+
</div>
|
| 1249 |
+
</div>
|
| 1250 |
+
</div>
|
| 1251 |
+
</main>
|
| 1252 |
+
</div>
|
| 1253 |
+
|
| 1254 |
+
<!-- Settings Panel -->
|
| 1255 |
+
<div class="settings-panel" id="settingsPanel">
|
| 1256 |
+
<div class="settings-content">
|
| 1257 |
+
<div class="settings-header">
|
| 1258 |
+
<h3>⚙️ الإعدادات</h3>
|
| 1259 |
+
<button class="close-btn" onclick="closeSettings()">×</button>
|
| 1260 |
+
</div>
|
| 1261 |
+
|
| 1262 |
+
<div class="setting-item">
|
| 1263 |
+
<label class="setting-label">اسم المستخدم</label>
|
| 1264 |
+
<input type="text" class="setting-input" id="settingUsername" placeholder="أدخل اسم المستخدم">
|
| 1265 |
+
</div>
|
| 1266 |
+
|
| 1267 |
+
<div class="setting-item">
|
| 1268 |
+
<label class="setting-label">البريد الإلكتروني</label>
|
| 1269 |
+
<input type="email" class="setting-input" id="settingEmail" placeholder="أدخل البريد الإلكتروني">
|
| 1270 |
+
</div>
|
| 1271 |
+
|
| 1272 |
+
<div class="setting-item">
|
| 1273 |
+
<label class="setting-label">لغة الواجهة</label>
|
| 1274 |
+
<select class="setting-select" id="settingLanguage">
|
| 1275 |
+
<option value="ar">العربية</option>
|
| 1276 |
+
<option value="en">English</option>
|
| 1277 |
+
</select>
|
| 1278 |
+
</div>
|
| 1279 |
+
|
| 1280 |
+
<div class="setting-item">
|
| 1281 |
+
<label class="setting-label">السمة</label>
|
| 1282 |
+
<select class="setting-select" id="settingTheme">
|
| 1283 |
+
<option value="light">فاتحة</option>
|
| 1284 |
+
<option value="dark">داكنة</option>
|
| 1285 |
+
<option value="auto">تلقائي</option>
|
| 1286 |
+
</select>
|
| 1287 |
+
</div>
|
| 1288 |
+
|
| 1289 |
+
<div class="setting-item">
|
| 1290 |
+
<label class="setting-label">فحص تلقائي عند الحفظ</label>
|
| 1291 |
+
<div class="setting-toggle" onclick="toggleSetting('autoScan')">
|
| 1292 |
+
<div class="toggle-switch" id="toggleAutoScan"></div>
|
| 1293 |
+
<span>تشغيل</span>
|
| 1294 |
+
</div>
|
| 1295 |
+
<p class="setting-description">إجراء فحص تلقائي للكود عند حفظ الملفات</p>
|
| 1296 |
+
</div>
|
| 1297 |
+
|
| 1298 |
+
<div class="setting-item">
|
| 1299 |
+
<label class="setting-label">إشعارات المشاكل الحرجة</label>
|
| 1300 |
+
<div class="setting-toggle" onclick="toggleSetting('criticalAlerts')">
|
| 1301 |
+
<div class="toggle-switch" id="toggleCriticalAlerts"></div>
|
| 1302 |
+
<span>تشغيل</span>
|
| 1303 |
+
</div>
|
| 1304 |
+
<p class="setting-description">إرسال إشعارات فورية للمشاكل الأمنية الحرجة</p>
|
| 1305 |
+
</div>
|
| 1306 |
+
|
| 1307 |
+
<div class="setting-item">
|
| 1308 |
+
<label class="setting-label">الإصلاح التلقائي الآمن</label>
|
| 1309 |
+
<div class="setting-toggle" onclick="toggleSetting('autoFix')">
|
| 1310 |
+
<div class="toggle-switch" id="toggleAutoFix"></div>
|
| 1311 |
+
<span>تشغيل</span>
|
| 1312 |
+
</div>
|
| 1313 |
+
<p class="setting-description">إصلاح المشاكل الآمنة تلقائياً دون تدخل</p>
|
| 1314 |
+
</div>
|
| 1315 |
+
|
| 1316 |
+
<button class="save-btn" onclick="saveSettings()">💾 حفظ الإعدادات</button>
|
| 1317 |
+
</div>
|
| 1318 |
+
</div>
|
| 1319 |
+
|
| 1320 |
+
<!-- Toast Container -->
|
| 1321 |
+
<div class="toast-container" id="toastContainer"></div>
|
| 1322 |
+
|
| 1323 |
+
<script>
|
| 1324 |
+
// Data
|
| 1325 |
+
let currentData = {
|
| 1326 |
+
threats: 1247,
|
| 1327 |
+
successRate: 99.9,
|
| 1328 |
+
openIssues: 23,
|
| 1329 |
+
responseTime: 0.3,
|
| 1330 |
+
issues: [],
|
| 1331 |
+
repos: []
|
| 1332 |
+
};
|
| 1333 |
+
|
| 1334 |
+
let settings = {
|
| 1335 |
+
username: '',
|
| 1336 |
+
email: '',
|
| 1337 |
+
language: 'ar',
|
| 1338 |
+
theme: 'light',
|
| 1339 |
+
autoScan: true,
|
| 1340 |
+
criticalAlerts: true,
|
| 1341 |
+
autoFix: true
|
| 1342 |
+
};
|
| 1343 |
+
|
| 1344 |
+
// Sample Data
|
| 1345 |
+
const sampleIssues = [
|
| 1346 |
+
{ id: 1, title: 'ثغرة أمنية في وحدة المصادقة', file: 'auth-module.py', time: 'قبل 5 دقائق', severity: 'critical' },
|
| 1347 |
+
{ id: 2, title: 'فشل في اختبارات الأداء', file: 'performance_test.py', time: 'قبل 23 دقيقة', severity: 'warning' },
|
| 1348 |
+
{ id: 3, title: 'تحذير في تنسيق الكود', file: 'main_controller.dart', time: 'قبل ساعة', severity: 'info' },
|
| 1349 |
+
{ id: 4, title: 'تم إصلاح مشكلة التنسيق تلقائياً', file: 'utils_helper.js', time: 'قبل ساعتين', severity: 'success' },
|
| 1350 |
+
{ id: 5, title: 'مشكلة في اتصال قاعدة البيانات', file: 'db_connection.java', time: 'قبل ساعتين', severity: 'critical' },
|
| 1351 |
+
{ id: 6, title: 'تحذير: استخدام دالة قديمة', file: 'legacy_code.py', time: 'قبل 3 ساعات', severity: 'warning' }
|
| 1352 |
+
];
|
| 1353 |
+
|
| 1354 |
+
const sampleRepos = [
|
| 1355 |
+
{ id: 1, name: 'auto-guardian-system', stars: 124, pullRequests: 45, bugs: 3, status: 'active' },
|
| 1356 |
+
{ id: 2, name: 'payment-gateway-api', stars: 89, pullRequests: 32, bugs: 5, status: 'warning' },
|
| 1357 |
+
{ id: 3, name: 'user-management-service', stars: 56, pullRequests: 18, bugs: 1, status: 'active' },
|
| 1358 |
+
{ id: 4, name: 'data-analytics-platform', stars: 234, pullRequests: 67, bugs: 8, status: 'error' }
|
| 1359 |
+
];
|
| 1360 |
+
|
| 1361 |
+
// Initialize
|
| 1362 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 1363 |
+
loadSettings();
|
| 1364 |
+
loadData();
|
| 1365 |
+
renderIssues();
|
| 1366 |
+
renderRepos();
|
| 1367 |
+
setupEventListeners();
|
| 1368 |
+
setupMobileMenu();
|
| 1369 |
+
showToast('🎉 مرحباً بك في Auto-Guardian!', 'success');
|
| 1370 |
+
});
|
| 1371 |
+
|
| 1372 |
+
// Setup Mobile Menu
|
| 1373 |
+
function setupMobileMenu() {
|
| 1374 |
+
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
|
| 1375 |
+
if (mobileMenuBtn) {
|
| 1376 |
+
// Show/hide mobile menu button based on screen size
|
| 1377 |
+
const checkScreenSize = () => {
|
| 1378 |
+
if (window.innerWidth <= 992) {
|
| 1379 |
+
mobileMenuBtn.style.display = 'flex';
|
| 1380 |
+
} else {
|
| 1381 |
+
mobileMenuBtn.style.display = 'none';
|
| 1382 |
+
closeMobileMenu();
|
| 1383 |
+
}
|
| 1384 |
+
};
|
| 1385 |
+
|
| 1386 |
+
checkScreenSize();
|
| 1387 |
+
window.addEventListener('resize', checkScreenSize);
|
| 1388 |
+
}
|
| 1389 |
+
}
|
| 1390 |
+
|
| 1391 |
+
// Toggle Mobile Menu
|
| 1392 |
+
function toggleMobileMenu() {
|
| 1393 |
+
const sidebar = document.getElementById('sidebar');
|
| 1394 |
+
const overlay = document.getElementById('sidebarOverlay');
|
| 1395 |
+
|
| 1396 |
+
if (sidebar && overlay) {
|
| 1397 |
+
sidebar.classList.toggle('active');
|
| 1398 |
+
overlay.classList.toggle('active');
|
| 1399 |
+
}
|
| 1400 |
+
}
|
| 1401 |
+
|
| 1402 |
+
// Close Mobile Menu
|
| 1403 |
+
function closeMobileMenu() {
|
| 1404 |
+
const sidebar = document.getElementById('sidebar');
|
| 1405 |
+
const overlay = document.getElementById('sidebarOverlay');
|
| 1406 |
+
|
| 1407 |
+
if (sidebar) {
|
| 1408 |
+
sidebar.classList.remove('active');
|
| 1409 |
+
}
|
| 1410 |
+
if (overlay) {
|
| 1411 |
+
overlay.classList.remove('active');
|
| 1412 |
+
}
|
| 1413 |
+
}
|
| 1414 |
+
|
| 1415 |
+
// Load Settings from LocalStorage
|
| 1416 |
+
function loadSettings() {
|
| 1417 |
+
const saved = localStorage.getItem('autoGuardianSettings');
|
| 1418 |
+
if (saved) {
|
| 1419 |
+
settings = JSON.parse(saved);
|
| 1420 |
+
}
|
| 1421 |
+
|
| 1422 |
+
// Update UI
|
| 1423 |
+
document.getElementById('settingUsername').value = settings.username || '';
|
| 1424 |
+
document.getElementById('settingEmail').value = settings.email || '';
|
| 1425 |
+
document.getElementById('settingLanguage').value = settings.language || 'ar';
|
| 1426 |
+
document.getElementById('settingTheme').value = settings.theme || 'light';
|
| 1427 |
+
updateToggle('toggleAutoScan', settings.autoScan);
|
| 1428 |
+
updateToggle('toggleCriticalAlerts', settings.criticalAlerts);
|
| 1429 |
+
updateToggle('toggleAutoFix', settings.autoFix);
|
| 1430 |
+
}
|
| 1431 |
+
|
| 1432 |
+
// Save Settings to LocalStorage
|
| 1433 |
+
function saveSettings() {
|
| 1434 |
+
settings.username = document.getElementById('settingUsername').value;
|
| 1435 |
+
settings.email = document.getElementById('settingEmail').value;
|
| 1436 |
+
settings.language = document.getElementById('settingLanguage').value;
|
| 1437 |
+
settings.theme = document.getElementById('settingTheme').value;
|
| 1438 |
+
|
| 1439 |
+
localStorage.setItem('autoGuardianSettings', JSON.stringify(settings));
|
| 1440 |
+
closeSettings();
|
| 1441 |
+
showToast('✅ تم حفظ الإعدادات بنجاح!', 'success');
|
| 1442 |
+
}
|
| 1443 |
+
|
| 1444 |
+
// Update toggle UI
|
| 1445 |
+
function updateToggle(id, value) {
|
| 1446 |
+
const toggle = document.getElementById(id);
|
| 1447 |
+
if (value) {
|
| 1448 |
+
toggle.classList.add('active');
|
| 1449 |
+
} else {
|
| 1450 |
+
toggle.classList.remove('active');
|
| 1451 |
+
}
|
| 1452 |
+
}
|
| 1453 |
+
|
| 1454 |
+
// Toggle setting
|
| 1455 |
+
function toggleSetting(setting) {
|
| 1456 |
+
settings[setting] = !settings[setting];
|
| 1457 |
+
updateToggle('toggle' + setting.charAt(0).toUpperCase() + setting.slice(1), settings[setting]);
|
| 1458 |
+
showToast(`⚙️ تم ${settings[setting] ? 'تفعيل' : 'تعطيل'} ${setting}`, 'info');
|
| 1459 |
+
}
|
| 1460 |
+
|
| 1461 |
+
// Load Data
|
| 1462 |
+
function loadData() {
|
| 1463 |
+
currentData.issues = sampleIssues;
|
| 1464 |
+
currentData.repos = sampleRepos;
|
| 1465 |
+
|
| 1466 |
+
// Randomize some values
|
| 1467 |
+
currentData.threats = Math.floor(Math.random() * 2000) + 500;
|
| 1468 |
+
currentData.openIssues = Math.floor(Math.random() * 30) + 10;
|
| 1469 |
+
currentData.responseTime = (Math.random() * 0.5 + 0.1).toFixed(1);
|
| 1470 |
+
|
| 1471 |
+
updateStatsUI();
|
| 1472 |
+
}
|
| 1473 |
+
|
| 1474 |
+
// Update Stats UI
|
| 1475 |
+
function updateStatsUI() {
|
| 1476 |
+
document.getElementById('statThreats').textContent = currentData.threats.toLocaleString();
|
| 1477 |
+
document.getElementById('statSuccess').textContent = currentData.successRate + '%';
|
| 1478 |
+
document.getElementById('statOpen').textContent = currentData.openIssues;
|
| 1479 |
+
document.getElementById('statResponse').textContent = currentData.responseTime + 's';
|
| 1480 |
+
|
| 1481 |
+
// Update legend
|
| 1482 |
+
const critical = currentData.issues.filter(i => i.severity === 'critical').length;
|
| 1483 |
+
const warning = currentData.issues.filter(i => i.severity === 'warning').length;
|
| 1484 |
+
const info = currentData.issues.filter(i => i.severity === 'info').length;
|
| 1485 |
+
const success = currentData.issues.filter(i => i.severity === 'success').length;
|
| 1486 |
+
|
| 1487 |
+
document.getElementById('legendCritical').textContent = critical;
|
| 1488 |
+
document.getElementById('legendHigh').textContent = warning;
|
| 1489 |
+
document.getElementById('legendMedium').textContent = info;
|
| 1490 |
+
document.getElementById('legendLow').textContent = success;
|
| 1491 |
+
document.getElementById('donutTotal').textContent = currentData.issues.length;
|
| 1492 |
+
}
|
| 1493 |
+
|
| 1494 |
+
// Render Issues
|
| 1495 |
+
function renderIssues(issues = currentData.issues) {
|
| 1496 |
+
const container = document.getElementById('issuesList');
|
| 1497 |
+
container.innerHTML = '';
|
| 1498 |
+
|
| 1499 |
+
issues.forEach(issue => {
|
| 1500 |
+
const severityClass = issue.severity === 'critical' ? 'badge-critical' :
|
| 1501 |
+
issue.severity === 'warning' ? 'badge-warning' :
|
| 1502 |
+
issue.severity === 'info' ? 'badge-info' : 'badge-success';
|
| 1503 |
+
|
| 1504 |
+
const severityLabel = issue.severity === 'critical' ? 'حرجة' :
|
| 1505 |
+
issue.severity === 'warning' ? 'عالية' :
|
| 1506 |
+
issue.severity === 'info' ? 'متوسطة' : 'تم الإصلاح';
|
| 1507 |
+
|
| 1508 |
+
const iconSvg = issue.severity === 'critical' ?
|
| 1509 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>' :
|
| 1510 |
+
issue.severity === 'warning' ?
|
| 1511 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' :
|
| 1512 |
+
issue.severity === 'success' ?
|
| 1513 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' :
|
| 1514 |
+
'<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>';
|
| 1515 |
+
|
| 1516 |
+
const html = `
|
| 1517 |
+
<div class="issue-item" onclick="showIssueDetails(${issue.id})">
|
| 1518 |
+
<div class="issue-icon" style="background: rgba(${issue.severity === 'critical' ? '239, 68, 68' : issue.severity === 'warning' ? '245, 158, 11' : issue.severity === 'success' ? '16, 185, 129' : '59, 130, 246'}, 0.1); color: ${issue.severity === 'critical' ? '#EF4444' : issue.severity === 'warning' ? '#F59E0B' : issue.severity === 'success' ? '#10B981' : '#3B82F6'};">
|
| 1519 |
+
${iconSvg}
|
| 1520 |
+
</div>
|
| 1521 |
+
<div class="issue-content">
|
| 1522 |
+
<div class="issue-title">${issue.title}</div>
|
| 1523 |
+
<div class="issue-meta">${issue.file} • ${issue.time}</div>
|
| 1524 |
+
</div>
|
| 1525 |
+
<span class="issue-badge ${severityClass}">${severityLabel}</span>
|
| 1526 |
+
</div>
|
| 1527 |
+
`;
|
| 1528 |
+
container.innerHTML += html;
|
| 1529 |
+
});
|
| 1530 |
+
}
|
| 1531 |
+
|
| 1532 |
+
// Render Repositories
|
| 1533 |
+
function renderRepos(repos = currentData.repos) {
|
| 1534 |
+
const container = document.getElementById('reposList');
|
| 1535 |
+
container.innerHTML = '';
|
| 1536 |
+
|
| 1537 |
+
repos.forEach(repo => {
|
| 1538 |
+
const statusClass = repo.status === 'active' ? 'active' : repo.status === 'warning' ? 'warning' : 'error';
|
| 1539 |
+
const statusLabel = repo.status === 'active' ? 'نشط' : repo.status === 'warning' ? 'يحتاج مراجعة' : 'مشاكل';
|
| 1540 |
+
const statusColor = repo.status === 'active' ? '#10B981' : repo.status === 'warning' ? '#F59E0B' : '#EF4444';
|
| 1541 |
+
|
| 1542 |
+
const html = `
|
| 1543 |
+
<div class="repo-item">
|
| 1544 |
+
<div class="repo-icon">
|
| 1545 |
+
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 1546 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/>
|
| 1547 |
+
</svg>
|
| 1548 |
+
</div>
|
| 1549 |
+
<div class="repo-content">
|
| 1550 |
+
<div class="repo-name">${repo.name}</div>
|
| 1551 |
+
<div class="repo-stats">
|
| 1552 |
+
<span>⭐ ${repo.stars}</span>
|
| 1553 |
+
<span>🔀 ${repo.pullRequests}</span>
|
| 1554 |
+
<span>🐛 ${repo.bugs}</span>
|
| 1555 |
+
</div>
|
| 1556 |
+
</div>
|
| 1557 |
+
<div class="repo-status">
|
| 1558 |
+
<span class="status-dot ${statusClass}"></span>
|
| 1559 |
+
<span style="color: ${statusColor};">${statusLabel}</span>
|
| 1560 |
+
</div>
|
| 1561 |
+
</div>
|
| 1562 |
+
`;
|
| 1563 |
+
container.innerHTML += html;
|
| 1564 |
+
});
|
| 1565 |
+
}
|
| 1566 |
+
|
| 1567 |
+
// Filter Issues
|
| 1568 |
+
function filterIssues(type) {
|
| 1569 |
+
let filtered = currentData.issues;
|
| 1570 |
+
|
| 1571 |
+
if (type === 'critical') {
|
| 1572 |
+
filtered = currentData.issues.filter(i => i.severity === 'critical');
|
| 1573 |
+
showToast(`🔍 عرض ${filtered.length} مشكلة حرجة`, 'info');
|
| 1574 |
+
} else if (type === 'open') {
|
| 1575 |
+
filtered = currentData.issues.filter(i => i.severity !== 'success');
|
| 1576 |
+
showToast(`🔍 عرض ${filtered.length} مشكلة مفتوحة`, 'info');
|
| 1577 |
+
} else if (type === 'all') {
|
| 1578 |
+
showToast(`🔍 عرض ${filtered.length} مشكلة`, 'info');
|
| 1579 |
+
}
|
| 1580 |
+
|
| 1581 |
+
renderIssues(filtered);
|
| 1582 |
+
}
|
| 1583 |
+
|
| 1584 |
+
// Show Issue Details
|
| 1585 |
+
function showIssueDetails(id) {
|
| 1586 |
+
const issue = currentData.issues.find(i => i.id === id);
|
| 1587 |
+
if (issue) {
|
| 1588 |
+
showToast(`📋 ${issue.title} - ${issue.file}`, 'info');
|
| 1589 |
+
}
|
| 1590 |
+
}
|
| 1591 |
+
|
| 1592 |
+
// Change Chart Period
|
| 1593 |
+
function changePeriod(period) {
|
| 1594 |
+
// Update active tab
|
| 1595 |
+
document.querySelectorAll('.chart-tab').forEach(tab => {
|
| 1596 |
+
tab.classList.remove('active');
|
| 1597 |
+
if (tab.dataset.period === period) {
|
| 1598 |
+
tab.classList.add('active');
|
| 1599 |
+
}
|
| 1600 |
+
});
|
| 1601 |
+
|
| 1602 |
+
// Update chart data based on period
|
| 1603 |
+
showToast(`📊 عرض بيانات ${period === 'day' ? '24 ساعة' : period === 'week' ? 'أسبوع' : 'شهر'}`, 'info');
|
| 1604 |
+
|
| 1605 |
+
// Simulate data update
|
| 1606 |
+
const randomFactor = period === 'day' ? 1 : period === 'week' ? 7 : 30;
|
| 1607 |
+
currentData.threats = Math.floor(Math.random() * 2000 * randomFactor) + 500;
|
| 1608 |
+
updateStatsUI();
|
| 1609 |
+
}
|
| 1610 |
+
|
| 1611 |
+
// Search Functionality
|
| 1612 |
+
function setupEventListeners() {
|
| 1613 |
+
// Navigation
|
| 1614 |
+
document.querySelectorAll('.nav-item').forEach(item => {
|
| 1615 |
+
item.addEventListener('click', function() {
|
| 1616 |
+
const view = this.dataset.view;
|
| 1617 |
+
|
| 1618 |
+
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
|
| 1619 |
+
this.classList.add('active');
|
| 1620 |
+
|
| 1621 |
+
// Close mobile menu when navigating
|
| 1622 |
+
closeMobileMenu();
|
| 1623 |
+
|
| 1624 |
+
if (view === 'settings') {
|
| 1625 |
+
openSettings();
|
| 1626 |
+
} else if (view === 'help') {
|
| 1627 |
+
showToast('📖 المساعدة: استخدم القائمة للتنقل بين الأقسام', 'info');
|
| 1628 |
+
} else {
|
| 1629 |
+
showToast(`📂 الانتقال إلى ${this.querySelector('span').textContent}`, 'info');
|
| 1630 |
+
}
|
| 1631 |
+
});
|
| 1632 |
+
});
|
| 1633 |
+
|
| 1634 |
+
// Search
|
| 1635 |
+
const searchInput = document.getElementById('searchInput');
|
| 1636 |
+
const searchResults = document.getElementById('searchResults');
|
| 1637 |
+
|
| 1638 |
+
searchInput.addEventListener('input', function() {
|
| 1639 |
+
const query = this.value.toLowerCase();
|
| 1640 |
+
|
| 1641 |
+
if (query.length < 2) {
|
| 1642 |
+
searchResults.classList.remove('active');
|
| 1643 |
+
return;
|
| 1644 |
+
}
|
| 1645 |
+
|
| 1646 |
+
// Search in issues and repos
|
| 1647 |
+
const results = [];
|
| 1648 |
+
|
| 1649 |
+
currentData.issues.forEach(issue => {
|
| 1650 |
+
if (issue.title.toLowerCase().includes(query) || issue.file.toLowerCase().includes(query)) {
|
| 1651 |
+
results.push({ type: 'issue', title: issue.title, subtitle: issue.file });
|
| 1652 |
+
}
|
| 1653 |
+
});
|
| 1654 |
+
|
| 1655 |
+
currentData.repos.forEach(repo => {
|
| 1656 |
+
if (repo.name.toLowerCase().includes(query)) {
|
| 1657 |
+
results.push({ type: 'repo', title: repo.name, subtitle: `⭐ ${repo.stars} | 🔀 ${repo.pullRequests}` });
|
| 1658 |
+
}
|
| 1659 |
+
});
|
| 1660 |
+
|
| 1661 |
+
if (results.length > 0) {
|
| 1662 |
+
searchResults.innerHTML = results.map(r => `
|
| 1663 |
+
<div class="search-result-item">
|
| 1664 |
+
<div style="font-weight: 500;">${r.title}</div>
|
| 1665 |
+
<div style="font-size: 12px; color: var(--text-muted);">${r.subtitle}</div>
|
| 1666 |
+
</div>
|
| 1667 |
+
`).join('');
|
| 1668 |
+
searchResults.classList.add('active');
|
| 1669 |
+
} else {
|
| 1670 |
+
searchResults.innerHTML = '<div class="search-result-item">لا توجد نتائج</div>';
|
| 1671 |
+
searchResults.classList.add('active');
|
| 1672 |
+
}
|
| 1673 |
+
});
|
| 1674 |
+
|
| 1675 |
+
searchInput.addEventListener('blur', function() {
|
| 1676 |
+
setTimeout(() => {
|
| 1677 |
+
searchResults.classList.remove('active');
|
| 1678 |
+
}, 200);
|
| 1679 |
+
});
|
| 1680 |
+
|
| 1681 |
+
searchInput.addEventListener('focus', function() {
|
| 1682 |
+
if (this.value.length >= 2) {
|
| 1683 |
+
searchResults.classList.add('active');
|
| 1684 |
+
}
|
| 1685 |
+
});
|
| 1686 |
+
|
| 1687 |
+
// Notification button
|
| 1688 |
+
document.getElementById('notificationBtn').addEventListener('click', function() {
|
| 1689 |
+
showToast('🔔 الإشعارات: 5 إشعارات جديدة', 'info');
|
| 1690 |
+
document.getElementById('notificationBadge').textContent = '0';
|
| 1691 |
+
});
|
| 1692 |
+
}
|
| 1693 |
+
|
| 1694 |
+
// Settings Panel
|
| 1695 |
+
function openSettings() {
|
| 1696 |
+
document.getElementById('settingsPanel').classList.add('active');
|
| 1697 |
+
}
|
| 1698 |
+
|
| 1699 |
+
function closeSettings() {
|
| 1700 |
+
document.getElementById('settingsPanel').classList.remove('active');
|
| 1701 |
+
}
|
| 1702 |
+
|
| 1703 |
+
// Toast Notifications
|
| 1704 |
+
function showToast(message, type = 'info') {
|
| 1705 |
+
const container = document.getElementById('toastContainer');
|
| 1706 |
+
const toast = document.createElement('div');
|
| 1707 |
+
toast.className = `toast ${type}`;
|
| 1708 |
+
toast.innerHTML = message;
|
| 1709 |
+
container.appendChild(toast);
|
| 1710 |
+
|
| 1711 |
+
setTimeout(() => {
|
| 1712 |
+
toast.remove();
|
| 1713 |
+
}, 3000);
|
| 1714 |
+
}
|
| 1715 |
+
|
| 1716 |
+
// Close settings on outside click
|
| 1717 |
+
document.getElementById('settingsPanel').addEventListener('click', function(e) {
|
| 1718 |
+
if (e.target === this) {
|
| 1719 |
+
closeSettings();
|
| 1720 |
+
}
|
| 1721 |
+
});
|
| 1722 |
+
</script>
|
| 1723 |
+
</body>
|
| 1724 |
+
</html>
|
public/data/latest.json
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"metadata": {
|
| 3 |
+
"timestamp": "2026-01-13T02:00:00.000Z",
|
| 4 |
+
"version": "1.0.0",
|
| 5 |
+
"tool": "auto-guardian",
|
| 6 |
+
"git": {
|
| 7 |
+
"commit_sha": "abc1234",
|
| 8 |
+
"branch": "main",
|
| 9 |
+
"workflow": "auto-guardian-scan"
|
| 10 |
+
}
|
| 11 |
+
},
|
| 12 |
+
"summary": {
|
| 13 |
+
"total_issues": 23,
|
| 14 |
+
"critical_issues": 2,
|
| 15 |
+
"high_issues": 5,
|
| 16 |
+
"medium_issues": 8,
|
| 17 |
+
"low_issues": 6,
|
| 18 |
+
"info_issues": 2,
|
| 19 |
+
"files_scanned": 15,
|
| 20 |
+
"security_score": 78,
|
| 21 |
+
"grade": "C"
|
| 22 |
+
},
|
| 23 |
+
"languages": {
|
| 24 |
+
"detected": ["python", "javascript", "typescript", "go"],
|
| 25 |
+
"lines_of_code": {
|
| 26 |
+
"python": 2450,
|
| 27 |
+
"javascript": 1890,
|
| 28 |
+
"typescript": 2100,
|
| 29 |
+
"go": 1200
|
| 30 |
+
},
|
| 31 |
+
"tools_used": {
|
| 32 |
+
"bandit": { "issues": 8, "status": "completed" },
|
| 33 |
+
"pylint": { "issues": 5, "status": "completed" },
|
| 34 |
+
"eslint": { "issues": 6, "status": "completed" },
|
| 35 |
+
"gosec": { "issues": 4, "status": "completed" }
|
| 36 |
+
}
|
| 37 |
+
},
|
| 38 |
+
"findings": [
|
| 39 |
+
{
|
| 40 |
+
"tool": "bandit",
|
| 41 |
+
"tool_name": "Bandit",
|
| 42 |
+
"severity": "CRITICAL",
|
| 43 |
+
"severity_level": 1,
|
| 44 |
+
"file": "src/authentication.py",
|
| 45 |
+
"line": 45,
|
| 46 |
+
"column": 20,
|
| 47 |
+
"rule_id": "B105",
|
| 48 |
+
"rule_name": "hardcoded_password",
|
| 49 |
+
"message": "Possible hardcoded password: 'admin123'",
|
| 50 |
+
"description": "Hardcoded password detected. This is a security vulnerability as passwords should be stored in environment variables or secure configuration files.",
|
| 51 |
+
"confidence": "HIGH",
|
| 52 |
+
"remediation": "Use environment variables or a secrets manager to store credentials. Example: os.environ.get('DB_PASSWORD')",
|
| 53 |
+
"code_snippet": "password = 'admin123' # This is insecure!",
|
| 54 |
+
"language": "python"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"tool": "gosec",
|
| 58 |
+
"tool_name": "Gosec",
|
| 59 |
+
"severity": "CRITICAL",
|
| 60 |
+
"severity_level": 1,
|
| 61 |
+
"file": "internal/api/handler.go",
|
| 62 |
+
"line": 89,
|
| 63 |
+
"column": 15,
|
| 64 |
+
"rule_id": "G104",
|
| 65 |
+
"rule_name": "Error check skipped",
|
| 66 |
+
"message": "Errors unhandled.",
|
| 67 |
+
"description": "Errors are being ignored without proper handling, which could lead to silent failures and security issues.",
|
| 68 |
+
"confidence": "HIGH",
|
| 69 |
+
"remediation": "Always handle errors properly using if err != nil { return err } pattern",
|
| 70 |
+
"code_snippet": "_ = json.Unmarshal(data, &obj) // Error ignored!",
|
| 71 |
+
"language": "go"
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"tool": "eslint",
|
| 75 |
+
"tool_name": "ESLint",
|
| 76 |
+
"severity": "HIGH",
|
| 77 |
+
"severity_level": 2,
|
| 78 |
+
"file": "src/utils/auth.js",
|
| 79 |
+
"line": 12,
|
| 80 |
+
"column": 18,
|
| 81 |
+
"rule_id": "security/detect-object-injection",
|
| 82 |
+
"rule_name": "Object Injection",
|
| 83 |
+
"message": "Avoid objects with unknown properties, object injection is possible.",
|
| 84 |
+
"description": "Object injection can lead to prototype pollution vulnerabilities if user input is used as object keys.",
|
| 85 |
+
"confidence": "HIGH",
|
| 86 |
+
"remediation": "Validate and sanitize user input before using it to access object properties",
|
| 87 |
+
"code_snippet": "const value = userData[userKey]; // Potential injection!",
|
| 88 |
+
"language": "javascript"
|
| 89 |
+
},
|
| 90 |
+
{
|
| 91 |
+
"tool": "bandit",
|
| 92 |
+
"tool_name": "Bandit",
|
| 93 |
+
"severity": "HIGH",
|
| 94 |
+
"severity_level": 2,
|
| 95 |
+
"file": "src/database/connection.py",
|
| 96 |
+
"line": 67,
|
| 97 |
+
"column": 25,
|
| 98 |
+
"rule_id": "B501",
|
| 99 |
+
"rule_name": "SQL statement with parameters",
|
| 100 |
+
"message": "Possible SQL injection: VALUES ('%s')",
|
| 101 |
+
"description": "SQL injection vulnerability detected. String formatting used to build SQL query could allow attackers to manipulate queries.",
|
| 102 |
+
"confidence": "HIGH",
|
| 103 |
+
"remediation": "Use parameterized queries or ORM methods instead of string formatting. Example: cursor.execute('SELECT * FROM users WHERE id = ?', (user_id,))",
|
| 104 |
+
"code_snippet": "query = f\"SELECT * FROM users WHERE id = '{user_id}'\"",
|
| 105 |
+
"language": "python"
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"tool": "gosec",
|
| 109 |
+
"tool_name": "Gosec",
|
| 110 |
+
"severity": "HIGH",
|
| 111 |
+
"severity_level": 2,
|
| 112 |
+
"file": "cmd/server/main.go",
|
| 113 |
+
"line": 234,
|
| 114 |
+
"column": 10,
|
| 115 |
+
"rule_id": "G107",
|
| 116 |
+
"rule_name": "HTTP absolute path traversal",
|
| 117 |
+
"message": "HTTP absolute path traversal",
|
| 118 |
+
"description": "Path traversal vulnerability detected. User input used directly in file paths without validation.",
|
| 119 |
+
"confidence": "HIGH",
|
| 120 |
+
"remediation": "Validate and sanitize file paths, use filepath.Clean and check for paths outside the allowed directory",
|
| 121 |
+
"code_snippet": "filePath := r.URL.Path + filename",
|
| 122 |
+
"language": "go"
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"tool": "eslint",
|
| 126 |
+
"tool_name": "ESLint",
|
| 127 |
+
"severity": "HIGH",
|
| 128 |
+
"severity_level": 2,
|
| 129 |
+
"file": "src/config/loader.ts",
|
| 130 |
+
"line": 28,
|
| 131 |
+
"column": 22,
|
| 132 |
+
"rule_id": "no-sync",
|
| 133 |
+
"rule_name": "Synchronous Operations",
|
| 134 |
+
"message": "Unexpected sync operation. Use asynchronous operations instead.",
|
| 135 |
+
"description": "Synchronous file operations can block the event loop and cause performance issues in Node.js applications.",
|
| 136 |
+
"confidence": "MEDIUM",
|
| 137 |
+
"remediation": "Use fs.promises.readFile() or fs.readFileSync() is acceptable but document why",
|
| 138 |
+
"code_snippet": "const config = fs.readFileSync(configPath, 'utf8');",
|
| 139 |
+
"language": "typescript"
|
| 140 |
+
},
|
| 141 |
+
{
|
| 142 |
+
"tool": "pylint",
|
| 143 |
+
"tool_name": "Pylint",
|
| 144 |
+
"severity": "HIGH",
|
| 145 |
+
"severity_level": 2,
|
| 146 |
+
"file": "src/api/routes.py",
|
| 147 |
+
"line": 156,
|
| 148 |
+
"column": 8,
|
| 149 |
+
"rule_id": "C0115",
|
| 150 |
+
"rule_name": "Missing function docstring",
|
| 151 |
+
"message": "Missing function or method docstring",
|
| 152 |
+
"description": "Public functions should have docstrings documenting their purpose, parameters, and return values.",
|
| 153 |
+
"confidence": "HIGH",
|
| 154 |
+
"remediation": "Add a docstring following Google or NumPy style format",
|
| 155 |
+
"code_snippet": "def process_data(input_data):\n # Missing docstring\n return transform(input_data)",
|
| 156 |
+
"language": "python"
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"tool": "bandit",
|
| 160 |
+
"tool_name": "Bandit",
|
| 161 |
+
"severity": "MEDIUM",
|
| 162 |
+
"severity_level": 3,
|
| 163 |
+
"file": "src/utils/helpers.py",
|
| 164 |
+
"line": 23,
|
| 165 |
+
"column": 15,
|
| 166 |
+
"rule_id": "B403",
|
| 167 |
+
"rule_name": "Consider possible security implications of pickle module",
|
| 168 |
+
"message": "Consider possible security implications of pickle module.",
|
| 169 |
+
"description": "The pickle module is not secure. Untrusted data can be crafted to execute arbitrary code.",
|
| 170 |
+
"confidence": "HIGH",
|
| 171 |
+
"remediation": "Use JSON or other safe serialization formats instead of pickle",
|
| 172 |
+
"code_snippet": "import pickle # Security risk!",
|
| 173 |
+
"language": "python"
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"tool": "eslint",
|
| 177 |
+
"tool_name": "ESLint",
|
| 178 |
+
"severity": "MEDIUM",
|
| 179 |
+
"severity_level": 3,
|
| 180 |
+
"file": "src/services/api.js",
|
| 181 |
+
"line": 45,
|
| 182 |
+
"column": 13,
|
| 183 |
+
"rule_id": "no-console",
|
| 184 |
+
"rule_name": "Console Log",
|
| 185 |
+
"message": "Unexpected console statement.",
|
| 186 |
+
"description": "Console statements should be removed in production code as they may expose sensitive information.",
|
| 187 |
+
"confidence": "HIGH",
|
| 188 |
+
"remediation": "Remove console.log statements or use a proper logging library with configurable log levels",
|
| 189 |
+
"code_snippet": "console.log('User data:', user); // Remove in production",
|
| 190 |
+
"language": "javascript"
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"tool": "pylint",
|
| 194 |
+
"tool_name": "Pylint",
|
| 195 |
+
"severity": "MEDIUM",
|
| 196 |
+
"severity_level": 3,
|
| 197 |
+
"file": "src/utils/validators.py",
|
| 198 |
+
"line": 78,
|
| 199 |
+
"column": 12,
|
| 200 |
+
"rule_id": "W0612",
|
| 201 |
+
"rule_name": "Unused variable",
|
| 202 |
+
"message": "Unused variable 'unused_param'",
|
| 203 |
+
"description": "Unused variables should be removed to keep code clean and maintainable.",
|
| 204 |
+
"confidence": "HIGH",
|
| 205 |
+
"remediation": "Remove unused variables or prefix with underscore to indicate intentional non-use",
|
| 206 |
+
"code_snippet": "def process(a, b, unused_param): # 'unused_param' is never used\n return a * 2",
|
| 207 |
+
"language": "python"
|
| 208 |
+
},
|
| 209 |
+
{
|
| 210 |
+
"tool": "gosec",
|
| 211 |
+
"tool_name": "Gosec",
|
| 212 |
+
"severity": "MEDIUM",
|
| 213 |
+
"severity_level": 3,
|
| 214 |
+
"file": "internal/utils/crypto.go",
|
| 215 |
+
"line": 112,
|
| 216 |
+
"column": 8,
|
| 217 |
+
"rule_id": "G401",
|
| 218 |
+
"rule_name": "Use of weak cryptographic primitive",
|
| 219 |
+
"message": "Use of weak cryptographic primitive (MD5 or SHA1)",
|
| 220 |
+
"description": "MD5 and SHA1 are considered cryptographically broken. Use SHA-256 or better.",
|
| 221 |
+
"confidence": "HIGH",
|
| 222 |
+
"remediation": "Use crypto/sha256 or higher instead of MD5/SHA1",
|
| 223 |
+
"code_snippet": "hash := md5.Sum([]byte(data)) // Use SHA-256!",
|
| 224 |
+
"language": "go"
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"tool": "eslint",
|
| 228 |
+
"tool_name": "ESLint",
|
| 229 |
+
"severity": "MEDIUM",
|
| 230 |
+
"severity_level": 3,
|
| 231 |
+
"file": "src/components/UserForm.jsx",
|
| 232 |
+
"line": 89,
|
| 233 |
+
"column": 15,
|
| 234 |
+
"rule_id": "react/no-danger",
|
| 235 |
+
"rule_name": "Dangerous Props",
|
| 236 |
+
"message": "Dangerous use of dangerouslySetInnerHTML",
|
| 237 |
+
"description": "Using dangerouslySetInnerHTML can expose XSS vulnerabilities if the content is not properly sanitized.",
|
| 238 |
+
"confidence": "HIGH",
|
| 239 |
+
"remediation": "Avoid using dangerouslySetInnerHTML or ensure content is sanitized with a library like DOMPurify",
|
| 240 |
+
"code_snippet": "<div dangerouslySetInnerHTML={{ __html: userContent }} />",
|
| 241 |
+
"language": "javascript"
|
| 242 |
+
},
|
| 243 |
+
{
|
| 244 |
+
"tool": "pylint",
|
| 245 |
+
"tool_name": "Pylint",
|
| 246 |
+
"severity": "MEDIUM",
|
| 247 |
+
"severity_level": 3,
|
| 248 |
+
"file": "src/api/middleware.py",
|
| 249 |
+
"line": 34,
|
| 250 |
+
"column": 4,
|
| 251 |
+
"rule_id": "R0913",
|
| 252 |
+
"rule_name": "Too many arguments",
|
| 253 |
+
"message": "Too many arguments (6/5)",
|
| 254 |
+
"description": "Functions with more than 5 arguments are difficult to maintain and use. Consider refactoring.",
|
| 255 |
+
"confidence": "MEDIUM",
|
| 256 |
+
"remediation": "Group related parameters into a configuration object or class",
|
| 257 |
+
"code_snippet": "def create_user(name, email, password, role, department, manager): pass # Too many!",
|
| 258 |
+
"language": "python"
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"tool": "gosec",
|
| 262 |
+
"tool_name": "Gosec",
|
| 263 |
+
"severity": "MEDIUM",
|
| 264 |
+
"severity_level": 3,
|
| 265 |
+
"file": "internal/api/middleware.go",
|
| 266 |
+
"line": 56,
|
| 267 |
+
"column": 12,
|
| 268 |
+
"rule_id": "G304",
|
| 269 |
+
"rule_name": "File path traversal",
|
| 270 |
+
"message": "File path traversal detected",
|
| 271 |
+
"description": "User input used directly in file path without proper validation could allow path traversal attacks.",
|
| 272 |
+
"confidence": "HIGH",
|
| 273 |
+
"remediation": "Validate file paths and ensure they are within the allowed directory using filepath.Clean and path verification",
|
| 274 |
+
"code_snippet": "file, _ := os.Open(userProvidedPath)",
|
| 275 |
+
"language": "go"
|
| 276 |
+
},
|
| 277 |
+
{
|
| 278 |
+
"tool": "eslint",
|
| 279 |
+
"tool_name": "ESLint",
|
| 280 |
+
"severity": "MEDIUM",
|
| 281 |
+
"severity_level": 3,
|
| 282 |
+
"file": "src/utils/api.js",
|
| 283 |
+
"line": 156,
|
| 284 |
+
"column": 9,
|
| 285 |
+
"rule_id": "no-underscore-dangle",
|
| 286 |
+
"rule_name": "Underscore Dangle",
|
| 287 |
+
"message": "Unexpected dangling '_' in 'fetch_url_'",
|
| 288 |
+
"description": "Variable names with trailing underscores are unconventional and may confuse developers.",
|
| 289 |
+
"confidence": "MEDIUM",
|
| 290 |
+
"remediation": "Use conventional naming without trailing underscores",
|
| 291 |
+
"code_snippet": "const fetch_url_ = 'https://api.example.com';",
|
| 292 |
+
"language": "javascript"
|
| 293 |
+
},
|
| 294 |
+
{
|
| 295 |
+
"tool": "bandit",
|
| 296 |
+
"tool_name": "Bandit",
|
| 297 |
+
"severity": "LOW",
|
| 298 |
+
"severity_level": 4,
|
| 299 |
+
"file": "tests/test_sample.py",
|
| 300 |
+
"line": 12,
|
| 301 |
+
"column": 10,
|
| 302 |
+
"rule_id": "B101",
|
| 303 |
+
"rule_name": "Assert used",
|
| 304 |
+
"message": "Use of assert detected",
|
| 305 |
+
"description": "Assert statements should not be used in production code as they can be disabled with Python's -O flag.",
|
| 306 |
+
"confidence": "HIGH",
|
| 307 |
+
"remediation": "Use unittest assertions or raise exceptions instead of assert",
|
| 308 |
+
"code_snippet": "assert result == expected, 'Test failed'",
|
| 309 |
+
"language": "python"
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"tool": "pylint",
|
| 313 |
+
"tool_name": "Pylint",
|
| 314 |
+
"severity": "LOW",
|
| 315 |
+
"severity_level": 4,
|
| 316 |
+
"file": "src/config/settings.py",
|
| 317 |
+
"line": 8,
|
| 318 |
+
"column": 0,
|
| 319 |
+
"rule_id": "C0114",
|
| 320 |
+
"rule_name": "Missing module docstring",
|
| 321 |
+
"message": "Missing module docstring",
|
| 322 |
+
"description": "Module-level docstrings should be present at the top of each file.",
|
| 323 |
+
"confidence": "HIGH",
|
| 324 |
+
"remediation": "Add a module docstring describing the purpose of this module",
|
| 325 |
+
"code_snippet": "# Module content starts here without docstring",
|
| 326 |
+
"language": "python"
|
| 327 |
+
},
|
| 328 |
+
{
|
| 329 |
+
"tool": "eslint",
|
| 330 |
+
"tool_name": "ESLint",
|
| 331 |
+
"severity": "LOW",
|
| 332 |
+
"severity_level": 4,
|
| 333 |
+
"file": "src/index.js",
|
| 334 |
+
"line": 3,
|
| 335 |
+
"column": 8,
|
| 336 |
+
"rule_id": "no-unused-vars",
|
| 337 |
+
"rule_name": "Unused Variables",
|
| 338 |
+
"message": "'React' is defined but never used.",
|
| 339 |
+
"description": "Unused variables increase code complexity and should be removed.",
|
| 340 |
+
"confidence": "HIGH",
|
| 341 |
+
"remediation": "Remove the unused import or use the variable",
|
| 342 |
+
"code_snippet": "import React from 'react'; // React is not used directly",
|
| 343 |
+
"language": "javascript"
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"tool": "gosec",
|
| 347 |
+
"tool_name": "Gosec",
|
| 348 |
+
"severity": "LOW",
|
| 349 |
+
"severity_level": 4,
|
| 350 |
+
"file": "internal/config/loader.go",
|
| 351 |
+
"line": 23,
|
| 352 |
+
"column": 6,
|
| 353 |
+
"rule_id": "G108",
|
| 354 |
+
"rule_name": "Performance regression detected",
|
| 355 |
+
"message": "Benchmark result indicates potential performance regression",
|
| 356 |
+
"description": "The function shows potential performance issues based on benchmark comparison.",
|
| 357 |
+
"confidence": "MEDIUM",
|
| 358 |
+
"remediation": "Review the function for potential optimizations like caching, reducing allocations, or algorithmic improvements",
|
| 359 |
+
"code_snippet": "// Consider adding caching for repeated calls",
|
| 360 |
+
"language": "go"
|
| 361 |
+
},
|
| 362 |
+
{
|
| 363 |
+
"tool": "pylint",
|
| 364 |
+
"tool_name": "Pylint",
|
| 365 |
+
"severity": "LOW",
|
| 366 |
+
"severity_level": 4,
|
| 367 |
+
"file": "src/utils/constants.py",
|
| 368 |
+
"line": 5,
|
| 369 |
+
"column": 0,
|
| 370 |
+
"rule_id": "C0103",
|
| 371 |
+
"rule_name": "Invalid constant name",
|
| 372 |
+
"message": "Constant name \"MAX_SIZE\" doesn't conform to UPPER_CASE naming style",
|
| 373 |
+
"description": "Constants should be named in UPPER_CASE with underscores.",
|
| 374 |
+
"confidence": "HIGH",
|
| 375 |
+
"remediation": "Rename the constant to use UPPER_CASE format",
|
| 376 |
+
"code_snippet": "max_size = 100 # Should be MAX_SIZE = 100",
|
| 377 |
+
"language": "python"
|
| 378 |
+
},
|
| 379 |
+
{
|
| 380 |
+
"tool": "eslint",
|
| 381 |
+
"tool_name": "ESLint",
|
| 382 |
+
"severity": "LOW",
|
| 383 |
+
"severity_level": 4,
|
| 384 |
+
"file": "src/styles/main.css",
|
| 385 |
+
"line": 1,
|
| 386 |
+
"column": 1,
|
| 387 |
+
"rule_id": "no-irregular-whitespace",
|
| 388 |
+
"rule_name": "Irregular Whitespace",
|
| 389 |
+
"message": "Irregular whitespace not allowed.",
|
| 390 |
+
"description": "Irregular whitespace characters can cause rendering issues and are typically typos.",
|
| 391 |
+
"confidence": "HIGH",
|
| 392 |
+
"remediation": "Remove any irregular whitespace characters from the file",
|
| 393 |
+
"code_snippet": " \t /* Space at beginning of file */",
|
| 394 |
+
"language": "javascript"
|
| 395 |
+
},
|
| 396 |
+
{
|
| 397 |
+
"tool": "bandit",
|
| 398 |
+
"tool_name": "Bandit",
|
| 399 |
+
"severity": "INFO",
|
| 400 |
+
"severity_level": 5,
|
| 401 |
+
"file": "setup.py",
|
| 402 |
+
"line": 15,
|
| 403 |
+
"column": 7,
|
| 404 |
+
"rule_id": "B602",
|
| 405 |
+
"rule_name": "Subprocess call with shell=True",
|
| 406 |
+
"message": "subprocess call with shell=True identified",
|
| 407 |
+
"description": "Using shell=True in subprocess allows shell injection attacks. Consider using shell=False.",
|
| 408 |
+
"confidence": "MEDIUM",
|
| 409 |
+
"remediation": "Use shell=False and pass arguments as a list to prevent shell injection",
|
| 410 |
+
"code_snippet": "subprocess.run(f'ls {directory}', shell=True) # Risky!",
|
| 411 |
+
"language": "python"
|
| 412 |
+
},
|
| 413 |
+
{
|
| 414 |
+
"tool": "pylint",
|
| 415 |
+
"tool_name": "Pylint",
|
| 416 |
+
"severity": "INFO",
|
| 417 |
+
"severity_level": 5,
|
| 418 |
+
"file": "src/main.py",
|
| 419 |
+
"line": 1,
|
| 420 |
+
"column": 1,
|
| 421 |
+
"rule_id": "C0111",
|
| 422 |
+
"rule_name": "Missing function docstring",
|
| 423 |
+
"message": "Missing function or method docstring (missing-docstring)",
|
| 424 |
+
"description": "Function docstrings help developers understand the purpose and usage of functions.",
|
| 425 |
+
"confidence": "MEDIUM",
|
| 426 |
+
"remediation": "Add a docstring explaining what the function does, its parameters, and return value",
|
| 427 |
+
"code_snippet": "def main(): # Missing docstring\n run_app()",
|
| 428 |
+
"language": "python"
|
| 429 |
+
}
|
| 430 |
+
],
|
| 431 |
+
"trends": {
|
| 432 |
+
"previous_scan": null,
|
| 433 |
+
"improvement": null
|
| 434 |
+
}
|
| 435 |
+
}
|
requirements.txt
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# متطلبات نظام الحارس التلقائي
|
| 2 |
+
# Auto Guardian System Requirements
|
| 3 |
+
# ====================================
|
| 4 |
+
|
| 5 |
+
# الإصدار: 1.3.0
|
| 6 |
+
# تاريخ التحديث: 2024-10-13
|
| 7 |
+
|
| 8 |
+
# ===============================
|
| 9 |
+
# المتطلبات الأساسية للنظام
|
| 10 |
+
# ===============================
|
| 11 |
+
|
| 12 |
+
# طلبات HTTP للتواصل مع APIs
|
| 13 |
+
requests>=2.31.0
|
| 14 |
+
|
| 15 |
+
# معالجة ملفات YAML للتكوين
|
| 16 |
+
pyyaml>=6.0
|
| 17 |
+
|
| 18 |
+
# متغيرات البيئة
|
| 19 |
+
python-dotenv>=1.0.0
|
| 20 |
+
|
| 21 |
+
# التواريخ والأوقات
|
| 22 |
+
pytz>=2023.3
|
| 23 |
+
|
| 24 |
+
# التحقق من صحة البيانات
|
| 25 |
+
marshmallow>=3.20.0
|
| 26 |
+
|
| 27 |
+
# ===============================
|
| 28 |
+
# التوثيق
|
| 29 |
+
# ===============================
|
| 30 |
+
|
| 31 |
+
# توليد التوثيق
|
| 32 |
+
sphinx>=7.0.0
|
| 33 |
+
|
| 34 |
+
# سمة التوثيق Read the Docs
|
| 35 |
+
sphinx-rtd-theme>=1.3.0
|
| 36 |
+
|
| 37 |
+
# ===============================
|
| 38 |
+
# أدوات التطوير والاختبار
|
| 39 |
+
# ===============================
|
| 40 |
+
|
| 41 |
+
# إطار الاختبارات
|
| 42 |
+
pytest>=7.4.0
|
| 43 |
+
pytest-cov>=4.1.0
|
| 44 |
+
pytest-mock>=3.11.0
|
| 45 |
+
pytest-asyncio>=0.21.0
|
| 46 |
+
|
| 47 |
+
# تغطية الكود
|
| 48 |
+
coverage>=7.3.0
|
| 49 |
+
|
| 50 |
+
# ===============================
|
| 51 |
+
# جودة الكود
|
| 52 |
+
# ===============================
|
| 53 |
+
|
| 54 |
+
# تنسيق كود Python
|
| 55 |
+
black>=23.0.0
|
| 56 |
+
|
| 57 |
+
# فحص الكود
|
| 58 |
+
flake8>=6.0.0
|
| 59 |
+
flake8-builtins>=2.1.0
|
| 60 |
+
flake8-docstrings>=1.7.0
|
| 61 |
+
flake8-comprehensions>=3.12.0
|
| 62 |
+
|
| 63 |
+
# نوع البيانات الثابت
|
| 64 |
+
mypy>=1.4.0
|
| 65 |
+
types-requests>=2.31.0
|
| 66 |
+
types-pyyaml>=6.0.0
|
| 67 |
+
|
| 68 |
+
# ترتيب الاستيرادات
|
| 69 |
+
isort>=5.12.0
|
| 70 |
+
|
| 71 |
+
# ===============================
|
| 72 |
+
# Docker والتطوير
|
| 73 |
+
# ===============================
|
| 74 |
+
|
| 75 |
+
# بناء الحاويات
|
| 76 |
+
docker>=6.1.0
|
| 77 |
+
docker-compose>=2.21.0
|
| 78 |
+
|
| 79 |
+
# ===============================
|
| 80 |
+
# المراقبة والتقارير
|
| 81 |
+
# ===============================
|
| 82 |
+
|
| 83 |
+
# Prometheus client
|
| 84 |
+
prometheus-client>=0.17.0
|
| 85 |
+
|
| 86 |
+
# إرسال التنبيهات
|
| 87 |
+
slack-sdk>=3.21.0
|
| 88 |
+
discord-webhook>=1.3.0
|
| 89 |
+
|
| 90 |
+
# ===============================
|
| 91 |
+
# التطوير الإضافي (اختياري)
|
| 92 |
+
# ===============================
|
| 93 |
+
|
| 94 |
+
# أدوات مساعدة
|
| 95 |
+
click>=8.1.0
|
| 96 |
+
rich>=13.5.0
|
| 97 |
+
colorama>=0.4.6
|
| 98 |
+
|
| 99 |
+
# معالجة الأخطاء
|
| 100 |
+
sentry-sdk>=1.30.0
|
| 101 |
+
|
| 102 |
+
# تسجيل محسن
|
| 103 |
+
loguru>=0.7.0
|
| 104 |
+
|
| 105 |
+
# تثبيت التطوير:
|
| 106 |
+
# pip install -r requirements-dev.txt
|
robots.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
User-agent: *
|
| 2 |
+
Allow: /
|
| 3 |
+
|
| 4 |
+
Sitemap: https://abdulelahothmangwaith.github.io/Auto-Guardian-Core/sitemap.xml
|
scripts/aggregate_results.py
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# استخراج نتائج الفحص وتجميعها في ملف JSON واحد
|
| 2 |
+
|
| 3 |
+
import json
|
| 4 |
+
import os
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
def load_json_file(filepath, default=None):
|
| 9 |
+
"""تحميل ملف JSON مع معالجة الأخطاء"""
|
| 10 |
+
if os.path.exists(filepath):
|
| 11 |
+
try:
|
| 12 |
+
with open(filepath, 'r', encoding='utf-8') as f:
|
| 13 |
+
return json.load(f)
|
| 14 |
+
except (json.JSONDecodeError, IOError):
|
| 15 |
+
return default if default is not None else []
|
| 16 |
+
return default if default is not None else []
|
| 17 |
+
|
| 18 |
+
def normalize_bandit_result(issue):
|
| 19 |
+
"""تطبيع نتيجة Bandit"""
|
| 20 |
+
return {
|
| 21 |
+
"tool": "bandit",
|
| 22 |
+
"tool_name": "Bandit",
|
| 23 |
+
"severity": issue.get("issue_severity", "MEDIUM").upper(),
|
| 24 |
+
"severity_level": get_severity_level(issue.get("issue_severity", "MEDIUM")),
|
| 25 |
+
"file": issue.get("filename", ""),
|
| 26 |
+
"line": issue.get("line_number", 0),
|
| 27 |
+
"column": issue.get("line_range", [0, 0])[0] if issue.get("line_range") else 0,
|
| 28 |
+
"rule_id": issue.get("test_id", ""),
|
| 29 |
+
"rule_name": issue.get("test_name", ""),
|
| 30 |
+
"message": issue.get("issue_text", ""),
|
| 31 |
+
"description": issue.get("issue_text", ""),
|
| 32 |
+
"confidence": issue.get("issue_confidence", "MEDIUM").upper(),
|
| 33 |
+
"remediation": issue.get("more_info", ""),
|
| 34 |
+
"code_snippet": "",
|
| 35 |
+
"language": "python"
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
def normalize_pylint_result(issue):
|
| 39 |
+
"""تطبيع نتيجة Pylint"""
|
| 40 |
+
return {
|
| 41 |
+
"tool": "pylint",
|
| 42 |
+
"tool_name": "Pylint",
|
| 43 |
+
"severity": map_pylint_severity(issue.get("type", "info")),
|
| 44 |
+
"severity_level": get_severity_level(map_pylint_severity(issue.get("type", "info"))),
|
| 45 |
+
"file": issue.get("path", ""),
|
| 46 |
+
"line": issue.get("line", 0),
|
| 47 |
+
"column": issue.get("column", 0),
|
| 48 |
+
"rule_id": issue.get("symbol", ""),
|
| 49 |
+
"rule_name": issue.get("message-id", ""),
|
| 50 |
+
"message": issue.get("message", ""),
|
| 51 |
+
"description": issue.get("message", ""),
|
| 52 |
+
"confidence": "HIGH",
|
| 53 |
+
"remediation": "",
|
| 54 |
+
"code_snippet": issue.get("body", ""),
|
| 55 |
+
"language": "python"
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
def normalize_eslint_result(issue):
|
| 59 |
+
"""تطبيع نتيجة ESLint"""
|
| 60 |
+
return {
|
| 61 |
+
"tool": "eslint",
|
| 62 |
+
"tool_name": "ESLint",
|
| 63 |
+
"severity": map_eslint_severity(issue.get("severity", 1)),
|
| 64 |
+
"severity_level": get_severity_level(map_eslint_severity(issue.get("severity", 1))),
|
| 65 |
+
"file": issue.get("filePath", ""),
|
| 66 |
+
"line": issue.get("line", 0),
|
| 67 |
+
"column": issue.get("column", 0),
|
| 68 |
+
"rule_id": issue.get("ruleId", ""),
|
| 69 |
+
"rule_name": issue.get("ruleId", ""),
|
| 70 |
+
"message": issue.get("message", ""),
|
| 71 |
+
"description": issue.get("message", ""),
|
| 72 |
+
"confidence": "HIGH",
|
| 73 |
+
"remediation": "",
|
| 74 |
+
"code_snippet": issue.get("source", ""),
|
| 75 |
+
"language": "javascript"
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
def normalize_gosec_result(issue):
|
| 79 |
+
"""تطبيع نتيجة Gosec"""
|
| 80 |
+
return {
|
| 81 |
+
"tool": "gosec",
|
| 82 |
+
"tool_name": "Gosec",
|
| 83 |
+
"severity": map_gosec_severity(issue.get("severity", "MEDIUM")),
|
| 84 |
+
"severity_level": get_severity_level(map_gosec_severity(issue.get("severity", "MEDIUM"))),
|
| 85 |
+
"file": issue.get("file", ""),
|
| 86 |
+
"line": issue.get("line", 0),
|
| 87 |
+
"column": 0,
|
| 88 |
+
"rule_id": issue.get("rule_id", ""),
|
| 89 |
+
"rule_name": issue.get("func_name", ""),
|
| 90 |
+
"message": issue.get("details", ""),
|
| 91 |
+
"description": issue.get("details", ""),
|
| 92 |
+
"confidence": "HIGH",
|
| 93 |
+
"remediation": "",
|
| 94 |
+
"code_snippet": "",
|
| 95 |
+
"language": "go"
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
def normalize_cargo_audit_result(vuln):
|
| 99 |
+
"""تطبيع نتيجة Cargo Audit"""
|
| 100 |
+
severity_map = {
|
| 101 |
+
"high": "CRITICAL",
|
| 102 |
+
"medium": "HIGH",
|
| 103 |
+
"low": "MEDIUM",
|
| 104 |
+
"unknown": "LOW"
|
| 105 |
+
}
|
| 106 |
+
return {
|
| 107 |
+
"tool": "cargo-audit",
|
| 108 |
+
"tool_name": "Cargo Audit",
|
| 109 |
+
"severity": severity_map.get(vuln.get("severity", "unknown"), "MEDIUM"),
|
| 110 |
+
"severity_level": get_severity_level(severity_map.get(vuln.get("severity", "unknown"), "MEDIUM")),
|
| 111 |
+
"file": vuln.get("package", {}).get("name", "unknown"),
|
| 112 |
+
"line": 0,
|
| 113 |
+
"column": 0,
|
| 114 |
+
"rule_id": vuln.get("id", ""),
|
| 115 |
+
"rule_name": vuln.get("advisory_id", ""),
|
| 116 |
+
"message": vuln.get("title", ""),
|
| 117 |
+
"description": vuln.get("description", ""),
|
| 118 |
+
"confidence": "HIGH",
|
| 119 |
+
"remediation": vuln.get("url", ""),
|
| 120 |
+
"code_snippet": "",
|
| 121 |
+
"language": "rust"
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
def map_pylint_severity(pylint_type):
|
| 125 |
+
"""تحويل نوع Pylint إلى شدة موحدة"""
|
| 126 |
+
severity_map = {
|
| 127 |
+
"error": "CRITICAL",
|
| 128 |
+
"warning": "HIGH",
|
| 129 |
+
"refactor": "MEDIUM",
|
| 130 |
+
"convention": "LOW",
|
| 131 |
+
"info": "INFO"
|
| 132 |
+
}
|
| 133 |
+
return severity_map.get(pylint_type.lower(), "MEDIUM")
|
| 134 |
+
|
| 135 |
+
def map_eslint_severity(eslint_severity):
|
| 136 |
+
"""تحويل شدة ESLint إلى ش��ة موحدة"""
|
| 137 |
+
severity_map = {
|
| 138 |
+
2: "CRITICAL", # Error
|
| 139 |
+
1: "HIGH", # Warning
|
| 140 |
+
0: "INFO" # Info
|
| 141 |
+
}
|
| 142 |
+
return severity_map.get(eslint_severity, "MEDIUM")
|
| 143 |
+
|
| 144 |
+
def map_gosec_severity(gosec_severity):
|
| 145 |
+
"""تحويل شدة Gosec إلى شدة موحدة"""
|
| 146 |
+
severity_map = {
|
| 147 |
+
"HIGH": "CRITICAL",
|
| 148 |
+
"MEDIUM": "HIGH",
|
| 149 |
+
"LOW": "MEDIUM",
|
| 150 |
+
"UNKNOWN": "LOW"
|
| 151 |
+
}
|
| 152 |
+
return severity_map.get(gosec_severity.upper(), "MEDIUM")
|
| 153 |
+
|
| 154 |
+
def get_severity_level(severity):
|
| 155 |
+
"""الحصول على مستوى الشدة للفرز"""
|
| 156 |
+
level_map = {
|
| 157 |
+
"CRITICAL": 1,
|
| 158 |
+
"HIGH": 2,
|
| 159 |
+
"MEDIUM": 3,
|
| 160 |
+
"LOW": 4,
|
| 161 |
+
"INFO": 5
|
| 162 |
+
}
|
| 163 |
+
return level_map.get(severity.upper(), 3)
|
| 164 |
+
|
| 165 |
+
def get_git_info():
|
| 166 |
+
"""استخراج معلومات Git"""
|
| 167 |
+
commit_sha = os.environ.get("GITHUB_SHA", "")[:7]
|
| 168 |
+
branch = os.environ.get("GITHUB_REF", "").replace("refs/heads/", "")
|
| 169 |
+
|
| 170 |
+
return {
|
| 171 |
+
"commit_sha": commit_sha,
|
| 172 |
+
"branch": branch,
|
| 173 |
+
"workflow": "auto-guardian-scan"
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
def detect_languages():
|
| 177 |
+
"""اكتشاف اللغات الموجودة في المشروع"""
|
| 178 |
+
languages = []
|
| 179 |
+
extensions = {
|
| 180 |
+
".py": "python",
|
| 181 |
+
".js": "javascript",
|
| 182 |
+
".ts": "typescript",
|
| 183 |
+
".jsx": "javascript",
|
| 184 |
+
".tsx": "typescript",
|
| 185 |
+
".go": "go",
|
| 186 |
+
".rs": "rust",
|
| 187 |
+
".java": "java",
|
| 188 |
+
".cpp": "cpp",
|
| 189 |
+
".c": "c"
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
for ext, lang in extensions.items():
|
| 193 |
+
if any(Path(".").rglob(f"*{ext}")):
|
| 194 |
+
if lang not in languages:
|
| 195 |
+
languages.append(lang)
|
| 196 |
+
|
| 197 |
+
return languages
|
| 198 |
+
|
| 199 |
+
def count_lines_by_language():
|
| 200 |
+
"""عدم الأسطر حسب اللغة"""
|
| 201 |
+
counts = {}
|
| 202 |
+
extensions = {
|
| 203 |
+
".py": "python",
|
| 204 |
+
".js": "javascript",
|
| 205 |
+
".ts": "typescript",
|
| 206 |
+
".go": "go",
|
| 207 |
+
".rs": "rust"
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
for ext, lang in extensions.items():
|
| 211 |
+
files = list(Path(".").rglob(f"*{ext}"))
|
| 212 |
+
total_lines = 0
|
| 213 |
+
for f in files:
|
| 214 |
+
try:
|
| 215 |
+
with open(f, 'r', encoding='utf-8', errors='ignore') as file:
|
| 216 |
+
total_lines += sum(1 for _ in file)
|
| 217 |
+
except:
|
| 218 |
+
pass
|
| 219 |
+
if total_lines > 0:
|
| 220 |
+
counts[lang] = total_lines
|
| 221 |
+
|
| 222 |
+
return counts
|
| 223 |
+
|
| 224 |
+
def main():
|
| 225 |
+
"""الدالة الرئيسية"""
|
| 226 |
+
print("=" * 50)
|
| 227 |
+
print("Auto-Guardian: تجميع نتائج الفحص")
|
| 228 |
+
print("=" * 50)
|
| 229 |
+
|
| 230 |
+
# استخراج معلومات Git
|
| 231 |
+
git_info = get_git_info()
|
| 232 |
+
print(f"Commit: {git_info['commit_sha']}")
|
| 233 |
+
print(f"Branch: {git_info['branch']}")
|
| 234 |
+
|
| 235 |
+
# اكتشاف اللغات
|
| 236 |
+
languages = detect_languages()
|
| 237 |
+
print(f"Languages detected: {', '.join(languages)}")
|
| 238 |
+
|
| 239 |
+
# تجميع جميع النتائج
|
| 240 |
+
all_findings = []
|
| 241 |
+
summary_by_tool = {}
|
| 242 |
+
findings_count = 0
|
| 243 |
+
|
| 244 |
+
# Bandit Results
|
| 245 |
+
print("\n[1/5] Processing Bandit results...")
|
| 246 |
+
bandit_results = load_json_file("bandit_results.json")
|
| 247 |
+
if isinstance(bandit_results, list):
|
| 248 |
+
for result in bandit_results:
|
| 249 |
+
if "results" in result:
|
| 250 |
+
for issue in result["results"]:
|
| 251 |
+
finding = normalize_bandit_result(issue)
|
| 252 |
+
all_findings.append(finding)
|
| 253 |
+
findings_count += 1
|
| 254 |
+
summary_by_tool["bandit"] = {"issues": findings_count, "status": "completed"}
|
| 255 |
+
else:
|
| 256 |
+
summary_by_tool["bandit"] = {"issues": 0, "status": "no_data"}
|
| 257 |
+
print(f" Found {findings_count} Bandit issues")
|
| 258 |
+
|
| 259 |
+
# Pylint Results
|
| 260 |
+
print("\n[2/5] Processing Pylint results...")
|
| 261 |
+
pylint_results = load_json_file("pylint_results.json")
|
| 262 |
+
pylint_count = 0
|
| 263 |
+
if isinstance(pylint_results, list):
|
| 264 |
+
for issue in pylint_results:
|
| 265 |
+
if isinstance(issue, dict):
|
| 266 |
+
finding = normalize_pylint_result(issue)
|
| 267 |
+
all_findings.append(finding)
|
| 268 |
+
pylint_count += 1
|
| 269 |
+
summary_by_tool["pylint"] = {"issues": pylint_count, "status": "completed"}
|
| 270 |
+
else:
|
| 271 |
+
summary_by_tool["pylint"] = {"issues": 0, "status": "no_data"}
|
| 272 |
+
print(f" Found {pylint_count} Pylint issues")
|
| 273 |
+
|
| 274 |
+
# ESLint Results
|
| 275 |
+
print("\n[3/5] Processing ESLint results...")
|
| 276 |
+
eslint_results = load_json_file("eslint_results.json")
|
| 277 |
+
eslint_count = 0
|
| 278 |
+
if isinstance(eslint_results, list):
|
| 279 |
+
for result in eslint_results:
|
| 280 |
+
if "messages" in result:
|
| 281 |
+
for issue in result["messages"]:
|
| 282 |
+
if isinstance(issue, dict):
|
| 283 |
+
finding = normalize_eslint_result(issue)
|
| 284 |
+
all_findings.append(finding)
|
| 285 |
+
eslint_count += 1
|
| 286 |
+
summary_by_tool["eslint"] = {"issues": eslint_count, "status": "completed"}
|
| 287 |
+
else:
|
| 288 |
+
summary_by_tool["eslint"] = {"issues": 0, "status": "no_data"}
|
| 289 |
+
print(f" Found {eslint_count} ESLint issues")
|
| 290 |
+
|
| 291 |
+
# Gosec Results
|
| 292 |
+
print("\n[4/5] Processing Gosec results...")
|
| 293 |
+
gosec_results = load_json_file("gosec_results.json")
|
| 294 |
+
gosec_count = 0
|
| 295 |
+
if isinstance(gosec_results, dict) and "Issues" in gosec_results:
|
| 296 |
+
for issue in gosec_results["Issues"]:
|
| 297 |
+
finding = normalize_gosec_result(issue)
|
| 298 |
+
all_findings.append(finding)
|
| 299 |
+
gosec_count += 1
|
| 300 |
+
summary_by_tool["gosec"] = {"issues": gosec_count, "status": "completed"}
|
| 301 |
+
else:
|
| 302 |
+
summary_by_tool["gosec"] = {"issues": 0, "status": "no_data"}
|
| 303 |
+
print(f" Found {gosec_count} Gosec issues")
|
| 304 |
+
|
| 305 |
+
# Cargo Audit Results
|
| 306 |
+
print("\n[5/5] Processing Cargo Audit results...")
|
| 307 |
+
cargo_results = load_json_file("cargo_audit_results.json")
|
| 308 |
+
cargo_count = 0
|
| 309 |
+
if isinstance(cargo_results, dict) and "vulnerabilities" in cargo_results:
|
| 310 |
+
for vuln in cargo_results["vulnerabilities"]:
|
| 311 |
+
finding = normalize_cargo_audit_result(vuln)
|
| 312 |
+
all_findings.append(finding)
|
| 313 |
+
cargo_count += 1
|
| 314 |
+
summary_by_tool["cargo-audit"] = {"issues": cargo_count, "status": "completed"}
|
| 315 |
+
else:
|
| 316 |
+
summary_by_tool["cargo-audit"] = {"issues": 0, "status": "no_data"}
|
| 317 |
+
print(f" Found {cargo_count} Cargo Audit issues")
|
| 318 |
+
|
| 319 |
+
# حساب الإحصائيات
|
| 320 |
+
severity_counts = {
|
| 321 |
+
"CRITICAL": 0,
|
| 322 |
+
"HIGH": 0,
|
| 323 |
+
"MEDIUM": 0,
|
| 324 |
+
"LOW": 0,
|
| 325 |
+
"INFO": 0
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
for finding in all_findings:
|
| 329 |
+
severity = finding.get("severity", "MEDIUM")
|
| 330 |
+
if severity in severity_counts:
|
| 331 |
+
severity_counts[severity] += 1
|
| 332 |
+
|
| 333 |
+
# حساب النتيجة
|
| 334 |
+
total_findings = len(all_findings)
|
| 335 |
+
critical_penalty = severity_counts["CRITICAL"] * 10
|
| 336 |
+
high_penalty = severity_counts["HIGH"] * 5
|
| 337 |
+
medium_penalty = severity_counts["MEDIUM"] * 2
|
| 338 |
+
base_score = 100
|
| 339 |
+
security_score = max(0, base_score - critical_penalty - high_penalty - medium_penalty)
|
| 340 |
+
|
| 341 |
+
# عدد الملفات الممسوحة ضوئياً
|
| 342 |
+
file_count = 0
|
| 343 |
+
files_set = set()
|
| 344 |
+
for finding in all_findings:
|
| 345 |
+
file_path = finding.get("file", "")
|
| 346 |
+
if file_path and file_path not in files_set:
|
| 347 |
+
files_set.add(file_path)
|
| 348 |
+
file_count = len(files_set)
|
| 349 |
+
|
| 350 |
+
# إنشاء التقرير النهائي
|
| 351 |
+
scan_results = {
|
| 352 |
+
"metadata": {
|
| 353 |
+
"timestamp": datetime.utcnow().isoformat() + "Z",
|
| 354 |
+
"version": "1.0.0",
|
| 355 |
+
"tool": "auto-guardian",
|
| 356 |
+
"git": git_info
|
| 357 |
+
},
|
| 358 |
+
"summary": {
|
| 359 |
+
"total_issues": total_findings,
|
| 360 |
+
"critical_issues": severity_counts["CRITICAL"],
|
| 361 |
+
"high_issues": severity_counts["HIGH"],
|
| 362 |
+
"medium_issues": severity_counts["MEDIUM"],
|
| 363 |
+
"low_issues": severity_counts["LOW"],
|
| 364 |
+
"info_issues": severity_counts["INFO"],
|
| 365 |
+
"files_scanned": file_count,
|
| 366 |
+
"security_score": security_score,
|
| 367 |
+
"grade": get_grade(security_score)
|
| 368 |
+
},
|
| 369 |
+
"languages": {
|
| 370 |
+
"detected": languages,
|
| 371 |
+
"lines_of_code": count_lines_by_language(),
|
| 372 |
+
"tools_used": summary_by_tool
|
| 373 |
+
},
|
| 374 |
+
"findings": sorted(all_findings, key=lambda x: x.get("severity_level", 99)),
|
| 375 |
+
"trends": {
|
| 376 |
+
"previous_scan": None,
|
| 377 |
+
"improvement": None
|
| 378 |
+
}
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
# حفظ النتائج
|
| 382 |
+
output_file = "scan_results.json"
|
| 383 |
+
with open(output_file, "w", encoding="utf-8") as f:
|
| 384 |
+
json.dump(scan_results, f, indent=2, ensure_ascii=False)
|
| 385 |
+
|
| 386 |
+
print("\n" + "=" * 50)
|
| 387 |
+
print("ملخص الفحص:")
|
| 388 |
+
print("=" * 50)
|
| 389 |
+
print(f" إجمالي المشاكل: {total_findings}")
|
| 390 |
+
print(f" مشاكل حرجة: {severity_counts['CRITICAL']}")
|
| 391 |
+
print(f" مشاكل عالية: {severity_counts['HIGH']}")
|
| 392 |
+
print(f" مشاكل متوسطة: {severity_counts['MEDIUM']}")
|
| 393 |
+
print(f" مشاكل منخفضة: {severity_counts['LOW']}")
|
| 394 |
+
print(f" الملفات الممسوحة: {file_count}")
|
| 395 |
+
print(f" نقاط الأمان: {security_score}/100 (الدرجة: {get_grade(security_score)})")
|
| 396 |
+
print("=" * 50)
|
| 397 |
+
print(f"✅ النتائج saved to: {output_file}")
|
| 398 |
+
print("=" * 50)
|
| 399 |
+
|
| 400 |
+
def get_grade(score):
|
| 401 |
+
"""الحصول على التقدير من النقاط"""
|
| 402 |
+
if score >= 90:
|
| 403 |
+
return "A"
|
| 404 |
+
elif score >= 80:
|
| 405 |
+
return "B"
|
| 406 |
+
elif score >= 70:
|
| 407 |
+
return "C"
|
| 408 |
+
elif score >= 60:
|
| 409 |
+
return "D"
|
| 410 |
+
else:
|
| 411 |
+
return "F"
|
| 412 |
+
|
| 413 |
+
if __name__ == "__main__":
|
| 414 |
+
main()
|
scripts/backup.sh
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# سكريبت النسخ الاحتياطي لنظام الحارس التلقائي
|
| 3 |
+
# Auto Guardian System Backup Script
|
| 4 |
+
# ======================================
|
| 5 |
+
|
| 6 |
+
# إعداداتColors
|
| 7 |
+
GREEN='\033[0;32m'
|
| 8 |
+
BLUE='\033[0;34m'
|
| 9 |
+
YELLOW='\033[1;33m'
|
| 10 |
+
RED='\033[0;31m'
|
| 11 |
+
NC='\033[0m'
|
| 12 |
+
|
| 13 |
+
# إعدادات النسخ الاحتياطي
|
| 14 |
+
BACKUP_DIR="backups"
|
| 15 |
+
BACKUP_PREFIX="auto-guardian"
|
| 16 |
+
RETENTION_DAYS=30
|
| 17 |
+
LOG_FILE="logs/backup.log"
|
| 18 |
+
|
| 19 |
+
# دوال مساعدة
|
| 20 |
+
print_info() {
|
| 21 |
+
echo -e "${BLUE}[INFO]${NC} $1"
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
print_success() {
|
| 25 |
+
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
print_warning() {
|
| 29 |
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
print_error() {
|
| 33 |
+
echo -e "${RED}[ERROR]${NC} $1"
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
log_message() {
|
| 37 |
+
local level=$1
|
| 38 |
+
local message=$2
|
| 39 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> "$LOG_FILE"
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
# إنشاء مجلد السجلات إن لم يوجد
|
| 43 |
+
mkdir -p "$(dirname "$LOG_FILE")"
|
| 44 |
+
|
| 45 |
+
print_header() {
|
| 46 |
+
echo ""
|
| 47 |
+
echo "=============================================="
|
| 48 |
+
echo " نظام الحارس التلقائي - النسخ الاحتياطي"
|
| 49 |
+
echo "=============================================="
|
| 50 |
+
echo ""
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
# دالة إنشاء نسخة احتياطية
|
| 54 |
+
create_backup() {
|
| 55 |
+
print_info "جاري إنشاء نسخة احتياطية..."
|
| 56 |
+
|
| 57 |
+
# إنشاء مجلد النسخ الاحتياطي إن لم يوجد
|
| 58 |
+
mkdir -p "$BACKUP_DIR"
|
| 59 |
+
|
| 60 |
+
# إنشاء اسم الملف مع التاريخ والوقت
|
| 61 |
+
local timestamp=$(date +%Y%m%d_%H%M%S)
|
| 62 |
+
local backup_filename="${BACKUP_PREFIX}_${timestamp}"
|
| 63 |
+
local backup_path="${BACKUP_DIR}/${backup_filename}"
|
| 64 |
+
local tar_filename="${backup_filename}.tar.gz"
|
| 65 |
+
|
| 66 |
+
log_message "INFO" "بدء إنشاء نسخة احتياطية: $tar_filename"
|
| 67 |
+
|
| 68 |
+
# إنشاء مجلد مؤقت للنسخة الاحتياطية
|
| 69 |
+
local temp_dir=$(mktemp -d)
|
| 70 |
+
trap "rm -rf $temp_dir" EXIT
|
| 71 |
+
|
| 72 |
+
print_info "جاري تجميع الملفات..."
|
| 73 |
+
|
| 74 |
+
# نسخ الإعدادات
|
| 75 |
+
print_info "نسخ الإعدادات..."
|
| 76 |
+
mkdir -p "$temp_dir/config"
|
| 77 |
+
cp config/settings.yaml "$temp_dir/config/" 2>/dev/null || true
|
| 78 |
+
cp config/rules.yaml "$temp_dir/config/" 2>/dev/null || true
|
| 79 |
+
cp config/alerts.yaml "$temp_dir/config/" 2>/dev/null || true
|
| 80 |
+
cp config/whitelist.yaml "$temp_dir/config/" 2>/dev/null || true
|
| 81 |
+
cp .env.example "$temp_dir/" 2>/dev/null || true
|
| 82 |
+
|
| 83 |
+
# نسخ السجلات (آخر 7 أيام)
|
| 84 |
+
print_info "نسخ السجلات..."
|
| 85 |
+
mkdir -p "$temp_dir/logs"
|
| 86 |
+
find logs/ -name "*.log" -mtime -7 -exec cp {} "$temp_dir/logs/" \; 2>/dev/null || true
|
| 87 |
+
|
| 88 |
+
# نسخ قاعدة البيانات إن وجدت
|
| 89 |
+
print_info "نسخ قاعدة البيانات..."
|
| 90 |
+
if [ -f "data/autoguardian.db" ]; then
|
| 91 |
+
mkdir -p "$temp_dir/data"
|
| 92 |
+
cp data/autoguardian.db "$temp_dir/data/"
|
| 93 |
+
fi
|
| 94 |
+
|
| 95 |
+
# نسخ قائمة العناوكات المحظورة
|
| 96 |
+
print_info "نسخ قائمة العناوكات المحظورة..."
|
| 97 |
+
if [ -f "data/blocked_ips.json" ]; then
|
| 98 |
+
mkdir -p "$temp_dir/data"
|
| 99 |
+
cp data/blocked_ips.json "$temp_dir/data/"
|
| 100 |
+
fi
|
| 101 |
+
|
| 102 |
+
# نسخ معلومات الإصدار
|
| 103 |
+
print_info "نسخ معلومات الإصدار..."
|
| 104 |
+
echo "{
|
| 105 |
+
\"backup_date\": \"$(date -Iseconds)\",
|
| 106 |
+
\"version\": \"$(git describe --tags 2>/dev/null || echo '1.3.0')\",
|
| 107 |
+
\"git_branch\": \"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')\",
|
| 108 |
+
\"git_commit\": \"$(git rev-parse HEAD 2>/dev/null || echo 'unknown')\"
|
| 109 |
+
}" > "$temp_dir/backup_info.json"
|
| 110 |
+
|
| 111 |
+
# ضغط الملفات
|
| 112 |
+
print_info "ضغط الملفات..."
|
| 113 |
+
tar -czf "$BACKUP_DIR/$tar_filename" -C "$temp_dir" .
|
| 114 |
+
|
| 115 |
+
# حذف المجلد المؤقت
|
| 116 |
+
rm -rf "$temp_dir"
|
| 117 |
+
|
| 118 |
+
# التحقق من نجاح الضغط
|
| 119 |
+
if [ -f "$BACKUP_DIR/$tar_filename" ]; then
|
| 120 |
+
local file_size=$(du -h "$BACKUP_DIR/$tar_filename" | cut -f1)
|
| 121 |
+
print_success "تم إنشاء النسخة الاحتياطية: $tar_filename ($file_size)"
|
| 122 |
+
log_message "INFO" "اكتمل النسخ الاحتياطي بنجاح: $tar_filename ($file_size)"
|
| 123 |
+
|
| 124 |
+
# إنشاء ملف فهرس
|
| 125 |
+
echo "$tar_filename $(date -Iseconds) $(git describe --tags 2>/dev/null || echo 'unknown')" >> "$BACKUP_DIR/backup_index.txt"
|
| 126 |
+
|
| 127 |
+
return 0
|
| 128 |
+
else
|
| 129 |
+
print_error "فشل في إنشاء النسخة الاحتياطية"
|
| 130 |
+
log_message "ERROR" "فشل في إنشاء النسخة الاحتياطية"
|
| 131 |
+
return 1
|
| 132 |
+
fi
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
# دالة حذف النسخ القديمة
|
| 136 |
+
cleanup_old_backups() {
|
| 137 |
+
print_info "جاري حذف النسخ الاحتياطية القديمة (أقدم من $RETENTION_DAYS يوماً)..."
|
| 138 |
+
|
| 139 |
+
local deleted_count=0
|
| 140 |
+
local deleted_size=0
|
| 141 |
+
|
| 142 |
+
# البحث عن الملفات القديمة
|
| 143 |
+
while IFS= read -r -d '' file; do
|
| 144 |
+
local file_size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null || echo 0)
|
| 145 |
+
deleted_size=$((deleted_size + file_size))
|
| 146 |
+
rm -f "$file"
|
| 147 |
+
((deleted_count++))
|
| 148 |
+
print_info "حُذف: $(basename "$file")"
|
| 149 |
+
done < <(find "$BACKUP_DIR" -name "${BACKUP_PREFIX}_*.tar.gz" -mtime +$RETENTION_DAYS -print0)
|
| 150 |
+
|
| 151 |
+
if [ $deleted_count -gt 0 ]; then
|
| 152 |
+
print_success "حُذفت $deleted_count نسخة احتياطية (حوالي $(echo "scale=2; $deleted_size/1048576" | bc) MB)"
|
| 153 |
+
log_message "INFO" "حُذفت $deleted_count نسخة احتياطية"
|
| 154 |
+
else
|
| 155 |
+
print_info "لا توجد نسخ احتياطية قديمة للحذف"
|
| 156 |
+
fi
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
# دالة عرض النسخ الاحتياطية المتاحة
|
| 160 |
+
list_backups() {
|
| 161 |
+
echo ""
|
| 162 |
+
echo "النسخ الاحتياطية المتاحة:"
|
| 163 |
+
echo "----------------------------"
|
| 164 |
+
|
| 165 |
+
if [ ! -d "$BACKUP_DIR" ] || [ -z "$(ls -A "$BACKUP_DIR" 2>/dev/null)" ]; then
|
| 166 |
+
print_warning "لا توجد نسخ احتياطية"
|
| 167 |
+
return 1
|
| 168 |
+
fi
|
| 169 |
+
|
| 170 |
+
local total_size=0
|
| 171 |
+
local count=0
|
| 172 |
+
|
| 173 |
+
while IFS= read -r -d '' file; do
|
| 174 |
+
local filename=$(basename "$file")
|
| 175 |
+
local filesize=$(du -h "$file" | cut -f1)
|
| 176 |
+
local filedate=$(stat -c %y "$file" 2>/dev/null | cut -d' ' -f1,2 | cut -d'.' -f1 || stat -f "%Sm" -t "%Y-%m-%d %H:%M:%S" "$file" 2>/dev/null)
|
| 177 |
+
|
| 178 |
+
echo " $filename"
|
| 179 |
+
echo " الحجم: $filesize | التاريخ: $filedate"
|
| 180 |
+
echo ""
|
| 181 |
+
|
| 182 |
+
total_size=$((total_size + $(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null || echo 0)))
|
| 183 |
+
((count++))
|
| 184 |
+
done < <(find "$BACKUP_DIR" -name "${BACKUP_PREFIX}_*.tar.gz" -print0 | sort -rz)
|
| 185 |
+
|
| 186 |
+
echo "----------------------------"
|
| 187 |
+
echo "إجمالي النسخ: $count"
|
| 188 |
+
echo "الحجم الإجمالي: $(echo "scale=2; $total_size/1048576" | bc) MB"
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
# دالة استعادة نسخة احتياطية
|
| 192 |
+
restore_backup() {
|
| 193 |
+
local backup_file=$1
|
| 194 |
+
|
| 195 |
+
if [ -z "$backup_file" ]; then
|
| 196 |
+
print_error "يرجى تحديد ملف النسخ الاحتياطية"
|
| 197 |
+
echo "الاستخدام: $0 restore <backup_file>"
|
| 198 |
+
return 1
|
| 199 |
+
fi
|
| 200 |
+
|
| 201 |
+
# التحقق من وجود الملف
|
| 202 |
+
if [ ! -f "$backup_file" ]; then
|
| 203 |
+
# البحث في مجلد النسخ الاحتياطية
|
| 204 |
+
if [ -f "$BACKUP_DIR/$backup_file" ]; then
|
| 205 |
+
backup_file="$BACKUP_DIR/$backup_file"
|
| 206 |
+
else
|
| 207 |
+
# البحث عن ملف يبدأ بالاسم
|
| 208 |
+
backup_file=$(find "$BACKUP_DIR" -name "${backup_file}*.tar.gz" -o -name "*${backup_file}*.tar.gz" 2>/dev/null | head -1)
|
| 209 |
+
if [ -z "$backup_file" ]; then
|
| 210 |
+
print_error "الملف غير موجود: $backup_file"
|
| 211 |
+
return 1
|
| 212 |
+
fi
|
| 213 |
+
fi
|
| 214 |
+
fi
|
| 215 |
+
|
| 216 |
+
print_warning "سيتم استعادة النسخة الاحتياطية: $(basename "$backup_file")"
|
| 217 |
+
print_warning "سيتم الكتابة فوق الإعدادات الحالية!"
|
| 218 |
+
|
| 219 |
+
read -p "هل تريد المتابعة؟ (y/N): " confirm
|
| 220 |
+
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
| 221 |
+
print_info "تم الإلغاء"
|
| 222 |
+
return 0
|
| 223 |
+
fi
|
| 224 |
+
|
| 225 |
+
print_info "جاري استعادة النسخة الاحتياطية..."
|
| 226 |
+
|
| 227 |
+
# إنشاء مجلد مؤقت
|
| 228 |
+
local temp_dir=$(mktemp -d)
|
| 229 |
+
trap "rm -rf $temp_dir" EXIT
|
| 230 |
+
|
| 231 |
+
# استخراج الملفات
|
| 232 |
+
tar -xzf "$backup_file" -C "$temp_dir"
|
| 233 |
+
|
| 234 |
+
# التحقق من وجود ملف المعلومات
|
| 235 |
+
if [ -f "$temp_dir/backup_info.json" ]; then
|
| 236 |
+
print_info "معلومات النسخة الاحتياطية:"
|
| 237 |
+
cat "$temp_dir/backup_info.json"
|
| 238 |
+
echo ""
|
| 239 |
+
fi
|
| 240 |
+
|
| 241 |
+
# استعادة الإعدادات
|
| 242 |
+
if [ -f "$temp_dir/config/settings.yaml" ]; then
|
| 243 |
+
cp "$temp_dir/config/settings.yaml" config/settings.yaml
|
| 244 |
+
print_success "استُعيدت الإعدادات"
|
| 245 |
+
fi
|
| 246 |
+
|
| 247 |
+
# استعادة السجلات
|
| 248 |
+
if [ -d "$temp_dir/logs" ]; then
|
| 249 |
+
cp -r "$temp_dir/logs/"* logs/ 2>/dev/null || true
|
| 250 |
+
print_success "استُعيدت السجلات"
|
| 251 |
+
fi
|
| 252 |
+
|
| 253 |
+
# استعادة قاعدة البيانات
|
| 254 |
+
if [ -f "$temp_dir/data/autoguardian.db" ]; then
|
| 255 |
+
mkdir -p data
|
| 256 |
+
cp "$temp_dir/data/autoguardian.db" data/
|
| 257 |
+
print_success "استُعيدت قاعدة البيانات"
|
| 258 |
+
fi
|
| 259 |
+
|
| 260 |
+
# استعادة قائمة العناوكات المحظورة
|
| 261 |
+
if [ -f "$temp_dir/data/blocked_ips.json" ]; then
|
| 262 |
+
mkdir -p data
|
| 263 |
+
cp "$temp_dir/data/blocked_ips.json" data/
|
| 264 |
+
print_success "استُعيدت قائمة العناوكات المحظورة"
|
| 265 |
+
fi
|
| 266 |
+
|
| 267 |
+
print_success "اكتمل استعادة النسخة الاحتياطية"
|
| 268 |
+
log_message "INFO" "استُعيدت النسخة الاحتياطية: $(basename "$backup_file")"
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
# دالة إنشاء نسخة احتياطية للسجلات ��قط
|
| 272 |
+
backup_logs_only() {
|
| 273 |
+
print_info "جاري إنشاء نسخة احتياطية للسجلات فقط..."
|
| 274 |
+
|
| 275 |
+
local timestamp=$(date +%Y%m%d_%H%M%S)
|
| 276 |
+
local backup_filename="${BACKUP_PREFIX}_logs_${timestamp}.tar.gz"
|
| 277 |
+
|
| 278 |
+
if [ -d "logs" ] && [ "$(ls -A logs 2>/dev/null)" ]; then
|
| 279 |
+
tar -czf "$BACKUP_DIR/$backup_filename" logs/
|
| 280 |
+
print_success "تم إنشاء: $backup_filename"
|
| 281 |
+
else
|
| 282 |
+
print_warning "لا توجد سجلات للنسخ الاحتياطي"
|
| 283 |
+
fi
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
# دالة عرض المساعدة
|
| 287 |
+
show_help() {
|
| 288 |
+
echo ""
|
| 289 |
+
echo "استخدام: $0 [الأمر]"
|
| 290 |
+
echo ""
|
| 291 |
+
echo "الأوامر المتاحة:"
|
| 292 |
+
echo ""
|
| 293 |
+
echo " backup - إنشاء نسخة احتياطية كاملة"
|
| 294 |
+
echo " backup-logs - إنشاء نسخة احتياطية للسجلات فقط"
|
| 295 |
+
echo " list - قائمة النسخ الاحتياطية المتاحة"
|
| 296 |
+
echo " restore <file> - استعادة نسخة احتياطية"
|
| 297 |
+
echo " cleanup - حذف النسخ القديمة"
|
| 298 |
+
echo " help - عرض هذه المساعدة"
|
| 299 |
+
echo ""
|
| 300 |
+
echo "أمثلة:"
|
| 301 |
+
echo " $0 backup"
|
| 302 |
+
echo " $0 list"
|
| 303 |
+
echo " $0 restore auto-guardian_20241013_120000.tar.gz"
|
| 304 |
+
echo " $0 cleanup"
|
| 305 |
+
echo ""
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
# ========================================
|
| 309 |
+
# البرنامج الرئيسي
|
| 310 |
+
# ========================================
|
| 311 |
+
|
| 312 |
+
print_header
|
| 313 |
+
|
| 314 |
+
# التحقق من الوسائط
|
| 315 |
+
case "${1:-backup}" in
|
| 316 |
+
backup)
|
| 317 |
+
create_backup
|
| 318 |
+
cleanup_old_backups
|
| 319 |
+
;;
|
| 320 |
+
backup-logs)
|
| 321 |
+
backup_logs_only
|
| 322 |
+
;;
|
| 323 |
+
list)
|
| 324 |
+
list_backups
|
| 325 |
+
;;
|
| 326 |
+
restore)
|
| 327 |
+
restore_backup "${2:-}"
|
| 328 |
+
;;
|
| 329 |
+
cleanup)
|
| 330 |
+
cleanup_old_backups
|
| 331 |
+
;;
|
| 332 |
+
help|--help|-h)
|
| 333 |
+
show_help
|
| 334 |
+
;;
|
| 335 |
+
*)
|
| 336 |
+
print_error "أمر غير معروف: $1"
|
| 337 |
+
show_help
|
| 338 |
+
exit 1
|
| 339 |
+
;;
|
| 340 |
+
esac
|
| 341 |
+
|
| 342 |
+
echo ""
|
| 343 |
+
print_success "اكتمل العمل بنجاح!"
|
| 344 |
+
echo ""
|
scripts/generate_report.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# سكريبت إنشاء تقارير الأمان
|
| 3 |
+
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
from datetime import datetime
|
| 7 |
+
|
| 8 |
+
def load_json_file(filepath):
|
| 9 |
+
"""تحميل ملف JSON"""
|
| 10 |
+
if os.path.exists(filepath):
|
| 11 |
+
with open(filepath, 'r', encoding='utf-8') as f:
|
| 12 |
+
return json.load(f)
|
| 13 |
+
return None
|
| 14 |
+
|
| 15 |
+
def generate_markdown_report(data):
|
| 16 |
+
"""إنشاء تقرير Markdown"""
|
| 17 |
+
if not data:
|
| 18 |
+
return None
|
| 19 |
+
|
| 20 |
+
summary = data.get('summary', {})
|
| 21 |
+
findings = data.get('findings', [])
|
| 22 |
+
metadata = data.get('metadata', {})
|
| 23 |
+
|
| 24 |
+
# تصنيف المشاكل حسب الشدة
|
| 25 |
+
critical = [f for f in findings if f.get('severity') == 'CRITICAL']
|
| 26 |
+
high = [f for f in findings if f.get('severity') == 'HIGH']
|
| 27 |
+
medium = [f for f in findings if f.get('severity') == 'MEDIUM']
|
| 28 |
+
low = [f for f in findings if f.get('severity') == 'LOW']
|
| 29 |
+
|
| 30 |
+
report = f"""# تقرير الأمان - Auto-Guardian
|
| 31 |
+
|
| 32 |
+
## معلومات التقرير
|
| 33 |
+
|
| 34 |
+
- **تاريخ الفحص:** {metadata.get('timestamp', 'غير متوفر')}
|
| 35 |
+
- **الالتزام:** {metadata.get('git', {}).get('commit_sha', 'غير متوفر')}
|
| 36 |
+
- **الفرع:** {metadata.get('git', {}).get('branch', 'غير متوفر')}
|
| 37 |
+
- **إصدار الأداة:** {metadata.get('version', '1.0.0')}
|
| 38 |
+
|
| 39 |
+
---
|
| 40 |
+
|
| 41 |
+
## ملخص النتائج
|
| 42 |
+
|
| 43 |
+
| المقياس | القيمة |
|
| 44 |
+
|---------|--------|
|
| 45 |
+
| **نتيجة الأمان** | {summary.get('security_score', 0)}/100 |
|
| 46 |
+
| **التقدير** | {summary.get('grade', '-')} |
|
| 47 |
+
| **إجمالي المشاكل** | {summary.get('total_issues', 0)} |
|
| 48 |
+
| **ملفات مفحوصة** | {summary.get('files_scanned', 0)} |
|
| 49 |
+
| **مشاكل حرجة** | {len(critical)} |
|
| 50 |
+
| **مشاكل عالية** | {len(high)} |
|
| 51 |
+
| **مشاكل متوسطة** | {len(medium)} |
|
| 52 |
+
| **مشاكل منخفضة** | {len(low)} |
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## المشاكل الحرجة ({len(critical)})
|
| 57 |
+
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
if critical:
|
| 61 |
+
for i, finding in enumerate(critical, 1):
|
| 62 |
+
report += f"""### {i}. {finding.get('rule_name', finding.get('rule_id', 'غير معروف'))}
|
| 63 |
+
|
| 64 |
+
- **الملف:** `{finding.get('file', 'غير معروف')}:{finding.get('line', 0)}`
|
| 65 |
+
- **الأداة:** {finding.get('tool_name', finding.get('tool', 'غير معروف'))}
|
| 66 |
+
- **الوصف:** {finding.get('message', finding.get('description', 'غير متوفر'))}
|
| 67 |
+
- **مستوى الثقة:** {finding.get('confidence', 'غير معروف')}
|
| 68 |
+
- **اللغة:** {finding.get('language', 'غير معروفة')}
|
| 69 |
+
|
| 70 |
+
"""
|
| 71 |
+
else:
|
| 72 |
+
report += "لا توجد مشاكل حرجة! ممتاز! 🎉\n\n"
|
| 73 |
+
|
| 74 |
+
report += f"""---
|
| 75 |
+
|
| 76 |
+
## المشاكل العالية ({len(high)})
|
| 77 |
+
|
| 78 |
+
"""
|
| 79 |
+
|
| 80 |
+
if high:
|
| 81 |
+
for i, finding in enumerate(high, 1):
|
| 82 |
+
report += f"""### {i}. {finding.get('rule_name', finding.get('rule_id', 'غير معروف'))}
|
| 83 |
+
|
| 84 |
+
- **الملف:** `{finding.get('file', 'غير معروف')}:{finding.get('line', 0)}`
|
| 85 |
+
- **الأداة:** {finding.get('tool_name', finding.get('tool', 'غير معروف'))}
|
| 86 |
+
- **الوصف:** {finding.get('message', finding.get('description', 'غير متوفر'))}
|
| 87 |
+
|
| 88 |
+
"""
|
| 89 |
+
else:
|
| 90 |
+
report += "لا توجد مشاكل عالية! 🎉\n\n"
|
| 91 |
+
|
| 92 |
+
report += f"""---
|
| 93 |
+
|
| 94 |
+
## التوصيات
|
| 95 |
+
|
| 96 |
+
"""
|
| 97 |
+
|
| 98 |
+
# إضافة توصيات بناءً على النتائج
|
| 99 |
+
if len(critical) > 0:
|
| 100 |
+
report += "1. **أولوية قصوى:** معالجة المشاكل الحرجة المكتشفة فوراً.\n"
|
| 101 |
+
if len(high) > 0:
|
| 102 |
+
report += "2. **أولوية عالية:** حل المشاكل العالية في أقرب وقت ممكن.\n"
|
| 103 |
+
if len(medium) > 0:
|
| 104 |
+
report += "3. **أولوية متوسطة:** جدولة حل المشاكل المتوسطة في الدورة القادمة.\n"
|
| 105 |
+
if len(low) > 0:
|
| 106 |
+
report += "4. **أولوية منخفضة:** يمكن معالجة المشاكل منخفضة عند توفر الوقت.\n"
|
| 107 |
+
|
| 108 |
+
report += """
|
| 109 |
+
---
|
| 110 |
+
|
| 111 |
+
## اللغات المفحوصة
|
| 112 |
+
|
| 113 |
+
"""
|
| 114 |
+
|
| 115 |
+
languages = data.get('languages', {})
|
| 116 |
+
for lang in languages.get('detected', []):
|
| 117 |
+
lines = languages.get('lines_of_code', {}).get(lang, 0)
|
| 118 |
+
tools = languages.get('tools_used', {}).get(lang, {})
|
| 119 |
+
report += f"- **{lang}:** {lines:,} سطر من الكود (فحص بـ {tools.get('issues', 0)} مشاكل)\n"
|
| 120 |
+
|
| 121 |
+
report += f"""
|
| 122 |
+
|
| 123 |
+
---
|
| 124 |
+
|
| 125 |
+
## أدوات الفحص المستخدمة
|
| 126 |
+
|
| 127 |
+
"""
|
| 128 |
+
|
| 129 |
+
tools_used = languages.get('tools_used', {})
|
| 130 |
+
for tool, info in tools_used.items():
|
| 131 |
+
report += f"- **{tool}:** {info.get('issues', 0)} مشاكل مكتشفة (الحالة: {info.get('status', 'غير معروف')})\n"
|
| 132 |
+
|
| 133 |
+
report += f"""
|
| 134 |
+
|
| 135 |
+
---
|
| 136 |
+
|
| 137 |
+
*تم إنشاء هذا التقرير تلقائياً بواسطة Auto-Guardian في {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
|
| 138 |
+
|
| 139 |
+
"""
|
| 140 |
+
|
| 141 |
+
return report
|
| 142 |
+
|
| 143 |
+
def main():
|
| 144 |
+
"""الدالة الرئيسية"""
|
| 145 |
+
print("=" * 50)
|
| 146 |
+
print("Auto-Guardian: إنشاء تقرير الأمان")
|
| 147 |
+
print("=" * 50)
|
| 148 |
+
|
| 149 |
+
# تحميل بيانات الفحص
|
| 150 |
+
data = load_json_file('scan_results.json')
|
| 151 |
+
|
| 152 |
+
if not data:
|
| 153 |
+
print("❌ لم يتم العثور على بيانات الفحص!")
|
| 154 |
+
print(" يرجى تشغيل aggregate_results.py أولاً")
|
| 155 |
+
return
|
| 156 |
+
|
| 157 |
+
# إنشاء التقرير
|
| 158 |
+
report = generate_markdown_report(data)
|
| 159 |
+
|
| 160 |
+
if report:
|
| 161 |
+
# حفظ التقرير
|
| 162 |
+
output_file = 'reports/security_report.md'
|
| 163 |
+
os.makedirs('reports', exist_ok=True)
|
| 164 |
+
|
| 165 |
+
with open(output_file, 'w', encoding='utf-8') as f:
|
| 166 |
+
f.write(report)
|
| 167 |
+
|
| 168 |
+
print(f"✅ تم إنشاء التقرير بنجاح!")
|
| 169 |
+
print(f" الملف: {output_file}")
|
| 170 |
+
print("=" * 50)
|
| 171 |
+
else:
|
| 172 |
+
print("❌ فشل في إنشاء التقرير")
|
| 173 |
+
|
| 174 |
+
if __name__ == "__main__":
|
| 175 |
+
main()
|
scripts/maintenance.sh
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# سكريبت صيانة نظام الحارس التلقائي
|
| 3 |
+
# Auto Guardian System Maintenance Script
|
| 4 |
+
# =========================================
|
| 5 |
+
|
| 6 |
+
# إعداداتColors
|
| 7 |
+
GREEN='\033[0;32m'
|
| 8 |
+
BLUE='\033[0;34m'
|
| 9 |
+
YELLOW='\033[1;33m'
|
| 10 |
+
RED='\033[0;31m'
|
| 11 |
+
CYAN='\033[0;36m'
|
| 12 |
+
NC='\033[0m'
|
| 13 |
+
|
| 14 |
+
# إعدادات
|
| 15 |
+
LOG_FILE="logs/maintenance.log"
|
| 16 |
+
DATA_DIR="data"
|
| 17 |
+
LOGS_DIR="logs"
|
| 18 |
+
|
| 19 |
+
# دوال مساعدة
|
| 20 |
+
print_info() {
|
| 21 |
+
echo -e "${BLUE}[INFO]${NC} $1"
|
| 22 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $1" >> "$LOG_FILE"
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
print_success() {
|
| 26 |
+
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
| 27 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $1" >> "$LOG_FILE"
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
print_warning() {
|
| 31 |
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
| 32 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] $1" >> "$LOG_FILE"
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
print_error() {
|
| 36 |
+
echo -e "${RED}[ERROR]${NC} $1"
|
| 37 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $1" >> "$LOG_FILE"
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
print_header() {
|
| 41 |
+
echo ""
|
| 42 |
+
echo "=============================================="
|
| 43 |
+
echo " نظام الحارس التلقائي - الصيانة"
|
| 44 |
+
echo "=============================================="
|
| 45 |
+
echo ""
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
# إنشاء مجلد السجلات إن لم يوجد
|
| 49 |
+
mkdir -p "$(dirname "$LOG_FILE")" "$DATA_DIR" "$LOGS_DIR"
|
| 50 |
+
|
| 51 |
+
# دالة تنظيف ملفات Python المؤقتة
|
| 52 |
+
clean_pycache() {
|
| 53 |
+
print_info "جاري تنظيف ملفات Python المؤقتة..."
|
| 54 |
+
|
| 55 |
+
local count=0
|
| 56 |
+
|
| 57 |
+
# حذف مجلدات __pycache__
|
| 58 |
+
while IFS= read -r -d '' dir; do
|
| 59 |
+
rm -rf "$dir"
|
| 60 |
+
print_info "حُذف: $dir"
|
| 61 |
+
((count++))
|
| 62 |
+
done < <(find . -type d -name "__pycache__" -print0 2>/dev/null)
|
| 63 |
+
|
| 64 |
+
# حذف ملفات .pyc
|
| 65 |
+
while IFS= read -r -d '' file; do
|
| 66 |
+
rm -f "$file"
|
| 67 |
+
((count++))
|
| 68 |
+
done < <(find . -name "*.pyc" -print0 2>/dev/null)
|
| 69 |
+
|
| 70 |
+
# حذف ملفات .pyo
|
| 71 |
+
while IFS= read -r -d '' file; do
|
| 72 |
+
rm -f "$file"
|
| 73 |
+
((count++))
|
| 74 |
+
done < <(find . -name "*.pyo" -print0 2>/dev/null)
|
| 75 |
+
|
| 76 |
+
# حذف مجلدات .pytest_cache
|
| 77 |
+
rm -rf .pytest_cache/ 2>/dev/null
|
| 78 |
+
((count++))
|
| 79 |
+
|
| 80 |
+
# حذف مجلدات .hypothesis
|
| 81 |
+
rm -rf .hypothesis/ 2>/dev/null
|
| 82 |
+
((count++))
|
| 83 |
+
|
| 84 |
+
print_success "تم تنظيف $count عنصر"
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
# دالة تنظيف السجلات القديمة
|
| 88 |
+
clean_logs() {
|
| 89 |
+
print_info "جاري تنظيف السجلات القديمة (أقدم من 14 يوماً)..."
|
| 90 |
+
|
| 91 |
+
local count=0
|
| 92 |
+
local size_freed=0
|
| 93 |
+
|
| 94 |
+
# البحث عن ملفات السجلات القديمة
|
| 95 |
+
while IFS= read -r -d '' file; do
|
| 96 |
+
local file_size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null || echo 0)
|
| 97 |
+
size_freed=$((size_freed + file_size))
|
| 98 |
+
rm -f "$file"
|
| 99 |
+
print_info "حُذف: $(basename "$file")"
|
| 100 |
+
((count++))
|
| 101 |
+
done < <(find "$LOGS_DIR" -name "*.log" -mtime +14 -print0 2>/dev/null)
|
| 102 |
+
|
| 103 |
+
if [ $count -gt 0 ]; then
|
| 104 |
+
print_success "حُذفت $count ملف سجل ($(echo "scale=2; $size_freed/1048576" | bc) MB)"
|
| 105 |
+
else
|
| 106 |
+
print_info "لا توجد ملفات سجل قديمة للحذف"
|
| 107 |
+
fi
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
# دالة تنظيف ملفات الاختبار
|
| 111 |
+
clean_tests() {
|
| 112 |
+
print_info "جاري تنظيف ملفات الاختبار..."
|
| 113 |
+
|
| 114 |
+
# حذف تقارير التغطية القديمة
|
| 115 |
+
rm -rf htmlcov/ .coverage .coverage.* 2>/dev/null
|
| 116 |
+
local count=1
|
| 117 |
+
|
| 118 |
+
# حذف تقارير pytest
|
| 119 |
+
rm -rf pytest-results/ 2>/dev/null || true
|
| 120 |
+
|
| 121 |
+
print_success "تم تنظيف ملفات الاختبار"
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
# دالة تنظيف ملفات البناء
|
| 125 |
+
clean_build() {
|
| 126 |
+
print_info "جاري تنظيف ملفات البناء..."
|
| 127 |
+
|
| 128 |
+
# مجلدات البناء
|
| 129 |
+
rm -rf build/ dist/ *.egg-info/ 2>/dev/null
|
| 130 |
+
local count=3
|
| 131 |
+
|
| 132 |
+
# ملفات .egg
|
| 133 |
+
rm -rf *.egg 2>/dev/null
|
| 134 |
+
|
| 135 |
+
# ملفات Wheel
|
| 136 |
+
rm -rf *.whl 2>/dev/null
|
| 137 |
+
|
| 138 |
+
print_success "تم تنظيف ملفات البناء"
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
# دالة تنظيف ملفات التخزين المؤقت
|
| 142 |
+
clean_cache() {
|
| 143 |
+
print_info "جاري تنظيف ملفات التخزين المؤقت..."
|
| 144 |
+
|
| 145 |
+
# حذف ذاكرة التخزين المؤقت لـ pip
|
| 146 |
+
pip cache purge 2>/dev/null || true
|
| 147 |
+
|
| 148 |
+
# حذف مجلدات ذاكرة التخزين المؤقت
|
| 149 |
+
rm -rf ~/.cache/pip 2>/dev/null || true
|
| 150 |
+
|
| 151 |
+
# حذف ذاكرة التخزين المؤقت لـ mypy
|
| 152 |
+
rm -rf .mypy_cache/ 2>/dev/null || true
|
| 153 |
+
|
| 154 |
+
# حذف ذاكرة التخزين المؤقت لـ ruff
|
| 155 |
+
rm -rf .ruff_cache/ 2>/dev/null || true
|
| 156 |
+
|
| 157 |
+
print_success "تم تنظيف ملفات التخزين المؤقت"
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
# دالة التحقق من مساحة القرص
|
| 161 |
+
check_disk_space() {
|
| 162 |
+
print_info "جاري التحقق من مساحة القرص..."
|
| 163 |
+
|
| 164 |
+
local disk_usage=$(df -h . | tail -1 | awk '{print $5}' | sed 's/%//')
|
| 165 |
+
local disk_available=$(df -h . | tail -1 | awk '{print $4}')
|
| 166 |
+
|
| 167 |
+
echo ""
|
| 168 |
+
echo "معلومات مساحة القرص:"
|
| 169 |
+
echo "--------------------"
|
| 170 |
+
df -h . | tail -1
|
| 171 |
+
echo ""
|
| 172 |
+
|
| 173 |
+
if [ "$disk_usage" -gt 80 ]; then
|
| 174 |
+
print_warning "تحذير: استخدام القرص مرتفع ($disk_usage%)"
|
| 175 |
+
print_info "المساحة المتاحة: $disk_available"
|
| 176 |
+
else
|
| 177 |
+
print_success "مساحة القرص كافية (사용량: $disk_usage%)"
|
| 178 |
+
fi
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
# دالة التحقق من حالة Git
|
| 182 |
+
check_git_status() {
|
| 183 |
+
print_info "جاري التحقق من حالة Git..."
|
| 184 |
+
|
| 185 |
+
# التحقق من وجود Git
|
| 186 |
+
if ! command -v git &> /dev/null; then
|
| 187 |
+
print_warning "Git غير مثبت"
|
| 188 |
+
return
|
| 189 |
+
fi
|
| 190 |
+
|
| 191 |
+
# التحقق من حالة المستودع
|
| 192 |
+
cd "$(dirname "$0")/.." 2>/dev/null
|
| 193 |
+
|
| 194 |
+
if [ -d ".git" ]; then
|
| 195 |
+
# الفروع المحلية
|
| 196 |
+
echo ""
|
| 197 |
+
echo "الفروع المحلية:"
|
| 198 |
+
git branch --color=never 2>/dev/null | head -5
|
| 199 |
+
|
| 200 |
+
# حالة المستودع
|
| 201 |
+
local status=$(git status --short 2>/dev/null | wc -l)
|
| 202 |
+
if [ "$status" -gt 0 ]; then
|
| 203 |
+
print_warning "توجد تغييرات غير ملتزم بها ($status ملف)"
|
| 204 |
+
else
|
| 205 |
+
print_success "المستودع نظيف"
|
| 206 |
+
fi
|
| 207 |
+
|
| 208 |
+
# التحقق من التحديثات
|
| 209 |
+
git fetch origin 2>/dev/null
|
| 210 |
+
|
| 211 |
+
local behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo 0)
|
| 212 |
+
if [ "$behind" -gt 0 ]; then
|
| 213 |
+
print_info "يوجد تحديث متاح ($behind commits behind)"
|
| 214 |
+
else
|
| 215 |
+
print_success "المستودع محدث"
|
| 216 |
+
fi
|
| 217 |
+
else
|
| 218 |
+
print_info "المستودع ليس Git"
|
| 219 |
+
fi
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
# دالة التحقق من التبعيات
|
| 223 |
+
check_dependencies() {
|
| 224 |
+
print_info "جاري التحقق من التبعيات..."
|
| 225 |
+
|
| 226 |
+
# التحقق من Python
|
| 227 |
+
if command -v python3 &> /dev/null; then
|
| 228 |
+
print_success "Python مثبت: $(python3 --version)"
|
| 229 |
+
else
|
| 230 |
+
print_error "Python غير مثبت!"
|
| 231 |
+
fi
|
| 232 |
+
|
| 233 |
+
# التحقق من الحزم المهمة
|
| 234 |
+
echo ""
|
| 235 |
+
echo "حالة الحزم:"
|
| 236 |
+
echo "----------"
|
| 237 |
+
|
| 238 |
+
for pkg in requests pyyaml pytest; do
|
| 239 |
+
if python3 -c "import $pkg" 2>/dev/null; then
|
| 240 |
+
print_success "$pkg ✓"
|
| 241 |
+
else
|
| 242 |
+
print_warning "$pkg ✗ (غير مثبت)"
|
| 243 |
+
fi
|
| 244 |
+
done
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
# دالة إنشاء تقارير الحالة
|
| 248 |
+
generate_status_report() {
|
| 249 |
+
print_info "جاري إنشاء تقرير الحالة..."
|
| 250 |
+
|
| 251 |
+
local report_file="logs/status_report_$(date +%Y%m%d_%H%M%S).txt"
|
| 252 |
+
|
| 253 |
+
{
|
| 254 |
+
echo "============================================="
|
| 255 |
+
echo " تقرير حالة نظام الحارس التلقائي"
|
| 256 |
+
echo "============================================="
|
| 257 |
+
echo ""
|
| 258 |
+
echo "التاريخ: $(date)"
|
| 259 |
+
echo ""
|
| 260 |
+
echo "بيئة التشغيل:"
|
| 261 |
+
echo "------------"
|
| 262 |
+
echo "Python: $(python3 --version 2>&1)"
|
| 263 |
+
echo "النظام: $(uname -a)"
|
| 264 |
+
echo ""
|
| 265 |
+
echo "مساحة القرص:"
|
| 266 |
+
echo "-----------"
|
| 267 |
+
df -h . | tail -1
|
| 268 |
+
echo ""
|
| 269 |
+
echo "حالة Git:"
|
| 270 |
+
echo "--------"
|
| 271 |
+
git status --short 2>/dev/null || echo "غير متاح"
|
| 272 |
+
echo ""
|
| 273 |
+
echo "============================================="
|
| 274 |
+
} > "$report_file"
|
| 275 |
+
|
| 276 |
+
print_success "تم إنشاء التقرير: $report_file"
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
# دالة إصلاح الأذونات
|
| 280 |
+
fix_permissions() {
|
| 281 |
+
print_info "جاري إصلاح أذونات الملفات..."
|
| 282 |
+
|
| 283 |
+
# تصحيح أذونات الملفات التنفيذية
|
| 284 |
+
chmod +x scripts/*.sh 2>/dev/null || true
|
| 285 |
+
|
| 286 |
+
# تصحيح أذونات الملفات المهمة
|
| 287 |
+
chmod 600 config/*.yaml 2>/dev/null || true
|
| 288 |
+
|
| 289 |
+
# تصحيح أذونات المجلدات
|
| 290 |
+
find . -type d -exec chmod 755 {} \; 2>/dev/null || true
|
| 291 |
+
|
| 292 |
+
print_success "تم إصلاح الأذونات"
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
# دالة حذف الملفات المؤقتة
|
| 296 |
+
clean_temp() {
|
| 297 |
+
print_info "جاري حذف الملفات المؤقتة..."
|
| 298 |
+
|
| 299 |
+
local count=0
|
| 300 |
+
|
| 301 |
+
# حذف ملفات ~
|
| 302 |
+
while IFS= read -r -d '' file; do
|
| 303 |
+
rm -f "$file"
|
| 304 |
+
((count++))
|
| 305 |
+
done < <(find . -name "*~" -print0 2>/dev/null)
|
| 306 |
+
|
| 307 |
+
# حذف ملفات .swp
|
| 308 |
+
while IFS= read -r -d '' file; do
|
| 309 |
+
rm -f "$file"
|
| 310 |
+
((count++))
|
| 311 |
+
done < <(find . -name "*.swp" -print0 2>/dev/null)
|
| 312 |
+
|
| 313 |
+
# حذف ملفات .swo
|
| 314 |
+
while IFS= read -r -d '' file; do
|
| 315 |
+
rm -f "$file"
|
| 316 |
+
((count++))
|
| 317 |
+
done < <(find . -name "*.swo" -print0 2>/dev/null)
|
| 318 |
+
|
| 319 |
+
# حذف ملفات .tmp
|
| 320 |
+
rm -f *.tmp 2>/dev/null
|
| 321 |
+
rm -f tmp/* 2>/dev/null || true
|
| 322 |
+
|
| 323 |
+
print_success "تم حذف $count ملف مؤقت"
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
# دالة عرض المساعدة
|
| 327 |
+
show_help() {
|
| 328 |
+
echo ""
|
| 329 |
+
echo "استخدام: $0 [الخيار]"
|
| 330 |
+
echo ""
|
| 331 |
+
echo "خيار��ت الصيانة:"
|
| 332 |
+
echo ""
|
| 333 |
+
echo " all - تشغيل جميع عمليات الصيانة"
|
| 334 |
+
echo " pycache - تنظيف ملفات Python المؤقتة"
|
| 335 |
+
echo " logs - تنظيف السجلات القديمة"
|
| 336 |
+
echo " tests - تنظيف ملفات الاختبار"
|
| 337 |
+
echo " build - تنظيف ملفات البناء"
|
| 338 |
+
echo " cache - تنظيف ملفات التخزين المؤقت"
|
| 339 |
+
echo " temp - حذف الملفات المؤقتة"
|
| 340 |
+
echo " permissions - إصلاح أذونات الملفات"
|
| 341 |
+
echo " disk - التحقق من مساحة القرص"
|
| 342 |
+
echo " git - التحقق من حالة Git"
|
| 343 |
+
echo " deps - التحقق من التبعيات"
|
| 344 |
+
echo " report - إنشاء تقرير الحالة"
|
| 345 |
+
echo " help - عرض هذه المساعدة"
|
| 346 |
+
echo ""
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
# ========================================
|
| 350 |
+
# البرنامج الرئيسي
|
| 351 |
+
# ========================================
|
| 352 |
+
|
| 353 |
+
print_header
|
| 354 |
+
|
| 355 |
+
# التحقق من الوسائط
|
| 356 |
+
case "${1:-all}" in
|
| 357 |
+
all)
|
| 358 |
+
echo "جاري تشغيل جميع عمليات الصيانة..."
|
| 359 |
+
echo ""
|
| 360 |
+
|
| 361 |
+
clean_pycache
|
| 362 |
+
echo ""
|
| 363 |
+
|
| 364 |
+
clean_logs
|
| 365 |
+
echo ""
|
| 366 |
+
|
| 367 |
+
clean_tests
|
| 368 |
+
echo ""
|
| 369 |
+
|
| 370 |
+
clean_build
|
| 371 |
+
echo ""
|
| 372 |
+
|
| 373 |
+
clean_cache
|
| 374 |
+
echo ""
|
| 375 |
+
|
| 376 |
+
clean_temp
|
| 377 |
+
echo ""
|
| 378 |
+
|
| 379 |
+
fix_permissions
|
| 380 |
+
echo ""
|
| 381 |
+
|
| 382 |
+
check_disk_space
|
| 383 |
+
echo ""
|
| 384 |
+
|
| 385 |
+
generate_status_report
|
| 386 |
+
;;
|
| 387 |
+
|
| 388 |
+
pycache)
|
| 389 |
+
clean_pycache
|
| 390 |
+
;;
|
| 391 |
+
|
| 392 |
+
logs)
|
| 393 |
+
clean_logs
|
| 394 |
+
;;
|
| 395 |
+
|
| 396 |
+
tests)
|
| 397 |
+
clean_tests
|
| 398 |
+
;;
|
| 399 |
+
|
| 400 |
+
build)
|
| 401 |
+
clean_build
|
| 402 |
+
;;
|
| 403 |
+
|
| 404 |
+
cache)
|
| 405 |
+
clean_cache
|
| 406 |
+
;;
|
| 407 |
+
|
| 408 |
+
temp)
|
| 409 |
+
clean_temp
|
| 410 |
+
;;
|
| 411 |
+
|
| 412 |
+
permissions)
|
| 413 |
+
fix_permissions
|
| 414 |
+
;;
|
| 415 |
+
|
| 416 |
+
disk)
|
| 417 |
+
check_disk_space
|
| 418 |
+
;;
|
| 419 |
+
|
| 420 |
+
git)
|
| 421 |
+
check_git_status
|
| 422 |
+
;;
|
| 423 |
+
|
| 424 |
+
deps)
|
| 425 |
+
check_dependencies
|
| 426 |
+
;;
|
| 427 |
+
|
| 428 |
+
report)
|
| 429 |
+
generate_status_report
|
| 430 |
+
;;
|
| 431 |
+
|
| 432 |
+
help|--help|-h)
|
| 433 |
+
show_help
|
| 434 |
+
;;
|
| 435 |
+
|
| 436 |
+
*)
|
| 437 |
+
print_error "خيار غير معروف: $1"
|
| 438 |
+
show_help
|
| 439 |
+
exit 1
|
| 440 |
+
;;
|
| 441 |
+
esac
|
| 442 |
+
|
| 443 |
+
echo ""
|
| 444 |
+
print_success "اكتمل العمل بنجاح!"
|
| 445 |
+
echo ""
|
scripts/security_scanner.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import datetime
|
| 4 |
+
|
| 5 |
+
class SecurityScanner:
|
| 6 |
+
def __init__(self, target_dir):
|
| 7 |
+
self.target_dir = target_dir
|
| 8 |
+
self.results = {
|
| 9 |
+
"scan_time": str(datetime.datetime.now()),
|
| 10 |
+
"vulnerabilities": [],
|
| 11 |
+
"summary": {"high": 0, "medium": 0, "low": 0}
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
def scan_files(self):
|
| 15 |
+
print(f"Starting security scan on: {self.target_dir}")
|
| 16 |
+
for root, dirs, files in os.walk(self.target_dir):
|
| 17 |
+
for file in files:
|
| 18 |
+
if file.endswith(('.py', '.js', '.html')):
|
| 19 |
+
self._check_file(os.path.join(root, file))
|
| 20 |
+
|
| 21 |
+
self._save_results()
|
| 22 |
+
|
| 23 |
+
def _check_file(self, file_path):
|
| 24 |
+
# Simple pattern matching for demonstration
|
| 25 |
+
patterns = {
|
| 26 |
+
"hardcoded_api_key": {"regex": "api_key =", "severity": "high", "desc": "Potential hardcoded API key found"},
|
| 27 |
+
"insecure_eval": {"regex": "eval\(", "severity": "high", "desc": "Use of insecure eval() function"},
|
| 28 |
+
"todo_comment": {"regex": "TODO:", "severity": "low", "desc": "Unresolved TODO comment"}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
try:
|
| 32 |
+
with open(file_path, 'r', errors='ignore') as f:
|
| 33 |
+
content = f.read()
|
| 34 |
+
for key, data in patterns.items():
|
| 35 |
+
if data["regex"] in content:
|
| 36 |
+
self.results["vulnerabilities"].append({
|
| 37 |
+
"file": file_path,
|
| 38 |
+
"issue": key,
|
| 39 |
+
"severity": data["severity"],
|
| 40 |
+
"description": data["desc"]
|
| 41 |
+
})
|
| 42 |
+
self.results["summary"][data["severity"]] += 1
|
| 43 |
+
except Exception as e:
|
| 44 |
+
print(f"Error scanning {file_path}: {e}")
|
| 45 |
+
|
| 46 |
+
def _save_results(self):
|
| 47 |
+
output_path = os.path.join(self.target_dir, 'public/data/security_scan_latest.json')
|
| 48 |
+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
| 49 |
+
with open(output_path, 'w') as f:
|
| 50 |
+
json.dump(self.results, f, indent=4)
|
| 51 |
+
print(f"Scan complete. Results saved to {output_path}")
|
| 52 |
+
|
| 53 |
+
if __name__ == "__main__":
|
| 54 |
+
scanner = SecurityScanner('.')
|
| 55 |
+
scanner.scan_files()
|
scripts/upgrade.sh
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# سكريبت ترقية نظام الحارس التلقائي
|
| 3 |
+
# Auto Guardian System Upgrade Script
|
| 4 |
+
# =====================================
|
| 5 |
+
|
| 6 |
+
# إعداداتColors
|
| 7 |
+
GREEN='\033[0;32m'
|
| 8 |
+
BLUE='\033[0;34m'
|
| 9 |
+
YELLOW='\033[1;33m'
|
| 10 |
+
RED='\033[0;31m'
|
| 11 |
+
CYAN='\033[0;36m'
|
| 12 |
+
BOLD='\033[1m'
|
| 13 |
+
NC='\033[0m'
|
| 14 |
+
|
| 15 |
+
# إعدادات
|
| 16 |
+
LOG_FILE="logs/upgrade.log"
|
| 17 |
+
BACKUP_DIR="backups"
|
| 18 |
+
CONFIG_BACKUP="config.backup.$(date +%Y%m%d_%H%M%S)"
|
| 19 |
+
|
| 20 |
+
# دوال مساعدة
|
| 21 |
+
print_info() {
|
| 22 |
+
echo -e "${BLUE}[INFO]${NC} $1"
|
| 23 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $1" >> "$LOG_FILE"
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
print_success() {
|
| 27 |
+
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
| 28 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $1" >> "$LOG_FILE"
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
print_warning() {
|
| 32 |
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
| 33 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] $1" >> "$LOG_FILE"
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
print_error() {
|
| 37 |
+
echo -e "${RED}[ERROR]${NC} $1"
|
| 38 |
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $1" >> "$LOG_FILE"
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
print_header() {
|
| 42 |
+
echo ""
|
| 43 |
+
echo "=============================================="
|
| 44 |
+
echo " نظام الحارس التلقائي - الترقية"
|
| 45 |
+
echo "=============================================="
|
| 46 |
+
echo ""
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
# إنشاء مجلد السجلات إن لم يوجد
|
| 50 |
+
mkdir -p "$(dirname "$LOG_FILE")" "$BACKUP_DIR"
|
| 51 |
+
|
| 52 |
+
# دالة النسخ الاحتياطي للإعدادات
|
| 53 |
+
backup_config() {
|
| 54 |
+
print_info "جاري إنشاء نسخة احتياطية من الإعدادات..."
|
| 55 |
+
|
| 56 |
+
if [ -d "config" ]; then
|
| 57 |
+
cp -r "config" "$CONFIG_BACKUP"
|
| 58 |
+
print_success "حُفظت الإعدادات في: $CONFIG_BACKUP"
|
| 59 |
+
return 0
|
| 60 |
+
else
|
| 61 |
+
print_warning "مجلد الإعدادات غير موجود"
|
| 62 |
+
return 1
|
| 63 |
+
fi
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
# دالة التحقق من المتطلبات
|
| 67 |
+
check_requirements() {
|
| 68 |
+
print_info "جاري التحقق من المتطلبات..."
|
| 69 |
+
|
| 70 |
+
# التحقق من Python
|
| 71 |
+
if ! command -v python3 &> /dev/null; then
|
| 72 |
+
print_error "Python 3 غير مثبت! يرجى تثبيت Python 3.8 أو أحدث."
|
| 73 |
+
return 1
|
| 74 |
+
fi
|
| 75 |
+
|
| 76 |
+
local python_version=$(python3 --version 2>&1 | grep -oP '\d+\.\d+')
|
| 77 |
+
local major=$(echo "$python_version" | cut -d. -f1)
|
| 78 |
+
local minor=$(echo "$python_version" | cut -d. -f2)
|
| 79 |
+
|
| 80 |
+
if [ "$major" -lt 3 ] || ([ "$major" -eq 3 ] && [ "$minor" -lt 8 ]); then
|
| 81 |
+
print_error "Python 3.8 أو أحدث مطلوب! الإصدار الحالي: $python_version"
|
| 82 |
+
return 1
|
| 83 |
+
fi
|
| 84 |
+
|
| 85 |
+
print_success "Python $python_version ✓"
|
| 86 |
+
|
| 87 |
+
# التحقق من Git
|
| 88 |
+
if ! command -v git &> /dev/null; then
|
| 89 |
+
print_error "Git غير مثبت! يرجى تثبيت Git."
|
| 90 |
+
return 1
|
| 91 |
+
fi
|
| 92 |
+
|
| 93 |
+
print_success "Git ✓"
|
| 94 |
+
|
| 95 |
+
# التحقق من Git repository
|
| 96 |
+
if [ ! -d ".git" ]; then
|
| 97 |
+
print_warning "المستودع ليس Git. لن يتم استخدام Git للترقية."
|
| 98 |
+
return 2
|
| 99 |
+
fi
|
| 100 |
+
|
| 101 |
+
return 0
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
# دالة جلب التحديثات من Git
|
| 105 |
+
git_pull() {
|
| 106 |
+
print_info "جاري جلب التحديثات من Git..."
|
| 107 |
+
|
| 108 |
+
# جلب التحديثات
|
| 109 |
+
git fetch origin
|
| 110 |
+
|
| 111 |
+
# الحصول على الفرع الحالي
|
| 112 |
+
local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
| 113 |
+
print_info "الفرع الحالي: $current_branch"
|
| 114 |
+
|
| 115 |
+
# جلب التغييرات
|
| 116 |
+
if git pull origin "$current_branch" --no-edit; then
|
| 117 |
+
print_success "تم جلب التحديثات"
|
| 118 |
+
return 0
|
| 119 |
+
else
|
| 120 |
+
print_error "فشل في جلب التحديثات"
|
| 121 |
+
return 1
|
| 122 |
+
fi
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
# دالة الترقية من ZIP
|
| 126 |
+
upgrade_from_zip() {
|
| 127 |
+
local zip_file=$1
|
| 128 |
+
|
| 129 |
+
if [ -z "$zip_file" ]; then
|
| 130 |
+
print_error "يرجى تحديد ملف ZIP"
|
| 131 |
+
return 1
|
| 132 |
+
fi
|
| 133 |
+
|
| 134 |
+
if [ ! -f "$zip_file" ]; then
|
| 135 |
+
print_error "الملف غير موجود: $zip_file"
|
| 136 |
+
return 1
|
| 137 |
+
fi
|
| 138 |
+
|
| 139 |
+
print_info "جاري الترقية من: $zip_file"
|
| 140 |
+
|
| 141 |
+
# إنشاء مجلد مؤقت
|
| 142 |
+
local temp_dir=$(mktemp -d)
|
| 143 |
+
trap "rm -rf $temp_dir" EXIT
|
| 144 |
+
|
| 145 |
+
# استخراج الملفات
|
| 146 |
+
unzip -q "$zip_file" -d "$temp_dir"
|
| 147 |
+
|
| 148 |
+
# التحقق من المحتوى
|
| 149 |
+
if [ ! -f "$temp_dir/README.md" ]; then
|
| 150 |
+
print_error "الملف ZIP ليس لتحديث نظام الحارس التلقائي"
|
| 151 |
+
return 1
|
| 152 |
+
fi
|
| 153 |
+
|
| 154 |
+
# نسخ الملفات (مع تجاوز)
|
| 155 |
+
print_info "جاري نسخ الملفات..."
|
| 156 |
+
cp -r "$temp_dir"/* .
|
| 157 |
+
|
| 158 |
+
print_success "تم الترقية من ملف ZIP"
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
# دالة تحديث التبعيات
|
| 162 |
+
update_dependencies() {
|
| 163 |
+
print_info "جاري تحديث التبعيات..."
|
| 164 |
+
|
| 165 |
+
# التحقق من ملف requirements.txt
|
| 166 |
+
if [ ! -f "requirements.txt" ]; then
|
| 167 |
+
print_warning "ملف requirements.txt غير موجود"
|
| 168 |
+
return 1
|
| 169 |
+
fi
|
| 170 |
+
|
| 171 |
+
# ترقية pip
|
| 172 |
+
print_info "تحديث pip..."
|
| 173 |
+
python3 -m pip install --upgrade pip wheel setuptools
|
| 174 |
+
|
| 175 |
+
# ترقية التبعيات
|
| 176 |
+
print_info "تحديث التبعيات..."
|
| 177 |
+
if python3 -m pip install -r requirements.txt --upgrade; then
|
| 178 |
+
print_success "تم تحديث التبعيات"
|
| 179 |
+
else
|
| 180 |
+
print_error "فشل في تحديث التبعيات"
|
| 181 |
+
return 1
|
| 182 |
+
fi
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
# دالة تشغيل التهجير
|
| 186 |
+
run_migrations() {
|
| 187 |
+
print_info "جاري تشغيل التهجير..."
|
| 188 |
+
|
| 189 |
+
# التحقق من وجود سكريبت التهجير
|
| 190 |
+
if [ -f "scripts/migrate.py" ]; then
|
| 191 |
+
python3 scripts/migrate.py
|
| 192 |
+
elif [ -f "migrate.py" ]; then
|
| 193 |
+
python3 migrate.py
|
| 194 |
+
else
|
| 195 |
+
print_info "لا توجد تهجيرات للترقية"
|
| 196 |
+
fi
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
# دالة التحقق من الإعدادات الجديدة
|
| 200 |
+
check_new_config() {
|
| 201 |
+
print_info "جاري التحقق من الإعدادات الجديدة..."
|
| 202 |
+
|
| 203 |
+
# التحقق من وجود نموذج الإعدادات
|
| 204 |
+
if [ -f "config/settings.example.yaml" ]; then
|
| 205 |
+
if [ ! -f "config/settings.yaml" ]; then
|
| 206 |
+
print_warning "تم إنشاء ملف إعدادات جديد"
|
| 207 |
+
cp config/settings.example.yaml config/settings.yaml
|
| 208 |
+
fi
|
| 209 |
+
|
| 210 |
+
# عرض الإعدادات الجديدة
|
| 211 |
+
print_info "راجع الإعدادات الجديدة في config/settings.yaml"
|
| 212 |
+
print_info "راجع التغييرات في config/settings.example.yaml"
|
| 213 |
+
fi
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
# دالة التحقق من الإضافات في GitHub Actions
|
| 217 |
+
check_github_actions() {
|
| 218 |
+
print_info "جاري التحقق من GitHub Actions..."
|
| 219 |
+
|
| 220 |
+
if [ -d ".github/workflows" ]; then
|
| 221 |
+
print_success "GitHub Actions موجود"
|
| 222 |
+
|
| 223 |
+
# عرض سير العمل الجديد
|
| 224 |
+
local new_workflows=$(git diff --name-only HEAD@{1}..HEAD .github/workflows/ 2>/dev/null | wc -l)
|
| 225 |
+
if [ "$new_workflows" -gt 0 ]; then
|
| 226 |
+
print_info "يوجد $new_workflows سير عمل جديد أو معدل"
|
| 227 |
+
fi
|
| 228 |
+
fi
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
# دالة إعادة تشغيل الخدمة
|
| 232 |
+
restart_service() {
|
| 233 |
+
print_info "جاري إعادة تشغيل الخدمة..."
|
| 234 |
+
|
| 235 |
+
# التحقق من systemd
|
| 236 |
+
if command -v systemctl &> /dev/null; then
|
| 237 |
+
if systemctl is-active --quiet autoguardian 2>/dev/null; then
|
| 238 |
+
print_info "إعادة تشغيل الخدمة عبر systemd..."
|
| 239 |
+
sudo systemctl restart autoguardian
|
| 240 |
+
print_success "تم إعادة تشغيل الخدمة"
|
| 241 |
+
return 0
|
| 242 |
+
fi
|
| 243 |
+
fi
|
| 244 |
+
|
| 245 |
+
# التحقق من Docker
|
| 246 |
+
if [ -f "docker-compose.yml" ]; then
|
| 247 |
+
print_info "إعادة تشغيل الحاويات..."
|
| 248 |
+
docker-compose restart auto-guardian
|
| 249 |
+
print_success "تم إعادة تشغيل الحاويات"
|
| 250 |
+
return 0
|
| 251 |
+
fi
|
| 252 |
+
|
| 253 |
+
# الطريقة اليدوية
|
| 254 |
+
print_info "جاري إيقاف النظام..."
|
| 255 |
+
pkill -f "python.*src.main" 2>/dev/null || true
|
| 256 |
+
|
| 257 |
+
print_info "جاري تشغيل النظام..."
|
| 258 |
+
nohup python3 -m src.main > logs/auto-guardian.log 2>&1 &
|
| 259 |
+
|
| 260 |
+
sleep 2
|
| 261 |
+
|
| 262 |
+
if pgrep -f "python.*src.main" > /dev/null; then
|
| 263 |
+
print_success "تم تشغيل النظام"
|
| 264 |
+
else
|
| 265 |
+
print_error "فشل في تشغيل النظام"
|
| 266 |
+
return 1
|
| 267 |
+
fi
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
# دالة عرض ملخص الترقية
|
| 271 |
+
show_upgrade_summary() {
|
| 272 |
+
local new_version=$1
|
| 273 |
+
|
| 274 |
+
echo ""
|
| 275 |
+
echo "=============================================="
|
| 276 |
+
echo " ملخص الترقية"
|
| 277 |
+
echo "=============================================="
|
| 278 |
+
echo ""
|
| 279 |
+
|
| 280 |
+
echo -e "${GREEN}✓${NC} تم إنشاء نسخة احتياطية من الإعدادات"
|
| 281 |
+
echo -e "${GREEN}✓${NC} تم تحديث التبعيات"
|
| 282 |
+
echo ""
|
| 283 |
+
|
| 284 |
+
if [ -n "$new_version" ]; then
|
| 285 |
+
echo -e "الإصدار الجديد: ${BOLD}$new_version${NC}"
|
| 286 |
+
fi
|
| 287 |
+
|
| 288 |
+
echo ""
|
| 289 |
+
echo "الخطوات التالية:"
|
| 290 |
+
echo "----------------"
|
| 291 |
+
echo "1. راجع ملف CHANGELOG.md لمعرفة التغييرات"
|
| 292 |
+
echo "2. راجع ملف requirements.txt للتعرف على التبعيات الجديدة"
|
| 293 |
+
echo "3. حدّث إعداداتك إذا لزم الأمر"
|
| 294 |
+
echo "4. شغل النظام: python3 -m src.main"
|
| 295 |
+
echo ""
|
| 296 |
+
|
| 297 |
+
echo "للإبلاغ عن المشاكل:"
|
| 298 |
+
echo "- GitHub Issues: https://github.com/AbdulElahOthmanGwaith/auto-guardian-system/issues"
|
| 299 |
+
echo "- البريد: support@autoguardian.local"
|
| 300 |
+
echo ""
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
# دالة عرض المساعدة
|
| 304 |
+
show_help() {
|
| 305 |
+
echo ""
|
| 306 |
+
echo "استخدام: $0 [الخيار] [الوسيطة]"
|
| 307 |
+
echo ""
|
| 308 |
+
echo "خيارات الترقية:"
|
| 309 |
+
echo ""
|
| 310 |
+
echo " git - الترقية من Git (الوضع الافتراضي)"
|
| 311 |
+
echo " zip <file> - الترقية من ملف ZIP"
|
| 312 |
+
echo " check - التحقق من التحديثات فقط"
|
| 313 |
+
echo " backup - إنشاء نسخة احتياطية فقط"
|
| 314 |
+
echo " deps - تحديث التبعيات فقط"
|
| 315 |
+
echo " restart - إعادة تشغيل الخدمة فقط"
|
| 316 |
+
echo " help - عرض هذه المساعدة"
|
| 317 |
+
echo ""
|
| 318 |
+
echo "أمثلة:"
|
| 319 |
+
echo " $0 git # الترقية من Git"
|
| 320 |
+
echo " $0 zip update.zip # الترقية من ZIP"
|
| 321 |
+
echo " $0 check # التحقق من التحديثات"
|
| 322 |
+
echo " $0 restart # إعادة تشغيل الخدمة"
|
| 323 |
+
echo ""
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
# ========================================
|
| 327 |
+
# البرنامج الرئيسي
|
| 328 |
+
# ========================================
|
| 329 |
+
|
| 330 |
+
print_header
|
| 331 |
+
|
| 332 |
+
# التحقق من الوسائط
|
| 333 |
+
case "${1:-git}" in
|
| 334 |
+
git)
|
| 335 |
+
echo "وضع الترقية: Git"
|
| 336 |
+
echo ""
|
| 337 |
+
|
| 338 |
+
# النسخ الاحتياطي للإعدادات
|
| 339 |
+
backup_config
|
| 340 |
+
|
| 341 |
+
# التحقق من المتطلبات
|
| 342 |
+
if ! check_requirements; then
|
| 343 |
+
if [ $? -eq 2 ]; then
|
| 344 |
+
print_warning "استمرار بدون Git"
|
| 345 |
+
else
|
| 346 |
+
print_error "فشل في التحقق من المتطلبات"
|
| 347 |
+
exit 1
|
| 348 |
+
fi
|
| 349 |
+
fi
|
| 350 |
+
|
| 351 |
+
# جلب التحديثات
|
| 352 |
+
if [ -d ".git" ]; then
|
| 353 |
+
git_pull
|
| 354 |
+
fi
|
| 355 |
+
|
| 356 |
+
# تحديث التبعيات
|
| 357 |
+
update_dependencies
|
| 358 |
+
|
| 359 |
+
# التحقق من الإعدادات الجديدة
|
| 360 |
+
check_new_config
|
| 361 |
+
|
| 362 |
+
# التحقق من GitHub Actions
|
| 363 |
+
check_github_actions
|
| 364 |
+
|
| 365 |
+
# عرض الملخص
|
| 366 |
+
local new_version=$(git describe --tags 2>/dev/null || echo "1.3.0")
|
| 367 |
+
show_upgrade_summary "$new_version"
|
| 368 |
+
;;
|
| 369 |
+
|
| 370 |
+
zip)
|
| 371 |
+
echo "وضع الترقية: ملف ZIP"
|
| 372 |
+
echo ""
|
| 373 |
+
|
| 374 |
+
# النسخ الاحتياطي للإعدادات
|
| 375 |
+
backup_config
|
| 376 |
+
|
| 377 |
+
# الترقية من ZIP
|
| 378 |
+
upgrade_from_zip "${2:-}"
|
| 379 |
+
|
| 380 |
+
# تحديث التبعيات
|
| 381 |
+
update_dependencies
|
| 382 |
+
|
| 383 |
+
# التحقق من الإعدادات الجديدة
|
| 384 |
+
check_new_config
|
| 385 |
+
|
| 386 |
+
show_upgrade_summary
|
| 387 |
+
;;
|
| 388 |
+
|
| 389 |
+
check)
|
| 390 |
+
echo "التحقق من التحديثات..."
|
| 391 |
+
echo ""
|
| 392 |
+
|
| 393 |
+
check_requirements || true
|
| 394 |
+
|
| 395 |
+
if [ -d ".git" ]; then
|
| 396 |
+
git fetch origin
|
| 397 |
+
|
| 398 |
+
local current_commit=$(git rev-parse HEAD)
|
| 399 |
+
local remote_commit=$(git rev-parse origin/main)
|
| 400 |
+
|
| 401 |
+
if [ "$current_commit" != "$remote_commit" ]; then
|
| 402 |
+
local commits_behind=$(git rev-list --count HEAD..origin/main)
|
| 403 |
+
print_info "يوجد تحديث متاح ($commits_behind commits behind)"
|
| 404 |
+
echo ""
|
| 405 |
+
git log --oneline HEAD..origin/main | head -10
|
| 406 |
+
else
|
| 407 |
+
print_success "المستودع محدث"
|
| 408 |
+
fi
|
| 409 |
+
fi
|
| 410 |
+
;;
|
| 411 |
+
|
| 412 |
+
backup)
|
| 413 |
+
echo "إنشاء نسخة احتياطية..."
|
| 414 |
+
echo ""
|
| 415 |
+
backup_config
|
| 416 |
+
;;
|
| 417 |
+
|
| 418 |
+
deps)
|
| 419 |
+
echo "تحديث التبعيات..."
|
| 420 |
+
echo ""
|
| 421 |
+
update_dependencies
|
| 422 |
+
;;
|
| 423 |
+
|
| 424 |
+
restart)
|
| 425 |
+
echo "إعادة تشغيل الخدمة..."
|
| 426 |
+
echo ""
|
| 427 |
+
restart_service
|
| 428 |
+
;;
|
| 429 |
+
|
| 430 |
+
help|--help|-h)
|
| 431 |
+
show_help
|
| 432 |
+
;;
|
| 433 |
+
|
| 434 |
+
*)
|
| 435 |
+
print_error "خيار غير معروف: $1"
|
| 436 |
+
show_help
|
| 437 |
+
exit 1
|
| 438 |
+
;;
|
| 439 |
+
esac
|
| 440 |
+
|
| 441 |
+
echo ""
|
| 442 |
+
print_success "اكتمل العمل بنجاح!"
|
| 443 |
+
echo ""
|
setup-guide.html
ADDED
|
@@ -0,0 +1,823 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ar" dir="rtl">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Auto-Guardian - دليل الإعداد الشامل</title>
|
| 7 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
+
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
| 10 |
+
<style>
|
| 11 |
+
:root {
|
| 12 |
+
--bg-primary: #0f172a;
|
| 13 |
+
--bg-secondary: #1e293b;
|
| 14 |
+
--bg-tertiary: #334155;
|
| 15 |
+
--text-primary: #f1f5f9;
|
| 16 |
+
--text-secondary: #94a3b8;
|
| 17 |
+
--text-muted: #64748b;
|
| 18 |
+
--border-color: #334155;
|
| 19 |
+
--accent-blue: #3b82f6;
|
| 20 |
+
--accent-purple: #8b5cf6;
|
| 21 |
+
--accent-cyan: #06b6d4;
|
| 22 |
+
--success: #10b981;
|
| 23 |
+
--warning: #f59e0b;
|
| 24 |
+
--danger: #ef4444;
|
| 25 |
+
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
|
| 26 |
+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4);
|
| 27 |
+
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
* {
|
| 31 |
+
margin: 0;
|
| 32 |
+
padding: 0;
|
| 33 |
+
box-sizing: border-box;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
body {
|
| 37 |
+
font-family: 'Noto Sans Arabic', -apple-system, sans-serif;
|
| 38 |
+
background: var(--bg-primary);
|
| 39 |
+
color: var(--text-primary);
|
| 40 |
+
line-height: 1.8;
|
| 41 |
+
overflow-x: hidden;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/* Hero Section */
|
| 45 |
+
.hero {
|
| 46 |
+
background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
|
| 47 |
+
padding: 80px 40px;
|
| 48 |
+
text-align: center;
|
| 49 |
+
position: relative;
|
| 50 |
+
overflow: hidden;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
.hero::before {
|
| 54 |
+
content: '';
|
| 55 |
+
position: absolute;
|
| 56 |
+
top: 0;
|
| 57 |
+
left: 0;
|
| 58 |
+
right: 0;
|
| 59 |
+
bottom: 0;
|
| 60 |
+
background:
|
| 61 |
+
radial-gradient(circle at 20% 80%, rgba(59, 130, 246, 0.1) 0%, transparent 50%),
|
| 62 |
+
radial-gradient(circle at 80% 20%, rgba(139, 92, 246, 0.1) 0%, transparent 50%);
|
| 63 |
+
pointer-events: none;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
.hero-content {
|
| 67 |
+
position: relative;
|
| 68 |
+
z-index: 1;
|
| 69 |
+
max-width: 800px;
|
| 70 |
+
margin: 0 auto;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.hero-badge {
|
| 74 |
+
display: inline-flex;
|
| 75 |
+
align-items: center;
|
| 76 |
+
gap: 8px;
|
| 77 |
+
background: rgba(59, 130, 246, 0.2);
|
| 78 |
+
border: 1px solid rgba(59, 130, 246, 0.3);
|
| 79 |
+
padding: 8px 20px;
|
| 80 |
+
border-radius: 50px;
|
| 81 |
+
font-size: 14px;
|
| 82 |
+
color: var(--accent-blue);
|
| 83 |
+
margin-bottom: 24px;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.hero-title {
|
| 87 |
+
font-size: 48px;
|
| 88 |
+
font-weight: 700;
|
| 89 |
+
margin-bottom: 16px;
|
| 90 |
+
background: linear-gradient(135deg, var(--text-primary), var(--accent-blue));
|
| 91 |
+
-webkit-background-clip: text;
|
| 92 |
+
-webkit-text-fill-color: transparent;
|
| 93 |
+
background-clip: text;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
.hero-subtitle {
|
| 97 |
+
font-size: 18px;
|
| 98 |
+
color: var(--text-muted);
|
| 99 |
+
margin-bottom: 40px;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.hero-actions {
|
| 103 |
+
display: flex;
|
| 104 |
+
gap: 16px;
|
| 105 |
+
justify-content: center;
|
| 106 |
+
flex-wrap: wrap;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.btn {
|
| 110 |
+
display: inline-flex;
|
| 111 |
+
align-items: center;
|
| 112 |
+
gap: 8px;
|
| 113 |
+
padding: 14px 28px;
|
| 114 |
+
border-radius: 12px;
|
| 115 |
+
font-size: 15px;
|
| 116 |
+
font-weight: 600;
|
| 117 |
+
cursor: pointer;
|
| 118 |
+
transition: var(--transition);
|
| 119 |
+
border: none;
|
| 120 |
+
font-family: inherit;
|
| 121 |
+
text-decoration: none;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.btn-primary {
|
| 125 |
+
background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple));
|
| 126 |
+
color: white;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
.btn-primary:hover {
|
| 130 |
+
transform: translateY(-3px);
|
| 131 |
+
box-shadow: var(--shadow-lg);
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
.btn-secondary {
|
| 135 |
+
background: var(--bg-tertiary);
|
| 136 |
+
color: var(--text-primary);
|
| 137 |
+
border: 1px solid var(--border-color);
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
.btn-secondary:hover {
|
| 141 |
+
background: var(--bg-secondary);
|
| 142 |
+
border-color: var(--accent-blue);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
/* Progress Section */
|
| 146 |
+
.progress-section {
|
| 147 |
+
background: var(--bg-secondary);
|
| 148 |
+
padding: 60px 40px;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.section-header {
|
| 152 |
+
text-align: center;
|
| 153 |
+
margin-bottom: 48px;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.section-title {
|
| 157 |
+
font-size: 32px;
|
| 158 |
+
font-weight: 700;
|
| 159 |
+
margin-bottom: 12px;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
.section-subtitle {
|
| 163 |
+
font-size: 16px;
|
| 164 |
+
color: var(--text-muted);
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.steps-container {
|
| 168 |
+
max-width: 900px;
|
| 169 |
+
margin: 0 auto;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
.step {
|
| 173 |
+
display: flex;
|
| 174 |
+
gap: 24px;
|
| 175 |
+
margin-bottom: 32px;
|
| 176 |
+
padding: 24px;
|
| 177 |
+
background: var(--bg-primary);
|
| 178 |
+
border-radius: 16px;
|
| 179 |
+
border: 1px solid var(--border-color);
|
| 180 |
+
transition: var(--transition);
|
| 181 |
+
opacity: 0.5;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.step.active {
|
| 185 |
+
opacity: 1;
|
| 186 |
+
border-color: var(--accent-blue);
|
| 187 |
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
.step.completed {
|
| 191 |
+
opacity: 1;
|
| 192 |
+
border-color: var(--success);
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
.step-number {
|
| 196 |
+
width: 48px;
|
| 197 |
+
height: 48px;
|
| 198 |
+
border-radius: 50%;
|
| 199 |
+
background: var(--bg-tertiary);
|
| 200 |
+
display: flex;
|
| 201 |
+
align-items: center;
|
| 202 |
+
justify-content: center;
|
| 203 |
+
font-size: 18px;
|
| 204 |
+
font-weight: 700;
|
| 205 |
+
flex-shrink: 0;
|
| 206 |
+
transition: var(--transition);
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
.step.active .step-number {
|
| 210 |
+
background: var(--accent-blue);
|
| 211 |
+
color: white;
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
.step.completed .step-number {
|
| 215 |
+
background: var(--success);
|
| 216 |
+
color: white;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.step-content {
|
| 220 |
+
flex: 1;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.step-title {
|
| 224 |
+
font-size: 20px;
|
| 225 |
+
font-weight: 600;
|
| 226 |
+
margin-bottom: 8px;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.step-description {
|
| 230 |
+
font-size: 14px;
|
| 231 |
+
color: var(--text-muted);
|
| 232 |
+
margin-bottom: 16px;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
.step-code {
|
| 236 |
+
background: var(--bg-secondary);
|
| 237 |
+
border-radius: 8px;
|
| 238 |
+
padding: 16px;
|
| 239 |
+
font-family: 'JetBrains Mono', monospace;
|
| 240 |
+
font-size: 13px;
|
| 241 |
+
overflow-x: auto;
|
| 242 |
+
border: 1px solid var(--border-color);
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
.step-files {
|
| 246 |
+
display: flex;
|
| 247 |
+
flex-wrap: wrap;
|
| 248 |
+
gap: 8px;
|
| 249 |
+
margin-top: 12px;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
.file-tag {
|
| 253 |
+
display: inline-flex;
|
| 254 |
+
align-items: center;
|
| 255 |
+
gap: 6px;
|
| 256 |
+
padding: 6px 12px;
|
| 257 |
+
background: var(--bg-tertiary);
|
| 258 |
+
border-radius: 6px;
|
| 259 |
+
font-size: 12px;
|
| 260 |
+
font-family: 'JetBrains Mono', monospace;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.step-checklist {
|
| 264 |
+
list-style: none;
|
| 265 |
+
margin-top: 12px;
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
.step-checklist li {
|
| 269 |
+
display: flex;
|
| 270 |
+
align-items: center;
|
| 271 |
+
gap: 8px;
|
| 272 |
+
padding: 8px 0;
|
| 273 |
+
font-size: 14px;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
.check-icon {
|
| 277 |
+
width: 20px;
|
| 278 |
+
height: 20px;
|
| 279 |
+
border-radius: 50%;
|
| 280 |
+
border: 2px solid var(--border-color);
|
| 281 |
+
display: flex;
|
| 282 |
+
align-items: center;
|
| 283 |
+
justify-content: center;
|
| 284 |
+
font-size: 12px;
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
.step.completed .check-icon {
|
| 288 |
+
background: var(--success);
|
| 289 |
+
border-color: var(--success);
|
| 290 |
+
color: white;
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
/* Files Structure */
|
| 294 |
+
.structure-section {
|
| 295 |
+
padding: 60px 40px;
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
.tree-container {
|
| 299 |
+
max-width: 700px;
|
| 300 |
+
margin: 0 auto;
|
| 301 |
+
background: var(--bg-secondary);
|
| 302 |
+
border-radius: 16px;
|
| 303 |
+
padding: 24px;
|
| 304 |
+
border: 1px solid var(--border-color);
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
.tree {
|
| 308 |
+
font-family: 'JetBrains Mono', monospace;
|
| 309 |
+
font-size: 14px;
|
| 310 |
+
line-height: 2;
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
.tree-line {
|
| 314 |
+
display: flex;
|
| 315 |
+
align-items: center;
|
| 316 |
+
gap: 8px;
|
| 317 |
+
padding-right: 20px;
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
.tree-folder {
|
| 321 |
+
color: var(--warning);
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
.tree-file {
|
| 325 |
+
color: var(--accent-cyan);
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
.tree-badge {
|
| 329 |
+
background: var(--accent-purple);
|
| 330 |
+
color: white;
|
| 331 |
+
padding: 2px 8px;
|
| 332 |
+
border-radius: 4px;
|
| 333 |
+
font-size: 10px;
|
| 334 |
+
margin-right: auto;
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
/* Feature Cards */
|
| 338 |
+
.features-section {
|
| 339 |
+
background: var(--bg-secondary);
|
| 340 |
+
padding: 60px 40px;
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
.features-grid {
|
| 344 |
+
display: grid;
|
| 345 |
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
| 346 |
+
gap: 24px;
|
| 347 |
+
max-width: 1200px;
|
| 348 |
+
margin: 0 auto;
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
.feature-card {
|
| 352 |
+
background: var(--bg-primary);
|
| 353 |
+
border-radius: 16px;
|
| 354 |
+
padding: 32px;
|
| 355 |
+
border: 1px solid var(--border-color);
|
| 356 |
+
transition: var(--transition);
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
.feature-card:hover {
|
| 360 |
+
transform: translateY(-4px);
|
| 361 |
+
border-color: var(--accent-blue);
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
.feature-icon {
|
| 365 |
+
width: 56px;
|
| 366 |
+
height: 56px;
|
| 367 |
+
border-radius: 14px;
|
| 368 |
+
display: flex;
|
| 369 |
+
align-items: center;
|
| 370 |
+
justify-content: center;
|
| 371 |
+
font-size: 28px;
|
| 372 |
+
margin-bottom: 20px;
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
.feature-icon.security { background: rgba(239, 68, 68, 0.2); }
|
| 376 |
+
.feature-icon.auto { background: rgba(59, 130, 246, 0.2); }
|
| 377 |
+
.feature-icon.dashboard { background: rgba(16, 185, 129, 0.2); }
|
| 378 |
+
.feature-icon.multi { background: rgba(139, 92, 246, 0.2); }
|
| 379 |
+
|
| 380 |
+
.feature-title {
|
| 381 |
+
font-size: 20px;
|
| 382 |
+
font-weight: 600;
|
| 383 |
+
margin-bottom: 12px;
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
.feature-description {
|
| 387 |
+
font-size: 14px;
|
| 388 |
+
color: var(--text-muted);
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
/* FAQ Section */
|
| 392 |
+
.faq-section {
|
| 393 |
+
padding: 60px 40px;
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
.faq-container {
|
| 397 |
+
max-width: 800px;
|
| 398 |
+
margin: 0 auto;
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
.faq-item {
|
| 402 |
+
background: var(--bg-secondary);
|
| 403 |
+
border-radius: 12px;
|
| 404 |
+
margin-bottom: 16px;
|
| 405 |
+
overflow: hidden;
|
| 406 |
+
border: 1px solid var(--border-color);
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
+
.faq-question {
|
| 410 |
+
padding: 20px 24px;
|
| 411 |
+
font-size: 16px;
|
| 412 |
+
font-weight: 600;
|
| 413 |
+
cursor: pointer;
|
| 414 |
+
display: flex;
|
| 415 |
+
justify-content: space-between;
|
| 416 |
+
align-items: center;
|
| 417 |
+
transition: var(--transition);
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
.faq-question:hover {
|
| 421 |
+
background: var(--bg-tertiary);
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
.faq-answer {
|
| 425 |
+
padding: 0 24px 20px;
|
| 426 |
+
font-size: 14px;
|
| 427 |
+
color: var(--text-muted);
|
| 428 |
+
display: none;
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
.faq-item.open .faq-answer {
|
| 432 |
+
display: block;
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
.faq-toggle {
|
| 436 |
+
transition: var(--transition);
|
| 437 |
+
}
|
| 438 |
+
|
| 439 |
+
.faq-item.open .faq-toggle {
|
| 440 |
+
transform: rotate(180deg);
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
/* Footer */
|
| 444 |
+
.footer {
|
| 445 |
+
background: var(--bg-secondary);
|
| 446 |
+
padding: 40px;
|
| 447 |
+
text-align: center;
|
| 448 |
+
border-top: 1px solid var(--border-color);
|
| 449 |
+
}
|
| 450 |
+
|
| 451 |
+
.footer-text {
|
| 452 |
+
font-size: 14px;
|
| 453 |
+
color: var(--text-muted);
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
/* Responsive */
|
| 457 |
+
@media (max-width: 768px) {
|
| 458 |
+
.hero {
|
| 459 |
+
padding: 40px 20px;
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
.hero-title {
|
| 463 |
+
font-size: 32px;
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
.step {
|
| 467 |
+
flex-direction: column;
|
| 468 |
+
}
|
| 469 |
+
|
| 470 |
+
.hero-actions {
|
| 471 |
+
flex-direction: column;
|
| 472 |
+
}
|
| 473 |
+
|
| 474 |
+
.btn {
|
| 475 |
+
width: 100%;
|
| 476 |
+
justify-content: center;
|
| 477 |
+
}
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
/* Animations */
|
| 481 |
+
@keyframes fadeIn {
|
| 482 |
+
from { opacity: 0; transform: translateY(20px); }
|
| 483 |
+
to { opacity: 1; transform: translateY(0); }
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
.step {
|
| 487 |
+
animation: fadeIn 0.5s ease forwards;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
.step:nth-child(1) { animation-delay: 0.1s; }
|
| 491 |
+
.step:nth-child(2) { animation-delay: 0.2s; }
|
| 492 |
+
.step:nth-child(3) { animation-delay: 0.3s; }
|
| 493 |
+
.step:nth-child(4) { animation-delay: 0.4s; }
|
| 494 |
+
.step:nth-child(5) { animation-delay: 0.5s; }
|
| 495 |
+
</style>
|
| 496 |
+
</head>
|
| 497 |
+
<body>
|
| 498 |
+
<!-- Hero Section -->
|
| 499 |
+
<section class="hero">
|
| 500 |
+
<div class="hero-content">
|
| 501 |
+
<div class="hero-badge">
|
| 502 |
+
<span>🚀</span>
|
| 503 |
+
<span>دليل الإعداد الشامل</span>
|
| 504 |
+
</div>
|
| 505 |
+
<h1 class="hero-title">ابدأ مع Auto-Guardian</h1>
|
| 506 |
+
<p class="hero-subtitle">
|
| 507 |
+
نظام الفحص الأمني التلقائي للكود. اتبع الخطوات أدناه لتفعيل النظام بالكامل والحصول على لوحة تحكم تفاعلية تعرض حالة أمان مستودعك.
|
| 508 |
+
</p>
|
| 509 |
+
<div class="hero-actions">
|
| 510 |
+
<button class="btn btn-primary" onclick="scrollToSection('steps')">
|
| 511 |
+
<span>📋</span>
|
| 512 |
+
<span>بدء الإعداد</span>
|
| 513 |
+
</button>
|
| 514 |
+
<a href="index.html" class="btn btn-secondary">
|
| 515 |
+
<span>🎨</span>
|
| 516 |
+
<span>معاينة لوحة التحكم</span>
|
| 517 |
+
</a>
|
| 518 |
+
</div>
|
| 519 |
+
</div>
|
| 520 |
+
</section>
|
| 521 |
+
|
| 522 |
+
<!-- Steps Section -->
|
| 523 |
+
<section class="progress-section" id="steps">
|
| 524 |
+
<div class="section-header">
|
| 525 |
+
<h2 class="section-title">خطوات الإعداد</h2>
|
| 526 |
+
<p class="section-subtitle">اتبع هذه الخطوات بالترتيب لتفعيل النظام على مستودعك</p>
|
| 527 |
+
</div>
|
| 528 |
+
|
| 529 |
+
<div class="steps-container">
|
| 530 |
+
<!-- Step 1 -->
|
| 531 |
+
<div class="step active" id="step1">
|
| 532 |
+
<div class="step-number">1</div>
|
| 533 |
+
<div class="step-content">
|
| 534 |
+
<h3 class="step-title">إنشاء المستودع أو نسخ القالب</h3>
|
| 535 |
+
<p class="step-description">
|
| 536 |
+
أولاً، تحتاج إلى إنشاء مستودع جديد. يمكنك استخدام هذا المشروع كقالب لإنشاء مستودع جديد، أو نسخ الملفات يدوياً إلى مستودع موجود.
|
| 537 |
+
</p>
|
| 538 |
+
<div class="step-checklist">
|
| 539 |
+
<li>
|
| 540 |
+
<span class="check-icon">✓</span>
|
| 541 |
+
<span>اذهب إلى <strong>GitHub</strong وسجل الدخول</span>
|
| 542 |
+
</li>
|
| 543 |
+
<li>
|
| 544 |
+
<span class="check-icon">✓</span>
|
| 545 |
+
<span>زر <strong>Use this template</strong> لإنشاء مستودع جديد</span>
|
| 546 |
+
</li>
|
| 547 |
+
<li>
|
| 548 |
+
<span class="check-icon">✓</span>
|
| 549 |
+
<span>أو انسخ الملفات يدوياً إذا كان لديك مستودع موجود</span>
|
| 550 |
+
</li>
|
| 551 |
+
</div>
|
| 552 |
+
</div>
|
| 553 |
+
</div>
|
| 554 |
+
|
| 555 |
+
<!-- Step 2 -->
|
| 556 |
+
<div class="step" id="step2">
|
| 557 |
+
<div class="step-number">2</div>
|
| 558 |
+
<div class="step-content">
|
| 559 |
+
<h3 class="step-title">رفع الملفات</h3>
|
| 560 |
+
<p class="step-description">
|
| 561 |
+
بعد إنشاء المستودع، تحتاج إلى رفع جميع الملفات. الهيكل التالي يجب أن يكون موجوداً في مستودعك:
|
| 562 |
+
</p>
|
| 563 |
+
<div class="step-files">
|
| 564 |
+
<span class="file-tag">📁 .github/workflows/scan-and-deploy.yml</span>
|
| 565 |
+
<span class="file-tag">📁 scripts/aggregate_results.py</span>
|
| 566 |
+
<span class="file-tag">📁 scripts/generate_report.py</span>
|
| 567 |
+
<span class="file-tag">📁 dashboard/public/data/latest.json</span>
|
| 568 |
+
<span class="file-tag">📁 dashboard/index.html</span>
|
| 569 |
+
<span class="file-tag">📄 README.md</span>
|
| 570 |
+
</div>
|
| 571 |
+
</div>
|
| 572 |
+
</div>
|
| 573 |
+
|
| 574 |
+
<!-- Step 3 -->
|
| 575 |
+
<div class="step" id="step3">
|
| 576 |
+
<div class="step-number">3</div>
|
| 577 |
+
<div class="step-content">
|
| 578 |
+
<h3 class="step-title">تفعيل GitHub Pages</h3>
|
| 579 |
+
<p class="step-description">
|
| 580 |
+
الآن تحتاج إلى تفعيل GitHub Pages للسماح بنشر لوحة التحكم. اتبع الخطوات التالية:
|
| 581 |
+
</p>
|
| 582 |
+
<div class="step-checklist">
|
| 583 |
+
<li>
|
| 584 |
+
<span class="check-icon">✓</span>
|
| 585 |
+
<span>اذهب إلى <strong>Settings</strong> في مستودعك</span>
|
| 586 |
+
</li>
|
| 587 |
+
<li>
|
| 588 |
+
<span class="check-icon">✓</span>
|
| 589 |
+
<span>انقر على <strong>Pages</strong> في القائمة الجانبية</span>
|
| 590 |
+
</li>
|
| 591 |
+
<li>
|
| 592 |
+
<span class="check-icon">✓</span>
|
| 593 |
+
<span>في قسم <strong>Build and deployment</strong>:</span>
|
| 594 |
+
</li>
|
| 595 |
+
<li>
|
| 596 |
+
<span class="check-icon">✓</span>
|
| 597 |
+
<span><strong>Source:</strong> اختر <mark>GitHub Actions</mark></span>
|
| 598 |
+
</li>
|
| 599 |
+
</div>
|
| 600 |
+
<div class="step-code">
|
| 601 |
+
┌─────────────────────────────────────────────┐
|
| 602 |
+
│ Build and deployment │
|
| 603 |
+
│ │
|
| 604 |
+
│ Source › GitHub Actions │
|
| 605 |
+
└─────────────────────────────────────────────┘
|
| 606 |
+
</div>
|
| 607 |
+
</div>
|
| 608 |
+
</div>
|
| 609 |
+
|
| 610 |
+
<!-- Step 4 -->
|
| 611 |
+
<div class="step" id="step4">
|
| 612 |
+
<div class="step-number">4</div>
|
| 613 |
+
<div class="step-content">
|
| 614 |
+
<h3 class="step-title">تفعيل GitHub Actions</h3>
|
| 615 |
+
<p class="step-description">
|
| 616 |
+
الآن دعنا نتحقق من أن GitHub Actions يعمل. سير العمل سيبدأ تلقائياً عند دفع أي تغيير.
|
| 617 |
+
</p>
|
| 618 |
+
<div class="step-checklist">
|
| 619 |
+
<li>
|
| 620 |
+
<span class="check-icon">✓</span>
|
| 621 |
+
<span>اذهب إلى تبويب <strong>Actions</strong> في المستودع</span>
|
| 622 |
+
</li>
|
| 623 |
+
<li>
|
| 624 |
+
<span class="check-icon">✓</span>
|
| 625 |
+
<span>ابحث عن <strong>Auto-Guardian Scan & Deploy</strong></span>
|
| 626 |
+
</li>
|
| 627 |
+
<li>
|
| 628 |
+
<span class="check-icon">✓</span>
|
| 629 |
+
<span>انقر على <strong>Enable workflow</strong> إذا كان معطلاً</span>
|
| 630 |
+
</li>
|
| 631 |
+
</div>
|
| 632 |
+
</div>
|
| 633 |
+
</div>
|
| 634 |
+
|
| 635 |
+
<!-- Step 5 -->
|
| 636 |
+
<div class="step" id="step5">
|
| 637 |
+
<div class="step-number">5</div>
|
| 638 |
+
<div class="step-content">
|
| 639 |
+
<h3 class="step-title">اختبار النظام</h3>
|
| 640 |
+
<p class="step-description">
|
| 641 |
+
للاختبار، قم بدفع أي تغيير بسيط إلى المستودع. سير العمل سيبدأ تلقائياً وسيتم نشر لوحة التحكم بعد اكتمال الفحص.
|
| 642 |
+
</p>
|
| 643 |
+
<div class="step-checklist">
|
| 644 |
+
<li>
|
| 645 |
+
<span class="check-icon">✓</span>
|
| 646 |
+
<span>أنشئ ملفاً جديداً أو عدل ملفاً موجوداً</span>
|
| 647 |
+
</li>
|
| 648 |
+
<li>
|
| 649 |
+
<span class="check-icon">✓</span>
|
| 650 |
+
<span>ادفع التغييرات: <code>git add . && git commit -m "test" && git push</code></span>
|
| 651 |
+
</li>
|
| 652 |
+
<li>
|
| 653 |
+
<span class="check-icon">✓</span>
|
| 654 |
+
<span>تحقق من تبويب <strong>Actions</strong> لرؤية تقدم الفحص</span>
|
| 655 |
+
</li>
|
| 656 |
+
<li>
|
| 657 |
+
<span class="check-icon">✓</span>
|
| 658 |
+
<span>بعد اكتمال الفحص، اذهب إلى <strong>Settings > Pages</strong> للحصول على الرابط</span>
|
| 659 |
+
</li>
|
| 660 |
+
</div>
|
| 661 |
+
</div>
|
| 662 |
+
</div>
|
| 663 |
+
</div>
|
| 664 |
+
</section>
|
| 665 |
+
|
| 666 |
+
<!-- File Structure Section -->
|
| 667 |
+
<section class="structure-section">
|
| 668 |
+
<div class="section-header">
|
| 669 |
+
<h2 class="section-title">هيكل الملفات</h2>
|
| 670 |
+
<p class="section-subtitle">تأكد من أن جميع الملفات موجودة في الأماكن الصحيحة</p>
|
| 671 |
+
</div>
|
| 672 |
+
|
| 673 |
+
<div class="tree-container">
|
| 674 |
+
<pre class="tree">
|
| 675 |
+
<span class="tree-line"><span class="tree-folder">📁</span> auto-guardian/
|
| 676 |
+
<span class="tree-line"> 📁 <span class="tree-folder">.github/</span>
|
| 677 |
+
<span class="tree-line"> 📁 workflows/
|
| 678 |
+
<span class="tree-badge">NEW</span> 📄 scan-and-deploy.yml</span>
|
| 679 |
+
<span class="tree-line"> 📁 <span class="tree-folder">dashboard/</span>
|
| 680 |
+
<span class="tree-line"> 📄 index.html</span>
|
| 681 |
+
<span class="tree-line"> 📁 <span class="tree-folder">public/</span>
|
| 682 |
+
<span class="tree-line"> 📁 <span class="tree-folder">data/</span>
|
| 683 |
+
<span class="tree-line"> 📄 latest.json</span>
|
| 684 |
+
<span class="tree-line"> 📁 <span class="tree-folder">scripts/</span>
|
| 685 |
+
<span class="tree-badge">NEW</span> 📄 aggregate_results.py
|
| 686 |
+
<span class="tree-line"> 📄 generate_report.py</span>
|
| 687 |
+
<span class="tree-line"> 📄 README.md</span></pre>
|
| 688 |
+
</div>
|
| 689 |
+
</section>
|
| 690 |
+
|
| 691 |
+
<!-- Features Section -->
|
| 692 |
+
<section class="features-section">
|
| 693 |
+
<div class="section-header">
|
| 694 |
+
<h2 class="section-title">مميزات النظام</h2>
|
| 695 |
+
<p class="section-subtitle">كل ما يقدمه لك نظام Auto-Guardian</p>
|
| 696 |
+
</div>
|
| 697 |
+
|
| 698 |
+
<div class="features-grid">
|
| 699 |
+
<div class="feature-card">
|
| 700 |
+
<div class="feature-icon security">🛡️</div>
|
| 701 |
+
<h3 class="feature-title">فحص أمني شامل</h3>
|
| 702 |
+
<p class="feature-description">
|
| 703 |
+
يكتشف الثغرات الأمنية والأخطاء البرمجية باستخدام أدوات متخصصة لكل لغة برمجية.
|
| 704 |
+
</p>
|
| 705 |
+
</div>
|
| 706 |
+
|
| 707 |
+
<div class="feature-card">
|
| 708 |
+
<div class="feature-icon auto">⚡</div>
|
| 709 |
+
<h3 class="feature-title">فحص تلقائي</h3>
|
| 710 |
+
<p class="feature-description">
|
| 711 |
+
يبدأ الفحص تلقائياً عند كل دفع للكود، ولا تحتاج لأي تدخل يدوي.
|
| 712 |
+
</p>
|
| 713 |
+
</div>
|
| 714 |
+
|
| 715 |
+
<div class="feature-card">
|
| 716 |
+
<div class="feature-icon dashboard">📊</div>
|
| 717 |
+
<h3 class="feature-title">لوحة تحكم تفاعلية</h3>
|
| 718 |
+
<p class="feature-description">
|
| 719 |
+
واجهة جميلة وسهلة الاستخ��ام تعرض حالة الأمان بشكل واضح ومباشر.
|
| 720 |
+
</p>
|
| 721 |
+
</div>
|
| 722 |
+
|
| 723 |
+
<div class="feature-card">
|
| 724 |
+
<div class="feature-icon multi">🌐</div>
|
| 725 |
+
<h3 class="feature-title">دعم لغات متعددة</h3>
|
| 726 |
+
<p class="feature-description">
|
| 727 |
+
يدعم Python وJavaScript وTypeScript وGo وRust وغيرها من اللغات.
|
| 728 |
+
</p>
|
| 729 |
+
</div>
|
| 730 |
+
</div>
|
| 731 |
+
</section>
|
| 732 |
+
|
| 733 |
+
<!-- FAQ Section -->
|
| 734 |
+
<section class="faq-section">
|
| 735 |
+
<div class="section-header">
|
| 736 |
+
<h2 class="section-title">الأسئلة الشائعة</h2>
|
| 737 |
+
<p class="section-subtitle">إجابات على الأسئلة المتكررة</p>
|
| 738 |
+
</div>
|
| 739 |
+
|
| 740 |
+
<div class="faq-container">
|
| 741 |
+
<div class="faq-item" onclick="toggleFaq(this)">
|
| 742 |
+
<div class="faq-question">
|
| 743 |
+
<span>كم يستغرق الفحص؟</span>
|
| 744 |
+
<span class="faq-toggle">▼</span>
|
| 745 |
+
</div>
|
| 746 |
+
<div class="faq-answer">
|
| 747 |
+
يعتمد وقت الفحص على حجم المشروع. للمشاريع الصغيرة (أقل من 100 ملف) يستغرق عادة من 2 إلى 5 دقائق. للمشاريع الكبيرة قد يستغرق حتى 15 دقيقة.
|
| 748 |
+
</div>
|
| 749 |
+
</div>
|
| 750 |
+
|
| 751 |
+
<div class="faq-item" onclick="toggleFaq(this)">
|
| 752 |
+
<div class="faq-question">
|
| 753 |
+
<span>هل يمكنني استخدام النظام في مستودع خاص؟</span>
|
| 754 |
+
<span class="faq-toggle">▼</span>
|
| 755 |
+
</div>
|
| 756 |
+
<div class="faq-answer">
|
| 757 |
+
نعم، يمكنك استخدام النظام في المستودعات الخاصة. لكن إذا كنت تريد GitHub Pages عام، ستحتاج إلى خطة GitHub مدفوعة.
|
| 758 |
+
</div>
|
| 759 |
+
</div>
|
| 760 |
+
|
| 761 |
+
<div class="faq-item" onclick="toggleFaq(this)">
|
| 762 |
+
<div class="faq-question">
|
| 763 |
+
<span>ماذا يعني درجة الأمان؟</span>
|
| 764 |
+
<span class="faq-toggle">▼</span>
|
| 765 |
+
</div>
|
| 766 |
+
<div class="faq-answer">
|
| 767 |
+
درجة الأمان هي رقم من 0 إلى 100. الدرجة A (90-100) تعني مستوى ممتاز، بينما F (أقل من 60) تعني وجود مشاكل حرجة تحتاج اهتماماً فورياً.
|
| 768 |
+
</div>
|
| 769 |
+
</div>
|
| 770 |
+
|
| 771 |
+
<div class="faq-item" onclick="toggleFaq(this)">
|
| 772 |
+
<div class="faq-question">
|
| 773 |
+
<span>هل يمكنني تخصيص أدوات الفحص؟</span>
|
| 774 |
+
<span class="faq-toggle">▼</span>
|
| 775 |
+
</div>
|
| 776 |
+
<div class="faq-answer">
|
| 777 |
+
نعم، يمكنك تعديل ملف سير العمل لإضافة أو إزالة أدوات الفحص، أو تخصيص إعدادات كل أداة من خلال ملفات الإعدادات الخاصة بها.
|
| 778 |
+
</div>
|
| 779 |
+
</div>
|
| 780 |
+
</div>
|
| 781 |
+
</section>
|
| 782 |
+
|
| 783 |
+
<!-- Footer -->
|
| 784 |
+
<footer class="footer">
|
| 785 |
+
<p class="footer-text">
|
| 786 |
+
صنع بـ ❤️ بواسطة Auto-Guardian Team |
|
| 787 |
+
<a href="#" style="color: var(--accent-blue);">التوثيق</a> |
|
| 788 |
+
<a href="#" style="color: var(--accent-blue);">الإبلاغ عن مشكلة</a>
|
| 789 |
+
</p>
|
| 790 |
+
</footer>
|
| 791 |
+
|
| 792 |
+
<script>
|
| 793 |
+
// FAQ Toggle
|
| 794 |
+
function toggleFaq(element) {
|
| 795 |
+
element.classList.toggle('open');
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
// Scroll to section
|
| 799 |
+
function scrollToSection(sectionId) {
|
| 800 |
+
document.getElementById(sectionId).scrollIntoView({
|
| 801 |
+
behavior: 'smooth'
|
| 802 |
+
});
|
| 803 |
+
}
|
| 804 |
+
|
| 805 |
+
// Animate steps on scroll
|
| 806 |
+
const observer = new IntersectionObserver((entries) => {
|
| 807 |
+
entries.forEach(entry => {
|
| 808 |
+
if (entry.isIntersecting) {
|
| 809 |
+
entry.target.style.opacity = '1';
|
| 810 |
+
}
|
| 811 |
+
});
|
| 812 |
+
}, { threshold: 0.1 });
|
| 813 |
+
|
| 814 |
+
document.querySelectorAll('.step').forEach(step => {
|
| 815 |
+
observer.observe(step);
|
| 816 |
+
});
|
| 817 |
+
|
| 818 |
+
// Welcome message
|
| 819 |
+
console.log('%c مرحباً بك في Auto-Guardian! 🎉', 'font-size: 20px; font-weight: bold; color: #3b82f6;');
|
| 820 |
+
console.log('%c نظام الفحص الأمني التلقائي للكود', 'font-size: 14px; color: #64748b;');
|
| 821 |
+
</script>
|
| 822 |
+
</body>
|
| 823 |
+
</html>
|