diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.test.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.test.tsx new file mode 100644 index 0000000000000..2bd673f68095f --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.test.tsx @@ -0,0 +1,84 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { useHostIsolationExceptionsAccess } from './use_host_isolation_exceptions_access'; +import { checkArtifactHasData } from '../../services/exceptions_list/check_artifact_has_data'; + +jest.mock('../../services/exceptions_list/check_artifact_has_data', () => ({ + checkArtifactHasData: jest.fn(), +})); + +const mockArtifactHasData = (hasData = true) => { + (checkArtifactHasData as jest.Mock).mockResolvedValueOnce(hasData); +}; + +describe('useHostIsolationExceptionsAccess', () => { + const mockApiClient = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + const setupHook = (canAccess: boolean, canRead: boolean) => { + return renderHook(() => useHostIsolationExceptionsAccess(canAccess, canRead, mockApiClient)); + }; + + test('should set access to true if canAccessHostIsolationExceptions is true', async () => { + const { result, waitFor } = setupHook(true, false); + + await waitFor(() => expect(result.current.hasAccessToHostIsolationExceptions).toBe(true)); + }); + + test('should check for artifact data if canReadHostIsolationExceptions is true and canAccessHostIsolationExceptions is false', async () => { + mockArtifactHasData(); + + const { result, waitFor } = setupHook(false, true); + + await waitFor(() => { + expect(checkArtifactHasData).toHaveBeenCalledWith(mockApiClient()); + expect(result.current.hasAccessToHostIsolationExceptions).toBe(true); + }); + }); + + test('should set access to false if canReadHostIsolationExceptions is true but no artifact data exists', async () => { + mockArtifactHasData(false); + + const { result, waitFor } = setupHook(false, true); + + await waitFor(() => { + expect(checkArtifactHasData).toHaveBeenCalledWith(mockApiClient()); + expect(result.current.hasAccessToHostIsolationExceptions).toBe(false); + }); + }); + + test('should set access to false if neither canAccessHostIsolationExceptions nor canReadHostIsolationExceptions is true', async () => { + const { result, waitFor } = setupHook(false, false); + await waitFor(() => { + expect(result.current.hasAccessToHostIsolationExceptions).toBe(false); + }); + }); + + test('should not call checkArtifactHasData if canAccessHostIsolationExceptions is true', async () => { + const { result, waitFor } = setupHook(true, true); + + await waitFor(() => { + expect(checkArtifactHasData).not.toHaveBeenCalled(); + expect(result.current.hasAccessToHostIsolationExceptions).toBe(true); + }); + }); + + test('should set loading state correctly while checking access', async () => { + const { result, waitFor } = setupHook(false, true); + + expect(result.current.isHostIsolationExceptionsAccessLoading).toBe(true); + + await waitFor(() => { + expect(result.current.isHostIsolationExceptionsAccessLoading).toBe(false); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.tsx new file mode 100644 index 0000000000000..daccba91bccf0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.tsx @@ -0,0 +1,43 @@ +/* + * 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 { useEffect, useState } from 'react'; +import { checkArtifactHasData } from '../../services/exceptions_list/check_artifact_has_data'; +import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; + +export const useHostIsolationExceptionsAccess = ( + canAccessHostIsolationExceptions: boolean, + canReadHostIsolationExceptions: boolean, + getApiClient: () => ExceptionsListApiClient +): { + hasAccessToHostIsolationExceptions: boolean; + isHostIsolationExceptionsAccessLoading: boolean; +} => { + const [hasAccess, setHasAccess] = useState(null); + + useEffect(() => { + (async () => { + // Host isolation exceptions is a paid feature and therefore: + // canAccessHostIsolationExceptions signifies if the user has required license to access the feature. + // canReadHostIsolationExceptions, however, is a privilege that allows the user to read and delete the data even if the license is not sufficient (downgrade scenario). + // In such cases, the tab should be visible only if there is existing data. + if (canAccessHostIsolationExceptions) { + setHasAccess(true); + } else if (canReadHostIsolationExceptions) { + const result = await checkArtifactHasData(getApiClient()); + setHasAccess(result); + } else { + setHasAccess(false); + } + })(); + }, [canAccessHostIsolationExceptions, canReadHostIsolationExceptions, getApiClient]); + + return { + hasAccessToHostIsolationExceptions: !!hasAccess, + isHostIsolationExceptionsAccessLoading: hasAccess === null, + }; +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/blocklist/services/blocklists_api_client.ts b/x-pack/plugins/security_solution/public/management/pages/blocklist/services/blocklists_api_client.ts index 017301c55a018..eb47a4d22ae2c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/blocklist/services/blocklists_api_client.ts +++ b/x-pack/plugins/security_solution/public/management/pages/blocklist/services/blocklists_api_client.ts @@ -10,7 +10,7 @@ import type { ExceptionListItemSchema, UpdateExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; -import { ENDPOINT_BLOCKLISTS_LIST_ID } from '@kbn/securitysolution-list-constants'; +import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants'; import type { HttpStart } from '@kbn/core/public'; import type { ConditionEntry } from '../../../../../common/endpoint/types'; @@ -46,7 +46,7 @@ export class BlocklistsApiClient extends ExceptionsListApiClient { constructor(http: HttpStart) { super( http, - ENDPOINT_BLOCKLISTS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.blocklists.id, BLOCKLISTS_LIST_DEFINITION, readTransform, writeTransform @@ -56,7 +56,7 @@ export class BlocklistsApiClient extends ExceptionsListApiClient { public static getInstance(http: HttpStart): ExceptionsListApiClient { return super.getInstance( http, - ENDPOINT_BLOCKLISTS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.blocklists.id, BLOCKLISTS_LIST_DEFINITION, readTransform, writeTransform diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/service/api_client.ts b/x-pack/plugins/security_solution/public/management/pages/event_filters/service/api_client.ts index a69e54bf7776d..e7c5e53e34274 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/service/api_client.ts +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/service/api_client.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ENDPOINT_EVENT_FILTERS_LIST_ID } from '@kbn/securitysolution-list-constants'; +import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants'; import type { HttpStart } from '@kbn/core/public'; import type { CreateExceptionListItemSchema, @@ -33,7 +33,7 @@ export class EventFiltersApiClient extends ExceptionsListApiClient { constructor(http: HttpStart) { super( http, - ENDPOINT_EVENT_FILTERS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.eventFilters.id, EVENT_FILTER_LIST_DEFINITION, undefined, writeTransform @@ -43,7 +43,7 @@ export class EventFiltersApiClient extends ExceptionsListApiClient { public static getInstance(http: HttpStart): ExceptionsListApiClient { return super.getInstance( http, - ENDPOINT_EVENT_FILTERS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.eventFilters.id, EVENT_FILTER_LIST_DEFINITION, undefined, writeTransform diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/host_isolation_exceptions_api_client.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/host_isolation_exceptions_api_client.ts index eea09ceaf91ca..94bdab6af651e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/host_isolation_exceptions_api_client.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/host_isolation_exceptions_api_client.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID } from '@kbn/securitysolution-list-constants'; +import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants'; import type { HttpStart } from '@kbn/core/public'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; import { HOST_ISOLATION_EXCEPTIONS_LIST_DEFINITION } from './constants'; @@ -19,7 +19,7 @@ export class HostIsolationExceptionsApiClient extends ExceptionsListApiClient { constructor(http: HttpStart) { super( http, - ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.hostIsolationExceptions.id, HOST_ISOLATION_EXCEPTIONS_LIST_DEFINITION ); } @@ -27,7 +27,7 @@ export class HostIsolationExceptionsApiClient extends ExceptionsListApiClient { public static getInstance(http: HttpStart): ExceptionsListApiClient { return super.getInstance( http, - ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.hostIsolationExceptions.id, HOST_ISOLATION_EXCEPTIONS_LIST_DEFINITION ); } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx index a41cd65f9db3c..ffcee81a3cb8f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx @@ -30,12 +30,15 @@ import { PolicyDetails } from './policy_details'; import { APP_UI_ID } from '../../../../../common/constants'; import { createLicenseServiceMock } from '../../../../../common/license/mocks'; import { licenseService as licenseServiceMocked } from '../../../../common/hooks/__mocks__/use_license'; +import { useHostIsolationExceptionsAccess } from '../../../hooks/artifacts/use_host_isolation_exceptions_access'; jest.mock('../../../../common/components/user_privileges'); jest.mock('../../../../common/hooks/use_license'); +jest.mock('../../../hooks/artifacts/use_host_isolation_exceptions_access'); const useUserPrivilegesMock = useUserPrivileges as jest.Mock; const useLicenseMock = _useLicense as jest.Mock; +const useHostIsolationExceptionsAccessMock = useHostIsolationExceptionsAccess as jest.Mock; describe('Policy Details', () => { const policyDetailsPathUrl = getPolicyDetailPath('1'); @@ -100,11 +103,15 @@ describe('Policy Details', () => { policyPackagePolicy.policy_id = policyPackagePolicy.policy_ids[0]; const policyListApiHandlers = policyListApiPathHandlers(); + useHostIsolationExceptionsAccessMock.mockReturnValue({ + hasAccessToHostIsolationExceptions: true, + isHostIsolationExceptionsAccessLoading: false, + }); http.get.mockImplementation((...args) => { const [path] = args; if (typeof path === 'string') { - // GET datasouce + // GET datasource if (path === `${PACKAGE_POLICY_API_ROOT}/1`) { asyncActions = asyncActions.then(async (): Promise => sleep()); return Promise.resolve({ @@ -135,6 +142,34 @@ describe('Policy Details', () => { history.push(policyDetailsPathUrl); }); + it('should NOT display tabs when Host Isolation Exceptions access is loading', async () => { + useHostIsolationExceptionsAccessMock.mockReturnValue({ + hasAccessToHostIsolationExceptions: false, + isHostIsolationExceptionsAccessLoading: true, + }); + policyView = render(); + await asyncActions; + policyView.update(); + const tab = policyView.find('[data-test-subj="policyTabs"]'); + expect(tab).toHaveLength(0); + const loader = policyView.find('span[data-test-subj="privilegesLoading"]'); + expect(loader).toHaveLength(1); + }); + + it('should display tabs when Host Isolation Exceptions access is not loading', async () => { + useHostIsolationExceptionsAccessMock.mockReturnValue({ + hasAccessToHostIsolationExceptions: true, + isHostIsolationExceptionsAccessLoading: false, + }); + policyView = render(); + await asyncActions; + policyView.update(); + const tab = policyView.find('div[data-test-subj="policyTabs"]'); + expect(tab).toHaveLength(1); + const loader = policyView.find('div[data-test-subj="privilegesLoading"]'); + expect(loader).toHaveLength(0); + }); + it('should NOT display timeline', async () => { policyView = render(); await asyncActions; @@ -210,13 +245,24 @@ describe('Policy Details', () => { expect(eventFiltersTab.text()).toBe('Event filters'); }); - it('should display the host isolation exceptions tab', async () => { + it('should display the host isolation exceptions tab if user have access', async () => { policyView = render(); await asyncActions; policyView.update(); - const tab = policyView.find('button#hostIsolationExceptions'); + const tab = policyView.find('button[data-test-subj="policyHostIsolationExceptionsTab"]'); expect(tab).toHaveLength(1); - expect(tab.text()).toBe('Host isolation exceptions'); + }); + + it("shouldn't display the host isolation exceptions tab when user doesn't have access", async () => { + useHostIsolationExceptionsAccessMock.mockReturnValue({ + hasAccessToHostIsolationExceptions: false, + isHostIsolationExceptionsAccessLoading: false, + }); + policyView = render(); + await asyncActions; + policyView.update(); + const tab = policyView.find('button[data-test-subj="policyHostIsolationExceptionsTab"]'); + expect(tab).toHaveLength(0); }); it('should display the protection updates tab', async () => { @@ -234,6 +280,10 @@ describe('Policy Details', () => { licenseServiceMock.isEnterprise.mockReturnValue(false); useLicenseMock.mockReturnValue(licenseServiceMock); + useHostIsolationExceptionsAccessMock.mockReturnValue({ + hasAccessToHostIsolationExceptions: false, + isHostIsolationExceptionsAccessLoading: false, + }); }); afterEach(() => { @@ -247,55 +297,55 @@ describe('Policy Details', () => { const tab = policyView.find('button#protectionUpdates'); expect(tab).toHaveLength(0); }); - }); - describe('without required permissions', () => { - const renderWithPrivilege = async (privilege: string) => { - useUserPrivilegesMock.mockReturnValue({ - endpointPrivileges: { - loading: false, - [privilege]: false, - }, - }); - policyView = render(); - await asyncActions; - policyView.update(); - }; - - it.each([ - ['trusted apps', 'canReadTrustedApplications', 'trustedApps'], - ['event filters', 'canReadEventFilters', 'eventFilters'], - ['host isolation exeptions', 'canReadHostIsolationExceptions', 'hostIsolationExceptions'], - ['blocklist', 'canReadBlocklist', 'blocklists'], - ])( - 'should not display the %s tab with no privileges', - async (_: string, privilege: string, selector: string) => { - await renderWithPrivilege(privilege); - expect(policyView.find(`button#${selector}`)).toHaveLength(0); - } - ); - - it.each([ - ['trusted apps', 'canReadTrustedApplications', getPolicyTrustedAppsPath('1')], - ['event filters', 'canReadEventFilters', getPolicyEventFiltersPath('1')], - [ - 'host isolation exeptions', - 'canReadHostIsolationExceptions', - getPolicyHostIsolationExceptionsPath('1'), - ], - ['blocklist', 'canReadBlocklist', getPolicyBlocklistsPath('1')], - ])( - 'should redirect to policy details when no %s required privileges', - async (_: string, privilege: string, path: string) => { - history.push(path); - await renderWithPrivilege(privilege); - expect(history.location.pathname).toBe(policyDetailsPathUrl); - expect(coreStart.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); - expect(coreStart.notifications.toasts.addDanger).toHaveBeenCalledWith( - 'You do not have the required Kibana permissions to use the given artifact.' - ); - } - ); + describe('without required permissions', () => { + const renderWithoutPrivilege = async (privilege: string) => { + useUserPrivilegesMock.mockReturnValue({ + endpointPrivileges: { + loading: false, + [privilege]: false, + }, + }); + policyView = render(); + await asyncActions; + policyView.update(); + }; + + it.each([ + ['trusted apps', 'canReadTrustedApplications', 'trustedApps'], + ['event filters', 'canReadEventFilters', 'eventFilters'], + ['host isolation exeptions', 'canReadHostIsolationExceptions', 'hostIsolationExceptions'], + ['blocklist', 'canReadBlocklist', 'blocklists'], + ])( + 'should not display the %s tab with no privileges', + async (_: string, privilege: string, selector: string) => { + await renderWithoutPrivilege(privilege); + expect(policyView.find(`button#${selector}`)).toHaveLength(0); + } + ); + + it.each([ + ['trusted apps', 'canReadTrustedApplications', getPolicyTrustedAppsPath('1')], + ['event filters', 'canReadEventFilters', getPolicyEventFiltersPath('1')], + [ + 'host isolation exeptions', + 'canReadHostIsolationExceptions', + getPolicyHostIsolationExceptionsPath('1'), + ], + ['blocklist', 'canReadBlocklist', getPolicyBlocklistsPath('1')], + ])( + 'should redirect to policy details when no %s required privileges', + async (_: string, privilege: string, path: string) => { + history.push(path); + await renderWithoutPrivilege(privilege); + expect(history.location.pathname).toBe(policyDetailsPathUrl); + expect(coreStart.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); + expect(coreStart.notifications.toasts.addDanger).toHaveBeenCalledWith( + 'You do not have the required Kibana permissions to use the given artifact.' + ); + } + ); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx index cb480615d27a5..c350f91c914d6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx @@ -58,6 +58,7 @@ import { SEARCHABLE_FIELDS as EVENT_FILTERS_SEARCHABLE_FIELDS } from '../../../e import { SEARCHABLE_FIELDS as HOST_ISOLATION_EXCEPTIONS_SEARCHABLE_FIELDS } from '../../../host_isolation_exceptions/constants'; import { SEARCHABLE_FIELDS as BLOCKLISTS_SEARCHABLE_FIELDS } from '../../../blocklist/constants'; import type { PolicyDetailsRouteState } from '../../../../../../common/endpoint/types'; +import { useHostIsolationExceptionsAccess } from '../../../../hooks/artifacts/use_host_isolation_exceptions_access'; enum PolicyTabKeys { SETTINGS = 'settings', @@ -118,11 +119,12 @@ export const PolicyTabs = React.memo(() => { canWriteTrustedApplications, canReadEventFilters, canWriteEventFilters, + canAccessHostIsolationExceptions, canReadHostIsolationExceptions, canWriteHostIsolationExceptions, canReadBlocklist, canWriteBlocklist, - loading: privilegesLoading, + loading: isPrivilegesLoading, } = useUserPrivileges().endpointPrivileges; const { state: routeState = {} } = useLocation(); @@ -131,12 +133,34 @@ export const PolicyTabs = React.memo(() => { ); const isEnterprise = useLicense().isEnterprise(); const isProtectionUpdatesEnabled = isEnterprise && isProtectionUpdatesFeatureEnabled; + + const getHostIsolationExceptionsApiClientInstance = useCallback( + () => HostIsolationExceptionsApiClient.getInstance(http), + [http] + ); + + const { hasAccessToHostIsolationExceptions, isHostIsolationExceptionsAccessLoading } = + useHostIsolationExceptionsAccess( + canAccessHostIsolationExceptions, + canReadHostIsolationExceptions, + getHostIsolationExceptionsApiClientInstance + ); + // move the user out of this route if they can't access it useEffect(() => { + if (isHostIsolationExceptionsAccessLoading || isPrivilegesLoading) { + return; + } + + const redirectHostIsolationException = + isInHostIsolationExceptionsTab && + (!canReadHostIsolationExceptions || + (!isHostIsolationExceptionsAccessLoading && !hasAccessToHostIsolationExceptions)); + if ( (isInTrustedAppsTab && !canReadTrustedApplications) || (isInEventFiltersTab && !canReadEventFilters) || - (isInHostIsolationExceptionsTab && !canReadHostIsolationExceptions) || + redirectHostIsolationException || (isInBlocklistsTab && !canReadBlocklist) ) { history.replace(getPolicyDetailPath(policyId)); @@ -152,12 +176,15 @@ export const PolicyTabs = React.memo(() => { canReadEventFilters, canReadHostIsolationExceptions, canReadTrustedApplications, + hasAccessToHostIsolationExceptions, history, + isHostIsolationExceptionsAccessLoading, isInBlocklistsTab, isInEventFiltersTab, isInHostIsolationExceptionsTab, isInProtectionUpdatesTab, isInTrustedAppsTab, + isPrivilegesLoading, policyId, toasts, ]); @@ -172,11 +199,6 @@ export const PolicyTabs = React.memo(() => { [http] ); - const getHostIsolationExceptionsApiClientInstance = useCallback( - () => HostIsolationExceptionsApiClient.getInstance(http), - [http] - ); - const getBlocklistsApiClientInstance = useCallback( () => BlocklistsApiClient.getInstance(http), [http] @@ -298,7 +320,7 @@ export const PolicyTabs = React.memo(() => { 'data-test-subj': 'policyEventFiltersTab', } : undefined, - [PolicyTabKeys.HOST_ISOLATION_EXCEPTIONS]: canReadHostIsolationExceptions + [PolicyTabKeys.HOST_ISOLATION_EXCEPTIONS]: hasAccessToHostIsolationExceptions ? { id: PolicyTabKeys.HOST_ISOLATION_EXCEPTIONS, name: i18n.translate( @@ -379,7 +401,7 @@ export const PolicyTabs = React.memo(() => { canReadEventFilters, getEventFiltersApiClientInstance, canWriteEventFilters, - canReadHostIsolationExceptions, + hasAccessToHostIsolationExceptions, getHostIsolationExceptionsApiClientInstance, canWriteHostIsolationExceptions, canReadBlocklist, @@ -485,7 +507,7 @@ export const PolicyTabs = React.memo(() => { }, [changeTab, unsavedChangesModal.nextTab]); // show loader for privileges validation - if (privilegesLoading) { + if (isPrivilegesLoading || isHostIsolationExceptionsAccessLoading) { return ; } diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts index 9ace94955d30f..85672ea0c8b03 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts @@ -10,7 +10,7 @@ import type { ExceptionListItemSchema, UpdateExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; -import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '@kbn/securitysolution-list-constants'; +import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants'; import type { HttpStart } from '@kbn/core/public'; import type { ConditionEntry } from '../../../../../common/endpoint/types'; @@ -46,7 +46,7 @@ export class TrustedAppsApiClient extends ExceptionsListApiClient { constructor(http: HttpStart) { super( http, - ENDPOINT_TRUSTED_APPS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.trustedApps.id, TRUSTED_APPS_EXCEPTION_LIST_DEFINITION, readTransform, writeTransform @@ -56,7 +56,7 @@ export class TrustedAppsApiClient extends ExceptionsListApiClient { public static getInstance(http: HttpStart): ExceptionsListApiClient { return super.getInstance( http, - ENDPOINT_TRUSTED_APPS_LIST_ID, + ENDPOINT_ARTIFACT_LISTS.trustedApps.id, TRUSTED_APPS_EXCEPTION_LIST_DEFINITION, readTransform, writeTransform