From cc5fc3ffb098ac8314b7d7cbf0d876dcd737b646 Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Fri, 24 May 2024 09:20:24 -0300 Subject: [PATCH 1/2] Fix discover flyout and improve events columns (#6691) * Fix events flyout and improve events columns * Update CHANGELOG * Update snapshot * Improve discover column renderers * Remove mitre attack columns displayAsText * Modularize renderColumns for Discover --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- .../__snapshots__/inventory.test.tsx.snap | 54 ++++------ .../common/data-grid/use-data-grid.ts | 23 +++-- .../common/wazuh-discover/render-columns.tsx | 81 +++++++++++++++ .../common/wazuh-discover/wz-discover.tsx | 38 +------ .../mitre/events/mitre-attack-columns.tsx | 82 ++-------------- .../office/events/office-365-columns.tsx | 16 +-- .../threat-hunting/dashboard/dashboard.tsx | 20 ++-- .../events/threat-hunting-columns.tsx | 98 ++----------------- 9 files changed, 147 insertions(+), 267 deletions(-) create mode 100644 plugins/main/public/components/common/wazuh-discover/render-columns.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc0bb77e4..162cce0009 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6286](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6286) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6459](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6459) [#6434](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6434) [#6504](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6504) [#6649](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6649) [#6506](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6506) [#6537](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6537) [#6528](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6528) [#6675](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6675) [#6674](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6674) [#6558](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6558) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6286](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6286) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6459](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6459) [#6434](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6434) [#6504](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6504) [#6649](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6649) [#6506](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6506) [#6537](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6537) [#6528](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6528) [#6675](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6675) [#6674](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6674) [#6558](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6558) [#6691](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6691) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) - Change how the configuration is managed in the backend side [#6337](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6337) [#6519](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6519) [#6573](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6573) diff --git a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap index df26ef4255..d048bbcd49 100644 --- a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap +++ b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap @@ -2,18 +2,16 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = `
string | React.ReactNode; + render?: (value: any, rowItem: object) => string | React.ReactNode; } & EuiDataGridColumn; +export type tDataGridRenderColumn = Required> & + Omit; + export type tDataGridProps = { indexPattern: IndexPattern; results: SearchResponse; defaultColumns: tDataGridColumn[]; + renderColumns?: tDataGridRenderColumn[]; DocViewInspectButton: ({ rowIndex, }: EuiDataGridCellValueElementProps) => React.JSX.Element; @@ -42,6 +42,7 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { DocViewInspectButton, results, defaultColumns, + renderColumns, pagination: defaultPagination, } = props; /** Columns **/ @@ -115,11 +116,19 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { // check if column have render method initialized const column = columns.find(column => column.id === columnId); if (column && column.render) { - return column.render( + return column.render(fieldFormatted, rowsParsed[relativeRowIndex]); + } + // check if column have render method in renderColumns prop + const renderColumn = renderColumns?.find( + column => column.id === columnId, + ); + if (renderColumn) { + return renderColumn.render( fieldFormatted, - rowsParsed[relativeRowIndex] + rowsParsed[relativeRowIndex], ); } + return fieldFormatted; } return null; diff --git a/plugins/main/public/components/common/wazuh-discover/render-columns.tsx b/plugins/main/public/components/common/wazuh-discover/render-columns.tsx new file mode 100644 index 0000000000..483b056a85 --- /dev/null +++ b/plugins/main/public/components/common/wazuh-discover/render-columns.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import { EuiLink } from '@elastic/eui'; +import { tDataGridRenderColumn } from '../data-grid'; +import { getCore } from '../../../kibana-services'; +import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; +import { endpointSummary, rules } from '../../../utils/applications'; +import { AppNavigate, formatUIDate } from '../../../react-services'; + +export const MAX_ENTRIES_PER_QUERY = 10000; + +const navigateTo = (ev, section, params) => { + AppNavigate.navigateToModule(ev, section, params); +}; + +const renderMitreTechnique = (technique: string) => + navigateTo(e, 'overview', { + tab: 'mitre', + tabView: 'intelligence', + tabRedirect: 'techniques', + idToRedirect: technique, + }) + } +> + {technique} + + +export const wzDiscoverRenderColumns: tDataGridRenderColumn[] = [ + { + id: 'agent.id', + render: (value) => { + if (value === '000') return value + + return + + {value} + + + } + }, + { + id: 'agent.name', + render: (value, row) => { + if (row.agent.id === '000') return value + + return + + {value} + + + } + }, + { + id: 'rule.id', + render: (value) => + + {value} + + + }, + { + id: 'rule.mitre.id', + render: (value) => Array.isArray(value) ?
+ {value?.map(technique => ( +
+ {renderMitreTechnique(technique)} +
+ ))} +
:
+ {renderMitreTechnique(value)} +
+ }, + { + id: 'timestamp', + render: (value) => formatUIDate(value) + }, +] \ No newline at end of file diff --git a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx index 11855a2cee..90f68d923c 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx @@ -13,7 +13,6 @@ import { EuiTitle, EuiSpacer, EuiPanel, - EuiLink, } from '@elastic/eui'; import { IntlProvider } from 'react-intl'; import { IndexPattern } from '../../../../../../src/plugins/data/common'; @@ -28,7 +27,7 @@ import { HttpError, } from '../../../react-services/error-management'; import useSearchBar from '../search-bar/use-search-bar'; -import { getCore, getPlugins } from '../../../kibana-services'; +import { getPlugins } from '../../../kibana-services'; import { histogramChartInput } from './config/histogram-chart'; import { getWazuhCorePlugin } from '../../../kibana-services'; const DashboardByRenderer = @@ -43,8 +42,7 @@ import { AlertsDataSourceRepository, } from '../data-source'; import DiscoverDataGridAdditionalControls from './components/data-grid-additional-controls'; -import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { endpointSummary } from '../../../utils/applications'; +import { wzDiscoverRenderColumns } from './render-columns'; export const MAX_ENTRIES_PER_QUERY = 10000; @@ -89,6 +87,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { [results], ); + const DocViewInspectButton = ({ rowIndex, }: EuiDataGridCellValueElementProps) => { @@ -114,6 +113,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { const dataGridProps = useDataGrid({ ariaLabelledBy: 'Discover events table', defaultColumns: defaultTableColumns, + renderColumns: wzDiscoverRenderColumns, results, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, @@ -137,35 +137,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { sorting, dateRange: { from: dateRangeFrom || '', to: dateRangeTo || '' }, }) - .then(results => { - results?.hits?.hits.map(value => { - const agentId = value._source.agent.id; - const agentName = value._source.agent.name; - if (agentId === '000') { - return value; - } - value._source.agent.name = ( - - - {agentName} - - - ); - value._source.agent.id = ( - - - {agentId} - - - ); - return value; - }); - setResults(results); - }) + .then(results => setResults(results)) .catch(error => { const searchError = ErrorFactory.create(HttpError, { error, diff --git a/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx b/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx index 6aeda38cdf..a080f31044 100644 --- a/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx +++ b/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx @@ -1,79 +1,11 @@ -import { EuiLink } from '@elastic/eui'; -import { AppNavigate } from '../../../../react-services'; import { tDataGridColumn } from '../../../common/data-grid'; -import React from 'react'; -import { formatUIDate } from '../../../../react-services'; -import { getCore } from '../../../../kibana-services'; -import { rules } from '../../../../utils/applications'; -import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; - -const navigateTo = (ev, section, params) => { - AppNavigate.navigateToModule(ev, section, params); -}; - -const renderTechniques = (value: []) => { - return ( -
- {value.length && - value.map(technique => ( -
- - navigateTo(e, 'overview', { - tab: 'mitre', - tabView: 'intelligence', - tabRedirect: 'techniques', - idToRedirect: technique, - }) - } - > - {technique} - -
- ))} -
- ); -}; export const mitreAttackColumns: tDataGridColumn[] = [ - { - id: 'timestamp', - displayAsText: 'Time', - render: value => formatUIDate(value), - }, - { - id: 'agent.name', - displayAsText: 'Agent Name', - render: (value: string, item: any) => { - return ( - - navigateTo(e, 'agents', { tab: 'welcome', agent: item.agent.id }) - } - > - {value} - - ); - }, - }, - { - id: 'rule.mitre.id', - displayAsText: 'Technique(s)', - render: value => renderTechniques(value), - }, - { id: 'rule.mitre.tactic', displayAsText: 'Tactic(s)' }, - { id: 'rule.description', displayAsText: 'Description' }, - { id: 'rule.level', displayAsText: 'Level' }, - { - id: 'rule.id', - displayAsText: 'Rule ID', - render: value => ( - - - {value} - - - ), - }, + { id: 'timestamp' }, + { id: 'agent.name' }, + { id: 'rule.mitre.id' }, + { id: 'rule.mitre.tactic' }, + { id: 'rule.description' }, + { id: 'rule.level' }, + { id: 'rule.id' }, ]; diff --git a/plugins/main/public/components/overview/office/events/office-365-columns.tsx b/plugins/main/public/components/overview/office/events/office-365-columns.tsx index 4fb1d2d511..06b16fb40d 100644 --- a/plugins/main/public/components/overview/office/events/office-365-columns.tsx +++ b/plugins/main/public/components/overview/office/events/office-365-columns.tsx @@ -1,9 +1,4 @@ -import React from 'react'; import { tDataGridColumn } from '../../../common/data-grid'; -import { EuiLink } from '@elastic/eui'; -import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { getCore } from '../../../../kibana-services'; -import { rules } from '../../../../utils/applications'; export const office365Columns: tDataGridColumn[] = [ { @@ -22,15 +17,6 @@ export const office365Columns: tDataGridColumn[] = [ id: 'rule.level', }, { - id: 'rule.id', - render: value => ( - - - {value} - - - ), + id: 'rule.id' }, ]; diff --git a/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx b/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx index 76f326e29b..66c2b6b888 100644 --- a/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx +++ b/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx @@ -52,6 +52,7 @@ import { import { DiscoverNoResults } from '../../../common/no-results/no-results'; import { LoadingSpinner } from '../../../common/loading-spinner/loading-spinner'; import { useReportingCommunicateSearchContext } from '../../../common/hooks/use-reporting-communicate-search-context'; +import { wzDiscoverRenderColumns } from '../../../common/wazuh-discover/render-columns'; const plugins = getPlugins(); @@ -112,6 +113,7 @@ const DashboardTH: React.FC = () => { const dataGridProps = useDataGrid({ ariaLabelledBy: 'Threat Hunting Table', defaultColumns: threatHuntingTableDefaultColumns, + renderColumns: wzDiscoverRenderColumns, results, indexPattern: dataSource?.indexPattern, DocViewInspectButton, @@ -282,18 +284,18 @@ const DashboardTH: React.FC = () => { {}} + onResetQuery={() => { }} tooltip={ results?.hits?.total && - results?.hits?.total > MAX_ENTRIES_PER_QUERY + results?.hits?.total > MAX_ENTRIES_PER_QUERY ? { - ariaLabel: 'Warning', - content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas( - MAX_ENTRIES_PER_QUERY, - )} hits.`, - iconType: 'alert', - position: 'top', - } + ariaLabel: 'Warning', + content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas( + MAX_ENTRIES_PER_QUERY, + )} hits.`, + iconType: 'alert', + position: 'top', + } : undefined } /> diff --git a/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx b/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx index 1cd9200b71..87bda4ea92 100644 --- a/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx +++ b/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx @@ -1,13 +1,5 @@ -import { EuiDataGridColumn, EuiLink } from '@elastic/eui'; +import { EuiDataGridColumn } from '@elastic/eui'; import { tDataGridColumn } from '../../../common/data-grid'; -import { getCore } from '../../../../kibana-services'; -import React from 'react'; -import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { - endpointSummary, - mitreAttack, - rules, -} from '../../../../utils/applications'; export const MAX_ENTRIES_PER_QUERY = 10000; @@ -19,55 +11,13 @@ export const threatHuntingTableDefaultColumns: tDataGridColumn[] = [ id: 'timestamp', }, { - id: 'agent.id', - render: (value: any) => { - if (value === '000') { - return value; - } - const destURL = getCore().application.getUrlForApp(endpointSummary.id, { - path: `#/agents?tab=welcome&agent=${value}`, - }); - return ( - - - {value} - - - ); - }, - }, - { - id: 'agent.name', - render: (value: any, _source) => { - if (_source.agent.id === '000') { - return value; - } - const destURL = getCore().application.getUrlForApp(endpointSummary.id, { - path: `#/agents?tab=welcome&agent=${_source.agent.id}`, - }); - return ( - - - {value} - - - ); - }, + id: 'agent.id' + }, + { + id: 'agent.name' }, { id: 'rule.mitre.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(mitreAttack.id, { - path: `#/overview/?tab=mitre&tabView=intelligence&tabRedirect=techniques&idToRedirect=${value}`, - }); - return ( - - - {value} - - - ); - }, }, { id: 'rule.mitre.tactic', @@ -79,19 +29,7 @@ export const threatHuntingTableDefaultColumns: tDataGridColumn[] = [ id: 'rule.level', }, { - id: 'rule.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(rules.id, { - path: `manager/?tab=ruleset&redirectRule=${value}`, - }); - return ( - - - {value} - - - ); - }, + id: 'rule.id' }, ]; @@ -104,18 +42,6 @@ export const threatHuntingTableAgentColumns: EuiDataGridColumn[] = [ }, { id: 'rule.mitre.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(mitreAttack.id, { - path: `#/overview/?tab=mitre&tabView=intelligence&tabRedirect=techniques&idToRedirect=${value}`, - }); - return ( - - - {value} - - - ); - }, }, { id: 'rule.mitre.tactic', @@ -128,17 +54,5 @@ export const threatHuntingTableAgentColumns: EuiDataGridColumn[] = [ }, { id: 'rule.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(rules.id, { - path: `manager/?tab=ruleset&redirectRule=${value}`, - }); - return ( - - - {value} - - - ); - }, }, ]; From cc93456b999df899da8c2458f3cec3a3383c0701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chantal=20Bel=C3=A9n=20kelm?= <99441266+chantal-kelm@users.noreply.github.com> Date: Mon, 27 May 2024 12:57:54 -0300 Subject: [PATCH 2/2] Fix invalid prop children of type array supplied to I18nProvider (#6698) fix invalid prop children of type array supplied to I18nProvider --- .../public/components/overview/mitre/framework/mitre.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/main/public/components/overview/mitre/framework/mitre.tsx b/plugins/main/public/components/overview/mitre/framework/mitre.tsx index d4b6899a6c..8581611100 100644 --- a/plugins/main/public/components/overview/mitre/framework/mitre.tsx +++ b/plugins/main/public/components/overview/mitre/framework/mitre.tsx @@ -155,8 +155,8 @@ const MitreComponent = props => { }; return ( -
- + + <> {isDataSourceLoading && !dataSource ? ( @@ -211,8 +211,8 @@ const MitreComponent = props => { - -
+ + ); };