@oneuptime/common 13.0.3 → 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/LoggerCore.test.ts +597 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtil.test.ts +1109 -0
- 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/EntityRegistry.test.ts +711 -0
- 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 +868 -0
- package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
- package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilCorePaths.test.ts +1014 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +9 -6
- package/Tests/Types/Rules/RuleCriteriaFieldRegistry.test.ts +276 -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/LlmConventions.test.ts +495 -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/SessionReplayHealth.test.ts +884 -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/OnCallDutyPolicy/Layer.ts +12 -0
- package/Types/Permission.ts +2 -2
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- 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/OnCallDutyPolicy/Layer.js +11 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/Permission.js +2 -2
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +9 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.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
package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js
ADDED
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
import { createHash, createHmac } from "crypto";
|
|
2
|
+
import APIException from "../../../../../Types/Exception/ApiException";
|
|
3
|
+
import BadDataException from "../../../../../Types/Exception/BadDataException";
|
|
4
|
+
import { REDACTED, redactLogString, redactLogValue, } from "../../../LogRedaction";
|
|
5
|
+
/*
|
|
6
|
+
* AWS Security Hub HTTP client: a hand-rolled AWS Signature Version 4
|
|
7
|
+
* signer plus the GetFindings list, with nothing from the AWS SDK.
|
|
8
|
+
*
|
|
9
|
+
* Contracts this file relies on, verified against AWS's references:
|
|
10
|
+
* - Signing: AWS Signature Version 4 as described in "Create a signed
|
|
11
|
+
* AWS API request" — canonical request (method, URI, sorted query,
|
|
12
|
+
* lowercased sorted headers, signed header list, hex SHA-256 of the
|
|
13
|
+
* payload), string to sign (AWS4-HMAC-SHA256, x-amz-date, credential
|
|
14
|
+
* scope YYYYMMDD/region/service/aws4_request, hex SHA-256 of the
|
|
15
|
+
* canonical request), the HMAC chain kDate → kRegion → kService →
|
|
16
|
+
* kSigning, and the Authorization header
|
|
17
|
+
* "AWS4-HMAC-SHA256 Credential=..., SignedHeaders=..., Signature=...".
|
|
18
|
+
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html
|
|
19
|
+
* Temporary credentials add x-amz-security-token, which the page says
|
|
20
|
+
* to include in the canonical headers. The signer is checked in tests
|
|
21
|
+
* against the vectors of AWS's published SigV4 test suite (get-vanilla,
|
|
22
|
+
* post-vanilla, post-x-www-form-urlencoded, post-header-key-sort,
|
|
23
|
+
* post-sts-header-before).
|
|
24
|
+
* - GetFindings: POST /findings with a JSON body of Filters, MaxResults
|
|
25
|
+
* (1..100), NextToken and SortCriteria [{Field, SortOrder}]; the
|
|
26
|
+
* response is { Findings: [...], NextToken? }. Errors are
|
|
27
|
+
* InvalidAccessException (401 in the GetFindings reference),
|
|
28
|
+
* AccessDeniedException (403, a common error), InvalidInputException
|
|
29
|
+
* (400), LimitExceededException (429) and InternalException (500).
|
|
30
|
+
* When cross-Region aggregation is enabled, a call in the home Region
|
|
31
|
+
* also returns findings from linked Regions.
|
|
32
|
+
* https://docs.aws.amazon.com/securityhub/1.0/APIReference/API_GetFindings.html
|
|
33
|
+
* - CreatedAt is set by the finding PROVIDER ("when the security findings
|
|
34
|
+
* provider created the potential security issue"), not by Security
|
|
35
|
+
* Hub; ProcessedAt is when Security Hub received it. Delivery lags
|
|
36
|
+
* CreatedAt (GuardDuty and AWS Config: usually within five minutes;
|
|
37
|
+
* EventBridge retries a failed delivery for up to 24 hours), which is
|
|
38
|
+
* why the catalog gives this provider a 30 minute cursor overlap.
|
|
39
|
+
* https://docs.aws.amazon.com/securityhub/1.0/APIReference/API_AwsSecurityFinding.html
|
|
40
|
+
* https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-internal-providers.html
|
|
41
|
+
* - DateFilter: { Start, End } timestamps, ISO 8601 with a Z suffix and
|
|
42
|
+
* up to nine fractional digits (Date.toISOString() qualifies).
|
|
43
|
+
* https://docs.aws.amazon.com/securityhub/1.0/APIReference/API_DateFilter.html
|
|
44
|
+
* https://docs.aws.amazon.com/securityhub/1.0/APIReference/Welcome.html#timestamps
|
|
45
|
+
* - Endpoints: securityhub.{region}.amazonaws.com, including the
|
|
46
|
+
* us-gov-* Regions; GetFindings is throttled at 3 requests per second
|
|
47
|
+
* (burst 6).
|
|
48
|
+
* https://docs.aws.amazon.com/general/latest/gr/sechub.html
|
|
49
|
+
*
|
|
50
|
+
* Every request goes through the injected ConnectorTransport (the
|
|
51
|
+
* SSRF-guarded DataSourceHttpFetch in production), carries the caller's
|
|
52
|
+
* timeout, and is additionally raced against a local deadline so a
|
|
53
|
+
* transport that never settles cannot pin a poll. Every error is an
|
|
54
|
+
* APIException whose prefix names the step ("findings request") and
|
|
55
|
+
* whose body excerpt has been through redaction, so the message can be
|
|
56
|
+
* stored on the connection row and shown in the UI.
|
|
57
|
+
*/
|
|
58
|
+
export const AWS_SECURITY_HUB_SERVICE = "securityhub";
|
|
59
|
+
/*
|
|
60
|
+
* GetFindings caps MaxResults at 100 (API reference). The poller's
|
|
61
|
+
* 20-request budget therefore covers 2,000 findings per run.
|
|
62
|
+
*/
|
|
63
|
+
export const AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE = 100;
|
|
64
|
+
export const AWS_SECURITY_HUB_MAX_PAGE_SIZE = 100;
|
|
65
|
+
export const AWS_SECURITY_HUB_DEFAULT_REQUEST_TIMEOUT_IN_MS = 60 * 1000;
|
|
66
|
+
const FINDINGS_STEP = "findings request";
|
|
67
|
+
const SIGV4_ALGORITHM = "AWS4-HMAC-SHA256";
|
|
68
|
+
const SIGV4_TERMINATOR = "aws4_request";
|
|
69
|
+
/*
|
|
70
|
+
* Region codes: a partition prefix of letters, one or more hyphenated
|
|
71
|
+
* words and a trailing number (us-east-1, us-gov-west-1, ap-southeast-3,
|
|
72
|
+
* eu-central-2, il-central-1, mx-central-1). The value is interpolated
|
|
73
|
+
* into a hostname and into the credential scope, so anything else is
|
|
74
|
+
* refused before a request is built.
|
|
75
|
+
*/
|
|
76
|
+
const REGION_REGEX = /^[a-z]{2,4}(?:-[a-z]+)+-\d+$/;
|
|
77
|
+
/*
|
|
78
|
+
* IAM access key ids are 16-128 characters of letters and digits (the
|
|
79
|
+
* AccessKeyId pattern on the IAM API is [\w]+ with those bounds); the
|
|
80
|
+
* common shapes are the 20-character AKIA... (long-lived) and ASIA...
|
|
81
|
+
* (temporary) ids.
|
|
82
|
+
*/
|
|
83
|
+
const ACCESS_KEY_ID_REGEX = /^[A-Za-z0-9]{16,128}$/;
|
|
84
|
+
// The shape DataSourceHttpFetch throws for a non-2xx answer.
|
|
85
|
+
const TRANSPORT_HTTP_ERROR_REGEX = /^Data source responded with HTTP (\d{3}):\s*([\s\S]*)$/;
|
|
86
|
+
/*
|
|
87
|
+
* Error codes AWS returns when the signature itself is rejected, i.e.
|
|
88
|
+
* before Security Hub's own authorization runs. They mean the access key,
|
|
89
|
+
* secret, session token, clock or signing code is wrong — never the IAM
|
|
90
|
+
* policy. Names from the SigV4 troubleshooting reference and the common
|
|
91
|
+
* AWS error taxonomy:
|
|
92
|
+
* https://docs.aws.amazon.com/IAM/latest/UserGuide/signature-v4-troubleshooting.html
|
|
93
|
+
*/
|
|
94
|
+
const SIGNATURE_ERROR_CODES = [
|
|
95
|
+
"UnrecognizedClientException",
|
|
96
|
+
"InvalidClientTokenId",
|
|
97
|
+
"InvalidSignatureException",
|
|
98
|
+
"SignatureDoesNotMatch",
|
|
99
|
+
"IncompleteSignatureException",
|
|
100
|
+
"ExpiredTokenException",
|
|
101
|
+
"ExpiredToken",
|
|
102
|
+
"RequestExpired",
|
|
103
|
+
"RequestTimeTooSkewed",
|
|
104
|
+
"MissingAuthenticationTokenException",
|
|
105
|
+
"MissingAuthenticationToken",
|
|
106
|
+
"InvalidAccessKeyId",
|
|
107
|
+
];
|
|
108
|
+
/*
|
|
109
|
+
* The only codes that mean AWS accepted the signature and Security Hub
|
|
110
|
+
* then refused the call: the IAM policy does not allow GetFindings, or
|
|
111
|
+
* Security Hub is not enabled for the account in the Region.
|
|
112
|
+
*/
|
|
113
|
+
const AUTHORIZATION_ERROR_CODES = [
|
|
114
|
+
"AccessDeniedException",
|
|
115
|
+
"InvalidAccessException",
|
|
116
|
+
];
|
|
117
|
+
/*
|
|
118
|
+
* REST-JSON services send the error code in the x-amzn-errortype header,
|
|
119
|
+
* and the production transport (DataSourceHttpFetch) keeps only the
|
|
120
|
+
* status and the body of a non-2xx answer. A signature rejection's body
|
|
121
|
+
* is often just {"message": "..."}, so without this table a wrong secret
|
|
122
|
+
* arrives as a code-less 403 and was once reported as valid credentials
|
|
123
|
+
* with an IAM remediation. Each entry is AWS's own wording for that code,
|
|
124
|
+
* checked in order (the expired-token wording before the invalid-token
|
|
125
|
+
* one, which shares its prefix).
|
|
126
|
+
*/
|
|
127
|
+
const MESSAGE_ERROR_CODES = [
|
|
128
|
+
{
|
|
129
|
+
pattern: /security token included in the request is expired/i,
|
|
130
|
+
code: "ExpiredTokenException",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
pattern: /security token included in the request is invalid/i,
|
|
134
|
+
code: "UnrecognizedClientException",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
pattern: /signature we calculated does not match/i,
|
|
138
|
+
code: "InvalidSignatureException",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
pattern: /signature expired|signature not yet current/i,
|
|
142
|
+
code: "InvalidSignatureException",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
pattern: /difference between the request time and the current time is too large/i,
|
|
146
|
+
code: "RequestTimeTooSkewed",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
pattern: /missing authentication token/i,
|
|
150
|
+
code: "MissingAuthenticationTokenException",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
pattern: /authorization header requires|credential should be scoped to/i,
|
|
154
|
+
code: "IncompleteSignatureException",
|
|
155
|
+
},
|
|
156
|
+
{ pattern: /is not authorized to perform/i, code: "AccessDeniedException" },
|
|
157
|
+
{
|
|
158
|
+
pattern: /is not subscribed to AWS Security Hub/i,
|
|
159
|
+
code: "InvalidAccessException",
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
// A signature rejected for its time rather than its key: the host clock.
|
|
163
|
+
const CLOCK_MESSAGE_REGEX = /signature expired|signature not yet current|request time and the current time is too large/i;
|
|
164
|
+
/*
|
|
165
|
+
* Authorization only when the recovered code says Security Hub itself
|
|
166
|
+
* refused a verified request. A code-less 403 stays "other": a wrong
|
|
167
|
+
* secret behind a header-dropping transport looks exactly like that, and
|
|
168
|
+
* calling it a permission problem sends the customer to IAM while the
|
|
169
|
+
* credential is what is wrong. Declared before the error class and the
|
|
170
|
+
* client because both use it.
|
|
171
|
+
*/
|
|
172
|
+
function classifyAwsSecurityHubFailure(status, code) {
|
|
173
|
+
if (SIGNATURE_ERROR_CODES.includes(code)) {
|
|
174
|
+
return "authentication";
|
|
175
|
+
}
|
|
176
|
+
if (AUTHORIZATION_ERROR_CODES.includes(code)) {
|
|
177
|
+
return "authorization";
|
|
178
|
+
}
|
|
179
|
+
if (status === 401) {
|
|
180
|
+
return "authentication";
|
|
181
|
+
}
|
|
182
|
+
return "other";
|
|
183
|
+
}
|
|
184
|
+
/*
|
|
185
|
+
* Thrown for every failure that carries an HTTP status, so the connector
|
|
186
|
+
* decides authentication versus permission from the recovered code
|
|
187
|
+
* instead of from hint wording in the message.
|
|
188
|
+
*/
|
|
189
|
+
export class AwsSecurityHubHttpError extends APIException {
|
|
190
|
+
constructor(data) {
|
|
191
|
+
super(data.message);
|
|
192
|
+
this.statusCode = data.statusCode;
|
|
193
|
+
this.errorCode = data.errorCode;
|
|
194
|
+
this.failureKind = classifyAwsSecurityHubFailure(data.statusCode, data.errorCode);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export default class AwsSecurityHubClient {
|
|
198
|
+
constructor(options) {
|
|
199
|
+
this.requestCount = 0;
|
|
200
|
+
AwsSecurityHubClient.validateRegion(options.region);
|
|
201
|
+
AwsSecurityHubClient.validateAccessKeyId(options.accessKeyId);
|
|
202
|
+
if (!options.secretAccessKey) {
|
|
203
|
+
throw new BadDataException("Secret access key is required.");
|
|
204
|
+
}
|
|
205
|
+
this.options = options;
|
|
206
|
+
this.requestTimeoutInMs =
|
|
207
|
+
options.requestTimeoutInMs && options.requestTimeoutInMs > 0
|
|
208
|
+
? options.requestTimeoutInMs
|
|
209
|
+
: AWS_SECURITY_HUB_DEFAULT_REQUEST_TIMEOUT_IN_MS;
|
|
210
|
+
}
|
|
211
|
+
// Every outbound request this instance made.
|
|
212
|
+
getRequestCount() {
|
|
213
|
+
return this.requestCount;
|
|
214
|
+
}
|
|
215
|
+
/*
|
|
216
|
+
* ---------------------------------------------------------------------
|
|
217
|
+
* Validation (shared with the connector's validateSettings)
|
|
218
|
+
* ---------------------------------------------------------------------
|
|
219
|
+
*/
|
|
220
|
+
static validateRegion(value) {
|
|
221
|
+
const trimmed = (value || "").trim();
|
|
222
|
+
if (!trimmed || !REGION_REGEX.test(trimmed)) {
|
|
223
|
+
throw new BadDataException("Region must be an AWS Region code such as us-east-1, eu-central-1 or us-gov-west-1.");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
static validateAccessKeyId(value) {
|
|
227
|
+
const trimmed = (value || "").trim();
|
|
228
|
+
if (!trimmed || !ACCESS_KEY_ID_REGEX.test(trimmed)) {
|
|
229
|
+
throw new BadDataException("Access key ID must be 16-128 letters or digits, such as the 20-character id that starts with AKIA (long-lived) or ASIA (temporary).");
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/*
|
|
233
|
+
* ---------------------------------------------------------------------
|
|
234
|
+
* URLs
|
|
235
|
+
* ---------------------------------------------------------------------
|
|
236
|
+
*/
|
|
237
|
+
/*
|
|
238
|
+
* The regional endpoint from the AWS General Reference. The China
|
|
239
|
+
* partition (cn-*) lives under amazonaws.com.cn; every other partition
|
|
240
|
+
* (aws, aws-us-gov) uses amazonaws.com.
|
|
241
|
+
*/
|
|
242
|
+
static getEndpointHost(region) {
|
|
243
|
+
const trimmed = region.trim();
|
|
244
|
+
const suffix = trimmed.startsWith("cn-")
|
|
245
|
+
? "amazonaws.com.cn"
|
|
246
|
+
: "amazonaws.com";
|
|
247
|
+
return `${AWS_SECURITY_HUB_SERVICE}.${trimmed}.${suffix}`;
|
|
248
|
+
}
|
|
249
|
+
getEndpointHost() {
|
|
250
|
+
return AwsSecurityHubClient.getEndpointHost(this.options.region);
|
|
251
|
+
}
|
|
252
|
+
getFindingsUrl() {
|
|
253
|
+
return `https://${this.getEndpointHost()}/findings`;
|
|
254
|
+
}
|
|
255
|
+
static clampPageSize(value) {
|
|
256
|
+
if (!value || !Number.isFinite(value)) {
|
|
257
|
+
return AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE;
|
|
258
|
+
}
|
|
259
|
+
return Math.min(AWS_SECURITY_HUB_MAX_PAGE_SIZE, Math.max(1, Math.floor(value)));
|
|
260
|
+
}
|
|
261
|
+
/*
|
|
262
|
+
* The GetFindings body for findings CREATED in [startTime, endTime],
|
|
263
|
+
* oldest first. Creation time is the poll basis (see Connectors/Types.ts
|
|
264
|
+
* for why): a GuardDuty finding is created when GuardDuty evaluates the
|
|
265
|
+
* activity, which can be well after FirstObservedAt, and a control
|
|
266
|
+
* finding is created when the control first evaluates the resource.
|
|
267
|
+
* CreatedAt is the provider's timestamp, so a finding can become
|
|
268
|
+
* readable here minutes after it; the catalog's 30 minute cursor overlap
|
|
269
|
+
* re-reads that span on every poll and the dedupe by finding Id drops
|
|
270
|
+
* what was already imported. DateFilter bounds are inclusive, which the
|
|
271
|
+
* same dedupe makes harmless. The ascending sort is what lets the
|
|
272
|
+
* connector report the CreatedAt of the last finding it read as a
|
|
273
|
+
* resume point when a bound stops it.
|
|
274
|
+
*/
|
|
275
|
+
static buildFindingsBody(data) {
|
|
276
|
+
const body = {
|
|
277
|
+
Filters: {
|
|
278
|
+
CreatedAt: [
|
|
279
|
+
{
|
|
280
|
+
Start: data.startTime.toISOString(),
|
|
281
|
+
End: data.endTime.toISOString(),
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
},
|
|
285
|
+
SortCriteria: [{ Field: "CreatedAt", SortOrder: "asc" }],
|
|
286
|
+
MaxResults: AwsSecurityHubClient.clampPageSize(data.maxResults),
|
|
287
|
+
};
|
|
288
|
+
if (data.nextToken) {
|
|
289
|
+
body["NextToken"] = data.nextToken;
|
|
290
|
+
}
|
|
291
|
+
return body;
|
|
292
|
+
}
|
|
293
|
+
/*
|
|
294
|
+
* ---------------------------------------------------------------------
|
|
295
|
+
* Signature Version 4
|
|
296
|
+
* ---------------------------------------------------------------------
|
|
297
|
+
*/
|
|
298
|
+
static sha256Hex(value) {
|
|
299
|
+
return createHash("sha256").update(value, "utf8").digest("hex");
|
|
300
|
+
}
|
|
301
|
+
static hmac(key, value) {
|
|
302
|
+
return createHmac("sha256", key).update(value, "utf8").digest();
|
|
303
|
+
}
|
|
304
|
+
/*
|
|
305
|
+
* AWS's UriEncode: RFC 3986 unreserved characters pass, everything else
|
|
306
|
+
* is percent-encoded with uppercase hex. encodeURIComponent already
|
|
307
|
+
* leaves A-Z a-z 0-9 - _ . ~ alone but also spares ! ' ( ) *, which AWS
|
|
308
|
+
* encodes.
|
|
309
|
+
*/
|
|
310
|
+
static uriEncode(value) {
|
|
311
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (character) => {
|
|
312
|
+
return `%${character.charCodeAt(0).toString(16).toUpperCase()}`;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
// YYYYMMDDTHHMMSSZ from a Date, the x-amz-date format.
|
|
316
|
+
static toAmzDate(date) {
|
|
317
|
+
return date
|
|
318
|
+
.toISOString()
|
|
319
|
+
.replace(/[-:]/g, "")
|
|
320
|
+
.replace(/\.\d{3}Z$/, "Z");
|
|
321
|
+
}
|
|
322
|
+
/*
|
|
323
|
+
* Sign one request. Pure and deterministic given `date`, so the tests
|
|
324
|
+
* can compare the canonical request, the string to sign and the
|
|
325
|
+
* signature against AWS's published vectors byte for byte.
|
|
326
|
+
*/
|
|
327
|
+
static signRequest(input) {
|
|
328
|
+
const amzDate = AwsSecurityHubClient.toAmzDate(input.date);
|
|
329
|
+
const dateStamp = amzDate.substring(0, 8);
|
|
330
|
+
const region = input.region.trim().toLowerCase();
|
|
331
|
+
const service = input.service.trim().toLowerCase();
|
|
332
|
+
/*
|
|
333
|
+
* Headers to sign: the caller's, plus host, x-amz-date and the session
|
|
334
|
+
* token. Names are lowercased and sorted; values are trimmed with
|
|
335
|
+
* internal runs of whitespace collapsed, per the canonical headers
|
|
336
|
+
* rules.
|
|
337
|
+
*/
|
|
338
|
+
const headerValues = {};
|
|
339
|
+
for (const name of Object.keys(input.headers || {})) {
|
|
340
|
+
const value = (input.headers || {})[name];
|
|
341
|
+
if (value === undefined || value === null) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
headerValues[name.toLowerCase()] = String(value);
|
|
345
|
+
}
|
|
346
|
+
headerValues["host"] = input.host;
|
|
347
|
+
headerValues["x-amz-date"] = amzDate;
|
|
348
|
+
if (input.sessionToken) {
|
|
349
|
+
headerValues["x-amz-security-token"] = input.sessionToken;
|
|
350
|
+
}
|
|
351
|
+
const signedHeaderNames = Object.keys(headerValues).sort();
|
|
352
|
+
const canonicalHeaders = signedHeaderNames
|
|
353
|
+
.map((name) => {
|
|
354
|
+
return `${name}:${(headerValues[name] || "").trim().replace(/\s+/g, " ")}\n`;
|
|
355
|
+
})
|
|
356
|
+
.join("");
|
|
357
|
+
const signedHeaders = signedHeaderNames.join(";");
|
|
358
|
+
// Query: each name and value URI-encoded, then sorted by encoded name.
|
|
359
|
+
const canonicalQueryString = Object.keys(input.query || {})
|
|
360
|
+
.map((name) => {
|
|
361
|
+
return [
|
|
362
|
+
AwsSecurityHubClient.uriEncode(name),
|
|
363
|
+
AwsSecurityHubClient.uriEncode((input.query || {})[name] || ""),
|
|
364
|
+
];
|
|
365
|
+
})
|
|
366
|
+
.sort((a, b) => {
|
|
367
|
+
if (a[0] === b[0]) {
|
|
368
|
+
return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0;
|
|
369
|
+
}
|
|
370
|
+
return a[0] < b[0] ? -1 : 1;
|
|
371
|
+
})
|
|
372
|
+
.map((pair) => {
|
|
373
|
+
return `${pair[0]}=${pair[1]}`;
|
|
374
|
+
})
|
|
375
|
+
.join("&");
|
|
376
|
+
// Path: each segment URI-encoded once; "/" itself is never encoded.
|
|
377
|
+
const canonicalUri = input.path === "" || input.path === "/"
|
|
378
|
+
? "/"
|
|
379
|
+
: input.path
|
|
380
|
+
.split("/")
|
|
381
|
+
.map((segment) => {
|
|
382
|
+
return AwsSecurityHubClient.uriEncode(segment);
|
|
383
|
+
})
|
|
384
|
+
.join("/");
|
|
385
|
+
const payloadHash = AwsSecurityHubClient.sha256Hex(input.body);
|
|
386
|
+
const canonicalRequest = [
|
|
387
|
+
input.method,
|
|
388
|
+
canonicalUri,
|
|
389
|
+
canonicalQueryString,
|
|
390
|
+
canonicalHeaders,
|
|
391
|
+
signedHeaders,
|
|
392
|
+
payloadHash,
|
|
393
|
+
].join("\n");
|
|
394
|
+
const credentialScope = `${dateStamp}/${region}/${service}/${SIGV4_TERMINATOR}`;
|
|
395
|
+
const stringToSign = [
|
|
396
|
+
SIGV4_ALGORITHM,
|
|
397
|
+
amzDate,
|
|
398
|
+
credentialScope,
|
|
399
|
+
AwsSecurityHubClient.sha256Hex(canonicalRequest),
|
|
400
|
+
].join("\n");
|
|
401
|
+
const kDate = AwsSecurityHubClient.hmac(`AWS4${input.secretAccessKey}`, dateStamp);
|
|
402
|
+
const kRegion = AwsSecurityHubClient.hmac(kDate, region);
|
|
403
|
+
const kService = AwsSecurityHubClient.hmac(kRegion, service);
|
|
404
|
+
const kSigning = AwsSecurityHubClient.hmac(kService, SIGV4_TERMINATOR);
|
|
405
|
+
const signature = createHmac("sha256", kSigning)
|
|
406
|
+
.update(stringToSign, "utf8")
|
|
407
|
+
.digest("hex");
|
|
408
|
+
const authorization = `${SIGV4_ALGORITHM} Credential=${input.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
|
|
409
|
+
/*
|
|
410
|
+
* Outgoing headers keep the caller's original casing for their own
|
|
411
|
+
* headers (HTTP is case-insensitive; the transport does not care) and
|
|
412
|
+
* add the AWS ones in their conventional spelling.
|
|
413
|
+
*/
|
|
414
|
+
const headers = Object.assign({}, (input.headers || {}));
|
|
415
|
+
headers["X-Amz-Date"] = amzDate;
|
|
416
|
+
if (input.sessionToken) {
|
|
417
|
+
headers["X-Amz-Security-Token"] = input.sessionToken;
|
|
418
|
+
}
|
|
419
|
+
headers["Authorization"] = authorization;
|
|
420
|
+
return {
|
|
421
|
+
headers,
|
|
422
|
+
canonicalRequest,
|
|
423
|
+
stringToSign,
|
|
424
|
+
signature,
|
|
425
|
+
amzDate,
|
|
426
|
+
credentialScope,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/*
|
|
430
|
+
* ---------------------------------------------------------------------
|
|
431
|
+
* Findings
|
|
432
|
+
* ---------------------------------------------------------------------
|
|
433
|
+
*/
|
|
434
|
+
/*
|
|
435
|
+
* One page of findings created in the window. Pass `nextToken` from the
|
|
436
|
+
* previous page to continue; the filter and sort are resent unchanged
|
|
437
|
+
* with it, as the API requires the same query on every page.
|
|
438
|
+
*/
|
|
439
|
+
async getFindings(data) {
|
|
440
|
+
const bodyObject = AwsSecurityHubClient.buildFindingsBody({
|
|
441
|
+
startTime: data.startTime,
|
|
442
|
+
endTime: data.endTime,
|
|
443
|
+
maxResults: data.maxResults || AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE,
|
|
444
|
+
nextToken: data.nextToken,
|
|
445
|
+
});
|
|
446
|
+
/*
|
|
447
|
+
* The body is serialized once and that exact string is both hashed
|
|
448
|
+
* into the signature and sent: a re-serialization by the transport
|
|
449
|
+
* would change the payload hash and fail the signature check.
|
|
450
|
+
*/
|
|
451
|
+
const bodyText = JSON.stringify(bodyObject);
|
|
452
|
+
const signed = AwsSecurityHubClient.signRequest({
|
|
453
|
+
method: "POST",
|
|
454
|
+
host: this.getEndpointHost(),
|
|
455
|
+
path: "/findings",
|
|
456
|
+
headers: { "Content-Type": "application/json" },
|
|
457
|
+
body: bodyText,
|
|
458
|
+
accessKeyId: this.options.accessKeyId.trim(),
|
|
459
|
+
secretAccessKey: this.options.secretAccessKey,
|
|
460
|
+
sessionToken: this.options.sessionToken || undefined,
|
|
461
|
+
region: this.options.region.trim(),
|
|
462
|
+
service: AWS_SECURITY_HUB_SERVICE,
|
|
463
|
+
date: this.options.now ? this.options.now() : new Date(),
|
|
464
|
+
});
|
|
465
|
+
const response = await this.send({
|
|
466
|
+
method: "POST",
|
|
467
|
+
url: this.getFindingsUrl(),
|
|
468
|
+
headers: signed.headers,
|
|
469
|
+
body: bodyText,
|
|
470
|
+
}, FINDINGS_STEP);
|
|
471
|
+
const body = this.requireJsonObject(response, FINDINGS_STEP);
|
|
472
|
+
const findingsRaw = body["Findings"];
|
|
473
|
+
if (!Array.isArray(findingsRaw)) {
|
|
474
|
+
throw new APIException(`AWS Security Hub ${FINDINGS_STEP} returned an unrecognized response shape: expected a "Findings" array, received keys ${this.scrub(AwsSecurityHubClient.describeKeys(body))}.`);
|
|
475
|
+
}
|
|
476
|
+
const findings = findingsRaw.filter((item) => {
|
|
477
|
+
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
478
|
+
});
|
|
479
|
+
const nextTokenRaw = body["NextToken"];
|
|
480
|
+
const nextToken = typeof nextTokenRaw === "string" && nextTokenRaw.trim()
|
|
481
|
+
? nextTokenRaw
|
|
482
|
+
: null;
|
|
483
|
+
return { findings, nextToken };
|
|
484
|
+
}
|
|
485
|
+
/*
|
|
486
|
+
* Bounded availability count: one page of `maxResults` findings created
|
|
487
|
+
* in the window plus whether a further page exists. Never walks the
|
|
488
|
+
* pages — a count is for the test checklist, not for import.
|
|
489
|
+
*/
|
|
490
|
+
async countFindingsCreated(data) {
|
|
491
|
+
const page = await this.getFindings({
|
|
492
|
+
startTime: data.startTime,
|
|
493
|
+
endTime: data.endTime,
|
|
494
|
+
maxResults: data.maxResults || AWS_SECURITY_HUB_DEFAULT_PAGE_SIZE,
|
|
495
|
+
});
|
|
496
|
+
return {
|
|
497
|
+
count: page.findings.length,
|
|
498
|
+
hasMore: page.nextToken !== null,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/*
|
|
502
|
+
* ---------------------------------------------------------------------
|
|
503
|
+
* Transport plumbing
|
|
504
|
+
* ---------------------------------------------------------------------
|
|
505
|
+
*/
|
|
506
|
+
// Send and require a 2xx answer.
|
|
507
|
+
async send(request, stepLabel) {
|
|
508
|
+
const response = await this.sendRaw(request, stepLabel);
|
|
509
|
+
this.assertOk(response, stepLabel);
|
|
510
|
+
return response;
|
|
511
|
+
}
|
|
512
|
+
/*
|
|
513
|
+
* Send and return whatever status came back. Transport failures that
|
|
514
|
+
* carry an HTTP status are folded into a response; everything else
|
|
515
|
+
* (connection refused, the transport's own timeout, the local deadline)
|
|
516
|
+
* throws with the step in the prefix.
|
|
517
|
+
*/
|
|
518
|
+
async sendRaw(request, stepLabel) {
|
|
519
|
+
this.requestCount++;
|
|
520
|
+
const timeoutSeconds = Math.max(1, Math.round(this.requestTimeoutInMs / 1000));
|
|
521
|
+
let timer = undefined;
|
|
522
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
523
|
+
timer = setTimeout(() => {
|
|
524
|
+
reject(new APIException(`AWS Security Hub ${stepLabel} timed out after ${timeoutSeconds} seconds with no response.`));
|
|
525
|
+
}, this.requestTimeoutInMs);
|
|
526
|
+
});
|
|
527
|
+
try {
|
|
528
|
+
return await Promise.race([
|
|
529
|
+
this.options.transport(Object.assign(Object.assign({}, request), { timeoutInMs: this.requestTimeoutInMs })),
|
|
530
|
+
deadline,
|
|
531
|
+
]);
|
|
532
|
+
}
|
|
533
|
+
catch (error) {
|
|
534
|
+
return this.recoverResponse(error, stepLabel);
|
|
535
|
+
}
|
|
536
|
+
finally {
|
|
537
|
+
clearTimeout(timer);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
assertOk(response, stepLabel) {
|
|
541
|
+
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
const code = AwsSecurityHubClient.errorCode(response);
|
|
545
|
+
throw new AwsSecurityHubHttpError({
|
|
546
|
+
message: `AWS Security Hub ${stepLabel} failed (HTTP ${response.statusCode}): ${this.scrub(AwsSecurityHubClient.describeBody(response))}${AwsSecurityHubClient.hintForFailure(response.statusCode, code, response.bodyText || "")}`,
|
|
547
|
+
statusCode: response.statusCode,
|
|
548
|
+
errorCode: code,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
/*
|
|
552
|
+
* Belt and braces over the generic redaction. redactLogString masks
|
|
553
|
+
* values whose KEY names a secret and a few self-identifying token
|
|
554
|
+
* shapes, but a body or proxy error that reflects the bare secret with
|
|
555
|
+
* no label around it would pass straight through. This client knows the
|
|
556
|
+
* exact secret values it holds, so every message it throws has them
|
|
557
|
+
* replaced whatever the surrounding text looks like.
|
|
558
|
+
*/
|
|
559
|
+
scrub(text) {
|
|
560
|
+
let result = text;
|
|
561
|
+
for (const secret of [
|
|
562
|
+
this.options.secretAccessKey,
|
|
563
|
+
this.options.sessionToken || "",
|
|
564
|
+
]) {
|
|
565
|
+
if (secret && secret.length >= 8 && result.includes(secret)) {
|
|
566
|
+
result = result.split(secret).join(REDACTED);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
return result;
|
|
570
|
+
}
|
|
571
|
+
/*
|
|
572
|
+
* The production transport does not return error statuses — it throws
|
|
573
|
+
* `Data source responded with HTTP <status>: <body>`. Recover the status
|
|
574
|
+
* so the operator sees the same "(HTTP 403)" prefix whichever transport
|
|
575
|
+
* is behind the client, and the docs' troubleshooting keys stay true.
|
|
576
|
+
*/
|
|
577
|
+
recoverResponse(error, stepLabel) {
|
|
578
|
+
if (error instanceof APIException) {
|
|
579
|
+
throw error;
|
|
580
|
+
}
|
|
581
|
+
const message = error instanceof Error ? error.message : String(error || "");
|
|
582
|
+
const match = message.match(TRANSPORT_HTTP_ERROR_REGEX);
|
|
583
|
+
if (match) {
|
|
584
|
+
const bodyText = match[2] || "";
|
|
585
|
+
let bodyJson = undefined;
|
|
586
|
+
try {
|
|
587
|
+
bodyJson = JSON.parse(bodyText);
|
|
588
|
+
}
|
|
589
|
+
catch (_a) {
|
|
590
|
+
bodyJson = undefined;
|
|
591
|
+
}
|
|
592
|
+
return { statusCode: Number(match[1]), bodyText, bodyJson };
|
|
593
|
+
}
|
|
594
|
+
throw new APIException(`AWS Security Hub ${stepLabel} failed: ${this.scrub(redactLogString(message || "unknown transport error")).substring(0, 500)}`);
|
|
595
|
+
}
|
|
596
|
+
requireJsonObject(response, stepLabel) {
|
|
597
|
+
const body = response.bodyJson;
|
|
598
|
+
if (body === undefined || body === null) {
|
|
599
|
+
throw new APIException(`AWS Security Hub ${stepLabel} returned a non-JSON body: ${this.scrub(redactLogString((response.bodyText || "").substring(0, 200)))}`);
|
|
600
|
+
}
|
|
601
|
+
if (typeof body !== "object" || Array.isArray(body)) {
|
|
602
|
+
throw new APIException(`AWS Security Hub ${stepLabel} returned an unrecognized response shape: expected a JSON object, received ${Array.isArray(body) ? "an array" : typeof body}.`);
|
|
603
|
+
}
|
|
604
|
+
return body;
|
|
605
|
+
}
|
|
606
|
+
/*
|
|
607
|
+
* A body excerpt safe to store: structurally redacted when it parsed as
|
|
608
|
+
* JSON (so any key that names a secret is masked whatever its value
|
|
609
|
+
* looks like), textually redacted otherwise, and clipped.
|
|
610
|
+
*/
|
|
611
|
+
static describeBody(response) {
|
|
612
|
+
if (response.bodyJson !== undefined && response.bodyJson !== null) {
|
|
613
|
+
const redacted = redactLogValue(response.bodyJson);
|
|
614
|
+
let serialized = "";
|
|
615
|
+
try {
|
|
616
|
+
serialized = JSON.stringify(redacted);
|
|
617
|
+
}
|
|
618
|
+
catch (_a) {
|
|
619
|
+
serialized = "[unserializable body]";
|
|
620
|
+
}
|
|
621
|
+
return serialized.substring(0, 500);
|
|
622
|
+
}
|
|
623
|
+
const text = (response.bodyText || "").trim();
|
|
624
|
+
return text
|
|
625
|
+
? redactLogString(text).substring(0, 500)
|
|
626
|
+
: "(empty response body)";
|
|
627
|
+
}
|
|
628
|
+
static describeKeys(body) {
|
|
629
|
+
const keys = Object.keys(body).slice(0, 10);
|
|
630
|
+
return keys.length ? keys.join(", ") : "(none)";
|
|
631
|
+
}
|
|
632
|
+
/*
|
|
633
|
+
* The AWS error code of a failed response. REST-JSON services put it in
|
|
634
|
+
* the x-amzn-errortype header (sometimes suffixed with ":http://..."),
|
|
635
|
+
* and in the body as "__type" (sometimes namespace-qualified, e.g.
|
|
636
|
+
* "com.amazon.coral.service#UnrecognizedClientException") or "Code".
|
|
637
|
+
* When neither is present — the production transport drops headers —
|
|
638
|
+
* the code is recovered from AWS's own message wording (see
|
|
639
|
+
* MESSAGE_ERROR_CODES), so a signature rejection is still named.
|
|
640
|
+
*/
|
|
641
|
+
static errorCode(response) {
|
|
642
|
+
const fromHeader = String((response.headers || {})["x-amzn-errortype"] || "");
|
|
643
|
+
const body = response.bodyJson &&
|
|
644
|
+
typeof response.bodyJson === "object" &&
|
|
645
|
+
!Array.isArray(response.bodyJson)
|
|
646
|
+
? response.bodyJson
|
|
647
|
+
: null;
|
|
648
|
+
const fromBody = body
|
|
649
|
+
? String(body["__type"] || body["Code"] || body["code"] || "")
|
|
650
|
+
: "";
|
|
651
|
+
const raw = fromHeader || fromBody;
|
|
652
|
+
const withoutUri = raw.split(":")[0] || "";
|
|
653
|
+
const hashIndex = withoutUri.lastIndexOf("#");
|
|
654
|
+
const declared = hashIndex === -1
|
|
655
|
+
? withoutUri.trim()
|
|
656
|
+
: withoutUri.substring(hashIndex + 1).trim();
|
|
657
|
+
if (declared) {
|
|
658
|
+
return declared;
|
|
659
|
+
}
|
|
660
|
+
return AwsSecurityHubClient.errorCodeFromMessage(AwsSecurityHubClient.messageText(response));
|
|
661
|
+
}
|
|
662
|
+
// The code AWS's wording stands for, or "" when the text names none.
|
|
663
|
+
static errorCodeFromMessage(text) {
|
|
664
|
+
for (const entry of MESSAGE_ERROR_CODES) {
|
|
665
|
+
if (entry.pattern.test(text)) {
|
|
666
|
+
return entry.code;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return "";
|
|
670
|
+
}
|
|
671
|
+
// The body's message field when it has one, else the raw body text.
|
|
672
|
+
static messageText(response) {
|
|
673
|
+
const body = response.bodyJson &&
|
|
674
|
+
typeof response.bodyJson === "object" &&
|
|
675
|
+
!Array.isArray(response.bodyJson)
|
|
676
|
+
? response.bodyJson
|
|
677
|
+
: null;
|
|
678
|
+
const fromBody = body
|
|
679
|
+
? body["message"] || body["Message"]
|
|
680
|
+
: undefined;
|
|
681
|
+
if (typeof fromBody === "string" && fromBody.trim()) {
|
|
682
|
+
return fromBody;
|
|
683
|
+
}
|
|
684
|
+
return response.bodyText || "";
|
|
685
|
+
}
|
|
686
|
+
static isSignatureErrorCode(code) {
|
|
687
|
+
return SIGNATURE_ERROR_CODES.includes(code);
|
|
688
|
+
}
|
|
689
|
+
// See classifyAwsSecurityHubFailure.
|
|
690
|
+
static classifyFailure(status, code) {
|
|
691
|
+
return classifyAwsSecurityHubFailure(status, code);
|
|
692
|
+
}
|
|
693
|
+
/*
|
|
694
|
+
* What the status most likely means, in the operator's terms. The hint
|
|
695
|
+
* never repeats the body; `bodyText` only tells a clock rejection apart
|
|
696
|
+
* from a key rejection that shares its error code.
|
|
697
|
+
*/
|
|
698
|
+
static hintForFailure(status, code, bodyText = "") {
|
|
699
|
+
const hint = AwsSecurityHubClient.hintText(status, code, bodyText);
|
|
700
|
+
return hint ? ` — ${hint}` : "";
|
|
701
|
+
}
|
|
702
|
+
static hintText(status, code, bodyText) {
|
|
703
|
+
if (AwsSecurityHubClient.isSignatureErrorCode(code)) {
|
|
704
|
+
if (code === "UnrecognizedClientException" ||
|
|
705
|
+
code === "InvalidClientTokenId" ||
|
|
706
|
+
code === "InvalidAccessKeyId") {
|
|
707
|
+
return "AWS does not recognize the Access key ID (or the session token sent with it). Check the id; for temporary credentials paste the matching session token, and for a long-lived AKIA key leave the session token empty.";
|
|
708
|
+
}
|
|
709
|
+
if (code === "ExpiredTokenException" || code === "ExpiredToken") {
|
|
710
|
+
return "The temporary credentials have expired. Issue new credentials with STS and update the connection, or use a long-lived access key.";
|
|
711
|
+
}
|
|
712
|
+
/*
|
|
713
|
+
* "Signature expired" arrives as InvalidSignatureException, the
|
|
714
|
+
* same code as a wrong secret; only the wording says the clock.
|
|
715
|
+
*/
|
|
716
|
+
if (code === "RequestExpired" ||
|
|
717
|
+
code === "RequestTimeTooSkewed" ||
|
|
718
|
+
CLOCK_MESSAGE_REGEX.test(bodyText)) {
|
|
719
|
+
return "AWS rejected the request time; the OneUptime server clock is more than 5 minutes off. Fix NTP on the app and worker hosts.";
|
|
720
|
+
}
|
|
721
|
+
return "AWS rejected the request signature. The Secret access key does not match the Access key ID (or the session token is missing for an ASIA... key). Create a new access key and update the connection.";
|
|
722
|
+
}
|
|
723
|
+
if (code === "InvalidAccessException") {
|
|
724
|
+
return "Security Hub is not enabled for this account in this Region, or the account is not a Security Hub administrator here. Enable Security Hub in the Region, or point the connection at the administrator account's home Region.";
|
|
725
|
+
}
|
|
726
|
+
if (code === "AccessDeniedException") {
|
|
727
|
+
return "AWS verified the signature, but the IAM identity is not allowed to call securityhub:GetFindings. Attach a policy that allows securityhub:GetFindings (for example the AWSSecurityHubReadOnlyAccess managed policy) to the user or role.";
|
|
728
|
+
}
|
|
729
|
+
if (status === 403) {
|
|
730
|
+
return "AWS refused the request without naming an error code, so it is not known whether the credentials or the IAM policy were rejected. Check the Access key ID, the Secret access key and the Session token first (empty for an AKIA key, required for an ASIA key), then that the identity is allowed securityhub:GetFindings.";
|
|
731
|
+
}
|
|
732
|
+
if (status === 401) {
|
|
733
|
+
return "AWS refused the credentials. Check the Access key ID and Secret access key.";
|
|
734
|
+
}
|
|
735
|
+
if (status === 404) {
|
|
736
|
+
return "No Security Hub endpoint answered at this Region. Check the Region code.";
|
|
737
|
+
}
|
|
738
|
+
if (status === 429 ||
|
|
739
|
+
code === "LimitExceededException" ||
|
|
740
|
+
code === "ThrottlingException") {
|
|
741
|
+
return "Security Hub is throttling GetFindings (3 requests per second per account and Region); the next poll retries.";
|
|
742
|
+
}
|
|
743
|
+
if (status >= 500) {
|
|
744
|
+
return "Security Hub reported a server-side problem; the next poll retries.";
|
|
745
|
+
}
|
|
746
|
+
if (status === 400) {
|
|
747
|
+
return "Security Hub rejected the request. The findings query is built by the connector, not from your settings; report this message to OneUptime support.";
|
|
748
|
+
}
|
|
749
|
+
return "";
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
//# sourceMappingURL=AwsSecurityHubClient.js.map
|