From 9828ff244e213545fcb66a7e8edfd59b6ff903f0 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Fri, 14 May 2021 16:56:08 -0600 Subject: [PATCH] [Security Solutions] Removes deprecation and more copied code between security solutions and lists plugin (#100150) ## Summary * Removes deprecations * Removes duplicated code ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- x-pack/plugins/lists/common/shared_exports.ts | 39 --- .../autocomplete/field_value_match.tsx | 2 +- .../autocomplete/field_value_match_any.tsx | 2 +- .../components/autocomplete/helpers.ts | 3 +- .../use_field_value_autocomplete.test.ts | 2 +- .../hooks/use_field_value_autocomplete.ts | 2 +- .../components/autocomplete/operators.ts | 6 +- .../components/autocomplete/types.ts | 6 +- .../builder/entry_renderer.stories.tsx | 5 +- .../components/builder/entry_renderer.tsx | 8 +- .../builder/exception_item_renderer.tsx | 3 +- .../builder/exception_items_renderer.tsx | 16 +- .../components/builder/helpers.test.ts | 330 ++++++++++++++++- .../exceptions/components/builder/helpers.ts | 24 +- .../exceptions/components/builder/reducer.ts | 4 +- .../exceptions/components/builder/types.ts | 16 +- .../lists/public/exceptions/transforms.ts | 3 +- x-pack/plugins/lists/public/shared_exports.ts | 14 +- .../detection_engine/schemas/types/lists.ts | 2 +- .../common/detection_engine/utils.test.ts | 3 +- .../common/detection_engine/utils.ts | 9 +- .../common/shared_imports.ts | 33 -- .../autocomplete/field_value_match.tsx | 3 +- .../autocomplete/field_value_match_any.tsx | 3 +- .../common/components/autocomplete/helpers.ts | 3 +- .../use_field_value_autocomplete.test.ts | 2 +- .../hooks/use_field_value_autocomplete.ts | 2 +- .../components/autocomplete/operators.ts | 5 +- .../common/components/autocomplete/types.ts | 5 +- .../exceptions/add_exception_comments.tsx | 2 +- .../add_exception_modal/index.test.tsx | 5 +- .../exceptions/add_exception_modal/index.tsx | 3 +- .../exceptions/edit_exception_modal/index.tsx | 3 +- .../components/exceptions/helpers.test.tsx | 331 +----------------- .../common/components/exceptions/helpers.tsx | 194 +--------- .../common/components/exceptions/types.ts | 19 +- .../exceptions/use_add_exception.test.tsx | 9 +- ...tch_or_create_rule_exception_list.test.tsx | 5 +- .../exceptions_viewer_header.stories.tsx | 2 +- .../viewer/exceptions_viewer_header.test.tsx | 3 +- .../viewer/exceptions_viewer_header.tsx | 2 +- .../components/exceptions/viewer/helpers.tsx | 10 +- .../exceptions/viewer/index.test.tsx | 8 +- .../components/exceptions/viewer/index.tsx | 3 +- .../components/exceptions/viewer/reducer.ts | 2 +- .../timeline_actions/alert_context_menu.tsx | 2 +- .../value_lists_management_modal/form.tsx | 4 +- .../rules/all/exceptions/columns.tsx | 2 +- .../rules/all/exceptions/exceptions_table.tsx | 2 +- .../detection_engine/rules/create/helpers.ts | 3 +- .../detection_engine/rules/details/index.tsx | 4 +- .../pages/event_filters/constants.ts | 3 +- .../public/shared_imports.ts | 10 +- .../endpoint/routes/trusted_apps/mapping.ts | 12 +- .../create_field_and_set_tuples.test.ts | 2 +- .../filters/create_field_and_set_tuples.ts | 2 +- 56 files changed, 501 insertions(+), 701 deletions(-) diff --git a/x-pack/plugins/lists/common/shared_exports.ts b/x-pack/plugins/lists/common/shared_exports.ts index bc9d0ca8d7b94..f00afb7ac810d 100644 --- a/x-pack/plugins/lists/common/shared_exports.ts +++ b/x-pack/plugins/lists/common/shared_exports.ts @@ -5,45 +5,6 @@ * 2.0. */ -// TODO: We should remove these and instead directly import them in the security_solution project. This is to get my PR across the line without too many conflicts. -export { - CommentsArray, - Comment, - CreateComment, - CreateCommentsArray, - Entry, - EntryExists, - EntryMatch, - EntryMatchAny, - EntryMatchWildcard, - EntryNested, - EntryList, - EntriesArray, - NamespaceType, - NestedEntriesArray, - ListOperator as Operator, - ListOperatorEnum as OperatorEnum, - ListOperatorTypeEnum as OperatorTypeEnum, - listOperator as operator, - ExceptionListTypeEnum, - ExceptionListType, - comment, - exceptionListType, - entry, - entriesNested, - nestedEntryItem, - entriesMatch, - entriesMatchAny, - entriesMatchWildcard, - entriesExists, - entriesList, - namespaceType, - osType, - osTypeArray, - OsTypeArray, - Type, -} from '@kbn/securitysolution-io-ts-list-types'; - export { ListSchema, ExceptionListSchema, diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match.tsx b/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match.tsx index a0994871808d1..c1776280842c6 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match.tsx @@ -14,8 +14,8 @@ import { EuiSuperSelect, } from '@elastic/eui'; import { uniq } from 'lodash'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; -import { OperatorTypeEnum } from '../../../../common'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match_any.tsx b/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match_any.tsx index 08958f6d99aab..82347f6212442 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match_any.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/field_value_match_any.tsx @@ -8,8 +8,8 @@ import React, { useCallback, useMemo, useState } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { uniq } from 'lodash'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; -import { OperatorTypeEnum } from '../../../../common'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/helpers.ts b/x-pack/plugins/lists/public/exceptions/components/autocomplete/helpers.ts index 4f25bec3b38dc..b982193d1d349 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/helpers.ts +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/helpers.ts @@ -7,8 +7,9 @@ import dateMath from '@elastic/datemath'; import { EuiComboBoxOptionOption } from '@elastic/eui'; +import type { Type } from '@kbn/securitysolution-io-ts-list-types'; -import { ListSchema, Type } from '../../../../common'; +import type { ListSchema } from '../../../../common'; import { IFieldType } from '../../../../../../../src/plugins/data/common'; import { diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.test.ts b/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.test.ts index 4e3fb2179d786..0335ffa55d2a2 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.test.ts +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.test.ts @@ -6,10 +6,10 @@ */ import { act, renderHook } from '@testing-library/react-hooks'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { stubIndexPatternWithFields } from '../../../../../../../../src/plugins/data/common/index_patterns/index_pattern.stub'; import { getField } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; -import { OperatorTypeEnum } from '../../../../../common'; import { dataPluginMock } from '../../../../../../../../src/plugins/data/public/mocks'; import { diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.ts b/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.ts index 6c6198ac55a0f..674bb5e5537d9 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.ts +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/hooks/use_field_value_autocomplete.ts @@ -7,10 +7,10 @@ import { useEffect, useRef, useState } from 'react'; import { debounce } from 'lodash'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { AutocompleteStart } from '../../../../../../../../src/plugins/data/public'; import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -import { OperatorTypeEnum } from '../../../../../common'; interface FuncArgs { fieldSelected: IFieldType | undefined; diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/operators.ts b/x-pack/plugins/lists/public/exceptions/components/autocomplete/operators.ts index 551dfcb61e3ad..83a424d72ec5f 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/operators.ts +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/operators.ts @@ -6,8 +6,10 @@ */ import { i18n } from '@kbn/i18n'; - -import { OperatorEnum, OperatorTypeEnum } from '../../../../common'; +import { + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; import { OperatorOption } from './types'; diff --git a/x-pack/plugins/lists/public/exceptions/components/autocomplete/types.ts b/x-pack/plugins/lists/public/exceptions/components/autocomplete/types.ts index 8ea3e8d927d68..76d5b7758007b 100644 --- a/x-pack/plugins/lists/public/exceptions/components/autocomplete/types.ts +++ b/x-pack/plugins/lists/public/exceptions/components/autocomplete/types.ts @@ -6,8 +6,10 @@ */ import { EuiComboBoxOptionOption } from '@elastic/eui'; - -import { OperatorEnum, OperatorTypeEnum } from '../../../../common'; +import type { + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; export interface GetGenericComboBoxPropsReturn { comboOptions: EuiComboBoxOptionOption[]; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx index 5b3730a6deb93..dd67381c30934 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx @@ -9,8 +9,11 @@ import { Story } from '@storybook/react'; import { action } from '@storybook/addon-actions'; import React from 'react'; import { HttpStart } from 'kibana/public'; +import { + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; -import { OperatorEnum, OperatorTypeEnum } from '../../../../common'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx index 0ece28d409bd5..09863660e98af 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx @@ -8,7 +8,11 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; import styled from 'styled-components'; -import { OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; +import { + ExceptionListType, + ListOperatorTypeEnum as OperatorTypeEnum, + OsTypeArray, +} from '@kbn/securitysolution-io-ts-list-types'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; @@ -21,7 +25,7 @@ import { AutocompleteFieldExistsComponent } from '../autocomplete/field_value_ex import { AutocompleteFieldMatchComponent } from '../autocomplete/field_value_match'; import { AutocompleteFieldMatchAnyComponent } from '../autocomplete/field_value_match_any'; import { AutocompleteFieldListsComponent } from '../autocomplete/field_value_lists'; -import { ExceptionListType, ListSchema, OperatorTypeEnum } from '../../../../common'; +import { ListSchema } from '../../../../common'; import { getEmptyValue } from '../../../common/empty_value'; import { diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx index 94c3bff8f4cf9..e10cd2934328f 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx @@ -10,9 +10,8 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; import { HttpStart } from 'kibana/public'; import { AutocompleteStart } from 'src/plugins/data/public'; -import { OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; +import { ExceptionListType, OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; -import { ExceptionListType } from '../../../../common'; import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { BuilderEntry, ExceptionsBuilderExceptionItem, FormattedBuilderEntry } from './types'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx index 4ec152e155e39..f771969a92025 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx @@ -10,19 +10,21 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; import { HttpStart } from 'kibana/public'; import { addIdToItem } from '@kbn/securitysolution-utils'; -import { OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; - -import { AutocompleteStart, IIndexPattern } from '../../../../../../../src/plugins/data/public'; import { - CreateExceptionListItemSchema, - ExceptionListItemSchema, ExceptionListType, NamespaceType, - OperatorEnum, - OperatorTypeEnum, + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, + OsTypeArray, entriesNested, +} from '@kbn/securitysolution-io-ts-list-types'; + +import { + CreateExceptionListItemSchema, + ExceptionListItemSchema, exceptionListItemSchema, } from '../../../../common'; +import { AutocompleteStart, IIndexPattern } from '../../../../../../../src/plugins/data/public'; import { AndOrBadge } from '../and_or_badge'; import { CreateExceptionListItemBuilderSchema, ExceptionsBuilderExceptionItem } from './types'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts index 1e74193299e56..dbfeaa4a258ca 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts @@ -5,6 +5,18 @@ * 2.0. */ +import { + EntryExists, + EntryList, + EntryMatch, + EntryMatchAny, + EntryNested, + ExceptionListType, + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; + +import { CreateExceptionListItemSchema, ExceptionListItemSchema } from '../../../../common'; import { ENTRIES_WITH_IDS } from '../../../../common/constants.mock'; import { getEntryExistsMock } from '../../../../common/schemas/types/entry_exists.mock'; import { getExceptionListItemSchemaMock } from '../../../../common/schemas/response/exception_list_item_schema.mock'; @@ -23,25 +35,23 @@ import { doesNotExistOperator, existsOperator, isInListOperator, + isNotInListOperator, isNotOneOfOperator, isNotOperator, isOneOfOperator, isOperator, } from '../autocomplete/operators'; -import { - EntryExists, - EntryList, - EntryMatch, - EntryMatchAny, - EntryNested, - ExceptionListType, - OperatorEnum, - OperatorTypeEnum, -} from '../../../../common'; import { OperatorOption } from '../autocomplete/types'; +import { getEntryListMock } from '../../../../common/schemas/types/entry_list.mock'; -import { BuilderEntry, ExceptionsBuilderExceptionItem, FormattedBuilderEntry } from './types'; import { + BuilderEntry, + EmptyEntry, + ExceptionsBuilderExceptionItem, + FormattedBuilderEntry, +} from './types'; +import { + filterExceptionItems, getCorrespondingKeywordField, getEntryFromOperator, getEntryOnFieldChange, @@ -49,10 +59,14 @@ import { getEntryOnMatchAnyChange, getEntryOnMatchChange, getEntryOnOperatorChange, + getEntryValue, + getExceptionOperatorSelect, getFilteredIndexPatterns, getFormattedBuilderEntries, getFormattedBuilderEntry, + getNewExceptionItem, getOperatorOptions, + getOperatorType, getUpdatedEntriesOnDelete, isEntryNested, } from './helpers'; @@ -1426,4 +1440,298 @@ describe('Exception builder helpers', () => { expect(output).toEqual(undefined); }); }); + + describe('#getOperatorType', () => { + test('returns operator type "match" if entry.type is "match"', () => { + const payload = getEntryMatchMock(); + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorTypeEnum.MATCH); + }); + + test('returns operator type "match_any" if entry.type is "match_any"', () => { + const payload = getEntryMatchAnyMock(); + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorTypeEnum.MATCH_ANY); + }); + + test('returns operator type "list" if entry.type is "list"', () => { + const payload = getEntryListMock(); + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorTypeEnum.LIST); + }); + + test('returns operator type "exists" if entry.type is "exists"', () => { + const payload = getEntryExistsMock(); + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorTypeEnum.EXISTS); + }); + }); + + describe('#getExceptionOperatorSelect', () => { + test('it returns "isOperator" when "operator" is "included" and operator type is "match"', () => { + const payload = getEntryMatchMock(); + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isOperator); + }); + + test('it returns "isNotOperator" when "operator" is "excluded" and operator type is "match"', () => { + const payload = getEntryMatchMock(); + payload.operator = 'excluded'; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isNotOperator); + }); + + test('it returns "isOneOfOperator" when "operator" is "included" and operator type is "match_any"', () => { + const payload = getEntryMatchAnyMock(); + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isOneOfOperator); + }); + + test('it returns "isNotOneOfOperator" when "operator" is "excluded" and operator type is "match_any"', () => { + const payload = getEntryMatchAnyMock(); + payload.operator = 'excluded'; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isNotOneOfOperator); + }); + + test('it returns "existsOperator" when "operator" is "included" and no operator type is provided', () => { + const payload = getEntryExistsMock(); + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(existsOperator); + }); + + test('it returns "doesNotExistsOperator" when "operator" is "excluded" and no operator type is provided', () => { + const payload = getEntryExistsMock(); + payload.operator = 'excluded'; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(doesNotExistOperator); + }); + + test('it returns "isInList" when "operator" is "included" and operator type is "list"', () => { + const payload = getEntryListMock(); + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isInListOperator); + }); + + test('it returns "isNotInList" when "operator" is "excluded" and operator type is "list"', () => { + const payload = getEntryListMock(); + payload.operator = 'excluded'; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isNotInListOperator); + }); + }); + + describe('#filterExceptionItems', () => { + // Please see `x-pack/plugins/lists/public/exceptions/transforms.ts` doc notes + // for context around the temporary `id` + test('it correctly validates entries that include a temporary `id`', () => { + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { ...getExceptionListItemSchemaMock(), entries: ENTRIES_WITH_IDS }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock(), entries: ENTRIES_WITH_IDS }]); + }); + + test('it removes entry items with "value" of "undefined"', () => { + const { entries, ...rest } = getExceptionListItemSchemaMock(); + const mockEmptyException: EmptyEntry = { + field: 'host.name', + id: '123', + operator: OperatorEnum.INCLUDED, + type: OperatorTypeEnum.MATCH, + value: undefined, + }; + const exceptions = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(exceptions).toEqual([getExceptionListItemSchemaMock()]); + }); + + test('it removes "match" entry items with "value" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EmptyEntry = { + field: 'host.name', + id: '123', + operator: OperatorEnum.INCLUDED, + type: OperatorTypeEnum.MATCH, + value: '', + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes "match" entry items with "field" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EmptyEntry = { + field: '', + id: '123', + operator: OperatorEnum.INCLUDED, + type: OperatorTypeEnum.MATCH, + value: 'some value', + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes "match_any" entry items with "field" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EmptyEntry = { + field: '', + id: '123', + operator: OperatorEnum.INCLUDED, + type: OperatorTypeEnum.MATCH_ANY, + value: ['some value'], + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes "nested" entry items with "field" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EntryNested = { + entries: [getEntryMatchMock()], + field: '', + type: OperatorTypeEnum.NESTED, + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes the "nested" entry entries with "value" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EntryNested = { + entries: [getEntryMatchMock(), { ...getEntryMatchMock(), value: '' }], + field: 'host.name', + type: OperatorTypeEnum.NESTED, + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([ + { + ...getExceptionListItemSchemaMock(), + entries: [ + ...getExceptionListItemSchemaMock().entries, + { ...mockEmptyException, entries: [getEntryMatchMock()] }, + ], + }, + ]); + }); + + test('it removes the "nested" entry item if all its entries are invalid', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EntryNested = { + entries: [{ ...getEntryMatchMock(), value: '' }], + field: 'host.name', + type: OperatorTypeEnum.NESTED, + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes `temporaryId` from items', () => { + const { meta, ...rest } = getNewExceptionItem({ + listId: '123', + namespaceType: 'single', + ruleName: 'rule name', + }); + const exceptions = filterExceptionItems([{ ...rest, meta }]); + + expect(exceptions).toEqual([{ ...rest, entries: [], meta: undefined }]); + }); + }); + + describe('#getEntryValue', () => { + it('returns "match" entry value', () => { + const payload = getEntryMatchMock(); + const result = getEntryValue(payload); + const expected = 'some host name'; + expect(result).toEqual(expected); + }); + + it('returns "match any" entry values', () => { + const payload = getEntryMatchAnyMock(); + const result = getEntryValue(payload); + const expected = ['some host name']; + expect(result).toEqual(expected); + }); + + it('returns "exists" entry value', () => { + const payload = getEntryExistsMock(); + const result = getEntryValue(payload); + const expected = undefined; + expect(result).toEqual(expected); + }); + + it('returns "list" entry value', () => { + const payload = getEntryListMock(); + const result = getEntryValue(payload); + const expected = 'some-list-id'; + expect(result).toEqual(expected); + }); + }); }); diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.ts b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.ts index 18d607d6807fc..6cd9dec0dc7a1 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.ts @@ -8,27 +8,29 @@ import uuid from 'uuid'; import { addIdToItem, removeIdFromItem } from '@kbn/securitysolution-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; -import { OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; - -import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/public'; import { - CreateExceptionListItemSchema, EntriesArray, Entry, EntryNested, - ExceptionListItemSchema, ExceptionListType, - ListSchema, NamespaceType, - OperatorEnum, - OperatorTypeEnum, - createExceptionListItemSchema, + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, + OsTypeArray, entriesList, entriesNested, entry, - exceptionListItemSchema, nestedEntryItem, +} from '@kbn/securitysolution-io-ts-list-types'; + +import { + CreateExceptionListItemSchema, + ExceptionListItemSchema, + ListSchema, + createExceptionListItemSchema, + exceptionListItemSchema, } from '../../../../common'; +import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/public'; import { EXCEPTION_OPERATORS, EXCEPTION_OPERATORS_SANS_LISTS, @@ -96,7 +98,7 @@ export const filterExceptionItems = ( return [...acc, item]; } else if (createExceptionListItemSchema.is(item)) { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { meta: _, ...rest } = item; + const { meta, ...rest } = item; const itemSansMetaId: CreateExceptionListItemSchema = { ...rest, meta: undefined }; return [...acc, itemSansMetaId]; } else { diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/reducer.ts b/x-pack/plugins/lists/public/exceptions/components/builder/reducer.ts index 92df2fd3793de..0e8a5fadd3b1a 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/reducer.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/reducer.ts @@ -5,7 +5,9 @@ * 2.0. */ -import { ExceptionListItemSchema, OperatorTypeEnum } from '../../../../common'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; + +import { ExceptionListItemSchema } from '../../../../common'; import { ExceptionsBuilderExceptionItem } from './types'; import { getDefaultEmptyEntry } from './helpers'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/types.ts b/x-pack/plugins/lists/public/exceptions/components/builder/types.ts index 800f1445217b9..5cf4238ab5e0c 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/types.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/types.ts @@ -5,20 +5,20 @@ * 2.0. */ -import { IFieldType } from '../../../../../../../src/plugins/data/common'; -import { OperatorOption } from '../autocomplete/types'; -import { - CreateExceptionListItemSchema, +import type { Entry, EntryExists, EntryMatch, EntryMatchAny, EntryMatchWildcard, EntryNested, - ExceptionListItemSchema, - OperatorEnum, - OperatorTypeEnum, -} from '../../../../common'; + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; + +import type { CreateExceptionListItemSchema, ExceptionListItemSchema } from '../../../../common'; +import { IFieldType } from '../../../../../../../src/plugins/data/common'; +import { OperatorOption } from '../autocomplete/types'; export interface FormattedBuilderEntry { id: string; diff --git a/x-pack/plugins/lists/public/exceptions/transforms.ts b/x-pack/plugins/lists/public/exceptions/transforms.ts index 50ce1b6e33a4b..564ba1a699f98 100644 --- a/x-pack/plugins/lists/public/exceptions/transforms.ts +++ b/x-pack/plugins/lists/public/exceptions/transforms.ts @@ -7,11 +7,10 @@ import { flow } from 'fp-ts/lib/function'; import { addIdToItem, removeIdFromItem } from '@kbn/securitysolution-utils'; +import type { EntriesArray, Entry } from '@kbn/securitysolution-io-ts-list-types'; import type { CreateExceptionListItemSchema, - EntriesArray, - Entry, ExceptionListItemSchema, UpdateExceptionListItemSchema, } from '../../common'; diff --git a/x-pack/plugins/lists/public/shared_exports.ts b/x-pack/plugins/lists/public/shared_exports.ts index 2032a44a8fd33..6d14c6b541904 100644 --- a/x-pack/plugins/lists/public/shared_exports.ts +++ b/x-pack/plugins/lists/public/shared_exports.ts @@ -7,11 +7,8 @@ // Exports to be shared with plugins export { withOptionalSignal } from './common/with_optional_signal'; -export { useIsMounted } from './common/hooks/use_is_mounted'; export { useAsync } from './common/hooks/use_async'; export { useApi } from './exceptions/hooks/use_api'; -export { usePersistExceptionItem } from './exceptions/hooks/persist_exception_item'; -export { usePersistExceptionList } from './exceptions/hooks/persist_exception_list'; export { useExceptionListItems } from './exceptions/hooks/use_exception_list_items'; export { useExceptionLists } from './exceptions/hooks/use_exception_lists'; export { useFindLists } from './lists/hooks/use_find_lists'; @@ -24,13 +21,18 @@ export { useReadListIndex } from './lists/hooks/use_read_list_index'; export { useCreateListIndex } from './lists/hooks/use_create_list_index'; export { useReadListPrivileges } from './lists/hooks/use_read_list_privileges'; export { - addExceptionListItem, - updateExceptionListItem, + getEntryValue, + getExceptionOperatorSelect, + getOperatorType, + getNewExceptionItem, + addIdToEntries, +} from './exceptions/components/builder/helpers'; +export { fetchExceptionListById, addExceptionList, addEndpointExceptionList, } from './exceptions/api'; -export { +export type { ExceptionList, ExceptionListFilter, ExceptionListIdentifiers, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts index 79fd264808138..e2c3ee88f6a65 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; -import { exceptionListType, namespaceType } from '../../../shared_imports'; +import { exceptionListType, namespaceType } from '@kbn/securitysolution-io-ts-list-types'; import { NonEmptyString } from './non_empty_string'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/utils.test.ts b/x-pack/plugins/security_solution/common/detection_engine/utils.test.ts index c477036a07d85..1e0f7e087a5b3 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/utils.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/utils.test.ts @@ -13,7 +13,8 @@ import { normalizeMachineLearningJobIds, normalizeThresholdField, } from './utils'; -import { EntriesArray } from '../shared_imports'; + +import type { EntriesArray } from '@kbn/securitysolution-io-ts-list-types'; describe('#hasLargeValueList', () => { test('it returns false if empty array', () => { diff --git a/x-pack/plugins/security_solution/common/detection_engine/utils.ts b/x-pack/plugins/security_solution/common/detection_engine/utils.ts index a8e0ffcccef82..611d23fd1ce22 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/utils.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/utils.ts @@ -7,11 +7,10 @@ import { isEmpty } from 'lodash'; -import { - CreateExceptionListItemSchema, - EntriesArray, - ExceptionListItemSchema, -} from '../shared_imports'; +import type { EntriesArray } from '@kbn/securitysolution-io-ts-list-types'; + +import { CreateExceptionListItemSchema, ExceptionListItemSchema } from '../shared_imports'; + import { Type, JobStatus, Threshold, ThresholdNormalized } from './schemas/common/schemas'; export const hasLargeValueItem = ( diff --git a/x-pack/plugins/security_solution/common/shared_imports.ts b/x-pack/plugins/security_solution/common/shared_imports.ts index e987775a8e768..a6bad0347e641 100644 --- a/x-pack/plugins/security_solution/common/shared_imports.ts +++ b/x-pack/plugins/security_solution/common/shared_imports.ts @@ -7,44 +7,14 @@ export { ListSchema, - CommentsArray, - CreateCommentsArray, - Comment, - CreateComment, ExceptionListSchema, ExceptionListItemSchema, CreateExceptionListSchema, CreateExceptionListItemSchema, UpdateExceptionListItemSchema, - Entry, - EntryExists, - EntryMatch, - EntryMatchAny, - EntryMatchWildcard, - EntryNested, - EntryList, - EntriesArray, - NamespaceType, - Operator, - OperatorEnum, - OperatorTypeEnum, - ExceptionListTypeEnum, exceptionListItemSchema, - exceptionListType, - comment, createExceptionListItemSchema, listSchema, - entry, - entriesNested, - nestedEntryItem, - entriesMatch, - entriesMatchAny, - entriesMatchWildcard, - entriesExists, - entriesList, - namespaceType, - ExceptionListType, - Type, ENDPOINT_LIST_ID, ENDPOINT_TRUSTED_APPS_LIST_ID, EXCEPTION_LIST_URL, @@ -52,8 +22,5 @@ export { ENDPOINT_EVENT_FILTERS_LIST_ID, ENDPOINT_EVENT_FILTERS_LIST_NAME, ENDPOINT_EVENT_FILTERS_LIST_DESCRIPTION, - osType, - osTypeArray, - OsTypeArray, buildExceptionFilter, } from '../../lists/common'; diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx index c1efb4d7c4565..9cb219e7a8d45 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx @@ -15,10 +15,11 @@ import { } from '@elastic/eui'; import { uniq } from 'lodash'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { useFieldValueAutocomplete } from './hooks/use_field_value_autocomplete'; import { paramIsValid, getGenericComboBoxProps } from './helpers'; -import { OperatorTypeEnum } from '../../../lists_plugin_deps'; + import { GetGenericComboBoxPropsReturn } from './types'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx index e77bf570adc63..dbfdaf9749b6d 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx @@ -9,11 +9,12 @@ import React, { useState, useCallback, useMemo } from 'react'; import { EuiFormRow, EuiComboBoxOptionOption, EuiComboBox } from '@elastic/eui'; import { uniq } from 'lodash'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { useFieldValueAutocomplete } from './hooks/use_field_value_autocomplete'; import { getGenericComboBoxProps, paramIsValid } from './helpers'; -import { OperatorTypeEnum } from '../../../lists_plugin_deps'; import { GetGenericComboBoxPropsReturn } from './types'; + import * as i18n from './translations'; interface AutocompleteFieldMatchAnyProps { diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts index b89f9525024c7..bd79bb0fcc8e8 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts @@ -8,6 +8,8 @@ import dateMath from '@elastic/datemath'; import { EuiComboBoxOptionOption } from '@elastic/eui'; +import type { Type } from '@kbn/securitysolution-io-ts-list-types'; +import type { ListSchema } from '../../../lists_plugin_deps'; import { IFieldType } from '../../../../../../../src/plugins/data/common'; import { @@ -19,7 +21,6 @@ import { } from './operators'; import { GetGenericComboBoxPropsReturn, OperatorOption } from './types'; import * as i18n from './translations'; -import { ListSchema, Type } from '../../../lists_plugin_deps'; /** * Returns the appropriate operators given a field type diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts index 36e050c84f0b3..e0bdbf2603dc3 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts @@ -15,7 +15,7 @@ import { import { useKibana } from '../../../../common/lib/kibana'; import { stubIndexPatternWithFields } from '../../../../../../../../src/plugins/data/common/index_patterns/index_pattern.stub'; import { getField } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; -import { OperatorTypeEnum } from '../../../../lists_plugin_deps'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; jest.mock('../../../../common/lib/kibana'); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.ts index b8440205e7d32..0f369fa01d01e 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.ts @@ -8,9 +8,9 @@ import { useEffect, useState, useRef } from 'react'; import { debounce } from 'lodash'; +import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; import { useKibana } from '../../../../common/lib/kibana'; -import { OperatorTypeEnum } from '../../../../lists_plugin_deps'; interface FuncArgs { fieldSelected: IFieldType | undefined; diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts index 93eab41264bf7..53e2ddf84b3d3 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts @@ -6,8 +6,11 @@ */ import { i18n } from '@kbn/i18n'; +import { + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; import { OperatorOption } from './types'; -import { OperatorEnum, OperatorTypeEnum } from '../../../lists_plugin_deps'; export const isOperator: OperatorOption = { message: i18n.translate('xpack.securitySolution.exceptions.isOperatorLabel', { diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/types.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/types.ts index 903edc403ea25..1d8e3e9aee28e 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/types.ts @@ -7,7 +7,10 @@ import { EuiComboBoxOptionOption } from '@elastic/eui'; -import { OperatorEnum, OperatorTypeEnum } from '../../../lists_plugin_deps'; +import type { + ListOperatorEnum as OperatorEnum, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; export interface GetGenericComboBoxPropsReturn { comboOptions: EuiComboBoxOptionOption[]; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx index c627363fc29ef..c13a1b011ccbd 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx @@ -17,7 +17,7 @@ import { EuiCommentProps, EuiText, } from '@elastic/eui'; -import { Comment } from '../../../shared_imports'; +import type { Comment } from '@kbn/securitysolution-io-ts-list-types'; import * as i18n from './translations'; import { useCurrentUser } from '../../lib/kibana'; import { getFormattedComments } from './helpers'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx index 5ec8999d20518..5fb527a821bac 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx @@ -49,7 +49,10 @@ jest.mock('../../../containers/source'); jest.mock('../../../../detections/containers/detection_engine/rules'); jest.mock('../use_add_exception'); jest.mock('../use_fetch_or_create_rule_exception_list'); -jest.mock('../../../../shared_imports'); +jest.mock('../../../../shared_imports', () => ({ + ...jest.requireActual('../../../../shared_imports'), + useAsync: jest.fn(), +})); jest.mock('../../../../detections/containers/detection_engine/rules/use_rule_async'); describe('When the add exception modal is opened', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx index 120c4ad8efc1b..6efbbcf64406b 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx @@ -25,6 +25,7 @@ import { EuiComboBox, EuiComboBoxOptionOption, } from '@elastic/eui'; +import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { hasEqlSequenceQuery, isEqlRule, @@ -34,9 +35,9 @@ import { Status } from '../../../../../common/detection_engine/schemas/common/sc import { ExceptionListItemSchema, CreateExceptionListItemSchema, - ExceptionListType, ExceptionBuilder, } from '../../../../../public/shared_imports'; + import * as i18nCommon from '../../../translations'; import * as i18n from './translations'; import * as sharedI18n from '../translations'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx index 5fb52994fb0f5..6c68dcf934b71 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx @@ -22,6 +22,7 @@ import { EuiCallOut, } from '@elastic/eui'; +import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { hasEqlSequenceQuery, isEqlRule, @@ -33,9 +34,9 @@ import { useRuleAsync } from '../../../../detections/containers/detection_engine import { ExceptionListItemSchema, CreateExceptionListItemSchema, - ExceptionListType, ExceptionBuilder, } from '../../../../../public/shared_imports'; + import * as i18n from './translations'; import * as sharedI18n from '../translations'; import { useKibana } from '../../../lib/kibana'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx index 907b30fcaa879..98c2b4db5676e 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -10,13 +10,8 @@ import { mount } from 'enzyme'; import moment from 'moment-timezone'; import { - getOperatorType, - getExceptionOperatorSelect, getFormattedComments, - filterExceptionItems, - getNewExceptionItem, formatOperatingSystems, - getEntryValue, formatExceptionItemForUpdate, enrichNewExceptionItemsWithComments, enrichExistingExceptionItemWithComments, @@ -32,35 +27,19 @@ import { retrieveAlertOsTypes, filterIndexPatterns, } from './helpers'; -import { AlertData, EmptyEntry } from './types'; +import { AlertData } from './types'; import { - isOperator, - isNotOperator, - isOneOfOperator, - isNotOneOfOperator, - isInListOperator, - isNotInListOperator, - existsOperator, - doesNotExistOperator, -} from '../autocomplete/operators'; -import { OperatorTypeEnum, OperatorEnum, EntryNested } from '../../../shared_imports'; + ListOperatorTypeEnum as OperatorTypeEnum, + EntriesArray, + OsTypeArray, +} from '@kbn/securitysolution-io-ts-list-types'; + import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchMock } from '../../../../../lists/common/schemas/types/entry_match.mock'; -import { getEntryMatchAnyMock } from '../../../../../lists/common/schemas/types/entry_match_any.mock'; -import { getEntryExistsMock } from '../../../../../lists/common/schemas/types/entry_exists.mock'; -import { getEntryListMock } from '../../../../../lists/common/schemas/types/entry_list.mock'; import { getCommentsArrayMock } from '../../../../../lists/common/schemas/types/comment.mock'; import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; -import { - ENTRIES, - ENTRIES_WITH_IDS, - OLD_DATE_RELATIVE_TO_DATE_NOW, -} from '../../../../../lists/common/constants.mock'; -import { EntriesArray, OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; -import { - CreateExceptionListItemSchema, - ExceptionListItemSchema, -} from '../../../../../lists/common/schemas'; +import { ENTRIES, OLD_DATE_RELATIVE_TO_DATE_NOW } from '../../../../../lists/common/constants.mock'; +import { ExceptionListItemSchema } from '../../../../../lists/common/schemas'; import { IFieldType, IIndexPattern } from 'src/plugins/data/common'; jest.mock('uuid', () => ({ @@ -162,128 +141,6 @@ describe('Exception helpers', () => { }); }); - describe('#getOperatorType', () => { - test('returns operator type "match" if entry.type is "match"', () => { - const payload = getEntryMatchMock(); - const operatorType = getOperatorType(payload); - - expect(operatorType).toEqual(OperatorTypeEnum.MATCH); - }); - - test('returns operator type "match_any" if entry.type is "match_any"', () => { - const payload = getEntryMatchAnyMock(); - const operatorType = getOperatorType(payload); - - expect(operatorType).toEqual(OperatorTypeEnum.MATCH_ANY); - }); - - test('returns operator type "list" if entry.type is "list"', () => { - const payload = getEntryListMock(); - const operatorType = getOperatorType(payload); - - expect(operatorType).toEqual(OperatorTypeEnum.LIST); - }); - - test('returns operator type "exists" if entry.type is "exists"', () => { - const payload = getEntryExistsMock(); - const operatorType = getOperatorType(payload); - - expect(operatorType).toEqual(OperatorTypeEnum.EXISTS); - }); - }); - - describe('#getExceptionOperatorSelect', () => { - test('it returns "isOperator" when "operator" is "included" and operator type is "match"', () => { - const payload = getEntryMatchMock(); - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(isOperator); - }); - - test('it returns "isNotOperator" when "operator" is "excluded" and operator type is "match"', () => { - const payload = getEntryMatchMock(); - payload.operator = 'excluded'; - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(isNotOperator); - }); - - test('it returns "isOneOfOperator" when "operator" is "included" and operator type is "match_any"', () => { - const payload = getEntryMatchAnyMock(); - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(isOneOfOperator); - }); - - test('it returns "isNotOneOfOperator" when "operator" is "excluded" and operator type is "match_any"', () => { - const payload = getEntryMatchAnyMock(); - payload.operator = 'excluded'; - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(isNotOneOfOperator); - }); - - test('it returns "existsOperator" when "operator" is "included" and no operator type is provided', () => { - const payload = getEntryExistsMock(); - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(existsOperator); - }); - - test('it returns "doesNotExistsOperator" when "operator" is "excluded" and no operator type is provided', () => { - const payload = getEntryExistsMock(); - payload.operator = 'excluded'; - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(doesNotExistOperator); - }); - - test('it returns "isInList" when "operator" is "included" and operator type is "list"', () => { - const payload = getEntryListMock(); - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(isInListOperator); - }); - - test('it returns "isNotInList" when "operator" is "excluded" and operator type is "list"', () => { - const payload = getEntryListMock(); - payload.operator = 'excluded'; - const result = getExceptionOperatorSelect(payload); - - expect(result).toEqual(isNotInListOperator); - }); - }); - - describe('#getEntryValue', () => { - it('returns "match" entry value', () => { - const payload = getEntryMatchMock(); - const result = getEntryValue(payload); - const expected = 'some host name'; - expect(result).toEqual(expected); - }); - - it('returns "match any" entry values', () => { - const payload = getEntryMatchAnyMock(); - const result = getEntryValue(payload); - const expected = ['some host name']; - expect(result).toEqual(expected); - }); - - it('returns "exists" entry value', () => { - const payload = getEntryExistsMock(); - const result = getEntryValue(payload); - const expected = undefined; - expect(result).toEqual(expected); - }); - - it('returns "list" entry value', () => { - const payload = getEntryListMock(); - const result = getEntryValue(payload); - const expected = 'some-list-id'; - expect(result).toEqual(expected); - }); - }); - describe('#formatOperatingSystems', () => { test('it returns null if no operating system tag specified', () => { const result = formatOperatingSystems(['some os', 'some other os']); @@ -324,178 +181,6 @@ describe('Exception helpers', () => { }); }); - describe('#filterExceptionItems', () => { - // Please see `x-pack/plugins/lists/public/exceptions/transforms.ts` doc notes - // for context around the temporary `id` - test('it correctly validates entries that include a temporary `id`', () => { - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { ...getExceptionListItemSchemaMock(), entries: ENTRIES_WITH_IDS }, - ]); - - expect(output).toEqual([{ ...getExceptionListItemSchemaMock(), entries: ENTRIES_WITH_IDS }]); - }); - - test('it removes entry items with "value" of "undefined"', () => { - const { entries, ...rest } = getExceptionListItemSchemaMock(); - const mockEmptyException: EmptyEntry = { - id: '123', - field: 'host.name', - type: OperatorTypeEnum.MATCH, - operator: OperatorEnum.INCLUDED, - value: undefined, - }; - const exceptions = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(exceptions).toEqual([getExceptionListItemSchemaMock()]); - }); - - test('it removes "match" entry items with "value" of empty string', () => { - const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; - const mockEmptyException: EmptyEntry = { - id: '123', - field: 'host.name', - type: OperatorTypeEnum.MATCH, - operator: OperatorEnum.INCLUDED, - value: '', - }; - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); - }); - - test('it removes "match" entry items with "field" of empty string', () => { - const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; - const mockEmptyException: EmptyEntry = { - id: '123', - field: '', - type: OperatorTypeEnum.MATCH, - operator: OperatorEnum.INCLUDED, - value: 'some value', - }; - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); - }); - - test('it removes "match_any" entry items with "field" of empty string', () => { - const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; - const mockEmptyException: EmptyEntry = { - id: '123', - field: '', - type: OperatorTypeEnum.MATCH_ANY, - operator: OperatorEnum.INCLUDED, - value: ['some value'], - }; - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); - }); - - test('it removes "nested" entry items with "field" of empty string', () => { - const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; - const mockEmptyException: EntryNested = { - field: '', - type: OperatorTypeEnum.NESTED, - entries: [getEntryMatchMock()], - }; - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); - }); - - test('it removes the "nested" entry entries with "value" of empty string', () => { - const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; - const mockEmptyException: EntryNested = { - field: 'host.name', - type: OperatorTypeEnum.NESTED, - entries: [getEntryMatchMock(), { ...getEntryMatchMock(), value: '' }], - }; - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(output).toEqual([ - { - ...getExceptionListItemSchemaMock(), - entries: [ - ...getExceptionListItemSchemaMock().entries, - { ...mockEmptyException, entries: [getEntryMatchMock()] }, - ], - }, - ]); - }); - - test('it removes the "nested" entry item if all its entries are invalid', () => { - const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; - const mockEmptyException: EntryNested = { - field: 'host.name', - type: OperatorTypeEnum.NESTED, - entries: [{ ...getEntryMatchMock(), value: '' }], - }; - const output: Array< - ExceptionListItemSchema | CreateExceptionListItemSchema - > = filterExceptionItems([ - { - ...rest, - entries: [...entries, mockEmptyException], - }, - ]); - - expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); - }); - - test('it removes `temporaryId` from items', () => { - const { meta, ...rest } = getNewExceptionItem({ - listId: '123', - namespaceType: 'single', - ruleName: 'rule name', - }); - const exceptions = filterExceptionItems([{ ...rest, meta }]); - - expect(exceptions).toEqual([{ ...rest, entries: [], meta: undefined }]); - }); - }); - describe('#formatExceptionItemForUpdate', () => { test('it should return correct update fields', () => { const payload = getExceptionListItemSchemaMock(); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx index ce76114309e2e..437e93bb26fef 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx @@ -9,46 +9,36 @@ import React from 'react'; import { EuiText, EuiCommentProps, EuiAvatar } from '@elastic/eui'; import { capitalize } from 'lodash'; import moment from 'moment'; -import uuid from 'uuid'; -import * as i18n from './translations'; -import { - AlertData, - BuilderEntry, - CreateExceptionListItemBuilderSchema, - ExceptionsBuilderExceptionItem, - Flattened, -} from './types'; -import { EXCEPTION_OPERATORS, isOperator } from '../autocomplete/operators'; -import { OperatorOption } from '../autocomplete/types'; import { + comment, + osType, CommentsArray, Comment, CreateComment, Entry, - ExceptionListItemSchema, NamespaceType, - OperatorTypeEnum, - CreateExceptionListItemSchema, - comment, - entry, - entriesNested, - nestedEntryItem, - createExceptionListItemSchema, - exceptionListItemSchema, - UpdateExceptionListItemSchema, EntryNested, OsTypeArray, - EntriesArray, - osType, ExceptionListType, + ListOperatorTypeEnum as OperatorTypeEnum, +} from '@kbn/securitysolution-io-ts-list-types'; + +import * as i18n from './translations'; +import { AlertData, ExceptionsBuilderExceptionItem, Flattened } from './types'; +import { + ExceptionListItemSchema, + CreateExceptionListItemSchema, + UpdateExceptionListItemSchema, + getOperatorType, + getNewExceptionItem, + addIdToEntries, } from '../../../shared_imports'; + import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; -import { validate } from '../../../../common/validate'; import { Ecs } from '../../../../common/ecs'; import { CodeSignature } from '../../../../common/ecs/file'; import { WithCopyToClipboard } from '../../lib/clipboard/with_copy_to_clipboard'; -import { addIdToItem, removeIdFromItem } from '../../../../common'; import exceptionableLinuxFields from './exceptionable_linux_fields.json'; import exceptionableWindowsMacFields from './exceptionable_windows_mac_fields.json'; import exceptionableEndpointFields from './exceptionable_endpoint_fields.json'; @@ -84,75 +74,6 @@ export const filterIndexPatterns = ( } }; -export const addIdToEntries = (entries: EntriesArray): EntriesArray => { - return entries.map((singleEntry) => { - if (singleEntry.type === 'nested') { - return addIdToItem({ - ...singleEntry, - entries: singleEntry.entries.map((nestedEntry) => addIdToItem(nestedEntry)), - }); - } else { - return addIdToItem(singleEntry); - } - }); -}; - -/** - * Returns the operator type, may not need this if using io-ts types - * - * @param item a single ExceptionItem entry - */ -export const getOperatorType = (item: BuilderEntry): OperatorTypeEnum => { - switch (item.type) { - case 'match': - return OperatorTypeEnum.MATCH; - case 'match_any': - return OperatorTypeEnum.MATCH_ANY; - case 'list': - return OperatorTypeEnum.LIST; - default: - return OperatorTypeEnum.EXISTS; - } -}; - -/** - * Determines operator selection (is/is not/is one of, etc.) - * Default operator is "is" - * - * @param item a single ExceptionItem entry - */ -export const getExceptionOperatorSelect = (item: BuilderEntry): OperatorOption => { - if (item.type === 'nested') { - return isOperator; - } else { - const operatorType = getOperatorType(item); - const foundOperator = EXCEPTION_OPERATORS.find((operatorOption) => { - return item.operator === operatorOption.operator && operatorType === operatorOption.type; - }); - - return foundOperator ?? isOperator; - } -}; - -/** - * Returns the fields corresponding value for an entry - * - * @param item a single ExceptionItem entry - */ -export const getEntryValue = (item: BuilderEntry): string | string[] | undefined => { - switch (item.type) { - case OperatorTypeEnum.MATCH: - case OperatorTypeEnum.MATCH_ANY: - return item.value; - case OperatorTypeEnum.EXISTS: - return undefined; - case OperatorTypeEnum.LIST: - return item.list.id; - default: - return undefined; - } -}; - /** * Formats os value array to a displayable string */ @@ -189,91 +110,6 @@ export const getFormattedComments = (comments: CommentsArray): EuiCommentProps[] ), })); -export const getNewExceptionItem = ({ - listId, - namespaceType, - ruleName, -}: { - listId: string; - namespaceType: NamespaceType; - ruleName: string; -}): CreateExceptionListItemBuilderSchema => { - return { - comments: [], - description: `${ruleName} - exception list item`, - entries: addIdToEntries([ - { - field: '', - operator: 'included', - type: 'match', - value: '', - }, - ]), - item_id: undefined, - list_id: listId, - meta: { - temporaryUuid: uuid.v4(), - }, - name: `${ruleName} - exception list item`, - namespace_type: namespaceType, - tags: [], - type: 'simple', - }; -}; - -export const filterExceptionItems = ( - exceptions: ExceptionsBuilderExceptionItem[] -): Array => { - return exceptions.reduce>( - (acc, exception) => { - const entries = exception.entries.reduce((nestedAcc, singleEntry) => { - const strippedSingleEntry = removeIdFromItem(singleEntry); - - if (entriesNested.is(strippedSingleEntry)) { - const nestedEntriesArray = strippedSingleEntry.entries.filter((singleNestedEntry) => { - const noIdSingleNestedEntry = removeIdFromItem(singleNestedEntry); - const [validatedNestedEntry] = validate(noIdSingleNestedEntry, nestedEntryItem); - return validatedNestedEntry != null; - }); - const noIdNestedEntries = nestedEntriesArray.map((singleNestedEntry) => - removeIdFromItem(singleNestedEntry) - ); - - const [validatedNestedEntry] = validate( - { ...strippedSingleEntry, entries: noIdNestedEntries }, - entriesNested - ); - - if (validatedNestedEntry != null) { - return [...nestedAcc, { ...singleEntry, entries: nestedEntriesArray }]; - } - return nestedAcc; - } else { - const [validatedEntry] = validate(strippedSingleEntry, entry); - - if (validatedEntry != null) { - return [...nestedAcc, singleEntry]; - } - return nestedAcc; - } - }, []); - - const item = { ...exception, entries }; - - if (exceptionListItemSchema.is(item)) { - return [...acc, item]; - } else if (createExceptionListItemSchema.is(item)) { - const { meta, ...rest } = item; - const itemSansMetaId: CreateExceptionListItemSchema = { ...rest, meta: undefined }; - return [...acc, itemSansMetaId]; - } else { - return acc; - } - }, - [] - ); -}; - export const formatExceptionItemForUpdate = ( exceptionItem: ExceptionListItemSchema ): UpdateExceptionListItemSchema => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts index 92a3cb2cfac93..49cdd7103c48b 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts @@ -6,23 +6,22 @@ */ import { ReactNode } from 'react'; -import { Ecs } from '../../../../common/ecs'; -import { CodeSignature } from '../../../../common/ecs/file'; -import { IFieldType } from '../../../../../../../src/plugins/data/common'; -import { OperatorOption } from '../autocomplete/types'; -import { +import type { EntryNested, Entry, EntryMatch, EntryMatchAny, EntryMatchWildcard, EntryExists, - ExceptionListItemSchema, - CreateExceptionListItemSchema, NamespaceType, - OperatorTypeEnum, - OperatorEnum, -} from '../../../lists_plugin_deps'; + ListOperatorTypeEnum as OperatorTypeEnum, + ListOperatorEnum as OperatorEnum, +} from '@kbn/securitysolution-io-ts-list-types'; +import { Ecs } from '../../../../common/ecs'; +import { CodeSignature } from '../../../../common/ecs/file'; +import { IFieldType } from '../../../../../../../src/plugins/data/common'; +import { OperatorOption } from '../autocomplete/types'; +import { ExceptionListItemSchema, CreateExceptionListItemSchema } from '../../../lists_plugin_deps'; export interface FormattedEntry { fieldName: string; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/use_add_exception.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/use_add_exception.test.tsx index 0f6dd19ea9b66..f609acf9c6c63 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/use_add_exception.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/use_add_exception.test.tsx @@ -27,6 +27,7 @@ import { ReturnUseAddOrUpdateException, AddOrUpdateExceptionItemsFunc, } from './use_add_exception'; +import { UpdateDocumentByQueryResponse } from 'elasticsearch'; const mockKibanaHttpService = coreMock.createStart().http; const mockKibanaServices = KibanaServices.get as jest.Mock; @@ -36,11 +37,9 @@ const fetchMock = jest.fn(); mockKibanaServices.mockReturnValue({ http: { fetch: fetchMock } }); describe('useAddOrUpdateException', () => { - let updateAlertStatus: jest.SpyInstance>; - let addExceptionListItem: jest.SpyInstance>; - let updateExceptionListItem: jest.SpyInstance< - ReturnType - >; + let updateAlertStatus: jest.SpyInstance>; + let addExceptionListItem: jest.SpyInstance>; + let updateExceptionListItem: jest.SpyInstance>; let getQueryFilter: jest.SpyInstance>; let buildAlertStatusFilter: jest.SpyInstance< ReturnType diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.test.tsx index 877f545b69d65..17237f4f94c61 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.test.tsx @@ -12,7 +12,7 @@ import * as rulesApi from '../../../detections/containers/detection_engine/rules import * as listsApi from '../../../../../lists/public/exceptions/api'; import { getExceptionListSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_schema.mock'; import { savedRuleMock } from '../../../detections/containers/detection_engine/rules/mock'; -import { ExceptionListType } from '../../../lists_plugin_deps'; +import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { ListArray } from '../../../../common/detection_engine/schemas/types'; import { getListArrayMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; import { @@ -20,6 +20,7 @@ import { UseFetchOrCreateRuleExceptionListProps, ReturnUseFetchOrCreateRuleExceptionList, } from './use_fetch_or_create_rule_exception_list'; +import { ExceptionListSchema } from '../../../shared_imports'; const mockKibanaHttpService = coreMock.createStart().http; jest.mock('../../../detections/containers/detection_engine/rules/api'); @@ -31,7 +32,7 @@ describe('useFetchOrCreateRuleExceptionList', () => { let addEndpointExceptionList: jest.SpyInstance< ReturnType >; - let fetchExceptionListById: jest.SpyInstance>; + let fetchExceptionListById: jest.SpyInstance>; let render: ( listType?: UseFetchOrCreateRuleExceptionListProps['exceptionListType'] ) => RenderHookResult< diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.stories.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.stories.tsx index 8ded1b902f302..4f78b49ea266c 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.stories.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.stories.tsx @@ -11,8 +11,8 @@ import React from 'react'; import { ThemeProvider } from 'styled-components'; import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { ExceptionsViewerHeader } from './exceptions_viewer_header'; -import { ExceptionListTypeEnum } from '../../../../../public/lists_plugin_deps'; addDecorator((storyFn) => ( ({ eui: euiLightVars, darkMode: false })}>{storyFn()} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.test.tsx index b82a472befdcf..7dcd59069b53c 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.test.tsx @@ -9,7 +9,8 @@ import React from 'react'; import { mount } from 'enzyme'; import { ExceptionsViewerHeader } from './exceptions_viewer_header'; -import { ExceptionListTypeEnum } from '../../../../../public/lists_plugin_deps'; + +import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; describe('ExceptionsViewerHeader', () => { it('it renders all disabled if "isInitLoading" is true', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx index eff4368ef6809..8fc28ad89156d 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx @@ -18,9 +18,9 @@ import { } from '@elastic/eui'; import React, { useEffect, useState, useCallback, useMemo } from 'react'; +import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import * as i18n from '../translations'; import { Filter } from '../types'; -import { ExceptionListTypeEnum } from '../../../../../public/lists_plugin_deps'; interface ExceptionsViewerHeaderProps { isInitLoading: boolean; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.tsx index 29764625075d6..abd45cf2945cb 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.tsx @@ -7,8 +7,14 @@ import moment from 'moment'; -import { entriesNested, ExceptionListItemSchema } from '../../../../lists_plugin_deps'; -import { getEntryValue, getExceptionOperatorSelect, formatOperatingSystems } from '../helpers'; +import { entriesNested } from '@kbn/securitysolution-io-ts-list-types'; +import { + ExceptionListItemSchema, + getEntryValue, + getExceptionOperatorSelect, +} from '../../../../lists_plugin_deps'; + +import { formatOperatingSystems } from '../helpers'; import { FormattedEntry, BuilderEntry, DescriptionListItem } from '../types'; import * as i18n from '../translations'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx index 3fe6497105af1..971b3fda47191 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx @@ -11,11 +11,9 @@ import { ThemeProvider } from 'styled-components'; import { ExceptionsViewer } from './'; import { useKibana } from '../../../../common/lib/kibana'; -import { - ExceptionListTypeEnum, - useExceptionListItems, - useApi, -} from '../../../../../public/lists_plugin_deps'; +import { useExceptionListItems, useApi } from '../../../../../public/lists_plugin_deps'; + +import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { getExceptionListSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_schema.mock'; import { getFoundExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/found_exception_list_item_schema.mock'; import { getMockTheme } from '../../../lib/kibana/kibana_react.mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx index 8c4569ed29b33..da7607f40ab72 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx @@ -9,6 +9,7 @@ import React, { useCallback, useEffect, useReducer } from 'react'; import { EuiSpacer } from '@elastic/eui'; import uuid from 'uuid'; +import type { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import * as i18n from '../translations'; import { useStateToaster } from '../../toasters'; import { useKibana } from '../../../../common/lib/kibana'; @@ -20,11 +21,11 @@ import { allExceptionItemsReducer, State, ViewerModalName } from './reducer'; import { useExceptionListItems, ExceptionListIdentifiers, - ExceptionListTypeEnum, ExceptionListItemSchema, UseExceptionListItemsSuccess, useApi, } from '../../../../../public/lists_plugin_deps'; + import { ExceptionsViewerPagination } from './exceptions_pagination'; import { ExceptionsViewerUtility } from './exceptions_utility'; import { ExceptionsViewerItems } from './exceptions_viewer_items'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/reducer.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/reducer.ts index 46ac19f47503d..bf8e454e9971f 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/reducer.ts +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/reducer.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { FilterOptions, ExceptionsPagination, @@ -12,7 +13,6 @@ import { Filter, } from '../types'; import { - ExceptionListType, ExceptionListItemSchema, ExceptionListIdentifiers, Pagination, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 69e41a2c3d0a2..3152c08fab323 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -19,6 +19,7 @@ import styled from 'styled-components'; import { getOr } from 'lodash/fp'; import { indexOf } from 'lodash'; +import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { buildGetAlertByIdQuery } from '../../../../common/components/exceptions/helpers'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { TimelineId } from '../../../../../common/types/timeline'; @@ -44,7 +45,6 @@ import { } from '../../../../common/components/toasters'; import { inputsModel } from '../../../../common/store'; import { useUserData } from '../../user_info'; -import { ExceptionListType } from '../../../../../common/shared_imports'; import { AlertData, EcsHit } from '../../../../common/components/exceptions/types'; import { useQueryAlerts } from '../../../containers/detection_engine/alerts/use_query'; import { useSignalIndex } from '../../../containers/detection_engine/alerts/use_signal_index'; diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx index 94cb22592f4ed..ea903882c326d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx @@ -18,7 +18,9 @@ import { EuiSelectOption, } from '@elastic/eui'; -import { useImportList, ListSchema, Type } from '../../../shared_imports'; +import type { Type } from '@kbn/securitysolution-io-ts-list-types'; +import { useImportList, ListSchema } from '../../../shared_imports'; + import * as i18n from './translations'; import { useKibana } from '../../../common/lib/kibana'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx index d11ceee7f5978..64cb936f160f1 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx @@ -11,8 +11,8 @@ import React from 'react'; import { EuiButtonIcon, EuiBasicTableColumn, EuiToolTip } from '@elastic/eui'; import { History } from 'history'; +import { NamespaceType } from '@kbn/securitysolution-io-ts-list-types'; import { Spacer } from '../../../../../../common/components/page'; -import { NamespaceType } from '../../../../../../../../lists/common'; import { FormatUrl } from '../../../../../../common/components/link_to'; import { LinkAnchor } from '../../../../../../common/components/links'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx index 146b7e8470718..50cf1b1830fec 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx @@ -15,9 +15,9 @@ import { } from '@elastic/eui'; import { History } from 'history'; +import { NamespaceType } from '@kbn/securitysolution-io-ts-list-types'; import { useAppToasts } from '../../../../../../common/hooks/use_app_toasts'; import { AutoDownload } from '../../../../../../common/components/auto_download/auto_download'; -import { NamespaceType } from '../../../../../../../../lists/common'; import { useKibana } from '../../../../../../common/lib/kibana'; import { ExceptionListFilter, useApi, useExceptionLists } from '../../../../../../shared_imports'; import { FormatUrl } from '../../../../../../common/components/link_to'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts index 64dfac5787f23..29b63721513d4 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts @@ -9,11 +9,12 @@ import { has, isEmpty } from 'lodash/fp'; import moment from 'moment'; import deepmerge from 'deepmerge'; +import type { ExceptionListType, NamespaceType } from '@kbn/securitysolution-io-ts-list-types'; import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../../common/constants'; import { assertUnreachable } from '../../../../../../common/utility_types'; import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; import { List } from '../../../../../../common/detection_engine/schemas/types'; -import { ENDPOINT_LIST_ID, ExceptionListType, NamespaceType } from '../../../../../shared_imports'; +import { ENDPOINT_LIST_ID } from '../../../../../shared_imports'; import { Rule } from '../../../../containers/detection_engine/rules'; import { Threats, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 0fab428ef6d1b..9660132147a57 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -28,6 +28,7 @@ import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import deepEqual from 'fast-deep-equal'; +import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { useDeepEqualSelector, useShallowEqualSelector, @@ -83,7 +84,8 @@ import { ExceptionsViewer } from '../../../../../common/components/exceptions/vi import { DEFAULT_INDEX_PATTERN } from '../../../../../../common/constants'; import { useGlobalFullScreen } from '../../../../../common/containers/use_full_screen'; import { Display } from '../../../../../hosts/pages/display'; -import { ExceptionListTypeEnum, ExceptionListIdentifiers } from '../../../../../shared_imports'; +import type { ExceptionListIdentifiers } from '../../../../../shared_imports'; + import { focusUtilityBarAction, onTimelineTabKeyPressed, diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/constants.ts b/x-pack/plugins/security_solution/public/management/pages/event_filters/constants.ts index 5d600f471994b..e1fa1107fcb01 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/constants.ts +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/constants.ts @@ -5,9 +5,8 @@ * 2.0. */ +import { ExceptionListType, ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { - ExceptionListType, - ExceptionListTypeEnum, EXCEPTION_LIST_URL, EXCEPTION_LIST_ITEM_URL, ENDPOINT_EVENT_FILTERS_LIST_ID, diff --git a/x-pack/plugins/security_solution/public/shared_imports.ts b/x-pack/plugins/security_solution/public/shared_imports.ts index e77c4a0eec486..76ec761d41703 100644 --- a/x-pack/plugins/security_solution/public/shared_imports.ts +++ b/x-pack/plugins/security_solution/public/shared_imports.ts @@ -33,23 +33,23 @@ export { ERROR_CODE } from '../../../../src/plugins/es_ui_shared/static/forms/he export { exportList, - useIsMounted, useCursor, useApi, useAsync, useExceptionListItems, useExceptionLists, - usePersistExceptionItem, - usePersistExceptionList, useFindLists, useDeleteList, useImportList, useCreateListIndex, useReadListIndex, useReadListPrivileges, - addExceptionListItem, - updateExceptionListItem, fetchExceptionListById, + addIdToEntries, + getOperatorType, + getNewExceptionItem, + getEntryValue, + getExceptionOperatorSelect, addExceptionList, ExceptionListFilter, ExceptionListIdentifiers, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/mapping.ts b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/mapping.ts index 786a74e91b51a..e4704523a16c3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/mapping.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/mapping.ts @@ -7,17 +7,19 @@ import uuid from 'uuid'; -import { OsType } from '../../../../../lists/common/schemas'; -import { +import type { EntriesArray, EntryMatch, EntryMatchWildcard, EntryNested, - ExceptionListItemSchema, NestedEntriesArray, -} from '../../../../../lists/common'; +} from '@kbn/securitysolution-io-ts-list-types'; + +import type { ExceptionListItemSchema } from '../../../../../lists/common'; + +import type { OsType } from '../../../../../lists/common/schemas'; import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants'; -import { +import type { CreateExceptionListItemOptions, UpdateExceptionListItemOptions, } from '../../../../../lists/server'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.test.ts index 3fa5d1178b3ec..578c1aba64558 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.test.ts @@ -11,7 +11,7 @@ import { mockLogger, sampleDocWithSortId } from '../__mocks__/es_results'; import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { listMock } from '../../../../../../lists/server/mocks'; import { getSearchListItemResponseMock } from '../../../../../../lists/common/schemas/response/search_list_item_schema.mock'; -import { EntryList } from '../../../../../../lists/common'; +import { EntryList } from '@kbn/securitysolution-io-ts-list-types'; import { buildRuleMessageMock as buildRuleMessage } from '../rule_messages.mock'; describe('filterEventsAgainstList', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.ts index b2002dbb5a7e2..40322029c1d98 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/create_field_and_set_tuples.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { EntryList, entriesList } from '../../../../../../lists/common'; +import { EntryList, entriesList } from '@kbn/securitysolution-io-ts-list-types'; import { createSetToFilterAgainst } from './create_set_to_filter_against'; import { CreateFieldAndSetTuplesOptions, FieldSet } from './types';