Files
tripz-llc/ride_server/intaleq/functions.php
T
Hamza-AyedandClaude Opus 5 4d8414c96b feat: استيراد كود سيرو إلى تريبز (سيرو @ecfe7568) — بلا تعديل
قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة
ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ.

الخريطة:
  backend · payment_server · loction_server · ride_server ·
  passenger_server · docker · dashboard · stress_test  → الجذر
  siro_rider  → apps/rider          siro_driver  → apps/driver
  siro_admin  → dashboards/admin    siro_service → dashboards/service
  android_bot → apps/android_bot    socialBot    → apps/socialBot

نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب)
لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً:
كل ما يلي يصير فرقاً مقروءاً مقابل المصدر.

لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز،
سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh
(ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في
مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و
dashboards/transit-web).

⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة:
1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر):
   كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner.
2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist)
   يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً.
3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع →
   يجب ضمّ الحزم داخله أسوة بـ apps/rider.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 05:14:13 +03:00

96 lines
3.6 KiB
PHP

<?php
// ride_server/intaleq/functions.php
// Bootstrap helpers for standalone REST endpoints under ride_server/intaleq/.
// Mirrors the env/key conventions already deployed on this box for
// ride_server/passenger_socket.php (/home/intaleq-rides/...), not invented.
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
// Shared secret used to authenticate to loction_server's internal HTTP API —
// same mechanism ride_server/passenger_socket.php already uses on this box.
function getInternalSocketKey(): string {
$key = getenv('INTERNAL_SOCKET_KEY');
if ($key) return trim($key);
$path = getenv('INTERNAL_SOCKET_KEY_PATH') ?: '/home/intaleq-rides/.internal_socket_key';
if (file_exists($path)) return trim((string) @file_get_contents($path));
return '';
}
// JWT signing secret — must resolve to the same value backend's
// core/Auth/JwtService.php signs tokens with, or every token fails here.
function getJwtSecret(): string {
$keyPath = getenv('JWT_SECRET_KEY_PATH');
if ($keyPath && file_exists($keyPath)) {
return trim(file_get_contents($keyPath));
}
return getenv('JWT_SECRET_KEY') ?: '';
}
function authenticateJWT() {
$secretKey = getJwtSecret();
if (!$secretKey) {
error_log("[ride_server] JWT secret not configured.");
http_response_code(500);
echo json_encode(['status' => 'failure', 'message' => 'Internal server configuration error.']);
exit;
}
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$token = null;
if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
$token = $matches[1];
}
if (!$token) {
http_response_code(401);
echo json_encode(['status' => 'failure', 'message' => 'Authorization token required']);
exit;
}
try {
return JWT::decode($token, new Key($secretKey, 'HS256'));
} catch (ExpiredException $e) {
http_response_code(401);
echo json_encode(['status' => 'failure', 'message' => 'Token expired']);
exit;
} catch (SignatureInvalidException $e) {
http_response_code(401);
echo json_encode(['status' => 'failure', 'message' => 'Invalid token signature']);
exit;
} catch (BeforeValidException $e) {
http_response_code(401);
echo json_encode(['status' => 'failure', 'message' => 'Token not yet valid']);
exit;
} catch (Exception $e) {
http_response_code(401);
echo json_encode(['status' => 'failure', 'message' => 'Invalid token']);
exit;
}
// NOTE: signature/expiry only — does not replicate backend's
// core/Auth/JwtService::authenticate() JTI-blacklist (revoked-token)
// check or X-Device-FP verification. Flagged as a follow-up in the
// plan; not blocking for this read-only endpoint.
}
// Flutter's CRUD().get() always issues an HTTP POST under the hood
// (see siro_rider/lib/controller/functions/crud.dart _makeRequest/doPost) —
// so every field this endpoint reads comes through $_POST, never $_GET.
function filterRequest($requestname, $type = 'string') {
if (isset($_POST[$requestname]) && $_POST[$requestname] !== '') {
$value = trim($_POST[$requestname]);
$value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $value);
if ($type === 'numeric') {
return filter_var($value, FILTER_VALIDATE_FLOAT) !== false ? $value : null;
}
return $value;
}
return null;
}
function printFailure($message = "none") {
echo json_encode(["status" => "failure", "message" => $message]);
}