fix(security): fix login AND logic to OR, add signup input validation, separate OTP rate limit keys
This commit is contained in:
@@ -6,8 +6,23 @@ $email = filterRequest('email');
|
|||||||
$phone = filterRequest('phone');
|
$phone = filterRequest('phone');
|
||||||
$password = filterRequest('password');
|
$password = filterRequest('password');
|
||||||
|
|
||||||
// Hash the password
|
if (empty($phone) && empty($email)) {
|
||||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
echo json_encode(["status" => "Failure", "data" => "Phone or email is required."]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build WHERE dynamically: support phone-only, email-only, or both
|
||||||
|
$conditions = [];
|
||||||
|
$params = [':password' => $password];
|
||||||
|
if (!empty($phone)) {
|
||||||
|
$conditions[] = "passengers.phone = :phone";
|
||||||
|
$params[':phone'] = $phone;
|
||||||
|
}
|
||||||
|
if (!empty($email)) {
|
||||||
|
$conditions[] = "passengers.email = :email";
|
||||||
|
$params[':email'] = $email;
|
||||||
|
}
|
||||||
|
$where = implode(' OR ', $conditions);
|
||||||
|
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
passengers.`id`,
|
passengers.`id`,
|
||||||
@@ -29,11 +44,9 @@ FROM
|
|||||||
`passengers`
|
`passengers`
|
||||||
LEFT JOIN email_verifications ON email_verifications.email = passengers.email
|
LEFT JOIN email_verifications ON email_verifications.email = passengers.email
|
||||||
WHERE
|
WHERE
|
||||||
passengers.phone = :phone AND passengers.email = :email ";
|
$where";
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
$stmt->bindParam(':email', $email);
|
$stmt->execute($params);
|
||||||
$stmt->bindParam(':phone', $phone);
|
|
||||||
$stmt->execute();
|
|
||||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
$count = $stmt->rowCount();
|
$count = $stmt->rowCount();
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ require_once __DIR__ . '/../../functions.php';
|
|||||||
|
|
||||||
// 0. Rate Limiting: 3 محاولات OTP كل 5 دقائق لكل IP
|
// 0. Rate Limiting: 3 محاولات OTP كل 5 دقائق لكل IP
|
||||||
$rateLimiter = new RateLimiter($redis);
|
$rateLimiter = new RateLimiter($redis);
|
||||||
$rateLimiter->enforce(RateLimiter::identifier(), 'otp');
|
$rateLimiter->enforce(RateLimiter::identifier(), 'otp_verify');
|
||||||
|
|
||||||
// 1. Fetch input parameters
|
// 1. Fetch input parameters
|
||||||
$phone_number = filterRequest("phone_number");
|
$phone_number = filterRequest("phone_number");
|
||||||
|
|||||||
@@ -12,6 +12,24 @@ $gender = filterRequest("gender");
|
|||||||
$birthdate = filterRequest("birthdate");
|
$birthdate = filterRequest("birthdate");
|
||||||
$site = filterRequest("site");
|
$site = filterRequest("site");
|
||||||
|
|
||||||
|
// --- Input Validation ---
|
||||||
|
if (empty($phone) || strlen(preg_replace('/\D+/', '', $phone)) < 8) {
|
||||||
|
jsonError("Valid phone number is required.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
jsonError("Valid email address is required.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (empty($password) || strlen($password) < 6) {
|
||||||
|
jsonError("Password must be at least 6 characters.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (empty($first_name) || empty($last_name)) {
|
||||||
|
jsonError("First name and last name are required.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
// تشفير البيانات الحساسة
|
// تشفير البيانات الحساسة
|
||||||
$phone = $encryptionHelper->encryptData($phone);
|
$phone = $encryptionHelper->encryptData($phone);
|
||||||
$email = $encryptionHelper->encryptData($email);
|
$email = $encryptionHelper->encryptData($email);
|
||||||
|
|||||||
Reference in New Issue
Block a user