Add Nabeh integration: nabeh/ endpoints with NABEH_API_KEY auth
This commit is contained in:
218
backend/nabeh/register.php
Normal file
218
backend/nabeh/register.php
Normal 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()
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user