From 05c93a0a2c00390a7b636047129363db923d754a Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Tue, 26 Nov 2024 17:53:22 -0800 Subject: [PATCH 1/2] fixed lint errors - part 1 Signed-off-by: Amardeepsingh Siglani --- package.json | 2 +- public/components/Modal/Modal.test.tsx | 11 ++- public/metrics/DetectorMetricsManager.ts | 6 +- public/metrics/MetricsContext.ts | 2 +- public/models/interfaces.ts | 6 +- .../pages/Alerts/containers/Alerts/Alerts.tsx | 6 +- .../DetectorDataSource/DetectorDataSource.tsx | 4 +- .../UpdateFieldMappings.tsx | 11 ++- .../FieldMappings/EditFieldMapping.tsx | 2 +- .../AddThreatIntelSource.tsx | 2 +- .../Overview/ThreatIntelOverview.tsx | 5 +- public/services/AlertsService.ts | 8 +- public/services/CorrelationService.ts | 43 +++++----- public/services/DetectorService.ts | 4 +- public/services/FieldMappingService.ts | 16 ++-- public/services/FindingsService.ts | 2 +- public/services/IndexPatternsService.ts | 4 +- public/services/IndexService.ts | 2 +- public/services/LogTypeService.ts | 2 +- public/services/MetricsService.ts | 4 +- public/services/NotificationsService.ts | 12 +-- public/services/OpenSearchService.ts | 10 +-- public/services/RuleService.ts | 2 +- public/services/SavedObjectService.ts | 12 +-- public/services/ThreatIntelService.ts | 2 +- public/services/index.ts | 28 ++++--- public/services/utils/constants.ts | 2 +- public/store/AlertsStore.ts | 4 +- public/store/CorrelationsStore.ts | 49 ++++++----- public/store/DataStore.ts | 2 +- public/store/DetectorsStore.tsx | 22 ++--- public/store/DocumentStore.ts | 5 +- public/store/FindingsStore.ts | 16 ++-- public/store/LogTypeStore.ts | 4 +- public/store/RulesStore.ts | 21 +++-- public/utils/constants.ts | 18 +--- public/utils/helpers.tsx | 84 +++++++++---------- .../services/fieldMappingService.mock.ts | 2 +- test/mocks/services/findingsService.mock.ts | 3 +- test/mocks/services/indexService.mock.ts | 6 +- .../mocks/services/savedObjectService.mock.ts | 3 +- 41 files changed, 226 insertions(+), 223 deletions(-) diff --git a/package.json b/package.json index ea4f5417d..a75ca627b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "cypress:run": "cypress run", "osd": "node ../../scripts/osd", "opensearch": "node ../../scripts/opensearch", - "lint": "node ../../scripts/eslint .", + "lint": "node ../../scripts/eslint", "plugin-helpers": "node ../../scripts/plugin_helpers", "test:jest": "../../node_modules/.bin/jest --config ./test/jest.config.js", "test:jest:dev": "../../node_modules/.bin/jest --watch --config ./test/jest.config.js", diff --git a/public/components/Modal/Modal.test.tsx b/public/components/Modal/Modal.test.tsx index 017e0ebc4..7b2257657 100644 --- a/public/components/Modal/Modal.test.tsx +++ b/public/components/Modal/Modal.test.tsx @@ -8,10 +8,9 @@ import { EuiButton, EuiOverlayMask, EuiModal } from '@elastic/eui'; import { render, fireEvent } from '@testing-library/react'; import ModalRoot from './ModalRoot'; import { ModalConsumer, ModalProvider } from './Modal'; -import { SecurityAnalyticsContext, SaContextConsumer } from '../../services'; +import { SecurityAnalyticsContext, SaContextConsumer, MetricsService } from '../../services'; import services from '../../../test/mocks/services'; import { MetricsContext } from '../../metrics/MetricsContext'; -import MetricsService from '../../services/MetricsService'; import httpClientMock from '../../../test/mocks/services/httpClient.mock'; describe(' spec', () => { @@ -28,7 +27,7 @@ describe(' spec', () => { ); - expect(container.firstChild).toBeNull(); + expect(container.firstChild).to.be.null; }); it('renders a modal that can close and open', () => { @@ -61,14 +60,14 @@ describe(' spec', () => { ); - expect(queryByText('A modal that has interesting text')).toBeNull(); + expect(queryByText('A modal that has interesting text')).to.be.null; fireEvent.click(getByTestId('showModal')); - expect(queryByText('A modal that has interesting text')).not.toBeNull(); + expect(queryByText('A modal that has interesting text')).not.to.be.null; fireEvent.click(getByLabelText('Closes this modal window')); - expect(queryByText('A modal that has interesting text')).toBeNull(); + expect(queryByText('A modal that has interesting text')).to.be.null; }); }); diff --git a/public/metrics/DetectorMetricsManager.ts b/public/metrics/DetectorMetricsManager.ts index edb17f01e..2441d3b98 100644 --- a/public/metrics/DetectorMetricsManager.ts +++ b/public/metrics/DetectorMetricsManager.ts @@ -4,7 +4,7 @@ */ import { CreateDetectorSteps, CreateDetectorStepValue } from '../../types'; -import MetricsService from '../services/MetricsService'; +import { MetricsService } from '../services'; export class DetectorMetricsManager { private static initialCheckpoint = CreateDetectorStepValue[CreateDetectorSteps.notStarted]; @@ -31,7 +31,7 @@ export class DetectorMetricsManager { [stepNameForCounter || step]: 1, }, }); - this.stepsLogged |= stepValue; + this.stepsLogged |= stepValue; // eslint-disable-line no-bitwise } } @@ -40,6 +40,6 @@ export class DetectorMetricsManager { } private metricEmittedForStep(stepValue: number): boolean { - return (this.stepsLogged & stepValue) === stepValue; + return (this.stepsLogged & stepValue) === stepValue; // eslint-disable-line no-bitwise } } diff --git a/public/metrics/MetricsContext.ts b/public/metrics/MetricsContext.ts index 3718118b0..69bf4082b 100644 --- a/public/metrics/MetricsContext.ts +++ b/public/metrics/MetricsContext.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import MetricsService from '../services/MetricsService'; +import { MetricsService } from '../services'; import { DetectorMetricsManager } from './DetectorMetricsManager'; export class MetricsContext { diff --git a/public/models/interfaces.ts b/public/models/interfaces.ts index 70ce57263..2c7c5a7e6 100644 --- a/public/models/interfaces.ts +++ b/public/models/interfaces.ts @@ -15,10 +15,10 @@ import { NotificationsService, IndexPatternsService, LogTypeService, + CorrelationService, + MetricsService, + ThreatIntelService, } from '../services'; -import CorrelationService from '../services/CorrelationService'; -import MetricsService from '../services/MetricsService'; -import ThreatIntelService from '../services/ThreatIntelService'; export interface BrowserServices { detectorsService: DetectorsService; diff --git a/public/pages/Alerts/containers/Alerts/Alerts.tsx b/public/pages/Alerts/containers/Alerts/Alerts.tsx index df6fb3dd5..29309f68d 100644 --- a/public/pages/Alerts/containers/Alerts/Alerts.tsx +++ b/public/pages/Alerts/containers/Alerts/Alerts.tsx @@ -40,8 +40,8 @@ import { DEFAULT_EMPTY_DATA, MAX_RECENTLY_USED_TIME_RANGES, } from '../../../../utils/constants'; -import AlertsService from '../../../../services/AlertsService'; -import DetectorService from '../../../../services/DetectorService'; +import { AlertsService } from '../../../../services/AlertsService'; +import { DetectorsService } from '../../../../services/DetectorService'; import { AlertFlyout } from '../../components/AlertFlyout/AlertFlyout'; import { CorrelationAlertFlyout } from '../../components/CorrelationAlertFlyout/CorrelationAlertFlyout'; import { @@ -85,7 +85,7 @@ type FilterAlertParams = export interface AlertsProps extends RouteComponentProps, DataSourceProps { alertService: AlertsService; - detectorService: DetectorService; + detectorService: DetectorsService; findingService: FindingsService; opensearchService: OpenSearchService; correlationService: CorrelationService; diff --git a/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx b/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx index f720bca58..4d169607d 100644 --- a/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx +++ b/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx @@ -11,17 +11,15 @@ import { EuiSpacer, EuiCallOut, EuiTextColor, - EuiTitle, EuiText, } from '@elastic/eui'; import { FormFieldHeader } from '../../../../../../components/FormFieldHeader/FormFieldHeader'; import { IndexOption } from '../../../../../Detectors/models/interfaces'; import { MIN_NUM_DATA_SOURCES } from '../../../../../Detectors/utils/constants'; -import IndexService from '../../../../../../services/IndexService'; import { NotificationsStart } from 'opensearch-dashboards/public'; import { getDataSources } from '../../../../../../utils/helpers'; import _ from 'lodash'; -import { FieldMappingService } from '../../../../../../services'; +import { FieldMappingService, IndexService } from '../../../../../../services'; import { DataSourceProps } from '../../../../../../../types'; interface DetectorDataSourceProps extends DataSourceProps { diff --git a/public/pages/Detectors/components/UpdateFieldMappings/UpdateFieldMappings.tsx b/public/pages/Detectors/components/UpdateFieldMappings/UpdateFieldMappings.tsx index cd5b2ff97..b13be3dc5 100644 --- a/public/pages/Detectors/components/UpdateFieldMappings/UpdateFieldMappings.tsx +++ b/public/pages/Detectors/components/UpdateFieldMappings/UpdateFieldMappings.tsx @@ -5,9 +5,16 @@ import React, { Component } from 'react'; import { RouteComponentProps } from 'react-router-dom'; -import { EuiSmallButton, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle, EuiText } from '@elastic/eui'; +import { + EuiSmallButton, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, + EuiText, +} from '@elastic/eui'; import { FieldMapping } from '../../../../../models/interfaces'; -import FieldMappingService from '../../../../services/FieldMappingService'; +import { FieldMappingService } from '../../../../services/FieldMappingService'; import { DetectorHit, SearchDetectorsResponse } from '../../../../../server/models/interfaces'; import { BREADCRUMBS, EMPTY_DEFAULT_DETECTOR, ROUTES } from '../../../../utils/constants'; import { DetectorsService } from '../../../../services'; diff --git a/public/pages/Detectors/containers/FieldMappings/EditFieldMapping.tsx b/public/pages/Detectors/containers/FieldMappings/EditFieldMapping.tsx index b40d257b2..5d849179c 100644 --- a/public/pages/Detectors/containers/FieldMappings/EditFieldMapping.tsx +++ b/public/pages/Detectors/containers/FieldMappings/EditFieldMapping.tsx @@ -16,7 +16,7 @@ import { import FieldMappingsTable from '../../../CreateDetector/components/ConfigureFieldMapping/components/RequiredFieldMapping'; import { ContentPanel } from '../../../../components/ContentPanel'; import { FieldMapping } from '../../../../../models/interfaces'; -import FieldMappingService from '../../../../services/FieldMappingService'; +import { FieldMappingService } from '../../../../services/FieldMappingService'; import { MappingViewType } from '../../../CreateDetector/components/ConfigureFieldMapping/components/RequiredFieldMapping/FieldMappingsTable'; import { Detector } from '../../../../../types'; import { FieldMappingsTableItem } from '../../../CreateDetector/models/interfaces'; diff --git a/public/pages/ThreatIntel/containers/AddThreatIntelSource/AddThreatIntelSource.tsx b/public/pages/ThreatIntel/containers/AddThreatIntelSource/AddThreatIntelSource.tsx index 90c3ba9ff..638fc17b2 100644 --- a/public/pages/ThreatIntel/containers/AddThreatIntelSource/AddThreatIntelSource.tsx +++ b/public/pages/ThreatIntel/containers/AddThreatIntelSource/AddThreatIntelSource.tsx @@ -22,7 +22,7 @@ import { import { BREADCRUMBS, ROUTES, defaultIntervalUnitOptions } from '../../../../utils/constants'; import { Interval } from '../../../CreateDetector/components/DefineDetector/components/DetectorSchedule/Interval'; import { RouteComponentProps } from 'react-router-dom'; -import ThreatIntelService from '../../../../services/ThreatIntelService'; +import { ThreatIntelService } from '../../../../services'; import { FileUploadSource, S3ConnectionSource, diff --git a/public/pages/ThreatIntel/containers/Overview/ThreatIntelOverview.tsx b/public/pages/ThreatIntel/containers/Overview/ThreatIntelOverview.tsx index 5b5f26588..3a98c808f 100644 --- a/public/pages/ThreatIntel/containers/Overview/ThreatIntelOverview.tsx +++ b/public/pages/ThreatIntel/containers/Overview/ThreatIntelOverview.tsx @@ -15,7 +15,6 @@ import { EuiTabbedContent, EuiTabbedContentTab, EuiText, - EuiTitle, } from '@elastic/eui'; import React, { MouseEventHandler, useCallback, useEffect, useMemo } from 'react'; import { BREADCRUMBS, ROUTES } from '../../../../utils/constants'; @@ -30,7 +29,7 @@ import { RouteComponentProps } from 'react-router-dom'; import { ThreatIntelSourcesList } from '../../components/ThreatIntelSourcesList/ThreatIntelSourcesList'; import { deriveFormModelFromConfig, getThreatIntelNextStepsProps } from '../../utils/helpers'; import { ThreatIntelOverviewActions } from '../../components/ThreatIntelOverviewActions/ThreatIntelOverviewActions'; -import ThreatIntelService from '../../../../services/ThreatIntelService'; +import { ThreatIntelService } from '../../../../services'; import { ThreatIntelLogScanConfig } from '../../components/ThreatIntelLogScanConfig/ThreatIntelLogScanConfig'; import { setBreadcrumbs } from '../../../../utils/helpers'; import { PageHeader } from '../../../../components/PageHeader/PageHeader'; @@ -237,7 +236,7 @@ export const ThreatIntelOverview: React.FC = ({ - + {flyoutContent && ( setFlyoutContent(null)}> diff --git a/public/services/AlertsService.ts b/public/services/AlertsService.ts index 06a43742e..e4e28ab2d 100644 --- a/public/services/AlertsService.ts +++ b/public/services/AlertsService.ts @@ -16,7 +16,7 @@ import { import { dataSourceInfo } from './utils/constants'; import { errorNotificationToast } from '../utils/helpers'; -export default class AlertsService { +export class AlertsService { constructor(private httpClient: HttpSetup, private notifications: NotificationsStart) {} getAlerts = async ( @@ -24,7 +24,7 @@ export default class AlertsService { ): Promise> => { const { detectorType, - detector_id, + detector_id, // eslint-disable-line @typescript-eslint/naming-convention size, sortOrder, startIndex, @@ -59,9 +59,9 @@ export default class AlertsService { acknowledgeAlerts = async ( alertIds: string[], - detector_id: string + detectorId: string ): Promise> => { - const url = API.ACKNOWLEDGE_ALERTS.replace('{detector_id}', detector_id); + const url = API.ACKNOWLEDGE_ALERTS.replace('{detector_id}', detectorId); const body = JSON.stringify({ alerts: alertIds }); return await this.httpClient.post(`..${url}`, { body, diff --git a/public/services/CorrelationService.ts b/public/services/CorrelationService.ts index e0664b3a5..53d14db56 100644 --- a/public/services/CorrelationService.ts +++ b/public/services/CorrelationService.ts @@ -15,28 +15,27 @@ import { ICorrelationsService, UpdateCorrelationRuleResponse, GetCorrelationAlertsResponse, - AckCorrelationAlertsResponse + AckCorrelationAlertsResponse, } from '../../types'; import { dataSourceInfo } from './utils/constants'; -export default class CorrelationService implements ICorrelationsService { +export class CorrelationService implements ICorrelationsService { constructor(private httpClient: HttpSetup) {} acknowledgeCorrelationAlerts = async ( body: any - ): Promise> => { - const url = `..${API.ACK_CORRELATION_ALERTS}`; - - return (await this.httpClient.post(url, { - body: JSON.stringify({alertIds: body}), - query: { - dataSourceId: dataSourceInfo.activeDataSource.id, - }, - })) as ServerResponse; - }; + ): Promise> => { + const url = `..${API.ACK_CORRELATION_ALERTS}`; - getCorrelationAlerts = async ( - ): Promise> => { + return (await this.httpClient.post(url, { + body: JSON.stringify({ alertIds: body }), + query: { + dataSourceId: dataSourceInfo.activeDataSource.id, + }, + })) as ServerResponse; + }; + + getCorrelationAlerts = async (): Promise> => { const url = `..${API.GET_CORRELATION_ALERTS}`; return (await this.httpClient.get(url, { @@ -48,15 +47,15 @@ export default class CorrelationService implements ICorrelationsService { getCorrelatedFindings = async ( finding: string, - detector_type: string, - nearby_findings: number = 20 + detectorType: string, + nearbyFindings: number = 20 ): Promise> => { const url = `..${API.FINDINGS_BASE}/correlate`; return (await this.httpClient.get(url, { query: { finding, - detector_type, - nearby_findings, + detector_type: detectorType, + nearby_findings: nearbyFindings, dataSourceId: dataSourceInfo.activeDataSource.id, }, })) as ServerResponse; @@ -117,14 +116,14 @@ export default class CorrelationService implements ICorrelationsService { }; getAllCorrelationsInTimeWindow = async ( - start_time: string, - end_time: string + startTime: string, + endTime: string ): Promise> => { const url = `..${API.CORRELATIONS}`; return (await this.httpClient.get(url, { query: { - start_time, - end_time, + start_time: startTime, + end_time: endTime, dataSourceId: dataSourceInfo.activeDataSource.id, }, })) as ServerResponse; diff --git a/public/services/DetectorService.ts b/public/services/DetectorService.ts index 6f35019c5..2e0aa0494 100644 --- a/public/services/DetectorService.ts +++ b/public/services/DetectorService.ts @@ -15,7 +15,7 @@ import { API } from '../../server/utils/constants'; import { Detector, GetDetectorResponse, IDetectorService } from '../../types'; import { dataSourceInfo } from './utils/constants'; -export default class DetectorsService implements IDetectorService { +export class DetectorsService implements IDetectorService { constructor(private httpClient: HttpSetup) {} createDetector = async (detector: Detector): Promise> => { @@ -41,7 +41,7 @@ export default class DetectorsService implements IDetectorService { }, }), query: { - dataSourceId: dataSourceId, + dataSourceId, }, })) as ServerResponse; diff --git a/public/services/FieldMappingService.ts b/public/services/FieldMappingService.ts index c8def908c..e53d07f93 100644 --- a/public/services/FieldMappingService.ts +++ b/public/services/FieldMappingService.ts @@ -16,7 +16,7 @@ import { API } from '../../server/utils/constants'; import { FieldMapping } from '.././../models/interfaces'; import { dataSourceInfo } from './utils/constants'; -export default class FieldMappingService { +export class FieldMappingService { constructor(private readonly httpClient: HttpSetup) {} getMappingsView = async ( @@ -36,12 +36,12 @@ export default class FieldMappingService { }; createMappings = async ( - index_name: string, - rule_topic: string, + indexName: string, + ruleTopic: string, fieldMappings: FieldMapping[] ): Promise> => { const url = `..${API.MAPPINGS_BASE}`; - const alias_mappings: FieldMappingPropertyMap = { + const aliasMappings: FieldMappingPropertyMap = { properties: {}, }; fieldMappings.forEach((mapping) => { @@ -49,16 +49,16 @@ export default class FieldMappingService { return; } - alias_mappings.properties[mapping.ruleFieldName] = { + aliasMappings.properties[mapping.ruleFieldName] = { type: 'alias', path: mapping.indexFieldName, }; }); const fieldMappingPayload: CreateMappingBody = { - index_name, - rule_topic, + index_name: indexName, + rule_topic: ruleTopic, partial: true, - alias_mappings, + alias_mappings: aliasMappings, }; const params = { body: JSON.stringify(fieldMappingPayload), diff --git a/public/services/FindingsService.ts b/public/services/FindingsService.ts index 538e04396..d604a1ef4 100644 --- a/public/services/FindingsService.ts +++ b/public/services/FindingsService.ts @@ -15,7 +15,7 @@ import { import { dataSourceInfo } from './utils/constants'; import { errorNotificationToast } from '../utils/helpers'; -export default class FindingsService { +export class FindingsService { constructor(private httpClient: HttpSetup, private notifications: NotificationsStart) {} getFindings = async ( diff --git a/public/services/IndexPatternsService.ts b/public/services/IndexPatternsService.ts index d65d1ba42..3cf4d77ba 100644 --- a/public/services/IndexPatternsService.ts +++ b/public/services/IndexPatternsService.ts @@ -11,7 +11,7 @@ import { import { IndexPatternSavedObjectAttrs } from '../../../../src/plugins/data/common/index_patterns/index_patterns'; import { SavedObject } from '../../../../src/plugins/data/common'; -export default class IndexPatternsService { +export class IndexPatternsService { constructor(private coreIndexPatternsService: CoreIndexPatternsService) {} async getFieldsForWildcard(options: GetFieldsOptions) { @@ -23,7 +23,7 @@ export default class IndexPatternsService { } public getIndexPatterns = async (): Promise< - SavedObject[] | null | undefined + Array> | null | undefined > => { const indexPatterns = await this.coreIndexPatternsService.getCache(); diff --git a/public/services/IndexService.ts b/public/services/IndexService.ts index d761a4aec..423deb6cc 100644 --- a/public/services/IndexService.ts +++ b/public/services/IndexService.ts @@ -10,7 +10,7 @@ import { API } from '../../server/utils/constants'; import { IIndexService } from '../../types'; import { dataSourceInfo } from './utils/constants'; -export default class IndexService implements IIndexService { +export class IndexService implements IIndexService { httpClient: HttpSetup; constructor(httpClient: HttpSetup) { diff --git a/public/services/LogTypeService.ts b/public/services/LogTypeService.ts index 8607fb80b..228382a03 100644 --- a/public/services/LogTypeService.ts +++ b/public/services/LogTypeService.ts @@ -15,7 +15,7 @@ import { import { API } from '../../server/utils/constants'; import { dataSourceInfo } from './utils/constants'; -export default class LogTypeService { +export class LogTypeService { constructor(private httpClient: HttpSetup) {} createLogType = async (logType: LogTypeBase) => { diff --git a/public/services/MetricsService.ts b/public/services/MetricsService.ts index 03cb9f7eb..f588443e4 100644 --- a/public/services/MetricsService.ts +++ b/public/services/MetricsService.ts @@ -4,12 +4,12 @@ */ import { HttpSetup } from 'opensearch-dashboards/public'; +import _ from 'lodash'; import { MetricsCounter, PartialMetricsCounter } from '../../types'; import { API, DEFAULT_METRICS_COUNTER } from '../../server/utils/constants'; -import _ from 'lodash'; import { aggregateMetrics, getSecurityAnalyticsPluginConfig } from '../../common/helpers'; -export default class MetricsService { +export class MetricsService { private newMetricsAvailable = false; private metricsCounter: MetricsCounter = _.cloneDeep(DEFAULT_METRICS_COUNTER); private emitTimer: NodeJS.Timer | undefined = undefined; diff --git a/public/services/NotificationsService.ts b/public/services/NotificationsService.ts index 78d5b8610..ca13f6800 100644 --- a/public/services/NotificationsService.ts +++ b/public/services/NotificationsService.ts @@ -9,7 +9,7 @@ import { API } from '../../server/utils/constants'; import { GetChannelsResponse, GetNotificationConfigsResponse } from '../../types'; import { dataSourceInfo } from './utils/constants'; -export default class NotificationsService { +export class NotificationsService { httpClient: HttpSetup; constructor(httpClient: HttpSetup) { @@ -19,7 +19,7 @@ export default class NotificationsService { getChannel = async ( channelId: string ): Promise> => { - let url = `..${API.CHANNELS}/${channelId}`; + const url = `..${API.CHANNELS}/${channelId}`; const response = (await this.httpClient.get(url, { query: { dataSourceId: dataSourceInfo.activeDataSource.id, @@ -29,7 +29,7 @@ export default class NotificationsService { }; getChannels = async (): Promise> => { - let url = `..${API.CHANNELS}`; + const url = `..${API.CHANNELS}`; const response = (await this.httpClient.get(url, { query: { dataSourceId: dataSourceInfo.activeDataSource.id, @@ -38,13 +38,13 @@ export default class NotificationsService { return response; }; - getServerFeatures = async (): Promise>> => { - let url = `..${API.NOTIFICATION_FEATURES}`; + getServerFeatures = async (): Promise> => { + const url = `..${API.NOTIFICATION_FEATURES}`; const response = (await this.httpClient.get(url, { query: { dataSourceId: dataSourceInfo.activeDataSource.id, }, - })) as ServerResponse>; + })) as ServerResponse; return response; }; } diff --git a/public/services/OpenSearchService.ts b/public/services/OpenSearchService.ts index c7c3ca410..32ed58990 100644 --- a/public/services/OpenSearchService.ts +++ b/public/services/OpenSearchService.ts @@ -13,14 +13,14 @@ import { API } from '../../server/utils/constants'; import { dataSourceInfo } from './utils/constants'; import { SearchResponse } from '../../server/models/interfaces'; -export default class OpenSearchService { +export class OpenSearchService { constructor( private httpClient: HttpSetup, private savedObjectsClient: SavedObjectsClientContract ) {} - getPlugins = async (): Promise> => { - let url = `..${API.PLUGINS}`; + getPlugins = async (): Promise>> => { + const url = `..${API.PLUGINS}`; return await this.httpClient.get(url, { query: { dataSourceId: dataSourceInfo.activeDataSource.id, @@ -28,7 +28,7 @@ export default class OpenSearchService { }); }; - getIndexPatterns = async (): Promise[]> => { + getIndexPatterns = async (): Promise>> => { const indexPatterns = await this.savedObjectsClient .find<{ title: string }>({ type: 'index-pattern', @@ -41,7 +41,7 @@ export default class OpenSearchService { }; getDocuments = async (index: string, documentIds: string[]) => { - let url = `..${API.DOCUMENT_IDS_QUERY}`; + const url = `..${API.DOCUMENT_IDS_QUERY}`; const res: ServerResponse> = await this.httpClient.post(url, { query: { dataSourceId: dataSourceInfo.activeDataSource.id, diff --git a/public/services/RuleService.ts b/public/services/RuleService.ts index 03da90e5f..92ececcca 100644 --- a/public/services/RuleService.ts +++ b/public/services/RuleService.ts @@ -15,7 +15,7 @@ import { API } from '../../server/utils/constants'; import { Rule } from '../../types'; import { dataSourceInfo } from './utils/constants'; -export default class RuleService { +export class RuleService { httpClient: HttpSetup; constructor(httpClient: HttpSetup) { diff --git a/public/services/SavedObjectService.ts b/public/services/SavedObjectService.ts index 040a823cd..1f9de1494 100644 --- a/public/services/SavedObjectService.ts +++ b/public/services/SavedObjectService.ts @@ -12,7 +12,7 @@ import { IIndexService, ISavedObjectsService, ServerResponse } from '../../types import { getSavedObjectConfigs } from '../store/savedObjectsConfig'; import { logTypesWithDashboards } from '../utils/constants'; -export default class SavedObjectService implements ISavedObjectsService { +export class SavedObjectService implements ISavedObjectsService { constructor( private savedObjectsClient: SavedObjectsClientContract, private readonly indexService: IIndexService @@ -46,7 +46,7 @@ export default class SavedObjectService implements ISavedObjectsService { const detectorReferences = [ { id: detectorId, - name: name, + name, type: 'detector-SA', }, ]; @@ -94,7 +94,7 @@ export default class SavedObjectService implements ISavedObjectsService { }); dashboardReferences.push({ id: detectorId, - name: name, + name, type: 'detector-SA', }); @@ -116,7 +116,7 @@ export default class SavedObjectService implements ISavedObjectsService { response: dashboardCreationRes, }); } catch (error: any) { - console.error('Failed to create dashboard for log type ' + logType); + // No-op } } } @@ -125,7 +125,7 @@ export default class SavedObjectService implements ISavedObjectsService { } public getDashboards = async (): Promise< - SimpleSavedObject<{ references: SavedObjectReference[]; id?: string }>[] + Array> > => { const dashboards = await this.savedObjectsClient .find<{ references: SavedObjectReference[]; id?: string }>({ @@ -155,7 +155,7 @@ export default class SavedObjectService implements ISavedObjectsService { return dashboard; }; - public async getIndexPatterns(): Promise[]> { + public async getIndexPatterns(): Promise>> { const indexPatterns = await this.savedObjectsClient .find<{ title: string }>({ type: 'index-pattern', diff --git a/public/services/ThreatIntelService.ts b/public/services/ThreatIntelService.ts index 064732be5..fc8b1d215 100644 --- a/public/services/ThreatIntelService.ts +++ b/public/services/ThreatIntelService.ts @@ -15,7 +15,7 @@ import { dataSourceInfo } from './utils/constants'; import { API } from '../../server/utils/constants'; import { errorNotificationToast, successNotificationToast } from '../utils/helpers'; -export default class ThreatIntelService { +export class ThreatIntelService { constructor(private httpClient: HttpSetup, private notifications: NotificationsStart) {} addThreatIntelSource = async ( diff --git a/public/services/index.ts b/public/services/index.ts index 08ff2ff3e..d076878fd 100644 --- a/public/services/index.ts +++ b/public/services/index.ts @@ -4,19 +4,20 @@ */ import { SecurityAnalyticsContext, SaContextConsumer } from './SecurityAnalyticsContext'; -import DetectorsService from './DetectorService'; -import FindingsService from './FindingsService'; -import OpenSearchService from './OpenSearchService'; -import FieldMappingService from './FieldMappingService'; -import AlertsService from './AlertsService'; -import RuleService from './RuleService'; -import IndexService from './IndexService'; -import NotificationsService from './NotificationsService'; -import IndexPatternsService from './IndexPatternsService'; -import SavedObjectService from './SavedObjectService'; -import CorrelationService from './CorrelationService'; -import LogTypeService from './LogTypeService'; -import ThreatIntelService from './ThreatIntelService'; +import { DetectorsService } from './DetectorService'; +import { FindingsService } from './FindingsService'; +import { OpenSearchService } from './OpenSearchService'; +import { FieldMappingService } from './FieldMappingService'; +import { AlertsService } from './AlertsService'; +import { RuleService } from './RuleService'; +import { IndexService } from './IndexService'; +import { NotificationsService } from './NotificationsService'; +import { IndexPatternsService } from './IndexPatternsService'; +import { SavedObjectService } from './SavedObjectService'; +import { CorrelationService } from './CorrelationService'; +import { LogTypeService } from './LogTypeService'; +import { ThreatIntelService } from './ThreatIntelService'; +import { MetricsService } from './MetricsService'; export { SaContextConsumer, @@ -34,4 +35,5 @@ export { SavedObjectService, LogTypeService, ThreatIntelService, + MetricsService, }; diff --git a/public/services/utils/constants.ts b/public/services/utils/constants.ts index f85015c63..7f795b3c2 100644 --- a/public/services/utils/constants.ts +++ b/public/services/utils/constants.ts @@ -4,8 +4,8 @@ */ import { DataSourceOption } from 'src/plugins/data_source_management/public/components/data_source_menu/types'; -import { createGetterSetter } from '../../../../../src/plugins/opensearch_dashboards_utils/common'; import { CoreStart, IUiSettingsClient, NotificationsStart } from 'opensearch-dashboards/public'; +import { createGetterSetter } from '../../../../../src/plugins/opensearch_dashboards_utils/common'; import { NavigationPublicPluginStart } from '../../../../../src/plugins/navigation/public'; import { ContentManagementPluginStart } from '../../../../../src/plugins/content_management/public'; import { BrowserServices } from '../../models/interfaces'; diff --git a/public/store/AlertsStore.ts b/public/store/AlertsStore.ts index 13e8440af..1cfee78b0 100644 --- a/public/store/AlertsStore.ts +++ b/public/store/AlertsStore.ts @@ -77,7 +77,7 @@ export class AlertsStore { ) { let allAlerts: any[] = []; const maxAlertsReturned = alertCount ?? 25; - let startIndex = 0; + const startIndex = 0; const getAlertsRes = await this.service.getAlerts({ detector_id: detectorId, @@ -152,7 +152,7 @@ export class AlertsStore { return { ...alert, - detectorName: detectorName, + detectorName, }; }); } diff --git a/public/store/CorrelationsStore.ts b/public/store/CorrelationsStore.ts index 28b36931a..118cf75bd 100644 --- a/public/store/CorrelationsStore.ts +++ b/public/store/CorrelationsStore.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { NotificationsStart } from 'opensearch-dashboards/public'; import { AckCorrelationAlertsResponse, CorrelationFieldCondition, @@ -15,11 +16,9 @@ import { IRulesStore, } from '../../types'; import { DetectorsService, FindingsService, CorrelationService } from '../services'; -import { NotificationsStart } from 'opensearch-dashboards/public'; import { errorNotificationToast } from '../utils/helpers'; import { DEFAULT_EMPTY_DATA } from '../utils/constants'; import { DataStore } from './DataStore'; -import { RuleSource } from '../../server/models/interfaces'; import { RuleSeverityPriority, RuleSeverityValue } from '../pages/Rules/utils/constants'; export interface ICorrelationsCache { @@ -73,11 +72,11 @@ export class CorrelationsStore implements ICorrelationsStore { }; if (queryString) { - correlationInput['query'] = queryString; + correlationInput.query = queryString; } if (query.field) { - correlationInput['field'] = query.field; + correlationInput.field = query.field; } return correlationInput; @@ -107,11 +106,11 @@ export class CorrelationsStore implements ICorrelationsStore { }; if (queryString) { - correlationInput['query'] = queryString; + correlationInput.query = queryString; } if (query.field) { - correlationInput['field'] = query.field; + correlationInput.field = query.field; } return correlationInput; @@ -150,7 +149,7 @@ export class CorrelationsStore implements ICorrelationsStore { name: hit._source.name, time_window: hit._source.time_window || 300000, queries, - trigger: hit._source?.trigger + trigger: hit._source?.trigger, }; } @@ -176,7 +175,7 @@ export class CorrelationsStore implements ICorrelationsStore { name: hit._source.name, time_window: hit._source.time_window || 300000, queries, - trigger: hit._source?.trigger + trigger: hit._source?.trigger, }; }); } @@ -194,10 +193,10 @@ export class CorrelationsStore implements ICorrelationsStore { return response.ok; } - public async getCorrelationsCountInWindow(start_time: string, end_time: string): Promise { + public async getCorrelationsCountInWindow(startTime: string, endTime: string): Promise { const allCorrelationsRes = await this.service.getAllCorrelationsInTimeWindow( - start_time, - end_time + startTime, + endTime ); if (allCorrelationsRes.ok) { @@ -208,15 +207,15 @@ export class CorrelationsStore implements ICorrelationsStore { } public async getAllCorrelationsInWindow( - start_time: string, - end_time: string - ): Promise<{ finding1: CorrelationFinding; finding2: CorrelationFinding }[]> { + startTime: string, + endTime: string + ): Promise> { const allCorrelationsRes = await this.service.getAllCorrelationsInTimeWindow( - start_time, - end_time + startTime, + endTime ); - const result: { finding1: CorrelationFinding; finding2: CorrelationFinding }[] = []; + const result: Array<{ finding1: CorrelationFinding; finding2: CorrelationFinding }> = []; if (allCorrelationsRes.ok) { const firstTenGrandCorrelations = allCorrelationsRes.response.findings.slice(0, 10000); @@ -275,7 +274,7 @@ export class CorrelationsStore implements ICorrelationsStore { detectorsRes.response.hits.hits.forEach((detector) => { detectorsMap[detector._id] = detector; }); - let findingsMap: { [id: string]: CorrelationFinding } = {}; + const findingsMap: { [id: string]: CorrelationFinding } = {}; const findings = await DataStore.findings.getFindingsByIds(findingIds); findings.forEach((f) => { const detector = detectorsMap[f.detectorId]; @@ -288,13 +287,13 @@ export class CorrelationsStore implements ICorrelationsStore { : 1; }); - const rule = allRules.find((rule) => rule._id === matchedRules[0]?._id); + const rule = allRules.find((item) => item._id === matchedRules[0]?._id); findingsMap[f.id] = { ...f, id: f.id, logType: detector._source.detector_type, - detector: detector, + detector, detectorName: detector._source.name, timestamp: new Date(f.timestamp).toLocaleString(), detectionRule: rule @@ -315,13 +314,13 @@ export class CorrelationsStore implements ICorrelationsStore { public async getCorrelatedFindings( findingId: string, - detector_type: string, - nearby_findings = 20 + detectorType: string, + nearbyFindings = 20 ): Promise<{ finding: CorrelationFinding; correlatedFindings: CorrelationFinding[] }> { const response = await this.service.getCorrelatedFindings( findingId, - detector_type, - nearby_findings + detectorType, + nearbyFindings ); if (response?.ok) { @@ -350,7 +349,7 @@ export class CorrelationsStore implements ICorrelationsStore { finding: { ...finding, id: findingId, - logType: detector_type, + logType: detectorType, timestamp: '', detectionRule: { name: '', severity: 'high' }, }, diff --git a/public/store/DataStore.ts b/public/store/DataStore.ts index dc07ee04e..563707465 100644 --- a/public/store/DataStore.ts +++ b/public/store/DataStore.ts @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { NotificationsStart } from 'opensearch-dashboards/public'; import { RulesStore } from './RulesStore'; import { BrowserServices } from '../models/interfaces'; -import { NotificationsStart } from 'opensearch-dashboards/public'; import { DetectorsStore } from './DetectorsStore'; import { CorrelationsStore } from './CorrelationsStore'; import { FindingsStore } from './FindingsStore'; diff --git a/public/store/DetectorsStore.tsx b/public/store/DetectorsStore.tsx index e050eaae5..b5db18a6c 100644 --- a/public/store/DetectorsStore.tsx +++ b/public/store/DetectorsStore.tsx @@ -4,18 +4,18 @@ */ import React from 'react'; -import { DetectorsService } from '../services'; import { NotificationsStart } from 'opensearch-dashboards/public'; +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { Toast } from '@opensearch-project/oui/src/eui_components/toast/global_toast_list'; +import { RouteComponentProps } from 'react-router-dom'; +import { v4 as uuidv4 } from 'uuid'; +import { DetectorsService } from '../services'; import { CreateDetectorState } from '../pages/CreateDetector/containers/CreateDetector'; import { ICalloutProps, resolveType, TCalloutColor } from '../pages/Main/components/Callout'; import { CreateDetectorResponse, ISavedObjectsService, ServerResponse } from '../../types'; import { CreateMappingsResponse } from '../../server/models/interfaces'; import { logTypesWithDashboards, ROUTES } from '../utils/constants'; -import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { Toast } from '@opensearch-project/oui/src/eui_components/toast/global_toast_list'; -import { RouteComponentProps } from 'react-router-dom'; import { DataStore } from './DataStore'; -import { v4 as uuidv4 } from 'uuid'; export interface IDetectorsStore { readonly service: DetectorsService; @@ -38,7 +38,7 @@ export interface IDetectorsStore { } export interface IDetectorsState { - pendingRequests: Promise[]; + pendingRequests: Array>; detectorInput: CreateDetectorState; } @@ -141,7 +141,7 @@ export class DetectorsStore implements IDetectorsStore { { - btnHandler && btnHandler(e); + btnHandler?.(e); this.hideCallout(); closeAllToasts(); }} @@ -273,8 +273,8 @@ export class DetectorsStore implements IDetectorsStore { setTimeout(() => this.hideCallout(), 3000); return Promise.resolve({ - detectorId: detectorId, - dashboardId: dashboardId, + detectorId, + dashboardId, ok: true, }); } @@ -290,8 +290,8 @@ export class DetectorsStore implements IDetectorsStore { ) => { return this.savedObjectsService .createSavedObject(detectorName, logType, detectorId, inputIndices) - .catch((error: any) => { - console.error(error); + .catch((_error: any) => { + // No op }); }; diff --git a/public/store/DocumentStore.ts b/public/store/DocumentStore.ts index e97922a54..9710bc161 100644 --- a/public/store/DocumentStore.ts +++ b/public/store/DocumentStore.ts @@ -10,7 +10,10 @@ export class DocumentStore { constructor(private opensearchService: OpenSearchService) {} - public async getDocuments(index: string, ids: string[]): Promise<{ [id: string]: string }[]> { + public async getDocuments( + index: string, + ids: string[] + ): Promise> { if (!this.documentsByIndex[index]) { this.documentsByIndex[index] = {}; } diff --git a/public/store/FindingsStore.ts b/public/store/FindingsStore.ts index ef0800233..faa9d6128 100644 --- a/public/store/FindingsStore.ts +++ b/public/store/FindingsStore.ts @@ -4,6 +4,7 @@ */ import React from 'react'; +import { NotificationsStart } from 'opensearch-dashboards/public'; import { CorrelationService, DetectorsService, @@ -11,7 +12,6 @@ import { IndexPatternsService, OpenSearchService, } from '../services'; -import { NotificationsStart } from 'opensearch-dashboards/public'; import { errorNotificationToast } from '../utils/helpers'; import { DetectorHit, @@ -70,8 +70,6 @@ export interface IFindingsStore { closeFlyout: () => void; } -export interface IFindingsCache {} - /** * Findings store * @@ -81,9 +79,9 @@ export interface IFindingsCache {} */ export class FindingsStore implements IFindingsStore { constructor( - readonly service: FindingsService, - readonly detectorsService: DetectorsService, - readonly notifications: NotificationsStart, + public readonly service: FindingsService, + public readonly detectorsService: DetectorsService, + public readonly notifications: NotificationsStart, private readonly indexPatternsService: IndexPatternsService, private readonly correlationService: CorrelationService, private readonly opensearchService: OpenSearchService @@ -142,7 +140,7 @@ export class FindingsStore implements IFindingsStore { allFindings = [...extendedFindings]; let remainingFindings = firstGetFindingsRes.response.total_findings - findingsSize; let startIndex = findingsSize + 1; - const getFindingsPromises: Promise>[] = []; + const getFindingsPromises: Array>> = []; while (remainingFindings > 0) { if (signal.aborted) { @@ -194,7 +192,7 @@ export class FindingsStore implements IFindingsStore { if (detectorsRes.ok) { const detectors = detectorsRes.response.hits.hits; - for (let detector of detectors) { + for (const detector of detectors) { const findings = await this.getFindingsPerDetector( detector._id, detector, @@ -260,7 +258,7 @@ export class FindingsStore implements IFindingsStore { ...finding, detectorName: detector._source.name, logType: detector._source.detector_type, - detector: detector, + detector, correlations: [], }; }); diff --git a/public/store/LogTypeStore.ts b/public/store/LogTypeStore.ts index f1fb07cdd..35277255a 100644 --- a/public/store/LogTypeStore.ts +++ b/public/store/LogTypeStore.ts @@ -5,7 +5,7 @@ import { NotificationsStart } from 'opensearch-dashboards/public'; import { LogType, LogTypeBase, LogTypeWithRules, RuleItemInfoBase } from '../../types'; -import LogTypeService from '../services/LogTypeService'; +import { LogTypeService } from '../services/LogTypeService'; import { errorNotificationToast } from '../utils/helpers'; import { DataStore } from './DataStore'; import { ruleTypes } from '../pages/Rules/utils/constants'; @@ -73,7 +73,7 @@ export class LogTypeStore { ); // Set log category types - for (const key in logTypesByCategories) { + for (const key of Object.keys(logTypesByCategories)) { delete logTypesByCategories[key]; } logTypes.forEach((logType) => { diff --git a/public/store/RulesStore.ts b/public/store/RulesStore.ts index 368cfd9fd..f7e0aa1e1 100644 --- a/public/store/RulesStore.ts +++ b/public/store/RulesStore.ts @@ -3,13 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { load, dump } from 'js-yaml'; +import { NotificationsStart } from 'opensearch-dashboards/public'; +import _ from 'lodash'; import { RuleService } from '../services'; -import { load, safeDump } from 'js-yaml'; import { RuleItemInfoBase, IRulesStore, IRulesCache, Rule } from '../../types'; -import { NotificationsStart } from 'opensearch-dashboards/public'; import { errorNotificationToast } from '../utils/helpers'; import { ruleTypes } from '../pages/Rules/utils/constants'; -import _ from 'lodash'; /** * Class is used to make rule's API calls and cache the rules. @@ -100,10 +100,11 @@ export class RulesStore implements IRulesStore { * @returns {Promise} */ public async getRules( - prePackaged: boolean, - terms?: { [key: string]: string[] } + ...args: [prePackaged: boolean, terms?: { [key: string]: string[] }, query?: any] ): Promise { - const cacheKey: string = `getRules:${JSON.stringify(arguments)}`; + const [prePackaged, inputTerms] = args; + let terms = inputTerms; + const cacheKey: string = `getRules:${JSON.stringify(args)}`; if (this.cache[cacheKey]) { return this.cache[cacheKey]; @@ -208,9 +209,11 @@ export class RulesStore implements IRulesStore { let detectionYaml = ''; try { - const detectionJson = load(ruleInfo._source.rule).detection; - detectionYaml = safeDump(detectionJson); - } catch (_error: any) {} + const detectionJson = (load(ruleInfo._source.rule) as any).detection; + detectionYaml = dump(detectionJson); + } catch (_error: any) { + // No op + } return { ...ruleInfo, diff --git a/public/utils/constants.ts b/public/utils/constants.ts index 87e36ea26..5f38cbf52 100644 --- a/public/utils/constants.ts +++ b/public/utils/constants.ts @@ -4,14 +4,13 @@ */ import { SimpleSavedObject } from 'opensearch-dashboards/public'; -import { Detector, LogType, ServerResponse } from '../../types'; -import { DetectorInput, PeriodSchedule } from '../../models/interfaces'; -import { DetectorHit } from '../../server/models/interfaces'; import _ from 'lodash'; import { euiPaletteColorBlind, euiPaletteForStatus } from '@elastic/eui'; import { DataSourceOption } from 'src/plugins/data_source_management/public'; import { BehaviorSubject } from 'rxjs'; -import { i18n } from '@osd/i18n'; +import { DetectorHit } from '../../server/models/interfaces'; +import { DetectorInput, PeriodSchedule } from '../../models/interfaces'; +import { Detector, LogType, ServerResponse } from '../../types'; export const DATE_MATH_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; export const MAX_RECENTLY_USED_TIME_RANGES = 5; @@ -221,7 +220,7 @@ export const pendingDashboardCreations: { [detectorId: string]: undefined | Promise>>; } = {}; -export const logTypeCategoryDescription: { name: string; description: string }[] = [ +export const logTypeCategoryDescription: Array<{ name: string; description: string }> = [ { name: 'Access Management', description: 'User access, authentication, group management' }, { name: 'Applications', description: 'Application lifecycle, API, and web resources activities' }, { name: 'Cloud Services', description: 'Services managed by cloud providers' }, @@ -309,16 +308,7 @@ export const ALERT_SEVERITY_PROPS = { }, }; -const LocalCluster: DataSourceOption = { - label: i18n.translate('dataSource.localCluster', { - defaultMessage: 'Local cluster', - }), - id: '', -}; - // We should use empty object for default value as local cluster may be disabled export const dataSourceObservable = new BehaviorSubject({}); export const DATA_SOURCE_NOT_SET_ERROR = 'Data source is not set'; - - diff --git a/public/utils/helpers.tsx b/public/utils/helpers.tsx index 14527df34..c70e6dd54 100644 --- a/public/utils/helpers.tsx +++ b/public/utils/helpers.tsx @@ -17,8 +17,22 @@ import { EuiEmptyPrompt, } from '@elastic/eui'; import moment from 'moment'; -import { PeriodSchedule } from '../../models/interfaces'; import React from 'react'; +import { + ChromeBreadcrumb, + CoreStart, + NotificationsStart, + SavedObject, +} from 'opensearch-dashboards/public'; +import _ from 'lodash'; +import { euiThemeVars } from '@osd/ui-shared-deps/theme'; +import dateMath from '@elastic/datemath'; +import { parse, View } from 'vega/build-es5/vega.js'; +import { compile } from 'vega-lite'; +import { Handler } from 'vega-tooltip'; +import { expressionInterpreter as vegaExpressionInterpreter } from 'vega-interpreter/build/vega-interpreter'; +import semver from 'semver'; +import { PeriodSchedule } from '../../models/interfaces'; import { ALERT_SEVERITY_OPTIONS, ALERT_SEVERITY_PROPS, @@ -35,34 +49,28 @@ import { RuleItemInfo, } from '../pages/CreateDetector/components/DefineDetector/components/DetectionRules/types/interfaces'; import { RuleInfo } from '../../server/models/interfaces'; -import { - ChromeBreadcrumb, - CoreStart, - NotificationsStart, - SavedObject, -} from 'opensearch-dashboards/public'; import { AlertsService, + CorrelationService, FieldMappingService, IndexPatternsService, IndexService, LogTypeService, NotificationsService, OpenSearchService, + DetectorsService, + FindingsService, + MetricsService, + RuleService, + SavedObjectService, + ThreatIntelService, } from '../services'; import { ruleSeverity, ruleTypes } from '../pages/Rules/utils/constants'; -import _ from 'lodash'; import { AlertCondition, DateTimeFilter, Duration, LogType } from '../../types'; import { DataStore } from '../store/DataStore'; import { LogCategoryOptionView } from '../components/Utility/LogCategoryOption'; import { getLogTypeLabel } from '../pages/LogTypes/utils/helpers'; -import { euiThemeVars } from '@osd/ui-shared-deps/theme'; -import dateMath from '@elastic/datemath'; import { IocLabel, ThreatIntelIocType } from '../../common/constants'; -import { parse, View } from 'vega/build-es5/vega.js'; -import { compile } from 'vega-lite'; -import { Handler } from 'vega-tooltip'; -import { expressionInterpreter as vegaExpressionInterpreter } from 'vega-interpreter/build/vega-interpreter'; import { getBreadCrumbsSetter, getBrowserServices, @@ -71,16 +79,8 @@ import { setBrowserServices, getDataSourceManagementPlugin, } from '../services/utils/constants'; -import DetectorsService from '../services/DetectorService'; -import CorrelationService from '../services/CorrelationService'; -import FindingsService from '../services/FindingsService'; -import RuleService from '../services/RuleService'; -import SavedObjectService from '../services/SavedObjectService'; -import MetricsService from '../services/MetricsService'; -import ThreatIntelService from '../services/ThreatIntelService'; import { BrowserServices } from '../models/interfaces'; import { IndexPatternsService as CoreIndexPatternsService } from '../../../../src/plugins/data/common/index_patterns'; -import semver from 'semver'; import * as pluginManifest from '../../opensearch_dashboards.json'; import { DataSourceThreatAlertsCard } from '../components/DataSourceThreatAlertsCard/DataSourceThreatAlertsCard'; import { DataSourceAttributes } from '../../../../src/plugins/data_source/common/data_sources'; @@ -96,7 +96,7 @@ export const renderTime = (time: number | string) => { }; export function createTextDetailsGroup( - data: { label: string; content: any; url?: string; target?: string }[] + data: Array<{ label: string; content: any; url?: string; target?: string }> ) { const createFormRow = ( label: string, @@ -225,19 +225,17 @@ export async function renderVisualization(spec: any, containerId: string) { try { setDefaultColors(spec); - renderVegaSpec(compile({ ...spec, width: 'container', height: 400 }).spec).catch((err: Error) => - console.error(err) - ); + renderVegaSpec(compile({ ...spec, width: 'container', height: 400 }).spec); } catch (error) { - console.error(error); + // No op } - async function renderVegaSpec(spec: {}) { + async function renderVegaSpec(compiledSpec: {}) { let chartColoredItems: any[] = []; const handler = new Handler({ formatTooltip: (value, sanitize) => { - let tooltipData = { ...value }; - let values = Object.entries(tooltipData); + const tooltipData = { ...value }; + const values = Object.entries(tooltipData); if (!values.length) return ''; const tooltipItem = chartColoredItems.filter((groupItem: any) => _.isEqual(groupItem.tooltip, tooltipData) @@ -276,18 +274,18 @@ export async function renderVisualization(spec: any, containerId: string) { `; }, }); - view = new View(parse(spec, undefined, { expr: vegaExpressionInterpreter } as any), { + view = new View(parse(compiledSpec, undefined, { expr: vegaExpressionInterpreter } as any), { renderer: 'canvas', // renderer (canvas or svg) container: `#${containerId}`, // parent DOM container hover: true, // enable hover processing }); view.tooltip(handler.call); - return view.runAsync().then((view: any) => { - const items = view.scenegraph().root.items[0].items || []; + return view.runAsync().then((updatedView: any) => { + const items = updatedView.scenegraph().root.items[0].items || []; const groups = items.filter( (item: any) => item.name && item.name.match(/^(layer_).*(_marks)$/) ); - for (let item of groups) { + for (const item of groups) { chartColoredItems = chartColoredItems.concat(item.items); } }); @@ -335,7 +333,6 @@ export const errorNotificationToast = ( return; } const message = `Failed to ${actionName} ${objectName}:`; - console.error(message, errorMessage); notifications?.toasts.addDanger({ title: message, text: errorMessage, @@ -392,9 +389,9 @@ export const getSeverityBadge = (severity: string) => { ); }; -export function formatToLogTypeOptions(logTypesByCategories: { [category: string]: LogType[] }) { +export function formatToLogTypeOptions(logTypesByCategory: { [category: string]: LogType[] }) { return logTypeCategories.map((category) => { - const logTypes = logTypesByCategories[category]; + const logTypes = logTypesByCategory[category]; return { label: category, value: category, @@ -492,7 +489,10 @@ export async function getDataSources( ): Promise< | { ok: true; - dataSources: { label: string; options: { label: string; value: string; index?: string }[] }[]; + dataSources: Array<{ + label: string; + options: Array<{ label: string; value: string; index?: string }>; + }>; } | { ok: false; error: string } > { @@ -507,7 +507,7 @@ export async function getDataSources( ); const aliasOptions = aliases.map(({ alias, index }) => ({ label: alias, - index: index, + index, value: alias, })); @@ -624,11 +624,11 @@ export function getIsNotificationPluginInstalled(): boolean { export async function getFieldsForIndex( fieldMappingService: FieldMappingService, indexName: string -): Promise<{ label: string; value: string }[]> { - let fields: { +): Promise> { + let fields: Array<{ label: string; value: string; - }[] = []; + }> = []; if (indexName) { const result = await fieldMappingService.getIndexAliasFields(indexName); diff --git a/test/mocks/services/fieldMappingService.mock.ts b/test/mocks/services/fieldMappingService.mock.ts index 91d779982..7e49affd5 100644 --- a/test/mocks/services/fieldMappingService.mock.ts +++ b/test/mocks/services/fieldMappingService.mock.ts @@ -1,4 +1,4 @@ -import FieldMappingService from '../../../public/services/FieldMappingService'; +import { FieldMappingService } from '../../../public/services'; import httpClientMock from './httpClient.mock'; const fieldMappingService = new FieldMappingService(httpClientMock); diff --git a/test/mocks/services/findingsService.mock.ts b/test/mocks/services/findingsService.mock.ts index ef8d2d96c..01d2661d3 100644 --- a/test/mocks/services/findingsService.mock.ts +++ b/test/mocks/services/findingsService.mock.ts @@ -1,7 +1,8 @@ import httpClientMock from './httpClient.mock'; import { FindingsService } from '../../../public/services'; +import notificationsMock from './notifications'; -const findingsService = new FindingsService(httpClientMock); +const findingsService = new FindingsService(httpClientMock, notificationsMock.NotificationsStart); Object.assign(findingsService, { getFindings: () => diff --git a/test/mocks/services/indexService.mock.ts b/test/mocks/services/indexService.mock.ts index c46f1afbf..d8b7d7cae 100644 --- a/test/mocks/services/indexService.mock.ts +++ b/test/mocks/services/indexService.mock.ts @@ -2,7 +2,7 @@ import httpClientMock from './httpClient.mock'; import { IndexService } from '../../../public/services'; jest.fn(); -const indexServiceMock = { +const indexServiceMock: IndexService = { getIndices: () => Promise.resolve({ ok: true, @@ -10,6 +10,10 @@ const indexServiceMock = { indices: [], }, }), + updateAliases: jest.fn(), + getAliases: jest.fn(), + getIndexFields: jest.fn(), + httpClient: httpClientMock, }; const indexService = new IndexService(httpClientMock); Object.assign(indexService, indexServiceMock); diff --git a/test/mocks/services/savedObjectService.mock.ts b/test/mocks/services/savedObjectService.mock.ts index 7ca1a4325..c25cd7b05 100644 --- a/test/mocks/services/savedObjectService.mock.ts +++ b/test/mocks/services/savedObjectService.mock.ts @@ -6,12 +6,13 @@ import { ISavedObjectsService } from '../../../types'; import { SavedObjectService } from '../../../public/services'; import savedObjectsClientMock from './savedObjectsClient.mock'; +import { indexServiceMock } from './indexService.mock'; jest.fn(); const savedObjectsServiceMock = { getDashboards: () => Promise.resolve([{ references: [], id: 'dashboardId' }]), }; -const savedObjectsService = new SavedObjectService(savedObjectsClientMock); +const savedObjectsService = new SavedObjectService(savedObjectsClientMock, indexServiceMock); Object.assign(savedObjectsService, savedObjectsServiceMock); export { savedObjectsServiceMock }; From 5a68b20a73d45084d98fe17bc4142fcb0dcaa339 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Tue, 3 Dec 2024 15:53:27 -0800 Subject: [PATCH 2/2] fixed UTs Signed-off-by: Amardeepsingh Siglani --- .eslintrc | 9 ------ public/components/Modal/Modal.test.tsx | 8 ++--- .../Alerts/__snapshots__/Alerts.test.tsx.snap | 18 +++++++++-- .../DetectorDetails.test.tsx.snap | 32 ++++++++++++++++--- .../RuleEditor/DetectionVisualEditor.test.tsx | 24 ++++++++++++++ .../RuleEditor/DetectionVisualEditor.mock.ts | 1 + 6 files changed, 73 insertions(+), 19 deletions(-) delete mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index ef199f39e..000000000 --- a/.eslintrc +++ /dev/null @@ -1,9 +0,0 @@ ---- -extends: "@elastic/kibana" - -settings: - import/resolver: - '@elastic/eslint-import-resolver-kibana': - rootPackageName: 'opensearch_security_analytics_dashboards' - pluginPaths: - - . diff --git a/public/components/Modal/Modal.test.tsx b/public/components/Modal/Modal.test.tsx index 7b2257657..45e6f1fd1 100644 --- a/public/components/Modal/Modal.test.tsx +++ b/public/components/Modal/Modal.test.tsx @@ -27,7 +27,7 @@ describe(' spec', () => { ); - expect(container.firstChild).to.be.null; + expect(container.firstChild).toBeNull(); }); it('renders a modal that can close and open', () => { @@ -60,14 +60,14 @@ describe(' spec', () => { ); - expect(queryByText('A modal that has interesting text')).to.be.null; + expect(queryByText('A modal that has interesting text')).toBeNull(); fireEvent.click(getByTestId('showModal')); - expect(queryByText('A modal that has interesting text')).not.to.be.null; + expect(queryByText('A modal that has interesting text')).not.toBeNull(); fireEvent.click(getByLabelText('Closes this modal window')); - expect(queryByText('A modal that has interesting text')).to.be.null; + expect(queryByText('A modal that has interesting text')).toBeNull(); }); }); diff --git a/public/pages/Alerts/containers/Alerts/__snapshots__/Alerts.test.tsx.snap b/public/pages/Alerts/containers/Alerts/__snapshots__/Alerts.test.tsx.snap index 2899073d5..0c6d738e2 100644 --- a/public/pages/Alerts/containers/Alerts/__snapshots__/Alerts.test.tsx.snap +++ b/public/pages/Alerts/containers/Alerts/__snapshots__/Alerts.test.tsx.snap @@ -47,7 +47,14 @@ exports[` spec renders the component 1`] = ` "getFindings": [Function], "getThreatIntelFindings": [Function], "httpClient": [MockFunction], - "notifications": undefined, + "notifications": Object { + "toasts": Object { + "addDanger": [MockFunction], + "addInfo": [MockFunction], + "addSuccess": [MockFunction], + "addWarning": [MockFunction], + }, + }, } } match={[MockFunction]} @@ -133,7 +140,14 @@ exports[` spec renders the component 1`] = ` "getFindings": [Function], "getThreatIntelFindings": [Function], "httpClient": [MockFunction], - "notifications": undefined, + "notifications": Object { + "toasts": Object { + "addDanger": [MockFunction], + "addInfo": [MockFunction], + "addSuccess": [MockFunction], + "addWarning": [MockFunction], + }, + }, } } history={ diff --git a/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap b/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap index 64ec5f51a..84c080ec8 100644 --- a/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap +++ b/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap @@ -226,7 +226,13 @@ exports[` spec renders the component 1`] = ` "deleteVisualization": [Function], "getDashboard": [Function], "getDashboards": [Function], - "indexService": undefined, + "indexService": Object { + "getAliases": [MockFunction], + "getIndexFields": [MockFunction], + "getIndices": [Function], + "httpClient": [MockFunction], + "updateAliases": [MockFunction], + }, "savedObjectsClient": Object { "delete": [MockFunction], "get": [MockFunction], @@ -1042,7 +1048,13 @@ exports[` spec renders the component 1`] = ` "deleteVisualization": [Function], "getDashboard": [Function], "getDashboards": [Function], - "indexService": undefined, + "indexService": Object { + "getAliases": [MockFunction], + "getIndexFields": [MockFunction], + "getIndices": [Function], + "httpClient": [MockFunction], + "updateAliases": [MockFunction], + }, "savedObjectsClient": Object { "delete": [MockFunction], "get": [MockFunction], @@ -1468,7 +1480,13 @@ exports[` spec renders the component 1`] = ` "deleteVisualization": [Function], "getDashboard": [Function], "getDashboards": [Function], - "indexService": undefined, + "indexService": Object { + "getAliases": [MockFunction], + "getIndexFields": [MockFunction], + "getIndices": [Function], + "httpClient": [MockFunction], + "updateAliases": [MockFunction], + }, "savedObjectsClient": Object { "delete": [MockFunction], "get": [MockFunction], @@ -2743,7 +2761,13 @@ exports[` spec renders the component 1`] = ` "deleteVisualization": [Function], "getDashboard": [Function], "getDashboards": [Function], - "indexService": undefined, + "indexService": Object { + "getAliases": [MockFunction], + "getIndexFields": [MockFunction], + "getIndices": [Function], + "httpClient": [MockFunction], + "updateAliases": [MockFunction], + }, "savedObjectsClient": Object { "delete": [MockFunction], "get": [MockFunction], diff --git a/public/pages/Rules/components/RuleEditor/DetectionVisualEditor.test.tsx b/public/pages/Rules/components/RuleEditor/DetectionVisualEditor.test.tsx index f48d79979..cb5335dd7 100644 --- a/public/pages/Rules/components/RuleEditor/DetectionVisualEditor.test.tsx +++ b/public/pages/Rules/components/RuleEditor/DetectionVisualEditor.test.tsx @@ -5,10 +5,34 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { expect } from '@jest/globals'; import { DetectionVisualEditor } from './DetectionVisualEditor'; import DetectionVisualEditorMock from '../../../../../test/mocks/Rules/components/RuleEditor/DetectionVisualEditor.mock'; describe(' spec', () => { + beforeAll(() => { + function at(this: any[], n: number) { + // ToInteger() abstract op + n = Math.trunc(n) || 0; + // Allow negative indexing from the end + if (n < 0) n += this.length; + // OOB access is guaranteed to return undefined + if (n < 0 || n >= this.length) return undefined; + // Otherwise, this is just normal property access + return this[n]; + } + + const TypedArray = Reflect.getPrototypeOf(Int8Array); + for (const C of [Array, String, TypedArray]) { + Object.defineProperty((C as any).prototype, 'at', { + value: at, + writable: true, + enumerable: false, + configurable: true, + }); + } + }); + it('renders the component', () => { const tree = render(); expect(tree).toMatchSnapshot(); diff --git a/test/mocks/Rules/components/RuleEditor/DetectionVisualEditor.mock.ts b/test/mocks/Rules/components/RuleEditor/DetectionVisualEditor.mock.ts index 74974f865..0fa37c01f 100644 --- a/test/mocks/Rules/components/RuleEditor/DetectionVisualEditor.mock.ts +++ b/test/mocks/Rules/components/RuleEditor/DetectionVisualEditor.mock.ts @@ -11,4 +11,5 @@ export default { setIsDetectionInvalid: () => {}, mode: 'create', isInvalid: false, + goToYamlEditor: jest.fn(), } as DetectionVisualEditorProps;