header('Authorization'); if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) { return response()->json([ 'status' => 'failure', 'message' => 'Missing or invalid Authorization header' ], 401); } $token = substr($authHeader, 7); try { $decoded = JWT::decode($token, new Key(config('intaleq.jwt_secret'), 'HS256')); // Verify issuer (allow Tripz, Tripz-Wallet, Intaleq, or empty for compatibility) $iss = $decoded->iss ?? ''; if (!empty($iss) && !in_array($iss, ['Tripz', 'Tripz-Wallet', 'Intaleq', 'Tripz-v2'])) { return response()->json([ 'status' => 'failure', 'message' => 'Invalid token issuer: ' . $iss ], 401); } // Attach JWT claims to request attributes (internal, not spoofable via POST/GET) $request->attributes->set('_jwt_user_id', $decoded->user_id ?? null); $request->attributes->set('_jwt_user_type', $decoded->user_type ?? null); $request->attributes->set('_jwt_fingerprint', $decoded->fingerprint ?? null); return $next($request); } catch (ExpiredException $e) { return response()->json([ 'status' => 'failure', 'message' => 'Token expired' ], 401); } catch (\Exception $e) { return response()->json([ 'status' => 'failure', 'message' => 'Invalid token' ], 401); } } }