diff --git a/x-pack/plugins/cases/public/components/case_view/index.tsx b/x-pack/plugins/cases/public/components/case_view/index.tsx index a44c2cb22010e..b333d908fa77c 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.tsx @@ -105,6 +105,7 @@ export const CaseComponent = React.memo( const [initLoadingData, setInitLoadingData] = useState(true); const init = useRef(true); const timelineUi = useTimelineContext()?.ui; + const alertConsumers = useTimelineContext()?.alertConsumers; const { caseUserActions, @@ -486,7 +487,9 @@ export const CaseComponent = React.memo( - {timelineUi?.renderTimelineDetailsPanel ? timelineUi.renderTimelineDetailsPanel() : null} + {timelineUi?.renderTimelineDetailsPanel + ? timelineUi.renderTimelineDetailsPanel({ alertConsumers }) + : null} ); } diff --git a/x-pack/plugins/cases/public/components/timeline_context/index.tsx b/x-pack/plugins/cases/public/components/timeline_context/index.tsx index 727e4b64628d1..76952e638e198 100644 --- a/x-pack/plugins/cases/public/components/timeline_context/index.tsx +++ b/x-pack/plugins/cases/public/components/timeline_context/index.tsx @@ -7,6 +7,7 @@ import React, { useState } from 'react'; import { EuiMarkdownEditorUiPlugin, EuiMarkdownAstNodePosition } from '@elastic/eui'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { Plugin } from 'unified'; /** * @description - manage the plugins, hooks, and ui components needed to enable timeline functionality within the cases plugin @@ -28,6 +29,7 @@ interface TimelineProcessingPluginRendererProps { } export interface CasesTimelineIntegration { + alertConsumers?: AlertConsumers[]; editor_plugins: { parsingPlugin: Plugin; processingPluginRenderer: React.FC< @@ -43,7 +45,11 @@ export interface CasesTimelineIntegration { }; ui?: { renderInvestigateInTimelineActionComponent?: (alertIds: string[]) => JSX.Element; - renderTimelineDetailsPanel?: () => JSX.Element; + renderTimelineDetailsPanel?: ({ + alertConsumers, + }: { + alertConsumers?: AlertConsumers[]; + }) => JSX.Element; }; } diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx index fdb12170309c7..21b97b9be0db9 100644 --- a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx @@ -7,6 +7,7 @@ import React, { useCallback, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { getCaseDetailsUrl, @@ -33,6 +34,7 @@ import { SpyRoute } from '../../../common/utils/route/spy_routes'; import * as timelineMarkdownPlugin from '../../../common/components/markdown_editor/plugins/timeline'; import { CaseDetailsRefreshContext } from '../../../common/components/endpoint/host_isolation/endpoint_host_isolation_cases_context'; import { getEndpointDetailsPath } from '../../../management/common/routing'; +import { EntityType } from '../../../timelines/containers/details'; interface Props { caseId: string; @@ -53,13 +55,17 @@ export interface CaseProps extends Props { updateCase: (newCase: Case) => void; } -const TimelineDetailsPanel = () => { +const ALERT_CONSUMER: AlertConsumers[] = [AlertConsumers.SIEM]; + +const TimelineDetailsPanel = ({ alertConsumers }: { alertConsumers?: AlertConsumers[] }) => { const { browserFields, docValueFields } = useSourcererScope(SourcererScopeName.detections); return ( @@ -228,6 +234,7 @@ export const CaseView = React.memo(({ caseId, subCaseId, userCanCrud }: Props) = showAlertDetails, subCaseId, timelineIntegration: { + alertConsumers: ALERT_CONSUMER, editor_plugins: { parsingPlugin: timelineMarkdownPlugin.parser, processingPluginRenderer: timelineMarkdownPlugin.renderer, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index fe6c7e85e175d..f5d1a20ded891 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -11,6 +11,7 @@ import deepEqual from 'fast-deep-equal'; import styled from 'styled-components'; import { isEmpty } from 'lodash/fp'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { inputsModel, inputsSelectors, State } from '../../store'; import { inputsActions } from '../../store/actions'; import { ControlColumnProps, RowRenderer, TimelineId } from '../../../../common/types/timeline'; @@ -30,6 +31,7 @@ import { useKibana } from '../../lib/kibana'; import { defaultControlColumn } from '../../../timelines/components/timeline/body/control_columns'; import { EventsViewer } from './events_viewer'; import * as i18n from './translations'; +import { EntityType } from '../../../timelines/containers/details'; const EMPTY_CONTROL_COLUMNS: ControlColumnProps[] = []; const leadingControlColumns: ControlColumnProps[] = [ @@ -67,6 +69,8 @@ export interface OwnProps { type Props = OwnProps & PropsFromRedux; +const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM]; + /** * The stateful events viewer component is the highest level component that is utilized across the security_solution pages layer where * timeline is used BESIDES the flyout. The flyout makes use of the `EventsViewer` component which is a subcomponent here @@ -205,7 +209,9 @@ const StatefulEventsViewerComponent: React.FC = ({ = ({ + alertConsumers, browserFields, docValueFields, + entityType, expandedEvent, handleOnEventClosed, isFlyoutView, @@ -74,7 +79,9 @@ const EventDetailsPanelComponent: React.FC = ({ timelineId, }) => { const [loading, detailsData] = useTimelineEventsDetails({ + alertConsumers, docValueFields, + entityType, indexName: expandedEvent.indexName ?? '', eventId: expandedEvent.eventId ?? '', skip: !expandedEvent.eventId, diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx index 3e57ec2e039f5..c45399c3de992 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx @@ -8,6 +8,8 @@ import React, { useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { EuiFlyout, EuiFlyoutProps } from '@elastic/eui'; +import { AlertConsumers } from '@kbn/rule-data-utils'; + import { timelineActions, timelineSelectors } from '../../store/timeline'; import { timelineDefaults } from '../../store/timeline/defaults'; import { BrowserFields, DocValueFields } from '../../../common/containers/source'; @@ -16,10 +18,13 @@ import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; import { EventDetailsPanel } from './event_details'; import { HostDetailsPanel } from './host_details'; import { NetworkDetailsPanel } from './network_details'; +import { EntityType } from '../../containers/details'; interface DetailsPanelProps { + alertConsumers?: AlertConsumers[]; browserFields: BrowserFields; docValueFields: DocValueFields[]; + entityType?: EntityType; handleOnPanelClosed?: () => void; isFlyoutView?: boolean; tabType?: TimelineTabs; @@ -33,8 +38,10 @@ interface DetailsPanelProps { */ export const DetailsPanel = React.memo( ({ + alertConsumers, browserFields, docValueFields, + entityType, handleOnPanelClosed, isFlyoutView, tabType, @@ -70,8 +77,10 @@ export const DetailsPanel = React.memo( panelSize = 'm'; visiblePanel = ( = ({ activeTab, columns, @@ -346,6 +349,7 @@ export const EqlTabContentComponent: React.FC = ({ = ({ timelineId } () => expandedDetail[TimelineTabs.notes]?.panelView ? ( React.ReactNode; rowRenderers: RowRenderer[]; @@ -266,6 +269,7 @@ export const PinnedTabContentComponent: React.FC = ({ theme.eui.paddingSizes.s}; `; +const alertConsumers: AlertConsumers[] = [AlertConsumers.SIEM]; + const isTimerangeSame = (prevProps: Props, nextProps: Props) => prevProps.end === nextProps.end && prevProps.start === nextProps.start && @@ -414,6 +417,7 @@ export const QueryTabContentComponent: React.FC = ({ { const myRequest = { ...(prevRequest ?? {}), + alertConsumers, docValueFields, + entityType, indexName, eventId, factoryQueryType: TimelineEventsQueries.details, @@ -114,7 +127,7 @@ export const useTimelineEventsDetails = ({ } return prevRequest; }); - }, [docValueFields, eventId, indexName]); + }, [alertConsumers, docValueFields, entityType, eventId, indexName]); useEffect(() => { timelineDetailsSearch(timelineDetailsRequest); diff --git a/x-pack/plugins/timelines/common/utils/field_formatters.ts b/x-pack/plugins/timelines/common/utils/field_formatters.ts index b436f8e616122..a48f03b90af6b 100644 --- a/x-pack/plugins/timelines/common/utils/field_formatters.ts +++ b/x-pack/plugins/timelines/common/utils/field_formatters.ts @@ -43,7 +43,7 @@ export const getDataFromSourceHits = ( category?: string, path?: string ): TimelineEventsDetailsItem[] => - Object.keys(sources).reduce((accumulator, source) => { + Object.keys(sources ?? {}).reduce((accumulator, source) => { const item: EventSource = get(source, sources); if (Array.isArray(item) || isString(item) || isNumber(item)) { const field = path ? `${path}.${source}` : source;