From 2a682dccd7e6bfa92fc82a83ffb6dded7d31d389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Thu, 10 Sep 2026 09:59:39 -0600 Subject: [PATCH] feat[frontend](threat-inteligense): falling back to generic threatwinds data when no instance ioc matches can be found --- .../threat-intel/domain/threat-intel.types.ts | 1 + .../threat-intel/hooks/use-ti-search-advanced.ts | 14 ++++++++++++-- .../threat-intel/pages/ThreatIntelPage.tsx | 10 +++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/frontend/src/features/threat-intel/domain/threat-intel.types.ts b/frontend/src/features/threat-intel/domain/threat-intel.types.ts index 595626509..cf115b302 100644 --- a/frontend/src/features/threat-intel/domain/threat-intel.types.ts +++ b/frontend/src/features/threat-intel/domain/threat-intel.types.ts @@ -124,6 +124,7 @@ export type UsageInfo = Record export type TiResult = | { kind: 'ok'; value: T } + | { kind: 'empty'; value: T } | { kind: 'not-configured' } export interface AdvancedRangeCondition { diff --git a/frontend/src/features/threat-intel/hooks/use-ti-search-advanced.ts b/frontend/src/features/threat-intel/hooks/use-ti-search-advanced.ts index ee1ab4676..2a7f14d33 100644 --- a/frontend/src/features/threat-intel/hooks/use-ti-search-advanced.ts +++ b/frontend/src/features/threat-intel/hooks/use-ti-search-advanced.ts @@ -6,8 +6,18 @@ import type { AdvancedSearchRequest } from '../domain/threat-intel.types' export function useTiSearchAdvanced() { return useMutation({ - mutationFn: (input: { body: AdvancedSearchRequest; limit?: number; page?: number }) => - threatIntelHttpService.searchAdvanced(input.body, { limit: input.limit, page: input.page }), + mutationFn: async (input: { body: AdvancedSearchRequest; limit?: number; page?: number }) =>{ + try{ + return await threatIntelHttpService.searchAdvanced(input.body, { limit: input.limit, page: input.page }) + }catch(e){ + if(isNotFound(e)){ + const resp = await threatIntelHttpService.searchAdvanced({}, { limit: input.limit, page: input.page }) + resp.kind="empty" + return resp + } + throw e + } + }, onError: (e) => { if (!isNotConfigured(e) && !isNotFound(e)) toast.error(describeError(e)) }, }) } diff --git a/frontend/src/features/threat-intel/pages/ThreatIntelPage.tsx b/frontend/src/features/threat-intel/pages/ThreatIntelPage.tsx index 648b73f63..643505ac3 100644 --- a/frontend/src/features/threat-intel/pages/ThreatIntelPage.tsx +++ b/frontend/src/features/threat-intel/pages/ThreatIntelPage.tsx @@ -89,6 +89,7 @@ export function ThreatIntelPage() { const [filters, setFilters] = useState(EMPTY_FILTERS) const [lastBody, setLastBody] = useState({}) + const [empty, setEmpty] = useState(false) const [filtersOpen, setFiltersOpen] = useState(false) const [timeRange, setTimeRange] = useState('all') @@ -113,7 +114,10 @@ export function ThreatIntelPage() { onSuccess: (data) => { if (my !== seqRef.current) return if (data?.kind === 'not-configured') return - if (data?.kind !== 'ok') return + if (data?.kind !== 'ok' && data?.kind !== 'empty') return + if(data.kind =='empty'){ + setEmpty(true) + } setTotalItems(data.value.items) setTotalPages(data.value.pages) setIocs((prev) => @@ -232,12 +236,12 @@ export function ThreatIntelPage() { matchedCount={totalItems} onExport={handleExport} isExporting={isExporting} - noInstanceIocs={observedFragment.ready && !observedFragment.hasInstanceIocs} + noInstanceIocs={empty || observedFragment.ready && !observedFragment.hasInstanceIocs} />
o.value === timeRange)?.interval ?? 'hour'} />