@oneuptime/common 13.0.4 → 13.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/RumApplication.ts +1 -1
- package/Models/DatabaseModels/SecurityEventConnection.ts +457 -0
- package/Models/DatabaseModels/SecurityEventConnectionRun.ts +263 -0
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +2 -2
- package/Server/API/AIInvestigationAPI.ts +484 -24
- package/Server/API/GoogleSecOpsConnectionAPI.ts +249 -8
- package/Server/API/SecurityEventConnectionAPI.ts +250 -0
- package/Server/API/TelemetryAPI.ts +402 -265
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Middleware/TelemetryIngest.ts +101 -6
- package/Server/Services/ExceptionAggregationService.ts +7 -16
- package/Server/Services/GoogleSecOpsConnectionService.ts +15 -0
- package/Server/Services/Index.ts +4 -0
- package/Server/Services/InventoryItemService.ts +28 -0
- package/Server/Services/LogAggregationService.ts +17 -23
- package/Server/Services/MetricAggregationService.ts +4 -14
- package/Server/Services/SecurityEventConnectionRunService.ts +10 -0
- package/Server/Services/SecurityEventConnectionService.ts +538 -0
- package/Server/Services/TraceAggregationService.ts +77 -28
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +13 -1
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +15 -1
- package/Server/Utils/AI/SRE/InvestigationEvidence.ts +658 -0
- package/Server/Utils/AI/SRE/InvestigationReferences.ts +324 -0
- package/Server/Utils/AI/Toolbox/Index.ts +38 -0
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +9 -2
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +80 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +5 -3
- package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.ts +1108 -0
- package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.ts +732 -0
- package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +495 -0
- package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.ts +689 -0
- package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.ts +767 -0
- package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.ts +571 -0
- package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.ts +827 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.ts +610 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.ts +549 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.ts +830 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.ts +684 -0
- package/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.ts +487 -0
- package/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.ts +778 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +1002 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.ts +556 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +275 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +53 -0
- package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.ts +709 -0
- package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.ts +596 -0
- package/Server/Utils/SecurityEvent/Connectors/Types.ts +191 -0
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +353 -65
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.ts +777 -0
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +747 -148
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +48 -2
- package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +81 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +741 -40
- package/Server/Utils/StartServer.ts +10 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +8 -0
- package/Server/Utils/Telemetry/KubernetesResourceAttributes.ts +108 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +174 -93
- package/Server/Utils/Telemetry/ResourceFacetPlanner.ts +251 -0
- package/Server/Utils/Telemetry/ResourceFacetResolver.ts +248 -413
- package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +668 -0
- package/Server/Utils/Telemetry/TraceContextPropagation.ts +348 -0
- package/Server/Utils/Telemetry.ts +18 -0
- package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +413 -0
- package/Tests/App/Dashboard/AIRootCauseFeedItem.test.tsx +285 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +242 -0
- package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +601 -15
- package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +835 -0
- package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +41 -0
- package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +604 -0
- package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +738 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +153 -6
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +165 -0
- package/Tests/App/Dashboard/EpisodeChangeState.test.tsx +1069 -0
- package/Tests/App/Dashboard/EpisodeMembersCard.test.tsx +772 -0
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +2354 -0
- package/Tests/App/Dashboard/EventOverviewSkeleton.test.tsx +210 -0
- package/Tests/App/Dashboard/EventStatBar.test.tsx +392 -0
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +247 -0
- package/Tests/App/Dashboard/ExceptionAIAssistance.test.tsx +606 -0
- package/Tests/App/Dashboard/ExceptionBreadcrumbTimeline.test.tsx +273 -0
- package/Tests/App/Dashboard/ExceptionDetailSideMenu.test.tsx +176 -0
- package/Tests/App/Dashboard/ExceptionOverviewCards.test.tsx +366 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +371 -0
- package/Tests/App/Dashboard/ExceptionStackFrameViewer.test.tsx +440 -0
- package/Tests/App/Dashboard/ExceptionSummary.test.tsx +381 -0
- package/Tests/App/Dashboard/ExceptionTriage.test.tsx +306 -0
- package/Tests/App/Dashboard/ExceptionsResourceFacets.test.tsx +604 -0
- package/Tests/App/Dashboard/ExceptionsViewerEntityChips.test.tsx +706 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +32 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionForm.test.tsx +838 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +18 -0
- package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +297 -20
- package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +618 -13
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +254 -207
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +303 -135
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +1251 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +303 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +876 -8
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +35 -0
- package/Tests/App/Dashboard/InvestigationReferenceLink.test.tsx +177 -0
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +1295 -0
- package/Tests/App/Dashboard/KubernetesImageReferenceView.test.tsx +114 -0
- package/Tests/App/Dashboard/KubernetesLogsTabChips.test.tsx +285 -0
- package/Tests/App/Dashboard/LogsEntityChipNames.test.tsx +316 -0
- package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +361 -0
- package/Tests/App/Dashboard/ProfileTableEntityNames.test.tsx +432 -0
- package/Tests/App/Dashboard/ProfileViewEntityName.test.tsx +250 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +10 -0
- package/Tests/App/Dashboard/ResourceLogsTabsBareLayout.test.tsx +700 -0
- package/Tests/App/Dashboard/ResourcePageEntityNameProps.test.tsx +803 -0
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +11 -1
- package/Tests/App/Dashboard/ScheduledMaintenanceChangeState.test.tsx +1026 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +436 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1022 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +905 -0
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +247 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +375 -274
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +410 -0
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +774 -0
- package/Tests/App/Dashboard/TopErrorsPanelResourceNames.test.tsx +316 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +30 -0
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +88 -24
- package/Tests/App/Dashboard/TraceExplorer.test.tsx +1590 -0
- package/Tests/App/Dashboard/TraceWaterfall.test.tsx +488 -0
- package/Tests/App/Dashboard/TracesAnalyticsSeriesLabels.test.tsx +367 -0
- package/Tests/App/Dashboard/TracesEntityNames.test.tsx +585 -0
- package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +613 -0
- package/Tests/App/Dashboard/UseServiceNames.test.tsx +359 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +7 -0
- package/Tests/Models/InventoryItemNaming.test.ts +132 -16
- package/Tests/Models/SecurityDomainAccessControl.test.ts +61 -17
- package/Tests/Server/API/AIInvestigationAPI.test.ts +611 -2
- package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +1098 -0
- package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +409 -0
- package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +856 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +528 -1
- package/Tests/Server/API/TelemetryFacetsAPI.test.ts +810 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +240 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +229 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +66 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/SecurityEventConnectionService.test.ts +1233 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +53 -0
- package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +218 -0
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +155 -1
- package/Tests/Server/Services/TraceAggregationExceptionScope.test.ts +142 -0
- package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +85 -24
- package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +33 -0
- package/Tests/Server/Utils/AI/InvestigationEvidence.test.ts +1395 -0
- package/Tests/Server/Utils/AI/InvestigationReferences.test.ts +616 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +119 -0
- package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +151 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +65 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorExceptionScope.test.ts +224 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
- package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.test.ts +1240 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.test.ts +1853 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +1129 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.test.ts +1066 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.test.ts +1568 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.test.ts +930 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.test.ts +1409 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.test.ts +763 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.test.ts +1296 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.test.ts +1102 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.test.ts +1174 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.test.ts +1032 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.test.ts +1558 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +3041 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +1168 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +906 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.test.ts +1068 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.test.ts +1004 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.test.ts +784 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +113 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +5 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +93 -13
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsHttpIntegration.test.ts +23 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +25 -3
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +22 -8
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +82 -16
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSearchDetections.test.ts +730 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsThreePassPoller.test.ts +1577 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayOriginAllowlist.test.ts +41 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1453 -18
- package/Tests/Server/Utils/Telemetry/KubernetesResourceAttributes.test.ts +162 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +460 -13
- package/Tests/Server/Utils/Telemetry/ResourceFacetPlanner.test.ts +678 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +348 -2
- package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
- package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +73 -0
- package/Tests/Types/Rum/SessionReplayTransportContracts.test.ts +95 -0
- package/Tests/Types/SecurityEvent/Connectors/ConnectorDiagnostics.test.ts +82 -0
- package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +314 -0
- package/Tests/Types/Telemetry/ExceptionSpanScope.test.ts +89 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +96 -0
- package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +304 -0
- package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +357 -0
- package/Tests/UI/Components/Card.test.tsx +312 -1
- package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +253 -0
- package/Tests/UI/Components/CardModelDetailRefresher.test.tsx +342 -0
- package/Tests/UI/Components/Checkbox.test.tsx +79 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +142 -0
- package/Tests/UI/Components/DetailCompactStyle.test.tsx +621 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +60 -0
- package/Tests/UI/Components/FacetSections.test.tsx +581 -0
- package/Tests/UI/Components/FacetSidebarControls.test.tsx +812 -0
- package/Tests/UI/Components/FacetVisibility.test.ts +429 -0
- package/Tests/UI/Components/LockedFilterActions.test.tsx +396 -0
- package/Tests/UI/Components/LockedFilterChip.test.tsx +651 -0
- package/Tests/UI/Components/LogsEntityNames.test.ts +1769 -0
- package/Tests/UI/Components/LogsEntityNamesComponents.test.tsx +696 -0
- package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +600 -0
- package/Tests/UI/Components/LogsViewerEntityNames.test.tsx +713 -0
- package/Tests/UI/Components/MarkdownInlineReferences.test.tsx +2079 -0
- package/Tests/UI/Components/MemberRoleAssignment.test.tsx +446 -0
- package/Tests/UI/Components/ModelDetailRefetch.test.tsx +397 -0
- package/Tests/UI/Components/ModelListRefetch.test.tsx +233 -0
- package/Tests/UI/Components/ModelPageModelChange.test.tsx +409 -0
- package/Tests/UI/Components/PaginationIntegration.test.tsx +25 -0
- package/Tests/UI/Components/ResourceFacetConfigs.test.ts +172 -0
- package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +32 -14
- package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +44 -1
- package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +304 -0
- package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +718 -0
- package/Tests/UI/Monitor/EvaluationLogList.test.tsx +303 -0
- package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +55 -1
- package/Tests/UI/Rum/FidelityNotices.test.ts +22 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +120 -136
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +988 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +32 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +709 -12
- package/Tests/UI/Rum/ReplayHeader.test.tsx +50 -1
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +67 -10
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +41 -12
- package/Tests/UI/Rum/ReplayStage.test.tsx +663 -1
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +173 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +189 -2
- package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +91 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +1 -1
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +585 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +844 -51
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +29 -1
- package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +288 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +31 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +6 -0
- package/Tests/UI/Utils/Clipboard.test.ts +154 -0
- package/Tests/UI/Utils/Navigation.test.ts +24 -0
- package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +2205 -0
- package/Tests/UI/Utils/Telemetry/UseTelemetryEntityNames.test.tsx +844 -0
- package/Tests/Utils/AI/InvestigationReport.test.ts +2430 -0
- package/Tests/Utils/APIOutgoingRequestTracer.test.ts +137 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +40 -0
- package/Tests/Utils/Rum/SessionReplayRecordingEnded.test.ts +619 -0
- package/Tests/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.test.ts +631 -0
- package/Tests/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.test.ts +479 -0
- package/Tests/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.test.ts +507 -0
- package/Tests/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.test.ts +686 -0
- package/Tests/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.test.ts +474 -0
- package/Tests/Utils/SecurityEvent/Connectors/OktaNormalizer.test.ts +736 -0
- package/Tests/Utils/SecurityEvent/Connectors/SplunkNormalizer.test.ts +407 -0
- package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +129 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +57 -1
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +36 -0
- package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +600 -0
- package/Tests/Utils/Telemetry/NetworkHost.test.ts +48 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +154 -0
- package/Tests/Utils/Traces/CriticalPath.test.ts +25 -0
- package/Types/AI/AIChatTypes.ts +8 -0
- package/Types/AI/InvestigationEvidence.ts +96 -0
- package/Types/Monitor/MonitorEvaluationSummary.ts +5 -0
- package/Types/Permission.ts +2 -2
- package/Types/Rum/SessionReplay.ts +109 -0
- package/Types/Rum/SessionReplayApi.ts +31 -0
- package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +111 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +87 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +492 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +41 -0
- package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +56 -1
- package/Types/SecurityEvent/GoogleSecOpsRegion.ts +34 -0
- package/Types/Telemetry/EntityType.ts +14 -0
- package/Types/Telemetry/ExceptionSpanScope.ts +83 -0
- package/Types/Telemetry/LockedFilterDetail.ts +46 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +17 -10
- package/Types/Telemetry/ResourceFacetCatalog.ts +171 -0
- package/UI/Components/Card/Card.tsx +118 -83
- package/UI/Components/Checkbox/Checkbox.tsx +8 -5
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +7 -1
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +4 -1
- package/UI/Components/Detail/Detail.tsx +137 -22
- package/UI/Components/ErrorBoundary.tsx +38 -0
- package/UI/Components/LogsViewer/LogsEntityNames.ts +912 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +156 -77
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +28 -11
- package/UI/Components/LogsViewer/components/FacetSection.tsx +66 -79
- package/UI/Components/LogsViewer/components/FacetValueRow.tsx +17 -2
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +45 -5
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +100 -19
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +156 -39
- package/UI/Components/LogsViewer/components/LogsTable.tsx +30 -8
- package/UI/Components/LogsViewer/types.ts +6 -0
- package/UI/Components/Markdown.tsx/InlineReferences.tsx +628 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +385 -312
- package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +50 -22
- package/UI/Components/ModelDetail/CardModelDetail.tsx +15 -0
- package/UI/Components/ModelDetail/ModelDetail.tsx +64 -19
- package/UI/Components/ModelList/ModelList.tsx +33 -8
- package/UI/Components/Page/ModelPage.tsx +119 -54
- package/UI/Components/Table/Table.tsx +8 -0
- package/UI/Components/Table/TableRow.tsx +13 -5
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +229 -0
- package/UI/Components/TelemetryViewer/ResourceFacetConfigs.ts +46 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +11 -0
- package/UI/Components/TelemetryViewer/components/FacetSearchInput.tsx +79 -0
- package/UI/Components/TelemetryViewer/components/FacetSectionHeader.tsx +69 -0
- package/UI/Components/TelemetryViewer/components/FacetShowMoreButton.tsx +36 -0
- package/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.tsx +88 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterActions.tsx +205 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +496 -0
- package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +30 -10
- package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +203 -10
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSection.tsx +60 -73
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +94 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +17 -2
- package/UI/Components/TelemetryViewer/types.ts +19 -0
- package/UI/Components/TelemetryViewer/useFacetSearchExemptions.ts +158 -0
- package/UI/Components/TelemetryViewer/useFacetSectionSearch.ts +102 -0
- package/UI/Utils/Clipboard.ts +68 -2
- package/UI/Utils/Navigation.ts +17 -2
- package/UI/Utils/Telemetry/TelemetryEntityNames.ts +620 -0
- package/UI/Utils/Telemetry/UseTelemetryEntityNames.ts +151 -0
- package/Utils/AI/InvestigationReport.ts +1789 -0
- package/Utils/API.ts +90 -1
- package/Utils/Rum/SessionReplayHealth.ts +11 -0
- package/Utils/Rum/SessionReplayRecordingEnded.ts +134 -0
- package/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.ts +427 -0
- package/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.ts +197 -0
- package/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.ts +464 -0
- package/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.ts +567 -0
- package/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.ts +299 -0
- package/Utils/SecurityEvent/Connectors/OktaNormalizer.ts +467 -0
- package/Utils/SecurityEvent/Connectors/SplunkNormalizer.ts +439 -0
- package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +124 -12
- package/Utils/Telemetry/CrossSignalScope.ts +22 -8
- package/Utils/Telemetry/EntityRelationship.ts +8 -0
- package/Utils/Telemetry/LockedFilterSearch.ts +412 -0
- package/Utils/Telemetry/NetworkHost.ts +43 -0
- package/Utils/Telemetry/OriginAllowList.ts +139 -4
- package/Utils/Traces/CriticalPath.ts +10 -4
- package/build/dist/Models/DatabaseModels/Index.js +4 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/SecurityEventConnection.js +490 -0
- package/build/dist/Models/DatabaseModels/SecurityEventConnection.js.map +1 -0
- package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js +287 -0
- package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js.map +1 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +2 -2
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +336 -27
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +182 -7
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +1 -1
- package/build/dist/Server/API/SecurityEventConnectionAPI.js +171 -0
- package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -0
- package/build/dist/Server/API/TelemetryAPI.js +248 -170
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +57 -4
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +7 -16
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +8 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +4 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +22 -0
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +8 -17
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +4 -14
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/SecurityEventConnectionRunService.js +9 -0
- package/build/dist/Server/Services/SecurityEventConnectionRunService.js.map +1 -0
- package/build/dist/Server/Services/SecurityEventConnectionService.js +356 -0
- package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -0
- package/build/dist/Server/Services/TraceAggregationService.js +51 -25
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +14 -7
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js +468 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js +230 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +32 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +6 -2
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +59 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +5 -3
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js +752 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js +493 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +352 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js +405 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js +466 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js +344 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js +511 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js +406 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js +336 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js +474 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js +417 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js +314 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js +494 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +719 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js +404 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +209 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +40 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js +494 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js +379 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +27 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +234 -61
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js +537 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +572 -115
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +35 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +52 -0
- package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +521 -32
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +8 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js +80 -0
- package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +122 -67
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js +146 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +174 -248
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +492 -0
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js +259 -0
- package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry.js +11 -5
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/AI/InvestigationEvidence.js +2 -0
- package/build/dist/Types/AI/InvestigationEvidence.js.map +1 -0
- package/build/dist/Types/Permission.js +2 -2
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +95 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js +18 -0
- package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +2 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +374 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +35 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js +35 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +14 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/ExceptionSpanScope.js +59 -0
- package/build/dist/Types/Telemetry/ExceptionSpanScope.js.map +1 -0
- package/build/dist/Types/Telemetry/LockedFilterDetail.js +16 -0
- package/build/dist/Types/Telemetry/LockedFilterDetail.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +16 -10
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -1
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +119 -0
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -0
- package/build/dist/UI/Components/Card/Card.js +34 -17
- package/build/dist/UI/Components/Card/Card.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +6 -4
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +63 -13
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +34 -0
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js +535 -0
- package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +117 -57
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +5 -7
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetSection.js +31 -44
- package/build/dist/UI/Components/LogsViewer/components/FacetSection.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +17 -3
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +19 -3
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +64 -18
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +100 -41
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +13 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js +403 -0
- package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +197 -179
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +30 -21
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +12 -0
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js +46 -12
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +26 -7
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +62 -34
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +3 -1
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +8 -1
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +111 -0
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js +22 -0
- package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js +36 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js +21 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js +14 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js +27 -0
- package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js +88 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +228 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +6 -6
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +111 -12
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js +27 -40
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +70 -10
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +17 -3
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/types.js +0 -4
- package/build/dist/UI/Components/TelemetryViewer/types.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js +70 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js +52 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js.map +1 -0
- package/build/dist/UI/Utils/Clipboard.js +59 -2
- package/build/dist/UI/Utils/Clipboard.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +11 -2
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +471 -0
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js +113 -0
- package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js.map +1 -0
- package/build/dist/Utils/AI/InvestigationReport.js +1241 -0
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -0
- package/build/dist/Utils/API.js +25 -0
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +10 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js +54 -0
- package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js +311 -0
- package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js +150 -0
- package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js +328 -0
- package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js +405 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js +212 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js +351 -0
- package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js +348 -0
- package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +103 -10
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +16 -5
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +7 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
- package/build/dist/Utils/Telemetry/LockedFilterSearch.js +277 -0
- package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/NetworkHost.js +39 -0
- package/build/dist/Utils/Telemetry/NetworkHost.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +105 -4
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
- package/build/dist/Utils/Traces/CriticalPath.js +9 -4
- package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
- package/package.json +1 -1
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +0 -600
- package/UI/Components/GanttChart/Bar/BarLabel.tsx +0 -17
- package/UI/Components/GanttChart/Bar/Index.tsx +0 -149
- package/UI/Components/GanttChart/ChartContainer.tsx +0 -50
- package/UI/Components/GanttChart/Index.tsx +0 -90
- package/UI/Components/GanttChart/Row/Index.tsx +0 -22
- package/UI/Components/GanttChart/Row/Row.tsx +0 -231
- package/UI/Components/GanttChart/Row/RowLabel.tsx +0 -30
- package/UI/Components/GanttChart/Rows.tsx +0 -59
- package/UI/Components/GanttChart/Timeline/Index.tsx +0 -46
- package/UI/Components/GanttChart/Timeline/TimelineInterval.tsx +0 -33
- package/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.tsx +0 -43
- package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js +0 -8
- package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Bar/Index.js +0 -77
- package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +0 -33
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Index.js +0 -39
- package/build/dist/UI/Components/GanttChart/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/Index.js +0 -7
- package/build/dist/UI/Components/GanttChart/Row/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/Row.js +0 -106
- package/build/dist/UI/Components/GanttChart/Row/Row.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +0 -10
- package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Rows.js +0 -19
- package/build/dist/UI/Components/GanttChart/Rows.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/Index.js +0 -16
- package/build/dist/UI/Components/GanttChart/Timeline/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js +0 -13
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js +0 -13
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js.map +0 -1
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
import BadDataException from "../../../../../Types/Exception/BadDataException";
|
|
2
|
+
import { JSONObject } from "../../../../../Types/JSON";
|
|
3
|
+
import NormalizedSecurityEvent from "../../../../../Types/SecurityEvent/NormalizedSecurityEvent";
|
|
4
|
+
import SecurityEventConnectorProvider from "../../../../../Types/SecurityEvent/Connectors/SecurityEventConnectorProvider";
|
|
5
|
+
import {
|
|
6
|
+
SecurityConnectorCheck,
|
|
7
|
+
SecurityConnectorSample,
|
|
8
|
+
} from "../../../../../Types/SecurityEvent/Connectors/ConnectorDiagnostics";
|
|
9
|
+
import AwsSecurityHubNormalizer from "../../../../../Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer";
|
|
10
|
+
import DataSourceHttpFetch, {
|
|
11
|
+
DataSourceHttpRequest,
|
|
12
|
+
} from "../../../DataSource/HttpFetch";
|
|
13
|
+
import { redactLogString } from "../../../LogRedaction";
|
|
14
|
+
import ConnectorErrorMessage from "../../ConnectorErrorMessage";
|
|
15
|
+
import {
|
|
16
|
+
ConnectorFetchOptions,
|
|
17
|
+
ConnectorFetchResult,
|
|
18
|
+
ConnectorFetchWindow,
|
|
19
|
+
ConnectorTestOptions,
|
|
20
|
+
ConnectorTransport,
|
|
21
|
+
SecurityConnectorSettings,
|
|
22
|
+
SecurityEventConnector,
|
|
23
|
+
makeCheck,
|
|
24
|
+
readSettingString,
|
|
25
|
+
} from "../Types";
|
|
26
|
+
import AwsSecurityHubClient, {
|
|
27
|
+
AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE,
|
|
28
|
+
AwsSecurityHubFindingCount,
|
|
29
|
+
AwsSecurityHubFindingsPage,
|
|
30
|
+
AwsSecurityHubHttpError,
|
|
31
|
+
} from "./AwsSecurityHubClient";
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* AWS Security Hub connector: imports findings from one Region of one
|
|
35
|
+
* account (ideally the delegated administrator's home Region, where
|
|
36
|
+
* cross-Region aggregation collects every member account's findings) as
|
|
37
|
+
* OCSF Detection Findings, or Compliance Findings for control checks.
|
|
38
|
+
*
|
|
39
|
+
* Polling is by the finding's CreatedAt (see Connectors/Types.ts for why
|
|
40
|
+
* creation time is the cursor basis). A GuardDuty finding is created when
|
|
41
|
+
* GuardDuty has evaluated enough activity to raise it, and a control
|
|
42
|
+
* finding when Security Hub first evaluates the resource — both can be
|
|
43
|
+
* long after FirstObservedAt, so a cursor over observation time would
|
|
44
|
+
* skip them. CreatedAt is still the PROVIDER's timestamp, and delivery to
|
|
45
|
+
* Security Hub lags it by minutes, so the catalog gives this provider a 30
|
|
46
|
+
* minute cursor overlap; the dedupe by finding Id drops what the overlap
|
|
47
|
+
* re-reads.
|
|
48
|
+
*
|
|
49
|
+
* GetFindings is sorted by CreatedAt ascending, so when a request or
|
|
50
|
+
* record bound stops a fetch, every finding created before the last one
|
|
51
|
+
* read has been read: fetchEvents reports that CreatedAt as resumeAfter
|
|
52
|
+
* and the poller moves on from there instead of re-reading the window.
|
|
53
|
+
*
|
|
54
|
+
* Security Hub has no notion of "alerting" findings, so the connection's
|
|
55
|
+
* alertingOnly flag is not consulted (the catalog marks the toggle as
|
|
56
|
+
* unsupported).
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
const PROVIDER_TITLE: string = "AWS Security Hub";
|
|
60
|
+
const DAY_IN_MS: number = 24 * 60 * 60 * 1000;
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* Wording of a request that never got an HTTP status: the client's own
|
|
64
|
+
* deadline, or the production transport's "Could not reach data source"
|
|
65
|
+
* wrapper around a DNS, connection, TLS or timeout failure.
|
|
66
|
+
*/
|
|
67
|
+
const CONNECTIVITY_FAILURE_REGEX: RegExp =
|
|
68
|
+
/timed out|timeout|could not reach data source|econnrefused|econnreset|enotfound|etimedout|eai_again/i;
|
|
69
|
+
|
|
70
|
+
interface ResolvedSettings {
|
|
71
|
+
region: string;
|
|
72
|
+
accessKeyId: string;
|
|
73
|
+
secretAccessKey: string;
|
|
74
|
+
sessionToken: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default class AwsSecurityHubConnector implements SecurityEventConnector {
|
|
78
|
+
public provider: SecurityEventConnectorProvider =
|
|
79
|
+
SecurityEventConnectorProvider.AwsSecurityHub;
|
|
80
|
+
|
|
81
|
+
private transport: ConnectorTransport;
|
|
82
|
+
|
|
83
|
+
public constructor(transport?: ConnectorTransport | undefined) {
|
|
84
|
+
this.transport =
|
|
85
|
+
transport ||
|
|
86
|
+
((request: DataSourceHttpRequest) => {
|
|
87
|
+
return DataSourceHttpFetch.fetch(request);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
* Settings are read by the catalog's field keys so the form, the service
|
|
93
|
+
* validation and this connector can never disagree on a key name.
|
|
94
|
+
*/
|
|
95
|
+
private static resolveSettings(
|
|
96
|
+
settings: SecurityConnectorSettings,
|
|
97
|
+
): ResolvedSettings {
|
|
98
|
+
const config: JSONObject = settings.config || {};
|
|
99
|
+
const secrets: JSONObject = settings.secrets || {};
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
region: readSettingString(config, "region").toLowerCase(),
|
|
103
|
+
accessKeyId: readSettingString(config, "accessKeyId"),
|
|
104
|
+
secretAccessKey: readSettingString(secrets, "secretAccessKey"),
|
|
105
|
+
sessionToken: readSettingString(secrets, "sessionToken"),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public validateSettings(settings: SecurityConnectorSettings): void {
|
|
110
|
+
if (settings.provider !== this.provider) {
|
|
111
|
+
throw new BadDataException(
|
|
112
|
+
`Settings are for provider "${String(settings.provider)}", not ${PROVIDER_TITLE}.`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const resolved: ResolvedSettings =
|
|
117
|
+
AwsSecurityHubConnector.resolveSettings(settings);
|
|
118
|
+
|
|
119
|
+
AwsSecurityHubClient.validateRegion(resolved.region);
|
|
120
|
+
AwsSecurityHubClient.validateAccessKeyId(resolved.accessKeyId);
|
|
121
|
+
|
|
122
|
+
if (!resolved.secretAccessKey) {
|
|
123
|
+
throw new BadDataException("Secret access key is required.");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Temporary credentials (ASIA... ids) only work with their session
|
|
128
|
+
* token; a missing token fails every request with
|
|
129
|
+
* UnrecognizedClientException, which reads like a wrong key. Catch it
|
|
130
|
+
* here where the message can name the field.
|
|
131
|
+
*/
|
|
132
|
+
if (resolved.accessKeyId.startsWith("ASIA") && !resolved.sessionToken) {
|
|
133
|
+
throw new BadDataException(
|
|
134
|
+
"Session token is required for a temporary access key (an Access key ID starting with ASIA).",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/*
|
|
139
|
+
* The reverse mistake: a long-lived AKIA... key with a session token
|
|
140
|
+
* left over from earlier temporary credentials. AWS signs the token in
|
|
141
|
+
* and rejects every request with "The security token included in the
|
|
142
|
+
* request is invalid", which reads like a wrong key. Name both fields
|
|
143
|
+
* so the person editing knows which one to clear.
|
|
144
|
+
*/
|
|
145
|
+
if (resolved.accessKeyId.startsWith("AKIA") && resolved.sessionToken) {
|
|
146
|
+
throw new BadDataException(
|
|
147
|
+
"Session token must be empty for a long-lived access key (an Access key ID starting with AKIA). Remove the stored Session token, or enter the temporary Access key ID (starting with ASIA) that the token was issued with.",
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private createClient(
|
|
153
|
+
settings: SecurityConnectorSettings,
|
|
154
|
+
requestTimeoutInMs: number,
|
|
155
|
+
): AwsSecurityHubClient {
|
|
156
|
+
const resolved: ResolvedSettings =
|
|
157
|
+
AwsSecurityHubConnector.resolveSettings(settings);
|
|
158
|
+
|
|
159
|
+
return new AwsSecurityHubClient({
|
|
160
|
+
region: resolved.region,
|
|
161
|
+
accessKeyId: resolved.accessKeyId,
|
|
162
|
+
secretAccessKey: resolved.secretAccessKey,
|
|
163
|
+
sessionToken: resolved.sessionToken || undefined,
|
|
164
|
+
transport: this.transport,
|
|
165
|
+
requestTimeoutInMs,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/*
|
|
170
|
+
* ---------------------------------------------------------------------
|
|
171
|
+
* Test connection
|
|
172
|
+
* ---------------------------------------------------------------------
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/*
|
|
176
|
+
* AWS has no separate token step: a single signed GetFindings for one
|
|
177
|
+
* finding over the last day answers both "are the credentials right"
|
|
178
|
+
* and "may this identity read findings", because AWS verifies the
|
|
179
|
+
* signature before Security Hub evaluates the IAM policy. Only an
|
|
180
|
+
* AccessDeniedException or InvalidAccessException proves the signature
|
|
181
|
+
* was verified, so only those pass authentication and fail the read
|
|
182
|
+
* permission; every other failure, a code-less 403 included, fails
|
|
183
|
+
* authentication.
|
|
184
|
+
*/
|
|
185
|
+
public async testConnection(
|
|
186
|
+
settings: SecurityConnectorSettings,
|
|
187
|
+
options: ConnectorTestOptions,
|
|
188
|
+
): Promise<Array<SecurityConnectorCheck>> {
|
|
189
|
+
const checks: Array<SecurityConnectorCheck> = [];
|
|
190
|
+
const now: Date = new Date();
|
|
191
|
+
const dayAgo: Date = new Date(now.getTime() - DAY_IN_MS);
|
|
192
|
+
const weekAgo: Date = new Date(now.getTime() - 7 * DAY_IN_MS);
|
|
193
|
+
const region: string = readSettingString(settings.config || {}, "region");
|
|
194
|
+
|
|
195
|
+
let client: AwsSecurityHubClient;
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
this.validateSettings(settings);
|
|
199
|
+
client = this.createClient(settings, options.requestTimeoutInMs);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
checks.push(
|
|
202
|
+
makeCheck({
|
|
203
|
+
key: "authentication",
|
|
204
|
+
name: "Authenticate with AWS",
|
|
205
|
+
status: "fail",
|
|
206
|
+
startedAtMs: Date.now(),
|
|
207
|
+
message: redactLogString(ConnectorErrorMessage.toMessage(error)),
|
|
208
|
+
remediation:
|
|
209
|
+
"Correct the highlighted setting and test again. Nothing was contacted.",
|
|
210
|
+
}),
|
|
211
|
+
);
|
|
212
|
+
checks.push(
|
|
213
|
+
AwsSecurityHubConnector.skipped(
|
|
214
|
+
"read-permission",
|
|
215
|
+
"Read findings",
|
|
216
|
+
"Skipped because the configuration is not usable.",
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
checks.push(
|
|
220
|
+
AwsSecurityHubConnector.skipped(
|
|
221
|
+
"detections-available",
|
|
222
|
+
"Findings available to import",
|
|
223
|
+
"Skipped because the configuration is not usable.",
|
|
224
|
+
),
|
|
225
|
+
);
|
|
226
|
+
return checks;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 1 + 2. One signed GetFindings for a single finding created in the last day.
|
|
230
|
+
const probeStartedMs: number = Date.now();
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
const page: AwsSecurityHubFindingsPage = await client.getFindings({
|
|
234
|
+
startTime: dayAgo,
|
|
235
|
+
endTime: now,
|
|
236
|
+
maxResults: 1,
|
|
237
|
+
});
|
|
238
|
+
checks.push(
|
|
239
|
+
makeCheck({
|
|
240
|
+
key: "authentication",
|
|
241
|
+
name: "Authenticate with AWS",
|
|
242
|
+
status: "pass",
|
|
243
|
+
startedAtMs: probeStartedMs,
|
|
244
|
+
message: `Security Hub in ${region} accepted the Signature Version 4 request signed with the access key.`,
|
|
245
|
+
}),
|
|
246
|
+
);
|
|
247
|
+
checks.push(
|
|
248
|
+
makeCheck({
|
|
249
|
+
key: "read-permission",
|
|
250
|
+
name: "Read findings",
|
|
251
|
+
status: "pass",
|
|
252
|
+
startedAtMs: probeStartedMs,
|
|
253
|
+
message: page.findings.length
|
|
254
|
+
? "Security Hub answered a GetFindings query; the IAM identity is allowed securityhub:GetFindings."
|
|
255
|
+
: "Security Hub answered a GetFindings query (no finding was created in the last 24 hours); the IAM identity is allowed securityhub:GetFindings.",
|
|
256
|
+
details: {
|
|
257
|
+
region,
|
|
258
|
+
sampleFindingCount: page.findings.length,
|
|
259
|
+
},
|
|
260
|
+
}),
|
|
261
|
+
);
|
|
262
|
+
} catch (error) {
|
|
263
|
+
const message: string = redactLogString(
|
|
264
|
+
ConnectorErrorMessage.toMessage(error),
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
if (AwsSecurityHubConnector.isPermissionFailure(error)) {
|
|
268
|
+
checks.push(
|
|
269
|
+
makeCheck({
|
|
270
|
+
key: "authentication",
|
|
271
|
+
name: "Authenticate with AWS",
|
|
272
|
+
status: "pass",
|
|
273
|
+
startedAtMs: probeStartedMs,
|
|
274
|
+
message: `Security Hub in ${region} verified the request signature, so the access key and secret are valid.`,
|
|
275
|
+
}),
|
|
276
|
+
);
|
|
277
|
+
checks.push(
|
|
278
|
+
makeCheck({
|
|
279
|
+
key: "read-permission",
|
|
280
|
+
name: "Read findings",
|
|
281
|
+
status: "fail",
|
|
282
|
+
startedAtMs: probeStartedMs,
|
|
283
|
+
message,
|
|
284
|
+
remediation: AwsSecurityHubConnector.readRemediation(
|
|
285
|
+
error,
|
|
286
|
+
message,
|
|
287
|
+
),
|
|
288
|
+
}),
|
|
289
|
+
);
|
|
290
|
+
checks.push(
|
|
291
|
+
AwsSecurityHubConnector.skipped(
|
|
292
|
+
"detections-available",
|
|
293
|
+
"Findings available to import",
|
|
294
|
+
"Skipped because findings could not be read.",
|
|
295
|
+
),
|
|
296
|
+
);
|
|
297
|
+
return checks;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
checks.push(
|
|
301
|
+
makeCheck({
|
|
302
|
+
key: "authentication",
|
|
303
|
+
name: "Authenticate with AWS",
|
|
304
|
+
status: "fail",
|
|
305
|
+
startedAtMs: probeStartedMs,
|
|
306
|
+
message,
|
|
307
|
+
remediation: AwsSecurityHubConnector.authenticationRemediation(
|
|
308
|
+
error,
|
|
309
|
+
message,
|
|
310
|
+
),
|
|
311
|
+
}),
|
|
312
|
+
);
|
|
313
|
+
checks.push(
|
|
314
|
+
AwsSecurityHubConnector.skipped(
|
|
315
|
+
"read-permission",
|
|
316
|
+
"Read findings",
|
|
317
|
+
"Skipped because authentication failed.",
|
|
318
|
+
),
|
|
319
|
+
);
|
|
320
|
+
checks.push(
|
|
321
|
+
AwsSecurityHubConnector.skipped(
|
|
322
|
+
"detections-available",
|
|
323
|
+
"Findings available to import",
|
|
324
|
+
"Skipped because authentication failed.",
|
|
325
|
+
),
|
|
326
|
+
);
|
|
327
|
+
return checks;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// 3. Availability: bounded counts over the last day and the last week.
|
|
331
|
+
const countStartedMs: number = Date.now();
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
const last24h: AwsSecurityHubFindingCount =
|
|
335
|
+
await client.countFindingsCreated({
|
|
336
|
+
startTime: dayAgo,
|
|
337
|
+
endTime: now,
|
|
338
|
+
maxResults: AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE,
|
|
339
|
+
});
|
|
340
|
+
const last7d: AwsSecurityHubFindingCount =
|
|
341
|
+
await client.countFindingsCreated({
|
|
342
|
+
startTime: weekAgo,
|
|
343
|
+
endTime: now,
|
|
344
|
+
maxResults: AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const label24h: string = AwsSecurityHubConnector.countLabel(last24h);
|
|
348
|
+
const label7d: string = AwsSecurityHubConnector.countLabel(last7d);
|
|
349
|
+
const nothing: boolean =
|
|
350
|
+
last24h.count === 0 &&
|
|
351
|
+
last7d.count === 0 &&
|
|
352
|
+
!last24h.hasMore &&
|
|
353
|
+
!last7d.hasMore;
|
|
354
|
+
|
|
355
|
+
checks.push(
|
|
356
|
+
makeCheck({
|
|
357
|
+
key: "detections-available",
|
|
358
|
+
name: "Findings available to import",
|
|
359
|
+
status: nothing ? "warn" : "pass",
|
|
360
|
+
startedAtMs: countStartedMs,
|
|
361
|
+
message: nothing
|
|
362
|
+
? "No findings were created in the last 7 days. Polling will import new findings as Security Hub creates them."
|
|
363
|
+
: `${label24h} finding${last24h.count === 1 && !last24h.hasMore ? "" : "s"} created in the last 24 hours and ${label7d} in the last 7 days.`,
|
|
364
|
+
...(nothing
|
|
365
|
+
? {
|
|
366
|
+
remediation:
|
|
367
|
+
"Confirm that Security Hub has integrations (GuardDuty, Inspector, Macie, IAM Access Analyzer, partner products) or security standards enabled in this Region, and that this account is the administrator or home Region if you expect other accounts' and Regions' findings here. A quiet account is not a connector fault.",
|
|
368
|
+
}
|
|
369
|
+
: {}),
|
|
370
|
+
details: {
|
|
371
|
+
createdLast24h: last24h.count,
|
|
372
|
+
hasMoreLast24h: last24h.hasMore,
|
|
373
|
+
createdLast7d: last7d.count,
|
|
374
|
+
hasMoreLast7d: last7d.hasMore,
|
|
375
|
+
},
|
|
376
|
+
}),
|
|
377
|
+
);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
const message: string = redactLogString(
|
|
380
|
+
ConnectorErrorMessage.toMessage(error),
|
|
381
|
+
);
|
|
382
|
+
checks.push(
|
|
383
|
+
makeCheck({
|
|
384
|
+
key: "detections-available",
|
|
385
|
+
name: "Findings available to import",
|
|
386
|
+
status: "fail",
|
|
387
|
+
startedAtMs: countStartedMs,
|
|
388
|
+
message,
|
|
389
|
+
remediation: AwsSecurityHubConnector.readRemediation(error, message),
|
|
390
|
+
}),
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return checks;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private static skipped(
|
|
398
|
+
key: string,
|
|
399
|
+
name: string,
|
|
400
|
+
message: string,
|
|
401
|
+
): SecurityConnectorCheck {
|
|
402
|
+
return makeCheck({
|
|
403
|
+
key,
|
|
404
|
+
name,
|
|
405
|
+
status: "skip",
|
|
406
|
+
startedAtMs: Date.now(),
|
|
407
|
+
message,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
private static countLabel(count: AwsSecurityHubFindingCount): string {
|
|
412
|
+
return count.hasMore ? `${count.count}+` : String(count.count);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/*
|
|
416
|
+
* The client puts "(HTTP <status>)" in every status-bearing message, so
|
|
417
|
+
* remediation can key off the status without re-parsing vendor bodies.
|
|
418
|
+
*/
|
|
419
|
+
private static statusFromMessage(message: string): number | null {
|
|
420
|
+
const match: RegExpMatchArray | null = message.match(/\(HTTP (\d{3})\)/);
|
|
421
|
+
|
|
422
|
+
return match ? Number(match[1]) : null;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/*
|
|
426
|
+
* A failure whose recovered error code is AccessDeniedException or
|
|
427
|
+
* InvalidAccessException came from Security Hub's authorization, after
|
|
428
|
+
* AWS verified the signature. The decision reads the code the client
|
|
429
|
+
* recovered (header, body, or AWS's message wording), never the hint
|
|
430
|
+
* text: a hint naming securityhub:GetFindings once turned a wrong secret
|
|
431
|
+
* behind the header-dropping production transport into "the access key
|
|
432
|
+
* and secret are valid".
|
|
433
|
+
*/
|
|
434
|
+
private static isPermissionFailure(error: unknown): boolean {
|
|
435
|
+
return (
|
|
436
|
+
error instanceof AwsSecurityHubHttpError &&
|
|
437
|
+
error.failureKind === "authorization"
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// The AWS error code the client recovered, or "" for other failures.
|
|
442
|
+
private static errorCodeOf(error: unknown): string {
|
|
443
|
+
return error instanceof AwsSecurityHubHttpError ? error.errorCode : "";
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/*
|
|
447
|
+
* A request that never produced an HTTP status: the client's own
|
|
448
|
+
* deadline ("timed out after N seconds"), or the production transport's
|
|
449
|
+
* "Could not reach data source: ..." wrapper around a DNS failure, a
|
|
450
|
+
* refused connection, a TLS problem, its own timeout or the egress
|
|
451
|
+
* guard. None of these say anything about the credentials, so the
|
|
452
|
+
* remediation must point at the network, not at IAM.
|
|
453
|
+
*/
|
|
454
|
+
private static isConnectivityFailure(message: string): boolean {
|
|
455
|
+
if (AwsSecurityHubConnector.statusFromMessage(message) !== null) {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return CONNECTIVITY_FAILURE_REGEX.test(message);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
private static connectivityRemediation(): string {
|
|
463
|
+
return "Security Hub could not be reached or did not answer in time. Check outbound HTTPS access (DNS, firewall, proxy) from the OneUptime app and worker processes to securityhub.<region>.amazonaws.com and test again.";
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
private static authenticationRemediation(
|
|
467
|
+
error: unknown,
|
|
468
|
+
message: string,
|
|
469
|
+
): string {
|
|
470
|
+
const status: number | null =
|
|
471
|
+
AwsSecurityHubConnector.statusFromMessage(message);
|
|
472
|
+
const code: string = AwsSecurityHubConnector.errorCodeOf(error);
|
|
473
|
+
|
|
474
|
+
if (AwsSecurityHubConnector.isConnectivityFailure(message)) {
|
|
475
|
+
return AwsSecurityHubConnector.connectivityRemediation();
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (
|
|
479
|
+
code === "ExpiredTokenException" ||
|
|
480
|
+
code === "ExpiredToken" ||
|
|
481
|
+
message.includes("ExpiredToken")
|
|
482
|
+
) {
|
|
483
|
+
return "The temporary credentials have expired. Issue new credentials with STS and use Update credentials on the connection, or switch to a long-lived access key.";
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (
|
|
487
|
+
code === "RequestExpired" ||
|
|
488
|
+
code === "RequestTimeTooSkewed" ||
|
|
489
|
+
message.includes("RequestExpired") ||
|
|
490
|
+
message.includes("RequestTimeTooSkewed") ||
|
|
491
|
+
message.includes("Signature expired") ||
|
|
492
|
+
message.includes("Signature not yet current")
|
|
493
|
+
) {
|
|
494
|
+
return "AWS rejected the request time. The OneUptime server clock is more than five minutes off; fix NTP on the app and worker hosts and test again.";
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (status === 404) {
|
|
498
|
+
return "No Security Hub endpoint answered at this Region. Compare the Region with the AWS console's Region selector (for example us-east-1) and test again.";
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (status === 429) {
|
|
502
|
+
return "Security Hub is throttling GetFindings for this account. Wait a minute and test again.";
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (status !== null && status >= 500) {
|
|
506
|
+
return "Security Hub reported a server-side problem. Test again in a few minutes; polling retries on its own.";
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/*
|
|
510
|
+
* A 403 with no recoverable code: the response did not say whether
|
|
511
|
+
* the signature or the IAM policy refused it, so point at both, the
|
|
512
|
+
* credentials first because that is what an unnamed rejection usually
|
|
513
|
+
* is.
|
|
514
|
+
*/
|
|
515
|
+
if (
|
|
516
|
+
status === 403 &&
|
|
517
|
+
!(
|
|
518
|
+
error instanceof AwsSecurityHubHttpError &&
|
|
519
|
+
error.failureKind === "authentication"
|
|
520
|
+
)
|
|
521
|
+
) {
|
|
522
|
+
return "AWS answered 403 without an error code, so the response does not say whether the credentials or the IAM policy refused the request. First compare the Access key ID in IAM > Users > the connector user > Security credentials with the connection and paste a fresh Secret access key (plus the Session token for an ASIA key, none for an AKIA key). If the credentials are right, allow securityhub:GetFindings for that user or role.";
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return "Open IAM > Users > the connector user > Security credentials and compare the Access key ID with the connection, then create a new access key and paste its Secret access key. For temporary credentials also paste the Session token (leave it empty for a long-lived AKIA key), and use the Region where Security Hub is enabled.";
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
private static readRemediation(error: unknown, message: string): string {
|
|
529
|
+
const status: number | null =
|
|
530
|
+
AwsSecurityHubConnector.statusFromMessage(message);
|
|
531
|
+
const code: string = AwsSecurityHubConnector.errorCodeOf(error);
|
|
532
|
+
|
|
533
|
+
if (AwsSecurityHubConnector.isConnectivityFailure(message)) {
|
|
534
|
+
return AwsSecurityHubConnector.connectivityRemediation();
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (
|
|
538
|
+
code === "InvalidAccessException" ||
|
|
539
|
+
message.includes("InvalidAccessException")
|
|
540
|
+
) {
|
|
541
|
+
return "Enable Security Hub in this Region for this account (Security Hub > Get started), or point the connection at the delegated administrator account's home Region where findings are aggregated.";
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (code === "AccessDeniedException" || status === 403) {
|
|
545
|
+
return "Allow securityhub:GetFindings for the IAM identity: attach the AWSSecurityHubReadOnlyAccess managed policy, or an inline policy with Action securityhub:GetFindings on Resource *, to the user or role whose access key the connection uses. To see member accounts' findings, use a key from the Security Hub delegated administrator account in its home (aggregation) Region.";
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (status === 429) {
|
|
549
|
+
return "Security Hub is throttling GetFindings for this account. Wait a minute and test again.";
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (status !== null && status >= 500) {
|
|
553
|
+
return "Security Hub reported a server-side problem. Test again in a few minutes; polling retries on its own.";
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return "Read the message: it names the step that failed and the response AWS returned. Correct the setting it points at and test again.";
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/*
|
|
560
|
+
* ---------------------------------------------------------------------
|
|
561
|
+
* Fetch
|
|
562
|
+
* ---------------------------------------------------------------------
|
|
563
|
+
*/
|
|
564
|
+
|
|
565
|
+
public async fetchEvents(
|
|
566
|
+
settings: SecurityConnectorSettings,
|
|
567
|
+
window: ConnectorFetchWindow,
|
|
568
|
+
options: ConnectorFetchOptions,
|
|
569
|
+
): Promise<ConnectorFetchResult> {
|
|
570
|
+
/*
|
|
571
|
+
* The same validation the form and the tester run, so a settings row
|
|
572
|
+
* for another provider or a temporary key saved without its session
|
|
573
|
+
* token is refused here with the field named, before a request that
|
|
574
|
+
* would only fail with an opaque UnrecognizedClientException.
|
|
575
|
+
*/
|
|
576
|
+
this.validateSettings(settings);
|
|
577
|
+
|
|
578
|
+
const client: AwsSecurityHubClient = this.createClient(
|
|
579
|
+
settings,
|
|
580
|
+
options.requestTimeoutInMs,
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
const result: ConnectorFetchResult = {
|
|
584
|
+
events: [],
|
|
585
|
+
fetchedCount: 0,
|
|
586
|
+
rejectedCount: 0,
|
|
587
|
+
failedCount: 0,
|
|
588
|
+
complete: true,
|
|
589
|
+
requestCount: 0,
|
|
590
|
+
warnings: [],
|
|
591
|
+
samples: [],
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
const maxRequests: number = Math.max(1, Math.floor(options.maxRequests));
|
|
595
|
+
const maxEvents: number = Math.max(1, Math.floor(options.maxEvents));
|
|
596
|
+
const sampleLimit: number = Math.max(0, Math.floor(options.sampleLimit));
|
|
597
|
+
|
|
598
|
+
let nextToken: string | null = null;
|
|
599
|
+
/*
|
|
600
|
+
* CreatedAt of the last finding read, in the API's ascending order.
|
|
601
|
+
* Every finding read counts, including ones the normalizer rejects:
|
|
602
|
+
* the point is how far through the window the read got.
|
|
603
|
+
*/
|
|
604
|
+
let lastCreatedAt: Date | undefined = undefined;
|
|
605
|
+
|
|
606
|
+
while (true) {
|
|
607
|
+
if (result.requestCount >= maxRequests) {
|
|
608
|
+
result.complete = false;
|
|
609
|
+
result.resumeAfter = lastCreatedAt;
|
|
610
|
+
result.warnings.push(
|
|
611
|
+
`Stopped after ${result.requestCount} findings requests (the per-run request limit) before the window was fully read. ${AwsSecurityHubConnector.progressSentence(lastCreatedAt)}`,
|
|
612
|
+
);
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const page: AwsSecurityHubFindingsPage = await client.getFindings({
|
|
617
|
+
startTime: window.startTime,
|
|
618
|
+
endTime: window.endTime,
|
|
619
|
+
maxResults: AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE,
|
|
620
|
+
nextToken,
|
|
621
|
+
});
|
|
622
|
+
result.requestCount++;
|
|
623
|
+
|
|
624
|
+
let findings: Array<JSONObject> = page.findings;
|
|
625
|
+
const remaining: number = maxEvents - result.fetchedCount;
|
|
626
|
+
let eventBoundHit: boolean = false;
|
|
627
|
+
|
|
628
|
+
if (findings.length > remaining) {
|
|
629
|
+
findings = findings.slice(0, Math.max(0, remaining));
|
|
630
|
+
eventBoundHit = true;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
for (const raw of findings) {
|
|
634
|
+
result.fetchedCount++;
|
|
635
|
+
|
|
636
|
+
const createdAt: Date | undefined =
|
|
637
|
+
AwsSecurityHubConnector.readCreatedAt(raw);
|
|
638
|
+
|
|
639
|
+
if (createdAt) {
|
|
640
|
+
lastCreatedAt = createdAt;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (!AwsSecurityHubNormalizer.isRecognized(raw)) {
|
|
644
|
+
result.rejectedCount++;
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
try {
|
|
649
|
+
const normalized: NormalizedSecurityEvent =
|
|
650
|
+
AwsSecurityHubNormalizer.normalize(raw);
|
|
651
|
+
result.events.push(normalized);
|
|
652
|
+
|
|
653
|
+
if (result.samples.length < sampleLimit) {
|
|
654
|
+
result.samples.push(AwsSecurityHubConnector.toSample(normalized));
|
|
655
|
+
}
|
|
656
|
+
} catch {
|
|
657
|
+
result.failedCount++;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (
|
|
662
|
+
eventBoundHit ||
|
|
663
|
+
(page.nextToken && result.fetchedCount >= maxEvents)
|
|
664
|
+
) {
|
|
665
|
+
result.complete = false;
|
|
666
|
+
result.resumeAfter = lastCreatedAt;
|
|
667
|
+
result.warnings.push(
|
|
668
|
+
`Stopped after ${result.fetchedCount} findings (the per-run record limit) before the window was fully read. ${AwsSecurityHubConnector.progressSentence(lastCreatedAt)}`,
|
|
669
|
+
);
|
|
670
|
+
break;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (!page.nextToken) {
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
nextToken = page.nextToken;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
return result;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/*
|
|
684
|
+
* A finding's CreatedAt as a Date, or undefined when it is missing or
|
|
685
|
+
* unparseable. ASFF allows up to nine fractional digits; Date keeps
|
|
686
|
+
* milliseconds, which only ever rounds the resume point earlier, so the
|
|
687
|
+
* next poll re-reads (and dedupes) rather than skips.
|
|
688
|
+
*/
|
|
689
|
+
private static readCreatedAt(raw: JSONObject): Date | undefined {
|
|
690
|
+
const value: unknown = raw["CreatedAt"];
|
|
691
|
+
|
|
692
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
693
|
+
return undefined;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const parsed: Date = new Date(value.trim());
|
|
697
|
+
|
|
698
|
+
return Number.isNaN(parsed.getTime()) ? undefined : parsed;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/*
|
|
702
|
+
* How far a stopped read got, in the warning the run records. The
|
|
703
|
+
* poller decides what the next poll does with it and says so itself.
|
|
704
|
+
*/
|
|
705
|
+
private static progressSentence(lastCreatedAt: Date | undefined): string {
|
|
706
|
+
return lastCreatedAt
|
|
707
|
+
? `The last finding read was created at ${lastCreatedAt.toISOString()}.`
|
|
708
|
+
: "No finding read carried a readable CreatedAt, so no resume point is reported.";
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
private static toSample(
|
|
712
|
+
event: NormalizedSecurityEvent,
|
|
713
|
+
): SecurityConnectorSample {
|
|
714
|
+
const createdTime: string = String(event.attributes["CreatedAt"] || "");
|
|
715
|
+
const observedTime: string = String(
|
|
716
|
+
event.attributes["FirstObservedAt"] || "",
|
|
717
|
+
);
|
|
718
|
+
|
|
719
|
+
return {
|
|
720
|
+
id: event.eventUid,
|
|
721
|
+
title: event.message,
|
|
722
|
+
severity: event.severityName,
|
|
723
|
+
...(createdTime ? { createdTime } : {}),
|
|
724
|
+
/*
|
|
725
|
+
* The sample's eventTime is the finding's own first-observed time
|
|
726
|
+
* when the product reported one, so the diagnostics view can show
|
|
727
|
+
* how far behind the activity a finding was created.
|
|
728
|
+
*/
|
|
729
|
+
eventTime: observedTime || event.time.toISOString(),
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
}
|