"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.EventDetail = void 0; var _react = _interopRequireWildcard(require("react")); var _i18n = require("@kbn/i18n"); var _i18nReact = require("@kbn/i18n-react"); var _eui = require("@elastic/eui"); var _styledComponents = _interopRequireDefault(require("styled-components")); var _reactRedux = require("react-redux"); var _styles = require("../styles"); var _styles2 = require("./styles"); var _generated_text = require("../generated_text"); var _copyable_panel_field = require("./copyable_panel_field"); var _breadcrumbs = require("./breadcrumbs"); var eventModel = _interopRequireWildcard(require("../../../../common/endpoint/models/event")); var selectors = _interopRequireWildcard(require("../../store/selectors")); var _panel_loading = require("./panel_loading"); var _panel_content_error = require("./panel_content_error"); var _descriptive_name = require("./descriptive_name"); var _use_link_props = require("../use_link_props"); var _deep_object_entries = require("./deep_object_entries"); var _use_formatted_date = require("./use_formatted_date"); var nodeDataModel = _interopRequireWildcard(require("../../models/node_data")); var _expand_dotted = require("../../../../common/utils/expand_dotted"); 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. */ /* eslint-disable no-continue */ const eventDetailRequestError = _i18n.i18n.translate('xpack.securitySolution.resolver.panel.eventDetail.requestError', { defaultMessage: 'Event details were unable to be retrieved' }); const EventDetail = /*#__PURE__*/(0, _react.memo)(function EventDetail({ id, nodeID, eventCategory: eventType }) { const isEventLoading = (0, _reactRedux.useSelector)(state => selectors.isCurrentRelatedEventLoading(state.analyzer[id])); const isTreeLoading = (0, _reactRedux.useSelector)(state => selectors.isTreeLoading(state.analyzer[id])); const processEvent = (0, _reactRedux.useSelector)(state => nodeDataModel.firstEvent(selectors.nodeDataForID(state.analyzer[id])(nodeID))); const nodeStatus = (0, _reactRedux.useSelector)(state => selectors.nodeDataStatus(state.analyzer[id])(nodeID)); const isNodeDataLoading = nodeStatus === 'loading'; const isLoading = isEventLoading || isTreeLoading || isNodeDataLoading; const event = (0, _reactRedux.useSelector)(state => selectors.currentRelatedEventData(state.analyzer[id])); return isLoading ? /*#__PURE__*/_react.default.createElement(_styles.StyledPanel, { hasBorder: true }, /*#__PURE__*/_react.default.createElement(_panel_loading.PanelLoading, { id: id })) : event ? /*#__PURE__*/_react.default.createElement(EventDetailContents, { id: id, nodeID: nodeID, event: event, processEvent: processEvent, eventType: eventType }) : /*#__PURE__*/_react.default.createElement(_styles.StyledPanel, { hasBorder: true }, /*#__PURE__*/_react.default.createElement(_panel_content_error.PanelContentError, { id: id, translatedErrorMessage: eventDetailRequestError })); }); /** * This view presents a detailed view of all the available data for a related event, split and titled by the "section" * it appears in the underlying ResolverEvent */ // eslint-disable-next-line react/display-name exports.EventDetail = EventDetail; const EventDetailContents = /*#__PURE__*/(0, _react.memo)(function ({ id, nodeID, event, eventType, processEvent }) { const timestamp = eventModel.timestampSafeVersion(event); const formattedDate = (0, _use_formatted_date.useFormattedDate)(timestamp) || _i18n.i18n.translate('xpack.securitySolution.enpdoint.resolver.panelutils.noTimestampRetrieved', { defaultMessage: 'No timestamp retrieved' }); const nodeName = processEvent ? eventModel.processNameSafeVersion(processEvent) : null; return /*#__PURE__*/_react.default.createElement(_styles.StyledPanel, { hasBorder: true, "data-test-subj": "resolver:panel:event-detail" }, /*#__PURE__*/_react.default.createElement(EventDetailBreadcrumbs, { id: id, nodeID: nodeID, nodeName: nodeName, event: event, breadcrumbEventCategory: eventType }), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "l" }), /*#__PURE__*/_react.default.createElement(_eui.EuiText, { size: "s" }, /*#__PURE__*/_react.default.createElement(_styles2.BoldCode, null, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.categoryAndType", values: { category: eventType, eventType: String(eventModel.eventType(event)) }, defaultMessage: "{category} {eventType}" })), /*#__PURE__*/_react.default.createElement(_styles2.StyledTime, { dateTime: formattedDate }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.atTime", values: { date: formattedDate }, defaultMessage: "@ {date}" }))), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(StyledDescriptiveName, null, /*#__PURE__*/_react.default.createElement(_generated_text.GeneratedText, null, /*#__PURE__*/_react.default.createElement(_descriptive_name.DescriptiveName, { event: event }))), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "l" }), /*#__PURE__*/_react.default.createElement(EventDetailFields, { event: event })); }); function EventDetailFields({ event }) { const sections = (0, _react.useMemo)(() => { const returnValue = []; const expandedEventObject = (0, _expand_dotted.expandDottedObject)(event); for (const [key, value] of Object.entries(expandedEventObject)) { // ignore these keys if (key === 'agent' || key === 'ecs' || key === '@timestamp' || !value) { continue; } const section = { // Group the fields by their top-level namespace namespace: /*#__PURE__*/_react.default.createElement(_generated_text.GeneratedText, null, key), descriptions: (0, _deep_object_entries.deepObjectEntries)(value).map(([path, fieldValue]) => { // The field name is the 'namespace' key as well as the rest of the path, joined with '.' const fieldName = [key, ...path].join('.'); return { title: /*#__PURE__*/_react.default.createElement(_generated_text.GeneratedText, null, fieldName), description: /*#__PURE__*/_react.default.createElement(_copyable_panel_field.CopyablePanelField, { textToCopy: String(fieldValue), content: /*#__PURE__*/_react.default.createElement(_generated_text.GeneratedText, null, String(fieldValue)) }) }; }) }; returnValue.push(section); } return returnValue; }, [event]); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, sections.map(({ namespace, descriptions }, index) => { return /*#__PURE__*/_react.default.createElement(_react.Fragment, { key: index }, index === 0 ? null : /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(_eui.EuiTitle, { size: "xxxs" }, /*#__PURE__*/_react.default.createElement(_eui.EuiTextColor, { color: "subdued" }, /*#__PURE__*/_react.default.createElement(StyledFlexTitle, null, namespace, /*#__PURE__*/_react.default.createElement(TitleHr, null)))), /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" }), /*#__PURE__*/_react.default.createElement(StyledDescriptionList, { type: "column", align: "left", titleProps: { className: 'desc-title', 'data-test-subj': 'resolver:panel:event-detail:event-field-title' }, compressed: true, listItems: descriptions }), index === sections.length - 1 ? null : /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, { size: "m" })); })); } function EventDetailBreadcrumbs({ id, nodeID, nodeName, event, breadcrumbEventCategory }) { const countByCategory = (0, _reactRedux.useSelector)(state => selectors.relatedEventCountOfTypeForNode(state.analyzer[id])(nodeID, breadcrumbEventCategory)); const relatedEventCount = (0, _reactRedux.useSelector)(state => selectors.relatedEventTotalCount(state.analyzer[id])(nodeID)); const nodesLinkNavProps = (0, _use_link_props.useLinkProps)(id, { panelView: 'nodes' }); const nodeDetailLinkNavProps = (0, _use_link_props.useLinkProps)(id, { panelView: 'nodeDetail', panelParameters: { nodeID } }); const nodeEventsLinkNavProps = (0, _use_link_props.useLinkProps)(id, { panelView: 'nodeEvents', panelParameters: { nodeID } }); const nodeEventsInCategoryLinkNavProps = (0, _use_link_props.useLinkProps)(id, { panelView: 'nodeEventsInCategory', panelParameters: { nodeID, eventCategory: breadcrumbEventCategory } }); const breadcrumbs = (0, _react.useMemo)(() => { const crumbs = [{ text: _i18n.i18n.translate('xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.events', { defaultMessage: 'Events' }), 'data-test-subj': 'resolver:event-detail:breadcrumbs:node-list-link', ...nodesLinkNavProps }, { text: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.numberOfEvents", values: { totalCount: relatedEventCount }, defaultMessage: "{totalCount} Events" }), ...nodeEventsLinkNavProps }, { text: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, { id: "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.countByCategory", values: { count: countByCategory, category: breadcrumbEventCategory }, defaultMessage: "{count} {category}" }), ...nodeEventsInCategoryLinkNavProps }, { text: /*#__PURE__*/_react.default.createElement(_descriptive_name.DescriptiveName, { event: event }) }]; if (nodeName) { crumbs.splice(1, 0, { text: nodeName, ...nodeDetailLinkNavProps }); } return crumbs; }, [breadcrumbEventCategory, countByCategory, event, nodeDetailLinkNavProps, nodeEventsLinkNavProps, nodeName, relatedEventCount, nodesLinkNavProps, nodeEventsInCategoryLinkNavProps]); return /*#__PURE__*/_react.default.createElement(_breadcrumbs.Breadcrumbs, { breadcrumbs: breadcrumbs }); } const StyledDescriptionList = /*#__PURE__*/(0, _react.memo)((0, _styledComponents.default)(_eui.EuiDescriptionList)` &.euiDescriptionList.euiDescriptionList--column dt.euiDescriptionList__title.desc-title { max-width: 8em; overflow-wrap: break-word; } &.euiDescriptionList.euiDescriptionList--column dd.euiDescriptionList__description { max-width: calc(100% - 8.5em); overflow-wrap: break-word; } `); // Also prevents horizontal scrollbars on long descriptive names const StyledDescriptiveName = /*#__PURE__*/(0, _react.memo)((0, _styledComponents.default)(_eui.EuiText)` padding-right: 1em; overflow-wrap: break-word; `); const StyledFlexTitle = /*#__PURE__*/(0, _react.memo)((0, _styledComponents.default)('h3')` align-items: center; display: flex; flex-flow: row; font-size: 1.2em; `); // eslint-disable-next-line react/display-name const TitleHr = /*#__PURE__*/(0, _react.memo)(() => { return /*#__PURE__*/_react.default.createElement(_eui.EuiHorizontalRule, { margin: "none", size: "half" }); });