From cb4d6aa8d50d02aa52bfbd32d5cac265522d5d0e Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Thu, 28 Jul 2022 10:09:54 -0400 Subject: [PATCH] [Security Solution][Endpoint] Display better success and failure messages for kill suspend process actions (#137353) * add map with endpoint action response code and associated i18n message * Add component to handle getting a failure message from a completed action * Add component to handle getting a failure message from a completed action * Correct type definition for ActionResponseOutput * New ActionSuccess component + use it in kill/suspend process * Change default failure message * add some jsdocs to the endpoint codes --- .../common/endpoint/types/actions.ts | 26 +++++-- .../management/components/console/index.ts | 11 ++- .../endpoint_action_failure_message.tsx | 71 +++++++++++++++++++ .../endpoint_action_failure_message/index.ts | 8 +++ .../endpoint_responder/action_error.tsx | 18 ++--- .../endpoint_responder/action_success.tsx | 37 ++++++++++ .../endpoint_action_response_codes.ts | 69 ++++++++++++++++++ .../get_processes_action.tsx | 20 ++++-- .../endpoint_responder/isolate_action.tsx | 2 +- .../kill_process_action.tsx | 39 ++++++---- .../endpoint_responder/release_action.tsx | 2 +- .../suspend_process_action.tsx | 31 +++++--- .../hooks/endpoint/use_get_action_details.ts | 10 +-- ...use_send_get_endpoint_processes_request.ts | 19 +++-- .../mocks/response_actions_http_mocks.ts | 8 +-- .../endpoint/action_responder/utils.ts | 4 +- 16 files changed, 304 insertions(+), 71 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/endpoint_action_failure_message.tsx create mode 100644 x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/index.ts create mode 100644 x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_success.tsx create mode 100644 x-pack/plugins/security_solution/public/management/components/endpoint_responder/endpoint_action_response_codes.ts diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index 8dee4af154e61..bfd35294a30fa 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -18,9 +18,7 @@ export type ISOLATION_ACTIONS = 'isolate' | 'unisolate'; /** The output provided by some of the Endpoint responses */ export interface ActionResponseOutput { type: 'json' | 'text'; - content: { - entries: TOutputContent[]; - }; + content: TOutputContent; } export interface ProcessesEntry { @@ -30,6 +28,24 @@ export interface ProcessesEntry { user: string; } +export interface GetProcessesActionOutputContent { + entries: ProcessesEntry[]; +} + +export interface SuspendProcessActionOutputContent { + code: string; + command?: string; + pid?: number; + entity_id?: string; +} + +export interface KillProcessActionOutputContent { + code: string; + command?: string; + pid?: number; + entity_id?: string; +} + export const RESPONSE_ACTION_COMMANDS = [ 'isolate', 'unisolate', @@ -275,9 +291,7 @@ export interface ActionDetails { startedAt: string; /** The date when the action was completed (a response by the endpoint (not fleet) was received) */ completedAt: string | undefined; - /** - * The output data from an action - */ + /** The output data from an action stored in an object where the key is the agent id */ outputs?: Record>; /** user that created the action */ createdBy: string; diff --git a/x-pack/plugins/security_solution/public/management/components/console/index.ts b/x-pack/plugins/security_solution/public/management/components/console/index.ts index c47971e2106b3..6f6f139b0aee7 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/index.ts +++ b/x-pack/plugins/security_solution/public/management/components/console/index.ts @@ -7,10 +7,19 @@ export { Console } from './console'; export { ConsoleManager, useConsoleManager } from './components/console_manager'; -export type { CommandDefinition, Command, ConsoleProps } from './types'; +export type { + CommandDefinition, + Command, + ConsoleProps, + CommandExecutionComponentProps, +} from './types'; export type { ConsoleRegistrationInterface, ManagedConsoleExtensionComponentProps, RegisteredConsoleClient, ConsoleManagerClient, } from './components/console_manager/types'; +export type { + CommandExecutionResultProps, + CommandExecutionResultComponent, +} from './components/command_execution_result'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/endpoint_action_failure_message.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/endpoint_action_failure_message.tsx new file mode 100644 index 0000000000000..1e2745cb03e60 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/endpoint_action_failure_message.tsx @@ -0,0 +1,71 @@ +/* + * 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. + */ + +import React, { memo, useMemo } from 'react'; +import { EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { endpointActionResponseCodes } from '../endpoint_responder/endpoint_action_response_codes'; +import type { ActionDetails, MaybeImmutable } from '../../../../common/endpoint/types'; + +interface EndpointActionFailureMessageProps { + action: MaybeImmutable>; +} + +export const EndpointActionFailureMessage = memo( + ({ action }) => { + return useMemo(() => { + if (!action.isCompleted || action.wasSuccessful) { + return null; + } + + const errors: string[] = []; + + // Determine if each endpoint returned a response code and if so, + // see if we have a localized message for it + if (action.outputs) { + for (const agent of action.agents) { + const endpointAgentOutput = action.outputs[agent]; + + if ( + endpointAgentOutput && + endpointAgentOutput.type === 'json' && + endpointAgentOutput.content.code && + endpointActionResponseCodes[endpointAgentOutput.content.code] + ) { + errors.push(endpointActionResponseCodes[endpointAgentOutput.content.code]); + } + } + } + + if (!errors.length) { + if (action.errors) { + errors.push(...action.errors); + } else { + errors.push( + i18n.translate('xpack.securitySolution.endpointActionFailureMessage.unknownFailure', { + defaultMessage: 'Action failed', + }) + ); + } + } + + return ( + <> + + +
{errors.join(' | ')}
+ + ); + }, [action]); + } +); +EndpointActionFailureMessage.displayName = 'EndpointActionFailureMessage'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/index.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/index.ts new file mode 100644 index 0000000000000..6cc14d0bb3844 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_action_failure_message/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export { EndpointActionFailureMessage } from './endpoint_action_failure_message'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_error.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_error.tsx index 0f199e175a235..3060f76247cb9 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_error.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_error.tsx @@ -6,25 +6,19 @@ */ import React, { memo } from 'react'; -import { EuiSpacer } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; +import { EndpointActionFailureMessage } from '../endpoint_action_failure_message'; import type { CommandExecutionResultComponent } from '../console/components/command_execution_result'; -import type { ImmutableArray } from '../../../../common/endpoint/types'; +import type { ActionDetails, MaybeImmutable } from '../../../../common/endpoint/types'; export const ActionError = memo<{ - errors: ImmutableArray; - title?: string; + action: MaybeImmutable; ResultComponent: CommandExecutionResultComponent; + title?: string; dataTestSubj?: string; -}>(({ title, dataTestSubj, errors, ResultComponent }) => { +}>(({ title, dataTestSubj, action, ResultComponent }) => { return ( - - -
{errors.join(' | ')}
+
); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_success.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_success.tsx new file mode 100644 index 0000000000000..183fb2fe5d67b --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_success.tsx @@ -0,0 +1,37 @@ +/* + * 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. + */ + +import React, { memo, useMemo } from 'react'; +import { endpointActionResponseCodes } from './endpoint_action_response_codes'; +import type { ActionDetails, MaybeImmutable } from '../../../../common/endpoint/types'; +import type { CommandExecutionResultComponent, CommandExecutionResultProps } from '../console'; + +export interface ActionSuccessProps extends CommandExecutionResultProps { + action: MaybeImmutable>; + ResultComponent: CommandExecutionResultComponent; +} + +/** + * Display generic success message for all actions + */ +export const ActionSuccess = memo( + ({ action, ResultComponent, title: _title, ...props }) => { + const title = useMemo(() => { + if (_title) { + return _title; + } + + const firstAgentId = action.agents[0]; + const actionOutputCode = action.outputs?.[firstAgentId]?.content?.code; + + return actionOutputCode ? endpointActionResponseCodes[actionOutputCode] : undefined; + }, [_title, action.agents, action.outputs]); + + return ; + } +); +ActionSuccess.displayName = 'ActionSuccess'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/endpoint_action_response_codes.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/endpoint_action_response_codes.ts new file mode 100644 index 0000000000000..6694601cd8930 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/endpoint_action_response_codes.ts @@ -0,0 +1,69 @@ +/* + * 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. + */ + +import { i18n } from '@kbn/i18n'; + +const CODES = Object.freeze({ + // ----------------------------------------------------------------- + // SUSPEND-PROCESS CODES + // ----------------------------------------------------------------- + /** + * Code will be used whenever you provide an entity_id or pid that isn't found. + * suspend_process will always be an error because the process was not found to be suspended + */ + 'ra_suspend-process_error_not-found': i18n.translate( + 'xpack.securitySolution.endpointActionResponseCodes.suspendProcess.notFoundError', + { defaultMessage: 'The provided process was not found' } + ), + + /** + * Code will be used when the provided process can not be killed (for stability reasons). + * Example: This occurs if you try to kill Endpoint Security + */ + 'ra_suspend-process_error_not-permitted': i18n.translate( + 'xpack.securitySolution.endpointActionResponseCodes.suspendProcess.notPermittedSuccess', + { defaultMessage: 'The provided process cannot be suspended' } + ), + + // ----------------------------------------------------------------- + // KILL-PROCESS CODES + // ----------------------------------------------------------------- + /** + * Code will be used whenever you provide an entity_id that isn't found. Since entity_id is + * unique, we can guarantee that it was legitimately not found and not just that the process + * was already killed. + */ + 'ra_kill-process_error_not-found': i18n.translate( + 'xpack.securitySolution.endpointActionResponseCodes.killProcess.notFoundError', + { defaultMessage: 'The provided process was not found' } + ), + + /** + * Code will be used whenever you provide a pid that isn't found. Since pid is reused, we aren't + * sure if the process was already killed or just wasn't found. In either case, a process with + * that pid will no longer be running. + */ + 'ra_kill-process_success_no-action': i18n.translate( + 'xpack.securitySolution.endpointActionResponseCodes.killProcess.noActionSuccess', + { defaultMessage: 'Action completed. The provided process was not found or already killed' } + ), + + /** + * Code will be used when the provided process can not be killed (for stability reasons). + * Example: This occurs if you try to kill Endpoint Security + */ + 'ra_kill-process_error_not-permitted': i18n.translate( + 'xpack.securitySolution.endpointActionResponseCodes.killProcess.notPermittedSuccess', + { defaultMessage: 'The provided process cannot be killed' } + ), +}); + +/** + * A map of possible code's that can be returned from the endpoint for response actions + */ +export const endpointActionResponseCodes: Readonly> = + CODES; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx index a76e73327673a..c778f03fcb5f5 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx @@ -11,7 +11,10 @@ import { EuiBasicTable } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { ActionDetails, ProcessesEntry } from '../../../../common/endpoint/types'; +import type { + ActionDetails, + GetProcessesActionOutputContent, +} from '../../../../common/endpoint/types'; import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; import type { EndpointCommandDefinitionMeta } from './types'; import type { CommandExecutionComponentProps } from '../console/types'; @@ -46,7 +49,7 @@ export const GetProcessesActionResult = memo< { actionId?: string; actionRequestSent?: boolean; - completedActionDetails?: ActionDetails; + completedActionDetails?: ActionDetails; apiError?: IHttpFetchError; }, EndpointCommandDefinitionMeta @@ -66,10 +69,13 @@ export const GetProcessesActionResult = memo< error: processesActionRequestError, } = useSendGetEndpointProcessesRequest(); - const { data: actionDetails } = useGetActionDetails(actionId ?? '-', { - enabled: Boolean(actionId) && isPending, - refetchInterval: isPending ? 3000 : false, - }); + const { data: actionDetails } = useGetActionDetails( + actionId ?? '-', + { + enabled: Boolean(actionId) && isPending, + refetchInterval: isPending ? 3000 : false, + } + ); // Send get processes request if not yet done useEffect(() => { @@ -201,7 +207,7 @@ export const GetProcessesActionResult = memo< { defaultMessage: 'Get processes action failed' } )} dataTestSubj={'getProcessesErrorCallout'} - errors={completedActionDetails?.errors} + action={completedActionDetails} ResultComponent={ResultComponent} /> ); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx index 54c26b529e4e8..ec11d022650ca 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx @@ -38,7 +38,7 @@ export const IsolateActionResult = memo( return ( ); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx index 4219babec00d6..111575a94521b 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx @@ -8,7 +8,11 @@ import React, { memo, useEffect } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { ActionDetails } from '../../../../common/endpoint/types'; +import { ActionSuccess } from './action_success'; +import type { + ActionDetails, + KillProcessActionOutputContent, +} from '../../../../common/endpoint/types'; import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; import type { EndpointCommandDefinitionMeta } from './types'; import { useSendKillProcessRequest } from '../../hooks/endpoint/use_send_kill_process_endpoint_request'; @@ -23,7 +27,7 @@ export const KillProcessActionResult = memo< { actionId?: string; actionRequestSent?: boolean; - completedActionDetails?: ActionDetails; + completedActionDetails?: ActionDetails; apiError?: IHttpFetchError; }, EndpointCommandDefinitionMeta @@ -37,10 +41,13 @@ export const KillProcessActionResult = memo< const { mutate, data, isSuccess, error } = useSendKillProcessRequest(); - const { data: actionDetails } = useGetActionDetails(actionId ?? '-', { - enabled: Boolean(actionId) && isPending, - refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, - }); + const { data: actionDetails } = useGetActionDetails( + actionId ?? '-', + { + enabled: Boolean(actionId) && isPending, + refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, + } + ); // Send Kill request if not yet done useEffect(() => { @@ -86,11 +93,6 @@ export const KillProcessActionResult = memo< } }, [actionDetails?.data, setStatus, setStore, isPending]); - // Show nothing if still pending - if (isPending) { - return ; - } - // Show API errors if perform action fails if (isError && apiError) { return ( @@ -104,18 +106,29 @@ export const KillProcessActionResult = memo< ); } + // Show nothing if still pending + if (isPending || !completedActionDetails) { + return ; + } + // Show errors if (completedActionDetails?.errors) { return ( ); } // Show Success - return ; + return ( + + ); }); KillProcessActionResult.displayName = 'KillProcessActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx index 8225e5244e62a..f789b48671324 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx @@ -39,7 +39,7 @@ export const ReleaseActionResult = memo( return ( ); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx index e4672fc37acb8..10c3a7d1a4a0d 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx @@ -8,7 +8,11 @@ import React, { memo, useEffect } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { ActionDetails } from '../../../../common/endpoint/types'; +import { ActionSuccess } from './action_success'; +import type { + ActionDetails, + SuspendProcessActionOutputContent, +} from '../../../../common/endpoint/types'; import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; import type { EndpointCommandDefinitionMeta } from './types'; import { useSendSuspendProcessRequest } from '../../hooks/endpoint/use_send_suspend_process_endpoint_request'; @@ -23,7 +27,7 @@ export const SuspendProcessActionResult = memo< { actionId?: string; actionRequestSent?: boolean; - completedActionDetails?: ActionDetails; + completedActionDetails?: ActionDetails; apiError?: IHttpFetchError; }, EndpointCommandDefinitionMeta @@ -37,10 +41,13 @@ export const SuspendProcessActionResult = memo< const { mutate, data, isSuccess, error } = useSendSuspendProcessRequest(); - const { data: actionDetails } = useGetActionDetails(actionId ?? '-', { - enabled: Boolean(actionId) && isPending, - refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, - }); + const { data: actionDetails } = useGetActionDetails( + actionId ?? '-', + { + enabled: Boolean(actionId) && isPending, + refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, + } + ); // Send Suspend request if not yet done useEffect(() => { @@ -100,7 +107,7 @@ export const SuspendProcessActionResult = memo< } // Show nothing if still pending - if (isPending) { + if (isPending || !completedActionDetails) { return ; } @@ -109,13 +116,19 @@ export const SuspendProcessActionResult = memo< return ( ); } // Show Success - return ; + return ( + + ); }); SuspendProcessActionResult.displayName = 'SuspendProcessActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts index ef3a4bd23d88f..5bc85d8007176 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts @@ -11,19 +11,19 @@ import { useQuery } from 'react-query'; import { useHttp } from '../../../common/lib/kibana'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; import { ACTION_DETAILS_ROUTE } from '../../../../common/endpoint/constants'; -import type { ActionDetailsApiResponse, ProcessesEntry } from '../../../../common/endpoint/types'; +import type { ActionDetailsApiResponse } from '../../../../common/endpoint/types'; export const useGetActionDetails = ( actionId: string, - options: UseQueryOptions, IHttpFetchError> = {} -): UseQueryResult, IHttpFetchError> => { + options: UseQueryOptions, IHttpFetchError> = {} +): UseQueryResult, IHttpFetchError> => { const http = useHttp(); - return useQuery, IHttpFetchError>({ + return useQuery, IHttpFetchError>({ queryKey: ['get-action-details', actionId], ...options, queryFn: () => { - return http.get>( + return http.get>( resolvePathVariables(ACTION_DETAILS_ROUTE, { action_id: actionId.trim() || 'undefined' }) ); }, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts index b474528dc06a3..aa3f2b69c807b 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts @@ -11,7 +11,7 @@ import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { ProcessesRequestBody, ResponseActionApiResponse, - ProcessesEntry, + GetProcessesActionOutputContent, } from '../../../../common/endpoint/types/actions'; import { GET_PROCESSES_ROUTE } from '../../../../common/endpoint/constants'; import { KibanaServices } from '../../../common/lib/kibana'; @@ -22,25 +22,24 @@ import { KibanaServices } from '../../../common/lib/kibana'; */ export const useSendGetEndpointProcessesRequest = ( customOptions?: UseMutationOptions< - ResponseActionApiResponse, + ResponseActionApiResponse, IHttpFetchError, ProcessesRequestBody > ): UseMutationResult< - ResponseActionApiResponse, + ResponseActionApiResponse, IHttpFetchError, ProcessesRequestBody > => { return useMutation< - ResponseActionApiResponse, + ResponseActionApiResponse, IHttpFetchError, ProcessesRequestBody >((getRunningProcessesData: ProcessesRequestBody) => { - return KibanaServices.get().http.post>( - GET_PROCESSES_ROUTE, - { - body: JSON.stringify(getRunningProcessesData), - } - ); + return KibanaServices.get().http.post< + ResponseActionApiResponse + >(GET_PROCESSES_ROUTE, { + body: JSON.stringify(getRunningProcessesData), + }); }, customOptions); }; diff --git a/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts b/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts index 30e9565562f1c..9289b1d3ffea0 100644 --- a/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts +++ b/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts @@ -24,8 +24,8 @@ import type { ActionListApiResponse, ResponseActionApiResponse, PendingActionsResponse, - ProcessesEntry, ActionDetails, + GetProcessesActionOutputContent, } from '../../../common/endpoint/types'; export type ResponseActionsHttpMocksInterface = ResponseProvidersInterface<{ @@ -43,7 +43,7 @@ export type ResponseActionsHttpMocksInterface = ResponseProvidersInterface<{ agentPendingActionsSummary: (options: HttpFetchOptionsWithPath) => PendingActionsResponse; - processes: () => ActionDetailsApiResponse; + processes: () => ActionDetailsApiResponse; }>; export const responseActionsHttpMocks = httpHandlerMockFactory([ @@ -134,7 +134,7 @@ export const responseActionsHttpMocks = httpHandlerMockFactory => { + handler: (): ActionDetailsApiResponse => { const generator = new EndpointActionGenerator('seed'); const response = generator.generateActionDetails({ outputs: { @@ -145,7 +145,7 @@ export const responseActionsHttpMocks = httpHandlerMockFactory; + }) as ActionDetails; return { data: response }; }, diff --git a/x-pack/plugins/security_solution/scripts/endpoint/action_responder/utils.ts b/x-pack/plugins/security_solution/scripts/endpoint/action_responder/utils.ts index 68e05299ac981..59bf6e6da303f 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/action_responder/utils.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/action_responder/utils.ts @@ -21,7 +21,7 @@ import type { EndpointActionResponse, LogsEndpointActionResponse, ActionResponseOutput, - ProcessesEntry, + GetProcessesActionOutputContent, } from '../../../common/endpoint/types'; import type { EndpointActionListRequestQuery } from '../../../common/endpoint/schema/actions'; import { EndpointActionGenerator } from '../../../common/endpoint/data_generators/endpoint_action_generator'; @@ -158,6 +158,6 @@ const getOutputDataIfNeeded = ( entries: endpointActionGenerator.randomResponseActionProcesses(100), }, }, - } as { output: ActionResponseOutput }) + } as { output: ActionResponseOutput }) : {}; };