Skip to content

Commit 2a682dc

Browse files
feat[frontend](threat-inteligense): falling back to generic threatwinds data when no instance ioc matches can be found
1 parent 1d12e82 commit 2a682dc

3 files changed

Lines changed: 20 additions & 5 deletions

File tree

frontend/src/features/threat-intel/domain/threat-intel.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export type UsageInfo = Record<string, EndpointUsage>
124124

125125
export type TiResult<T> =
126126
| { kind: 'ok'; value: T }
127+
| { kind: 'empty'; value: T }
127128
| { kind: 'not-configured' }
128129

129130
export interface AdvancedRangeCondition {

frontend/src/features/threat-intel/hooks/use-ti-search-advanced.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,18 @@ import type { AdvancedSearchRequest } from '../domain/threat-intel.types'
66

77
export function useTiSearchAdvanced() {
88
return useMutation({
9-
mutationFn: (input: { body: AdvancedSearchRequest; limit?: number; page?: number }) =>
10-
threatIntelHttpService.searchAdvanced(input.body, { limit: input.limit, page: input.page }),
9+
mutationFn: async (input: { body: AdvancedSearchRequest; limit?: number; page?: number }) =>{
10+
try{
11+
return await threatIntelHttpService.searchAdvanced(input.body, { limit: input.limit, page: input.page })
12+
}catch(e){
13+
if(isNotFound(e)){
14+
const resp = await threatIntelHttpService.searchAdvanced({}, { limit: input.limit, page: input.page })
15+
resp.kind="empty"
16+
return resp
17+
}
18+
throw e
19+
}
20+
},
1121
onError: (e) => { if (!isNotConfigured(e) && !isNotFound(e)) toast.error(describeError(e)) },
1222
})
1323
}

frontend/src/features/threat-intel/pages/ThreatIntelPage.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export function ThreatIntelPage() {
8989

9090
const [filters, setFilters] = useState<FiltersState>(EMPTY_FILTERS)
9191
const [lastBody, setLastBody] = useState<AdvancedSearchRequest>({})
92+
const [empty, setEmpty] = useState<boolean>(false)
9293
const [filtersOpen, setFiltersOpen] = useState(false)
9394
const [timeRange, setTimeRange] = useState<TimeRange>('all')
9495

@@ -113,7 +114,10 @@ export function ThreatIntelPage() {
113114
onSuccess: (data) => {
114115
if (my !== seqRef.current) return
115116
if (data?.kind === 'not-configured') return
116-
if (data?.kind !== 'ok') return
117+
if (data?.kind !== 'ok' && data?.kind !== 'empty') return
118+
if(data.kind =='empty'){
119+
setEmpty(true)
120+
}
117121
setTotalItems(data.value.items)
118122
setTotalPages(data.value.pages)
119123
setIocs((prev) =>
@@ -232,12 +236,12 @@ export function ThreatIntelPage() {
232236
matchedCount={totalItems}
233237
onExport={handleExport}
234238
isExporting={isExporting}
235-
noInstanceIocs={observedFragment.ready && !observedFragment.hasInstanceIocs}
239+
noInstanceIocs={empty || observedFragment.ready && !observedFragment.hasInstanceIocs}
236240
/>
237241

238242
<div className="mt-5">
239243
<MatchOverviewCard
240-
body={observedFragment.ready ? lastBody : undefined}
244+
body={observedFragment.ready ? (empty? {}:lastBody) : undefined}
241245
interval={TIME_RANGE_OPTIONS.find((o) => o.value === timeRange)?.interval ?? 'hour'}
242246
/>
243247
</div>

0 commit comments

Comments
 (0)