mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[SECURITY SOLUTION] [CASES] Allow cases to be there when security solutions privileges is none (#113573)
* allow case to itself when security solutions privileges is none * bring back the right owner for cases * bring no privilege msg when needed it * fix types * fix test * adding test * review * deepLinks generation fixed * register home solution with old app id * fix get deep links * fix home link * fix unit test * add test * fix telemetry Co-authored-by: semd <sergi.massaneda@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
106183551a
commit
436c74a9ce
82 changed files with 800 additions and 447 deletions
|
@ -94,7 +94,7 @@ pageLoadAssetSize:
|
|||
expressionShape: 34008
|
||||
interactiveSetup: 80000
|
||||
expressionTagcloud: 27505
|
||||
securitySolution: 231753
|
||||
securitySolution: 273763
|
||||
customIntegrations: 28810
|
||||
expressionMetricVis: 23121
|
||||
visTypeMetric: 23332
|
||||
|
|
|
@ -156,7 +156,7 @@ export const applicationUsageSchema = {
|
|||
security_login: commonSchema,
|
||||
security_logout: commonSchema,
|
||||
security_overwritten_session: commonSchema,
|
||||
securitySolution: commonSchema,
|
||||
securitySolutionUI: commonSchema,
|
||||
siem: commonSchema,
|
||||
space_selector: commonSchema,
|
||||
uptime: commonSchema,
|
||||
|
|
|
@ -5018,7 +5018,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"securitySolution": {
|
||||
"securitySolutionUI": {
|
||||
"properties": {
|
||||
"appId": {
|
||||
"type": "keyword",
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ENABLE_CASE_CONNECTOR } from '../../cases/common';
|
|||
import { METADATA_TRANSFORMS_PATTERN } from './endpoint/constants';
|
||||
|
||||
export const APP_ID = 'securitySolution';
|
||||
export const APP_UI_ID = 'securitySolutionUI';
|
||||
export const CASES_FEATURE_ID = 'securitySolutionCases';
|
||||
export const SERVER_APP_ID = 'siem';
|
||||
export const APP_NAME = 'Security';
|
||||
|
|
|
@ -8,7 +8,7 @@ import { getDeepLinks, PREMIUM_DEEP_LINK_IDS } from '.';
|
|||
import { AppDeepLink, Capabilities } from '../../../../../../src/core/public';
|
||||
import { SecurityPageName } from '../types';
|
||||
import { mockGlobalState } from '../../common/mock';
|
||||
import { CASES_FEATURE_ID } from '../../../common/constants';
|
||||
import { CASES_FEATURE_ID, SERVER_APP_ID } from '../../../common/constants';
|
||||
|
||||
const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null =>
|
||||
deepLinks.reduce((deepLinkFound: AppDeepLink | null, deepLink) => {
|
||||
|
@ -24,10 +24,11 @@ const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null
|
|||
return null;
|
||||
}, null);
|
||||
|
||||
const basicLicense = 'basic';
|
||||
const platinumLicense = 'platinum';
|
||||
|
||||
describe('deepLinks', () => {
|
||||
it('should return a subset of links for basic license and the full set for platinum', () => {
|
||||
const basicLicense = 'basic';
|
||||
const platinumLicense = 'platinum';
|
||||
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense);
|
||||
const platinumLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense);
|
||||
|
||||
|
@ -57,26 +58,25 @@ describe('deepLinks', () => {
|
|||
});
|
||||
|
||||
it('should return case links for basic license with only read_cases capabilities', () => {
|
||||
const basicLicense = 'basic';
|
||||
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
[SERVER_APP_ID]: { show: true },
|
||||
} as unknown as Capabilities);
|
||||
|
||||
expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return case links with NO deepLinks for basic license with only read_cases capabilities', () => {
|
||||
const basicLicense = 'basic';
|
||||
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
[SERVER_APP_ID]: { show: true },
|
||||
} as unknown as Capabilities);
|
||||
expect(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length === 0).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return case links with deepLinks for basic license with crud_cases capabilities', () => {
|
||||
const basicLicense = 'basic';
|
||||
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
[SERVER_APP_ID]: { show: true },
|
||||
} as unknown as Capabilities);
|
||||
|
||||
expect(
|
||||
|
@ -84,17 +84,32 @@ describe('deepLinks', () => {
|
|||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return case links with deepLinks for basic license with crud_cases capabilities and security disabled', () => {
|
||||
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense, {
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
[SERVER_APP_ID]: { show: false },
|
||||
} as unknown as Capabilities);
|
||||
expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return NO case links for basic license with NO read_cases capabilities', () => {
|
||||
const basicLicense = 'basic';
|
||||
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
[SERVER_APP_ID]: { show: true },
|
||||
} as unknown as Capabilities);
|
||||
|
||||
expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return empty links for any license', () => {
|
||||
const emptyDeepLinks = getDeepLinks(
|
||||
mockGlobalState.app.enableExperimental,
|
||||
basicLicense,
|
||||
{} as unknown as Capabilities
|
||||
);
|
||||
expect(emptyDeepLinks.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should return case links for basic license with undefined capabilities', () => {
|
||||
const basicLicense = 'basic';
|
||||
const basicLinks = getDeepLinks(
|
||||
mockGlobalState.app.enableExperimental,
|
||||
basicLicense,
|
||||
|
@ -105,7 +120,6 @@ describe('deepLinks', () => {
|
|||
});
|
||||
|
||||
it('should return case deepLinks for basic license with undefined capabilities', () => {
|
||||
const basicLicense = 'basic';
|
||||
const basicLinks = getDeepLinks(
|
||||
mockGlobalState.app.enableExperimental,
|
||||
basicLicense,
|
||||
|
|
|
@ -6,16 +6,11 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { isEmpty } from 'lodash';
|
||||
import { LicenseType } from '../../../../licensing/common/types';
|
||||
import { SecurityPageName } from '../types';
|
||||
import {
|
||||
AppDeepLink,
|
||||
ApplicationStart,
|
||||
AppNavLinkStatus,
|
||||
AppUpdater,
|
||||
} from '../../../../../../src/core/public';
|
||||
import { AppDeepLink, ApplicationStart, AppNavLinkStatus } from '../../../../../../src/core/public';
|
||||
import {
|
||||
OVERVIEW,
|
||||
DETECT,
|
||||
|
@ -50,6 +45,7 @@ import {
|
|||
UEBA_PATH,
|
||||
CASES_FEATURE_ID,
|
||||
HOST_ISOLATION_EXCEPTIONS_PATH,
|
||||
SERVER_APP_ID,
|
||||
} from '../../../common/constants';
|
||||
import { ExperimentalFeatures } from '../../../common/experimental_features';
|
||||
|
||||
|
@ -356,25 +352,18 @@ export function getDeepLinks(
|
|||
): AppDeepLink[] {
|
||||
const isPremium = isPremiumLicense(licenseType);
|
||||
|
||||
/**
|
||||
* Recursive DFS function to filter deepLinks by permissions (licence and capabilities).
|
||||
* Checks "end" deepLinks with no children first, the other parent deepLinks will be included if
|
||||
* they still have children deepLinks after filtering
|
||||
*/
|
||||
const filterDeepLinks = (deepLinks: AppDeepLink[]): AppDeepLink[] => {
|
||||
return deepLinks
|
||||
.filter((deepLink) => {
|
||||
if (!isPremium && PREMIUM_DEEP_LINK_IDS.has(deepLink.id)) {
|
||||
return false;
|
||||
}
|
||||
if (deepLink.id === SecurityPageName.case) {
|
||||
return capabilities == null || capabilities[CASES_FEATURE_ID].read_cases === true;
|
||||
}
|
||||
if (deepLink.id === SecurityPageName.ueba) {
|
||||
return enableExperimental.uebaEnabled;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((deepLink) => {
|
||||
if (
|
||||
deepLink.id === SecurityPageName.case &&
|
||||
capabilities != null &&
|
||||
capabilities[CASES_FEATURE_ID].crud_cases === false
|
||||
capabilities[CASES_FEATURE_ID]?.crud_cases === false
|
||||
) {
|
||||
return {
|
||||
...deepLink,
|
||||
|
@ -388,6 +377,21 @@ export function getDeepLinks(
|
|||
};
|
||||
}
|
||||
return deepLink;
|
||||
})
|
||||
.filter((deepLink) => {
|
||||
if (!isPremium && PREMIUM_DEEP_LINK_IDS.has(deepLink.id)) {
|
||||
return false;
|
||||
}
|
||||
if (deepLink.path && deepLink.path.startsWith(CASES_PATH)) {
|
||||
return capabilities == null || capabilities[CASES_FEATURE_ID]?.read_cases === true;
|
||||
}
|
||||
if (deepLink.id === SecurityPageName.ueba) {
|
||||
return enableExperimental.uebaEnabled;
|
||||
}
|
||||
if (!isEmpty(deepLink.deepLinks)) {
|
||||
return true;
|
||||
}
|
||||
return capabilities == null || capabilities[SERVER_APP_ID]?.show === true;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -402,18 +406,3 @@ export function isPremiumLicense(licenseType?: LicenseType): boolean {
|
|||
licenseType === 'trial'
|
||||
);
|
||||
}
|
||||
|
||||
export function updateGlobalNavigation({
|
||||
capabilities,
|
||||
updater$,
|
||||
enableExperimental,
|
||||
}: {
|
||||
capabilities: ApplicationStart['capabilities'];
|
||||
updater$: Subject<AppUpdater>;
|
||||
enableExperimental: ExperimentalFeatures;
|
||||
}) {
|
||||
updater$.next(() => ({
|
||||
navLinkStatus: AppNavLinkStatus.hidden, // needed to prevent showing main nav link
|
||||
deepLinks: getDeepLinks(enableExperimental, undefined, capabilities),
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -78,8 +78,12 @@ export const SecuritySolutionTemplateWrapper: React.FC<SecuritySolutionPageWrapp
|
|||
const showEmptyState = useShowPagesWithEmptyView();
|
||||
const emptyStateProps = showEmptyState ? NO_DATA_PAGE_TEMPLATE_PROPS : {};
|
||||
|
||||
// StyledKibanaPageTemplate is a styled EuiPageTemplate. Security solution currently passes the header and page content as the children of StyledKibanaPageTemplate, as opposed to using the pageHeader prop, which may account for any style discrepancies, such as the bottom border not extending the full width of the page, between EuiPageTemplate and the security solution pages.
|
||||
|
||||
/*
|
||||
* StyledKibanaPageTemplate is a styled EuiPageTemplate. Security solution currently passes the header
|
||||
* and page content as the children of StyledKibanaPageTemplate, as opposed to using the pageHeader prop,
|
||||
* which may account for any style discrepancies, such as the bottom border not extending the full width of the page,
|
||||
* between EuiPageTemplate and the security solution pages.
|
||||
*/
|
||||
return (
|
||||
<StyledKibanaPageTemplate
|
||||
$isTimelineBottomBarVisible={isTimelineBottomBarVisible}
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||
import { OVERVIEW_PATH } from '../../common/constants';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { NotFoundPage } from './404';
|
||||
import { SecurityApp } from './app';
|
||||
|
@ -22,7 +21,7 @@ export const renderApp = ({
|
|||
services,
|
||||
store,
|
||||
usageCollection,
|
||||
subPlugins,
|
||||
subPluginRoutes,
|
||||
}: RenderAppProps): (() => void) => {
|
||||
const ApplicationUsageTrackingProvider =
|
||||
usageCollection?.components.ApplicationUsageTrackingProvider ?? React.Fragment;
|
||||
|
@ -36,25 +35,9 @@ export const renderApp = ({
|
|||
>
|
||||
<ApplicationUsageTrackingProvider>
|
||||
<Switch>
|
||||
{[
|
||||
...subPlugins.overview.routes,
|
||||
...subPlugins.alerts.routes,
|
||||
...subPlugins.rules.routes,
|
||||
...subPlugins.exceptions.routes,
|
||||
...subPlugins.hosts.routes,
|
||||
...subPlugins.network.routes,
|
||||
// will be undefined if enabledExperimental.uebaEnabled === false
|
||||
...(subPlugins.ueba != null ? subPlugins.ueba.routes : []),
|
||||
...subPlugins.timelines.routes,
|
||||
...subPlugins.cases.routes,
|
||||
...subPlugins.management.routes,
|
||||
].map((route, index) => (
|
||||
<Route key={`route-${index}`} {...route} />
|
||||
))}
|
||||
|
||||
<Route path="" exact>
|
||||
<Redirect to={OVERVIEW_PATH} />
|
||||
</Route>
|
||||
{subPluginRoutes.map((route, index) => {
|
||||
return <Route key={`route-${index}`} {...route} />;
|
||||
})}
|
||||
<Route>
|
||||
<NotFoundPage />
|
||||
</Route>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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, { useMemo } from 'react';
|
||||
|
||||
import { EuiPageTemplate } from '@elastic/eui';
|
||||
import { SecuritySolutionPageWrapper } from '../common/components/page_wrapper';
|
||||
import { EmptyPage } from '../common/components/empty_page';
|
||||
import { useKibana } from '../common/lib/kibana';
|
||||
import * as i18n from './translations';
|
||||
|
||||
interface NoPrivilegesPageProps {
|
||||
subPluginKey: string;
|
||||
}
|
||||
|
||||
export const NoPrivilegesPage = React.memo<NoPrivilegesPageProps>(({ subPluginKey }) => {
|
||||
const { docLinks } = useKibana().services;
|
||||
const emptyPageActions = useMemo(
|
||||
() => ({
|
||||
feature: {
|
||||
icon: 'documents',
|
||||
label: i18n.GO_TO_DOCUMENTATION,
|
||||
url: `${docLinks.links.siem.privileges}`,
|
||||
target: '_blank',
|
||||
},
|
||||
}),
|
||||
[docLinks]
|
||||
);
|
||||
return (
|
||||
<SecuritySolutionPageWrapper>
|
||||
<EuiPageTemplate template="centeredContent">
|
||||
<EmptyPage
|
||||
actions={emptyPageActions}
|
||||
message={i18n.NO_PERMISSIONS_MSG(subPluginKey)}
|
||||
data-test-subj="no_feature_permissions-alerts"
|
||||
title={i18n.NO_PERMISSIONS_TITLE}
|
||||
/>
|
||||
</EuiPageTemplate>
|
||||
</SecuritySolutionPageWrapper>
|
||||
);
|
||||
});
|
||||
|
||||
NoPrivilegesPage.displayName = 'NoPrivilegePage';
|
|
@ -80,3 +80,21 @@ export const INVESTIGATE = i18n.translate('xpack.securitySolution.navigation.inv
|
|||
export const MANAGE = i18n.translate('xpack.securitySolution.navigation.manage', {
|
||||
defaultMessage: 'Manage',
|
||||
});
|
||||
|
||||
export const GO_TO_DOCUMENTATION = i18n.translate(
|
||||
'xpack.securitySolution.goToDocumentationButton',
|
||||
{
|
||||
defaultMessage: 'View documentation',
|
||||
}
|
||||
);
|
||||
|
||||
export const NO_PERMISSIONS_MSG = (subPluginKey: string) =>
|
||||
i18n.translate('xpack.securitySolution.noPermissionsMessage', {
|
||||
values: { subPluginKey },
|
||||
defaultMessage:
|
||||
'To view {subPluginKey}, you must update privileges. For more information, contact your Kibana administrator.',
|
||||
});
|
||||
|
||||
export const NO_PERMISSIONS_TITLE = i18n.translate('xpack.securitySolution.noPermissionsTitle', {
|
||||
defaultMessage: 'Privileges required',
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ import {
|
|||
import { RouteProps } from 'react-router-dom';
|
||||
import { AppMountParameters } from '../../../../../src/core/public';
|
||||
import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public';
|
||||
import { StartedSubPlugins, StartServices } from '../types';
|
||||
import { StartServices } from '../types';
|
||||
|
||||
/**
|
||||
* The React properties used to render `SecurityApp` as well as the `element` to render it into.
|
||||
|
@ -26,7 +26,7 @@ import { StartedSubPlugins, StartServices } from '../types';
|
|||
export interface RenderAppProps extends AppMountParameters {
|
||||
services: StartServices;
|
||||
store: Store<State, Action>;
|
||||
subPlugins: StartedSubPlugins;
|
||||
subPluginRoutes: RouteProps[];
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
} from '../../../common/components/link_to';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_ID, APP_UI_ID } from '../../../../common/constants';
|
||||
|
||||
export interface AllCasesNavProps {
|
||||
detailName: string;
|
||||
|
@ -36,7 +36,7 @@ export const AllCases = React.memo<AllCasesProps>(({ userCanCrud }) => {
|
|||
const goToCreateCase = useCallback(
|
||||
async (ev) => {
|
||||
ev.preventDefault();
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCreateCaseUrl(urlSearch),
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ export const AllCases = React.memo<AllCasesProps>(({ userCanCrud }) => {
|
|||
const goToCaseConfigure = useCallback(
|
||||
async (ev) => {
|
||||
ev.preventDefault();
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getConfigureCasesUrl(urlSearch),
|
||||
});
|
||||
|
@ -61,7 +61,7 @@ export const AllCases = React.memo<AllCasesProps>(({ userCanCrud }) => {
|
|||
return formatUrl(getCaseDetailsUrl({ id: detailName, subCaseId }));
|
||||
},
|
||||
onClick: async ({ detailName, subCaseId, search }: AllCasesNavProps) => {
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseDetailsUrl({ id: detailName, search, subCaseId }),
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ import { Case, CaseViewRefreshPropInterface } from '../../../../../cases/common'
|
|||
import { TimelineId } from '../../../../common/types/timeline';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
import { timelineActions } from '../../../timelines/store/timeline';
|
||||
import { useSourcererScope } from '../../../common/containers/sourcerer';
|
||||
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
|
||||
|
@ -153,7 +153,7 @@ export const CaseView = React.memo(
|
|||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: allCasesLink,
|
||||
});
|
||||
|
@ -165,7 +165,7 @@ export const CaseView = React.memo(
|
|||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseDetailsUrl({ id: caseId }),
|
||||
});
|
||||
|
@ -178,7 +178,7 @@ export const CaseView = React.memo(
|
|||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getConfigureCasesUrl(search),
|
||||
});
|
||||
|
@ -193,7 +193,7 @@ export const CaseView = React.memo(
|
|||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
path: getEndpointDetailsPath({
|
||||
name: 'endpointActivityLog',
|
||||
selected_endpoint: endpointId,
|
||||
|
@ -207,7 +207,7 @@ export const CaseView = React.memo(
|
|||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId ?? ''),
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Create } from '.';
|
|||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { Case } from '../../../../../cases/public/containers/types';
|
||||
import { basicCase } from '../../../../../cases/public/containers/mock';
|
||||
import { APP_ID, SecurityPageName } from '../../../../common/constants';
|
||||
import { APP_ID, APP_UI_ID, SecurityPageName } from '../../../../common/constants';
|
||||
import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search';
|
||||
|
||||
jest.mock('../use_insert_timeline');
|
||||
|
@ -71,7 +71,7 @@ describe('Create case', () => {
|
|||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(mockNavigateToApp).toHaveBeenCalledWith(APP_ID, {
|
||||
expect(mockNavigateToApp).toHaveBeenCalledWith(APP_UI_ID, {
|
||||
path: `?${mockRes}`,
|
||||
deepLinkId: SecurityPageName.case,
|
||||
})
|
||||
|
@ -96,7 +96,7 @@ describe('Create case', () => {
|
|||
);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(mockNavigateToApp).toHaveBeenNthCalledWith(1, APP_ID, {
|
||||
expect(mockNavigateToApp).toHaveBeenNthCalledWith(1, APP_UI_ID, {
|
||||
path: `/basic-case-id?${mockRes}`,
|
||||
deepLinkId: SecurityPageName.case,
|
||||
})
|
||||
|
|
|
@ -11,7 +11,7 @@ import { getCaseDetailsUrl, getCaseUrl } from '../../../common/components/link_t
|
|||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import * as timelineMarkdownPlugin from '../../../common/components/markdown_editor/plugins/timeline';
|
||||
import { useInsertTimeline } from '../use_insert_timeline';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_ID, APP_UI_ID } from '../../../../common/constants';
|
||||
import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search';
|
||||
import { navTabs } from '../../../app/home/home_navigations';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
|
@ -24,7 +24,7 @@ export const Create = React.memo(() => {
|
|||
const search = useGetUrlSearch(navTabs.case);
|
||||
const onSuccess = useCallback(
|
||||
async ({ id }) =>
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseDetailsUrl({ id, search }),
|
||||
}),
|
||||
|
@ -32,7 +32,7 @@ export const Create = React.memo(() => {
|
|||
);
|
||||
const handleSetIsCancel = useCallback(
|
||||
async () =>
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseUrl(search),
|
||||
}),
|
||||
|
|
|
@ -16,7 +16,7 @@ import { useGetUserCasesPermissions, useKibana } from '../../common/lib/kibana';
|
|||
import { getCaseUrl } from '../../common/components/link_to';
|
||||
import { navTabs } from '../../app/home/home_navigations';
|
||||
import { CaseView } from '../components/case_view';
|
||||
import { APP_ID } from '../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../common/constants';
|
||||
import { Case } from '../../../../cases/common';
|
||||
|
||||
export const CaseDetailsPage = React.memo(() => {
|
||||
|
@ -32,7 +32,7 @@ export const CaseDetailsPage = React.memo(() => {
|
|||
|
||||
useEffect(() => {
|
||||
if (userPermissions != null && !userPermissions.read) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseUrl(search),
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ import { navTabs } from '../../app/home/home_navigations';
|
|||
import { CaseHeaderPage } from '../components/case_header_page';
|
||||
import { WhitePageWrapper, SectionWrapper } from '../components/wrappers';
|
||||
import * as i18n from './translations';
|
||||
import { APP_ID } from '../../../common/constants';
|
||||
import { APP_ID, APP_UI_ID } from '../../../common/constants';
|
||||
|
||||
const ConfigureCasesPageComponent: React.FC = () => {
|
||||
const {
|
||||
|
@ -39,7 +39,7 @@ const ConfigureCasesPageComponent: React.FC = () => {
|
|||
|
||||
useEffect(() => {
|
||||
if (userPermissions != null && !userPermissions.read) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseUrl(search),
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@ import { navTabs } from '../../app/home/home_navigations';
|
|||
import { CaseHeaderPage } from '../components/case_header_page';
|
||||
import { Create } from '../components/create';
|
||||
import * as i18n from './translations';
|
||||
import { APP_ID } from '../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../common/constants';
|
||||
|
||||
export const CreateCasePage = React.memo(() => {
|
||||
const userPermissions = useGetUserCasesPermissions();
|
||||
|
@ -37,7 +37,7 @@ export const CreateCasePage = React.memo(() => {
|
|||
|
||||
useEffect(() => {
|
||||
if (userPermissions != null && !userPermissions.crud) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseUrl(search),
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ import { getCaseDetailsUrl, getCreateCaseUrl } from '../../common/components/lin
|
|||
import { RouteSpyState } from '../../common/utils/route/types';
|
||||
import * as i18n from './translations';
|
||||
import { GetUrlForApp } from '../../common/components/navigation/types';
|
||||
import { APP_ID } from '../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../common/constants';
|
||||
import { SecurityPageName } from '../../app/types';
|
||||
|
||||
export const getBreadcrumbs = (
|
||||
|
@ -26,7 +26,7 @@ export const getBreadcrumbs = (
|
|||
let breadcrumb = [
|
||||
{
|
||||
text: i18n.PAGE_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: queryParameters,
|
||||
}),
|
||||
|
@ -37,7 +37,7 @@ export const getBreadcrumbs = (
|
|||
...breadcrumb,
|
||||
{
|
||||
text: i18n.CREATE_BC_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCreateCaseUrl(queryParameters),
|
||||
}),
|
||||
|
@ -48,7 +48,7 @@ export const getBreadcrumbs = (
|
|||
...breadcrumb,
|
||||
{
|
||||
text: params.state?.caseTitle ?? '',
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseDetailsUrl({ id: params.detailName, search: queryParameters }),
|
||||
}),
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React, { memo, MouseEventHandler } from 'react';
|
||||
import { EuiLink, EuiLinkProps, EuiButton, EuiButtonProps } from '@elastic/eui';
|
||||
import { useNavigateToAppEventHandler } from '../../hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
|
||||
export type LinkToAppProps = (EuiLinkProps | EuiButtonProps) & {
|
||||
/** the app id - normally the value of the `id` in that plugin's `kibana.json` */
|
||||
|
@ -30,7 +30,7 @@ export type LinkToAppProps = (EuiLinkProps | EuiButtonProps) & {
|
|||
*/
|
||||
export const LinkToApp = memo<LinkToAppProps>(
|
||||
({
|
||||
appId = APP_ID,
|
||||
appId = APP_UI_ID,
|
||||
deepLinkId,
|
||||
appPath: path,
|
||||
appState: state,
|
||||
|
|
|
@ -14,7 +14,7 @@ import * as i18n from './translations';
|
|||
import { TimelineEventsDetailsItem } from '../../../../common';
|
||||
import { LinkAnchor } from '../links';
|
||||
import { useKibana } from '../../lib/kibana';
|
||||
import { APP_ID, SecurityPageName } from '../../../../common/constants';
|
||||
import { APP_UI_ID, SecurityPageName } from '../../../../common/constants';
|
||||
import { EVENT_DETAILS_PLACEHOLDER } from '../../../timelines/components/side_panel/event_details/translations';
|
||||
import { getFieldValue } from '../../../detections/components/host_isolation/helpers';
|
||||
|
||||
|
@ -64,7 +64,7 @@ export const ReasonComponent: React.FC<Props> = ({ eventId, data }) => {
|
|||
data-test-subj="ruleName"
|
||||
onClick={(ev: { preventDefault: () => void }) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId),
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
import React, { useMemo, useCallback, SyntheticEvent } from 'react';
|
||||
import { isNil } from 'lodash/fp';
|
||||
|
||||
import { IP_REPUTATION_LINKS_SETTING, APP_ID } from '../../../../common/constants';
|
||||
import { IP_REPUTATION_LINKS_SETTING, APP_UI_ID } from '../../../../common/constants';
|
||||
import {
|
||||
DefaultFieldRendererOverflow,
|
||||
DEFAULT_MORE_MAX_HEIGHT,
|
||||
|
@ -56,7 +56,7 @@ const UebaDetailsLinkComponent: React.FC<{
|
|||
const goToUebaDetails = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.ueba,
|
||||
path: getUebaDetailsUrl(encodeURIComponent(hostName), search),
|
||||
});
|
||||
|
@ -99,7 +99,7 @@ const HostDetailsLinkComponent: React.FC<{
|
|||
const goToHostDetails = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
path: getHostDetailsUrl(encodeURIComponent(hostName), search),
|
||||
});
|
||||
|
@ -183,7 +183,7 @@ const NetworkDetailsLinkComponent: React.FC<{
|
|||
const goToNetworkDetails = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.network,
|
||||
path: getNetworkDetailsUrl(encodeURIComponent(encodeIpv6(ip)), flowTarget, search),
|
||||
});
|
||||
|
@ -229,7 +229,7 @@ const CaseDetailsLinkComponent: React.FC<{
|
|||
const goToCaseDetails = useCallback(
|
||||
async (ev) => {
|
||||
ev.preventDefault();
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseDetailsUrl({ id: detailName, search, subCaseId }),
|
||||
});
|
||||
|
@ -257,7 +257,7 @@ export const CreateCaseLink = React.memo<{ children: React.ReactNode }>(({ child
|
|||
const goToCreateCase = useCallback(
|
||||
async (ev) => {
|
||||
ev.preventDefault();
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCreateCaseUrl(search),
|
||||
});
|
||||
|
|
|
@ -158,11 +158,11 @@ describe('Navigation Breadcrumbs', () => {
|
|||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{
|
||||
href: 'securitySolution/overview',
|
||||
href: 'securitySolutionUI/overview',
|
||||
text: 'Security',
|
||||
},
|
||||
{
|
||||
href: "securitySolution/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
text: 'Hosts',
|
||||
},
|
||||
{
|
||||
|
@ -178,10 +178,10 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Network',
|
||||
href: "securitySolution/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: 'Flows',
|
||||
|
@ -196,10 +196,10 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Timelines',
|
||||
href: "securitySolution/timelines?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/timelines?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -210,14 +210,14 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Hosts',
|
||||
href: "securitySolution/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: 'siem-kibana',
|
||||
href: "securitySolution/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{ text: 'Authentications', href: '' },
|
||||
]);
|
||||
|
@ -229,14 +229,14 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Network',
|
||||
href: "securitySolution/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: ipv4,
|
||||
href: `securitySolution/network/ip/${ipv4}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
href: `securitySolutionUI/network/ip/${ipv4}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
},
|
||||
{ text: 'Flows', href: '' },
|
||||
]);
|
||||
|
@ -248,14 +248,14 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Network',
|
||||
href: "securitySolution/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: ipv6,
|
||||
href: `securitySolution/network/ip/${ipv6Encoded}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
href: `securitySolutionUI/network/ip/${ipv6Encoded}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
},
|
||||
{ text: 'Flows', href: '' },
|
||||
]);
|
||||
|
@ -267,7 +267,7 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Alerts',
|
||||
href: '',
|
||||
|
@ -281,7 +281,7 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Exceptions',
|
||||
href: '',
|
||||
|
@ -295,10 +295,10 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Rules',
|
||||
href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -309,10 +309,10 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Rules',
|
||||
href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: 'Create',
|
||||
|
@ -335,14 +335,14 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Rules',
|
||||
href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: mockRuleName,
|
||||
href: `securitySolution/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
href: `securitySolutionUI/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -361,14 +361,14 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Rules',
|
||||
href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: 'ALERT_RULE_NAME',
|
||||
href: `securitySolution/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
href: `securitySolutionUI/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
},
|
||||
{
|
||||
text: 'Edit',
|
||||
|
@ -383,10 +383,10 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Cases',
|
||||
href: "securitySolution/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -403,14 +403,14 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Cases',
|
||||
href: "securitySolution/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
},
|
||||
{
|
||||
text: sampleCase.name,
|
||||
href: `securitySolution/case/${sampleCase.id}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
href: `securitySolutionUI/case/${sampleCase.id}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -420,7 +420,7 @@ describe('Navigation Breadcrumbs', () => {
|
|||
getUrlForAppMock
|
||||
);
|
||||
expect(breadcrumbs).toEqual([
|
||||
{ text: 'Security', href: 'securitySolution/overview' },
|
||||
{ text: 'Security', href: 'securitySolutionUI/overview' },
|
||||
{
|
||||
text: 'Endpoints',
|
||||
href: '',
|
||||
|
@ -442,17 +442,17 @@ describe('Navigation Breadcrumbs', () => {
|
|||
expect(setBreadcrumbsMock).toBeCalledWith([
|
||||
expect.objectContaining({
|
||||
text: 'Security',
|
||||
href: 'securitySolution/overview',
|
||||
href: 'securitySolutionUI/overview',
|
||||
onClick: expect.any(Function),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
text: 'Hosts',
|
||||
href: "securitySolution/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
onClick: expect.any(Function),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
text: 'siem-kibana',
|
||||
href: "securitySolution/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
href: "securitySolutionUI/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
|
||||
onClick: expect.any(Function),
|
||||
}),
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ import { getOr, omit } from 'lodash/fp';
|
|||
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { ChromeBreadcrumb } from '../../../../../../../../src/core/public';
|
||||
import { APP_NAME, APP_ID } from '../../../../../common/constants';
|
||||
import { APP_NAME, APP_UI_ID } from '../../../../../common/constants';
|
||||
import { StartServices } from '../../../../types';
|
||||
import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../hosts/pages/details/utils';
|
||||
import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../network/pages/details';
|
||||
|
@ -92,7 +92,7 @@ export const getBreadcrumbsForRoute = (
|
|||
getUrlForApp: GetUrlForApp
|
||||
): ChromeBreadcrumb[] | null => {
|
||||
const spyState: RouteSpyState = omit('navTabs', object);
|
||||
const overviewPath = getUrlForApp(APP_ID, { deepLinkId: SecurityPageName.overview });
|
||||
const overviewPath = getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.overview });
|
||||
const siemRootBreadcrumb: ChromeBreadcrumb = {
|
||||
text: APP_NAME,
|
||||
href: getAppOverviewUrl(overviewPath),
|
||||
|
|
|
@ -116,7 +116,7 @@ describe('Table Navigation', () => {
|
|||
`EuiTab[data-test-subj="navigation-${HostsTableType.authentications}"]`
|
||||
);
|
||||
expect(firstTab.props().href).toBe(
|
||||
`/app/securitySolution/hosts/siem-window/authentications${SEARCH_QUERY}`
|
||||
`/app/securitySolutionUI/hosts/siem-window/authentications${SEARCH_QUERY}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@ import { UrlInputsModel } from '../../../store/inputs/model';
|
|||
import { useRouteSpy } from '../../../utils/route/use_route_spy';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features';
|
||||
import { TestProviders } from '../../../mock';
|
||||
import { CASES_FEATURE_ID } from '../../../../../common/constants';
|
||||
import { useCanSeeHostIsolationExceptionsMenu } from '../../../../management/pages/host_isolation_exceptions/view/hooks';
|
||||
|
||||
jest.mock('../../../lib/kibana/kibana_react');
|
||||
|
@ -88,9 +89,10 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
`${appId}/${options?.deepLinkId ?? ''}${options?.path ?? ''}`,
|
||||
capabilities: {
|
||||
siem: {
|
||||
crud_alerts: true,
|
||||
read_alerts: true,
|
||||
show: true,
|
||||
crud: true,
|
||||
},
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
},
|
||||
},
|
||||
chrome: {
|
||||
|
@ -114,10 +116,10 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
"id": "main",
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-href": "securitySolution/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-overview",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "overview",
|
||||
"isSelected": false,
|
||||
"name": "Overview",
|
||||
|
@ -130,30 +132,30 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
"id": "detect",
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-href": "securitySolution/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-alerts",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "alerts",
|
||||
"isSelected": false,
|
||||
"name": "Alerts",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-href": "securitySolution/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-rules",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "rules",
|
||||
"isSelected": false,
|
||||
"name": "Rules",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-href": "securitySolution/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-exceptions",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "exceptions",
|
||||
"isSelected": false,
|
||||
"name": "Exceptions",
|
||||
|
@ -166,20 +168,20 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
"id": "explore",
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-href": "securitySolution/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-hosts",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "hosts",
|
||||
"isSelected": true,
|
||||
"name": "Hosts",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-href": "securitySolution/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-network",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "network",
|
||||
"isSelected": false,
|
||||
"name": "Network",
|
||||
|
@ -192,10 +194,10 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
"id": "investigate",
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-href": "securitySolution/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-timelines",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "timelines",
|
||||
"isSelected": false,
|
||||
"name": "Timelines",
|
||||
|
@ -208,40 +210,40 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
"id": "manage",
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-href": "securitySolution/endpoints",
|
||||
"data-href": "securitySolutionUI/endpoints",
|
||||
"data-test-subj": "navigation-endpoints",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/endpoints",
|
||||
"href": "securitySolutionUI/endpoints",
|
||||
"id": "endpoints",
|
||||
"isSelected": false,
|
||||
"name": "Endpoints",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-href": "securitySolution/trusted_apps",
|
||||
"data-href": "securitySolutionUI/trusted_apps",
|
||||
"data-test-subj": "navigation-trusted_apps",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/trusted_apps",
|
||||
"href": "securitySolutionUI/trusted_apps",
|
||||
"id": "trusted_apps",
|
||||
"isSelected": false,
|
||||
"name": "Trusted applications",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-href": "securitySolution/event_filters",
|
||||
"data-href": "securitySolutionUI/event_filters",
|
||||
"data-test-subj": "navigation-event_filters",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/event_filters",
|
||||
"href": "securitySolutionUI/event_filters",
|
||||
"id": "event_filters",
|
||||
"isSelected": false,
|
||||
"name": "Event filters",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-href": "securitySolution/host_isolation_exceptions",
|
||||
"data-href": "securitySolutionUI/host_isolation_exceptions",
|
||||
"data-test-subj": "navigation-host_isolation_exceptions",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/host_isolation_exceptions",
|
||||
"href": "securitySolutionUI/host_isolation_exceptions",
|
||||
"id": "host_isolation_exceptions",
|
||||
"isSelected": false,
|
||||
"name": "Host isolation exceptions",
|
||||
|
@ -299,10 +301,10 @@ describe('useSecuritySolutionNavigation', () => {
|
|||
);
|
||||
expect(caseNavItem).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"data-href": "securitySolution/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-href": "securitySolutionUI/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"data-test-subj": "navigation-case",
|
||||
"disabled": false,
|
||||
"href": "securitySolution/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"href": "securitySolutionUI/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
|
||||
"id": "case",
|
||||
"isSelected": false,
|
||||
"name": "Cases",
|
||||
|
|
|
@ -11,6 +11,7 @@ import { EuiSideNavItemType } from '@elastic/eui/src/components/side_nav/side_na
|
|||
import { securityNavGroup } from '../../../../app/home/home_navigations';
|
||||
import { getSearch } from '../helpers';
|
||||
import { PrimaryNavigationItemsProps } from './types';
|
||||
import { useKibana } from '../../../lib/kibana/kibana_react';
|
||||
import { useGetUserCasesPermissions } from '../../../lib/kibana';
|
||||
import { useNavigation } from '../../../lib/kibana/hooks';
|
||||
import { NavTab } from '../types';
|
||||
|
@ -64,34 +65,52 @@ export const usePrimaryNavigationItems = ({
|
|||
function usePrimaryNavigationItemsToDisplay(navTabs: Record<string, NavTab>) {
|
||||
const hasCasesReadPermissions = useGetUserCasesPermissions()?.read;
|
||||
const canSeeHostIsolationExceptions = useCanSeeHostIsolationExceptionsMenu();
|
||||
return useMemo(() => {
|
||||
return [
|
||||
{
|
||||
id: 'main',
|
||||
name: '',
|
||||
items: [navTabs.overview],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.detect,
|
||||
items: [navTabs.alerts, navTabs.rules, navTabs.exceptions],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.explore,
|
||||
items: [navTabs.hosts, navTabs.network, ...(navTabs.ueba != null ? [navTabs.ueba] : [])],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.investigate,
|
||||
items: hasCasesReadPermissions ? [navTabs.timelines, navTabs.case] : [navTabs.timelines],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.manage,
|
||||
items: [
|
||||
navTabs.endpoints,
|
||||
navTabs.trusted_apps,
|
||||
navTabs.event_filters,
|
||||
...(canSeeHostIsolationExceptions ? [navTabs.host_isolation_exceptions] : []),
|
||||
],
|
||||
},
|
||||
];
|
||||
}, [navTabs, hasCasesReadPermissions, canSeeHostIsolationExceptions]);
|
||||
const uiCapabilities = useKibana().services.application.capabilities;
|
||||
return useMemo(
|
||||
() =>
|
||||
uiCapabilities.siem.show
|
||||
? [
|
||||
{
|
||||
id: 'main',
|
||||
name: '',
|
||||
items: [navTabs.overview],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.detect,
|
||||
items: [navTabs.alerts, navTabs.rules, navTabs.exceptions],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.explore,
|
||||
items: [
|
||||
navTabs.hosts,
|
||||
navTabs.network,
|
||||
...(navTabs.ueba != null ? [navTabs.ueba] : []),
|
||||
],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.investigate,
|
||||
items: hasCasesReadPermissions
|
||||
? [navTabs.timelines, navTabs.case]
|
||||
: [navTabs.timelines],
|
||||
},
|
||||
{
|
||||
...securityNavGroup.manage,
|
||||
items: [
|
||||
navTabs.endpoints,
|
||||
navTabs.trusted_apps,
|
||||
navTabs.event_filters,
|
||||
...(canSeeHostIsolationExceptions ? [navTabs.host_isolation_exceptions] : []),
|
||||
],
|
||||
},
|
||||
]
|
||||
: hasCasesReadPermissions
|
||||
? [
|
||||
{
|
||||
...securityNavGroup.investigate,
|
||||
items: [navTabs.case],
|
||||
},
|
||||
]
|
||||
: [],
|
||||
[uiCapabilities.siem.show, navTabs, hasCasesReadPermissions, canSeeHostIsolationExceptions]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -40,15 +40,16 @@ export const UserPrivilegesProvider = ({
|
|||
kibanaCapabilities,
|
||||
children,
|
||||
}: UserPrivilegesProviderProps) => {
|
||||
const listPrivileges = useFetchListPrivileges();
|
||||
const detectionEnginePrivileges = useFetchDetectionEnginePrivileges();
|
||||
const endpointPrivileges = useEndpointPrivileges();
|
||||
const [kibanaSecuritySolutionsPrivileges, setKibanaSecuritySolutionsPrivileges] = useState({
|
||||
crud: false,
|
||||
read: false,
|
||||
});
|
||||
const crud: boolean = kibanaCapabilities[SERVER_APP_ID].crud === true;
|
||||
const read: boolean = kibanaCapabilities[SERVER_APP_ID].show === true;
|
||||
const [kibanaSecuritySolutionsPrivileges, setKibanaSecuritySolutionsPrivileges] = useState({
|
||||
crud,
|
||||
read,
|
||||
});
|
||||
|
||||
const listPrivileges = useFetchListPrivileges(read);
|
||||
const detectionEnginePrivileges = useFetchDetectionEnginePrivileges(read);
|
||||
const endpointPrivileges = useEndpointPrivileges();
|
||||
|
||||
useEffect(() => {
|
||||
setKibanaSecuritySolutionsPrivileges((currPrivileges) => {
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
createStartServicesMock,
|
||||
createWithKibanaMock,
|
||||
} from '../kibana_react.mock';
|
||||
import { APP_ID } from '../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../common/constants';
|
||||
|
||||
const mockStartServicesMock = createStartServicesMock();
|
||||
export const KibanaServices = { get: jest.fn(), getKibanaVersion: jest.fn(() => '8.0.0') };
|
||||
|
@ -65,7 +65,7 @@ export const useGetUserCasesPermissions = jest.fn();
|
|||
export const useAppUrl = jest.fn().mockReturnValue({
|
||||
getAppUrl: jest
|
||||
.fn()
|
||||
.mockImplementation(({ appId = APP_ID, ...options }) =>
|
||||
.mockImplementation(({ appId = APP_UI_ID, ...options }) =>
|
||||
mockStartServicesMock.application.getUrlForApp(appId, options)
|
||||
),
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { camelCase, isArray, isObject } from 'lodash';
|
||||
import { set } from '@elastic/safer-lodash-set';
|
||||
import {
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
CASES_FEATURE_ID,
|
||||
DEFAULT_DATE_FORMAT,
|
||||
DEFAULT_DATE_FORMAT_TZ,
|
||||
|
@ -174,7 +174,7 @@ export const useAppUrl = () => {
|
|||
|
||||
const getAppUrl = useCallback(
|
||||
({
|
||||
appId = APP_ID,
|
||||
appId = APP_UI_ID,
|
||||
...options
|
||||
}: {
|
||||
appId?: string;
|
||||
|
@ -197,7 +197,7 @@ export const useNavigateTo = () => {
|
|||
const navigateTo = useCallback(
|
||||
({
|
||||
url,
|
||||
appId = APP_ID,
|
||||
appId = APP_UI_ID,
|
||||
...options
|
||||
}: {
|
||||
url?: string;
|
||||
|
|
|
@ -22,7 +22,7 @@ import { createStartServicesMock } from '../../lib/kibana/kibana_react.mock';
|
|||
import { SUB_PLUGINS_REDUCER, mockGlobalState, createSecuritySolutionStorageMock } from '..';
|
||||
import { ExperimentalFeatures } from '../../../../common/experimental_features';
|
||||
import { PLUGIN_ID } from '../../../../../fleet/common';
|
||||
import { APP_ID, APP_PATH } from '../../../../common/constants';
|
||||
import { APP_UI_ID, APP_PATH } from '../../../../common/constants';
|
||||
import { KibanaContextProvider, KibanaServices } from '../../lib/kibana';
|
||||
import { getDeepLinks } from '../../../app/deep_links';
|
||||
import { fleetGetPackageListHttpMock } from '../../../management/pages/mocks';
|
||||
|
@ -176,7 +176,7 @@ const createCoreStartMock = (
|
|||
switch (appId) {
|
||||
case PLUGIN_ID:
|
||||
return '/app/fleet';
|
||||
case APP_ID:
|
||||
case APP_UI_ID:
|
||||
return `${APP_PATH}${
|
||||
deepLinkId && deepLinkPaths[deepLinkId] ? deepLinkPaths[deepLinkId] : ''
|
||||
}${path ?? ''}`;
|
||||
|
@ -186,7 +186,7 @@ const createCoreStartMock = (
|
|||
});
|
||||
|
||||
coreStart.application.navigateToApp.mockImplementation((appId, { deepLinkId, path } = {}) => {
|
||||
if (appId === APP_ID) {
|
||||
if (appId === APP_UI_ID) {
|
||||
history.push(
|
||||
`${deepLinkId && deepLinkPaths[deepLinkId] ? deepLinkPaths[deepLinkId] : ''}${path ?? ''}`
|
||||
);
|
||||
|
|
|
@ -26,6 +26,7 @@ import { FieldHook } from '../../shared_imports';
|
|||
import { SUB_PLUGINS_REDUCER } from './utils';
|
||||
import { createSecuritySolutionStorageMock, localStorageMock } from './mock_local_storage';
|
||||
import { UserPrivilegesProvider } from '../components/user_privileges';
|
||||
import { CASES_FEATURE_ID } from '../../../common/constants';
|
||||
|
||||
const state: State = mockGlobalState;
|
||||
|
||||
|
@ -76,7 +77,10 @@ const TestProvidersWithPrivilegesComponent: React.FC<Props> = ({
|
|||
<ThemeProvider theme={() => ({ eui: euiDarkVars, darkMode: true })}>
|
||||
<UserPrivilegesProvider
|
||||
kibanaCapabilities={
|
||||
{ siem: { crud_alerts: true, read_alerts: true } } as unknown as Capabilities
|
||||
{
|
||||
siem: { show: true, crud: true },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
} as unknown as Capabilities
|
||||
}
|
||||
>
|
||||
<DragDropContext onDragEnd={onDragEnd}>{children}</DragDropContext>
|
||||
|
|
|
@ -122,7 +122,7 @@ describe('AlertsHistogramPanel', () => {
|
|||
preventDefault: jest.fn(),
|
||||
});
|
||||
|
||||
expect(mockNavigateToApp).toBeCalledWith('securitySolution', {
|
||||
expect(mockNavigateToApp).toBeCalledWith('securitySolutionUI', {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
path: '',
|
||||
});
|
||||
|
|
|
@ -14,7 +14,7 @@ import { isEmpty } from 'lodash/fp';
|
|||
import uuid from 'uuid';
|
||||
|
||||
import { useGlobalTime } from '../../../../common/containers/use_global_time';
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../../common/constants';
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../../common/constants';
|
||||
import type { UpdateDateRange } from '../../../../common/components/charts/common';
|
||||
import type { LegendItem } from '../../../../common/components/charts/draggable_legend_item';
|
||||
import { escapeDataProviderId } from '../../../../common/components/drag_and_drop/helpers';
|
||||
|
@ -147,7 +147,7 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>(
|
|||
const goToDetectionEngine = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
path: getDetectionEngineUrl(urlSearch),
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { useMemo } from 'react';
|
||||
import { useGetUserCasesPermissions, useKibana } from '../../../../common/lib/kibana';
|
||||
import { TimelineId, TimelineNonEcsData } from '../../../../../common';
|
||||
import { APP_ID } from '../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../common/constants';
|
||||
import { useInsertTimeline } from '../../../../cases/components/use_insert_timeline';
|
||||
import { Ecs } from '../../../../../common/ecs';
|
||||
|
||||
|
@ -39,7 +39,7 @@ export const useAddToCaseActions = ({
|
|||
event: { data: nonEcsData ?? [], ecs: ecsData, _id: ecsData?._id },
|
||||
useInsertTimeline: insertTimelineHook,
|
||||
casePermissions,
|
||||
appId: APP_ID,
|
||||
appId: APP_UI_ID,
|
||||
onClose: afterCaseSelection,
|
||||
}
|
||||
: null,
|
||||
|
|
|
@ -30,7 +30,7 @@ import { getRulesUrl } from '../../../../common/components/link_to/redirect_to_d
|
|||
import { getToolTipContent } from '../../../../common/utils/privileges';
|
||||
import { useBoolState } from '../../../../common/hooks/use_bool_state';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import { APP_ID, SecurityPageName } from '../../../../../common/constants';
|
||||
import { APP_UI_ID, SecurityPageName } from '../../../../../common/constants';
|
||||
|
||||
const MyEuiButtonIcon = styled(EuiButtonIcon)`
|
||||
&.euiButtonIcon {
|
||||
|
@ -62,7 +62,7 @@ const RuleActionsOverflowComponent = ({
|
|||
const [, dispatchToaster] = useStateToaster();
|
||||
|
||||
const onRuleDeletedCallback = useCallback(() => {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRulesUrl(),
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ import { RuleActionsField } from '../rule_actions_field';
|
|||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import { getSchema } from './schema';
|
||||
import * as I18n from './translations';
|
||||
import { APP_ID } from '../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../common/constants';
|
||||
import { useManageCaseAction } from './use_manage_case_action';
|
||||
|
||||
interface StepRuleActionsProps extends RuleStepProps {
|
||||
|
@ -80,7 +80,7 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
|
|||
} = useKibana();
|
||||
const kibanaAbsoluteUrl = useMemo(
|
||||
() =>
|
||||
application.getUrlForApp(`${APP_ID}`, {
|
||||
application.getUrlForApp(`${APP_UI_ID}`, {
|
||||
absolute: true,
|
||||
}),
|
||||
[application]
|
||||
|
|
|
@ -69,9 +69,7 @@ describe('useUserInfo', () => {
|
|||
const wrapper = ({ children }: { children: JSX.Element }) => (
|
||||
<TestProviders>
|
||||
<UserPrivilegesProvider
|
||||
kibanaCapabilities={
|
||||
{ siem: { crud_alerts: true, read_alerts: true } } as unknown as Capabilities
|
||||
}
|
||||
kibanaCapabilities={{ siem: { show: true, crud: true } } as unknown as Capabilities}
|
||||
>
|
||||
<ManageUserInfo>{children}</ManageUserInfo>
|
||||
</UserPrivilegesProvider>
|
||||
|
|
|
@ -13,7 +13,7 @@ import * as i18n from './translations';
|
|||
|
||||
export const useFetchPrivileges = () => useAsync(withOptionalSignal(getUserPrivilege));
|
||||
|
||||
export const useFetchDetectionEnginePrivileges = () => {
|
||||
export const useFetchDetectionEnginePrivileges = (isAppAvailable: boolean = true) => {
|
||||
const { start, ...detectionEnginePrivileges } = useFetchPrivileges();
|
||||
const { addError } = useAppToasts();
|
||||
const abortCtrlRef = useRef(new AbortController());
|
||||
|
@ -21,12 +21,12 @@ export const useFetchDetectionEnginePrivileges = () => {
|
|||
useEffect(() => {
|
||||
const { loading, result, error } = detectionEnginePrivileges;
|
||||
|
||||
if (!loading && !(result || error)) {
|
||||
if (isAppAvailable && !loading && !(result || error)) {
|
||||
abortCtrlRef.current.abort();
|
||||
abortCtrlRef.current = new AbortController();
|
||||
start({ signal: abortCtrlRef.current.signal });
|
||||
}
|
||||
}, [start, detectionEnginePrivileges]);
|
||||
}, [start, detectionEnginePrivileges, isAppAvailable]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
|
|
@ -22,7 +22,7 @@ interface ListPrivileges {
|
|||
};
|
||||
}
|
||||
|
||||
export const useFetchListPrivileges = () => {
|
||||
export const useFetchListPrivileges = (isAppAvailable: boolean = true) => {
|
||||
const http = useHttp();
|
||||
const { lists } = useKibana().services;
|
||||
const { start: fetchListPrivileges, ...listPrivileges } = useReadListPrivileges();
|
||||
|
@ -32,12 +32,12 @@ export const useFetchListPrivileges = () => {
|
|||
useEffect(() => {
|
||||
const { loading, result, error } = listPrivileges;
|
||||
|
||||
if (lists && !loading && !(result || error)) {
|
||||
if (isAppAvailable && lists && !loading && !(result || error)) {
|
||||
abortCtrlRef.current.abort();
|
||||
abortCtrlRef.current = new AbortController();
|
||||
fetchListPrivileges({ http, signal: abortCtrlRef.current.signal });
|
||||
}
|
||||
}, [http, lists, fetchListPrivileges, listPrivileges]);
|
||||
}, [http, lists, fetchListPrivileges, listPrivileges, isAppAvailable]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { Dispatch } from 'react';
|
||||
import { NavigateToAppOptions } from '../../../../../../../../../src/core/public';
|
||||
import { APP_ID } from '../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../common/constants';
|
||||
import { BulkAction } from '../../../../../../common/detection_engine/schemas/common/schemas';
|
||||
import { CreateRulesSchema } from '../../../../../../common/detection_engine/schemas/request';
|
||||
import { SecurityPageName } from '../../../../../app/types';
|
||||
|
@ -37,7 +37,7 @@ export const editRuleAction = (
|
|||
ruleId: string,
|
||||
navigateToApp: (appId: string, options?: NavigateToAppOptions | undefined) => Promise<void>
|
||||
) => {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getEditRuleUrl(ruleId ?? ''),
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ import { getToolTipContent, canEditRuleWithActions } from '../../../../../common
|
|||
import { PopoverTooltip } from './popover_tooltip';
|
||||
import { TagsDisplay } from './tag_display';
|
||||
import { getRuleStatusText } from '../../../../../../common/detection_engine/utils';
|
||||
import { APP_ID, SecurityPageName } from '../../../../../../common/constants';
|
||||
import { APP_UI_ID, SecurityPageName } from '../../../../../../common/constants';
|
||||
import { DocLinksStart, NavigateToAppOptions } from '../../../../../../../../../src/core/public';
|
||||
|
||||
export const getActions = (
|
||||
|
@ -164,7 +164,7 @@ export const getColumns = ({
|
|||
data-test-subj="ruleName"
|
||||
onClick={(ev: { preventDefault: () => void }) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(item.id),
|
||||
});
|
||||
|
@ -329,7 +329,7 @@ export const getMonitoringColumns = (
|
|||
data-test-subj="ruleName"
|
||||
onClick={(ev: { preventDefault: () => void }) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(item.id),
|
||||
});
|
||||
|
|
|
@ -47,7 +47,7 @@ import { formatRule, stepIsValid } from './helpers';
|
|||
import * as i18n from './translations';
|
||||
import { SecurityPageName } from '../../../../../app/types';
|
||||
import { ruleStepsOrder } from '../utils';
|
||||
import { APP_ID } from '../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../common/constants';
|
||||
import { useKibana } from '../../../../../common/lib/kibana';
|
||||
|
||||
const formHookNoop = async (): Promise<undefined> => undefined;
|
||||
|
@ -269,7 +269,7 @@ const CreateRulePageComponent: React.FC = () => {
|
|||
|
||||
if (ruleName && ruleId) {
|
||||
displaySuccessToast(i18n.SUCCESSFULLY_CREATED_RULES(ruleName), dispatchToaster);
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId),
|
||||
});
|
||||
|
@ -284,13 +284,13 @@ const CreateRulePageComponent: React.FC = () => {
|
|||
needsListsConfiguration
|
||||
)
|
||||
) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
path: getDetectionEngineUrl(),
|
||||
});
|
||||
return null;
|
||||
} else if (!userHasPermissions(canUserCRUD)) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRulesUrl(),
|
||||
});
|
||||
|
|
|
@ -89,7 +89,7 @@ import { LinkButton } from '../../../../../common/components/links';
|
|||
import { useFormatUrl } from '../../../../../common/components/link_to';
|
||||
import { ExceptionsViewer } from '../../../../../common/components/exceptions/viewer';
|
||||
import {
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
DEFAULT_INDEX_PATTERN,
|
||||
DEFAULT_INDEX_PATTERN_EXPERIMENTAL,
|
||||
} from '../../../../../../common/constants';
|
||||
|
@ -574,7 +574,7 @@ const RuleDetailsPageComponent: React.FC<DetectionEngineComponentProps> = ({
|
|||
const goToEditRule = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getEditRuleUrl(ruleId ?? ''),
|
||||
});
|
||||
|
@ -683,7 +683,7 @@ const RuleDetailsPageComponent: React.FC<DetectionEngineComponentProps> = ({
|
|||
needsListsConfiguration
|
||||
)
|
||||
) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
path: getDetectionEngineUrl(),
|
||||
});
|
||||
|
|
|
@ -56,7 +56,7 @@ import * as i18n from './translations';
|
|||
import { SecurityPageName } from '../../../../../app/types';
|
||||
import { ruleStepsOrder } from '../utils';
|
||||
import { useKibana } from '../../../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../common/constants';
|
||||
|
||||
const formHookNoop = async (): Promise<undefined> => undefined;
|
||||
|
||||
|
@ -300,7 +300,7 @@ const EditRulePageComponent: FC = () => {
|
|||
const goToDetailsRule = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId ?? ''),
|
||||
});
|
||||
|
@ -318,7 +318,7 @@ const EditRulePageComponent: FC = () => {
|
|||
|
||||
if (isSaved) {
|
||||
displaySuccessToast(i18n.SUCCESSFULLY_SAVED_RULE(rule?.name ?? ''), dispatchToaster);
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId ?? ''),
|
||||
});
|
||||
|
@ -333,13 +333,13 @@ const EditRulePageComponent: FC = () => {
|
|||
needsListsConfiguration
|
||||
)
|
||||
) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
path: getDetectionEngineUrl(),
|
||||
});
|
||||
return null;
|
||||
} else if (!userHasPermissions(canUserCRUD)) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId ?? ''),
|
||||
});
|
||||
|
|
|
@ -36,7 +36,7 @@ import { useFormatUrl } from '../../../../common/components/link_to';
|
|||
import { NeedAdminForUpdateRulesCallOut } from '../../../components/callouts/need_admin_for_update_callout';
|
||||
import { MlJobCompatibilityCallout } from '../../../components/callouts/ml_job_compatibility_callout';
|
||||
import { MissingPrivilegesCallOut } from '../../../components/callouts/missing_privileges_callout';
|
||||
import { APP_ID } from '../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../common/constants';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
|
||||
type Func = () => Promise<void>;
|
||||
|
@ -125,7 +125,7 @@ const RulesPageComponent: React.FC = () => {
|
|||
const goToNewRule = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, { deepLinkId: SecurityPageName.rules, path: getCreateRuleUrl() });
|
||||
navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getCreateRuleUrl() });
|
||||
},
|
||||
[navigateToApp]
|
||||
);
|
||||
|
@ -156,7 +156,7 @@ const RulesPageComponent: React.FC = () => {
|
|||
needsListsConfiguration
|
||||
)
|
||||
) {
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
path: getDetectionEngineUrl(),
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ import * as i18nRules from './translations';
|
|||
import { RouteSpyState } from '../../../../common/utils/route/types';
|
||||
import { GetUrlForApp } from '../../../../common/components/navigation/types';
|
||||
import { SecurityPageName } from '../../../../app/types';
|
||||
import { APP_ID, RULES_PATH } from '../../../../../common/constants';
|
||||
import { APP_UI_ID, RULES_PATH } from '../../../../../common/constants';
|
||||
import { RuleStep, RuleStepsOrder } from './types';
|
||||
|
||||
export const ruleStepsOrder: RuleStepsOrder = [
|
||||
|
@ -32,7 +32,7 @@ const getRulesBreadcrumb = (pathname: string, search: string[], getUrlForApp: Ge
|
|||
if (tabPath === 'rules') {
|
||||
return {
|
||||
text: i18nRules.PAGE_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRulesUrl(!isEmpty(search[0]) ? search[0] : ''),
|
||||
}),
|
||||
|
@ -64,7 +64,7 @@ export const getBreadcrumbs = (
|
|||
...breadcrumb,
|
||||
{
|
||||
text: params.state.ruleName,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(params.detailName, !isEmpty(search[0]) ? search[0] : ''),
|
||||
}),
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* 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 { parseRoute, getHostRiskIndex } from './helpers';
|
||||
|
||||
describe('public helpers parseRoute', () => {
|
||||
it('should properly parse hash route', () => {
|
||||
const hashSearch =
|
||||
'?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))';
|
||||
const hashLocation = {
|
||||
hash: `#/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`,
|
||||
pathname: '/app/siem',
|
||||
search: '',
|
||||
};
|
||||
|
||||
expect(parseRoute(hashLocation)).toEqual({
|
||||
pageName: 'detections',
|
||||
path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`,
|
||||
search: hashSearch,
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse non-hash route', () => {
|
||||
const nonHashLocation = {
|
||||
hash: '',
|
||||
pathname: '/app/security/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit',
|
||||
search:
|
||||
'?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))',
|
||||
};
|
||||
|
||||
expect(parseRoute(nonHashLocation)).toEqual({
|
||||
pageName: 'detections',
|
||||
path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${nonHashLocation.search}`,
|
||||
search: nonHashLocation.search,
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse non-hash subplugin route', () => {
|
||||
const nonHashLocation = {
|
||||
hash: '',
|
||||
pathname: '/app/security/detections',
|
||||
search:
|
||||
'?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))',
|
||||
};
|
||||
|
||||
expect(parseRoute(nonHashLocation)).toEqual({
|
||||
pageName: 'detections',
|
||||
path: `${nonHashLocation.search}`,
|
||||
search: nonHashLocation.search,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('public helpers export getHostRiskIndex', () => {
|
||||
it('should properly return index if space is specified', () => {
|
||||
expect(getHostRiskIndex('testName')).toEqual('ml_host_risk_score_latest_testName');
|
||||
});
|
||||
});
|
276
x-pack/plugins/security_solution/public/helpers.test.tsx
Normal file
276
x-pack/plugins/security_solution/public/helpers.test.tsx
Normal file
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* 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 from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Capabilities } from '../../../../src/core/public';
|
||||
import { CASES_FEATURE_ID, SERVER_APP_ID } from '../common/constants';
|
||||
import {
|
||||
parseRoute,
|
||||
getHostRiskIndex,
|
||||
isSubPluginAvailable,
|
||||
getSubPluginRoutesByCapabilities,
|
||||
RedirectRoute,
|
||||
} from './helpers';
|
||||
import { StartedSubPlugins } from './types';
|
||||
|
||||
describe('public helpers parseRoute', () => {
|
||||
it('should properly parse hash route', () => {
|
||||
const hashSearch =
|
||||
'?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))';
|
||||
const hashLocation = {
|
||||
hash: `#/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`,
|
||||
pathname: '/app/siem',
|
||||
search: '',
|
||||
};
|
||||
|
||||
expect(parseRoute(hashLocation)).toEqual({
|
||||
pageName: 'detections',
|
||||
path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`,
|
||||
search: hashSearch,
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse non-hash route', () => {
|
||||
const nonHashLocation = {
|
||||
hash: '',
|
||||
pathname: '/app/security/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit',
|
||||
search:
|
||||
'?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))',
|
||||
};
|
||||
|
||||
expect(parseRoute(nonHashLocation)).toEqual({
|
||||
pageName: 'detections',
|
||||
path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${nonHashLocation.search}`,
|
||||
search: nonHashLocation.search,
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse non-hash subplugin route', () => {
|
||||
const nonHashLocation = {
|
||||
hash: '',
|
||||
pathname: '/app/security/detections',
|
||||
search:
|
||||
'?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))',
|
||||
};
|
||||
|
||||
expect(parseRoute(nonHashLocation)).toEqual({
|
||||
pageName: 'detections',
|
||||
path: `${nonHashLocation.search}`,
|
||||
search: nonHashLocation.search,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('public helpers export getHostRiskIndex', () => {
|
||||
it('should properly return index if space is specified', () => {
|
||||
expect(getHostRiskIndex('testName')).toEqual('ml_host_risk_score_latest_testName');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getSubPluginRoutesByCapabilities', () => {
|
||||
const mockRender = () => null;
|
||||
const mockSubPlugins = {
|
||||
alerts: { routes: [{ path: 'alerts', render: mockRender }] },
|
||||
cases: { routes: [{ path: 'cases', render: mockRender }] },
|
||||
} as unknown as StartedSubPlugins;
|
||||
it('cases routes should return NoPrivilegesPage component when cases plugin is NOT available ', () => {
|
||||
const routes = getSubPluginRoutesByCapabilities(mockSubPlugins, {
|
||||
[SERVER_APP_ID]: { show: true, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities);
|
||||
const casesRoute = routes.find((r) => r.path === 'cases');
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const CasesView = (casesRoute?.component ?? mockRender) as React.ComponentType<any>;
|
||||
expect(shallow(<CasesView />)).toMatchInlineSnapshot(`
|
||||
<NoPrivilegePage
|
||||
subPluginKey="cases"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('alerts should return NoPrivilegesPage component when siem plugin is NOT available ', () => {
|
||||
const routes = getSubPluginRoutesByCapabilities(mockSubPlugins, {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
} as unknown as Capabilities);
|
||||
const alertsRoute = routes.find((r) => r.path === 'alerts');
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const AlertsView = (alertsRoute?.component ?? mockRender) as React.ComponentType<any>;
|
||||
expect(shallow(<AlertsView />)).toMatchInlineSnapshot(`
|
||||
<NoPrivilegePage
|
||||
subPluginKey="alerts"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('should return NoPrivilegesPage for each route when both plugins are NOT available ', () => {
|
||||
const routes = getSubPluginRoutesByCapabilities(mockSubPlugins, {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities);
|
||||
const casesRoute = routes.find((r) => r.path === 'cases');
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const CasesView = (casesRoute?.component ?? mockRender) as React.ComponentType<any>;
|
||||
|
||||
const alertsRoute = routes.find((r) => r.path === 'alerts');
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const AlertsView = (alertsRoute?.component ?? mockRender) as React.ComponentType<any>;
|
||||
|
||||
expect(shallow(<AlertsView />)).toMatchInlineSnapshot(`
|
||||
<NoPrivilegePage
|
||||
subPluginKey="alerts"
|
||||
/>
|
||||
`);
|
||||
expect(shallow(<CasesView />)).toMatchInlineSnapshot(`
|
||||
<NoPrivilegePage
|
||||
subPluginKey="cases"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#isSubPluginAvailable', () => {
|
||||
it('plugin outsides of cases should be available if siem privilege is all and independently of cases privileges', () => {
|
||||
expect(
|
||||
isSubPluginAvailable('pluginKey', {
|
||||
[SERVER_APP_ID]: { show: true, crud: true },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('plugin outsides of cases should be available if siem privilege is read and independently of cases privileges', () => {
|
||||
expect(
|
||||
isSubPluginAvailable('pluginKey', {
|
||||
[SERVER_APP_ID]: { show: true, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('plugin outsides of cases should NOT be available if siem privilege is none and independently of cases privileges', () => {
|
||||
expect(
|
||||
isSubPluginAvailable('pluginKey', {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities)
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('cases plugin should be available if cases privilege is all and independently of siem privileges', () => {
|
||||
expect(
|
||||
isSubPluginAvailable('cases', {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
} as unknown as Capabilities)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('cases plugin should be available if cases privilege is read and independently of siem privileges', () => {
|
||||
expect(
|
||||
isSubPluginAvailable('cases', {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
} as unknown as Capabilities)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('cases plugin should NOT be available if cases privilege is none independently of siem privileges', () => {
|
||||
expect(
|
||||
isSubPluginAvailable('pluginKey', {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities)
|
||||
).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('RedirectRoute', () => {
|
||||
it('RedirectRoute should redirect to overview page when siem and case privileges are all', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: true, crud: true },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/overview"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('RedirectRoute should redirect to overview page when siem and case privileges are read', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: true, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/overview"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('RedirectRoute should redirect to overview page when siem and case privileges are off', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: false, crud_cases: false },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/overview"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('RedirectRoute should redirect to overview page when siem privilege is read and case privilege is all', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: true, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/overview"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('RedirectRoute should redirect to overview page when siem privilege is read and case privilege is read', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: true, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/overview"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('RedirectRoute should redirect to cases page when siem privilege is none and case privilege is read', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: false },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/cases"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
||||
it('RedirectRoute should redirect to cases page when siem privilege is none and case privilege is all', () => {
|
||||
const mockCapabilitities = {
|
||||
[SERVER_APP_ID]: { show: false, crud: false },
|
||||
[CASES_FEATURE_ID]: { read_cases: true, crud_cases: true },
|
||||
} as unknown as Capabilities;
|
||||
expect(shallow(<RedirectRoute capabilities={mockCapabilitities} />)).toMatchInlineSnapshot(`
|
||||
<Redirect
|
||||
to="/cases"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
});
|
|
@ -6,24 +6,30 @@
|
|||
*/
|
||||
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import { matchPath } from 'react-router-dom';
|
||||
import React from 'react';
|
||||
import { matchPath, RouteProps, Redirect } from 'react-router-dom';
|
||||
|
||||
import { CoreStart } from '../../../../src/core/public';
|
||||
import { Capabilities, CoreStart } from '../../../../src/core/public';
|
||||
import {
|
||||
ALERTS_PATH,
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
EXCEPTIONS_PATH,
|
||||
RULES_PATH,
|
||||
UEBA_PATH,
|
||||
RISKY_HOSTS_INDEX_PREFIX,
|
||||
SERVER_APP_ID,
|
||||
CASES_FEATURE_ID,
|
||||
OVERVIEW_PATH,
|
||||
CASES_PATH,
|
||||
} from '../common/constants';
|
||||
import {
|
||||
FactoryQueryTypes,
|
||||
StrategyResponseType,
|
||||
} from '../common/search_strategy/security_solution';
|
||||
import { TimelineEqlResponse } from '../common/search_strategy/timeline';
|
||||
import { NoPrivilegesPage } from './app/no_privileges';
|
||||
import { SecurityPageName } from './app/types';
|
||||
import { InspectResponse } from './types';
|
||||
import { CASES_SUB_PLUGIN_KEY, InspectResponse, StartedSubPlugins } from './types';
|
||||
|
||||
export const parseRoute = (location: Pick<Location, 'hash' | 'pathname' | 'search'>) => {
|
||||
if (!isEmpty(location.hash)) {
|
||||
|
@ -59,49 +65,49 @@ export const manageOldSiemRoutes = async (coreStart: CoreStart) => {
|
|||
|
||||
switch (pageName) {
|
||||
case SecurityPageName.overview:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.overview,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
case 'ml-hosts':
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
replace: true,
|
||||
path: `/ml-hosts${path}`,
|
||||
});
|
||||
break;
|
||||
case SecurityPageName.hosts:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
case 'ml-network':
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.network,
|
||||
replace: true,
|
||||
path: `/ml-network${path}`,
|
||||
});
|
||||
break;
|
||||
case SecurityPageName.network:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.network,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
case SecurityPageName.timelines:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.timelines,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
case SecurityPageName.case:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
replace: true,
|
||||
path,
|
||||
|
@ -109,28 +115,28 @@ export const manageOldSiemRoutes = async (coreStart: CoreStart) => {
|
|||
break;
|
||||
case SecurityPageName.detections:
|
||||
case SecurityPageName.alerts:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.alerts,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
case SecurityPageName.rules:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
case SecurityPageName.exceptions:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.exceptions,
|
||||
replace: true,
|
||||
path,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
application.navigateToApp(APP_ID, {
|
||||
application.navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.overview,
|
||||
replace: true,
|
||||
path,
|
||||
|
@ -158,3 +164,47 @@ export const isDetectionsPath = (pathname: string): boolean => {
|
|||
export const getHostRiskIndex = (spaceId: string): string => {
|
||||
return `${RISKY_HOSTS_INDEX_PREFIX}${spaceId}`;
|
||||
};
|
||||
|
||||
export const getSubPluginRoutesByCapabilities = (
|
||||
subPlugins: StartedSubPlugins,
|
||||
capabilities: Capabilities
|
||||
): RouteProps[] => {
|
||||
return [
|
||||
...Object.entries(subPlugins).reduce<RouteProps[]>((acc, [key, value]) => {
|
||||
if (isSubPluginAvailable(key, capabilities)) {
|
||||
return [...acc, ...value.routes];
|
||||
}
|
||||
return [
|
||||
...acc,
|
||||
...value.routes.map((route: RouteProps) => ({
|
||||
path: route.path,
|
||||
component: () => <NoPrivilegesPage subPluginKey={key} />,
|
||||
})),
|
||||
];
|
||||
}, []),
|
||||
{
|
||||
path: '',
|
||||
component: () => <RedirectRoute capabilities={capabilities} />,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const isSubPluginAvailable = (pluginKey: string, capabilities: Capabilities): boolean => {
|
||||
if (CASES_SUB_PLUGIN_KEY === pluginKey) {
|
||||
return capabilities[CASES_FEATURE_ID].read_cases === true;
|
||||
}
|
||||
return capabilities[SERVER_APP_ID].show === true;
|
||||
};
|
||||
|
||||
export const RedirectRoute = React.memo<{ capabilities: Capabilities }>(({ capabilities }) => {
|
||||
const overviewAvailable = isSubPluginAvailable('overview', capabilities);
|
||||
const casesAvailable = isSubPluginAvailable(CASES_SUB_PLUGIN_KEY, capabilities);
|
||||
if (overviewAvailable) {
|
||||
return <Redirect to={OVERVIEW_PATH} />;
|
||||
}
|
||||
if (casesAvailable) {
|
||||
return <Redirect to={CASES_PATH} />;
|
||||
}
|
||||
return <Redirect to={OVERVIEW_PATH} />;
|
||||
});
|
||||
RedirectRoute.displayName = 'RedirectRoute';
|
|
@ -15,7 +15,7 @@ import { getHostDetailsUrl } from '../../../common/components/link_to/redirect_t
|
|||
import * as i18n from '../translations';
|
||||
import { HostRouteSpyState } from '../../../common/utils/route/types';
|
||||
import { GetUrlForApp } from '../../../common/components/navigation/types';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
|
||||
export const type = hostsModel.HostsType.details;
|
||||
|
@ -37,7 +37,7 @@ export const getBreadcrumbs = (
|
|||
let breadcrumb = [
|
||||
{
|
||||
text: i18n.PAGE_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
path: !isEmpty(search[0]) ? search[0] : '',
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
}),
|
||||
|
@ -49,7 +49,7 @@ export const getBreadcrumbs = (
|
|||
...breadcrumb,
|
||||
{
|
||||
text: params.detailName,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
path: getHostDetailsUrl(params.detailName, !isEmpty(search[0]) ? search[0] : ''),
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
}),
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
ContextMenuWithRouterSupportProps,
|
||||
} from './context_menu_with_router_support';
|
||||
import { act, fireEvent, waitForElementToBeRemoved } from '@testing-library/react';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
|
||||
describe('When using the ContextMenuWithRouterSupport component', () => {
|
||||
let appTestContext: AppContextTestRender;
|
||||
|
@ -42,7 +42,7 @@ describe('When using the ContextMenuWithRouterSupport component', () => {
|
|||
},
|
||||
{
|
||||
children: 'click me 2',
|
||||
navigateAppId: APP_ID,
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: {
|
||||
path: '/one/two/three',
|
||||
},
|
||||
|
@ -126,7 +126,7 @@ describe('When using the ContextMenuWithRouterSupport component', () => {
|
|||
});
|
||||
|
||||
expect(appTestContext.coreStart.application.navigateToApp).toHaveBeenCalledWith(
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
expect.objectContaining({ path: '/one/two/three' })
|
||||
);
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { useMemo } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { APP_ID } from '../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../common/constants';
|
||||
import { pagePathGetters } from '../../../../../../../fleet/public';
|
||||
import { getEndpointDetailsPath } from '../../../../common/routing';
|
||||
import { HostMetadata, MaybeImmutable } from '../../../../../../common/endpoint/types';
|
||||
|
@ -67,7 +67,7 @@ export const useEndpointActionItems = (
|
|||
'data-test-subj': 'unIsolateLink',
|
||||
icon: 'logoSecurity',
|
||||
key: 'unIsolateHost',
|
||||
navigateAppId: APP_ID,
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: {
|
||||
path: endpointUnIsolatePath,
|
||||
},
|
||||
|
@ -85,7 +85,7 @@ export const useEndpointActionItems = (
|
|||
'data-test-subj': 'isolateLink',
|
||||
icon: 'logoSecurity',
|
||||
key: 'isolateHost',
|
||||
navigateAppId: APP_ID,
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: {
|
||||
path: endpointIsolatePath,
|
||||
},
|
||||
|
@ -105,7 +105,7 @@ export const useEndpointActionItems = (
|
|||
'data-test-subj': 'hostLink',
|
||||
icon: 'logoSecurity',
|
||||
key: 'hostDetailsLink',
|
||||
navigateAppId: APP_ID,
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: { path: `/hosts/${endpointHostName}` },
|
||||
href: getAppUrl({ path: `/hosts/${endpointHostName}` }),
|
||||
children: (
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
import { PolicyDetailsRouteState } from '../../../../../common/endpoint/types';
|
||||
import { getEndpointListPath } from '../../../common/routing';
|
||||
import { useAppUrl } from '../../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../common/constants';
|
||||
|
||||
export const PolicyDetails = React.memo(() => {
|
||||
// TODO: Remove this and related code when removing FF
|
||||
|
@ -68,7 +68,7 @@ export const PolicyDetails = React.memo(() => {
|
|||
),
|
||||
backButtonUrl: getAppUrl({ path: endpointListPath }),
|
||||
onBackButtonNavigateTo: [
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
{
|
||||
path: endpointListPath,
|
||||
},
|
||||
|
|
|
@ -118,7 +118,7 @@ describe('Policy Form Layout', () => {
|
|||
cancelbutton.simulate('click', { button: 0 });
|
||||
const navigateToAppMockedCalls = coreStart.application.navigateToApp.mock.calls;
|
||||
expect(navigateToAppMockedCalls[navigateToAppMockedCalls.length - 1]).toEqual([
|
||||
'securitySolution',
|
||||
'securitySolutionUI',
|
||||
{ path: endpointListPath },
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ import { SpyRoute } from '../../../../../../common/utils/route/spy_routes';
|
|||
import { SecurityPageName } from '../../../../../../app/types';
|
||||
import { getEndpointListPath } from '../../../../../common/routing';
|
||||
import { useNavigateToAppEventHandler } from '../../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { PolicyDetailsRouteState } from '../../../../../../../common/endpoint/types';
|
||||
import { SecuritySolutionPageWrapper } from '../../../../../../common/components/page_wrapper';
|
||||
import { PolicyDetailsForm } from '../../policy_details_form';
|
||||
|
@ -65,7 +65,7 @@ export const PolicyFormLayout = React.memo(() => {
|
|||
|
||||
const routingOnCancelNavigateTo = routeState?.onCancelNavigateTo;
|
||||
const navigateToAppArguments = useMemo((): Parameters<ApplicationStart['navigateToApp']> => {
|
||||
return routingOnCancelNavigateTo ?? [APP_ID, { path: hostListRouterPath }];
|
||||
return routingOnCancelNavigateTo ?? [APP_UI_ID, { path: hostListRouterPath }];
|
||||
}, [hostListRouterPath, routingOnCancelNavigateTo]);
|
||||
|
||||
// Handle showing update statuses
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ConfigForm } from '../../components/config_form';
|
|||
import { RadioButtons } from '../components/radio_buttons';
|
||||
import { UserNotification } from '../components/user_notification';
|
||||
import { ProtectionSwitch } from '../components/protection_switch';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app';
|
||||
import { SecurityPageName } from '../../../../../../app/types';
|
||||
|
||||
|
@ -51,7 +51,7 @@ export const BehaviorProtection = React.memo(() => {
|
|||
defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page."
|
||||
values={{
|
||||
detectionRulesLink: (
|
||||
<LinkToApp appId={APP_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<LinkToApp appId={APP_UI_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policy.details.detectionRulesLink"
|
||||
defaultMessage="related detection rules"
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../../../../app/types';
|
||||
import { Immutable, OperatingSystem } from '../../../../../../../common/endpoint/types';
|
||||
import { MalwareProtectionOSes, OS } from '../../../types';
|
||||
|
@ -54,7 +54,7 @@ export const MalwareProtections = React.memo(() => {
|
|||
defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page."
|
||||
values={{
|
||||
detectionRulesLink: (
|
||||
<LinkToApp appId={APP_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<LinkToApp appId={APP_UI_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policy.details.detectionRulesLink"
|
||||
defaultMessage="related detection rules"
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../../../../app/types';
|
||||
import { Immutable, OperatingSystem } from '../../../../../../../common/endpoint/types';
|
||||
import { MemoryProtectionOSes, OS } from '../../../types';
|
||||
|
@ -51,7 +51,7 @@ export const MemoryProtection = React.memo(() => {
|
|||
defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page."
|
||||
values={{
|
||||
detectionRulesLink: (
|
||||
<LinkToApp appId={APP_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<LinkToApp appId={APP_UI_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policy.details.detectionRulesLink"
|
||||
defaultMessage="related detection rules"
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../../../../app/types';
|
||||
import { Immutable, OperatingSystem } from '../../../../../../../common/endpoint/types';
|
||||
import { RansomwareProtectionOSes, OS } from '../../../types';
|
||||
|
@ -52,7 +52,7 @@ export const Ransomware = React.memo(() => {
|
|||
defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page."
|
||||
values={{
|
||||
detectionRulesLink: (
|
||||
<LinkToApp appId={APP_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<LinkToApp appId={APP_UI_ID} deepLinkId={SecurityPageName.rules}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policy.details.detectionRulesLink"
|
||||
defaultMessage="related detection rules"
|
||||
|
|
|
@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { useNavigateToAppEventHandler } from '../../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
import { useAppUrl } from '../../../../../../common/lib/kibana/hooks';
|
||||
import { getPolicyTrustedAppsPath, getTrustedAppsListPath } from '../../../../../common/routing';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
|
||||
export const useGetLinkTo = (policyId: string, policyName: string) => {
|
||||
const { getAppUrl } = useAppUrl();
|
||||
|
@ -35,19 +35,19 @@ export const useGetLinkTo = (policyId: string, policyName: string) => {
|
|||
}
|
||||
),
|
||||
onBackButtonNavigateTo: [
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
{
|
||||
path: policyTrustedAppsPath,
|
||||
},
|
||||
],
|
||||
backButtonUrl: getAppUrl({
|
||||
appId: APP_ID,
|
||||
appId: APP_UI_ID,
|
||||
path: policyTrustedAppsPath,
|
||||
}),
|
||||
};
|
||||
}, [getAppUrl, policyName, policyTrustedAppsPath]);
|
||||
|
||||
const onClickHandler = useNavigateToAppEventHandler(APP_ID, {
|
||||
const onClickHandler = useNavigateToAppEventHandler(APP_UI_ID, {
|
||||
state: policyTrustedAppRouteState,
|
||||
path: toRoutePath,
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
isLoadedResourceState,
|
||||
} from '../../../../../state';
|
||||
import { fireEvent, within, act, waitFor } from '@testing-library/react';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import {
|
||||
EndpointPrivileges,
|
||||
useEndpointPrivileges,
|
||||
|
@ -203,7 +203,7 @@ describe('when rendering the PolicyTrustedAppsList', () => {
|
|||
});
|
||||
|
||||
expect(appTestContext.coreStart.application.navigateToApp).toHaveBeenCalledWith(
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
expect.objectContaining({
|
||||
path: '/administration/trusted_apps?filter=89f72d8a-05b5-4350-8cad-0dc3661d6e67',
|
||||
})
|
||||
|
|
|
@ -33,7 +33,7 @@ import {
|
|||
} from '../../../../../common/routing';
|
||||
import { Immutable, TrustedApp } from '../../../../../../../common/endpoint/types';
|
||||
import { useAppUrl, useToasts } from '../../../../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { ContextMenuItemNavByRouterProps } from '../../../../../components/context_menu_with_router_support/context_menu_item_nav_by_router';
|
||||
import { ArtifactEntryCollapsibleCardProps } from '../../../../../components/artifact_entry_card';
|
||||
import { useTestIdGenerator } from '../../../../../components/hooks/use_test_id_generator';
|
||||
|
@ -130,7 +130,7 @@ export const PolicyTrustedAppsList = memo<PolicyTrustedAppsListProps>(
|
|||
const policyDetailsPath = getPolicyDetailPath(trustedAppAssignedPolicyId);
|
||||
|
||||
const thisPolicyMenuProps: ContextMenuItemNavByRouterProps = {
|
||||
navigateAppId: APP_ID,
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: {
|
||||
path: policyDetailsPath,
|
||||
},
|
||||
|
@ -150,8 +150,8 @@ export const PolicyTrustedAppsList = memo<PolicyTrustedAppsListProps>(
|
|||
'xpack.securitySolution.endpoint.policy.trustedApps.list.viewAction',
|
||||
{ defaultMessage: 'View full details' }
|
||||
),
|
||||
href: getAppUrl({ appId: APP_ID, path: viewUrlPath }),
|
||||
navigateAppId: APP_ID,
|
||||
href: getAppUrl({ appId: APP_UI_ID, path: viewUrlPath }),
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: { path: viewUrlPath },
|
||||
'data-test-subj': getTestId('viewFullDetailsAction'),
|
||||
},
|
||||
|
|
|
@ -37,7 +37,7 @@ import {
|
|||
ArtifactEntryCardProps,
|
||||
} from '../../../../../components/artifact_entry_card';
|
||||
import { AppAction } from '../../../../../../common/store/actions';
|
||||
import { APP_ID } from '../../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../../common/constants';
|
||||
import { useAppUrl } from '../../../../../../common/lib/kibana';
|
||||
|
||||
export interface PaginationBarProps {
|
||||
|
@ -115,7 +115,7 @@ export const TrustedAppsGrid = memo(() => {
|
|||
backLink: {
|
||||
label: BACK_TO_TRUSTED_APPS_LABEL,
|
||||
navigateTo: [
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
{
|
||||
path: currentPagePath,
|
||||
},
|
||||
|
@ -123,7 +123,7 @@ export const TrustedAppsGrid = memo(() => {
|
|||
href: getAppUrl({ path: currentPagePath }),
|
||||
},
|
||||
onCancelNavigateTo: [
|
||||
APP_ID,
|
||||
APP_UI_ID,
|
||||
{
|
||||
path: currentPagePath,
|
||||
},
|
||||
|
@ -131,6 +131,7 @@ export const TrustedAppsGrid = memo(() => {
|
|||
};
|
||||
|
||||
policyToNavOptionsMap[policyId] = {
|
||||
navigateAppId: APP_UI_ID,
|
||||
navigateOptions: {
|
||||
path: policyDetailsPath,
|
||||
state: routeState,
|
||||
|
|
|
@ -15,7 +15,7 @@ import * as i18n from '../translations';
|
|||
import { NetworkRouteType } from '../navigation/types';
|
||||
import { NetworkRouteSpyState } from '../../../common/utils/route/types';
|
||||
import { GetUrlForApp } from '../../../common/components/navigation/types';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
|
||||
export const type = networkModel.NetworkType.details;
|
||||
|
@ -36,7 +36,7 @@ export const getBreadcrumbs = (
|
|||
let breadcrumb = [
|
||||
{
|
||||
text: i18n.PAGE_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.network,
|
||||
path: !isEmpty(search[0]) ? search[0] : '',
|
||||
}),
|
||||
|
@ -47,7 +47,7 @@ export const getBreadcrumbs = (
|
|||
...breadcrumb,
|
||||
{
|
||||
text: decodeIpv6(params.detailName),
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.network,
|
||||
path: getNetworkDetailsUrl(
|
||||
params.detailName,
|
||||
|
|
|
@ -9,7 +9,7 @@ import numeral from '@elastic/numeral';
|
|||
import React, { useEffect, useMemo, useCallback } from 'react';
|
||||
import { Position } from '@elastic/charts';
|
||||
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants';
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants';
|
||||
import { SHOWING, UNIT } from '../../../common/components/alerts_viewer/translations';
|
||||
import { MatrixHistogram } from '../../../common/components/matrix_histogram';
|
||||
import { useKibana, useUiSetting$ } from '../../../common/lib/kibana';
|
||||
|
@ -68,7 +68,7 @@ const AlertsByCategoryComponent: React.FC<Props> = ({
|
|||
const goToHostAlerts = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
path: getTabsOnHostsUrl(HostsTableType.alerts, urlSearch),
|
||||
});
|
||||
|
|
|
@ -9,15 +9,15 @@ import React, { memo } from 'react';
|
|||
import { EuiCallOut, EuiButton, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
import { getEndpointListPath } from '../../../management/common/routing';
|
||||
import { useNavigateToAppEventHandler } from '../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
|
||||
export const EndpointNotice = memo<{ onDismiss: () => void }>(({ onDismiss }) => {
|
||||
const { getUrlForApp } = useKibana().services.application;
|
||||
const endpointsPath = getEndpointListPath({ name: 'endpointList' });
|
||||
const endpointsLink = getUrlForApp(APP_ID, { path: endpointsPath });
|
||||
const handleGetStartedClick = useNavigateToAppEventHandler(APP_ID, {
|
||||
const endpointsLink = getUrlForApp(APP_UI_ID, { path: endpointsPath });
|
||||
const handleGetStartedClick = useNavigateToAppEventHandler(APP_UI_ID, {
|
||||
path: endpointsPath,
|
||||
});
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import numeral from '@elastic/numeral';
|
|||
import React, { useEffect, useMemo, useCallback } from 'react';
|
||||
import uuid from 'uuid';
|
||||
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants';
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants';
|
||||
import { SHOWING, UNIT } from '../../../common/components/events_viewer/translations';
|
||||
import { getTabsOnHostsUrl } from '../../../common/components/link_to/redirect_to_hosts';
|
||||
import { MatrixHistogram } from '../../../common/components/matrix_histogram';
|
||||
|
@ -101,7 +101,7 @@ const EventsByDatasetComponent: React.FC<Props> = ({
|
|||
const goToHostEvents = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
path: getTabsOnHostsUrl(HostsTableType.events, urlSearch),
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ import numeral from '@elastic/numeral';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants';
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants';
|
||||
import { ESQuery } from '../../../../common/typed_json';
|
||||
import { ID as OverviewHostQueryId, useHostOverview } from '../../containers/overview_host';
|
||||
import { HeaderSection } from '../../../common/components/header_section';
|
||||
|
@ -57,7 +57,7 @@ const OverviewHostComponent: React.FC<OverviewHostProps> = ({
|
|||
const goToHost = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
path: getHostDetailsUrl('allHosts', urlSearch),
|
||||
});
|
||||
|
|
|
@ -138,7 +138,7 @@ describe('OverviewNetwork', () => {
|
|||
preventDefault: jest.fn(),
|
||||
});
|
||||
|
||||
expect(mockNavigateToApp).toBeCalledWith('securitySolution', {
|
||||
expect(mockNavigateToApp).toBeCalledWith('securitySolutionUI', {
|
||||
path: '',
|
||||
deepLinkId: SecurityPageName.network,
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ import numeral from '@elastic/numeral';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants';
|
||||
import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants';
|
||||
import { ESQuery } from '../../../../common/typed_json';
|
||||
import { HeaderSection } from '../../../common/components/header_section';
|
||||
import { useUiSetting$, useKibana } from '../../../common/lib/kibana';
|
||||
|
@ -59,7 +59,7 @@ const OverviewNetworkComponent: React.FC<OverviewNetworkProps> = ({
|
|||
const goToNetwork = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.network,
|
||||
path: getNetworkUrl(urlSearch),
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { EuiButtonEmpty, EuiText } from '@elastic/eui';
|
||||
import { APP_ID, SecurityPageName } from '../../../../common/constants';
|
||||
import { APP_UI_ID, SecurityPageName } from '../../../../common/constants';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
|
||||
export const NavigateToHost: React.FC<{ name: string }> = ({ name }): JSX.Element => {
|
||||
|
@ -27,7 +27,7 @@ export const NavigateToHost: React.FC<{ name: string }> = ({ name }): JSX.Elemen
|
|||
query: { match_phrase: { 'host.name': name } },
|
||||
},
|
||||
]);
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.hosts,
|
||||
});
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from '../../../common/components/link_to/redirect_to_case';
|
||||
import { useFormatUrl } from '../../../common/components/link_to';
|
||||
import { useGetUserCasesPermissions, useKibana } from '../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_ID, APP_UI_ID } from '../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
import { AllCasesNavProps } from '../../../cases/components/all_cases';
|
||||
|
||||
|
@ -33,7 +33,7 @@ const RecentCasesComponent = () => {
|
|||
href: formatUrl(getCaseUrl()),
|
||||
onClick: async (e) => {
|
||||
e?.preventDefault();
|
||||
return navigateToApp(APP_ID, { deepLinkId: SecurityPageName.case });
|
||||
return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case });
|
||||
},
|
||||
},
|
||||
caseDetailsNavigation: {
|
||||
|
@ -42,7 +42,7 @@ const RecentCasesComponent = () => {
|
|||
},
|
||||
onClick: async ({ detailName, subCaseId, search }, e) => {
|
||||
e?.preventDefault();
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCaseDetailsUrl({ id: detailName, search, subCaseId }),
|
||||
});
|
||||
|
@ -52,7 +52,7 @@ const RecentCasesComponent = () => {
|
|||
href: formatUrl(getCreateCaseUrl()),
|
||||
onClick: async (e) => {
|
||||
e?.preventDefault();
|
||||
return navigateToApp(APP_ID, {
|
||||
return navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCreateCaseUrl(),
|
||||
});
|
||||
|
|
|
@ -25,7 +25,7 @@ import { LoadingPlaceholders } from '../loading_placeholders';
|
|||
import { useTimelineStatus } from '../../../timelines/components/open_timeline/use_timeline_status';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
import { useFormatUrl } from '../../../common/components/link_to';
|
||||
import { LinkAnchor } from '../../../common/components/links';
|
||||
import { Direction } from '../../../../common/search_strategy';
|
||||
|
@ -61,7 +61,7 @@ const StatefulRecentTimelinesComponent: React.FC<Props> = ({ filterBy }) => {
|
|||
const goToTimelines = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.timelines,
|
||||
});
|
||||
},
|
||||
|
|
|
@ -37,16 +37,16 @@ import { SOLUTION_NAME } from './common/translations';
|
|||
|
||||
import {
|
||||
APP_ID,
|
||||
OVERVIEW_PATH,
|
||||
APP_OVERVIEW_PATH,
|
||||
APP_UI_ID,
|
||||
APP_PATH,
|
||||
DEFAULT_INDEX_KEY,
|
||||
APP_ICON_SOLUTION,
|
||||
DETECTION_ENGINE_INDEX_URL,
|
||||
SERVER_APP_ID,
|
||||
} from '../common/constants';
|
||||
|
||||
import { getDeepLinks, updateGlobalNavigation } from './app/deep_links';
|
||||
import { manageOldSiemRoutes } from './helpers';
|
||||
import { getDeepLinks } from './app/deep_links';
|
||||
import { getSubPluginRoutesByCapabilities, manageOldSiemRoutes } from './helpers';
|
||||
import {
|
||||
IndexFieldsStrategyRequest,
|
||||
IndexFieldsStrategyResponse,
|
||||
|
@ -98,7 +98,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
{
|
||||
usageCollection: plugins.usageCollection,
|
||||
},
|
||||
APP_ID
|
||||
APP_UI_ID
|
||||
);
|
||||
|
||||
if (plugins.home) {
|
||||
|
@ -110,7 +110,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
'Prevent, collect, detect, and respond to threats for unified protection across your infrastructure.',
|
||||
}),
|
||||
icon: 'logoSecurity',
|
||||
path: APP_OVERVIEW_PATH,
|
||||
path: APP_PATH,
|
||||
order: 300,
|
||||
});
|
||||
}
|
||||
|
@ -133,13 +133,12 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
})();
|
||||
|
||||
core.application.register({
|
||||
id: APP_ID,
|
||||
id: APP_UI_ID,
|
||||
title: SOLUTION_NAME,
|
||||
appRoute: APP_PATH,
|
||||
category: DEFAULT_APP_CATEGORIES.security,
|
||||
navLinkStatus: AppNavLinkStatus.hidden,
|
||||
searchable: true,
|
||||
defaultPath: OVERVIEW_PATH,
|
||||
updater$: this.appUpdater$,
|
||||
euiIconType: APP_ICON_SOLUTION,
|
||||
deepLinks: getDeepLinks(this.experimentalFeatures),
|
||||
|
@ -152,7 +151,10 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
services: await startServices,
|
||||
store: await this.store(coreStart, startPlugins, subPlugins),
|
||||
usageCollection: plugins.usageCollection,
|
||||
subPlugins,
|
||||
subPluginRoutes: getSubPluginRoutesByCapabilities(
|
||||
subPlugins,
|
||||
coreStart.application.capabilities
|
||||
),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -232,11 +234,14 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
}
|
||||
});
|
||||
} else {
|
||||
updateGlobalNavigation({
|
||||
capabilities: core.application.capabilities,
|
||||
updater$: this.appUpdater$,
|
||||
enableExperimental: this.experimentalFeatures,
|
||||
});
|
||||
this.appUpdater$.next(() => ({
|
||||
navLinkStatus: AppNavLinkStatus.hidden, // workaround to prevent main navLink to switch to visible after update. should not be needed
|
||||
deepLinks: getDeepLinks(
|
||||
this.experimentalFeatures,
|
||||
undefined,
|
||||
core.application.capabilities
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -313,9 +318,9 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
return {
|
||||
overview: subPlugins.overview.start(),
|
||||
alerts: subPlugins.alerts.start(storage),
|
||||
cases: subPlugins.cases.start(),
|
||||
rules: subPlugins.rules.start(storage),
|
||||
exceptions: subPlugins.exceptions.start(storage),
|
||||
cases: subPlugins.cases.start(),
|
||||
hosts: subPlugins.hosts.start(storage),
|
||||
network: subPlugins.network.start(storage),
|
||||
ueba: subPlugins.ueba.start(storage),
|
||||
|
@ -358,9 +363,11 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
// }
|
||||
// );
|
||||
// signal = { name: indexName[0] };
|
||||
signal = await coreStart.http.fetch(DETECTION_ENGINE_INDEX_URL, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (coreStart.application.capabilities[SERVER_APP_ID].read === true) {
|
||||
signal = await coreStart.http.fetch(DETECTION_ENGINE_INDEX_URL, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
signal = { name: null };
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ describe('AddToCaseButton', () => {
|
|||
wrapper.find(`[data-test-subj="attach-timeline-case-button"]`).first().simulate('click');
|
||||
wrapper.find(`[data-test-subj="attach-timeline-existing-case"]`).first().simulate('click');
|
||||
|
||||
expect(navigateToApp).toHaveBeenCalledWith('securitySolution', {
|
||||
expect(navigateToApp).toHaveBeenCalledWith('securitySolutionUI', {
|
||||
path: '/create',
|
||||
deepLinkId: SecurityPageName.case,
|
||||
});
|
||||
|
@ -84,7 +84,7 @@ describe('AddToCaseButton', () => {
|
|||
wrapper.find(`[data-test-subj="attach-timeline-case-button"]`).first().simulate('click');
|
||||
wrapper.find(`[data-test-subj="attach-timeline-existing-case"]`).first().simulate('click');
|
||||
|
||||
expect(navigateToApp).toHaveBeenCalledWith('securitySolution', {
|
||||
expect(navigateToApp).toHaveBeenCalledWith('securitySolutionUI', {
|
||||
path: '/case-id',
|
||||
deepLinkId: SecurityPageName.case,
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ import React, { useCallback, useMemo, useState } from 'react';
|
|||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { Case, SubCase } from '../../../../../../cases/common';
|
||||
import { APP_ID } from '../../../../../common/constants';
|
||||
import { APP_ID, APP_UI_ID } from '../../../../../common/constants';
|
||||
import { timelineSelectors } from '../../../../timelines/store/timeline';
|
||||
import { setInsertTimeline, showTimeline } from '../../../store/timeline/actions';
|
||||
import { useDeepEqualSelector } from '../../../../common/hooks/use_selector';
|
||||
|
@ -55,7 +55,7 @@ const AddToCaseButtonComponent: React.FC<Props> = ({ timelineId }) => {
|
|||
const onRowClick = useCallback(
|
||||
async (theCase?: Case | SubCase) => {
|
||||
openCaseModal(false);
|
||||
await navigateToApp(APP_ID, {
|
||||
await navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: theCase != null ? getCaseDetailsUrl({ id: theCase.id }) : getCreateCaseUrl(),
|
||||
});
|
||||
|
@ -90,7 +90,7 @@ const AddToCaseButtonComponent: React.FC<Props> = ({ timelineId }) => {
|
|||
const handleNewCaseClick = useCallback(() => {
|
||||
handlePopoverClose();
|
||||
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.case,
|
||||
path: getCreateCaseUrl(),
|
||||
}).then(() => {
|
||||
|
|
|
@ -33,21 +33,6 @@ exports[`Expandable Host Component ExpandableHostDetails: rendering it should re
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
.c4 {
|
||||
padding: 16px;
|
||||
background: rgba(250,251,253,0.9);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.c2 dt {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
@ -75,6 +60,21 @@ exports[`Expandable Host Component ExpandableHostDetails: rendering it should re
|
|||
z-index: 2;
|
||||
}
|
||||
|
||||
.c4 {
|
||||
padding: 16px;
|
||||
background: rgba(250,251,253,0.9);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
<ExpandableHostDetails
|
||||
contextID="text-context"
|
||||
hostName="testHostName"
|
||||
|
|
|
@ -30,7 +30,7 @@ import * as i18n from './translations';
|
|||
import { SecurityPageName } from '../../../../../app/types';
|
||||
import { useFormatUrl } from '../../../../../common/components/link_to';
|
||||
import { useKibana } from '../../../../../common/lib/kibana';
|
||||
import { APP_ID } from '../../../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../../../common/constants';
|
||||
import { LinkAnchor } from '../../../../../common/components/links';
|
||||
|
||||
const EventModuleFlexItem = styled(EuiFlexItem)`
|
||||
|
@ -73,7 +73,7 @@ export const RenderRuleName: React.FC<RenderRuleNameProps> = ({
|
|||
const goToRuleDetails = useCallback(
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
navigateToApp(APP_ID, {
|
||||
navigateToApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId ?? '', search),
|
||||
});
|
||||
|
@ -83,7 +83,7 @@ export const RenderRuleName: React.FC<RenderRuleNameProps> = ({
|
|||
|
||||
const href = useMemo(
|
||||
() =>
|
||||
getUrlForApp(APP_ID, {
|
||||
getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.rules,
|
||||
path: getRuleDetailsUrl(ruleId ?? '', search),
|
||||
}),
|
||||
|
|
|
@ -18,7 +18,7 @@ import { TimelinesPage } from './timelines_page';
|
|||
import { PAGE_TITLE } from './translations';
|
||||
import { appendSearch } from '../../common/components/link_to/helpers';
|
||||
import { GetUrlForApp } from '../../common/components/navigation/types';
|
||||
import { APP_ID, TIMELINES_PATH } from '../../../common/constants';
|
||||
import { APP_UI_ID, TIMELINES_PATH } from '../../../common/constants';
|
||||
import { SecurityPageName } from '../../app/types';
|
||||
|
||||
const timelinesPagePath = `${TIMELINES_PATH}/:tabName(${TimelineType.default}|${TimelineType.template})`;
|
||||
|
@ -31,7 +31,7 @@ export const getBreadcrumbs = (
|
|||
): ChromeBreadcrumb[] => [
|
||||
{
|
||||
text: PAGE_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
deepLinkId: SecurityPageName.timelines,
|
||||
path: !isEmpty(search[0]) ? search[0] : '',
|
||||
}),
|
||||
|
|
|
@ -87,11 +87,12 @@ export interface AppObservableLibs {
|
|||
|
||||
export type InspectResponse = Inspect & { response: string[] };
|
||||
|
||||
export const CASES_SUB_PLUGIN_KEY = 'cases';
|
||||
export interface SubPlugins {
|
||||
alerts: Detections;
|
||||
rules: Rules;
|
||||
exceptions: Exceptions;
|
||||
cases: Cases;
|
||||
[CASES_SUB_PLUGIN_KEY]: Cases;
|
||||
hosts: Hosts;
|
||||
network: Network;
|
||||
ueba: Ueba;
|
||||
|
@ -105,7 +106,7 @@ export interface StartedSubPlugins {
|
|||
alerts: ReturnType<Detections['start']>;
|
||||
rules: ReturnType<Rules['start']>;
|
||||
exceptions: ReturnType<Exceptions['start']>;
|
||||
cases: ReturnType<Cases['start']>;
|
||||
[CASES_SUB_PLUGIN_KEY]: ReturnType<Cases['start']>;
|
||||
hosts: ReturnType<Hosts['start']>;
|
||||
network: ReturnType<Network['start']>;
|
||||
ueba: ReturnType<Ueba['start']>;
|
||||
|
|
|
@ -15,7 +15,7 @@ import { getUebaDetailsUrl } from '../../../common/components/link_to/redirect_t
|
|||
import * as i18n from '../translations';
|
||||
import { UebaRouteSpyState } from '../../../common/utils/route/types';
|
||||
import { GetUrlForApp } from '../../../common/components/navigation/types';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import { APP_UI_ID } from '../../../../common/constants';
|
||||
import { SecurityPageName } from '../../../app/types';
|
||||
|
||||
export const type = uebaModel.UebaType.details;
|
||||
|
@ -35,7 +35,7 @@ export const getBreadcrumbs = (
|
|||
let breadcrumb = [
|
||||
{
|
||||
text: i18n.PAGE_TITLE,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
path: !isEmpty(search[0]) ? search[0] : '',
|
||||
deepLinkId: SecurityPageName.ueba,
|
||||
}),
|
||||
|
@ -47,7 +47,7 @@ export const getBreadcrumbs = (
|
|||
...breadcrumb,
|
||||
{
|
||||
text: params.detailName,
|
||||
href: getUrlForApp(APP_ID, {
|
||||
href: getUrlForApp(APP_UI_ID, {
|
||||
path: getUebaDetailsUrl(params.detailName, !isEmpty(search[0]) ? search[0] : ''),
|
||||
deepLinkId: SecurityPageName.ueba,
|
||||
}),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue