Files
Siro/backend/migrate_driver_passwords.php
Hamza-Ayed 3543fdd2cd Fix #21: High-severity fixes (H-01 through H-06)
H-01: Egypt document uploads - added path traversal prevention (basename),
       replaced HTTP_HOST with APP_DOMAIN env var
H-02: 7 remaining hardcoded /home/siro-api/ paths replaced with env vars
       (ENV_FILE_PATH, INTERNAL_SOCKET_KEY_PATH, WEBHOOK_SECRET_KEY_PATH)
H-03: serviceapp/updateDriver.php - added ownership check (user_id must match
       driverID or user must be admin); non-admins blocked from changing
       password/status/email/phone
H-04: ggg.php - replaced weak client-supplied phone auth with proper admin
       JWT authentication via JwtService
H-05: Static IV fallback in encrypt_decrypt.php already documented as legacy
H-06: Wallet shared password noted as design limitation (mitigated by
       fingerprint verification + short token TTL)
- Also fixed functions.php log message (removed hardcoded path)
2026-06-17 07:56:57 +03:00

128 lines
4.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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);
}