@oneuptime/common 12.0.5 → 12.0.6
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/AIRun.ts +33 -0
- package/Models/DatabaseModels/DataSource.ts +744 -0
- package/Models/DatabaseModels/Index.ts +3 -0
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
- package/Models/DatabaseModels/User.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
- package/Models/DatabaseModels/UserSession.ts +2 -0
- package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
- package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
- package/Server/API/AIInsightAPI.ts +47 -4
- package/Server/API/AIInvestigationAPI.ts +25 -0
- package/Server/API/DashboardAPI.ts +176 -492
- package/Server/API/DataSourceAPI.ts +268 -0
- package/Server/API/StatusPageAPI.ts +11 -1
- package/Server/API/UserAPI.ts +119 -0
- package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Infrastructure/Queue.ts +26 -0
- package/Server/Infrastructure/QueueWorker.ts +17 -0
- package/Server/Middleware/TelemetryIngest.ts +8 -3
- package/Server/Services/AIInsightService.ts +132 -12
- package/Server/Services/AIRunService.ts +34 -0
- package/Server/Services/AIService.ts +17 -2
- package/Server/Services/AlertService.ts +38 -32
- package/Server/Services/AnalyticsDatabaseService.ts +8 -4
- package/Server/Services/DataSourceService.ts +200 -0
- package/Server/Services/HostService.ts +92 -0
- package/Server/Services/IncidentService.ts +45 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +49 -0
- package/Server/Services/MonitorStatusService.ts +166 -0
- package/Server/Services/OpenTelemetryIngestService.ts +255 -184
- package/Server/Services/RumSessionPinService.ts +7 -21
- package/Server/Services/StatusPageSubscriberService.ts +13 -0
- package/Server/Services/UserService.ts +280 -9
- package/Server/Static/Vendor/README.md +62 -0
- package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
- package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
- package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
- package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
- package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
- package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
- package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
- package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
- package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
- package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
- package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
- package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
- package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
- package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
- package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
- package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
- package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
- package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
- package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
- package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
- package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
- package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
- package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
- package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
- package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
- package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
- package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
- package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
- package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
- package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
- package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
- package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
- package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
- package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
- package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
- package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
- package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
- package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
- package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
- package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
- package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
- package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
- package/Server/Utils/DataSource/EgressGuard.ts +446 -0
- package/Server/Utils/DataSource/HttpFetch.ts +221 -0
- package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
- package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
- package/Server/Utils/DataSource/Types.ts +93 -0
- package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
- package/Server/Utils/InProcessMemo.ts +141 -0
- package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
- package/Server/Utils/Monitor/MonitorResource.ts +14 -0
- package/Server/Utils/Response.ts +12 -1
- package/Server/Utils/SSRFProtection.ts +237 -0
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
- package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
- package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
- package/Server/Utils/Telemetry/Telemetry.ts +112 -1
- package/Server/Utils/Telemetry.ts +104 -3
- package/Server/Utils/VendorAssets.ts +165 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
- package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
- package/Server/Views/Partials/Head.ejs +21 -7
- package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
- package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
- package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
- package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
- package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
- package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
- package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
- package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
- package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
- package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
- package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
- package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
- package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
- package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
- package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
- package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
- package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
- package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
- package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
- package/Tests/Server/Services/AIInsightService.test.ts +266 -11
- package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
- package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
- package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
- package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
- package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
- package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
- package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
- package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
- package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
- package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
- package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
- package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
- package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
- package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
- package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
- package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
- package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
- package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
- package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
- package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
- package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
- package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
- package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
- package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
- package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
- package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
- package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
- package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
- package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
- package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
- package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
- package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
- package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
- package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
- package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
- package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
- package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
- package/Tests/Server/Utils/Telemetry.test.ts +87 -0
- package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
- package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
- package/Tests/Server/Views/OfflineRender.test.ts +297 -0
- package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
- package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
- package/Tests/Types/Password.test.ts +363 -0
- package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
- package/Tests/UI/Components/Modal.test.tsx +281 -1
- package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/Utils/Analytics.test.ts +23 -0
- package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
- package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
- package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
- package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
- package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
- package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
- package/Types/AI/AIInsightEvidence.ts +6 -0
- package/Types/Analytics/RevenueEvent.ts +31 -0
- package/Types/Dashboard/DashboardComponentType.ts +31 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
- package/Types/DataSource/DataSourceLimits.ts +62 -0
- package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
- package/Types/DataSource/DataSourceTableResult.ts +38 -0
- package/Types/DataSource/DataSourceType.ts +213 -0
- package/Types/Date.ts +43 -3
- package/Types/Password.ts +64 -0
- package/Types/Permission.ts +46 -0
- package/Types/UserAuthenticationStatus.ts +34 -0
- package/UI/Components/Button/Button.tsx +1 -1
- package/UI/Components/ErrorBoundary.tsx +459 -108
- package/UI/Components/Icon/Icon.tsx +10 -9
- package/UI/Components/Modal/ConfirmModal.tsx +6 -1
- package/UI/Components/Modal/Modal.tsx +267 -35
- package/UI/Components/Modal/ModalFooter.tsx +6 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
- package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
- package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
- package/UI/Components/StatusPage/ResourceList.tsx +570 -0
- package/UI/Styles/Theme.css +18 -0
- package/UI/Utils/API/RequestOptions.ts +7 -0
- package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
- package/UI/Utils/TestDataSource.ts +61 -0
- package/UI/esbuild-config.js +45 -0
- package/Utils/Analytics.ts +15 -0
- package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
- package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
- package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
- package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
- package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
- package/Utils/Dashboard/Components/Index.ts +28 -0
- package/Utils/DataSource/DataSourceQueryText.ts +94 -0
- package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
- package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
- package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
- package/Utils/StatusPage/ResourceExplorer.ts +853 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
- package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +2 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
- package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +34 -4
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +119 -433
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/DataSourceAPI.js +173 -0
- package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +11 -1
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +94 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +27 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIInsightService.js +110 -10
- package/build/dist/Server/Services/AIInsightService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +34 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +16 -2
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +28 -35
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DataSourceService.js +159 -0
- package/build/dist/Server/Services/DataSourceService.js.map +1 -0
- package/build/dist/Server/Services/HostService.js +74 -0
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +35 -24
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusService.js +129 -0
- package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +7 -15
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +241 -10
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Types.js +2 -0
- package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
- package/build/dist/Server/Utils/InProcessMemo.js +113 -0
- package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +9 -1
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +192 -0
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +93 -6
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +121 -0
- package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
- package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceType.js +183 -0
- package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
- package/build/dist/Types/Date.js +38 -3
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Password.js +56 -0
- package/build/dist/Types/Password.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/UserAuthenticationStatus.js +2 -0
- package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
- package/build/dist/UI/Components/ErrorBoundary.js +388 -72
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +10 -4
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +178 -19
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/TestDataSource.js +39 -0
- package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
- package/build/dist/Utils/Analytics.js +4 -0
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
- package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
- package/jest.config.json +1 -0
- package/package.json +5 -1
- package/tsconfig.json +12 -10
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* ClickHouse client keep-alive.
|
|
5
|
+
*
|
|
6
|
+
* @clickhouse/client enables HTTP keep-alive by default but destroys idle
|
|
7
|
+
* pooled sockets after only 2500ms (keep_alive.idle_socket_ttl), while the
|
|
8
|
+
* telemetry fan-in writer flushes on a TELEMETRY_FANIN_MAX_WAIT_MS window
|
|
9
|
+
* that defaults to 5000ms. Under sub-saturation ingest load every flush
|
|
10
|
+
* therefore found its pooled socket already destroyed and paid TCP (+TLS)
|
|
11
|
+
* connection setup again — on every single flush. ClickhouseConfig.ts now
|
|
12
|
+
* pins keep_alive explicitly with an env-configurable TTL
|
|
13
|
+
* (CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS, default 8000ms) sandwiched
|
|
14
|
+
* between two constraints:
|
|
15
|
+
*
|
|
16
|
+
* - it must sit ABOVE the fan-in flush window, or sockets keep dying
|
|
17
|
+
* between flushes and the setting is pointless;
|
|
18
|
+
* - it must sit BELOW the ClickHouse server's keep_alive_timeout (10s in
|
|
19
|
+
* the bundled Clickhouse/config.xml, also the server default since
|
|
20
|
+
* 23.11), or the client reuses sockets the server already closed and
|
|
21
|
+
* requests fail with ECONNRESET.
|
|
22
|
+
*
|
|
23
|
+
* This suite pins the default, the env override, the invalid-value
|
|
24
|
+
* fallback, that EVERY pool derived from the shared options object carries
|
|
25
|
+
* the setting (query, ingest, migration, test — and the two clients
|
|
26
|
+
* ClickhouseDatabase.connect() actually constructs), and both ordering
|
|
27
|
+
* constraints above.
|
|
28
|
+
*
|
|
29
|
+
* The config module reads env at import time, so each case re-imports it
|
|
30
|
+
* in isolation (same pattern as PostgresLockTimeoutOptions.test.ts).
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import ClickhouseDatabase, {
|
|
34
|
+
ClickhouseClient,
|
|
35
|
+
} from "../../../Server/Infrastructure/ClickhouseDatabase";
|
|
36
|
+
import {
|
|
37
|
+
ClickHouseClientConfigOptions,
|
|
38
|
+
dataSourceOptions,
|
|
39
|
+
ingestDataSourceOptions,
|
|
40
|
+
} from "../../../Server/Infrastructure/ClickhouseConfig";
|
|
41
|
+
import { readFanInWriterOptionsFromEnv } from "../../../Server/Utils/Telemetry/TelemetryFanInWriter";
|
|
42
|
+
import { createClient } from "@clickhouse/client";
|
|
43
|
+
import fs from "fs";
|
|
44
|
+
import path from "path";
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* Count and capture every client the ClickhouseDatabase connect() flow
|
|
48
|
+
* builds. The mock lives INSIDE the hoisted factory (a module-scope const
|
|
49
|
+
* would not be initialized yet when the hoisted static imports trigger the
|
|
50
|
+
* factory) and is retrieved below through the mocked module itself. Each
|
|
51
|
+
* fake client resolves the exact calls connect() makes: exec (CREATE
|
|
52
|
+
* DATABASE on the bootstrap client), close (bootstrap client teardown),
|
|
53
|
+
* ping (pool client health check).
|
|
54
|
+
*/
|
|
55
|
+
jest.mock("@clickhouse/client", () => {
|
|
56
|
+
return {
|
|
57
|
+
__esModule: true,
|
|
58
|
+
createClient: jest.fn(() => {
|
|
59
|
+
return {
|
|
60
|
+
exec: jest.fn(async () => {
|
|
61
|
+
return;
|
|
62
|
+
}),
|
|
63
|
+
close: jest.fn(async () => {
|
|
64
|
+
return;
|
|
65
|
+
}),
|
|
66
|
+
ping: jest.fn(async () => {
|
|
67
|
+
return { success: true };
|
|
68
|
+
}),
|
|
69
|
+
};
|
|
70
|
+
}),
|
|
71
|
+
ClickHouseError: class MockClickHouseError extends Error {},
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const mockCreateClient: jest.Mock = createClient as unknown as jest.Mock;
|
|
76
|
+
|
|
77
|
+
interface KeepAliveOptionsUnderTest {
|
|
78
|
+
enabled?: boolean;
|
|
79
|
+
idle_socket_ttl?: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface ClickhouseOptionsUnderTest {
|
|
83
|
+
keep_alive?: KeepAliveOptionsUnderTest;
|
|
84
|
+
request_timeout?: number;
|
|
85
|
+
max_open_connections?: number;
|
|
86
|
+
compression?: { request?: boolean; response?: boolean };
|
|
87
|
+
database?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface LoadedClickhouseConfig {
|
|
91
|
+
dataSourceOptions: ClickhouseOptionsUnderTest;
|
|
92
|
+
ingestDataSourceOptions: ClickhouseOptionsUnderTest;
|
|
93
|
+
migrationDataSourceOptions: ClickhouseOptionsUnderTest;
|
|
94
|
+
testDataSourceOptions: ClickhouseOptionsUnderTest;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
* Run a callback with process.env temporarily overridden (undefined
|
|
99
|
+
* deletes the key), restoring the previous values afterwards so cases
|
|
100
|
+
* cannot leak env into each other or into unrelated suites.
|
|
101
|
+
*/
|
|
102
|
+
function withEnv<T>(
|
|
103
|
+
env: Record<string, string | undefined>,
|
|
104
|
+
callback: () => T,
|
|
105
|
+
): T {
|
|
106
|
+
const previous: Record<string, string | undefined> = {};
|
|
107
|
+
|
|
108
|
+
for (const [key, value] of Object.entries(env)) {
|
|
109
|
+
previous[key] = process.env[key];
|
|
110
|
+
if (value === undefined) {
|
|
111
|
+
delete process.env[key];
|
|
112
|
+
} else {
|
|
113
|
+
process.env[key] = value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
return callback();
|
|
119
|
+
} finally {
|
|
120
|
+
for (const [key, value] of Object.entries(previous)) {
|
|
121
|
+
if (value === undefined) {
|
|
122
|
+
delete process.env[key];
|
|
123
|
+
} else {
|
|
124
|
+
process.env[key] = value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function loadConfig(
|
|
131
|
+
env: Record<string, string | undefined>,
|
|
132
|
+
): LoadedClickhouseConfig {
|
|
133
|
+
let loaded: LoadedClickhouseConfig | undefined = undefined;
|
|
134
|
+
|
|
135
|
+
jest.isolateModules(() => {
|
|
136
|
+
withEnv(env, () => {
|
|
137
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
139
|
+
loaded = require("../../../Server/Infrastructure/ClickhouseConfig");
|
|
140
|
+
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return loaded!;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
describe("ClickHouse client keep-alive options", () => {
|
|
148
|
+
describe("default", () => {
|
|
149
|
+
test("keep-alive is enabled with an 8000ms idle-socket TTL when the env var is unset", () => {
|
|
150
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
151
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: undefined,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
expect(config.dataSourceOptions.keep_alive).toEqual({
|
|
155
|
+
enabled: true,
|
|
156
|
+
idle_socket_ttl: 8000,
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
/*
|
|
161
|
+
* The whole point of the change: the client's own 2500ms default is
|
|
162
|
+
* what destroyed every socket between 5000ms fan-in flushes. If the
|
|
163
|
+
* key were ever dropped from the options object again, the client
|
|
164
|
+
* would silently regress to 2500ms — so pin its presence explicitly.
|
|
165
|
+
*/
|
|
166
|
+
test("the client default of 2500ms is overridden, not inherited", () => {
|
|
167
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
168
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: undefined,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(config.dataSourceOptions.keep_alive).toBeDefined();
|
|
172
|
+
expect(config.dataSourceOptions.keep_alive!.idle_socket_ttl).not.toBe(
|
|
173
|
+
2500,
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe("env override", () => {
|
|
179
|
+
test("a positive integer value is applied", () => {
|
|
180
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
181
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: "12000",
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(config.dataSourceOptions.keep_alive).toEqual({
|
|
185
|
+
enabled: true,
|
|
186
|
+
idle_socket_ttl: 12000,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test("surrounding whitespace is tolerated", () => {
|
|
191
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
192
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: " 9000 ",
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
expect(config.dataSourceOptions.keep_alive!.idle_socket_ttl).toBe(9000);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
/*
|
|
199
|
+
* parseInt semantics: a decimal string yields its leading integer
|
|
200
|
+
* part. Milliseconds are documented as integers; pin the behavior so
|
|
201
|
+
* a future parser change is a conscious one.
|
|
202
|
+
*/
|
|
203
|
+
test("a decimal value is truncated to its integer part", () => {
|
|
204
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
205
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: "12000.9",
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
expect(config.dataSourceOptions.keep_alive!.idle_socket_ttl).toBe(12000);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe("invalid values fall back to the default", () => {
|
|
213
|
+
test.each([
|
|
214
|
+
["non-numeric", "not-a-number"],
|
|
215
|
+
["empty string", ""],
|
|
216
|
+
["whitespace only", " "],
|
|
217
|
+
/*
|
|
218
|
+
* Zero is rejected deliberately: the client treats 0 as "disable
|
|
219
|
+
* idle-socket reaping entirely", which reintroduces the
|
|
220
|
+
* server-closes-first ECONNRESET failure mode the TTL exists to
|
|
221
|
+
* prevent.
|
|
222
|
+
*/
|
|
223
|
+
["zero", "0"],
|
|
224
|
+
["negative", "-500"],
|
|
225
|
+
["NaN literal", "NaN"],
|
|
226
|
+
])("%s (%p) falls back to 8000ms", (_label: string, rawValue: string) => {
|
|
227
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
228
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: rawValue,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
expect(config.dataSourceOptions.keep_alive).toEqual({
|
|
232
|
+
enabled: true,
|
|
233
|
+
idle_socket_ttl: 8000,
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
/*
|
|
239
|
+
* The setting lives on the shared base `options` object, so every pool
|
|
240
|
+
* derived from it must carry it — a keep-alive that only covered the
|
|
241
|
+
* query pool would leave the INGEST pool (the hot path this change is
|
|
242
|
+
* for) still paying per-flush connection setup.
|
|
243
|
+
*/
|
|
244
|
+
describe("every pool derived from the shared options carries the setting", () => {
|
|
245
|
+
test("default reaches query, ingest, migration and test pools", () => {
|
|
246
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
247
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: undefined,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const expected: KeepAliveOptionsUnderTest = {
|
|
251
|
+
enabled: true,
|
|
252
|
+
idle_socket_ttl: 8000,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
expect(config.dataSourceOptions.keep_alive).toEqual(expected);
|
|
256
|
+
expect(config.ingestDataSourceOptions.keep_alive).toEqual(expected);
|
|
257
|
+
expect(config.migrationDataSourceOptions.keep_alive).toEqual(expected);
|
|
258
|
+
expect(config.testDataSourceOptions.keep_alive).toEqual(expected);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test("an override reaches query, ingest, migration and test pools", () => {
|
|
262
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
263
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: "7000",
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
const expected: KeepAliveOptionsUnderTest = {
|
|
267
|
+
enabled: true,
|
|
268
|
+
idle_socket_ttl: 7000,
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
expect(config.dataSourceOptions.keep_alive).toEqual(expected);
|
|
272
|
+
expect(config.ingestDataSourceOptions.keep_alive).toEqual(expected);
|
|
273
|
+
expect(config.migrationDataSourceOptions.keep_alive).toEqual(expected);
|
|
274
|
+
expect(config.testDataSourceOptions.keep_alive).toEqual(expected);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
/*
|
|
279
|
+
* The default is only correct while it stays strictly between the fan-in
|
|
280
|
+
* flush window (below) and the ClickHouse server's keep_alive_timeout
|
|
281
|
+
* (above). Both neighbours live in other files, so pin the ordering
|
|
282
|
+
* against their real sources rather than restating magic numbers that
|
|
283
|
+
* could drift apart silently.
|
|
284
|
+
*/
|
|
285
|
+
describe("ordering constraints on the default", () => {
|
|
286
|
+
test("the TTL outlives the fan-in writer's default flush window, so sockets survive between flushes", () => {
|
|
287
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
288
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: undefined,
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const fanInMaxWaitMs: number = withEnv(
|
|
292
|
+
{ TELEMETRY_FANIN_MAX_WAIT_MS: undefined },
|
|
293
|
+
() => {
|
|
294
|
+
return readFanInWriterOptionsFromEnv().maxWaitMs;
|
|
295
|
+
},
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
expect(
|
|
299
|
+
config.dataSourceOptions.keep_alive!.idle_socket_ttl!,
|
|
300
|
+
).toBeGreaterThan(fanInMaxWaitMs);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test("the TTL stays below the bundled ClickHouse server keep_alive_timeout, so the client always closes first", () => {
|
|
304
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
305
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: undefined,
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
/*
|
|
309
|
+
* Read the authoritative server value from the bundled server
|
|
310
|
+
* config (repo root /Clickhouse/config.xml) instead of hardcoding
|
|
311
|
+
* 10s here: if an operator-facing change ever lowers the server
|
|
312
|
+
* timeout, this test fails and forces the client default to move
|
|
313
|
+
* with it.
|
|
314
|
+
*/
|
|
315
|
+
const serverConfigPath: string = path.join(
|
|
316
|
+
__dirname,
|
|
317
|
+
"../../../../Clickhouse/config.xml",
|
|
318
|
+
);
|
|
319
|
+
const serverConfigXml: string = fs.readFileSync(
|
|
320
|
+
serverConfigPath,
|
|
321
|
+
"utf-8",
|
|
322
|
+
);
|
|
323
|
+
const keepAliveTimeoutMatch: RegExpMatchArray | null =
|
|
324
|
+
serverConfigXml.match(
|
|
325
|
+
/<keep_alive_timeout>(\d+)<\/keep_alive_timeout>/,
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
expect(keepAliveTimeoutMatch).not.toBeNull();
|
|
329
|
+
|
|
330
|
+
const serverKeepAliveTimeoutInMs: number =
|
|
331
|
+
parseInt(keepAliveTimeoutMatch![1]!, 10) * 1000;
|
|
332
|
+
|
|
333
|
+
expect(
|
|
334
|
+
config.dataSourceOptions.keep_alive!.idle_socket_ttl!,
|
|
335
|
+
).toBeLessThan(serverKeepAliveTimeoutInMs);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
/*
|
|
340
|
+
* The efficiency change must not disturb any of the other tuned client
|
|
341
|
+
* options — those carry their own hard-won constraints (nginx timeout
|
|
342
|
+
* headroom, pool sizing, compression preconditions).
|
|
343
|
+
*/
|
|
344
|
+
describe("pre-existing options are unchanged", () => {
|
|
345
|
+
test("request_timeout, compression and pool sizing keep their values", () => {
|
|
346
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
347
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: "12000",
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
expect(config.dataSourceOptions.request_timeout).toBe(58_000);
|
|
351
|
+
expect(config.ingestDataSourceOptions.request_timeout).toBe(58_000);
|
|
352
|
+
expect(config.dataSourceOptions.compression).toEqual({
|
|
353
|
+
request: true,
|
|
354
|
+
response: true,
|
|
355
|
+
});
|
|
356
|
+
/*
|
|
357
|
+
* The migration pool's idle ceiling has a 30-minute floor (see
|
|
358
|
+
* migrationRequestTimeoutInMs in ClickhouseConfig.ts).
|
|
359
|
+
*/
|
|
360
|
+
expect(
|
|
361
|
+
config.migrationDataSourceOptions.request_timeout!,
|
|
362
|
+
).toBeGreaterThanOrEqual(30 * 60 * 1000);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test("the ingest pool still sizes its connections independently while carrying keep-alive", () => {
|
|
366
|
+
const config: LoadedClickhouseConfig = loadConfig({
|
|
367
|
+
CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: undefined,
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
/*
|
|
371
|
+
* EnvironmentConfig is imported (not re-required) by the isolated
|
|
372
|
+
* ClickhouseConfig load, so the connection counts reflect whatever
|
|
373
|
+
* the ambient test env resolved at first import. Assert the
|
|
374
|
+
* RELATIONSHIP — ingest keep-alive present alongside its own
|
|
375
|
+
* max_open_connections — not an absolute count.
|
|
376
|
+
*/
|
|
377
|
+
expect(config.ingestDataSourceOptions.max_open_connections).toBeDefined();
|
|
378
|
+
expect(config.ingestDataSourceOptions.keep_alive).toEqual(
|
|
379
|
+
config.dataSourceOptions.keep_alive,
|
|
380
|
+
);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
/*
|
|
385
|
+
* Options only matter if they reach the clients ClickhouseDatabase
|
|
386
|
+
* actually constructs. connect() builds TWO clients — a short-lived
|
|
387
|
+
* bootstrap client against the `default` database (CREATE DATABASE IF
|
|
388
|
+
* NOT EXISTS) and the long-lived pool client — and BOTH must carry
|
|
389
|
+
* keep_alive, so the counting mock captures every createClient call.
|
|
390
|
+
*/
|
|
391
|
+
describe("the setting reaches the clients built from this config", () => {
|
|
392
|
+
beforeEach(() => {
|
|
393
|
+
mockCreateClient.mockClear();
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
test("connect() passes keep-alive to both the bootstrap client and the pool client", async () => {
|
|
397
|
+
const database: ClickhouseDatabase = new ClickhouseDatabase();
|
|
398
|
+
|
|
399
|
+
const client: ClickhouseClient =
|
|
400
|
+
await database.connect(dataSourceOptions);
|
|
401
|
+
|
|
402
|
+
expect(client).toBeDefined();
|
|
403
|
+
expect(mockCreateClient).toHaveBeenCalledTimes(2);
|
|
404
|
+
|
|
405
|
+
const bootstrapOptions: ClickhouseOptionsUnderTest = mockCreateClient.mock
|
|
406
|
+
.calls[0]![0] as ClickhouseOptionsUnderTest;
|
|
407
|
+
const poolOptions: ClickhouseOptionsUnderTest = mockCreateClient.mock
|
|
408
|
+
.calls[1]![0] as ClickhouseOptionsUnderTest;
|
|
409
|
+
|
|
410
|
+
expect(bootstrapOptions.database).toBe("default");
|
|
411
|
+
expect(bootstrapOptions.keep_alive).toEqual(dataSourceOptions.keep_alive);
|
|
412
|
+
expect(poolOptions).toBe(dataSourceOptions);
|
|
413
|
+
expect(poolOptions.keep_alive).toEqual({
|
|
414
|
+
enabled: true,
|
|
415
|
+
idle_socket_ttl: expect.any(Number),
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
await database.disconnect();
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
test("the ingest pool client carries keep-alive too", async () => {
|
|
422
|
+
const database: ClickhouseDatabase = new ClickhouseDatabase(
|
|
423
|
+
ingestDataSourceOptions,
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
await database.connect(
|
|
427
|
+
database.getDatasourceOptions() as ClickHouseClientConfigOptions,
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
expect(mockCreateClient).toHaveBeenCalledTimes(2);
|
|
431
|
+
|
|
432
|
+
const poolOptions: ClickhouseOptionsUnderTest = mockCreateClient.mock
|
|
433
|
+
.calls[1]![0] as ClickhouseOptionsUnderTest;
|
|
434
|
+
|
|
435
|
+
expect(poolOptions).toBe(ingestDataSourceOptions);
|
|
436
|
+
expect(poolOptions.keep_alive).toEqual(dataSourceOptions.keep_alive);
|
|
437
|
+
|
|
438
|
+
await database.disconnect();
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { describe, expect, test, beforeEach } from "@jest/globals";
|
|
2
|
+
import TelemetryIngest from "../../../Server/Middleware/TelemetryIngest";
|
|
3
|
+
import TelemetryIngestionKeyService from "../../../Server/Services/TelemetryIngestionKeyService";
|
|
4
|
+
import Response from "../../../Server/Utils/Response";
|
|
5
|
+
import logger from "../../../Server/Utils/Logger";
|
|
6
|
+
import {
|
|
7
|
+
ExpressRequest,
|
|
8
|
+
ExpressResponse,
|
|
9
|
+
NextFunction,
|
|
10
|
+
} from "../../../Server/Utils/Express";
|
|
11
|
+
import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* The token resolver is mocked so the invalid-token branch can be forced
|
|
15
|
+
* without a database; the middleware under test must never see a real
|
|
16
|
+
* Postgres/Redis dependency.
|
|
17
|
+
*/
|
|
18
|
+
jest.mock("../../../Server/Services/TelemetryIngestionKeyService", () => {
|
|
19
|
+
return {
|
|
20
|
+
__esModule: true,
|
|
21
|
+
default: {
|
|
22
|
+
getProjectIdFromSecretKey: jest.fn(),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
jest.mock("../../../Server/Utils/Response", () => {
|
|
28
|
+
return {
|
|
29
|
+
__esModule: true,
|
|
30
|
+
default: {
|
|
31
|
+
sendErrorResponse: jest.fn(),
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
type MockFn = jest.Mock;
|
|
37
|
+
|
|
38
|
+
/*
|
|
39
|
+
* Regression pin for the secret-leak fix in isAuthorizedServiceMiddleware:
|
|
40
|
+
* an invalid ingestion token must never appear in any log output. The gRPC
|
|
41
|
+
* half of the same fix is pinned by GrpcServerAuth.test.ts in App; this
|
|
42
|
+
* covers the HTTP middleware half, which fronts the higher-traffic
|
|
43
|
+
* OTLP/syslog/fluent ingest routes and whose logger.error lines also land
|
|
44
|
+
* in the in-process recentLogs ring buffer surfaced on the admin health
|
|
45
|
+
* pages.
|
|
46
|
+
*/
|
|
47
|
+
describe("TelemetryIngest.isAuthorizedServiceMiddleware token logging", () => {
|
|
48
|
+
/*
|
|
49
|
+
* Deliberately shaped like a real (mistyped) ingestion key so a substring
|
|
50
|
+
* check is meaningful.
|
|
51
|
+
*/
|
|
52
|
+
const SENTINEL_TOKEN: string = "sentinel-secret-ingestion-key-12345";
|
|
53
|
+
|
|
54
|
+
let loggedErrorArgs: Array<Array<unknown>>;
|
|
55
|
+
let errorSpy: { mockRestore: () => void };
|
|
56
|
+
|
|
57
|
+
const buildRequest: (headers: Record<string, string>) => ExpressRequest = (
|
|
58
|
+
headers: Record<string, string>,
|
|
59
|
+
): ExpressRequest => {
|
|
60
|
+
return {
|
|
61
|
+
headers,
|
|
62
|
+
id: "test-request-id",
|
|
63
|
+
} as unknown as ExpressRequest;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const runMiddleware: (req: ExpressRequest) => Promise<void> = async (
|
|
67
|
+
req: ExpressRequest,
|
|
68
|
+
): Promise<void> => {
|
|
69
|
+
const res: ExpressResponse = {} as ExpressResponse;
|
|
70
|
+
const next: NextFunction = jest.fn() as unknown as NextFunction;
|
|
71
|
+
await TelemetryIngest.isAuthorizedServiceMiddleware(req, res, next);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
beforeEach(() => {
|
|
75
|
+
jest.clearAllMocks();
|
|
76
|
+
loggedErrorArgs = [];
|
|
77
|
+
const spy: unknown = jest
|
|
78
|
+
.spyOn(logger, "error")
|
|
79
|
+
.mockImplementation((...args: Array<unknown>) => {
|
|
80
|
+
loggedErrorArgs.push(args);
|
|
81
|
+
return undefined as never;
|
|
82
|
+
});
|
|
83
|
+
errorSpy = spy as { mockRestore: () => void };
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
afterEach(() => {
|
|
87
|
+
errorSpy.mockRestore();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("invalid token: responds 401 and never logs the token value", async () => {
|
|
91
|
+
(
|
|
92
|
+
TelemetryIngestionKeyService.getProjectIdFromSecretKey as MockFn
|
|
93
|
+
).mockResolvedValue(null as never);
|
|
94
|
+
|
|
95
|
+
await runMiddleware(buildRequest({ "x-oneuptime-token": SENTINEL_TOKEN }));
|
|
96
|
+
|
|
97
|
+
// The invalid-token branch must still log — just without the secret.
|
|
98
|
+
expect(loggedErrorArgs.length).toBeGreaterThan(0);
|
|
99
|
+
for (const args of loggedErrorArgs) {
|
|
100
|
+
expect(JSON.stringify(args)).not.toContain(SENTINEL_TOKEN);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const sendErrorResponse: MockFn = Response.sendErrorResponse as MockFn;
|
|
104
|
+
expect(sendErrorResponse).toHaveBeenCalledTimes(1);
|
|
105
|
+
const errorArg: unknown = sendErrorResponse.mock.calls[0]?.[2];
|
|
106
|
+
expect(errorArg).toBeInstanceOf(NotAuthenticatedException);
|
|
107
|
+
// The response body must not echo the token either.
|
|
108
|
+
expect(JSON.stringify((errorArg as Error).message)).not.toContain(
|
|
109
|
+
SENTINEL_TOKEN,
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("invalid token via the alternate header names is not logged either", async () => {
|
|
114
|
+
(
|
|
115
|
+
TelemetryIngestionKeyService.getProjectIdFromSecretKey as MockFn
|
|
116
|
+
).mockResolvedValue(null as never);
|
|
117
|
+
|
|
118
|
+
for (const headerName of [
|
|
119
|
+
"x-oneuptime-service-token",
|
|
120
|
+
"x-oneuptime-ingestion-key",
|
|
121
|
+
]) {
|
|
122
|
+
loggedErrorArgs = [];
|
|
123
|
+
await runMiddleware(buildRequest({ [headerName]: SENTINEL_TOKEN }));
|
|
124
|
+
|
|
125
|
+
expect(loggedErrorArgs.length).toBeGreaterThan(0);
|
|
126
|
+
for (const args of loggedErrorArgs) {
|
|
127
|
+
expect(JSON.stringify(args)).not.toContain(SENTINEL_TOKEN);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("missing token: responds 401 without consulting the resolver", async () => {
|
|
133
|
+
await runMiddleware(buildRequest({}));
|
|
134
|
+
|
|
135
|
+
expect(
|
|
136
|
+
TelemetryIngestionKeyService.getProjectIdFromSecretKey as MockFn,
|
|
137
|
+
).not.toHaveBeenCalled();
|
|
138
|
+
expect(Response.sendErrorResponse as MockFn).toHaveBeenCalledTimes(1);
|
|
139
|
+
});
|
|
140
|
+
});
|