diff --git a/app/Http/Controllers/CortexXdrController.php b/app/Http/Controllers/CortexXdrController.php index b0c0759..8b49d16 100644 --- a/app/Http/Controllers/CortexXdrController.php +++ b/app/Http/Controllers/CortexXdrController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Services\CortexXdrService; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; class CortexXdrController extends Controller { @@ -23,7 +24,9 @@ class CortexXdrController extends Controller public function getData(CortexXdrService $cortexService) { try { - $summary = $cortexService->getSummary(); + $summary = Cache::remember('cortex_summary_data', 300, function () use ($cortexService) { + return $cortexService->getSummary(); + }); return response()->json($summary); } catch (\Exception $e) { return response()->json(['error' => $e->getMessage()], 500); diff --git a/app/Services/CortexXdrService.php b/app/Services/CortexXdrService.php index ce27ed3..c67a225 100644 --- a/app/Services/CortexXdrService.php +++ b/app/Services/CortexXdrService.php @@ -37,9 +37,9 @@ class CortexXdrService * Get Incidents * Using pagination to fetch up to $limit incidents. */ - public function getIncidents($limit = 1000) + public function getIncidents($limit = 1000, $filters = []) { - return $this->fetchAll('incidents/get_incidents', 'incidents', $limit); + return $this->fetchAll('incidents/get_incidents', 'incidents', $limit, $filters); } /** @@ -54,7 +54,7 @@ class CortexXdrService /** * Generic fetch method with pagination. */ - private function fetchAll($endpoint, $dataKey, $limit) + private function fetchAll($endpoint, $dataKey, $limit, $filters = []) { if (empty($this->apiKey) || empty($this->apiKeyId) || empty($this->baseUrl)) { Log::warning('Cortex XDR credentials missing.'); @@ -81,10 +81,10 @@ class CortexXdrService $response = Http::withHeaders($this->getHeaders()) ->post("{$this->baseUrl}/public_api/v1/{$endpoint}/", [ - 'request_data' => [ + 'request_data' => array_merge([ 'search_from' => $offset, 'search_to' => $offset + $currentBatchSize, - ] + ], !empty($filters) ? ['filters' => $filters] : []) ]); if ($response->successful()) { @@ -122,7 +122,15 @@ class CortexXdrService public function getSummary() { try { - $incidents = $this->getIncidents(1000); // Limit incidents to 1000 recent + // Filter to fetch only active incidents to improve performance + $filters = [ + [ + 'field' => 'status', + 'operator' => 'in', + 'value' => ['new', 'under_investigation'] + ] + ]; + $incidents = $this->getIncidents(1000, $filters); // Limit incidents to 1000 recent active $endpoints = $this->getEndpoints(1000); // Limit endpoints to 2000 } catch (\Exception $e) { // In dashboard context, we verify configuration separately. @@ -137,6 +145,8 @@ class CortexXdrService $endpointsDisconnected = collect($endpoints)->filter(fn($e) => strtolower($e['endpoint_status'] ?? '') === 'disconnected')->count(); // Filter only Active Incidents (New or Under Investigation) + // Since we now filter at API level, we can just use the result, + // but keeping the collection filter adds a layer of safety if filters change. $activeIncidents = collect($incidents)->filter(fn($i) => in_array($i['status'] ?? '', ['new', 'under_investigation'])); //die(var_dump($activeIncidents)); @@ -163,6 +173,7 @@ class CortexXdrService 'endpoints_types' => $endpointTypes, // New Data 'recent_incidents' => collect($incidents) ->filter(fn($i) => !in_array($i['status'] ?? '', ['resolved_true_positive', 'resolved_false_positive'])) + ->sortByDesc('incident_id') ->slice(0, 10) ->values() ->all()