Update: 2026-06-26 17:29:23
This commit is contained in:
@@ -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>";
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
@@ -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"]);
|
||||
}
|
||||
@@ -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";
|
||||
?>
|
||||
@@ -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.");
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
?>
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user