diff --git a/x-pack/legacy/plugins/siem/common/constants.ts b/x-pack/legacy/plugins/siem/common/constants.ts index 4383329fea072..5116416b527a5 100644 --- a/x-pack/legacy/plugins/siem/common/constants.ts +++ b/x-pack/legacy/plugins/siem/common/constants.ts @@ -27,8 +27,6 @@ export const DEFAULT_SEARCH_AFTER_PAGE_SIZE = 100; export const DEFAULT_ANOMALY_SCORE = 'siem:defaultAnomalyScore'; export const DEFAULT_MAX_TABLE_QUERY_SIZE = 10000; export const DEFAULT_SCALE_DATE_FORMAT = 'dateFormat:scaled'; -export const DEFAULT_KBN_VERSION = 'kbnVersion'; -export const DEFAULT_TIMEZONE_BROWSER = 'timezoneBrowser'; export const DEFAULT_FROM = 'now-24h'; export const DEFAULT_TO = 'now'; export const DEFAULT_INTERVAL_PAUSE = true; diff --git a/x-pack/legacy/plugins/siem/index.ts b/x-pack/legacy/plugins/siem/index.ts index cf9fffc6a1455..c5038626fdfc2 100644 --- a/x-pack/legacy/plugins/siem/index.ts +++ b/x-pack/legacy/plugins/siem/index.ts @@ -9,7 +9,7 @@ import { resolve } from 'path'; import { Server } from 'hapi'; import { Root } from 'joi'; -import { PluginInitializerContext } from 'src/core/server'; +import { PluginInitializerContext } from '../../../../src/core/server'; import { plugin } from './server'; import { savedObjectMappings } from './server/saved_objects'; @@ -43,7 +43,7 @@ export const siem = (kibana: any) => { description: i18n.translate('xpack.siem.securityDescription', { defaultMessage: 'Explore your SIEM App', }), - main: 'plugins/siem/app', + main: 'plugins/siem/legacy', euiIconType: 'securityAnalyticsApp', title: APP_NAME, listed: false, diff --git a/x-pack/legacy/plugins/siem/public/apps/start_app.tsx b/x-pack/legacy/plugins/siem/public/app/app.tsx similarity index 96% rename from x-pack/legacy/plugins/siem/public/apps/start_app.tsx rename to x-pack/legacy/plugins/siem/public/app/app.tsx index 100f10aaf2e7b..5f9199735d8c0 100644 --- a/x-pack/legacy/plugins/siem/public/apps/start_app.tsx +++ b/x-pack/legacy/plugins/siem/public/app/app.tsx @@ -25,7 +25,7 @@ import { DEFAULT_DARK_MODE } from '../../common/constants'; import { ErrorToastDispatcher } from '../components/error_toast_dispatcher'; import { compose } from '../lib/compose/kibana_compose'; import { AppFrontendLibs, AppApolloClient } from '../lib/lib'; -import { StartCore, StartPlugins } from './plugin'; +import { CoreStart, StartPlugins } from '../plugin'; import { PageRouter } from '../routes'; import { createStore } from '../store'; import { GlobalToaster, ManageGlobalToaster } from '../components/toasters'; @@ -89,10 +89,8 @@ const StartAppComponent: FC = libs => { const StartApp = memo(StartAppComponent); -export const ROOT_ELEMENT_ID = 'react-siem-root'; - interface SiemAppComponentProps { - core: StartCore; + core: CoreStart; plugins: StartPlugins; } diff --git a/x-pack/legacy/plugins/siem/public/app/index.tsx b/x-pack/legacy/plugins/siem/public/app/index.tsx new file mode 100644 index 0000000000000..01175a98d1e44 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/app/index.tsx @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { CoreStart, StartPlugins, AppMountParameters } from '../plugin'; +import { SiemApp } from './app'; + +export const renderApp = ( + core: CoreStart, + plugins: StartPlugins, + { element }: AppMountParameters +) => { + render(, element); + return () => unmountComponentAtNode(element); +}; diff --git a/x-pack/legacy/plugins/siem/public/apps/index.ts b/x-pack/legacy/plugins/siem/public/apps/index.ts deleted file mode 100644 index 0cc5c5584e1b7..0000000000000 --- a/x-pack/legacy/plugins/siem/public/apps/index.ts +++ /dev/null @@ -1,18 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import chrome from 'ui/chrome'; -import { npStart } from 'ui/new_platform'; -import { Plugin } from './plugin'; - -const { data, embeddable, inspector, uiActions } = npStart.plugins; -const startPlugins = { data, embeddable, inspector, uiActions }; - -new Plugin( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - { opaqueId: Symbol('siem'), env: {} as any, config: { get: () => ({} as any) } }, - chrome -).start(npStart.core, startPlugins); diff --git a/x-pack/legacy/plugins/siem/public/apps/plugin.tsx b/x-pack/legacy/plugins/siem/public/apps/plugin.tsx deleted file mode 100644 index aa42504e07635..0000000000000 --- a/x-pack/legacy/plugins/siem/public/apps/plugin.tsx +++ /dev/null @@ -1,59 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { render } from 'react-dom'; -import { LegacyCoreStart, PluginInitializerContext } from 'src/core/public'; -import { PluginsStart } from 'ui/new_platform/new_platform'; -import { Chrome } from 'ui/chrome'; - -import { DEFAULT_KBN_VERSION, DEFAULT_TIMEZONE_BROWSER } from '../../common/constants'; -import { SiemApp } from './start_app'; -import template from './template.html'; - -export const ROOT_ELEMENT_ID = 'react-siem-root'; - -export type StartCore = LegacyCoreStart; -export type StartPlugins = Required< - Pick ->; -export type StartServices = StartCore & StartPlugins; - -export class Plugin { - constructor( - // @ts-ignore this is added to satisfy the New Platform typing constraint, - // but we're not leveraging any of its functionality yet. - private readonly initializerContext: PluginInitializerContext, - private readonly chrome: Chrome - ) { - this.chrome = chrome; - } - - public start(core: StartCore, plugins: StartPlugins) { - // TODO(rylnd): These are unknown by uiSettings by default - core.uiSettings.set(DEFAULT_KBN_VERSION, '8.0.0'); - core.uiSettings.set(DEFAULT_TIMEZONE_BROWSER, 'UTC'); - - // @ts-ignore improper type description - this.chrome.setRootTemplate(template); - const checkForRoot = () => { - return new Promise(resolve => { - const ready = !!document.getElementById(ROOT_ELEMENT_ID); - if (ready) { - resolve(); - } else { - setTimeout(() => resolve(checkForRoot()), 10); - } - }); - }; - checkForRoot().then(() => { - const node = document.getElementById(ROOT_ELEMENT_ID); - if (node) { - render(, node); - } - }); - } -} diff --git a/x-pack/legacy/plugins/siem/public/apps/template.html b/x-pack/legacy/plugins/siem/public/apps/template.html deleted file mode 100644 index 9f757b25ccecb..0000000000000 --- a/x-pack/legacy/plugins/siem/public/apps/template.html +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx index ba07a3f3436d9..71f22efadc6ed 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx @@ -18,6 +18,7 @@ import { import { getOr, get, isNull, isNumber } from 'lodash/fp'; import { AutoSizer } from '../auto_sizer'; import { ChartPlaceHolder } from './chart_place_holder'; +import { useTimeZone } from '../../hooks'; import { chartDefaultSettings, ChartSeriesConfigs, @@ -26,7 +27,6 @@ import { getChartWidth, WrappedByAutoSizer, useTheme, - useBrowserTimeZone, } from './common'; // custom series styles: https://ela.st/areachart-styling @@ -71,7 +71,7 @@ export const AreaChartBaseComponent = ({ configs?: ChartSeriesConfigs | undefined; }) => { const theme = useTheme(); - const timeZone = useBrowserTimeZone(); + const timeZone = useTimeZone(); const xTickFormatter = get('configs.axis.xTickFormatter', chartConfigs); const yTickFormatter = get('configs.axis.yTickFormatter', chartConfigs); const xAxisId = `group-${data[0].key}-x`; diff --git a/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx index db84d7dbd2c18..415cbeb7c2440 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { Chart, BarSeries, Axis, Position, ScaleType, Settings } from '@elastic/charts'; import { getOr, get, isNumber } from 'lodash/fp'; +import { useTimeZone } from '../../hooks'; import { AutoSizer } from '../auto_sizer'; import { ChartPlaceHolder } from './chart_place_holder'; import { @@ -17,7 +18,6 @@ import { getChartHeight, getChartWidth, WrappedByAutoSizer, - useBrowserTimeZone, useTheme, } from './common'; @@ -44,7 +44,7 @@ export const BarChartBaseComponent = ({ configs?: ChartSeriesConfigs | undefined; }) => { const theme = useTheme(); - const timeZone = useBrowserTimeZone(); + const timeZone = useTimeZone(); const xTickFormatter = get('configs.axis.xTickFormatter', chartConfigs); const yTickFormatter = get('configs.axis.yTickFormatter', chartConfigs); const tickSize = getOr(0, 'configs.axis.tickSize', chartConfigs); diff --git a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx index a4be390019916..78cce72f0a0d3 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx @@ -15,10 +15,9 @@ import { SettingsSpecProps, TickFormatter, } from '@elastic/charts'; -import moment from 'moment-timezone'; import styled from 'styled-components'; import { useUiSetting } from '../../lib/kibana'; -import { DEFAULT_DATE_FORMAT_TZ, DEFAULT_DARK_MODE } from '../../../common/constants'; +import { DEFAULT_DARK_MODE } from '../../../common/constants'; export const defaultChartHeight = '100%'; export const defaultChartWidth = '100%'; @@ -108,11 +107,6 @@ export const chartDefaultSettings = { debug: false, }; -export const useBrowserTimeZone = () => { - const kibanaTimezone = useUiSetting(DEFAULT_DATE_FORMAT_TZ); - return kibanaTimezone === 'Browser' ? moment.tz.guess() : kibanaTimezone; -}; - export const getChartHeight = (customHeight?: number, autoSizerHeight?: number): string => { const height = customHeight || autoSizerHeight; return height ? `${height}px` : defaultChartHeight; diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx index 1a8955d111624..5b18e2d9b1fbc 100644 --- a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx @@ -14,8 +14,6 @@ import { mockBrowserFields } from '../../containers/source/mock'; import { defaultHeaders } from '../../mock/header'; import { useMountAppended } from '../../utils/use_mount_appended'; -jest.mock('../../lib/kibana'); - describe('EventFieldsBrowser', () => { const mount = useMountAppended(); diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx index b44d83c27a60d..3cef3e98c2f0a 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx @@ -18,8 +18,6 @@ import { mockBrowserFields } from '../../containers/source/mock'; import { eventsDefaultModel } from './default_model'; import { useMountAppended } from '../../utils/use_mount_appended'; -jest.mock('../../lib/kibana'); - const mockUseFetchIndexPatterns: jest.Mock = useFetchIndexPatterns as jest.Mock; jest.mock('../../containers/detection_engine/rules/fetch_index_patterns'); mockUseFetchIndexPatterns.mockImplementation(() => [ diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx index 27c3abf7f6824..1e225dabb2541 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx @@ -17,8 +17,6 @@ import { useFetchIndexPatterns } from '../../containers/detection_engine/rules/f import { mockBrowserFields } from '../../containers/source/mock'; import { eventsDefaultModel } from './default_model'; -jest.mock('../../lib/kibana'); - const mockUseFetchIndexPatterns: jest.Mock = useFetchIndexPatterns as jest.Mock; jest.mock('../../containers/detection_engine/rules/fetch_index_patterns'); mockUseFetchIndexPatterns.mockImplementation(() => [ diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx index 0196f500fee74..d94c5f4d0a4f2 100644 --- a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx @@ -16,8 +16,6 @@ const testFlyoutHeight = 980; const testWidth = 640; const usersViewing = ['elastic']; -jest.mock('../../../lib/kibana'); - describe('Pane', () => { test('renders correctly against snapshot', () => { const EmptyComponent = shallow( diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_bytes/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/formatted_bytes/__snapshots__/index.test.tsx.snap index d23b1c61f7aee..ae30325f2a93b 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_bytes/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/formatted_bytes/__snapshots__/index.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`formatted_bytes PreferenceFormattedBytes rendering renders correctly against snapshot 1`] = ` +exports[`PreferenceFormattedBytes renders correctly against snapshot 1`] = ` 2.7MB diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.test.tsx index 665d90f6a05ec..4412159114444 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.test.tsx @@ -8,7 +8,6 @@ import { mount, shallow } from 'enzyme'; import toJson from 'enzyme-to-json'; import React from 'react'; -import { mockFrameworks, getMockKibanaUiSetting } from '../../mock'; import { useUiSetting$ } from '../../lib/kibana'; import { PreferenceFormattedBytesComponent } from '.'; @@ -16,50 +15,42 @@ import { PreferenceFormattedBytesComponent } from '.'; jest.mock('../../lib/kibana'); const mockUseUiSetting$ = useUiSetting$ as jest.Mock; -describe('formatted_bytes', () => { - describe('PreferenceFormattedBytes', () => { - describe('rendering', () => { - beforeEach(() => { - mockUseUiSetting$.mockClear(); - }); +const DEFAULT_BYTES_FORMAT_VALUE = '0,0.[0]b'; // kibana's default for this setting +const bytes = '2806422'; - const bytes = '2806422'; +describe('PreferenceFormattedBytes', () => { + test('renders correctly against snapshot', () => { + mockUseUiSetting$.mockImplementation(() => [DEFAULT_BYTES_FORMAT_VALUE]); + const wrapper = shallow(); - test('renders correctly against snapshot', () => { - mockUseUiSetting$.mockImplementation( - getMockKibanaUiSetting(mockFrameworks.default_browser) - ); - const wrapper = shallow(); - expect(toJson(wrapper)).toMatchSnapshot(); - }); + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders bytes to Numeral formatting when no format setting exists', () => { + mockUseUiSetting$.mockImplementation(() => [null]); + const wrapper = mount(); + + expect(wrapper.text()).toEqual('2,806,422'); + }); - test('it renders bytes to hardcoded format when no configuration exists', () => { - mockUseUiSetting$.mockImplementation(() => [null]); - const wrapper = mount(); - expect(wrapper.text()).toEqual('2.7MB'); - }); + test('it renders bytes according to the default format', () => { + mockUseUiSetting$.mockImplementation(() => [DEFAULT_BYTES_FORMAT_VALUE]); + const wrapper = mount(); - test('it renders bytes according to the default format', () => { - mockUseUiSetting$.mockImplementation( - getMockKibanaUiSetting(mockFrameworks.default_browser) - ); - const wrapper = mount(); - expect(wrapper.text()).toEqual('2.7MB'); - }); + expect(wrapper.text()).toEqual('2.7MB'); + }); + + test('it renders bytes supplied as a number according to the default format', () => { + mockUseUiSetting$.mockImplementation(() => [DEFAULT_BYTES_FORMAT_VALUE]); + const wrapper = mount(); + + expect(wrapper.text()).toEqual('2.7MB'); + }); - test('it renders bytes supplied as a number according to the default format', () => { - mockUseUiSetting$.mockImplementation( - getMockKibanaUiSetting(mockFrameworks.default_browser) - ); - const wrapper = mount(); - expect(wrapper.text()).toEqual('2.7MB'); - }); + test('it renders bytes according to new format', () => { + mockUseUiSetting$.mockImplementation(() => ['0b']); + const wrapper = mount(); - test('it renders bytes according to new format', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.bytes_short)); - const wrapper = mount(); - expect(wrapper.text()).toEqual('3MB'); - }); - }); + expect(wrapper.text()).toEqual('3MB'); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.tsx index 5a4816a96324b..98a1acf471629 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_bytes/index.tsx @@ -10,13 +10,22 @@ import numeral from '@elastic/numeral'; import { DEFAULT_BYTES_FORMAT } from '../../../common/constants'; import { useUiSetting$ } from '../../lib/kibana'; -export const PreferenceFormattedBytesComponent = ({ value }: { value: string | number }) => { +type Bytes = string | number; + +export const formatBytes = (value: Bytes, format: string) => { + return numeral(value).format(format); +}; + +export const useFormatBytes = () => { const [bytesFormat] = useUiSetting$(DEFAULT_BYTES_FORMAT); - return ( - <>{bytesFormat ? numeral(value).format(bytesFormat) : numeral(value).format('0,0.[0]b')} - ); + + return (value: Bytes) => formatBytes(value, bytesFormat); }; +export const PreferenceFormattedBytesComponent = ({ value }: { value: Bytes }) => ( + <>{useFormatBytes()(value)} +); + PreferenceFormattedBytesComponent.displayName = 'PreferenceFormattedBytesComponent'; export const PreferenceFormattedBytes = React.memo(PreferenceFormattedBytesComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_date/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/formatted_date/__snapshots__/index.test.tsx.snap index d196a23bff5bf..9e851ddcd7d0f 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_date/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/formatted_date/__snapshots__/index.test.tsx.snap @@ -1,9 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`formatted_date PreferenceFormattedDate rendering renders correctly against snapshot 1`] = ` +exports[`formatted_date PreferenceFormattedDate renders correctly against snapshot 1`] = ` - 2019-02-25T22:27:05.000Z + 2019-02-25T22:27:05Z `; diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx index 6f8bab13a0094..1b6f63f944882 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx @@ -6,174 +6,165 @@ import { mount, shallow } from 'enzyme'; import toJson from 'enzyme-to-json'; -import moment from 'moment-timezone'; import React from 'react'; -import { useUiSetting$ } from '../../lib/kibana'; +import { useDateFormat, useTimeZone } from '../../hooks'; -import { mockFrameworks, TestProviders, MockFrameworks, getMockKibanaUiSetting } from '../../mock'; +import { TestProviders } from '../../mock'; import { getEmptyString, getEmptyValue } from '../empty_value'; import { PreferenceFormattedDate, FormattedDate, FormattedRelativePreferenceDate } from '.'; -jest.mock('../../lib/kibana'); -const mockUseUiSetting$ = useUiSetting$ as jest.Mock; +jest.mock('../../hooks'); +const mockUseDateFormat = useDateFormat as jest.Mock; +const mockUseTimeZone = useTimeZone as jest.Mock; + +const isoDateString = '2019-02-25T22:27:05.000Z'; describe('formatted_date', () => { + let isoDate: Date; + + beforeEach(() => { + isoDate = new Date(isoDateString); + mockUseDateFormat.mockImplementation(() => 'MMM D, YYYY @ HH:mm:ss.SSS'); + mockUseTimeZone.mockImplementation(() => 'UTC'); + }); + describe('PreferenceFormattedDate', () => { - describe('rendering', () => { - const isoDateString = '2019-02-25T22:27:05.000Z'; - const isoDate = new Date(isoDateString); - const configFormattedDateString = (dateString: string, config: MockFrameworks): string => - moment - .tz( - dateString, - config.dateFormatTz! === 'Browser' ? config.timezone! : config.dateFormatTz! - ) - .format(config.dateFormat); - - test('renders correctly against snapshot', () => { - mockUseUiSetting$.mockImplementation(() => [null]); - const wrapper = mount(); - expect(toJson(wrapper)).toMatchSnapshot(); - }); - - test('it renders the UTC ISO8601 date string supplied when no configuration exists', () => { - mockUseUiSetting$.mockImplementation(() => [null]); - const wrapper = mount(); - expect(wrapper.text()).toEqual(isoDateString); - }); - - test('it renders the UTC ISO8601 date supplied when the default configuration exists', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - - const wrapper = mount(); - expect(wrapper.text()).toEqual( - configFormattedDateString(isoDateString, mockFrameworks.default_UTC) - ); - }); - - test('it renders the correct tz when the default browser configuration exists', () => { - mockUseUiSetting$.mockImplementation( - getMockKibanaUiSetting(mockFrameworks.default_browser) - ); - const wrapper = mount(); - expect(wrapper.text()).toEqual( - configFormattedDateString(isoDateString, mockFrameworks.default_browser) - ); - }); - - test('it renders the correct tz when a non-UTC configuration exists', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_MT)); - const wrapper = mount(); - expect(wrapper.text()).toEqual( - configFormattedDateString(isoDateString, mockFrameworks.default_MT) - ); - }); + test('renders correctly against snapshot', () => { + mockUseDateFormat.mockImplementation(() => ''); + const wrapper = mount(); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders the date with the default configuration', () => { + const wrapper = mount(); + + expect(wrapper.text()).toEqual('Feb 25, 2019 @ 22:27:05.000'); + }); + + test('it renders a UTC ISO8601 date string supplied when no date format configuration exists', () => { + mockUseDateFormat.mockImplementation(() => ''); + const wrapper = mount(); + + expect(wrapper.text()).toEqual('2019-02-25T22:27:05Z'); + }); + + test('it renders the correct timezone when a non-UTC configuration exists', () => { + mockUseTimeZone.mockImplementation(() => 'America/Denver'); + const wrapper = mount(); + + expect(wrapper.text()).toEqual('Feb 25, 2019 @ 15:27:05.000'); + }); + + test('it renders the date with a user-defined format', () => { + mockUseDateFormat.mockImplementation(() => 'MMM-DD-YYYY'); + const wrapper = mount(); + + expect(wrapper.text()).toEqual('Feb-25-2019'); }); }); describe('FormattedDate', () => { - describe('rendering', () => { - test('it renders against a numeric epoch', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount(); - expect(wrapper.text()).toEqual('May 28, 2019 @ 21:35:39.000'); - }); - - test('it renders against a string epoch', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount(); - expect(wrapper.text()).toEqual('May 28, 2019 @ 21:35:39.000'); - }); - - test('it renders against a ISO string', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount( - - ); - expect(wrapper.text()).toEqual('May 28, 2019 @ 22:04:49.957'); - }); - - test('it renders against an empty string as an empty string placeholder', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount( - - - - ); - expect(wrapper.text()).toEqual('(Empty String)'); - }); - - test('it renders against an null as a EMPTY_VALUE', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount( - - - - ); - expect(wrapper.text()).toEqual(getEmptyValue()); - }); - - test('it renders against an undefined as a EMPTY_VALUE', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount( - - - - ); - expect(wrapper.text()).toEqual(getEmptyValue()); - }); - - test('it renders against an invalid date time as just the string its self', () => { - mockUseUiSetting$.mockImplementation(getMockKibanaUiSetting(mockFrameworks.default_UTC)); - const wrapper = mount( - - - - ); - expect(wrapper.text()).toEqual('Rebecca Evan Braden'); - }); + test('it renders against a numeric epoch', () => { + const wrapper = mount(); + expect(wrapper.text()).toEqual('May 28, 2019 @ 21:35:39.000'); + }); + + test('it renders against a string epoch', () => { + const wrapper = mount(); + expect(wrapper.text()).toEqual('May 28, 2019 @ 21:35:39.000'); + }); + + test('it renders against a ISO string', () => { + const wrapper = mount( + + ); + expect(wrapper.text()).toEqual('May 28, 2019 @ 22:04:49.957'); + }); + + test('it renders against an empty string as an empty string placeholder', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toEqual(getEmptyString()); + }); + + test('it renders against an null as a EMPTY_VALUE', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toEqual(getEmptyValue()); + }); + + test('it renders against an undefined as a EMPTY_VALUE', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toEqual(getEmptyValue()); + }); + + test('it renders against an invalid date time as just the string its self', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toEqual('Rebecca Evan Braden'); }); }); describe('FormattedRelativePreferenceDate', () => { - describe('rendering', () => { - test('renders time over an hour correctly against snapshot', () => { - const isoDateString = '2019-02-25T22:27:05.000Z'; - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="preference-time"]').exists()).toBe(true); - }); - test('renders time under an hour correctly against snapshot', () => { - const timeTwelveMinutesAgo = new Date(new Date().getTime() - 12 * 60 * 1000).toISOString(); - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="relative-time"]').exists()).toBe(true); - }); - test('renders empty string value correctly', () => { - const wrapper = mount( - - - - ); - expect(wrapper.text()).toBe(getEmptyString()); - }); - - test('renders undefined value correctly', () => { - const wrapper = mount( - - - - ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); - - test('renders null value correctly', () => { - const wrapper = mount( - - - - ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); + test('renders time over an hour correctly against snapshot', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="preference-time"]').exists()).toBe(true); + }); + + test('renders time under an hour correctly against snapshot', () => { + const timeTwelveMinutesAgo = new Date(new Date().getTime() - 12 * 60 * 1000).toISOString(); + const wrapper = shallow(); + + expect(wrapper.find('[data-test-subj="relative-time"]').exists()).toBe(true); + }); + + test('renders empty string value correctly', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toBe(getEmptyString()); + }); + + test('renders undefined value correctly', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toBe(getEmptyValue()); + }); + + test('renders null value correctly', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.text()).toBe(getEmptyValue()); }); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx index 169696d5fcde9..4e5903c02abf7 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx @@ -8,29 +8,16 @@ import moment from 'moment-timezone'; import React from 'react'; import { FormattedRelative } from '@kbn/i18n/react'; -import { useUiSetting$ } from '../../lib/kibana'; - -import { - DEFAULT_DATE_FORMAT, - DEFAULT_DATE_FORMAT_TZ, - DEFAULT_TIMEZONE_BROWSER, -} from '../../../common/constants'; +import { useDateFormat, useTimeZone } from '../../hooks'; import { getOrEmptyTagFromValue } from '../empty_value'; import { LocalizedDateTooltip } from '../localized_date_tooltip'; import { getMaybeDate } from './maybe_date'; export const PreferenceFormattedDate = React.memo<{ value: Date }>(({ value }) => { - const [dateFormat] = useUiSetting$(DEFAULT_DATE_FORMAT); - const [dateFormatTz] = useUiSetting$(DEFAULT_DATE_FORMAT_TZ); - const [timezone] = useUiSetting$(DEFAULT_TIMEZONE_BROWSER); + const dateFormat = useDateFormat(); + const timeZone = useTimeZone(); - return ( - <> - {dateFormat && dateFormatTz && timezone - ? moment.tz(value, dateFormatTz === 'Browser' ? timezone : dateFormatTz).format(dateFormat) - : moment.utc(value).toISOString()} - - ); + return <>{moment.tz(value, timeZone).format(dateFormat)}; }); PreferenceFormattedDate.displayName = 'PreferenceFormattedDate'; diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts index 1eb5e96b86857..a7ef71f7a6a0d 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts +++ b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts @@ -6,7 +6,7 @@ import { ScaleType, niceTimeFormatter, Position } from '@elastic/charts'; import { get, groupBy, map, toPairs } from 'lodash/fp'; -import numeral from '@elastic/numeral'; + import { UpdateDateRange, ChartSeriesData } from '../charts/common'; import { MatrixHistogramDataTypes, MatrixHistogramMappingTypes } from './types'; @@ -87,7 +87,3 @@ export const getCustomChartData = ( }, formattedChartData); else return formattedChartData; }; - -export const bytesFormatter = (value: number) => { - return numeral(value).format('0,0.[0]b'); -}; diff --git a/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts b/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts index bce99c943c7a5..48277b0b6fa52 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts @@ -15,11 +15,8 @@ import { errorToToaster } from '../api/error_to_toaster'; import * as i18n from './translations'; import { useUiSetting$ } from '../../../lib/kibana'; -import { - DEFAULT_ANOMALY_SCORE, - DEFAULT_TIMEZONE_BROWSER, - DEFAULT_KBN_VERSION, -} from '../../../../common/constants'; +import { DEFAULT_ANOMALY_SCORE } from '../../../../common/constants'; +import { useTimeZone } from '../../../hooks'; interface Args { influencers?: InfluencerInput[]; @@ -67,9 +64,8 @@ export const useAnomaliesTableData = ({ const capabilities = useContext(MlCapabilitiesContext); const userPermissions = hasMlUserPermissions(capabilities); const [, dispatchToaster] = useStateToaster(); - const [timezone] = useUiSetting$(DEFAULT_TIMEZONE_BROWSER); + const timeZone = useTimeZone(); const [anomalyScore] = useUiSetting$(DEFAULT_ANOMALY_SCORE); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const siemJobIds = siemJobs.filter(job => job.isInstalled).map(job => job.id); @@ -95,11 +91,10 @@ export const useAnomaliesTableData = ({ earliestMs, latestMs, influencers: influencersInput, - dateFormatTz: timezone, + dateFormatTz: timeZone, maxRecords: 500, maxExamples: 10, }, - kbnVersion, abortCtrl.signal ); if (isSubscribed) { diff --git a/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts b/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts index e66d984a15294..10b2538d1e785 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts @@ -21,20 +21,15 @@ export interface Body { maxExamples: number; } -export const anomaliesTableData = async ( - body: Body, - kbnVersion: string, - signal: AbortSignal -): Promise => { +export const anomaliesTableData = async (body: Body, signal: AbortSignal): Promise => { const response = await fetch(`${chrome.getBasePath()}/api/ml/results/anomalies_table_data`, { method: 'POST', credentials: 'same-origin', body: JSON.stringify(body), headers: { - 'kbn-system-api': 'true', 'content-Type': 'application/json', - 'kbn-xsrf': kbnVersion, - 'kbn-version': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, signal, }); diff --git a/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts b/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts index c1654a1648f2b..1333951028494 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts @@ -22,18 +22,14 @@ export interface Body { maxExamples: number; } -export const getMlCapabilities = async ( - kbnVersion: string, - signal: AbortSignal -): Promise => { +export const getMlCapabilities = async (signal: AbortSignal): Promise => { const response = await fetch(`${chrome.getBasePath()}/api/ml/ml_capabilities`, { method: 'GET', credentials: 'same-origin', headers: { - 'kbn-system-api': 'true', 'content-Type': 'application/json', - 'kbn-xsrf': kbnVersion, - 'kbn-version': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, signal, }); diff --git a/x-pack/legacy/plugins/siem/public/components/ml/permissions/ml_capabilities_provider.tsx b/x-pack/legacy/plugins/siem/public/components/ml/permissions/ml_capabilities_provider.tsx index b8d6908df464e..cae05e26b115b 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/permissions/ml_capabilities_provider.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/permissions/ml_capabilities_provider.tsx @@ -11,8 +11,6 @@ import { getMlCapabilities } from '../api/get_ml_capabilities'; import { emptyMlCapabilities } from '../empty_ml_capabilities'; import { errorToToaster } from '../api/error_to_toaster'; import { useStateToaster } from '../../toasters'; -import { useUiSetting$ } from '../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; import * as i18n from './translations'; @@ -36,7 +34,6 @@ export const MlCapabilitiesProvider = React.memo<{ children: JSX.Element }>(({ c emptyMlCapabilitiesProvider ); const [, dispatchToaster] = useStateToaster(); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); useEffect(() => { let isSubscribed = true; @@ -44,7 +41,7 @@ export const MlCapabilitiesProvider = React.memo<{ children: JSX.Element }>(({ c async function fetchMlCapabilities() { try { - const mlCapabilities = await getMlCapabilities(kbnVersion, abortCtrl.signal); + const mlCapabilities = await getMlCapabilities(abortCtrl.signal); if (isSubscribed) { setCapabilities({ ...mlCapabilities, capabilitiesFetched: true }); } diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx index 8e7bedd8f872a..a04b8f4b99653 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx @@ -25,12 +25,10 @@ import { throwIfNotOk } from '../../hooks/api/api'; * Checks the ML Recognizer API to see if a given indexPattern has any compatible modules * * @param indexPatternName ES index pattern to check for compatible modules - * @param headers optional headers to add * @param signal to cancel request */ export const checkRecognizer = async ({ indexPatternName, - kbnVersion, signal, }: CheckRecognizerProps): Promise => { const response = await fetch( @@ -39,10 +37,9 @@ export const checkRecognizer = async ({ method: 'GET', credentials: 'same-origin', headers: { - 'kbn-system-api': 'true', 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, signal, } @@ -55,22 +52,16 @@ export const checkRecognizer = async ({ * Returns ML Module for given moduleId. Returns all modules if no moduleId specified * * @param moduleId id of the module to retrieve - * @param headers optional headers to add optional headers to add * @param signal to cancel request */ -export const getModules = async ({ - moduleId = '', - kbnVersion, - signal, -}: GetModulesProps): Promise => { +export const getModules = async ({ moduleId = '', signal }: GetModulesProps): Promise => { const response = await fetch(`${chrome.getBasePath()}/api/ml/modules/get_module/${moduleId}`, { method: 'GET', credentials: 'same-origin', headers: { - 'kbn-system-api': 'true', 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, signal, }); @@ -93,7 +84,6 @@ export const setupMlJob = async ({ indexPatternName = 'auditbeat-*', jobIdErrorFilter = [], groups = ['siem'], - kbnVersion, prefix = '', }: MlSetupArgs): Promise => { const response = await fetch(`${chrome.getBasePath()}/api/ml/modules/setup/${configTemplate}`, { @@ -107,10 +97,9 @@ export const setupMlJob = async ({ useDedicatedIndex: true, }), headers: { - 'kbn-system-api': 'true', 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, }); await throwIfNotOk(response); @@ -124,16 +113,13 @@ export const setupMlJob = async ({ * * @param datafeedIds * @param start - * @param headers optional headers to add */ export const startDatafeeds = async ({ datafeedIds, - kbnVersion, start = 0, }: { datafeedIds: string[]; start: number; - kbnVersion: string; }): Promise => { const response = await fetch(`${chrome.getBasePath()}/api/ml/jobs/force_start_datafeeds`, { method: 'POST', @@ -143,10 +129,9 @@ export const startDatafeeds = async ({ ...(start !== 0 && { start }), }), headers: { - 'kbn-system-api': 'true', 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, }); await throwIfNotOk(response); @@ -163,10 +148,8 @@ export const startDatafeeds = async ({ */ export const stopDatafeeds = async ({ datafeedIds, - kbnVersion, }: { datafeedIds: string[]; - kbnVersion: string; }): Promise<[StopDatafeedResponse | ErrorResponse, CloseJobsResponse]> => { const stopDatafeedsResponse = await fetch(`${chrome.getBasePath()}/api/ml/jobs/stop_datafeeds`, { method: 'POST', @@ -175,9 +158,9 @@ export const stopDatafeeds = async ({ datafeedIds, }), headers: { - 'kbn-system-api': 'true', 'content-type': 'application/json', - 'kbn-xsrf': kbnVersion, + 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, }); @@ -198,7 +181,7 @@ export const stopDatafeeds = async ({ headers: { 'content-type': 'application/json', 'kbn-system-api': 'true', - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, }); @@ -214,10 +197,7 @@ export const stopDatafeeds = async ({ * * @param signal to cancel request */ -export const getJobsSummary = async ( - signal: AbortSignal, - kbnVersion: string -): Promise => { +export const getJobsSummary = async (signal: AbortSignal): Promise => { const response = await fetch(`${chrome.getBasePath()}/api/ml/jobs/jobs_summary`, { method: 'POST', credentials: 'same-origin', @@ -225,8 +205,7 @@ export const getJobsSummary = async ( headers: { 'content-type': 'application/json', 'kbn-system-api': 'true', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, signal, }); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs.tsx index f9d110d711d07..9df93d087e166 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs.tsx @@ -13,7 +13,7 @@ import { MlCapabilitiesContext } from '../../ml/permissions/ml_capabilities_prov import { useStateToaster } from '../../toasters'; import { errorToToaster } from '../../ml/api/error_to_toaster'; import { useUiSetting$ } from '../../../lib/kibana'; -import { DEFAULT_INDEX_KEY, DEFAULT_KBN_VERSION } from '../../../../common/constants'; +import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; import * as i18n from './translations'; import { createSiemJobs } from './use_siem_jobs_helpers'; @@ -34,7 +34,6 @@ export const useSiemJobs = (refetchData: boolean): Return => { const capabilities = useContext(MlCapabilitiesContext); const userPermissions = hasMlUserPermissions(capabilities); const [siemDefaultIndex] = useUiSetting$(DEFAULT_INDEX_KEY); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); useEffect(() => { @@ -47,11 +46,10 @@ export const useSiemJobs = (refetchData: boolean): Return => { try { // Batch fetch all installed jobs, ML modules, and check which modules are compatible with siemDefaultIndex const [jobSummaryData, modulesData, compatibleModules] = await Promise.all([ - getJobsSummary(abortCtrl.signal, kbnVersion), - getModules({ signal: abortCtrl.signal, kbnVersion }), + getJobsSummary(abortCtrl.signal), + getModules({ signal: abortCtrl.signal }), checkRecognizer({ indexPatternName: siemDefaultIndex, - kbnVersion, signal: abortCtrl.signal, }), ]); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx index c34ed51d22994..307be06424ee3 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/ml_popover.tsx @@ -10,8 +10,7 @@ import moment from 'moment'; import React, { useContext, useReducer, useState } from 'react'; import styled from 'styled-components'; -import { DEFAULT_KBN_VERSION } from '../../../common/constants'; -import { useKibana, useUiSetting$ } from '../../lib/kibana'; +import { useKibana } from '../../lib/kibana'; import { METRIC_TYPE, TELEMETRY_EVENT, trackUiAction as track } from '../../lib/track_usage'; import { errorToToaster } from '../ml/api/error_to_toaster'; import { hasMlAdminPermissions } from '../ml/permissions/has_ml_admin_permissions'; @@ -97,7 +96,6 @@ export const MlPopover = React.memo(() => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [filterProperties, setFilterProperties] = useState(defaultFilterProps); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [isLoadingSiemJobs, siemJobs] = useSiemJobs(refreshToggle); const [, dispatchToaster] = useStateToaster(); const capabilities = useContext(MlCapabilitiesContext); @@ -114,7 +112,6 @@ export const MlPopover = React.memo(() => { indexPatternName: job.defaultIndexPattern, jobIdErrorFilter: [job.id], groups: job.groups, - kbnVersion, }); } catch (error) { errorToToaster({ title: i18n.CREATE_JOB_FAILURE, error, dispatchToaster }); @@ -132,14 +129,14 @@ export const MlPopover = React.memo(() => { if (enable) { const startTime = Math.max(latestTimestampMs, maxStartTime); try { - await startDatafeeds({ datafeedIds: [`datafeed-${job.id}`], kbnVersion, start: startTime }); + await startDatafeeds({ datafeedIds: [`datafeed-${job.id}`], start: startTime }); } catch (error) { track(METRIC_TYPE.COUNT, TELEMETRY_EVENT.JOB_ENABLE_FAILURE); errorToToaster({ title: i18n.START_JOB_FAILURE, error, dispatchToaster }); } } else { try { - await stopDatafeeds({ datafeedIds: [`datafeed-${job.id}`], kbnVersion }); + await stopDatafeeds({ datafeedIds: [`datafeed-${job.id}`] }); } catch (error) { track(METRIC_TYPE.COUNT, TELEMETRY_EVENT.JOB_DISABLE_FAILURE); errorToToaster({ title: i18n.STOP_JOB_FAILURE, error, dispatchToaster }); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/types.ts b/x-pack/legacy/plugins/siem/public/components/ml_popover/types.ts index f8794c1963961..964ae8c8242d4 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/types.ts @@ -14,7 +14,6 @@ export interface Group { export interface CheckRecognizerProps { indexPatternName: string[]; - kbnVersion: string; signal: AbortSignal; } @@ -30,7 +29,6 @@ export interface RecognizerModule { export interface GetModulesProps { moduleId?: string; - kbnVersion: string; signal: AbortSignal; } @@ -97,7 +95,6 @@ export interface MlSetupArgs { jobIdErrorFilter: string[]; groups: string[]; prefix?: string; - kbnVersion: string; } /** diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/first_last_seen_host/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/first_last_seen_host/index.test.tsx index 0c6976ef774e2..4a836333f3311 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/first_last_seen_host/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/hosts/first_last_seen_host/index.test.tsx @@ -15,8 +15,6 @@ import { TestProviders } from '../../../../mock'; import { FirstLastSeenHost, FirstLastSeenHostType } from '.'; -jest.mock('../../../../lib/kibana'); - describe('FirstLastSeen Component', () => { const firstSeen = 'Apr 8, 2019 @ 16:09:40.692'; const lastSeen = 'Apr 8, 2019 @ 18:35:45.064'; diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx index 490efd08f0aa7..e7b0d8e7d00d5 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx @@ -9,22 +9,23 @@ import React from 'react'; import { ScaleType } from '@elastic/charts'; import * as i18n from './translation'; import { MatrixHistogram } from '../../../matrix_histogram'; -import { bytesFormatter } from '../../../matrix_histogram/utils'; import { MatrixOverOrdinalHistogramData } from '../../../../graphql/types'; import { MatrixHistogramBasicProps } from '../../../matrix_histogram/types'; +import { useFormatBytes } from '../../../formatted_bytes'; export const NetworkDnsHistogram = ( props: MatrixHistogramBasicProps ) => { const dataKey = 'histogram'; const { ...matrixOverTimeProps } = props; + const formatBytes = useFormatBytes(); return ( diff --git a/x-pack/legacy/plugins/siem/public/components/query_bar/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/query_bar/index.test.tsx index e403963cbbe20..870d0b40d8cd4 100644 --- a/x-pack/legacy/plugins/siem/public/components/query_bar/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/query_bar/index.test.tsx @@ -14,8 +14,6 @@ import { FilterManager, SearchBar } from '../../../../../../../src/plugins/data/ import { QueryBar, QueryBarComponentProps } from '.'; import { createKibanaContextProviderMock } from '../../mock/kibana_react'; -jest.mock('../../lib/kibana'); - const mockUiSettingsForFilterManager = createKibanaCoreStartMock().uiSettings; describe('QueryBar ', () => { diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.test.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.test.tsx index 5c25216cf8487..975af67efd763 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.test.tsx @@ -7,21 +7,16 @@ import { shallow } from 'enzyme'; import toJson from 'enzyme-to-json'; import { cloneDeep } from 'lodash/fp'; -import moment from 'moment-timezone'; import React from 'react'; import { TimelineNonEcsData } from '../../../../graphql/types'; -import { defaultHeaders, mockFrameworks, mockTimelineData, TestProviders } from '../../../../mock'; +import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../mock'; import { getEmptyValue } from '../../../empty_value'; import { useMountAppended } from '../../../../utils/use_mount_appended'; import { plainColumnRenderer } from './plain_column_renderer'; import { getValues, deleteItemIdx, findItem } from './helpers'; -jest.mock('../../../../lib/kibana'); - -const mockFramework = mockFrameworks.default_UTC; - describe('plain_column_renderer', () => { const mount = useMountAppended(); @@ -134,11 +129,7 @@ describe('plain_column_renderer', () => { {column} ); - expect(wrapper.text()).toEqual( - moment - .tz(getValues('@timestamp', mockDatum)![0], mockFramework.dateFormatTz!) - .format(mockFramework.dateFormat) - ); + expect(wrapper.text()).toEqual('Nov 5, 2018 @ 19:03:25.937'); }); test('should return an empty value if destination ip is empty', () => { diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/system/generic_row_renderer.test.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/system/generic_row_renderer.test.tsx index 62402ba8a4c4e..4d3f2d71604e8 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/system/generic_row_renderer.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/system/generic_row_renderer.test.tsx @@ -49,8 +49,6 @@ import { } from './generic_row_renderer'; import * as i18n from './translations'; -jest.mock('../../../../../lib/kibana'); - describe('GenericRowRenderer', () => { const mount = useMountAppended(); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts index a3ee878e305b4..f9611995cdb04 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts @@ -23,17 +23,15 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../common/constants'; * Add provided Rule * * @param rule to add - * @param kbnVersion current Kibana Version to use for headers * @param signal to cancel request */ -export const addRule = async ({ rule, kbnVersion, signal }: AddRulesProps): Promise => { +export const addRule = async ({ rule, signal }: AddRulesProps): Promise => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_RULES_URL}`, { method: rule.id != null ? 'PUT' : 'POST', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, body: JSON.stringify(rule), signal, @@ -49,7 +47,6 @@ export const addRule = async ({ rule, kbnVersion, signal }: AddRulesProps): Prom * @param filterOptions desired filters (e.g. filter/sortField/sortOrder) * @param pagination desired pagination options (e.g. page/perPage) * @param id if specified, will return specific rule if exists - * @param kbnVersion current Kibana Version to use for headers * @param signal to cancel request */ export const fetchRules = async ({ @@ -64,7 +61,6 @@ export const fetchRules = async ({ total: 0, }, id, - kbnVersion, signal, }: FetchRulesProps): Promise => { const queryParams = [ @@ -101,16 +97,14 @@ export const fetchRules = async ({ * Fetch a Rule by providing a Rule ID * * @param id Rule ID's (not rule_id) - * @param kbnVersion current Kibana Version to use for headers */ -export const fetchRuleById = async ({ id, kbnVersion, signal }: FetchRuleProps): Promise => { +export const fetchRuleById = async ({ id, signal }: FetchRuleProps): Promise => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_RULES_URL}?id=${id}`, { method: 'GET', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, signal, }); @@ -124,21 +118,15 @@ export const fetchRuleById = async ({ id, kbnVersion, signal }: FetchRuleProps): * * @param ids array of Rule ID's (not rule_id) to enable/disable * @param enabled to enable or disable - * @param kbnVersion current Kibana Version to use for headers */ -export const enableRules = async ({ - ids, - enabled, - kbnVersion, -}: EnableRulesProps): Promise => { +export const enableRules = async ({ ids, enabled }: EnableRulesProps): Promise => { const requests = ids.map(id => fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_RULES_URL}`, { method: 'PUT', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, body: JSON.stringify({ id, enabled }), }) @@ -155,9 +143,8 @@ export const enableRules = async ({ * Deletes provided Rule ID's * * @param ids array of Rule ID's (not rule_id) to delete - * @param kbnVersion current Kibana Version to use for headers */ -export const deleteRules = async ({ ids, kbnVersion }: DeleteRulesProps): Promise => { +export const deleteRules = async ({ ids }: DeleteRulesProps): Promise => { // TODO: Don't delete if immutable! const requests = ids.map(id => fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_RULES_URL}?id=${id}`, { @@ -165,8 +152,7 @@ export const deleteRules = async ({ ids, kbnVersion }: DeleteRulesProps): Promis credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, }) ); @@ -182,20 +168,15 @@ export const deleteRules = async ({ ids, kbnVersion }: DeleteRulesProps): Promis * Duplicates provided Rules * * @param rule to duplicate - * @param kbnVersion current Kibana Version to use for headers */ -export const duplicateRules = async ({ - rules, - kbnVersion, -}: DuplicateRulesProps): Promise => { +export const duplicateRules = async ({ rules }: DuplicateRulesProps): Promise => { const requests = rules.map(rule => fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_RULES_URL}`, { method: 'POST', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, body: JSON.stringify({ ...rule, diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/persist_rule.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/persist_rule.tsx index 82490991236de..ea03c34ec31ba 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/persist_rule.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/persist_rule.tsx @@ -6,8 +6,6 @@ import { useEffect, useState, Dispatch } from 'react'; -import { useUiSetting$ } from '../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; import { useStateToaster } from '../../../components/toasters'; import { errorToToaster } from '../../../components/ml/api/error_to_toaster'; @@ -26,7 +24,6 @@ export const usePersistRule = (): Return => { const [rule, setRule] = useState(null); const [isSaved, setIsSaved] = useState(false); const [isLoading, setIsLoading] = useState(false); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); useEffect(() => { @@ -37,7 +34,7 @@ export const usePersistRule = (): Return => { if (rule != null) { try { setIsLoading(true); - await persistRule({ rule, kbnVersion, signal: abortCtrl.signal }); + await persistRule({ rule, signal: abortCtrl.signal }); if (isSubscribed) { setIsSaved(true); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/types.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/types.ts index 0885e541cead5..9f3cba7189fb1 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/types.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/types.ts @@ -41,7 +41,6 @@ export type NewRule = t.TypeOf; export interface AddRulesProps { rule: NewRule; - kbnVersion: string; signal: AbortSignal; } @@ -98,7 +97,6 @@ export interface FetchRulesProps { pagination?: PaginationOptions; filterOptions?: FilterOptions; id?: string; - kbnVersion: string; signal: AbortSignal; } @@ -117,22 +115,18 @@ export interface FetchRulesResponse { export interface FetchRuleProps { id: string; - kbnVersion: string; signal: AbortSignal; } export interface EnableRulesProps { ids: string[]; enabled: boolean; - kbnVersion: string; } export interface DeleteRulesProps { ids: string[]; - kbnVersion: string; } export interface DuplicateRulesProps { rules: Rules; - kbnVersion: string; } diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rule.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rule.tsx index ad0b87385ee79..22ba86cd09f74 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rule.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rule.tsx @@ -6,8 +6,6 @@ import { useEffect, useState } from 'react'; -import { useUiSetting$ } from '../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; import { useStateToaster } from '../../../components/toasters'; import { errorToToaster } from '../../../components/ml/api/error_to_toaster'; import { fetchRuleById } from './api'; @@ -25,7 +23,6 @@ type Return = [boolean, Rule | null]; export const useRule = (id: string | undefined): Return => { const [rule, setRule] = useState(null); const [loading, setLoading] = useState(true); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); useEffect(() => { @@ -37,7 +34,6 @@ export const useRule = (id: string | undefined): Return => { setLoading(true); const ruleResponse = await fetchRuleById({ id: idToFetch, - kbnVersion, signal: abortCtrl.signal, }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx index 66285c804aa28..b49dd8d51d4f7 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx @@ -6,8 +6,6 @@ import { useEffect, useState } from 'react'; -import { useUiSetting$ } from '../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; import { FetchRulesResponse, FilterOptions, PaginationOptions } from './types'; import { useStateToaster } from '../../../components/toasters'; import { fetchRules } from './api'; @@ -35,7 +33,6 @@ export const useRules = ( data: [], }); const [loading, setLoading] = useState(true); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); useEffect(() => { @@ -48,7 +45,6 @@ export const useRules = ( const fetchRulesResult = await fetchRules({ filterOptions, pagination, - kbnVersion, signal: abortCtrl.signal, }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts index e69bbfe1925fb..e7641fd37678e 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts @@ -29,12 +29,10 @@ import { parseJsonFromBody } from '../../../utils/api'; * Fetch Signals by providing a query * * @param query String to match a dsl - * @param kbnVersion current Kibana Version to use for headers * @param signal AbortSignal for cancelling request */ export const fetchQuerySignals = async ({ query, - kbnVersion, signal, }: QuerySignals): Promise> => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_QUERY_SIGNALS_URL}`, { @@ -42,8 +40,7 @@ export const fetchQuerySignals = async ({ credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, body: query, signal, @@ -58,13 +55,11 @@ export const fetchQuerySignals = async ({ * * @param query of signals to update * @param status to update to('open' / 'closed') - * @param kbnVersion current Kibana Version to use for headers * @param signal AbortSignal for cancelling request */ export const updateSignalStatus = async ({ query, status, - kbnVersion, signal, }: UpdateSignalStatusProps): Promise => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_SIGNALS_STATUS_URL}`, { @@ -72,8 +67,7 @@ export const updateSignalStatus = async ({ credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, body: JSON.stringify({ status, ...query }), signal, @@ -86,20 +80,15 @@ export const updateSignalStatus = async ({ /** * Fetch Signal Index * - * @param kbnVersion current Kibana Version to use for headers * @param signal AbortSignal for cancelling request */ -export const getSignalIndex = async ({ - kbnVersion, - signal, -}: BasicSignals): Promise => { +export const getSignalIndex = async ({ signal }: BasicSignals): Promise => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_INDEX_URL}`, { method: 'GET', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, signal, }); @@ -117,20 +106,15 @@ export const getSignalIndex = async ({ /** * Get User Privileges * - * @param kbnVersion current Kibana Version to use for headers * @param signal AbortSignal for cancelling request */ -export const getUserPrivilege = async ({ - kbnVersion, - signal, -}: BasicSignals): Promise => { +export const getUserPrivilege = async ({ signal }: BasicSignals): Promise => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_PRIVILEGES_URL}`, { method: 'GET', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, signal, }); @@ -142,20 +126,15 @@ export const getUserPrivilege = async ({ /** * Create Signal Index if needed it * - * @param kbnVersion current Kibana Version to use for headers * @param signal AbortSignal for cancelling request */ -export const createSignalIndex = async ({ - kbnVersion, - signal, -}: BasicSignals): Promise => { +export const createSignalIndex = async ({ signal }: BasicSignals): Promise => { const response = await fetch(`${chrome.getBasePath()}${DETECTION_ENGINE_INDEX_URL}`, { method: 'POST', credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-version': kbnVersion, - 'kbn-xsrf': kbnVersion, + 'kbn-xsrf': 'true', }, signal, }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/types.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/types.ts index 118c2b367ca5b..32f53691bae87 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/types.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/types.ts @@ -7,7 +7,6 @@ export * from './errors_types'; export interface BasicSignals { - kbnVersion: string; signal: AbortSignal; } export interface QuerySignals extends BasicSignals { @@ -39,7 +38,6 @@ export interface SignalSearchResponse extend export interface UpdateSignalStatusProps { query: object; status: 'open' | 'closed'; - kbnVersion: string; signal?: AbortSignal; // TODO: implement cancelling } diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_privilege_user.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_privilege_user.tsx index 6f897703059f7..aa66df53d9fd9 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_privilege_user.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_privilege_user.tsx @@ -6,8 +6,6 @@ import { useEffect, useState } from 'react'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; -import { useUiSetting$ } from '../../../lib/kibana'; import { getUserPrivilege } from './api'; type Return = [boolean, boolean | null, boolean | null]; @@ -20,7 +18,6 @@ export const usePrivilegeUser = (): Return => { const [loading, setLoading] = useState(true); const [isAuthenticated, setAuthenticated] = useState(null); const [hasWrite, setHasWrite] = useState(null); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); useEffect(() => { let isSubscribed = true; @@ -30,7 +27,6 @@ export const usePrivilegeUser = (): Return => { async function fetchData() { try { const privilege = await getUserPrivilege({ - kbnVersion, signal: abortCtrl.signal, }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_query.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_query.tsx index 9501f1189a483..65a5ac866e68d 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_query.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_query.tsx @@ -6,9 +6,6 @@ import { useEffect, useState } from 'react'; -import { useUiSetting$ } from '../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; - import { fetchQuerySignals } from './api'; import { SignalSearchResponse } from './types'; @@ -23,7 +20,6 @@ type Return = [boolean, SignalSearchResponse | null]; export const useQuerySignals = (query: string): Return => { const [signals, setSignals] = useState | null>(null); const [loading, setLoading] = useState(true); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); useEffect(() => { let isSubscribed = true; @@ -34,7 +30,6 @@ export const useQuerySignals = (query: string): Return => try { const signalResponse = await fetchQuerySignals({ query, - kbnVersion, signal: abortCtrl.signal, }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx index 347c90fa3b411..1ff4422cf6411 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx @@ -6,10 +6,8 @@ import { useEffect, useState, useRef } from 'react'; -import { DEFAULT_KBN_VERSION } from '../../../../common/constants'; import { errorToToaster } from '../../../components/ml/api/error_to_toaster'; import { useStateToaster } from '../../../components/toasters'; -import { useUiSetting$ } from '../../../lib/kibana'; import { createSignalIndex, getSignalIndex } from './api'; import * as i18n from './translations'; import { PostSignalError } from './types'; @@ -28,7 +26,6 @@ export const useSignalIndex = (): Return => { const [signalIndexName, setSignalIndexName] = useState(null); const [signalIndexExists, setSignalIndexExists] = useState(null); const createDeSignalIndex = useRef(null); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); useEffect(() => { @@ -38,10 +35,7 @@ export const useSignalIndex = (): Return => { const fetchData = async () => { try { setLoading(true); - const signal = await getSignalIndex({ - kbnVersion, - signal: abortCtrl.signal, - }); + const signal = await getSignalIndex({ signal: abortCtrl.signal }); if (isSubscribed && signal != null) { setSignalIndexName(signal.name); @@ -62,10 +56,7 @@ export const useSignalIndex = (): Return => { let isFetchingData = false; try { setLoading(true); - await createSignalIndex({ - kbnVersion, - signal: abortCtrl.signal, - }); + await createSignalIndex({ signal: abortCtrl.signal }); if (isSubscribed) { isFetchingData = true; diff --git a/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx b/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx index 12282241247cb..8d319ffe23902 100644 --- a/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx +++ b/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx @@ -17,13 +17,9 @@ const emptyIndexPattern: IndexPatternSavedObject[] = []; * * TODO: Refactor to context provider: https://github.com/elastic/siem-team/issues/448 * - * @param headers * @param signal */ -export const getIndexPatterns = async ( - signal: AbortSignal, - kbnVersion: string -): Promise => { +export const getIndexPatterns = async (signal: AbortSignal): Promise => { const response = await fetch( `${chrome.getBasePath()}/api/saved_objects/_find?type=index-pattern&fields=title&fields=type&per_page=10000`, { @@ -31,9 +27,8 @@ export const getIndexPatterns = async ( credentials: 'same-origin', headers: { 'content-type': 'application/json', - 'kbn-xsrf': kbnVersion, - 'kbn-version': kbnVersion, 'kbn-system-api': 'true', + 'kbn-xsrf': 'true', }, signal, } diff --git a/x-pack/legacy/plugins/siem/public/app.ts b/x-pack/legacy/plugins/siem/public/hooks/index.ts similarity index 79% rename from x-pack/legacy/plugins/siem/public/app.ts rename to x-pack/legacy/plugins/siem/public/hooks/index.ts index b068f8a9becda..5049e4587d383 100644 --- a/x-pack/legacy/plugins/siem/public/app.ts +++ b/x-pack/legacy/plugins/siem/public/hooks/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import './apps/index'; +export { useDateFormat, useTimeZone } from './use_ui_settings'; diff --git a/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx b/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx index f5b595b0d01c6..7abe88402096c 100644 --- a/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx +++ b/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx @@ -6,11 +6,9 @@ import { useEffect, useState } from 'react'; -import { DEFAULT_KBN_VERSION } from '../../common/constants'; import { useStateToaster } from '../components/toasters'; import { errorToToaster } from '../components/ml/api/error_to_toaster'; import { IndexPatternSavedObject } from '../components/ml_popover/types'; -import { useUiSetting$ } from '../lib/kibana'; import { getIndexPatterns } from './api/api'; import * as i18n from './translations'; @@ -21,7 +19,6 @@ export const useIndexPatterns = (refreshToggle = false): Return => { const [indexPatterns, setIndexPatterns] = useState([]); const [isLoading, setIsLoading] = useState(true); const [, dispatchToaster] = useStateToaster(); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); useEffect(() => { let isSubscribed = true; @@ -30,7 +27,7 @@ export const useIndexPatterns = (refreshToggle = false): Return => { async function fetchIndexPatterns() { try { - const data = await getIndexPatterns(abortCtrl.signal, kbnVersion); + const data = await getIndexPatterns(abortCtrl.signal); if (isSubscribed) { setIndexPatterns(data); diff --git a/x-pack/legacy/plugins/siem/public/hooks/use_ui_settings.ts b/x-pack/legacy/plugins/siem/public/hooks/use_ui_settings.ts new file mode 100644 index 0000000000000..7eb0242e8e116 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/hooks/use_ui_settings.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import moment from 'moment-timezone'; + +import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT_TZ } from '../../common/constants'; +import { useUiSetting } from '../lib/kibana'; + +export const useDateFormat = (): string => useUiSetting(DEFAULT_DATE_FORMAT); + +export const useTimeZone = (): string => { + const timeZone = useUiSetting(DEFAULT_DATE_FORMAT_TZ); + return timeZone === 'Browser' ? moment.tz.guess() : timeZone; +}; diff --git a/x-pack/legacy/plugins/siem/public/index.ts b/x-pack/legacy/plugins/siem/public/index.ts new file mode 100644 index 0000000000000..3a396a0637ea1 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Plugin, PluginInitializerContext } from './plugin'; + +export const plugin = (context: PluginInitializerContext): Plugin => new Plugin(context); diff --git a/x-pack/legacy/plugins/siem/public/legacy.ts b/x-pack/legacy/plugins/siem/public/legacy.ts new file mode 100644 index 0000000000000..49a03c93120d4 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/legacy.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { npSetup, npStart } from 'ui/new_platform'; + +import { PluginInitializerContext } from '../../../../../src/core/public'; +import { plugin } from './'; + +const pluginInstance = plugin({} as PluginInitializerContext); + +pluginInstance.setup(npSetup.core, npSetup.plugins); +pluginInstance.start(npStart.core, npStart.plugins); diff --git a/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts b/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts index 80a42b91dbd32..9cdd4148134ad 100644 --- a/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts @@ -20,9 +20,7 @@ export const getLinks = (cache: InMemoryCache) => [ }), new HttpLink({ credentials: 'same-origin', - headers: { - 'kbn-xsrf': chrome.getXsrfToken(), - }, + headers: { 'kbn-xsrf': 'true' }, uri: `${chrome.getBasePath()}/api/siem/graphql`, }), ]; diff --git a/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts b/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts index 96d9c8330d265..012a1cfef5da2 100644 --- a/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts +++ b/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts @@ -12,7 +12,7 @@ import { useUiSetting$, withKibana, } from '../../../../../../../src/plugins/kibana_react/public'; -import { StartServices } from '../../apps/plugin'; +import { StartServices } from '../../plugin'; export type KibanaContext = KibanaReactContextValue; export interface WithKibanaProps { diff --git a/x-pack/legacy/plugins/siem/public/lib/lib.ts b/x-pack/legacy/plugins/siem/public/lib/lib.ts index 7a6cd32aa8864..e7b39d2ea50f9 100644 --- a/x-pack/legacy/plugins/siem/public/lib/lib.ts +++ b/x-pack/legacy/plugins/siem/public/lib/lib.ts @@ -24,7 +24,6 @@ export interface AppFrameworkAdapter { darkMode?: boolean; indexPattern?: string; anomalyScore?: number; - kbnVersion?: string; scaledDateFormat?: string; timezone?: string; diff --git a/x-pack/legacy/plugins/siem/public/mock/index.ts b/x-pack/legacy/plugins/siem/public/mock/index.ts index 620e266618c5c..dbf5f2e55e713 100644 --- a/x-pack/legacy/plugins/siem/public/mock/index.ts +++ b/x-pack/legacy/plugins/siem/public/mock/index.ts @@ -8,7 +8,6 @@ export * from './global_state'; export * from './header'; export * from './hook_wrapper'; export * from './index_pattern'; -export * from './kibana_config'; export * from './mock_timeline_data'; export * from './mock_detail_item'; export * from './netflow'; diff --git a/x-pack/legacy/plugins/siem/public/mock/kibana_config.ts b/x-pack/legacy/plugins/siem/public/mock/kibana_config.ts deleted file mode 100644 index 23f1f0e86dd6a..0000000000000 --- a/x-pack/legacy/plugins/siem/public/mock/kibana_config.ts +++ /dev/null @@ -1,123 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import { - DEFAULT_DATE_FORMAT, - DEFAULT_DATE_FORMAT_TZ, - DEFAULT_BYTES_FORMAT, - DEFAULT_KBN_VERSION, - DEFAULT_TIMEZONE_BROWSER, - DEFAULT_TIMEPICKER_QUICK_RANGES, -} from '../../common/constants'; - -export interface MockFrameworks { - bytesFormat: string; - dateFormat: string; - dateFormatTz: string; - timezone: string; -} - -export const getMockKibanaUiSetting = (config: MockFrameworks) => (key: string) => { - if (key === DEFAULT_DATE_FORMAT) { - return [config.dateFormat]; - } else if (key === DEFAULT_DATE_FORMAT_TZ) { - return [config.dateFormatTz]; - } else if (key === DEFAULT_BYTES_FORMAT) { - return [config.bytesFormat]; - } else if (key === DEFAULT_KBN_VERSION) { - return ['8.0.0']; - } else if (key === DEFAULT_TIMEZONE_BROWSER) { - return config && config.timezone ? [config.timezone] : ['America/New_York']; - } else if (key === DEFAULT_TIMEPICKER_QUICK_RANGES) { - return [ - [ - { - from: 'now/d', - to: 'now/d', - display: 'Today', - }, - { - from: 'now/w', - to: 'now/w', - display: 'This week', - }, - { - from: 'now-15m', - to: 'now', - display: 'Last 15 minutes', - }, - { - from: 'now-30m', - to: 'now', - display: 'Last 30 minutes', - }, - { - from: 'now-1h', - to: 'now', - display: 'Last 1 hour', - }, - { - from: 'now-24h', - to: 'now', - display: 'Last 24 hours', - }, - { - from: 'now-7d', - to: 'now', - display: 'Last 7 days', - }, - { - from: 'now-30d', - to: 'now', - display: 'Last 30 days', - }, - { - from: 'now-90d', - to: 'now', - display: 'Last 90 days', - }, - { - from: 'now-1y', - to: 'now', - display: 'Last 1 year', - }, - ], - ]; - } - return [null]; -}; - -export const mockFrameworks: Readonly> = { - bytes_short: { - bytesFormat: '0b', - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', - dateFormatTz: 'Browser', - timezone: 'America/Denver', - }, - default_browser: { - bytesFormat: '0,0.[0]b', - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', - dateFormatTz: 'Browser', - timezone: 'America/Denver', - }, - default_ET: { - bytesFormat: '0,0.[0]b', - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', - dateFormatTz: 'America/New_York', - timezone: 'America/New_York', - }, - default_MT: { - bytesFormat: '0,0.[0]b', - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', - dateFormatTz: 'America/Denver', - timezone: 'America/Denver', - }, - default_UTC: { - bytesFormat: '0,0.[0]b', - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', - dateFormatTz: 'UTC', - timezone: 'UTC', - }, -}; diff --git a/x-pack/legacy/plugins/siem/public/mock/kibana_react.ts b/x-pack/legacy/plugins/siem/public/mock/kibana_react.ts index a6b4fe664efba..7d843977d1f32 100644 --- a/x-pack/legacy/plugins/siem/public/mock/kibana_react.ts +++ b/x-pack/legacy/plugins/siem/public/mock/kibana_react.ts @@ -22,7 +22,7 @@ import { DEFAULT_TO, DEFAULT_INTERVAL_PAUSE, DEFAULT_INTERVAL_VALUE, - DEFAULT_TIMEZONE_BROWSER, + DEFAULT_BYTES_FORMAT, } from '../../common/constants'; import { defaultIndexPattern } from '../../default_index_pattern'; import { createKibanaCoreStartMock, createKibanaPluginsStartMock } from './kibana_core'; @@ -40,8 +40,8 @@ export const mockUiSettings: Record = { value: DEFAULT_INTERVAL_VALUE, }, [DEFAULT_INDEX_KEY]: defaultIndexPattern, + [DEFAULT_BYTES_FORMAT]: '0,0.[0]b', [DEFAULT_DATE_FORMAT_TZ]: 'UTC', - [DEFAULT_TIMEZONE_BROWSER]: 'America/New_York', [DEFAULT_DATE_FORMAT]: 'MMM D, YYYY @ HH:mm:ss.SSS', [DEFAULT_DARK_MODE]: false, }; @@ -87,11 +87,15 @@ export const createWithKibanaMock = () => { export const createKibanaContextProviderMock = () => { const kibana = createUseKibanaMock()(); + const uiSettings = { + ...kibana.services.uiSettings, + get: createUseUiSettingMock(), + }; // eslint-disable-next-line @typescript-eslint/no-explicit-any return ({ services, ...rest }: any) => React.createElement(KibanaContextProvider, { ...rest, - services: { ...kibana.services, ...services }, + services: { ...kibana.services, uiSettings, ...services }, }); }; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/actions.tsx index c0ed58daeca7f..d08e282a4c399 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/actions.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/actions.tsx @@ -42,18 +42,13 @@ export const updateSignalStatusAction = async ({ status, setEventsLoading, setEventsDeleted, - kbnVersion, }: UpdateSignalStatusActionProps) => { try { setEventsLoading({ eventIds: signalIds, isLoading: true }); const queryObject = query ? { query: JSON.parse(query) } : getUpdateSignalsQuery(signalIds); - await updateSignalStatus({ - query: queryObject, - status, - kbnVersion, - }); + await updateSignalStatus({ query: queryObject, status }); // TODO: Only delete those that were successfully updated from updatedRules setEventsDeleted({ eventIds: signalIds, isDeleted: true }); } catch (e) { diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/default_config.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/default_config.tsx index 6b8cd5521c533..1a7ad5822a246 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/default_config.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/default_config.tsx @@ -172,13 +172,11 @@ export const getSignalsActions = ({ setEventsDeleted, createTimeline, status, - kbnVersion, }: { setEventsLoading: ({ eventIds, isLoading }: SetEventsLoadingProps) => void; setEventsDeleted: ({ eventIds, isDeleted }: SetEventsDeletedProps) => void; createTimeline: CreateTimeline; status: 'open' | 'closed'; - kbnVersion: string; }): TimelineAction[] => [ { getAction: ({ eventId, data }: TimelineActionProps): JSX.Element => ( @@ -211,7 +209,6 @@ export const getSignalsActions = ({ status, setEventsLoading, setEventsDeleted, - kbnVersion, }) } iconType={status === FILTER_OPEN ? 'indexOpen' : 'indexClose'} diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx index f9e80334a8882..47a78482cfb6e 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/index.tsx @@ -25,8 +25,7 @@ import { SignalFilterOption, SignalsTableFilterGroup, } from './signals_filter_group'; -import { useKibana, useUiSetting$ } from '../../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../../common/constants'; +import { useKibana } from '../../../../lib/kibana'; import { defaultHeaders } from '../../../../components/timeline/body/column_headers/default_headers'; import { ColumnHeader } from '../../../../components/timeline/body/column_headers/column_header'; import { esFilters, esQuery } from '../../../../../../../../../src/plugins/data/common/es_query'; @@ -121,7 +120,6 @@ export const SignalsTableComponent = React.memo( const [showClearSelectionAction, setShowClearSelectionAction] = useState(false); const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); const [{ browserFields, indexPatterns }] = useFetchIndexPatterns([signalsIndex]); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const kibana = useKibana(); const getGlobalQuery = useCallback(() => { @@ -208,7 +206,6 @@ export const SignalsTableComponent = React.memo( status, setEventsDeleted: setEventsDeletedCallback, setEventsLoading: setEventsLoadingCallback, - kbnVersion, }); }, [ @@ -261,9 +258,8 @@ export const SignalsTableComponent = React.memo( setEventsLoading: setEventsLoadingCallback, setEventsDeleted: setEventsDeletedCallback, status: filterGroup === FILTER_OPEN ? FILTER_CLOSED : FILTER_OPEN, - kbnVersion, }), - [createTimelineCallback, filterGroup, kbnVersion] + [createTimelineCallback, filterGroup] ); const defaultIndices = useMemo(() => [signalsIndex], [signalsIndex]); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/types.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/types.ts index b02b8eb0ef976..51bea27ec6a4b 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/types.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals/types.ts @@ -31,7 +31,6 @@ export interface UpdateSignalStatusActionProps { status: 'open' | 'closed'; setEventsLoading: ({ eventIds, isLoading }: SetEventsLoadingProps) => void; setEventsDeleted: ({ eventIds, isDeleted }: SetEventsDeletedProps) => void; - kbnVersion: string; } export type SendSignalsToTimeline = () => void; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx index 4de6136e9d3de..f176109b1d7a5 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx @@ -22,13 +22,9 @@ export const editRuleAction = (rule: Rule, history: H.History) => { export const runRuleAction = () => {}; -export const duplicateRuleAction = async ( - rule: Rule, - dispatch: React.Dispatch, - kbnVersion: string -) => { +export const duplicateRuleAction = async (rule: Rule, dispatch: React.Dispatch) => { dispatch({ type: 'updateLoading', ids: [rule.id], isLoading: true }); - const duplicatedRule = await duplicateRules({ rules: [rule], kbnVersion }); + const duplicatedRule = await duplicateRules({ rules: [rule] }); dispatch({ type: 'updateLoading', ids: [rule.id], isLoading: false }); dispatch({ type: 'updateRules', rules: duplicatedRule, appendRuleId: rule.id }); }; @@ -37,25 +33,20 @@ export const exportRulesAction = async (rules: Rule[], dispatch: React.Dispatch< dispatch({ type: 'setExportPayload', exportPayload: rules }); }; -export const deleteRulesAction = async ( - ids: string[], - dispatch: React.Dispatch, - kbnVersion: string -) => { +export const deleteRulesAction = async (ids: string[], dispatch: React.Dispatch) => { dispatch({ type: 'updateLoading', ids, isLoading: true }); - const deletedRules = await deleteRules({ ids, kbnVersion }); + const deletedRules = await deleteRules({ ids }); dispatch({ type: 'deleteRules', rules: deletedRules }); }; export const enableRulesAction = async ( ids: string[], enabled: boolean, - dispatch: React.Dispatch, - kbnVersion: string + dispatch: React.Dispatch ) => { try { dispatch({ type: 'updateLoading', ids, isLoading: true }); - const updatedRules = await enableRules({ ids, enabled, kbnVersion }); + const updatedRules = await enableRules({ ids, enabled }); dispatch({ type: 'updateRules', rules: updatedRules }); } catch { // TODO Add error toast support to actions (and @throw jsdoc to api calls) diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx index c8fb9d98fde6a..72d38454ad9bc 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx @@ -14,8 +14,7 @@ import { deleteRulesAction, enableRulesAction, exportRulesAction } from './actio export const getBatchItems = ( selectedState: TableData[], dispatch: React.Dispatch, - closePopover: () => void, - kbnVersion: string + closePopover: () => void ) => { const containsEnabled = selectedState.some(v => v.activate); const containsDisabled = selectedState.some(v => !v.activate); @@ -29,7 +28,7 @@ export const getBatchItems = ( onClick={async () => { closePopover(); const deactivatedIds = selectedState.filter(s => !s.activate).map(s => s.id); - await enableRulesAction(deactivatedIds, true, dispatch, kbnVersion); + await enableRulesAction(deactivatedIds, true, dispatch); }} > {i18n.BATCH_ACTION_ACTIVATE_SELECTED} @@ -41,7 +40,7 @@ export const getBatchItems = ( onClick={async () => { closePopover(); const activatedIds = selectedState.filter(s => s.activate).map(s => s.id); - await enableRulesAction(activatedIds, false, dispatch, kbnVersion); + await enableRulesAction(activatedIds, false, dispatch); }} > {i18n.BATCH_ACTION_DEACTIVATE_SELECTED} @@ -78,8 +77,7 @@ export const getBatchItems = ( closePopover(); await deleteRulesAction( selectedState.map(({ sourceRule: { id } }) => id), - dispatch, - kbnVersion + dispatch ); }} > diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx index 1fcd8c7da8256..42c4bb1d0ef95 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx @@ -33,7 +33,7 @@ import * as i18n from '../translations'; import { PreferenceFormattedDate } from '../../../../components/formatted_date'; import { RuleSwitch } from '../components/rule_switch'; -const getActions = (dispatch: React.Dispatch, kbnVersion: string, history: H.History) => [ +const getActions = (dispatch: React.Dispatch, history: H.History) => [ { description: i18n.EDIT_RULE_SETTINGS, icon: 'visControls', @@ -52,7 +52,7 @@ const getActions = (dispatch: React.Dispatch, kbnVersion: string, histor description: i18n.DUPLICATE_RULE, icon: 'copy', name: i18n.DUPLICATE_RULE, - onClick: (rowItem: TableData) => duplicateRuleAction(rowItem.sourceRule, dispatch, kbnVersion), + onClick: (rowItem: TableData) => duplicateRuleAction(rowItem.sourceRule, dispatch), }, { description: i18n.EXPORT_RULE, @@ -64,14 +64,13 @@ const getActions = (dispatch: React.Dispatch, kbnVersion: string, histor description: i18n.DELETE_RULE, icon: 'trash', name: i18n.DELETE_RULE, - onClick: (rowItem: TableData) => deleteRulesAction([rowItem.id], dispatch, kbnVersion), + onClick: (rowItem: TableData) => deleteRulesAction([rowItem.id], dispatch), }, ]; // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes? export const getColumns = ( dispatch: React.Dispatch, - kbnVersion: string, history: H.History ): Array | EuiTableActionsColumnType> => [ { @@ -173,7 +172,7 @@ export const getColumns = ( width: '85px', }, { - actions: getActions(dispatch, kbnVersion, history), + actions: getActions(dispatch, history), width: '40px', } as EuiTableActionsColumnType, ]; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx index 442360bbf1484..060f8baccc3b7 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx @@ -31,8 +31,6 @@ import { getBatchItems } from './batch_actions'; import { EuiBasicTableOnChange, TableData } from '../types'; import { allRulesReducer, State } from './reducer'; import * as i18n from '../translations'; -import { useUiSetting$ } from '../../../../lib/kibana'; -import { DEFAULT_KBN_VERSION } from '../../../../../common/constants'; import { JSONDownloader } from '../components/json_downloader'; import { useStateToaster } from '../../../../components/toasters'; @@ -78,16 +76,13 @@ export const AllRules = React.memo<{ importCompleteToggle: boolean }>(importComp const history = useHistory(); const [isInitialLoad, setIsInitialLoad] = useState(true); const [isLoadingRules, rulesData] = useRules(pagination, filterOptions, refreshToggle); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); const getBatchItemsPopoverContent = useCallback( (closePopover: () => void) => ( - + ), - [selectedItems, dispatch, kbnVersion] + [selectedItems, dispatch] ); useEffect(() => { @@ -185,7 +180,7 @@ export const AllRules = React.memo<{ importCompleteToggle: boolean }>(importComp { const [selectedFiles, setSelectedFiles] = useState(null); const [isImporting, setIsImporting] = useState(false); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const [, dispatchToaster] = useStateToaster(); const cleanupAndCloseModal = () => { @@ -89,7 +86,7 @@ export const ImportRuleModalComponent = ({ }, identity) ); - const duplicatedRules = await duplicateRules({ rules: decodedRules, kbnVersion }); + const duplicatedRules = await duplicateRules({ rules: decodedRules }); importComplete(); cleanupAndCloseModal(); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.test.tsx index 4e7ff6fb3a886..3fc29c472e4d7 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.test.tsx @@ -9,7 +9,6 @@ import toJson from 'enzyme-to-json'; import React from 'react'; import { RuleSwitchComponent } from './index'; -jest.mock('../../../../../lib/kibana'); describe('RuleSwitch', () => { test('renders correctly against snapshot', () => { diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.tsx index 54f0fc453830e..a1fa4770a41ac 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_switch/index.tsx @@ -15,9 +15,7 @@ import { isEmpty } from 'lodash/fp'; import styled from 'styled-components'; import React, { useCallback, useState, useEffect } from 'react'; -import { DEFAULT_KBN_VERSION } from '../../../../../../common/constants'; import { enableRules } from '../../../../../containers/detection_engine/rules'; -import { useUiSetting$ } from '../../../../../lib/kibana'; import { enableRulesAction } from '../../all/actions'; import { Action } from '../../all/reducer'; @@ -50,19 +48,17 @@ export const RuleSwitchComponent = ({ }: RuleSwitchProps) => { const [myIsLoading, setMyIsLoading] = useState(false); const [myEnabled, setMyEnabled] = useState(enabled ?? false); - const [kbnVersion] = useUiSetting$(DEFAULT_KBN_VERSION); const onRuleStateChange = useCallback( async (event: EuiSwitchEvent) => { setMyIsLoading(true); if (dispatch != null) { - await enableRulesAction([id], event.target.checked!, dispatch, kbnVersion); + await enableRulesAction([id], event.target.checked!, dispatch); } else { try { const updatedRules = await enableRules({ ids: [id], enabled: event.target.checked!, - kbnVersion, }); setMyEnabled(updatedRules[0].enabled); } catch { @@ -71,7 +67,7 @@ export const RuleSwitchComponent = ({ } setMyIsLoading(false); }, - [dispatch, id, kbnVersion] + [dispatch, id] ); useEffect(() => { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx index 092c2463419d1..aafeea6465fb3 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx @@ -16,8 +16,6 @@ import { hostDetailsPagePath } from '../types'; import { type } from './utils'; import { useMountAppended } from '../../../utils/use_mount_appended'; -jest.mock('../../../lib/kibana'); - jest.mock('../../../containers/source', () => ({ indicesExistOrDataTemporarilyUnavailable: () => true, WithSource: ({ diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx index 729777745d689..f7e0863465f9a 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx @@ -20,8 +20,6 @@ import { SiemNavigation } from '../../components/navigation'; import { HostsComponentProps } from './types'; import { Hosts } from './hosts'; -jest.mock('../../lib/kibana'); - // Test will fail because we will to need to mock some core services to make the test work // For now let's forget about SiemSearchBar and QueryBar jest.mock('../../components/search_bar', () => ({ diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx index bde41ac02bc0a..347f15ed0a849 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx @@ -28,8 +28,6 @@ const pop: Action = 'POP'; type GlobalWithFetch = NodeJS.Global & { fetch: jest.Mock }; -jest.mock('../../../lib/kibana'); - // Test will fail because we will to need to mock some core services to make the test work // For now let's forget about SiemSearchBar and QueryBar jest.mock('../../../components/search_bar', () => ({ diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.test.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.test.tsx index 9c87d29cd1056..26b2bd9dace48 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network.test.tsx @@ -16,8 +16,6 @@ import { mocksSource } from '../../containers/source/mock'; import { TestProviders } from '../../mock'; import { Network } from './network'; -jest.mock('../../lib/kibana'); - // Test will fail because we will to need to mock some core services to make the test work // For now let's forget about SiemSearchBar and QueryBar jest.mock('../../components/search_bar', () => ({ diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/overview.test.tsx b/x-pack/legacy/plugins/siem/public/pages/overview/overview.test.tsx index 7f9f4b1eb70b0..eff61bf6a9710 100644 --- a/x-pack/legacy/plugins/siem/public/pages/overview/overview.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/overview/overview.test.tsx @@ -14,8 +14,6 @@ import { TestProviders } from '../../mock'; import { mocksSource } from '../../containers/source/mock'; import { Overview } from './index'; -jest.mock('../../lib/kibana'); - let localSource: Array<{ request: {}; result: { diff --git a/x-pack/legacy/plugins/siem/public/plugin.tsx b/x-pack/legacy/plugins/siem/public/plugin.tsx new file mode 100644 index 0000000000000..44624f497a91b --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/plugin.tsx @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + AppMountParameters, + CoreSetup, + CoreStart, + PluginInitializerContext, + Plugin as IPlugin, +} from '../../../../../src/core/public'; +import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; +import { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; +import { IEmbeddableStart } from '../../../../../src/plugins/embeddable/public'; +import { Start as InspectorStart } from '../../../../../src/plugins/inspector/public'; +import { IUiActionsStart } from '../../../../../src/plugins/ui_actions/public'; + +export { AppMountParameters, CoreSetup, CoreStart, PluginInitializerContext }; + +export interface SetupPlugins { + home: HomePublicPluginSetup; +} +export interface StartPlugins { + data: DataPublicPluginStart; + embeddable: IEmbeddableStart; + inspector: InspectorStart; + uiActions: IUiActionsStart; +} +export type StartServices = CoreStart & StartPlugins; + +export type Setup = ReturnType; +export type Start = ReturnType; + +export class Plugin implements IPlugin { + public id = 'siem'; + public name = 'SIEM'; + constructor( + // @ts-ignore this is added to satisfy the New Platform typing constraint, + // but we're not leveraging any of its functionality yet. + private readonly initializerContext: PluginInitializerContext + ) {} + + public setup(core: CoreSetup, plugins: SetupPlugins) { + core.application.register({ + id: this.id, + title: this.name, + async mount(context, params) { + const [coreStart, pluginsStart] = await core.getStartServices(); + const { renderApp } = await import('./app'); + + return renderApp(coreStart, pluginsStart as StartPlugins, params); + }, + }); + + return {}; + } + + public start(core: CoreStart, plugins: StartPlugins) { + return {}; + } + + public stop() { + return {}; + } +} diff --git a/x-pack/legacy/plugins/siem/public/register_feature.ts b/x-pack/legacy/plugins/siem/public/register_feature.ts index 36c4e28dbd874..ca7a22408b6ff 100644 --- a/x-pack/legacy/plugins/siem/public/register_feature.ts +++ b/x-pack/legacy/plugins/siem/public/register_feature.ts @@ -4,19 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - FeatureCatalogueCategory, - FeatureCatalogueRegistryProvider, -} from 'ui/registry/feature_catalogue'; +import { npSetup } from 'ui/new_platform'; +import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public'; +import { APP_ID } from '../common/constants'; -const APP_ID = 'siem'; - -FeatureCatalogueRegistryProvider.register(() => ({ - id: 'siem', +// TODO(rylnd): move this into Plugin.setup once we're on NP +npSetup.plugins.home.featureCatalogue.register({ + id: APP_ID, title: 'SIEM', description: 'Explore security metrics and logs for events and alerts', icon: 'securityAnalyticsApp', path: `/app/${APP_ID}`, showOnHomePage: true, category: FeatureCatalogueCategory.DATA, -})); +});