Update: 2026-06-26 17:29:23

This commit is contained in:
Hamza-Ayed
2026-06-26 17:29:23 +03:00
parent a323da29aa
commit 9ded734e38
139 changed files with 1815 additions and 2676 deletions

View File

@@ -1,63 +0,0 @@
<?php
/**
* Admin/Staff/add_super_admin.php
* إضافة مشرف عام (Super Admin) — استخدام لمرة واحدة
*/
require_once __DIR__ . '/../../core/bootstrap.php';
// $adminKey = filterRequest('admin_key') ?? '';
// $expected = getenv('MIGRATION_ADMIN_KEY');
// if (empty($adminKey) || empty($expected) || !hash_equals($expected, $adminKey)) {
// http_response_code(403);
// exit(json_encode(['error' => 'Access denied. Admin key required.']));
// }
$con = Database::get('main');
$name = $_GET['name'] ?? filterRequest('name') ?: 'Super Admin';
$email = $_GET['email'] ?? filterRequest('email') ?: '';
$phone = $_GET['phone'] ?? filterRequest('phone') ?: '';
$fingerprint = $_GET['fingerprint'] ?? filterRequest('fingerprint') ?: '';
$password = $_GET['password'] ?? filterRequest('password') ?: bin2hex(random_bytes(8));
try {
$hashedPass = password_hash($password, PASSWORD_DEFAULT);
$encName = $encryptionHelper->encryptData($name);
$encPhone = $phone ? $encryptionHelper->encryptData($phone) : '';
$encEmail = $email ? $encryptionHelper->encryptData($email) : '';
$encFp = $fingerprint ? $encryptionHelper->encryptData($fingerprint) : '';
$fpHash = $fingerprint ? hash('sha256', $fingerprint) : '';
$uniqueId = bin2hex(random_bytes(16));
$check = $con->prepare("SELECT id FROM adminUser WHERE role = 'super_admin' LIMIT 1");
$check->execute();
if ($check->fetch()) {
echo "<h2>⚠️ Super Admin already exists.</h2>";
exit;
}
$sql = "INSERT INTO adminUser (id, fingerprint, fingerprint_hash, name, phone, email, password, role, created_at)
VALUES (:id, :fp, :fp_hash, :name, :phone, :email, :pass, 'super_admin', NOW())";
$stmt = $con->prepare($sql);
$stmt->execute([
':id' => $uniqueId,
':fp' => $encFp,
':fp_hash' => $fpHash,
':name' => $encName,
':phone' => $encPhone,
':email' => $encEmail,
':pass' => $hashedPass,
]);
if ($stmt->rowCount() > 0) {
echo "<h2>✅ Super Admin created successfully!</h2>";
echo "<p><b>ID:</b> $uniqueId</p>";
echo "<p><b>Name:</b> $name</p>";
echo "<p><b>Password:</b> $password</p>";
echo "<p style='color:red;'><b>⚠️ Save this password. Delete this file after use.</b></p>";
} else {
echo "<h2>❌ Failed to create Super Admin.</h2>";
}
} catch (Exception $e) {
echo "<h2>❌ Error: " . htmlspecialchars($e->getMessage()) . "</h2>";
}

View File

