Alllplmpliedl manual JWT check and restored all driver fields68j2
This commit is contained in:
@@ -5,15 +5,24 @@ namespace App\Http\Controllers\Api;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Firebase\JWT\JWT;
|
use Firebase\JWT\JWT;
|
||||||
use Illuminate\Support\Facades\File;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PaymentTokenController — توليد رموز الدفع المتوافقة مع سيرفر المحفظة V1
|
||||||
|
*
|
||||||
|
* ⚠️ مهم جداً:
|
||||||
|
* سيرفر المحفظة (walletintaleq.intaleq.xyz) يعمل بكود V1 ويتحقق من التوكن باستخدام:
|
||||||
|
* - المفتاح: /home/intaleq-api/.secret_key (وليس PAYMENT_INTERNAL_KEY_PATH)
|
||||||
|
* - الـ Issuer: 'Tripz' أو 'Tripz-Wallet'
|
||||||
|
* - الـ Claim: user_id (وليس sub)
|
||||||
|
*
|
||||||
|
* لذلك يجب أن يكون التوكن المُولّد هنا متوافقاً تماماً مع V1.
|
||||||
|
*/
|
||||||
class PaymentTokenController extends Controller
|
class PaymentTokenController extends Controller
|
||||||
{
|
{
|
||||||
// 1. مسار الراكب
|
// 1. مسار الراكب
|
||||||
public function generatePassengerToken(Request $request)
|
public function generatePassengerToken(Request $request)
|
||||||
{
|
{
|
||||||
$userId = $request->attributes->get('_jwt_user_id');
|
$userId = $request->attributes->get('_jwt_user_id');
|
||||||
// تحقق خاص بالراكب (لا يوجد بصمة سيارة مثلاً)
|
|
||||||
return $this->buildToken($userId, 'android/ios_passenger', $request->input('fingerPrint'));
|
return $this->buildToken($userId, 'android/ios_passenger', $request->input('fingerPrint'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +30,6 @@ class PaymentTokenController extends Controller
|
|||||||
public function generateDriverToken(Request $request)
|
public function generateDriverToken(Request $request)
|
||||||
{
|
{
|
||||||
$userId = $request->attributes->get('_jwt_user_id');
|
$userId = $request->attributes->get('_jwt_user_id');
|
||||||
// تحقق خاص بالسائق (ضرورة وجود بصمة جهاز قوية)
|
|
||||||
return $this->buildToken($userId, 'android/ios_driver', $request->input('fingerPrint'));
|
return $this->buildToken($userId, 'android/ios_driver', $request->input('fingerPrint'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,36 +37,43 @@ class PaymentTokenController extends Controller
|
|||||||
public function generateAdminToken(Request $request)
|
public function generateAdminToken(Request $request)
|
||||||
{
|
{
|
||||||
$userId = $request->attributes->get('_jwt_user_id');
|
$userId = $request->attributes->get('_jwt_user_id');
|
||||||
// المدراء لديهم صلاحيات أوسع، قد يكون الـ aud مختلفاً
|
|
||||||
return $this->buildToken($userId, 'web_admin', 'admin_secure_context');
|
return $this->buildToken($userId, 'web_admin', 'admin_secure_context');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. دالة البناء المركزية (Private)
|
// 4. دالة البناء المركزية — متوافقة مع V1 authenticateJWT()
|
||||||
private function buildToken($userId, $audience, $fingerprint)
|
private function buildToken($userId, $audience, $fingerprint)
|
||||||
{
|
{
|
||||||
$keyPath = env('PAYMENT_INTERNAL_KEY_PATH');
|
// ⚠️ مهم جداً لموافاة V1:
|
||||||
|
// سيرفر المحفظة (walletintaleq.intaleq.xyz) يستخدم V1authenticateJWT()
|
||||||
|
// التي تقرأ المفتاح من: /home/intaleq-api/.secret_key
|
||||||
|
// لذلك يجب استخدام jwt_secret هنا وليس wallet_jwt_secret.
|
||||||
|
$secret = config('intaleq.jwt_secret');
|
||||||
|
|
||||||
if (!File::exists($keyPath)) {
|
if (empty($secret)) {
|
||||||
return response()->json(['status' => 'error', 'message' => 'Security Key Missing'], 500);
|
return response()->json(['status' => 'error', 'message' => 'Security Key Missing (JWT)'], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
$internalSecret = trim(File::get($keyPath));
|
// بناء التوكن بنفس الهيكل المطلوب من V1
|
||||||
|
|
||||||
$payload = [
|
$payload = [
|
||||||
'iss' => 'Intaleq_V2',
|
'user_id' => $userId, // V1 يستخرج: $decoded->user_id
|
||||||
'sub' => $userId,
|
'iss' => 'Tripz', // V1 يتحقق: $decoded->iss === 'Tripz'
|
||||||
'aud' => $audience,
|
'aud' => $audience,
|
||||||
'iat' => time(),
|
'iat' => time(),
|
||||||
'exp' => time() + 60,
|
'exp' => time() + 120, // زيادة الوقت قليلاً لـ 120 ثانية
|
||||||
'fingerprint' => $fingerprint
|
'fingerPrint' => hash('sha256', ($fingerprint ?? '') . config('intaleq.fp_pepper', '')),
|
||||||
|
'jti' => bin2hex(random_bytes(16)),
|
||||||
];
|
];
|
||||||
|
|
||||||
$token = JWT::encode($payload, $internalSecret, 'HS256');
|
$token = JWT::encode($payload, $secret, 'HS256');
|
||||||
|
|
||||||
|
// HMAC: يستخدم SECRET_KEY_HMAC (متوفر في .env)
|
||||||
|
$hmacSecret = config('intaleq.wallet_hmac_secret');
|
||||||
|
$hmac = hash_hmac('sha256', $userId, $hmacSecret);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'token' => $token,
|
'token' => $token,
|
||||||
'hmac' => hash_hmac('sha256', $token, $internalSecret)
|
'hmac' => $hmac
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
127
app/Http/Controllers/OverlayController.php
Normal file
127
app/Http/Controllers/OverlayController.php
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OverlayController — إدارة بيانات الرحلة المقبولة من الخلفية
|
||||||
|
*
|
||||||
|
* الغرض:
|
||||||
|
* عندما يقبل السائق رحلة وهو في الخلفية (Background)، يتم تخزين بيانات الرحلة
|
||||||
|
* في جدول write_argument_after_applied_from_background حتى يتمكن التطبيق من
|
||||||
|
* استرجاعها عند العودة للواجهة (Foreground).
|
||||||
|
*
|
||||||
|
* يعادل: intaleq_v1/ride/overLay/getArgumentAfterAppliedFromBackground.php
|
||||||
|
* intaleq_v1/ride/overLay/add.php
|
||||||
|
*/
|
||||||
|
class OverlayController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* GET /v2/overlay/background-args
|
||||||
|
* جلب بيانات الرحلة المقبولة من الخلفية (آخر دقيقتين فقط)
|
||||||
|
*/
|
||||||
|
public function getBackgroundArgs(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$driverId = $request->attributes->get('_jwt_user_id');
|
||||||
|
|
||||||
|
if (empty($driverId)) {
|
||||||
|
return response()->json(['status' => 'failure', 'message' => 'Missing driver ID']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = DB::connection('primary')
|
||||||
|
->table('write_argument_after_applied_from_background')
|
||||||
|
->where('driver_id', $driverId)
|
||||||
|
->whereRaw('TIMESTAMPDIFF(MINUTE, time_of_order, NOW()) <= 2')
|
||||||
|
->orderBy('time_of_order', 'desc')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($row) {
|
||||||
|
return response()->json(['status' => 'success', 'message' => (array) $row]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(['status' => 'failure', 'message' => 'No data found']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /v2/overlay/background-args
|
||||||
|
* تخزين بيانات الرحلة المقبولة من الخلفية
|
||||||
|
*/
|
||||||
|
public function storeBackgroundArgs(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$driverId = $request->attributes->get('_jwt_user_id');
|
||||||
|
|
||||||
|
$rideId = $request->input('rideId');
|
||||||
|
$passengerLocation = $request->input('passengerLocation');
|
||||||
|
$passengerDestination = $request->input('passengerDestination');
|
||||||
|
|
||||||
|
if (empty($rideId) || empty($driverId) || empty($passengerLocation) || empty($passengerDestination)) {
|
||||||
|
return response()->json([
|
||||||
|
'status' => 'failure',
|
||||||
|
'message' => 'Missing required fields (rideId, driver_id, or locations)'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::connection('primary')
|
||||||
|
->table('write_argument_after_applied_from_background')
|
||||||
|
->insert([
|
||||||
|
'ride_id' => $rideId,
|
||||||
|
'driver_id' => $driverId,
|
||||||
|
'passenger_id' => $request->input('passengerId'),
|
||||||
|
'passenger_location' => $passengerLocation,
|
||||||
|
'passenger_destination' => $passengerDestination,
|
||||||
|
'duration' => (int) $request->input('Duration', 0),
|
||||||
|
'duration_to_passenger' => (int) $request->input('DurationToPassenger', 0),
|
||||||
|
'duration_of_ride' => (int) $request->input('durationOfRideValue', 0),
|
||||||
|
'distance' => (float) $request->input('Distance', 0),
|
||||||
|
'total_cost' => (float) $request->input('totalCost', 0),
|
||||||
|
'payment_amount' => (float) $request->input('paymentAmount', 0),
|
||||||
|
'payment_method' => $request->input('paymentMethod'),
|
||||||
|
'wallet_checked' => $request->input('WalletChecked') === 'true' ? 1 : 0,
|
||||||
|
'has_steps' => !empty($request->input('isHaveSteps')) ? 1 : 0,
|
||||||
|
'step0' => $request->input('step0'),
|
||||||
|
'step1' => $request->input('step1'),
|
||||||
|
'step2' => $request->input('step2'),
|
||||||
|
'step3' => $request->input('step3'),
|
||||||
|
'step4' => $request->input('step4'),
|
||||||
|
'passenger_wallet_burc' => (float) $request->input('passengerWalletBurc', 0),
|
||||||
|
'token_passenger' => $request->input('tokenPassenger'),
|
||||||
|
'name' => $request->input('name'),
|
||||||
|
'phone' => $request->input('phone'),
|
||||||
|
'email' => $request->input('email'),
|
||||||
|
'start_name_location' => $request->input('startNameLocation'),
|
||||||
|
'end_name_location' => $request->input('endNameLocation'),
|
||||||
|
'car_type' => $request->input('carType'),
|
||||||
|
'kazan' => (float) $request->input('kazan', 0),
|
||||||
|
'direction_url' => $request->input('direction'),
|
||||||
|
'time_of_order' => $request->input('timeOfOrder', now()),
|
||||||
|
'total_passenger' => (int) $request->input('totalPassenger', 0),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json(['status' => 'success', 'message' => 'Background args saved']);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error('OverlayController Error: ' . $e->getMessage());
|
||||||
|
return response()->json(['status' => 'failure', 'message' => 'Database error']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE /v2/overlay/background-args
|
||||||
|
* حذف بيانات الرحلة المقبولة بعد استلامها
|
||||||
|
*/
|
||||||
|
public function deleteBackgroundArgs(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$driverId = $request->attributes->get('_jwt_user_id');
|
||||||
|
|
||||||
|
DB::connection('primary')
|
||||||
|
->table('write_argument_after_applied_from_background')
|
||||||
|
->where('driver_id', $driverId)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return response()->json(['status' => 'success', 'message' => 'Background args deleted']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ use App\Http\Controllers\InviteController;
|
|||||||
use App\Http\Controllers\DriverDocController;
|
use App\Http\Controllers\DriverDocController;
|
||||||
use App\Http\Controllers\SupportController;
|
use App\Http\Controllers\SupportController;
|
||||||
use App\Http\Controllers\Api\PaymentTokenController;
|
use App\Http\Controllers\Api\PaymentTokenController;
|
||||||
|
use App\Http\Controllers\OverlayController;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -194,6 +195,11 @@ Route::prefix('v2')->middleware(['hmac.auth', 'jwt.auth'])->group(function () {
|
|||||||
|
|
||||||
// ── Support ──
|
// ── Support ──
|
||||||
Route::post('/support/complaints', [SupportController::class, 'storeComplaint']);
|
Route::post('/support/complaints', [SupportController::class, 'storeComplaint']);
|
||||||
|
|
||||||
|
// ── Overlay / Background Args ──
|
||||||
|
Route::get('/overlay/background-args', [OverlayController::class, 'getBackgroundArgs']);
|
||||||
|
Route::post('/overlay/background-args', [OverlayController::class, 'storeBackgroundArgs']);
|
||||||
|
Route::delete('/overlay/background-args', [OverlayController::class, 'deleteBackgroundArgs']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ══════════════════════════════════════════════
|
// ══════════════════════════════════════════════
|
||||||
|
|||||||
Reference in New Issue
Block a user