Add Nabeh integration: nabeh/ endpoints with NABEH_API_KEY auth

This commit is contained in:
Hamza-Ayed
2026-06-17 18:22:45 +03:00
parent c2c4ed22e3
commit b67417eb98
5 changed files with 733 additions and 0 deletions

218
backend/nabeh/register.php Normal file
View File

@@ -0,0 +1,218 @@
<?php
/**
* Nabeh Integration — Driver Registration
*
* Called by Nabeh AI platform to register drivers in Siro.
* Authenticated via NABEH_API_KEY (shared between servers).
* Handles all 3 countries: Syria, Jordan, Egypt.
*/
require_once __DIR__ . '/../core/bootstrap.php';
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-API-Key');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['status' => 'failure', 'message' => 'Method not allowed']);
exit;
}
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
$expectedKey = getenv('NABEH_API_KEY') ?: '';
if (empty($apiKey) || $apiKey !== $expectedKey) {
http_response_code(401);
echo json_encode(['status' => 'failure', 'message' => 'Unauthorized: invalid API key']);
exit;
}
// Rate limiting
$rateLimitFile = __DIR__ . '/../logs/nabeh_rate_' . md5($_SERVER['REMOTE_ADDR'] ?? 'unknown') . '.lock';
$rateLimitWindow = 60;
$rateLimitMax = 5;
$now = time();
$attempts = [];
if (file_exists($rateLimitFile)) {
$attempts = json_decode(file_get_contents($rateLimitFile), true) ?: [];
$attempts = array_filter($attempts, fn($t) => $t > ($now - $rateLimitWindow));
}
if (count($attempts) >= $rateLimitMax) {
http_response_code(429);
echo json_encode(['status' => 'failure', 'message' => 'Too many requests. Try again later.']);
exit;
}
$attempts[] = $now;
file_put_contents($rateLimitFile, json_encode($attempts), LOCK_EX);
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
http_response_code(400);
echo json_encode(['status' => 'failure', 'message' => 'Invalid JSON body']);
exit;
}
$phone = preg_replace('/[^0-9]/', '', $input['phone'] ?? '');
$password = $input['password'] ?? substr(md5($phone . time()), 0, 12);
$firstName = $input['first_name'] ?? $input['name_arabic'] ?? '';
$lastName = $input['last_name'] ?? '-';
$nameArabic = $input['name_arabic'] ?? $firstName;
$nationalNumber = $input['national_number'] ?? '';
$birthdate = $input['birthdate'] ?? '';
$address = $input['address'] ?? '';
$gender = $input['gender'] ?? 'Male';
$site = $input['site'] ?? '';
$vin = $input['vin'] ?? '';
$carPlate = $input['car_plate'] ?? '';
$make = $input['make'] ?? '';
$model = $input['model'] ?? '';
$year = $input['year'] ?? '';
$color = $input['color'] ?? '';
$colorHex = $input['color_hex'] ?? '#000000';
$owner = $input['owner'] ?? '';
$fuel = $input['fuel'] ?? 'Petrol';
$expirationDate = $input['expiration_date'] ?? '';
$idFront = $input['id_front'] ?? $input['id_front_url'] ?? '';
$idBack = $input['id_back'] ?? $input['id_back_url'] ?? '';
$driverLicense = $input['driver_license'] ?? $input['driver_license_front_url'] ?? '';
$driverLicenseBack = $input['driver_license_back'] ?? $input['driver_license_back_url'] ?? '';
$carLicenseFront = $input['car_license_front'] ?? $input['vehicle_license_front_url'] ?? '';
$carLicenseBack = $input['car_license_back'] ?? $input['vehicle_license_back_url'] ?? '';
$criminalRecord = $input['criminal_record'] ?? $input['criminal_record_url'] ?? '';
$profilePicture = $input['profile_picture'] ?? '';
if (empty($phone)) {
jsonError('Phone number is required');
}
if (empty($firstName)) {
jsonError('First name is required');
}
if (empty($vin) || empty($carPlate) || empty($make) || empty($model) || empty($year)) {
jsonError('Car details (vin, plate, make, model, year) are required');
}
try {
$db = Database::get('main');
$driverId = 'DRV' . date('YmdHis') . rand(100, 999);
$hashedPassword = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
global $encryptionHelper;
$encryptedPhone = $encryptionHelper->encryptData($phone);
$encryptedFirstName = $encryptionHelper->encryptData($firstName);
$encryptedLastName = $encryptionHelper->encryptData($lastName);
$encryptedNameArabic = $encryptionHelper->encryptData($nameArabic);
$encryptedNationalNumber = !empty($nationalNumber) ? $encryptionHelper->encryptData($nationalNumber) : '';
$encryptedAddress = !empty($address) ? $encryptionHelper->encryptData($address) : '';
$encryptedGender = $encryptionHelper->encryptData($gender);
$encryptedVin = $encryptionHelper->encryptData($vin);
$encryptedCarPlate = $encryptionHelper->encryptData($carPlate);
$encryptedOwner = $encryptionHelper->encryptData($owner);
$encryptedSite = !empty($site) ? $encryptionHelper->encryptData($site) : $encryptedAddress;
$nowDate = date('Y-m-d H:i:s');
$driverStmt = $db->prepare("
INSERT INTO driver (
id, phone, email, password, gender, first_name, last_name,
name_arabic, national_number, address, site, birthdate,
status, created_at, updated_at
) VALUES (
:id, :phone, :email, :password, :gender, :first_name, :last_name,
:name_arabic, :national_number, :address, :site, :birthdate,
'yet', :created_at, :updated_at
)
");
$driverStmt->execute([
':id' => $driverId,
':phone' => $encryptedPhone,
':email' => $phone . '@intaleqapp.com',
':password' => $hashedPassword,
':gender' => $encryptedGender,
':first_name' => $encryptedFirstName,
':last_name' => $encryptedLastName,
':name_arabic' => $encryptedNameArabic,
':national_number' => $encryptedNationalNumber,
':address' => $encryptedAddress,
':site' => $encryptedSite,
':birthdate' => $birthdate,
':created_at' => $nowDate,
':updated_at' => $nowDate,
]);
$carStmt = $db->prepare("
INSERT INTO CarRegistration (
driverID, vin, car_plate, make, model, year,
expiration_date, color, owner, color_hex, fuel,
isDefault, status, created_at, vehicle_category_id
) VALUES (
:driverID, :vin, :car_plate, :make, :model, :year,
:expiration_date, :color, :owner, :color_hex, :fuel,
1, 'yet', :created_at, 1
)
");
$carStmt->execute([
':driverID' => $driverId,
':vin' => $encryptedVin,
':car_plate' => $encryptedCarPlate,
':make' => $make,
':model' => $model,
':year' => $year,
':expiration_date' => $expirationDate ?: $nowDate,
':color' => $color,
':owner' => $encryptedOwner,
':color_hex' => $colorHex,
':fuel' => $fuel,
':created_at' => $nowDate,
]);
$carRegId = $db->lastInsertId();
$docTypes = [
'id_front' => $idFront,
'id_back' => $idBack,
'driver_license' => $driverLicense,
'driver_license_back' => $driverLicenseBack,
'car_license_front' => $carLicenseFront,
'car_license_back' => $carLicenseBack,
'criminal_record' => $criminalRecord,
'profile_picture' => $profilePicture,
];
$docStmt = $db->prepare("
INSERT INTO driver_documents (driverID, doc_type, image_name, link, upload_date)
VALUES (:driverID, :doc_type, :image_name, :link, :upload_date)
");
foreach ($docTypes as $docType => $link) {
if (!empty($link)) {
$docStmt->execute([
':driverID' => $driverId,
':doc_type' => $docType,
':image_name' => $driverId . '_' . $docType,
':link' => $link,
':upload_date' => $nowDate,
]);
}
}
error_log("[Nabeh Registration] New driver registered: {$driverId}, Phone: {$phone}");
echo json_encode([
'status' => 'success',
'message' => [
'status' => 'success',
'driverID' => $driverId,
'carRegID' => $carRegId,
]
], JSON_UNESCAPED_UNICODE);
} catch (\Exception $e) {
error_log("[Nabeh Registration Error] " . $e->getMessage());
http_response_code(500);
echo json_encode([
'status' => 'failure',
'message' => 'Internal server error: ' . $e->getMessage()
]);
}