diff --git a/x-pack/plugins/security_solution/public/common/translations.ts b/x-pack/plugins/security_solution/public/common/translations.ts
index 551e977ec9861..676546b63b224 100644
--- a/x-pack/plugins/security_solution/public/common/translations.ts
+++ b/x-pack/plugins/security_solution/public/common/translations.ts
@@ -77,7 +77,7 @@ export const UNSAVED_TIMELINE_SAVE_PROMPT_TITLE = i18n.translate(
export const getAgentTypeName = (agentType: ResponseActionAgentType) => {
switch (agentType) {
case 'endpoint':
- return 'Endpoint';
+ return 'Elastic Defend';
case 'sentinel_one':
return 'SentinelOne';
default:
diff --git a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts
index 8a4d98ae76f90..62772fa029e66 100644
--- a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts
+++ b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts
@@ -39,7 +39,7 @@ const getThirdPartyAgentInfo = (
) as ResponseActionAgentType,
},
host: {
- name: getFieldValue({ category: 'host', field: 'host.os.name' }, eventData),
+ name: getFieldValue({ category: 'host', field: 'host.name' }, eventData),
os: {
name: getFieldValue({ category: 'host', field: 'host.os.name' }, eventData),
family: getFieldValue({ category: 'host', field: 'host.os.family' }, eventData),
diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx
index 03268178bc3d9..5a44f6584520a 100644
--- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx
@@ -9,6 +9,8 @@ import React, { memo, useMemo } from 'react';
import { EuiCodeBlock, EuiDescriptionList, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { css, euiStyled } from '@kbn/kibana-react-plugin/common';
import { map } from 'lodash';
+import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
+import { getAgentTypeName } from '../../../../common/translations';
import { RESPONSE_ACTION_API_COMMAND_TO_CONSOLE_COMMAND_MAP } from '../../../../../common/endpoint/service/response_actions/constants';
import {
isExecuteAction,
@@ -178,7 +180,19 @@ export const ActionsLogExpandedTray = memo<{
}>(({ action, 'data-test-subj': dataTestSubj }) => {
const getTestId = useTestIdGenerator(dataTestSubj);
- const { hosts, startedAt, completedAt, command: _command, comment, parameters } = action;
+ const isSentinelOneV1Enabled = useIsExperimentalFeatureEnabled(
+ 'responseActionsSentinelOneV1Enabled'
+ );
+
+ const {
+ hosts,
+ startedAt,
+ completedAt,
+ command: _command,
+ comment,
+ parameters,
+ agentType,
+ } = action;
const parametersList = useMemo(
() =>
@@ -192,45 +206,61 @@ export const ActionsLogExpandedTray = memo<{
const command = RESPONSE_ACTION_API_COMMAND_TO_CONSOLE_COMMAND_MAP[_command];
- const dataList = useMemo(
- () =>
- [
- {
- title: OUTPUT_MESSAGES.expandSection.placedAt,
- description: `${startedAt}`,
- },
- {
- title: OUTPUT_MESSAGES.expandSection.startedAt,
- description: `${startedAt}`,
- },
- {
- title: OUTPUT_MESSAGES.expandSection.completedAt,
- description: `${completedAt ?? emptyValue}`,
- },
- {
- title: OUTPUT_MESSAGES.expandSection.input,
- description: `${command}`,
- },
- {
- title: OUTPUT_MESSAGES.expandSection.parameters,
- description: parametersList ? parametersList.join(', ') : emptyValue,
- },
- {
- title: OUTPUT_MESSAGES.expandSection.comment,
- description: comment ? comment : emptyValue,
- },
- {
- title: OUTPUT_MESSAGES.expandSection.hostname,
- description: map(hosts, (host) => host.name).join(', ') || emptyValue,
- },
- ].map(({ title, description }) => {
- return {
- title: {title},
- description: {description},
- };
- }),
- [command, comment, completedAt, hosts, parametersList, startedAt]
- );
+ const dataList = useMemo(() => {
+ const list = [
+ {
+ title: OUTPUT_MESSAGES.expandSection.placedAt,
+ description: `${startedAt}`,
+ },
+ {
+ title: OUTPUT_MESSAGES.expandSection.startedAt,
+ description: `${startedAt}`,
+ },
+ {
+ title: OUTPUT_MESSAGES.expandSection.completedAt,
+ description: `${completedAt ?? emptyValue}`,
+ },
+ {
+ title: OUTPUT_MESSAGES.expandSection.input,
+ description: `${command}`,
+ },
+ {
+ title: OUTPUT_MESSAGES.expandSection.parameters,
+ description: parametersList ? parametersList.join(', ') : emptyValue,
+ },
+ {
+ title: OUTPUT_MESSAGES.expandSection.comment,
+ description: comment ? comment : emptyValue,
+ },
+ {
+ title: OUTPUT_MESSAGES.expandSection.hostname,
+ description: map(hosts, (host) => host.name).join(', ') || emptyValue,
+ },
+ ];
+
+ if (isSentinelOneV1Enabled) {
+ list.push({
+ title: OUTPUT_MESSAGES.expandSection.agentType,
+ description: getAgentTypeName(agentType) || emptyValue,
+ });
+ }
+
+ return list.map(({ title, description }) => {
+ return {
+ title: {title},
+ description: {description},
+ };
+ });
+ }, [
+ agentType,
+ command,
+ comment,
+ completedAt,
+ hosts,
+ isSentinelOneV1Enabled,
+ parametersList,
+ startedAt,
+ ]);
const outputList = useMemo(
() => [
diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx
index 36d5d8d1f556b..b8e08f557aa2d 100644
--- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx
@@ -189,18 +189,28 @@ const getTypesFilterInitialState = (
// v8.13 onwards
// for showing agent types and action types in the same filter
if (isSentinelOneV1Enabled) {
+ if (!isFlyout) {
+ return [
+ {
+ label: FILTER_NAMES.agentTypes,
+ isGroupLabel: true,
+ },
+ ...RESPONSE_ACTION_AGENT_TYPE.map((type) =>
+ getFilterOptions({
+ key: type,
+ label: getAgentTypeName(type),
+ checked: !isFlyout && agentTypes?.includes(type) ? 'on' : undefined,
+ })
+ ),
+ {
+ label: FILTER_NAMES.actionTypes,
+ isGroupLabel: true,
+ },
+ ...defaultFilterOptions,
+ ];
+ }
+
return [
- {
- label: FILTER_NAMES.agentTypes,
- isGroupLabel: true,
- },
- ...RESPONSE_ACTION_AGENT_TYPE.map((type) =>
- getFilterOptions({
- key: type,
- label: getAgentTypeName(type),
- checked: !isFlyout && agentTypes?.includes(type) ? 'on' : undefined,
- })
- ),
{
label: FILTER_NAMES.actionTypes,
isGroupLabel: true,
@@ -336,7 +346,10 @@ export const useActionsLogFilter = ({
() => items.filter((item) => item.checked === 'on').length,
[items]
);
- const numFilters = useMemo(() => items.filter((item) => item.checked !== 'on').length, [items]);
+ const numFilters = useMemo(
+ () => items.filter((item) => item.key && item.checked !== 'on').length,
+ [items]
+ );
return {
areHostsSelectedOnMount,
diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx
index 2b909e637bd20..3486da1191b4c 100644
--- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx
@@ -28,8 +28,10 @@ import { getActionListMock } from '../mocks';
import { useGetEndpointsList } from '../../../hooks/endpoint/use_get_endpoints_list';
import { v4 as uuidv4 } from 'uuid';
import {
+ RESPONSE_ACTION_AGENT_TYPE,
RESPONSE_ACTION_API_COMMAND_TO_CONSOLE_COMMAND_MAP,
RESPONSE_ACTION_API_COMMANDS_NAMES,
+ RESPONSE_ACTION_TYPE,
} from '../../../../../common/endpoint/service/response_actions/constants';
import { useUserPrivileges as _useUserPrivileges } from '../../../../common/components/user_privileges';
import { responseActionsHttpMocks } from '../../../mocks/response_actions_http_mocks';
@@ -571,6 +573,30 @@ describe('Response actions history', () => {
);
});
+ it('should contain agent type info in each expanded row', async () => {
+ mockedContext.setExperimentalFlag({ responseActionsSentinelOneV1Enabled: true });
+ render();
+ const { getAllByTestId } = renderResult;
+
+ const expandButtons = getAllByTestId(`${testPrefix}-expand-button`);
+ expandButtons.map((button) => userEvent.click(button));
+ const trays = getAllByTestId(`${testPrefix}-details-tray`);
+ expect(trays).toBeTruthy();
+ expect(Array.from(trays[0].querySelectorAll('dt')).map((title) => title.textContent)).toEqual(
+ [
+ 'Command placed',
+ 'Execution started on',
+ 'Execution completed',
+ 'Input',
+ 'Parameters',
+ 'Comment',
+ 'Hostname',
+ 'Agent type',
+ 'Output:',
+ ]
+ );
+ });
+
it('should refresh data when autoRefresh is toggled on', async () => {
const listHookResponse = getBaseMockedActionList();
useGetEndpointActionListMock.mockReturnValue(listHookResponse);
@@ -1380,4 +1406,49 @@ describe('Response actions history', () => {
);
});
});
+
+ describe('Types filter', () => {
+ const filterPrefix = 'types-filter';
+ it('should show a list of action types when opened', () => {
+ render();
+ const { getByTestId, getAllByTestId } = renderResult;
+
+ userEvent.click(getByTestId(`${testPrefix}-${filterPrefix}-popoverButton`));
+ const filterList = getByTestId(`${testPrefix}-${filterPrefix}-popoverList`);
+ expect(filterList).toBeTruthy();
+ expect(getAllByTestId(`${filterPrefix}-option`).length).toEqual(RESPONSE_ACTION_TYPE.length);
+ expect(getAllByTestId(`${filterPrefix}-option`).map((option) => option.textContent)).toEqual([
+ 'Triggered by rule',
+ 'Triggered manually',
+ ]);
+ });
+
+ it('should show a list of agent and action types when opened in page view', () => {
+ mockedContext.setExperimentalFlag({ responseActionsSentinelOneV1Enabled: true });
+ render({ isFlyout: false });
+ const { getByTestId, getAllByTestId } = renderResult;
+
+ userEvent.click(getByTestId(`${testPrefix}-${filterPrefix}-popoverButton`));
+ const filterList = getByTestId(`${testPrefix}-${filterPrefix}-popoverList`);
+ expect(filterList).toBeTruthy();
+ expect(getAllByTestId(`${filterPrefix}-option`).length).toEqual(
+ [...RESPONSE_ACTION_AGENT_TYPE, ...RESPONSE_ACTION_TYPE].length
+ );
+ expect(getAllByTestId(`${filterPrefix}-option`).map((option) => option.textContent)).toEqual([
+ 'Elastic Defend',
+ 'SentinelOne',
+ 'Triggered by rule',
+ 'Triggered manually',
+ ]);
+ });
+
+ it('should have `clear all` button `disabled` when no selected values', () => {
+ render();
+ const { getByTestId } = renderResult;
+
+ userEvent.click(getByTestId(`${testPrefix}-${filterPrefix}-popoverButton`));
+ const clearAllButton = getByTestId(`${testPrefix}-${filterPrefix}-clearAllButton`);
+ expect(clearAllButton.hasAttribute('disabled')).toBeTruthy();
+ });
+ });
});
diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx
index 907348790e92d..b11f31bbd1b72 100644
--- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx
@@ -77,6 +77,12 @@ export const OUTPUT_MESSAGES = Object.freeze({
defaultMessage: 'Hostname',
}
),
+ agentType: i18n.translate(
+ 'xpack.securitySolution.responseActionsList.list.item.expandSection.agentType',
+ {
+ defaultMessage: 'Agent type',
+ }
+ ),
},
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx
index 19ce46111d1c7..65cd4ffc09908 100644
--- a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx
@@ -437,7 +437,7 @@ describe('Response actions history page', () => {
}, []);
expect(selectedFilterOptions.length).toEqual(1);
- expect(selectedFilterOptions).toEqual(['Endpoint. Checked option.']);
+ expect(selectedFilterOptions).toEqual(['Elastic Defend. Checked option.']);
expect(history.location.search).toEqual('?agentTypes=endpoint');
});
});