@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,268 @@
|
|
|
1
|
+
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import CommonAPI from "./CommonAPI";
|
|
3
|
+
import DataSourceService, {
|
|
4
|
+
Service as DataSourceServiceType,
|
|
5
|
+
} from "../Services/DataSourceService";
|
|
6
|
+
import {
|
|
7
|
+
ExpressRequest,
|
|
8
|
+
ExpressResponse,
|
|
9
|
+
NextFunction,
|
|
10
|
+
} from "../Utils/Express";
|
|
11
|
+
import Response from "../Utils/Response";
|
|
12
|
+
import BaseAPI from "./BaseAPI";
|
|
13
|
+
import DataSource from "../../Models/DatabaseModels/DataSource";
|
|
14
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
15
|
+
import Exception from "../../Types/Exception/Exception";
|
|
16
|
+
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
17
|
+
import { JSONObject } from "../../Types/JSON";
|
|
18
|
+
import ObjectID from "../../Types/ObjectID";
|
|
19
|
+
import AggregatedResult from "../../Types/BaseDatabase/AggregatedResult";
|
|
20
|
+
import DataSourceTableResult from "../../Types/DataSource/DataSourceTableResult";
|
|
21
|
+
import { DataSourceResultKind } from "../../Types/DataSource/DataSourceQueryConfig";
|
|
22
|
+
import {
|
|
23
|
+
DataSourceConnectionSettings,
|
|
24
|
+
DataSourceConnector,
|
|
25
|
+
} from "../Utils/DataSource/Types";
|
|
26
|
+
import ConnectorRegistry from "../Utils/DataSource/ConnectorRegistry";
|
|
27
|
+
import logger from "../Utils/Logger";
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* Upper bound on stored/ad-hoc query text. Real PromQL/SQL/DSL queries are
|
|
31
|
+
* a few KB; anything beyond this is abuse or a mistake.
|
|
32
|
+
*/
|
|
33
|
+
const MAX_QUERY_LENGTH: number = 100_000;
|
|
34
|
+
|
|
35
|
+
export default class DataSourceAPI extends BaseAPI<
|
|
36
|
+
DataSource,
|
|
37
|
+
DataSourceServiceType
|
|
38
|
+
> {
|
|
39
|
+
public constructor() {
|
|
40
|
+
super(DataSource, DataSourceService);
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* Test a data source's connectivity + credentials. Authenticated
|
|
44
|
+
* users only; access is checked by reading the record with the
|
|
45
|
+
* caller's own permissions before any root read of credentials.
|
|
46
|
+
*/
|
|
47
|
+
this.router.post(
|
|
48
|
+
`${new this.entityType().getCrudApiPath()?.toString()}/test`,
|
|
49
|
+
UserMiddleware.getUserMiddleware,
|
|
50
|
+
UserMiddleware.requireUserAuthentication,
|
|
51
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
52
|
+
try {
|
|
53
|
+
const body: JSONObject = req.body;
|
|
54
|
+
|
|
55
|
+
const dataSource: DataSource = await this.getAccessibleDataSource({
|
|
56
|
+
req,
|
|
57
|
+
dataSourceId: body["dataSourceId"] as string,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const settings: DataSourceConnectionSettings =
|
|
61
|
+
await this.getConnectionSettings(dataSource);
|
|
62
|
+
|
|
63
|
+
const connector: DataSourceConnector = ConnectorRegistry.getConnector(
|
|
64
|
+
settings.dataSourceType,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
await connector.testConnection(settings);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
logger.error(err);
|
|
71
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
72
|
+
ok: false,
|
|
73
|
+
message: this.toFriendlyErrorMessage(err),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
78
|
+
ok: true,
|
|
79
|
+
message: "Connection successful.",
|
|
80
|
+
});
|
|
81
|
+
} catch (err) {
|
|
82
|
+
next(err);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* Execute a query against a data source and return normalized time
|
|
89
|
+
* series (for chart/value/gauge widgets) or rows (for the table
|
|
90
|
+
* widget).
|
|
91
|
+
*
|
|
92
|
+
* SECURITY: authenticated project users only — this route must NEVER
|
|
93
|
+
* be reachable from the anonymous public-dashboard surface, because
|
|
94
|
+
* it executes caller-supplied query text. Public dashboards render a
|
|
95
|
+
* placeholder for data-source widgets instead.
|
|
96
|
+
*/
|
|
97
|
+
this.router.post(
|
|
98
|
+
`${new this.entityType().getCrudApiPath()?.toString()}/query`,
|
|
99
|
+
UserMiddleware.getUserMiddleware,
|
|
100
|
+
UserMiddleware.requireUserAuthentication,
|
|
101
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
102
|
+
try {
|
|
103
|
+
const body: JSONObject = req.body;
|
|
104
|
+
|
|
105
|
+
const query: string = (body["query"] as string) || "";
|
|
106
|
+
if (!query || query.trim().length === 0) {
|
|
107
|
+
return Response.sendErrorResponse(
|
|
108
|
+
req,
|
|
109
|
+
res,
|
|
110
|
+
new BadDataException("query is required"),
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
if (query.length > MAX_QUERY_LENGTH) {
|
|
114
|
+
return Response.sendErrorResponse(
|
|
115
|
+
req,
|
|
116
|
+
res,
|
|
117
|
+
new BadDataException("query is too long"),
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const resultKind: DataSourceResultKind =
|
|
122
|
+
body["resultKind"] === DataSourceResultKind.Table
|
|
123
|
+
? DataSourceResultKind.Table
|
|
124
|
+
: DataSourceResultKind.TimeSeries;
|
|
125
|
+
|
|
126
|
+
const startDate: Date = new Date(body["startDate"] as string);
|
|
127
|
+
const endDate: Date = new Date(body["endDate"] as string);
|
|
128
|
+
if (
|
|
129
|
+
isNaN(startDate.getTime()) ||
|
|
130
|
+
isNaN(endDate.getTime()) ||
|
|
131
|
+
startDate.getTime() >= endDate.getTime()
|
|
132
|
+
) {
|
|
133
|
+
return Response.sendErrorResponse(
|
|
134
|
+
req,
|
|
135
|
+
res,
|
|
136
|
+
new BadDataException(
|
|
137
|
+
"A valid startDate and endDate are required (startDate must be before endDate).",
|
|
138
|
+
),
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let stepInSeconds: number | undefined = undefined;
|
|
143
|
+
if (body["stepInSeconds"] !== undefined) {
|
|
144
|
+
const parsedStep: number = Number(body["stepInSeconds"]);
|
|
145
|
+
if (Number.isFinite(parsedStep) && parsedStep > 0) {
|
|
146
|
+
// Floor, but never to 0 — Loki/Prometheus reject step=0.
|
|
147
|
+
stepInSeconds = Math.max(1, Math.floor(parsedStep));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const dataSource: DataSource = await this.getAccessibleDataSource({
|
|
152
|
+
req,
|
|
153
|
+
dataSourceId: body["dataSourceId"] as string,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const settings: DataSourceConnectionSettings =
|
|
157
|
+
await this.getConnectionSettings(dataSource);
|
|
158
|
+
|
|
159
|
+
const connector: DataSourceConnector = ConnectorRegistry.getConnector(
|
|
160
|
+
settings.dataSourceType,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
if (resultKind === DataSourceResultKind.Table) {
|
|
165
|
+
const tableResult: DataSourceTableResult =
|
|
166
|
+
await connector.queryTable(settings, query, {
|
|
167
|
+
startDate,
|
|
168
|
+
endDate,
|
|
169
|
+
stepInSeconds,
|
|
170
|
+
});
|
|
171
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
172
|
+
resultKind: DataSourceResultKind.Table,
|
|
173
|
+
result: tableResult as unknown as JSONObject,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const timeSeriesResult: AggregatedResult =
|
|
178
|
+
await connector.queryTimeSeries(settings, query, {
|
|
179
|
+
startDate,
|
|
180
|
+
endDate,
|
|
181
|
+
stepInSeconds,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
185
|
+
resultKind: DataSourceResultKind.TimeSeries,
|
|
186
|
+
result: timeSeriesResult as unknown as JSONObject,
|
|
187
|
+
});
|
|
188
|
+
} catch (err) {
|
|
189
|
+
logger.error(err);
|
|
190
|
+
return Response.sendErrorResponse(
|
|
191
|
+
req,
|
|
192
|
+
res,
|
|
193
|
+
new BadDataException(
|
|
194
|
+
`Data source query failed: ${this.toFriendlyErrorMessage(err)}`,
|
|
195
|
+
),
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
} catch (err) {
|
|
199
|
+
next(err);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/*
|
|
206
|
+
* Two-phase access pattern (same as LlmProviderAPI /test): first read
|
|
207
|
+
* the record with the CALLER'S permissions — wrong project or missing
|
|
208
|
+
* ReadDataSource yields null — and only then may callers proceed to a
|
|
209
|
+
* root read of credentials.
|
|
210
|
+
*/
|
|
211
|
+
private async getAccessibleDataSource(data: {
|
|
212
|
+
req: ExpressRequest;
|
|
213
|
+
dataSourceId: string;
|
|
214
|
+
}): Promise<DataSource> {
|
|
215
|
+
if (!data.dataSourceId) {
|
|
216
|
+
throw new BadDataException("dataSourceId is required");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!ObjectID.isValidUUID(data.dataSourceId)) {
|
|
220
|
+
throw new BadDataException(
|
|
221
|
+
"Data source not found, or you do not have access to it.",
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const props: DatabaseCommonInteractionProps =
|
|
226
|
+
await CommonAPI.getDatabaseCommonInteractionProps(data.req);
|
|
227
|
+
|
|
228
|
+
const accessibleDataSource: DataSource | null =
|
|
229
|
+
await DataSourceService.findOneById({
|
|
230
|
+
id: new ObjectID(data.dataSourceId),
|
|
231
|
+
select: {
|
|
232
|
+
_id: true,
|
|
233
|
+
projectId: true,
|
|
234
|
+
dataSourceType: true,
|
|
235
|
+
},
|
|
236
|
+
props: props,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
if (!accessibleDataSource) {
|
|
240
|
+
throw new BadDataException(
|
|
241
|
+
"Data source not found, or you do not have access to it.",
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return accessibleDataSource;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private async getConnectionSettings(
|
|
249
|
+
dataSource: DataSource,
|
|
250
|
+
): Promise<DataSourceConnectionSettings> {
|
|
251
|
+
const settings: DataSourceConnectionSettings | null =
|
|
252
|
+
await DataSourceService.getConnectionSettingsById(dataSource.id!);
|
|
253
|
+
|
|
254
|
+
if (!settings) {
|
|
255
|
+
throw new BadDataException("Data source configuration is incomplete.");
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return settings;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private toFriendlyErrorMessage(err: unknown): string {
|
|
262
|
+
const message: string =
|
|
263
|
+
err instanceof Exception
|
|
264
|
+
? err.message
|
|
265
|
+
: "Could not reach the data source. Please verify the connection details.";
|
|
266
|
+
return message.substring(0, 1000);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
@@ -3853,9 +3853,19 @@ export default class StatusPageAPI extends BaseAPI<
|
|
|
3853
3853
|
`Updating existing subscriber with ID: ${subscriberId} for status page with ID: ${objectId}`,
|
|
3854
3854
|
getLogAttributesFromRequest(req as any),
|
|
3855
3855
|
);
|
|
3856
|
+
/*
|
|
3857
|
+
* Scope the lookup to the status page in the route. This endpoint only
|
|
3858
|
+
* checks read access on that status page, so without the statusPageId
|
|
3859
|
+
* clause anyone holding a subscriber UUID could pass any status page they
|
|
3860
|
+
* can read and edit a subscriber belonging to a different — possibly
|
|
3861
|
+
* private — status page. A subscriber on another page must be
|
|
3862
|
+
* indistinguishable from one that does not exist, so that the shared
|
|
3863
|
+
* "Subscriber not found" below cannot be used to probe for valid UUIDs.
|
|
3864
|
+
*/
|
|
3856
3865
|
statusPageSubscriber = await StatusPageSubscriberService.findOneBy({
|
|
3857
3866
|
query: {
|
|
3858
3867
|
_id: subscriberId.toString(),
|
|
3868
|
+
statusPageId: objectId,
|
|
3859
3869
|
},
|
|
3860
3870
|
props: {
|
|
3861
3871
|
isRoot: true,
|
|
@@ -3864,7 +3874,7 @@ export default class StatusPageAPI extends BaseAPI<
|
|
|
3864
3874
|
|
|
3865
3875
|
if (!statusPageSubscriber) {
|
|
3866
3876
|
logger.debug(
|
|
3867
|
-
`Subscriber not found with ID: ${subscriberId}`,
|
|
3877
|
+
`Subscriber not found with ID: ${subscriberId} on status page with ID: ${objectId}`,
|
|
3868
3878
|
getLogAttributesFromRequest(req as any),
|
|
3869
3879
|
);
|
|
3870
3880
|
throw new BadDataException("Subscriber not found");
|
package/Server/API/UserAPI.ts
CHANGED
|
@@ -12,8 +12,10 @@ import PositiveNumber from "../../Types/PositiveNumber";
|
|
|
12
12
|
import TeamMembersByProject, {
|
|
13
13
|
UserProjectMembership,
|
|
14
14
|
} from "../../Utils/TeamMembersByProject";
|
|
15
|
+
import Email from "../../Types/Email";
|
|
15
16
|
import MasterAdminAuthorization from "../Middleware/MasterAdminAuthorization";
|
|
16
17
|
import TeamMemberService from "../Services/TeamMemberService";
|
|
18
|
+
import UserAuthenticationStatus from "../../Types/UserAuthenticationStatus";
|
|
17
19
|
import UserService, {
|
|
18
20
|
Service as UserServiceType,
|
|
19
21
|
} from "../Services/UserService";
|
|
@@ -191,6 +193,123 @@ export default class UserAPI extends BaseAPI<User, UserServiceType> {
|
|
|
191
193
|
},
|
|
192
194
|
);
|
|
193
195
|
|
|
196
|
+
/*
|
|
197
|
+
* How one user can sign in, for Admin Dashboard > User > Authentication.
|
|
198
|
+
*
|
|
199
|
+
* A dedicated endpoint rather than extra columns on the CRUD read, because
|
|
200
|
+
* the interesting fact -- "does this account have a password at all?" --
|
|
201
|
+
* cannot be answered from the CRUD API without shipping the password
|
|
202
|
+
* column itself. A master admin bypasses column read permissions, so
|
|
203
|
+
* selecting `password` in the browser would put every user's scrypt digest
|
|
204
|
+
* in a page's network tab. The booleans below are derived server-side and
|
|
205
|
+
* nothing secret crosses the wire.
|
|
206
|
+
*/
|
|
207
|
+
this.router.get(
|
|
208
|
+
`${new this.entityType().getCrudApiPath()?.toString()}/:userId/authentication-status`,
|
|
209
|
+
MasterAdminAuthorization.isAuthorizedMasterAdminMiddleware,
|
|
210
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
211
|
+
try {
|
|
212
|
+
const userId: ObjectID = UserAPI.getUserIdFromParams(req);
|
|
213
|
+
|
|
214
|
+
const status: UserAuthenticationStatus =
|
|
215
|
+
await UserService.getAuthenticationStatus(userId);
|
|
216
|
+
|
|
217
|
+
/*
|
|
218
|
+
* Whether an account has a password is exactly the sort of answer a
|
|
219
|
+
* shared cache must not keep -- and it changes the moment either
|
|
220
|
+
* action below is used.
|
|
221
|
+
*/
|
|
222
|
+
Response.setNoCacheHeaders(res);
|
|
223
|
+
|
|
224
|
+
return Response.sendJsonObjectResponse(
|
|
225
|
+
req,
|
|
226
|
+
res,
|
|
227
|
+
status as unknown as JSONObject,
|
|
228
|
+
);
|
|
229
|
+
} catch (err) {
|
|
230
|
+
return next(err);
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
* Set a user's password on their behalf.
|
|
237
|
+
*
|
|
238
|
+
* Master-admin only, and deliberately its own route rather than a PUT to
|
|
239
|
+
* /user/:id with a password in it. That generic write would work -- a
|
|
240
|
+
* master admin bypasses the password column's `update: [CurrentUser]` ACL
|
|
241
|
+
* -- but nothing about the URL would say so, the password policy could not
|
|
242
|
+
* be enforced, and the payload would have to be a hand-serialized
|
|
243
|
+
* HashedString. Here the gate is a middleware anyone can grep for, and the
|
|
244
|
+
* body is a plain string.
|
|
245
|
+
*
|
|
246
|
+
* Session revocation and the "Password Changed." email happen in
|
|
247
|
+
* UserService's update hook, not here, so they cannot be forgotten by a
|
|
248
|
+
* caller and cannot fire twice.
|
|
249
|
+
*/
|
|
250
|
+
this.router.post(
|
|
251
|
+
`${new this.entityType().getCrudApiPath()?.toString()}/:userId/set-password`,
|
|
252
|
+
MasterAdminAuthorization.isAuthorizedMasterAdminMiddleware,
|
|
253
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
254
|
+
try {
|
|
255
|
+
const userId: ObjectID = UserAPI.getUserIdFromParams(req);
|
|
256
|
+
|
|
257
|
+
const password: unknown = req.body?.["password"];
|
|
258
|
+
|
|
259
|
+
/*
|
|
260
|
+
* Type-checked rather than cast. `as string` on a JSON body is a
|
|
261
|
+
* lie the moment somebody posts {"password": {...}} or a number, and
|
|
262
|
+
* the value flows into the hasher.
|
|
263
|
+
*/
|
|
264
|
+
if (typeof password !== "string") {
|
|
265
|
+
throw new BadDataException("Password is required");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
await UserService.setPassword({
|
|
269
|
+
userId: userId,
|
|
270
|
+
password: password,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
return Response.sendEmptySuccessResponse(req, res);
|
|
274
|
+
} catch (err) {
|
|
275
|
+
return next(err);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
/*
|
|
281
|
+
* Email the user a link that lets them choose their own password.
|
|
282
|
+
*
|
|
283
|
+
* The counterpart to setting one for them: it never puts the operator in
|
|
284
|
+
* possession of the user's credentials, which is the better default when
|
|
285
|
+
* the point is simply to get somebody back into a locked-out account. The
|
|
286
|
+
* link is the same one /forgot-password sends, redeemed by the same page.
|
|
287
|
+
*/
|
|
288
|
+
this.router.post(
|
|
289
|
+
`${new this.entityType().getCrudApiPath()?.toString()}/:userId/send-password-reset-link`,
|
|
290
|
+
MasterAdminAuthorization.isAuthorizedMasterAdminMiddleware,
|
|
291
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
292
|
+
try {
|
|
293
|
+
const userId: ObjectID = UserAPI.getUserIdFromParams(req);
|
|
294
|
+
|
|
295
|
+
const email: Email = await UserService.sendPasswordResetLink({
|
|
296
|
+
userId: userId,
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
/*
|
|
300
|
+
* Echoed back so the page can say where the link went. The caller is
|
|
301
|
+
* a master admin who can already read this user's email through the
|
|
302
|
+
* CRUD API, so this discloses nothing new.
|
|
303
|
+
*/
|
|
304
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
305
|
+
email: email.toString(),
|
|
306
|
+
});
|
|
307
|
+
} catch (err) {
|
|
308
|
+
return next(err);
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
);
|
|
312
|
+
|
|
194
313
|
this.router.get(
|
|
195
314
|
`${new this.entityType().getCrudApiPath()?.toString()}/profile-picture/:userId`,
|
|
196
315
|
async (req: ExpressRequest, res: ExpressResponse) => {
|
|
@@ -23,6 +23,52 @@ const hostProtocol: string = ClickHouseIsHostHttps ? "https" : "http";
|
|
|
23
23
|
const clickhouseHost: Hostname = ClickhouseHost || new Hostname("clickhouse");
|
|
24
24
|
const clickhousePort: string = (ClickhousePort || 8123).toString();
|
|
25
25
|
|
|
26
|
+
/*
|
|
27
|
+
* How long the client keeps an idle pooled HTTP socket alive before
|
|
28
|
+
* destroying it (keep_alive.idle_socket_ttl). @clickhouse/client enables
|
|
29
|
+
* keep-alive by default but expires idle sockets after only 2500ms, while
|
|
30
|
+
* the telemetry fan-in writer's flush window (TELEMETRY_FANIN_MAX_WAIT_MS,
|
|
31
|
+
* see TelemetryFanInWriter.ts) defaults to 5000ms — so under sub-saturation
|
|
32
|
+
* ingest load every pooled socket was destroyed between flushes and every
|
|
33
|
+
* flush paid TCP (+TLS) connection setup again. The default here is bounded
|
|
34
|
+
* on both sides:
|
|
35
|
+
*
|
|
36
|
+
* - ABOVE the 5000ms fan-in flush window, so the socket a flush opened is
|
|
37
|
+
* still alive when the next flush fires and gets reused instead of
|
|
38
|
+
* being re-established;
|
|
39
|
+
* - BELOW the ClickHouse server's keep_alive_timeout of 10s (the bundled
|
|
40
|
+
* Clickhouse/config.xml pins <keep_alive_timeout>10</keep_alive_timeout>,
|
|
41
|
+
* which is also the server default since 23.11), so the CLIENT always
|
|
42
|
+
* retires an idle socket before the SERVER does. Operators who lower
|
|
43
|
+
* the server's keep_alive_timeout below this TTL must lower
|
|
44
|
+
* CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS along with it (keeping it a
|
|
45
|
+
* fair bit under the server value) — otherwise the client reuses
|
|
46
|
+
* sockets the server has already closed and requests fail with
|
|
47
|
+
* ECONNRESET.
|
|
48
|
+
*
|
|
49
|
+
* The value must be a positive number of milliseconds; unset, non-numeric,
|
|
50
|
+
* zero and negative values all fall back to the default. Zero is rejected
|
|
51
|
+
* deliberately: the client treats 0 as "disable idle-socket reaping
|
|
52
|
+
* entirely", which reintroduces the server-closes-first ECONNRESET failure
|
|
53
|
+
* mode this TTL exists to prevent.
|
|
54
|
+
*/
|
|
55
|
+
const DEFAULT_KEEP_ALIVE_IDLE_SOCKET_TTL_MS: number = 8000;
|
|
56
|
+
|
|
57
|
+
const keepAliveIdleSocketTtlRawValue: string = (
|
|
58
|
+
process.env["CLICKHOUSE_KEEP_ALIVE_IDLE_SOCKET_TTL_MS"] || ""
|
|
59
|
+
).trim();
|
|
60
|
+
|
|
61
|
+
const keepAliveIdleSocketTtlParsedValue: number = parseInt(
|
|
62
|
+
keepAliveIdleSocketTtlRawValue,
|
|
63
|
+
10,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const keepAliveIdleSocketTtlInMs: number =
|
|
67
|
+
Number.isFinite(keepAliveIdleSocketTtlParsedValue) &&
|
|
68
|
+
keepAliveIdleSocketTtlParsedValue > 0
|
|
69
|
+
? keepAliveIdleSocketTtlParsedValue
|
|
70
|
+
: DEFAULT_KEEP_ALIVE_IDLE_SOCKET_TTL_MS;
|
|
71
|
+
|
|
26
72
|
const options: ClickHouseClientConfigOptions = {
|
|
27
73
|
url: `${hostProtocol}://${clickhouseHost.toString()}:${clickhousePort}`,
|
|
28
74
|
username: ClickhouseUsername,
|
|
@@ -72,6 +118,19 @@ const options: ClickHouseClientConfigOptions = {
|
|
|
72
118
|
request: true,
|
|
73
119
|
response: true,
|
|
74
120
|
},
|
|
121
|
+
/*
|
|
122
|
+
* Reuse pooled sockets across fan-in flush windows — see the note on
|
|
123
|
+
* keepAliveIdleSocketTtlInMs above for both bounds on the TTL and the
|
|
124
|
+
* operator warning about the server's keep_alive_timeout. `enabled: true`
|
|
125
|
+
* restates the client default explicitly so the pairing with
|
|
126
|
+
* idle_socket_ttl is visible here rather than implied. This lives on the
|
|
127
|
+
* shared `options` object, so every pool derived from it (query, ingest,
|
|
128
|
+
* migration, test) gets the same keep-alive behavior.
|
|
129
|
+
*/
|
|
130
|
+
keep_alive: {
|
|
131
|
+
enabled: true,
|
|
132
|
+
idle_socket_ttl: keepAliveIdleSocketTtlInMs,
|
|
133
|
+
},
|
|
75
134
|
};
|
|
76
135
|
|
|
77
136
|
if (ShouldClickhouseSslEnable && ClickhouseTlsCa) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class AddDataSourceTable1786303472848 implements MigrationInterface {
|
|
4
|
+
public name: string = "AddDataSourceTable1786303472848";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`CREATE TABLE "DataSource" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "name" character varying(100) NOT NULL, "slug" character varying(100) NOT NULL, "description" character varying(500), "dataSourceType" character varying(100) NOT NULL, "url" character varying, "databaseHost" character varying(100), "databasePort" integer, "databaseName" character varying(100), "username" character varying(100), "password" text, "apiToken" text, "customHeaders" jsonb, "additionalOptions" jsonb, "createdByUserId" uuid, "deletedByUserId" uuid, CONSTRAINT "PK_49141becafea4a0574d9b5219ca" PRIMARY KEY ("_id"))`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`CREATE INDEX "IDX_0e559ea9d7fbc66d014a29c380" ON "DataSource" ("projectId") `,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "DataSource" ADD CONSTRAINT "FK_0e559ea9d7fbc66d014a29c3804" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "DataSource" ADD CONSTRAINT "FK_38843f53e5ca0ce0bf4de525d6f" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "DataSource" ADD CONSTRAINT "FK_29f0d663494b52c4ed2c0cc8e88" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "DataSource" DROP CONSTRAINT "FK_29f0d663494b52c4ed2c0cc8e88"`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "DataSource" DROP CONSTRAINT "FK_38843f53e5ca0ce0bf4de525d6f"`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "DataSource" DROP CONSTRAINT "FK_0e559ea9d7fbc66d014a29c3804"`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`DROP INDEX "public"."IDX_0e559ea9d7fbc66d014a29c380"`,
|
|
36
|
+
);
|
|
37
|
+
await queryRunner.query(`DROP TABLE "DataSource"`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Generated with `npm run generate-postgres-migration` after adding
|
|
5
|
+
* AIRun.analysisTldr — the AI-written one or two sentence summary of a
|
|
6
|
+
* completed investigation's posted report. Nullable: legacy runs, runs that
|
|
7
|
+
* published no report, and runs whose bounded TL;DR call failed simply have
|
|
8
|
+
* none, and the panel omits the TL;DR block for them.
|
|
9
|
+
*/
|
|
10
|
+
export class AddInvestigationAnalysisTldr1786600000000
|
|
11
|
+
implements MigrationInterface
|
|
12
|
+
{
|
|
13
|
+
public name = "AddInvestigationAnalysisTldr1786600000000";
|
|
14
|
+
|
|
15
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "AIRun" ADD "analysisTldr" character varying(500)`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
22
|
+
await queryRunner.query(`ALTER TABLE "AIRun" DROP COLUMN "analysisTldr"`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Drops the global UNIQUE constraints on ProjectCallSMSConfig's Twilio
|
|
5
|
+
* credentials. Generated with `npm run generate-postgres-migration` after
|
|
6
|
+
* flipping both columns to `unique: false`; the statements are the generator's,
|
|
7
|
+
* renumbered to sort last and given IF EXISTS (see below).
|
|
8
|
+
*
|
|
9
|
+
* WHY THEY WERE WRONG
|
|
10
|
+
*
|
|
11
|
+
* ProjectCallSMSConfig is tenant-scoped (@TenantColumn("projectId")) and
|
|
12
|
+
* inherently multi-row: a project has as many configs as it has Twilio
|
|
13
|
+
* setups. The constraints came from the InitialMigration, where this table's
|
|
14
|
+
* columns were modelled on GlobalConfig — a singleton table whose every column
|
|
15
|
+
* carries a pointless `unique: true`. On a singleton that is harmless. Here it
|
|
16
|
+
* meant no two rows anywhere in the instance could share a Twilio account.
|
|
17
|
+
*
|
|
18
|
+
* That is not a constraint anybody wants:
|
|
19
|
+
*
|
|
20
|
+
* - One Twilio account, two numbers. Poland (and several other countries)
|
|
21
|
+
* requires a Local number for Voice and a Mobile number for SMS, so a
|
|
22
|
+
* single project legitimately needs two configs on one account. This is
|
|
23
|
+
* what issue #3020 was reported against.
|
|
24
|
+
* - Two projects, one account. On a shared instance the FIRST project to
|
|
25
|
+
* save a given account SID locked every other project out of it, across
|
|
26
|
+
* the tenant boundary — one tenant could deny another the use of its own
|
|
27
|
+
* Twilio credentials, and neither could see why.
|
|
28
|
+
*
|
|
29
|
+
* Both surfaced the same way: Postgres raised unique_violation (23505),
|
|
30
|
+
* which is not a OneUptime Exception, so it fell through to the generic
|
|
31
|
+
* handler and reached the client as a bare 500 `{"error":"Server Error"}`
|
|
32
|
+
* with nothing to act on.
|
|
33
|
+
*
|
|
34
|
+
* NOT REPLACED WITH A NARROWER UNIQUE
|
|
35
|
+
*
|
|
36
|
+
* There is no uniqueness to restore at any scope. Reusing one account across
|
|
37
|
+
* configs is the supported case, not an accident to be guarded against. Config
|
|
38
|
+
* identity is `name`, which is already unique per project via
|
|
39
|
+
* @UniqueColumnBy("projectId"). After this migration ProjectCallSMSConfig has
|
|
40
|
+
* no UNIQUE constraint on any credential column, which matches every other
|
|
41
|
+
* tenant-scoped table: theirs are all on slugs, keys and tokens — identifiers
|
|
42
|
+
* that really are global.
|
|
43
|
+
*
|
|
44
|
+
* IF EXISTS
|
|
45
|
+
*
|
|
46
|
+
* Self-hosted operators hit by #3020 were told in the issue thread that the
|
|
47
|
+
* workaround is to drop the constraint by hand. IF EXISTS keeps this migration
|
|
48
|
+
* from failing on those databases. down() cannot be made safe the same way: it
|
|
49
|
+
* will fail if duplicates exist by then, which is correct — silently
|
|
50
|
+
* hard-deleting a project's Twilio config to make room for a constraint would
|
|
51
|
+
* be worse than a failed rollback.
|
|
52
|
+
*/
|
|
53
|
+
export class DropProjectCallSMSConfigCredentialUniques1786700000000
|
|
54
|
+
implements MigrationInterface
|
|
55
|
+
{
|
|
56
|
+
public name: string =
|
|
57
|
+
"DropProjectCallSMSConfigCredentialUniques1786700000000";
|
|
58
|
+
|
|
59
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
60
|
+
await queryRunner.query(
|
|
61
|
+
`ALTER TABLE "ProjectCallSMSConfig" DROP CONSTRAINT IF EXISTS "UQ_0886139eac04ad49627e446d477"`,
|
|
62
|
+
);
|
|
63
|
+
await queryRunner.query(
|
|
64
|
+
`ALTER TABLE "ProjectCallSMSConfig" DROP CONSTRAINT IF EXISTS "UQ_2eb1a240d549a7701b6e82d2f94"`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
69
|
+
await queryRunner.query(
|
|
70
|
+
`ALTER TABLE "ProjectCallSMSConfig" ADD CONSTRAINT "UQ_2eb1a240d549a7701b6e82d2f94" UNIQUE ("twilioAuthToken")`,
|
|
71
|
+
);
|
|
72
|
+
await queryRunner.query(
|
|
73
|
+
`ALTER TABLE "ProjectCallSMSConfig" ADD CONSTRAINT "UQ_0886139eac04ad49627e446d477" UNIQUE ("twilioAccountSID")`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -509,6 +509,9 @@ import { RestoreDroppedUniqueIndexes1786200000000 } from "./1786200000000-Restor
|
|
|
509
509
|
import { QuarantineUnboundGitHubInstallations1786300000000 } from "./1786300000000-QuarantineUnboundGitHubInstallations";
|
|
510
510
|
import { AddMasterPasswordSalt1786400000000 } from "./1786400000000-AddMasterPasswordSalt";
|
|
511
511
|
import { AddInvestigationCodeFixRecommendation1786500000000 } from "./1786500000000-AddInvestigationCodeFixRecommendation";
|
|
512
|
+
import { AddInvestigationAnalysisTldr1786600000000 } from "./1786600000000-AddInvestigationAnalysisTldr";
|
|
513
|
+
import { DropProjectCallSMSConfigCredentialUniques1786700000000 } from "./1786700000000-DropProjectCallSMSConfigCredentialUniques";
|
|
514
|
+
import { AddDataSourceTable1786303472848 } from "./1786303472848-AddDataSourceTable";
|
|
512
515
|
|
|
513
516
|
export default [
|
|
514
517
|
InitialMigration,
|
|
@@ -1022,4 +1025,7 @@ export default [
|
|
|
1022
1025
|
AddMasterPasswordSalt1786400000000,
|
|
1023
1026
|
MigrationName1786105470826,
|
|
1024
1027
|
AddInvestigationCodeFixRecommendation1786500000000,
|
|
1028
|
+
AddInvestigationAnalysisTldr1786600000000,
|
|
1029
|
+
DropProjectCallSMSConfigCredentialUniques1786700000000,
|
|
1030
|
+
AddDataSourceTable1786303472848,
|
|
1025
1031
|
];
|