"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.DetectionEnginePage = void 0; var _eui = require("@elastic/eui"); var _styledComponents = _interopRequireDefault(require("styled-components")); var _fp = require("lodash/fp"); var _react = _interopRequireWildcard(require("react")); var _reactRedux = require("react-redux"); var _public = require("@kbn/timelines-plugin/public"); var _securitysolutionDataTable = require("@kbn/securitysolution-data-table"); var _constants = require("../../../../common/constants"); var _use_data_table_filters = require("../../../common/hooks/use_data_table_filters"); var _use_experimental_features = require("../../../common/hooks/use_experimental_features"); var _constants2 = require("../../../common/store/inputs/constants"); var _use_selector = require("../../../common/hooks/use_selector"); var _types = require("../../../app/types"); var _use_global_time = require("../../../common/containers/use_global_time"); var _filters_global = require("../../../common/components/filters_global"); var _redirect_to_detection_engine = require("../../../common/components/link_to/redirect_to_detection_engine"); var _search_bar = require("../../../common/components/search_bar"); var _page_wrapper = require("../../../common/components/page_wrapper"); var _inputs = require("../../../common/store/inputs"); var _actions = require("../../../common/store/inputs/actions"); var _no_api_integration_callout = require("../../components/callouts/no_api_integration_callout"); var _user_info = require("../../components/user_info"); var _detection_engine_no_index = require("./detection_engine_no_index"); var _use_lists_config = require("../../containers/detection_engine/lists/use_lists_config"); var _detection_engine_user_unauthenticated = require("./detection_engine_user_unauthenticated"); var i18n = _interopRequireWildcard(require("./translations")); var _links = require("../../../common/components/links"); var _link_to = require("../../../common/components/link_to"); var _use_full_screen = require("../../../common/containers/use_full_screen"); var _display = require("../../../explore/hosts/pages/display"); var _helpers = require("../../../timelines/components/timeline/helpers"); var _default_config = require("../../components/alerts_table/default_config"); var _chart_panels = require("./chart_panels"); var _sourcerer = require("../../../common/containers/sourcerer"); var _use_signal_helpers = require("../../../common/containers/sourcerer/use_signal_helpers"); var _model = require("../../../common/store/sourcerer/model"); var _need_admin_for_update_callout = require("../../components/callouts/need_admin_for_update_callout"); var _missing_privileges_callout = require("../../components/callouts/missing_privileges_callout"); var _kibana = require("../../../common/lib/kibana"); var _no_privileges = require("../../../common/components/no_privileges"); var _header_page = require("../../../common/components/header_page"); var _landing_page = require("../../../common/components/landing_page"); var _alerts_filter_group = require("../../components/alerts_table/alerts_filter_group"); var _alerts_grouping = require("../../components/alerts_table/alerts_grouping"); var _alerts_table = require("../../components/alerts_table"); var _detection_page_filters = require("../../components/detection_page_filters"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ // No bueno, I know! Encountered when reverting RBAC work post initial BCs // Don't want to include large amounts of refactor in this temporary workaround // TODO: Refactor code - component can be broken apart /** * Need a 100% height here to account for the graph/analyze tool, which sets no explicit height parameters, but fills the available space. */ const StyledFullHeightContainer = _styledComponents.default.div` display: flex; flex-direction: column; flex: 1 1 auto; `; const DetectionEnginePageComponent = ({ clearEventsLoading, clearEventsDeleted }) => { const dispatch = (0, _reactRedux.useDispatch)(); const containerElement = (0, _react.useRef)(null); const getTable = (0, _react.useMemo)(() => _securitysolutionDataTable.dataTableSelectors.getTableByIdSelector(), []); const graphEventId = (0, _use_selector.useShallowEqualSelector)(state => { var _getTable; return ((_getTable = getTable(state, _securitysolutionDataTable.TableId.alertsOnAlertsPage)) !== null && _getTable !== void 0 ? _getTable : _securitysolutionDataTable.tableDefaults).graphEventId; }); const isTableLoading = (0, _use_selector.useShallowEqualSelector)(state => { var _getTable2; return ((_getTable2 = getTable(state, _securitysolutionDataTable.TableId.alertsOnAlertsPage)) !== null && _getTable2 !== void 0 ? _getTable2 : _securitysolutionDataTable.tableDefaults).isLoading; }); const getGlobalFiltersQuerySelector = (0, _react.useMemo)(() => _inputs.inputsSelectors.globalFiltersQuerySelector(), []); const getGlobalQuerySelector = (0, _react.useMemo)(() => _inputs.inputsSelectors.globalQuerySelector(), []); const query = (0, _use_selector.useDeepEqualSelector)(getGlobalQuerySelector); const filters = (0, _use_selector.useDeepEqualSelector)(getGlobalFiltersQuerySelector); const { to, from } = (0, _use_global_time.useGlobalTime)(); const { globalFullScreen } = (0, _use_full_screen.useGlobalFullScreen)(); const [{ loading: userInfoLoading, isAuthenticated: isUserAuthenticated, hasEncryptionKey, signalIndexName, canUserREAD, hasIndexRead, hasIndexWrite, hasIndexMaintenance }] = (0, _user_info.useUserData)(); const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = (0, _use_lists_config.useListsConfig)(); const arePageFiltersEnabled = (0, _use_experimental_features.useIsExperimentalFeatureEnabled)('alertsPageFiltersEnabled'); // when arePageFiltersEnabled === false const [statusFilter, setStatusFilter] = (0, _react.useState)([]); const updatedAt = (0, _use_selector.useShallowEqualSelector)(state => { var _getTable3; return ((_getTable3 = getTable(state, _securitysolutionDataTable.TableId.alertsOnAlertsPage)) !== null && _getTable3 !== void 0 ? _getTable3 : _securitysolutionDataTable.tableDefaults).updated; }); // when arePageFiltersEnabled === true const [detectionPageFilters, setDetectionPageFilters] = (0, _react.useState)(); const [detectionPageFilterHandler, setDetectionPageFilterHandler] = (0, _react.useState)(); const { indexPattern, runtimeMappings, loading: isLoadingIndexPattern } = (0, _sourcerer.useSourcererDataView)(_model.SourcererScopeName.detections); const { formatUrl } = (0, _link_to.useFormatUrl)(_types.SecurityPageName.rules); const { showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts } = (0, _use_data_table_filters.useDataTableFilters)(_securitysolutionDataTable.TableId.alertsOnAlertsPage); const loading = userInfoLoading || listsConfigLoading; const { application: { navigateToUrl }, timelines: timelinesUi, data } = (0, _kibana.useKibana)().services; const { filterManager } = data.query; const topLevelFilters = (0, _react.useMemo)(() => { return [...filters, ...(0, _default_config.buildShowBuildingBlockFilter)(showBuildingBlockAlerts), ...(0, _default_config.buildThreatMatchFilter)(showOnlyThreatIndicatorAlerts)]; }, [showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, filters]); const alertPageFilters = (0, _react.useMemo)(() => { var _statusFilter$; if (arePageFiltersEnabled) { return detectionPageFilters; } return (0, _default_config.buildAlertStatusFilter)((_statusFilter$ = statusFilter[0]) !== null && _statusFilter$ !== void 0 ? _statusFilter$ : 'open'); }, [statusFilter, detectionPageFilters, arePageFiltersEnabled]); (0, _react.useEffect)(() => { if (!detectionPageFilterHandler) return; // if Alert is reloaded because of action by the user. // We want reload the values in the detection Page filters if (!isTableLoading) detectionPageFilterHandler.reload(); }, [isTableLoading, detectionPageFilterHandler]); const addFilter = (0, _react.useCallback)(({ field, value, negate }) => { filterManager.addFilters([{ meta: { alias: null, disabled: false, negate: negate !== null && negate !== void 0 ? negate : false }, ...(value != null ? { query: { match_phrase: { [field]: value } } } : { exists: { field } }) }]); }, [filterManager]); const updateDateRangeCallback = (0, _react.useCallback)(({ x }) => { if (!x) { return; } const [min, max] = x; dispatch((0, _actions.setAbsoluteRangeDatePicker)({ id: _constants2.InputsModelId.global, from: new Date(min).toISOString(), to: new Date(max).toISOString() })); }, [dispatch]); const goToRules = (0, _react.useCallback)(ev => { ev.preventDefault(); navigateToUrl(formatUrl((0, _redirect_to_detection_engine.getRulesUrl)())); }, [formatUrl, navigateToUrl]); const alertsDefaultFilters = (0, _react.useMemo)(() => [...topLevelFilters, ...(alertPageFilters !== null && alertPageFilters !== void 0 ? alertPageFilters : [])], [topLevelFilters, alertPageFilters]); // AlertsTable manages global filters itself, so not including `filters` const alertsTableDefaultFilters = (0, _react.useMemo)(() => [...(0, _default_config.buildShowBuildingBlockFilter)(showBuildingBlockAlerts), ...(0, _default_config.buildThreatMatchFilter)(showOnlyThreatIndicatorAlerts), ...(alertPageFilters !== null && alertPageFilters !== void 0 ? alertPageFilters : [])], [showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, alertPageFilters]); const { signalIndexNeedsInit, pollForSignalIndex } = (0, _use_signal_helpers.useSignalHelpers)(); const onSkipFocusBeforeEventsTable = (0, _react.useCallback)(() => { (0, _helpers.focusUtilityBarAction)(containerElement.current); }, [containerElement]); const onSkipFocusAfterEventsTable = (0, _react.useCallback)(() => { (0, _helpers.resetKeyboardFocus)(); }, []); const onKeyDown = (0, _react.useCallback)(keyboardEvent => { if ((0, _public.isTab)(keyboardEvent)) { (0, _helpers.onTimelineTabKeyPressed)({ containerElement: containerElement.current, keyboardEvent, onSkipFocusBeforeEventsTable, onSkipFocusAfterEventsTable }); } }, [containerElement, onSkipFocusBeforeEventsTable, onSkipFocusAfterEventsTable]); const pageFiltersUpdateHandler = (0, _react.useCallback)(newFilters => { setDetectionPageFilters(newFilters); if (newFilters.length) { const newStatusFilter = newFilters.find(filter => filter.meta.key === 'kibana.alert.workflow_status'); if (newStatusFilter) { var _newStatusFilter$quer; const status = newStatusFilter.meta.params ? newStatusFilter.meta.params : [(_newStatusFilter$quer = newStatusFilter.query) === null || _newStatusFilter$quer === void 0 ? void 0 : _newStatusFilter$quer.match_phrase['kibana.alert.workflow_status']]; setStatusFilter(status); } else { setStatusFilter([]); } } }, []); // Callback for when open/closed filter changes const onFilterGroupChangedCallback = (0, _react.useCallback)(newFilterGroup => { const timelineId = _securitysolutionDataTable.TableId.alertsOnAlertsPage; clearEventsLoading({ id: timelineId }); clearEventsDeleted({ id: timelineId }); setStatusFilter([newFilterGroup]); }, [clearEventsLoading, clearEventsDeleted, setStatusFilter]); const areDetectionPageFiltersLoading = (0, _react.useMemo)(() => { if (arePageFiltersEnabled) { return !Array.isArray(detectionPageFilters); } return false; }, [detectionPageFilters, arePageFiltersEnabled]); const isAlertTableLoading = (0, _react.useMemo)(() => loading || areDetectionPageFiltersLoading, [loading, areDetectionPageFiltersLoading]); const isChartPanelLoading = (0, _react.useMemo)(() => isLoadingIndexPattern || areDetectionPageFiltersLoading, [isLoadingIndexPattern, areDetectionPageFiltersLoading]); const showUpdating = (0, _react.useMemo)(() => isAlertTableLoading || loading, [isAlertTableLoading, loading]); const AlertPageFilters = (0, _react.useMemo)(() => { var _statusFilter$2; return !arePageFiltersEnabled ? /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { alignItems: "center", justifyContent: "spaceBetween" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_alerts_filter_group.AlertsTableFilterGroup, { status: (_statusFilter$2 = statusFilter[0]) !== null && _statusFilter$2 !== void 0 ? _statusFilter$2 : 'open', onFilterGroupChanged: onFilterGroupChangedCallback })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { alignItems: "center", gutterSize: "none" }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false }, updatedAt && timelinesUi.getLastUpdated({ updatedAt: updatedAt || Date.now(), showUpdating }))))) : /*#__PURE__*/_react.default.createElement(_detection_page_filters.DetectionPageFilterSet, { onFilterChange: pageFiltersUpdateHandler, filters: topLevelFilters, query: query, timeRange: { from, to, mode: 'absolute' }, chainingSystem: 'HIERARCHICAL', onInit: setDetectionPageFilterHandler }); }, [topLevelFilters, arePageFiltersEnabled, statusFilter, onFilterGroupChangedCallback, pageFiltersUpdateHandler, showUpdating, from, query, timelinesUi, to, updatedAt]); const renderAlertTable = (0, _react.useCallback)(groupingFilters => { return /*#__PURE__*/_react.default.createElement(_alerts_table.AlertsTableComponent, { configId: _constants.ALERTS_TABLE_REGISTRY_CONFIG_IDS.ALERTS_PAGE, flyoutSize: "m", inputFilters: [...alertsTableDefaultFilters, ...groupingFilters], tableId: _securitysolutionDataTable.TableId.alertsOnAlertsPage, isLoading: isAlertTableLoading }); }, [alertsTableDefaultFilters, isAlertTableLoading]); if (loading) { return /*#__PURE__*/_react.default.createElement(_page_wrapper.SecuritySolutionPageWrapper, null, /*#__PURE__*/_react.default.createElement(_header_page.HeaderPage, { border: true, title: i18n.PAGE_TITLE, isLoading: loading }), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { justifyContent: "center", alignItems: "center" }, /*#__PURE__*/_react.default.createElement(_eui.EuiLoadingSpinner, { size: "xl" }))); } if (isUserAuthenticated != null && !isUserAuthenticated && !loading) { return /*#__PURE__*/_react.default.createElement(_page_wrapper.SecuritySolutionPageWrapper, null, /*#__PURE__*/_react.default.createElement(_header_page.HeaderPage, { border: true, title: i18n.PAGE_TITLE }), /*#__PURE__*/_react.default.createElement(_detection_engine_user_unauthenticated.DetectionEngineUserUnauthenticated, null)); } if (!loading && signalIndexNeedsInit || needsListsConfiguration) { return /*#__PURE__*/_react.default.createElement(_page_wrapper.SecuritySolutionPageWrapper, null, /*#__PURE__*/_react.default.createElement(_header_page.HeaderPage, { border: true, title: i18n.PAGE_TITLE }), /*#__PURE__*/_react.default.createElement(_detection_engine_no_index.DetectionEngineNoIndex, { needsSignalsIndex: signalIndexNeedsInit, needsListsIndex: needsListsConfiguration })); } return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, hasEncryptionKey != null && !hasEncryptionKey && /*#__PURE__*/_react.default.createElement(_no_api_integration_callout.NoApiIntegrationKeyCallOut, null), /*#__PURE__*/_react.default.createElement(_need_admin_for_update_callout.NeedAdminForUpdateRulesCallOut, null), /*#__PURE__*/_react.default.createElement(_missing_privileges_callout.MissingPrivilegesCallOut, null), !signalIndexNeedsInit && (hasIndexRead === false || canUserREAD === false) ? /*#__PURE__*/_react.default.createElement(_no_privileges.NoPrivileges, { pageName: i18n.PAGE_TITLE.toLowerCase(), docLinkSelector: docLinks => docLinks.siem.privileges }) : !signalIndexNeedsInit && hasIndexRead && canUserREAD ? /*#__PURE__*/_react.default.createElement(StyledFullHeightContainer, { onKeyDown: onKeyDown, ref: containerElement }, /*#__PURE__*/_react.default.createElement(_eui.EuiWindowEvent, { event: "resize", handler: _fp.noop }), /*#__PURE__*/_react.default.createElement(_filters_global.FiltersGlobal, { show: (0, _helpers.showGlobalFilters)({ globalFullScreen, graphEventId }) }, /*#__PURE__*/_react.default.createElement(_search_bar.SiemSearchBar, { id: _constants2.InputsModelId.global, pollForSignalIndex: pollForSignalIndex, indexPattern: indexPattern })), /*#__PURE__*/_react.default.createElement(_page_wrapper.SecuritySolutionPageWrapper, { noPadding: globalFullScreen, "data-test-subj": "detectionsAlertsPage" }, /*#__PURE__*/_react.default.createElement(_display.Display, { show: !globalFullScreen }, /*#__PURE__*/_react.default.createElement(_header_page.HeaderPage, { title: i18n.PAGE_TITLE }, /*#__PURE__*/_react.default.createElement(_links.SecuritySolutionLinkButton, { onClick: goToRules, deepLinkId: _types.SecurityPageName.rules, "data-test-subj": "manage-alert-detection-rules", fill: true }, i18n.BUTTON_MANAGE_RULES)), /*#__PURE__*/_react.default.createElement(_eui.EuiHorizontalRule, { margin: "none" }), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "l" }), AlertPageFilters, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "l" }), /*#__PURE__*/_react.default.createElement(_chart_panels.ChartPanels, { addFilter: addFilter, alertsDefaultFilters: alertsDefaultFilters, isLoadingIndexPattern: isChartPanelLoading, query: query, runtimeMappings: runtimeMappings, signalIndexName: signalIndexName, updateDateRangeCallback: updateDateRangeCallback }), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "l" })), /*#__PURE__*/_react.default.createElement(_alerts_grouping.GroupedAlertsTable, { currentAlertStatusFilterValue: statusFilter, defaultFilters: alertsTableDefaultFilters, from: from, globalFilters: filters, globalQuery: query, hasIndexMaintenance: hasIndexMaintenance !== null && hasIndexMaintenance !== void 0 ? hasIndexMaintenance : false, hasIndexWrite: hasIndexWrite !== null && hasIndexWrite !== void 0 ? hasIndexWrite : false, loading: isAlertTableLoading, renderChildComponent: renderAlertTable, runtimeMappings: runtimeMappings, signalIndexName: signalIndexName, tableId: _securitysolutionDataTable.TableId.alertsOnAlertsPage, to: to }))) : /*#__PURE__*/_react.default.createElement(_landing_page.LandingPageComponent, null)); }; const mapDispatchToProps = dispatch => ({ clearSelected: ({ id }) => dispatch(_securitysolutionDataTable.dataTableActions.clearSelected({ id })), clearEventsLoading: ({ id }) => dispatch(_securitysolutionDataTable.dataTableActions.clearEventsLoading({ id })), clearEventsDeleted: ({ id }) => dispatch(_securitysolutionDataTable.dataTableActions.clearEventsDeleted({ id })) }); const connector = (0, _reactRedux.connect)(null, mapDispatchToProps); const DetectionEnginePage = connector( /*#__PURE__*/_react.default.memo(DetectionEnginePageComponent)); exports.DetectionEnginePage = DetectionEnginePage;