@@ -7,7 +7,6 @@ error_reporting(E_ALL);
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$invoiceNumber = filterRequest("invoiceNumber");
$amount = filterRequest("amount");
$date = filterRequest("date");
@@ -17,7 +16,7 @@ $linkImage = null;
$uploadDate = date("Y-m-d H:i:s");
// ✅ طباعة بيانات الإدخال للتأكد
error_log("[add_invoice.php] 📥 Data received | driverID: $driverID, invoiceNumber: $invoiceNumber, amount: $amount, date: $date");
error_log("[add_invoice.php] 📥 Data received | invoiceNumber: $invoiceNumber, amount: $amount, date: $date");
// التحقق من وجود ملف الصورة
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
@@ -43,7 +42,7 @@ if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
exit;
}
$new_filename = $invoiceNumber . "_" . $driverID . '.' . $image_extension;
$new_filename = $invoiceNumber . '.' . $image_extension;
$target_dir = "invoice_images/";
$target_file = $target_dir . $new_filename;
@@ -66,9 +65,9 @@ if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
}
try {
$stmt = $con->prepare("INSERT INTO invoice_records (driverID, invoice_number,name, amount, date, image_link, created_at)
VALUES (?, ?, ?,?, ?, ?, ?)");
$stmt->execute([$driverID, $invoiceNumber,$name, $amount, $date, $linkImage, $uploadDate]);
$stmt = $con->prepare("INSERT INTO invoice_records (invoice_number, name, amount, date, image_link, created_at)
VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$invoiceNumber, $name, $amount, $date, $linkImage, $uploadDate]);
echo json_encode([
'status' => 'success',

View File

@@ -1,28 +0,0 @@
<?php
require_once __DIR__ . '/../../core/bootstrap.php';
try {
$con = Database::get('main');
// Check if columns already exist to avoid errors
$check = $con->query("SHOW COLUMNS FROM adminUser LIKE 'status'");
if ($check->rowCount() == 0) {
$sql = "ALTER TABLE adminUser
ADD COLUMN status ENUM('pending', 'approved', 'suspended', 'rejected') NOT NULL DEFAULT 'pending' AFTER role,
ADD COLUMN phone VARCHAR(50) DEFAULT NULL AFTER name,
ADD COLUMN email VARCHAR(255) DEFAULT NULL AFTER phone,
ADD COLUMN approved_by VARCHAR(64) DEFAULT NULL AFTER status,
ADD COLUMN approved_at DATETIME DEFAULT NULL AFTER approved_by";
$con->exec($sql);
// Update existing admins to approved and super_admin
$con->exec("UPDATE adminUser SET status = 'approved', role = 'super_admin' WHERE id IS NOT NULL");
echo json_encode(["status" => "success", "message" => "Migration completed successfully."]);
} else {
echo json_encode(["status" => "success", "message" => "Columns already exist."]);
}
} catch (Exception $e) {
echo json_encode(["status" => "error", "message" => "An internal error occurred"]);
}

View File

@@ -1,128 +0,0 @@
<?php
// ============================================================
// Admin/auth/migration_cryptography.php
// سكريبت لترحيل التشفير القديم (CBC) إلى التشفير الجديد (AES-256-GCM)
// يمكن تشغيله عبر الـ CLI أو المتصفح (بصلاحيات مسؤول).
// ============================================================
require_once __DIR__ . '/../../connect.php';
echo "Starting Cryptography Migration to AES-256-GCM...\n";
ob_flush(); flush();
$tables = [
'driver' => [
'phone', 'email', 'gender', 'birthdate', 'site',
'first_name', 'last_name', 'accountBank', 'education',
'employmentType', 'maritalStatus', 'national_number',
'name_arabic', 'address'
],
'passengers' => [
'phone', 'email', 'gender', 'birthdate',
'first_name', 'last_name', 'token'
],
'CarRegistration' => [
'vin', 'car_plate', 'owner', 'address'
],
'carPlateEdit' => [
'carPlate', 'owner'
],
'phone_verification' => [
'phone_number'
],
'phone_verification_passenger' => [
'phone_number'
],
'driverToken' => [
'token'
],
'passengerToken' => [
'token'
],
'mishwari' => [
'phone', 'gender', 'name', 'name_english', 'car_plate', 'token', 'education', 'national_number', 'age'
],
'rate_app' => [
'email', 'phone'
],
'admins' => [
'name', 'phone', 'email', 'fp'
],
'driver_assurance' => [
'assured', 'health_insurance_provider'
],
'blacklist_drivers' => [
'phone'
],
'blacklist_passengers' => [
'phone'
],
'feedBack' => [
'feedBack'
]
];
$totalUpdated = 0;
foreach ($tables as $table => $columns) {
echo "Processing table: $table ...\n";
ob_flush(); flush();
try {
$sql = "SELECT `id`, `" . implode("`, `", $columns) . "` FROM `$table`";
$stmt = $con->query($sql);
if (!$stmt) {
echo "Skipped $table (Not found or missing columns).\n";
continue;
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
echo "An internal error occurred" . "\n";
continue;
}
$tableUpdatedCount = 0;
foreach ($rows as $row) {
$id = $row['id'];
$needsUpdate = false;
$updateValues = [];
$params = [':id' => $id];
foreach ($columns as $col) {
$value = $row[$col];
// تحقق إذا كان الحقل يحتوي على قيمة وإذا لم يكن مشفر بالنظام الجديد
if (!empty($value) && strpos($value, 'GCM:') !== 0) {
// محاولة فك التشفير القديم (CBC)
try {
$decrypted = $encryptionHelper->decryptData($value);
if ($decrypted !== false && $decrypted !== '') {
// إعادة التشفير (سيستخدم GCM الآن)
$newEncrypted = $encryptionHelper->encryptData($decrypted);
$updateValues[] = "`$col` = :$col";
$params[":$col"] = $newEncrypted;
$needsUpdate = true;
}
} catch (Exception $e) {
error_log("Failed to migrate $col for ID $id in $table: " . $e->getMessage());
}
}
}
if ($needsUpdate) {
$setClause = implode(", ", $updateValues);
$updateSql = "UPDATE `$table` SET $setClause WHERE `id` = :id";
$updateStmt = $con->prepare($updateSql);
$updateStmt->execute($params);
$tableUpdatedCount++;
}
}
echo "Finished $table. Updated rows: $tableUpdatedCount\n";
$totalUpdated += $tableUpdatedCount;
ob_flush(); flush();
}
echo "Migration completed! Total rows updated: $totalUpdated\n";
?>

View File

@@ -30,7 +30,7 @@ class SiroGeminiService {
float $siroBasePrice,
string $regionName,
string $countryCode,
string $model = 'gemini-1.5-flash'
string $model = 'gemini-flash-lite-latest'
): ?array {
if (!$this->apiKey) {
error_log("[SiroGeminiService] API Key is missing.");

View File

@@ -1,38 +0,0 @@
<?php
header('Content-Type: text/plain; charset=UTF-8');
require_once __DIR__ . '/core/bootstrap.php';
echo "--- 🔍 SIRO FINGERPRINT DIAGNOSTIC TOOL ---\n\n";
try {
$con = Database::get('main');
echo "✅ Database connection successful.\n";
} catch (Exception $e) {
echo "❌ Database connection failed: " . $e->getMessage() . "\n";
exit;
}
$targetId = 'e494c5750f95e1c26654';
echo "Target Passenger ID: " . $targetId . "\n\n";
try {
$stmt = $con->prepare("SELECT * FROM tokens WHERE passengerID = ? LIMIT 1");
$stmt->execute([$targetId]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
echo "✅ Token row found:\n";
echo " - Passenger ID: " . $row['passengerID'] . "\n";
echo " - Token (encrypted/raw): " . $row['token'] . "\n";
echo " - Fingerprint (stored): " . $row['fingerprint'] . "\n";
$decryptedToken = $encryptionHelper->decryptData($row['token']);
echo " - Decrypted Token: " . $decryptedToken . "\n";
$fpPepper = getenv('FP_PEPPER') ?: '';
echo " - FP_PEPPER: " . ($fpPepper ? "Set" : "Not Set") . "\n";
} else {
echo "❌ No token row found for passenger!\n";
}
} catch (Exception $e) {
echo "❌ Error: " . $e->getMessage() . "\n";
}

View File

@@ -1,94 +0,0 @@
<?php
header('Content-Type: text/plain; charset=UTF-8');
require_once __DIR__ . '/core/bootstrap.php';
echo "--- 🔍 SIRO LOGIN DIAGNOSTIC TOOL ---\n\n";
try {
$con = Database::get('main');
echo "✅ Database connection successful.\n";
} catch (Exception $e) {
echo "❌ Database connection failed: " . $e->getMessage() . "\n";
exit;
}
$targetId = 'e494c5750f95e1c26654';
echo "Target Passenger ID: " . $targetId . "\n\n";
// 1. Check passengers table
try {
$stmt = $con->prepare("SELECT * FROM passengers WHERE id = ?");
$stmt->execute([$targetId]);
$p = $stmt->fetch(PDO::FETCH_ASSOC);
if ($p) {
echo "✅ Passenger found in database:\n";
echo " - Phone (encrypted): " . $p['phone'] . "\n";
echo " - Phone (decrypted): " . $encryptionHelper->decryptData($p['phone']) . "\n";
echo " - First Name (decrypted): " . $encryptionHelper->decryptData($p['first_name']) . "\n";
echo " - Last Name (decrypted): " . $encryptionHelper->decryptData($p['last_name']) . "\n";
} else {
echo "❌ Passenger NOT found in database!\n";
}
} catch (Exception $e) {
echo "❌ Error querying passengers table: " . $e->getMessage() . "\n";
}
// 2. Check phone_verification_passenger table
try {
$decryptedPhone = '962798583052';
$encryptedPhone = $encryptionHelper->encryptData($decryptedPhone);
echo "\nSearching phone_verification_passenger for: $decryptedPhone ($encryptedPhone)\n";
$stmt = $con->prepare("SELECT * FROM phone_verification_passenger WHERE phone_number = ?");
$stmt->execute([$encryptedPhone]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($rows)) {
echo "✅ Phone verification rows found (" . count($rows) . "):\n";
foreach ($rows as $row) {
echo " - ID: " . $row['id'] . " | Verified: " . $row['verified'] . " | Expiration: " . $row['expiration_time'] . " | Created At: " . $row['created_at'] . "\n";
}
} else {
echo "❌ No phone verification rows found for this phone number!\n";
// Let's get any recent rows
$stmt2 = $con->prepare("SELECT * FROM phone_verification_passenger ORDER BY id DESC LIMIT 5");
$stmt2->execute();
$all = $stmt2->fetchAll(PDO::FETCH_ASSOC);
echo " Recent rows in table:\n";
foreach ($all as $row) {
$dec = $encryptionHelper->decryptData($row['phone_number']);
echo " - ID: " . $row['id'] . " | Phone (decrypted): $dec | Verified: " . $row['verified'] . "\n";
}
}
} catch (Exception $e) {
echo "❌ Error querying phone_verification_passenger: " . $e->getMessage() . "\n";
}
// 3. Test the exact SQL query from loginFromGooglePassenger.php
echo "\n--- 🧪 Testing loginFromGooglePassenger query (WITH verified = 1 constraint) ---\n";
try {
$sqlOld = "SELECT p.`id` FROM passengers p
LEFT JOIN phone_verification_passenger ON phone_verification_passenger.phone_number = p.phone
WHERE p.id = :id AND phone_verification_passenger.verified = '1'";
$stmt = $con->prepare($sqlOld);
$stmt->execute([':id' => $targetId]);
$count = $stmt->rowCount();
echo "Old query row count: $count\n";
} catch (Exception $e) {
echo "Old query error: " . $e->getMessage() . "\n";
}
echo "\n--- 🧪 Testing loginFromGooglePassenger query (WITHOUT verified = 1 constraint) ---\n";
try {
$sqlNew = "SELECT p.`id` FROM passengers p
LEFT JOIN phone_verification_passenger ON phone_verification_passenger.phone_number = p.phone
WHERE p.id = :id";
$stmt = $con->prepare($sqlNew);
$stmt->execute([':id' => $targetId]);
$count = $stmt->rowCount();
echo "New query row count: $count\n";
} catch (Exception $e) {
echo "New query error: " . $e->getMessage() . "\n";
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +0,0 @@
<?php
// migrate_driver_passwords.php
// سكربت لمرة واحدة لإعادة توليد كلمة السر لكل السائقين
// المعادلة: baseString = id | normalizedPhone | [national_number OR birthYear]
// السر: hmacHex = hash_hmac('sha256', baseString, SECRET_KEY_HMAC, false)
// المخزن في DB: password_hash(hmacHex)
set_time_limit(0); // منع انتهاء المهلة أثناء المايغريشن
ini_set('memory_limit', '512M');
require_once realpath(__DIR__ . '/../vendor/autoload.php');
require_once 'load_env.php';
$env_file = getenv('ENV_FILE_PATH') ?: (__DIR__ . '/../../../env/.env');
loadEnvironment($env_file);
include "encrypt_decrypt.php"; // لاستخدام $encryptionHelper
$dbUser = getenv('USER');
$dbPass = getenv('PASS');
$dbname = getenv('dbname');
$pepper = getenv('SECRET_KEY_HMAC');
if ($dbUser === false || $dbPass === false || $dbname === false || $pepper === false) {
error_log("[MIGRATE] Missing env vars (USER/PASS/dbname/SECRET_KEY_HMAC). Abort.");
exit(1);
}
try {
$dsn = "mysql:host=localhost;dbname={$dbname};charset=utf8mb4";
$options = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8",
];
$pdo = new PDO($dsn, $dbUser, $dbPass, $options);
// نجلب الحقول التي نحتاجها لبناء السر
$sql = "SELECT id, phone, birthdate, national_number FROM driver";
$stmt = $pdo->query($sql);
$update = $pdo->prepare("UPDATE driver SET password = :pwd WHERE id = :id");
$count = 0;
$skipped = 0;
$startTime = microtime(true);
while ($row = $stmt->fetch()) {
$id = $row['id'];
$encPhone = $row['phone'];
$encBirth = $row['birthdate'] ?? null;
$encNat = $row['national_number'] ?? null;
// نفك التشفير قد يرجع null لو الحقل فاضي
$phone = $encPhone ? $encryptionHelper->decryptData($encPhone) : null;
$birth = $encBirth ? $encryptionHelper->decryptData($encBirth) : null;
$nat = $encNat ? $encryptionHelper->decryptData($encNat) : null;
if (empty($id) || empty($phone)) {
// لو ناقصين، نتجاوز السطر مع تسجيل في اللوج
error_log("[MIGRATE] Skip driver id={$id}: missing phone or id.");
$skipped++;
continue;
}
// في الوضع المثالي عندك nat + birthdate لكل السائقين
// لو حاب تجبرهم يكونوا موجودين:
/*
if (empty($nat) || empty($birth)) {
error_log("[MIGRATE] Skip driver id={$id}: missing nat or birthdate.");
$skipped++;
continue;
}
*/
// phone مفروض يكون أصلاً مطبّع (9639...) من سكربت التسجيل
$normalizedPhone = trim($phone);
// نبني baseString: الأساس id + phone
$parts = [$id, $normalizedPhone];
// نضيف رقم وطني أو سنة الميلاد (حسب الموجود)
if (!empty($nat)) {
$parts[] = trim($nat);
} elseif (!empty($birth)) {
// birthdate متوقعة بصيغة YYYY-01-01 -> نأخذ السنة فقط
$year = substr($birth, 0, 4);
if (preg_match('/^\d{4}$/', $year)) {
$parts[] = $year;
}
}
$baseString = implode('|', $parts);
// اشتقاق السر النهائي (HEX string، بدون باينري)
$hmacHex = hash_hmac('sha256', $baseString, $pepper, false);
// نخزن فقط الهاش باستخدام password_hash
$pwdHash = password_hash($hmacHex, PASSWORD_DEFAULT);
$update->execute([
':pwd' => $pwdHash,
':id' => $id,
]);
$count++;
// لوج بسيط كل 100 سائق
if ($count % 100 === 0) {
$elapsed = round(microtime(true) - $startTime, 2);
error_log("[MIGRATE] Progress: updated {$count} drivers, skipped {$skipped}, elapsed {$elapsed}s");
}
}
$totalTime = round(microtime(true) - $startTime, 2);
error_log("[MIGRATE] Done. Updated {$count} driver passwords, skipped {$skipped}. Total time: {$totalTime}s");
echo "Migration finished. Updated {$count} drivers, skipped {$skipped}. Time: {$totalTime}s\n";
} catch (PDOException $e) {
error_log("[MIGRATE][PDO] " . $e->getMessage());
echo "Migration failed (DB error).\n";
exit(1);
} catch (Exception $e) {
error_log("[MIGRATE][GENERAL] " . $e->getMessage());
echo "Migration failed (general error).\n";
exit(1);
}

View File

@@ -1,21 +0,0 @@
<?php
require_once __DIR__ . '/core/bootstrap.php';
try {
$con = Database::get('main');
$sql = "CREATE TABLE IF NOT EXISTS `passenger_opening_locations` (
`id` int NOT NULL AUTO_INCREMENT,
`passenger_id` varchar(100) NOT NULL,
`latitude` varchar(30) NOT NULL,
`longitude` varchar(30) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_passenger_id` (`passenger_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
$con->exec($sql);
echo "SUCCESS: passenger_opening_locations table created successfully.\n";
} catch (Exception $e) {
echo "An internal error occurred" . "\n";
}
?>

View File

@@ -1,210 +0,0 @@
<?php
/**
* test_add_driver_and_car.php
* ===========================
* يضيف سائق + سيارته في قاعدة البيانات مباشرة (لأغراض الاختبار).
* يستخدم نفس التشفير ونظام إدارة الهوية مثل الإنتاج.
*
* الاستخدام:
* https://example.com/backend/test_add_driver_and_car.php?phone=96279xxxxxxx&password=1234&first_name=Ahmed&last_name=Ali&make=Hyundai&model=Elantra&year=2020&car_plate=1234&color=White
*
* جميع الحقول الاختيارية لها قيمة افتراضية.
*/
require_once __DIR__ . '/core/bootstrap.php';
header('Content-Type: application/json; charset=utf-8');
// دمج GET + POST + JSON body
$rawBody = file_get_contents('php://input');
$json = $rawBody ? json_decode($rawBody, true) : [];
$_POST = array_merge($_GET, $_POST, $json ?: []);
try {
/* ================== قراءة المدخلات ================== */
$phone = filterRequest('phone');
$password = filterRequest('password');
$first_name = filterRequest('first_name');
$last_name = filterRequest('last_name');
if (empty($phone) || empty($password) || empty($first_name) || empty($last_name)) {
jsonError('Required: phone, password, first_name, last_name');
exit;
}
// توحيد الرقم (إزالة +/مسافات)
$phone = preg_replace('/[ \-\(\)\+]/', '', $phone);
// حقول السائق الاختيارية
$email = filterRequest('email') ?: $phone . '@intaleqapp.com';
$gender = filterRequest('gender') ?: 'Male';
$national_number = filterRequest('national_number') ?: '';
$birthdate = filterRequest('birthdate') ?: '1990-01-01';
$site = filterRequest('site') ?: 'testing';
$license_type = filterRequest('license_type') ?: 'private';
$employmentType = filterRequest('employmentType') ?: 'full_time';
// حقول السيارة
$make = filterRequest('make') ?: 'Toyota';
$model = filterRequest('model') ?: 'Camry';
$year = filterRequest('year') ?: '2020';
$car_plate = filterRequest('car_plate') ?: 'TEST' . random_int(100, 999);
$vin = filterRequest('vin') ?: 'VIN' . bin2hex(random_bytes(8));
$color = filterRequest('color') ?: 'White';
$color_hex = filterRequest('color_hex') ?: '#FFFFFF';
$fuel = filterRequest('fuel') ?: 'Petrol';
$owner = filterRequest('owner') ?: trim($first_name . ' ' . $last_name);
$expiration_date = filterRequest('expiration_date') ?: date('Y-m-d', strtotime('+1 year'));
/* ================== ID السائق ================== */
$driverId = 'TEST' . date('YmdHis') . random_int(1000, 9999);
/* ================== التشفير ================== */
$encPhone = $encryptionHelper->encryptData($phone);
$encEmail = $encryptionHelper->encryptData($email);
$encFirstName = $encryptionHelper->encryptData($first_name);
$encLastName = $encryptionHelper->encryptData($last_name);
$encNameArabic = $encryptionHelper->encryptData("$first_name $last_name");
$encGender = $encryptionHelper->encryptData($gender);
$encNationalNumber = $national_number ? $encryptionHelper->encryptData($national_number) : '';
$encBirthdate = $encryptionHelper->encryptData($birthdate);
$encSite = $encryptionHelper->encryptData($site);
$encOwner = $encryptionHelper->encryptData($owner);
$encCarPlate = $encryptionHelper->encryptData($car_plate);
$encVin = $encryptionHelper->encryptData($vin);
$passwordHashed = password_hash($password, PASSWORD_DEFAULT);
$con = Database::get('main');
/* ================== التحقق من التكرار ================== */
$dup = $con->prepare("SELECT id FROM driver WHERE phone = :p OR email = :e");
$dup->execute([':p' => $encPhone, ':e' => $encEmail]);
if ($dup->rowCount() > 0) {
jsonError("Phone or email already registered.");
exit;
}
$con->beginTransaction();
/* ================== 1) إدراج السائق ================== */
$sqlDriver = "
INSERT INTO driver (
id, phone, email, password, gender, license_type, national_number,
name_arabic, issue_date, expiry_date, license_categories,
address, licenseIssueDate, status, birthdate, site,
first_name, last_name, accountBank, bankCode,
employmentType, maritalStatus, fullNameMaritial, expirationDate,
created_at, updated_at
) VALUES (
:id, :phone, :email, :pwd, :gender, :license_type, :national_number,
:name_arabic, :issue_date, :expiry_date, :license_categories,
:address, :licenseIssueDate, :status, :birthdate, :site,
:first_name, :last_name, :accountBank, :bankCode,
:employmentType, :maritalStatus, :fullNameMaritial, :expirationDate,
NOW(), NOW()
)
";
$insD = $con->prepare($sqlDriver);
$insD->execute([
':id' => $driverId,
':phone' => $encPhone,
':email' => $encEmail,
':pwd' => $passwordHashed,
':gender' => $encGender,
':license_type' => $license_type,
':national_number' => $encNationalNumber,
':name_arabic' => $encNameArabic,
':issue_date' => '2020-01-01',
':expiry_date' => '2030-01-01',
':license_categories' => 'B',
':address' => $encSite,
':licenseIssueDate' => '2020-01-01',
':status' => 'pending_review',
':birthdate' => $encBirthdate,
':site' => $encSite,
':first_name' => $encFirstName,
':last_name' => $encLastName,
':accountBank' => 'yet',
':bankCode' => 'CIB',
':employmentType' => $employmentType,
':maritalStatus' => 'Single',
':fullNameMaritial' => '',
':expirationDate' => date('Y-m-d', strtotime('+5 years')),
]);
/* ================== 2) إدراج السيارة ================== */
$sqlCar = "
INSERT INTO CarRegistration (
driverID, vin, car_plate, make, model, year, expiration_date,
color, owner, color_hex, fuel,
vehicle_category_id, fuel_type_id,
isDefault, created_at, status
) VALUES (
:driverID, :vin, :car_plate, :make, :model, :year, :expiration_date,
:color, :owner, :color_hex, :fuel,
:vehicle_category_id, :fuel_type_id,
:isDefault, NOW(), 'active'
)
";
$insC = $con->prepare($sqlCar);
$insC->execute([
':driverID' => $driverId,
':vin' => $encVin,
':car_plate' => $encCarPlate,
':make' => $make,
':model' => $model,
':year' => $year,
':expiration_date' => $expiration_date,
':color' => $color,
':owner' => $encOwner,
':color_hex' => $color_hex,
':fuel' => $fuel,
':vehicle_category_id' => 1,
':fuel_type_id' => 1,
':isDefault' => 1,
]);
$carRegID = $con->lastInsertId();
/* ================== 3) توكن السائق ================== */
$token = bin2hex(random_bytes(20));
$sqlToken = "
INSERT INTO driverToken (token, captain_id, fingerPrint, created_at)
VALUES (:token, :captain_id, :fingerPrint, NOW())
";
$con->prepare($sqlToken)->execute([
':token' => $token,
':captain_id' => $driverId,
':fingerPrint' => 'test_fingerprint',
]);
/* ================== 4) توثيق رقم الهاتف ================== */
$sqlPhoneVer = "
INSERT INTO phone_verification (phone_number, driverId, email, token_code, expiration_time, is_verified, created_at)
VALUES (:phone, :driverId, :email, :token_code, DATE_ADD(NOW(), INTERVAL 1 YEAR), 1, NOW())
";
$con->prepare($sqlPhoneVer)->execute([
':phone' => $encPhone,
':driverId' => $driverId,
':email' => $encEmail,
':token_code' => $encryptionHelper->encryptData('999'),
]);
/* ================== Commit ================== */
$con->commit();
printSuccess([
'driverID' => $driverId,
'carRegID' => $carRegID,
'status' => 'success',
'message' => "Driver $first_name $last_name created successfully with status pending_review.",
]);
} catch (Exception $e) {
if (isset($con) && $con instanceof PDO && $con->inTransaction()) {
$con->rollBack();
}
error_log("[test_add_driver] " . $e->getMessage());
jsonError($e->getMessage());
}

View File

@@ -1,94 +0,0 @@
<?php
// test_signed_pricing.php
// Mock parameters and verify price token generation and booking verification.
define('TESTING_BYPASS_AUTH', true);
// Set mock POST parameters for pricing estimation
$_POST['distance'] = "10.5";
$_POST['durationToRide'] = "1200"; // 20 minutes
$_POST['passenger_id'] = "12345";
$_POST['country'] = "Syria";
$_POST['passengerLat'] = "33.5138";
$_POST['passengerLng'] = "36.2765";
$_POST['destLat'] = "33.5200";
$_POST['destLng'] = "36.2800";
$_POST['startNameAddress'] = "Malki, Damascus";
$_POST['endNameAddress'] = "Abu Rummaneh, Damascus";
$_POST['carType'] = "Speed";
echo "=== MOCKING PRICING ESTIMATION (get.php) ===\n";
ob_start();
include __DIR__ . '/ride/pricing/get.php';
$responseJson = ob_get_clean();
echo "Response received:\n" . $responseJson . "\n\n";
$response = json_decode($responseJson, true);
if (!$response || $response['status'] !== 'success' || empty($response['price_token'])) {
echo "❌ FAILED: Pricing token was not generated successfully.\n";
exit(1);
}
$priceToken = $response['price_token'];
$estimatedPrices = $response['data'];
echo "✅ SUCCESS: Generated price_token successfully!\n";
echo "Estimated Speed price: " . $estimatedPrices['totalPassengerSpeed'] . "\n\n";
// Test 1: Valid Booking with Token
echo "=== TEST 1: Booking with authentic token and coordinates ===\n";
$_POST['start_location'] = "33.5138, 36.2765";
$_POST['end_location'] = "33.5200, 36.2800";
$_POST['price'] = "99999.00"; // Client attempts to send garbage price, server must override it!
$_POST['price_token'] = $priceToken;
$_POST['passenger_id'] = "12345";
$_POST['carType'] = "Speed";
$_POST['status'] = "waiting";
// Mock other fields for add_ride.php to prevent errors
$_POST['passenger_name'] = "Hamza";
$_POST['passenger_phone'] = "+963999999999";
$_POST['passenger_token'] = "mock_fcm_token";
$_POST['passenger_email'] = "hamza@siromove.com";
$_POST['passenger_wallet'] = "0";
$_POST['passenger_rating'] = "5.0";
$_POST['start_name'] = "Malki";
$_POST['end_name'] = "Abu Rummaneh";
$_POST['duration_text'] = "20 min";
$_POST['distance_text'] = "10.5 km";
$_POST['is_wallet'] = "false";
$_POST['has_steps'] = "false";
ob_start();
include __DIR__ . '/ride/rides/add_ride.php';
$bookingJson = ob_get_clean();
echo "Booking response:\n" . $bookingJson . "\n\n";
$bookingRes = json_decode($bookingJson, true);
if ($bookingRes && $bookingRes['status'] === 'success') {
echo "✅ TEST 1 PASSED: Booking succeeded and overrode client fare!\n";
} else {
echo "❌ TEST 1 FAILED: Booking rejected valid token.\n";
}
// Test 2: Booking with Tampered Coordinates
echo "=== TEST 2: Booking with mismatched start location coordinates ===\n";
$_POST['start_location'] = "34.5000, 36.2000"; // Changed start location
$_POST['price'] = "99999.00";
$_POST['price_token'] = $priceToken;
ob_start();
include __DIR__ . '/ride/rides/add_ride.php';
$tamperedJson = ob_get_clean();
echo "Tampered response:\n" . $tamperedJson . "\n\n";
$tamperedRes = json_decode($tamperedJson, true);
if ($tamperedRes && $tamperedRes['status'] === 'failure' && strpos($tamperedRes['message'], 'route mismatch') !== false) {
echo "✅ TEST 2 PASSED: Successfully detected coordinates mismatch and rejected booking!\n";
} else {
echo "❌ TEST 2 FAILED: Did not correctly reject mismatched coordinates.\n";
}
?>