@oneuptime/common 12.0.33 → 12.0.34
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/AnalyticsModels/RumSession.ts +117 -1
- package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
- package/Models/DatabaseModels/AlertCustomField.ts +77 -3
- package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
- package/Models/DatabaseModels/RumApplication.ts +6 -6
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
- package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamMember.ts +0 -9
- package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamPermission.ts +3 -24
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
- package/Models/DatabaseModels/UserTelegram.ts +0 -4
- package/Scripts/benchmark-fanin-capacity.js +181 -0
- package/Server/API/TelemetryAPI.ts +1284 -164
- package/Server/API/UserNotificationSettingAPI.ts +55 -0
- package/Server/API/UserTelegramAPI.ts +48 -4
- package/Server/EnvironmentConfig.ts +35 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/QueueWorker.ts +20 -14
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Middleware/TelemetryIngest.ts +453 -7
- package/Server/Services/AccessTokenService.ts +1 -0
- package/Server/Services/AlertCustomFieldService.ts +98 -0
- package/Server/Services/AlertService.ts +37 -0
- package/Server/Services/ApiKeyPermissionService.ts +461 -29
- package/Server/Services/CustomFieldMappingService.ts +879 -0
- package/Server/Services/GlobalConfigService.ts +194 -0
- package/Server/Services/IncidentCustomFieldService.ts +98 -0
- package/Server/Services/IncidentService.ts +35 -0
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +32 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
- package/Server/Services/ProjectService.ts +22 -0
- package/Server/Services/RoutineEmailSettingsService.ts +73 -0
- package/Server/Services/RumSessionReplayViewService.ts +104 -24
- package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
- package/Server/Services/ScheduledMaintenanceService.ts +32 -0
- package/Server/Services/TeamMemberService.ts +78 -0
- package/Server/Services/TeamPermissionService.ts +235 -3
- package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
- package/Server/Services/UserNotificationSettingService.ts +34 -6
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/QueryHelper.ts +2 -0
- package/Server/Utils/APIKey/AccessPermission.ts +5 -2
- package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
- package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
- package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
- package/Server/Utils/DataSource/EgressGuard.ts +177 -8
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
- package/Server/Utils/FrontendEnvironment.ts +40 -0
- package/Server/Utils/LogRedaction.ts +20 -0
- package/Server/Utils/Logger.ts +11 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
- package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
- package/Server/Utils/SSRFProtection.ts +217 -10
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
- package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
- package/Server/Utils/StartServer.ts +2 -17
- package/Server/Utils/TelegramVerificationToken.ts +185 -0
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
- package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +975 -95
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
- package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
- package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
- package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
- package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
- package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
- package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
- package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
- package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
- package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
- package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
- package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
- package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
- package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
- package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
- package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
- package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
- package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
- package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
- package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
- package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
- package/Tests/Types/JSONFunctions.test.ts +260 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
- package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
- package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
- package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
- package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
- package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
- package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
- package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
- package/Tests/Types/WebsiteRequest.test.ts +285 -3
- package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
- package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
- package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
- package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
- package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
- package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
- package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
- package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
- package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
- package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
- package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
- package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
- package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
- package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
- package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
- package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
- package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
- package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
- package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
- package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
- package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
- package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
- package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
- package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
- package/Tests/Utils/ValueFormatter.test.ts +148 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSONFunctions.ts +189 -43
- package/Types/Monitor/CephAlertTemplates.ts +157 -195
- package/Types/Monitor/DockerAlertTemplates.ts +338 -128
- package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
- package/Types/Monitor/HostAlertTemplates.ts +302 -130
- package/Types/Monitor/IotAlertTemplates.ts +112 -104
- package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
- package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
- package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
- package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
- package/Types/Monitor/RumAlertTemplates.ts +46 -7
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
- package/Types/Rum/SessionReplay.ts +209 -0
- package/Types/Rum/SessionReplayApi.ts +722 -0
- package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
- package/Types/Rum/SessionReplayConsentMode.ts +11 -7
- package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
- package/Types/Rum/SessionReplayHealth.ts +238 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
- package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
- package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
- package/Types/WebsiteRequest.ts +85 -3
- package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
- package/UI/Components/Charts/Line/LineChart.tsx +13 -2
- package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
- package/UI/Components/Charts/Utils/XAxis.ts +217 -0
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
- package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
- package/UI/Components/Header/Header.tsx +25 -9
- package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
- package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
- package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
- package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
- package/UI/Components/Icon/Icon.tsx +11 -0
- package/UI/Components/JSONTable/JSONTable.tsx +2 -2
- package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
- package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
- package/UI/Components/ModelTable/Column.ts +15 -0
- package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
- package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
- package/UI/Components/Table/CellClassName.ts +81 -0
- package/UI/Components/Table/TableRow.tsx +20 -14
- package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
- package/UI/Components/Table/Types/Column.ts +36 -0
- package/UI/Components/Tooltip/Tooltip.tsx +11 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
- package/UI/Components/Workflow/NodePlacement.ts +57 -0
- package/UI/Components/Workflow/Workflow.tsx +47 -18
- package/UI/Config.ts +15 -33
- package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
- package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
- package/UI/Utils/Telemetry/Telemetry.ts +10 -8
- package/Utils/API.ts +129 -3
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
- package/Utils/Rum/ChunkMath.ts +106 -0
- package/Utils/Rum/SessionReplayHealth.ts +732 -0
- package/Utils/Rum/SessionReplayStringMap.ts +226 -0
- package/Utils/Schema/ModelSchema.ts +1 -0
- package/Utils/StatusPage/ResourceSearch.ts +290 -0
- package/Utils/Telemetry/OriginAllowList.ts +355 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
- package/Utils/ValueFormatter.ts +35 -1
- package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
- package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
- package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +769 -109
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
- package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
- package/build/dist/Server/API/UserTelegramAPI.js +28 -6
- package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +29 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +1 -0
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
- package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +34 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
- package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
- package/build/dist/Server/Services/GlobalConfigService.js +133 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +32 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +163 -0
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +29 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
- package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
- package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
- package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +62 -2
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +166 -3
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +257 -4
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +20 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +10 -0
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
- package/build/dist/Server/Utils/SSRFProtection.js +136 -9
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +3 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
- package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +118 -37
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
- package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
- package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
- package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
- package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +117 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
- package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Types/WebsiteRequest.js +55 -3
- package/build/dist/Types/WebsiteRequest.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
- package/build/dist/UI/Components/Header/Header.js +2 -3
- package/build/dist/UI/Components/Header/Header.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +5 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
- package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
- package/build/dist/UI/Components/Table/CellClassName.js +55 -0
- package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
- package/build/dist/UI/Components/Table/TableRow.js +16 -13
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
- package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Config.js +10 -20
- package/build/dist/UI/Config.js.map +1 -1
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
- package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Utils/API.js +67 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
- package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
- package/build/dist/Utils/Rum/ChunkMath.js +76 -0
- package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
- package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
- package/build/dist/Utils/ValueFormatter.js +32 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,26 @@ import { OnUpdate } from "../Types/Database/Hooks";
|
|
|
6
6
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
7
7
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
8
8
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
9
|
+
import TelegramVerificationToken from "../Utils/TelegramVerificationToken";
|
|
10
|
+
import GlobalCache from "../Infrastructure/GlobalCache";
|
|
11
|
+
|
|
12
|
+
const TELEGRAM_WEBHOOK_SECRET_CACHE_NAMESPACE: string =
|
|
13
|
+
"global-config-security";
|
|
14
|
+
const TELEGRAM_WEBHOOK_SECRET_GENERATION_KEY: string =
|
|
15
|
+
"telegram-webhook-secret-generation";
|
|
16
|
+
const TELEGRAM_WEBHOOK_SECRET_INITIAL_GENERATION: string = "initial";
|
|
17
|
+
const TELEGRAM_WEBHOOK_SECRET_MISSING_VALUE: string = "__not_configured__";
|
|
18
|
+
const TELEGRAM_WEBHOOK_SECRET_CACHE_TTL_SECONDS: number = 5;
|
|
19
|
+
|
|
20
|
+
interface TelegramWebhookSecretTokenLoadResult {
|
|
21
|
+
value: string | undefined;
|
|
22
|
+
isCurrentGeneration: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface TelegramWebhookSecretTokenLoad {
|
|
26
|
+
generation: string;
|
|
27
|
+
promise: Promise<TelegramWebhookSecretTokenLoadResult>;
|
|
28
|
+
}
|
|
9
29
|
|
|
10
30
|
export class Service extends DatabaseService<Model> {
|
|
11
31
|
/*
|
|
@@ -15,6 +35,15 @@ export class Service extends DatabaseService<Model> {
|
|
|
15
35
|
*/
|
|
16
36
|
private requireSsoForLoginCache: InMemoryTTLCache<boolean> =
|
|
17
37
|
new InMemoryTTLCache(10_000);
|
|
38
|
+
/*
|
|
39
|
+
* The public Telegram webhook is hit without a OneUptime session. The value
|
|
40
|
+
* cache lives in Redis so every app replica observes the same generation.
|
|
41
|
+
* Only the in-flight promise is process-local: it collapses a cache-miss
|
|
42
|
+
* burst to one Postgres read per replica without retaining a retired secret.
|
|
43
|
+
*/
|
|
44
|
+
private telegramWebhookSecretTokenLoad:
|
|
45
|
+
| TelegramWebhookSecretTokenLoad
|
|
46
|
+
| undefined = undefined;
|
|
18
47
|
|
|
19
48
|
public constructor() {
|
|
20
49
|
super(Model);
|
|
@@ -43,10 +72,168 @@ export class Service extends DatabaseService<Model> {
|
|
|
43
72
|
return value;
|
|
44
73
|
}
|
|
45
74
|
|
|
75
|
+
@CaptureSpan()
|
|
76
|
+
public async getTelegramWebhookSecretToken(): Promise<string | undefined> {
|
|
77
|
+
while (true) {
|
|
78
|
+
const generation: string =
|
|
79
|
+
await this.getTelegramWebhookSecretTokenGeneration();
|
|
80
|
+
const cacheKey: string =
|
|
81
|
+
this.getTelegramWebhookSecretTokenCacheKey(generation);
|
|
82
|
+
const cached: string | null = await GlobalCache.getString(
|
|
83
|
+
TELEGRAM_WEBHOOK_SECRET_CACHE_NAMESPACE,
|
|
84
|
+
cacheKey,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (cached !== null) {
|
|
88
|
+
return cached === TELEGRAM_WEBHOOK_SECRET_MISSING_VALUE
|
|
89
|
+
? undefined
|
|
90
|
+
: cached;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const existingLoad: TelegramWebhookSecretTokenLoad | undefined =
|
|
94
|
+
this.telegramWebhookSecretTokenLoad;
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
* Cache expiry is visible to every public webhook request at once. Share
|
|
98
|
+
* the database read for that generation so a burst cannot turn one
|
|
99
|
+
* expiry into one root Postgres query per request.
|
|
100
|
+
*/
|
|
101
|
+
const load: TelegramWebhookSecretTokenLoad =
|
|
102
|
+
existingLoad?.generation === generation
|
|
103
|
+
? existingLoad
|
|
104
|
+
: {
|
|
105
|
+
generation,
|
|
106
|
+
promise: this.loadTelegramWebhookSecretToken(
|
|
107
|
+
generation,
|
|
108
|
+
cacheKey,
|
|
109
|
+
),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
if (load !== existingLoad) {
|
|
113
|
+
this.telegramWebhookSecretTokenLoad = load;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const result: TelegramWebhookSecretTokenLoadResult = await load.promise;
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* A rotation that completed during the database read makes the result
|
|
121
|
+
* unreachable through the new generation key. Loop so this request
|
|
122
|
+
* also joins the new generation instead of authenticating with the
|
|
123
|
+
* value that was retired while it waited.
|
|
124
|
+
*/
|
|
125
|
+
if (result.isCurrentGeneration) {
|
|
126
|
+
return result.value;
|
|
127
|
+
}
|
|
128
|
+
} finally {
|
|
129
|
+
/*
|
|
130
|
+
* An invalidation can start a newer-generation load while this one is
|
|
131
|
+
* still pending. The older promise must not clear that newer flight.
|
|
132
|
+
*/
|
|
133
|
+
if (this.telegramWebhookSecretTokenLoad === load) {
|
|
134
|
+
this.telegramWebhookSecretTokenLoad = undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private async getTelegramWebhookSecretTokenGeneration(): Promise<string> {
|
|
141
|
+
return (
|
|
142
|
+
(await GlobalCache.getString(
|
|
143
|
+
TELEGRAM_WEBHOOK_SECRET_CACHE_NAMESPACE,
|
|
144
|
+
TELEGRAM_WEBHOOK_SECRET_GENERATION_KEY,
|
|
145
|
+
)) || TELEGRAM_WEBHOOK_SECRET_INITIAL_GENERATION
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private getTelegramWebhookSecretTokenCacheKey(generation: string): string {
|
|
150
|
+
return `telegram-webhook-secret:${generation}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private async loadTelegramWebhookSecretToken(
|
|
154
|
+
generation: string,
|
|
155
|
+
cacheKey: string,
|
|
156
|
+
): Promise<TelegramWebhookSecretTokenLoadResult> {
|
|
157
|
+
const config: Model | null = await this.findOneBy({
|
|
158
|
+
query: {
|
|
159
|
+
_id: ObjectID.getZeroObjectID().toString(),
|
|
160
|
+
},
|
|
161
|
+
select: {
|
|
162
|
+
telegramWebhookSecretToken: true,
|
|
163
|
+
},
|
|
164
|
+
props: {
|
|
165
|
+
isRoot: true,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
const value: string | undefined =
|
|
169
|
+
config?.telegramWebhookSecretToken?.trim() || undefined;
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
* A read begun before a rotation may return after the update has committed.
|
|
173
|
+
* Check the shared generation before populating Redis; an old replica can
|
|
174
|
+
* still finish its query, but it cannot republish the retired value under
|
|
175
|
+
* the generation every other replica now reads.
|
|
176
|
+
*/
|
|
177
|
+
if (generation !== (await this.getTelegramWebhookSecretTokenGeneration())) {
|
|
178
|
+
return {
|
|
179
|
+
value: undefined,
|
|
180
|
+
isCurrentGeneration: false,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
await GlobalCache.setString(
|
|
185
|
+
TELEGRAM_WEBHOOK_SECRET_CACHE_NAMESPACE,
|
|
186
|
+
cacheKey,
|
|
187
|
+
value || TELEGRAM_WEBHOOK_SECRET_MISSING_VALUE,
|
|
188
|
+
{ expiresInSeconds: TELEGRAM_WEBHOOK_SECRET_CACHE_TTL_SECONDS },
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
value,
|
|
193
|
+
isCurrentGeneration:
|
|
194
|
+
generation === (await this.getTelegramWebhookSecretTokenGeneration()),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private async rotateTelegramWebhookSecretTokenGeneration(): Promise<void> {
|
|
199
|
+
await GlobalCache.setString(
|
|
200
|
+
TELEGRAM_WEBHOOK_SECRET_CACHE_NAMESPACE,
|
|
201
|
+
TELEGRAM_WEBHOOK_SECRET_GENERATION_KEY,
|
|
202
|
+
ObjectID.generate().toString(),
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
46
206
|
@CaptureSpan()
|
|
47
207
|
protected override async onBeforeUpdate(
|
|
48
208
|
updateBy: UpdateBy<Model>,
|
|
49
209
|
): Promise<OnUpdate<Model>> {
|
|
210
|
+
if (updateBy.data.telegramWebhookSecretToken !== undefined) {
|
|
211
|
+
const secret: unknown = updateBy.data.telegramWebhookSecretToken;
|
|
212
|
+
|
|
213
|
+
if (
|
|
214
|
+
secret !== null &&
|
|
215
|
+
secret !== "" &&
|
|
216
|
+
!TelegramVerificationToken.isWebhookSecretStrong(secret)
|
|
217
|
+
) {
|
|
218
|
+
throw new BadDataException(
|
|
219
|
+
"Telegram webhook secret token must be 32-100 characters and contain only letters, numbers, underscores, or hyphens.",
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (typeof secret === "string") {
|
|
224
|
+
updateBy.data.telegramWebhookSecretToken = secret.trim();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* Move every replica to a fresh shared generation before the write. A
|
|
229
|
+
* request during the transaction may still read the currently committed
|
|
230
|
+
* secret, but it cannot repopulate the generation used before rotation.
|
|
231
|
+
* The success hook rotates once more after commit. If the write fails,
|
|
232
|
+
* this generation simply continues to cache the still-valid old value.
|
|
233
|
+
*/
|
|
234
|
+
await this.rotateTelegramWebhookSecretTokenGeneration();
|
|
235
|
+
}
|
|
236
|
+
|
|
50
237
|
const capacitySettingKeys: Array<keyof Model> = [
|
|
51
238
|
"clickhouseCapacityNotificationEnabled",
|
|
52
239
|
"clickhouseCapacityNotificationThresholdPercent",
|
|
@@ -201,6 +388,13 @@ export class Service extends DatabaseService<Model> {
|
|
|
201
388
|
this.requireSsoForLoginCache.clear();
|
|
202
389
|
}
|
|
203
390
|
|
|
391
|
+
if (
|
|
392
|
+
(onUpdate.updateBy.data as { telegramWebhookSecretToken?: unknown })
|
|
393
|
+
.telegramWebhookSecretToken !== undefined
|
|
394
|
+
) {
|
|
395
|
+
await this.rotateTelegramWebhookSecretTokenGeneration();
|
|
396
|
+
}
|
|
397
|
+
|
|
204
398
|
return onUpdate;
|
|
205
399
|
}
|
|
206
400
|
}
|
|
@@ -1,9 +1,107 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import Model from "../../Models/DatabaseModels/IncidentCustomField";
|
|
3
|
+
import ObjectID from "../../Types/ObjectID";
|
|
4
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
5
|
+
import UpdateBy from "../Types/Database/UpdateBy";
|
|
6
|
+
import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
|
|
7
|
+
import { backfillMappedCustomFieldValues } from "../Utils/CustomField/CustomFieldDefinitionMappingHooks";
|
|
8
|
+
import {
|
|
9
|
+
validateCustomFieldMappingOnCreate,
|
|
10
|
+
validateCustomFieldMappingOnUpdate,
|
|
11
|
+
} from "../Utils/CustomField/CustomFieldMappingValidator";
|
|
12
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
3
13
|
|
|
14
|
+
/*
|
|
15
|
+
* An incident custom field can take its value from the same field on the
|
|
16
|
+
* incident's monitors instead of being typed in again
|
|
17
|
+
* (OneUptime/oneuptime#3549). These hooks are the two halves of that
|
|
18
|
+
* configuration being saved: refusing a mapping that could never resolve, and
|
|
19
|
+
* filling in the incidents that already exist once one is saved.
|
|
20
|
+
*/
|
|
4
21
|
export class Service extends DatabaseService<Model> {
|
|
5
22
|
public constructor() {
|
|
6
23
|
super(Model);
|
|
7
24
|
}
|
|
25
|
+
|
|
26
|
+
@CaptureSpan()
|
|
27
|
+
protected override async onBeforeCreate(
|
|
28
|
+
createBy: CreateBy<Model>,
|
|
29
|
+
): Promise<OnCreate<Model>> {
|
|
30
|
+
await validateCustomFieldMappingOnCreate({
|
|
31
|
+
definitionModelType: Model,
|
|
32
|
+
createBy: createBy,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return { createBy, carryForward: null };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@CaptureSpan()
|
|
39
|
+
protected override async onBeforeUpdate(
|
|
40
|
+
updateBy: UpdateBy<Model>,
|
|
41
|
+
): Promise<OnUpdate<Model>> {
|
|
42
|
+
await validateCustomFieldMappingOnUpdate({
|
|
43
|
+
definitionModelType: Model,
|
|
44
|
+
definitionService: this,
|
|
45
|
+
updateBy: updateBy,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return { updateBy, carryForward: null };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@CaptureSpan()
|
|
52
|
+
protected override async onCreateSuccess(
|
|
53
|
+
_onCreate: OnCreate<Model>,
|
|
54
|
+
createdItem: Model,
|
|
55
|
+
): Promise<Model> {
|
|
56
|
+
backfillMappedCustomFieldValues({
|
|
57
|
+
definitionModelType: Model,
|
|
58
|
+
projectId: createdItem.projectId,
|
|
59
|
+
definitionName: "incident custom field",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return createdItem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@CaptureSpan()
|
|
66
|
+
protected override async onUpdateSuccess(
|
|
67
|
+
onUpdate: OnUpdate<Model>,
|
|
68
|
+
updatedItemIds: Array<ObjectID>,
|
|
69
|
+
): Promise<OnUpdate<Model>> {
|
|
70
|
+
if (updatedItemIds.length > 0) {
|
|
71
|
+
backfillMappedCustomFieldValues({
|
|
72
|
+
definitionModelType: Model,
|
|
73
|
+
projectId: await this.getProjectIdForBackfill(onUpdate, updatedItemIds),
|
|
74
|
+
definitionName: "incident custom field",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return onUpdate;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/*
|
|
82
|
+
* `props.tenantId` is set on every dashboard write but not on internal
|
|
83
|
+
* root-scoped ones, so fall back to the row itself rather than skipping the
|
|
84
|
+
* backfill for a mapping that was changed by a script.
|
|
85
|
+
*/
|
|
86
|
+
private async getProjectIdForBackfill(
|
|
87
|
+
onUpdate: OnUpdate<Model>,
|
|
88
|
+
updatedItemIds: Array<ObjectID>,
|
|
89
|
+
): Promise<ObjectID | undefined> {
|
|
90
|
+
const tenantId: ObjectID | undefined = onUpdate.updateBy.props.tenantId as
|
|
91
|
+
| ObjectID
|
|
92
|
+
| undefined;
|
|
93
|
+
|
|
94
|
+
if (tenantId) {
|
|
95
|
+
return tenantId;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const item: Model | null = await this.findOneById({
|
|
99
|
+
id: updatedItemIds[0]!,
|
|
100
|
+
select: { projectId: true },
|
|
101
|
+
props: { isRoot: true },
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return item?.projectId;
|
|
105
|
+
}
|
|
8
106
|
}
|
|
9
107
|
export default new Service();
|
|
@@ -8,6 +8,8 @@ import FindBy from "../Types/Database/FindBy";
|
|
|
8
8
|
import { OnCreate, OnDelete, OnFind, OnUpdate } from "../Types/Database/Hooks";
|
|
9
9
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
10
10
|
import DatabaseService from "./DatabaseService";
|
|
11
|
+
import IncidentCustomField from "../../Models/DatabaseModels/IncidentCustomField";
|
|
12
|
+
import CustomFieldMappingService from "./CustomFieldMappingService";
|
|
11
13
|
import AIRunService from "./AIRunService";
|
|
12
14
|
import AIRunType from "../../Types/AI/AIRunType";
|
|
13
15
|
import AIRunStatus from "../../Types/AI/AIRunStatus";
|
|
@@ -556,6 +558,18 @@ export class Service extends DatabaseService<Model> {
|
|
|
556
558
|
}
|
|
557
559
|
}
|
|
558
560
|
|
|
561
|
+
/*
|
|
562
|
+
* Re-apply mapped custom field values. Covers the Custom Fields modal
|
|
563
|
+
* saving the whole bag back over a mapped value, and the incident's
|
|
564
|
+
* monitors being added or removed — both change what a mapped field should
|
|
565
|
+
* hold, and folding the answer into this payload keeps it one write with a
|
|
566
|
+
* truthful audit entry.
|
|
567
|
+
*/
|
|
568
|
+
await CustomFieldMappingService.applyMappingsToUpdate({
|
|
569
|
+
definitionModelType: IncidentCustomField,
|
|
570
|
+
updateBy: updateBy,
|
|
571
|
+
});
|
|
572
|
+
|
|
559
573
|
return {
|
|
560
574
|
updateBy: updateBy,
|
|
561
575
|
carryForward: carryForward,
|
|
@@ -1014,6 +1028,21 @@ export class Service extends DatabaseService<Model> {
|
|
|
1014
1028
|
StatusPageSubscriberNotificationStatus.Pending;
|
|
1015
1029
|
}
|
|
1016
1030
|
|
|
1031
|
+
/*
|
|
1032
|
+
* Last, because the incident template copy above can still be adding
|
|
1033
|
+
* monitors and mapped custom fields are resolved from the final set.
|
|
1034
|
+
*
|
|
1035
|
+
* In onBeforeCreate rather than onCreateSuccess because `customFields` is
|
|
1036
|
+
* a column on this row and the onCreateSuccess chain is un-awaited — a
|
|
1037
|
+
* value written there would be missing from the incident the caller gets
|
|
1038
|
+
* back. Written not to throw: a custom field failing to inherit must not
|
|
1039
|
+
* stop an incident from being declared.
|
|
1040
|
+
*/
|
|
1041
|
+
await CustomFieldMappingService.applyMappingsToCreate({
|
|
1042
|
+
definitionModelType: IncidentCustomField,
|
|
1043
|
+
createBy: createBy,
|
|
1044
|
+
});
|
|
1045
|
+
|
|
1017
1046
|
return {
|
|
1018
1047
|
createBy,
|
|
1019
1048
|
carryForward: null,
|
|
@@ -1914,6 +1943,12 @@ ${incident.remediationNotes || "No remediation notes provided."}
|
|
|
1914
1943
|
onUpdate: OnUpdate<Model>,
|
|
1915
1944
|
updatedItemIds: ObjectID[],
|
|
1916
1945
|
): Promise<OnUpdate<Model>> {
|
|
1946
|
+
CustomFieldMappingService.restampAfterMultiRowUpdate({
|
|
1947
|
+
definitionModelType: IncidentCustomField,
|
|
1948
|
+
updateBy: onUpdate.updateBy,
|
|
1949
|
+
updatedItemIds: updatedItemIds,
|
|
1950
|
+
});
|
|
1951
|
+
|
|
1917
1952
|
/*
|
|
1918
1953
|
* Correcting a timestamp is the whole point of making these fields
|
|
1919
1954
|
* editable, so the numbers derived from them have to move. Without this
|
|
@@ -30,6 +30,8 @@ import {
|
|
|
30
30
|
import { keyForContainer } from "../Utils/Telemetry/TelemetryEntity";
|
|
31
31
|
import { getEntityBudget } from "../Utils/Telemetry/EntityRegistry";
|
|
32
32
|
import { EntityScopeQueryValue } from "../Utils/AnalyticsDatabase/StatementGenerator";
|
|
33
|
+
import Includes from "../../Types/BaseDatabase/Includes";
|
|
34
|
+
import EqualTo from "../../Types/BaseDatabase/EqualTo";
|
|
33
35
|
import InventoryItemService from "./InventoryItemService";
|
|
34
36
|
import InventoryItem from "../../Models/DatabaseModels/InventoryItem";
|
|
35
37
|
import EntityType from "../../Types/Telemetry/EntityType";
|
|
@@ -1030,6 +1032,12 @@ export class MetricService extends AnalyticsDatabaseService<Metric> {
|
|
|
1030
1032
|
}
|
|
1031
1033
|
}
|
|
1032
1034
|
|
|
1035
|
+
/*
|
|
1036
|
+
* No rollup can serve this aggregation, so it reads the raw table.
|
|
1037
|
+
* Narrow that scan to the queried entity before it is compiled.
|
|
1038
|
+
*/
|
|
1039
|
+
this.applyRawEntityKeyPrune(aggregateBy);
|
|
1040
|
+
|
|
1033
1041
|
if (
|
|
1034
1042
|
aggregateBy.aggregateColumnName.toString() === "value" &&
|
|
1035
1043
|
aggregateBy.aggregationTimestampColumnName.toString() === "time"
|
|
@@ -1043,6 +1051,13 @@ export class MetricService extends AnalyticsDatabaseService<Metric> {
|
|
|
1043
1051
|
return super.toAggregateStatement(aggregateBy);
|
|
1044
1052
|
}
|
|
1045
1053
|
|
|
1054
|
+
/*
|
|
1055
|
+
* Percentiles never route to a rollup (the MVs store sum/count/min/max
|
|
1056
|
+
* states, not quantile states), so every percentile aggregation reads
|
|
1057
|
+
* the raw table and wants the same entity prune.
|
|
1058
|
+
*/
|
|
1059
|
+
this.applyRawEntityKeyPrune(aggregateBy);
|
|
1060
|
+
|
|
1046
1061
|
const percentileLevel: number | null = getPercentileLevel(
|
|
1047
1062
|
aggregateBy.aggregationType,
|
|
1048
1063
|
);
|
|
@@ -2569,6 +2584,185 @@ export class MetricService extends AnalyticsDatabaseService<Metric> {
|
|
|
2569
2584
|
return { route, keys: [expectedKey] };
|
|
2570
2585
|
}
|
|
2571
2586
|
|
|
2587
|
+
/**
|
|
2588
|
+
* Entity keys derivable from ONE attribute filter on a recognized
|
|
2589
|
+
* entity attribute, or null when this filter shape yields no provable
|
|
2590
|
+
* key set.
|
|
2591
|
+
*
|
|
2592
|
+
* Accepts the shapes an entity filter actually arrives in — a bare
|
|
2593
|
+
* string, `EqualTo(string)`, and `Includes([...strings])` ("is any
|
|
2594
|
+
* of") — because for each of those the set of matching rows is exactly
|
|
2595
|
+
* the union of the listed values' entities. Everything else (negations
|
|
2596
|
+
* like NotEqual / IncludesNone, substring operators, numbers, arrays of
|
|
2597
|
+
* AND-ed operators) is refused: their matching set is not a finite
|
|
2598
|
+
* enumerable key set, so no key predicate could be proven lossless.
|
|
2599
|
+
*/
|
|
2600
|
+
private getEntityKeysForAttributeFilter(data: {
|
|
2601
|
+
route: EntityMVRoute;
|
|
2602
|
+
projectId: string;
|
|
2603
|
+
attributeValue: unknown;
|
|
2604
|
+
}): Array<string> | null {
|
|
2605
|
+
const keyForValue: ((projectId: string, value: string) => string) | null =
|
|
2606
|
+
data.route.keyForValue;
|
|
2607
|
+
|
|
2608
|
+
/*
|
|
2609
|
+
* Service is excluded for the same reason it is excluded from the
|
|
2610
|
+
* single-attribute MV route: ingest folds `service.namespace` into
|
|
2611
|
+
* the key, so a bare name does not derive the stamped key and the
|
|
2612
|
+
* predicate could drop the namespaced variants' rows.
|
|
2613
|
+
*/
|
|
2614
|
+
if (!keyForValue) {
|
|
2615
|
+
return null;
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
const rawValues: Array<unknown> =
|
|
2619
|
+
data.attributeValue instanceof Includes
|
|
2620
|
+
? (data.attributeValue.values as Array<unknown>) || []
|
|
2621
|
+
: [
|
|
2622
|
+
data.attributeValue instanceof EqualTo
|
|
2623
|
+
? (data.attributeValue.value as unknown)
|
|
2624
|
+
: data.attributeValue,
|
|
2625
|
+
];
|
|
2626
|
+
|
|
2627
|
+
const keys: Array<string> = [];
|
|
2628
|
+
for (const rawValue of rawValues) {
|
|
2629
|
+
/*
|
|
2630
|
+
* One non-string (or empty) member makes the whole union
|
|
2631
|
+
* underivable — refuse rather than prune to a partial set, which
|
|
2632
|
+
* would silently drop rows.
|
|
2633
|
+
*/
|
|
2634
|
+
if (typeof rawValue !== "string" || !rawValue) {
|
|
2635
|
+
return null;
|
|
2636
|
+
}
|
|
2637
|
+
const key: string = keyForValue(data.projectId, rawValue);
|
|
2638
|
+
if (!keys.includes(key)) {
|
|
2639
|
+
keys.push(key);
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
return keys.length > 0 ? keys : null;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
/**
|
|
2647
|
+
* Narrow a raw-table aggregation to the entity it filters on, by
|
|
2648
|
+
* ANDing a predicate on the bloom-indexed scalar entity-key column
|
|
2649
|
+
* onto the query.
|
|
2650
|
+
*
|
|
2651
|
+
* WHY: `attributes` is a Map column with no index and no place in the
|
|
2652
|
+
* sort key, so `attributes['resource.host.name'] = 'web-1'` cannot
|
|
2653
|
+
* prune a single granule — ClickHouse reads EVERY row for the
|
|
2654
|
+
* project+metric in the window and evaluates the map lookup per row.
|
|
2655
|
+
* The per-entity rollups (tryBuildEntityAggregateMVStatement) hide
|
|
2656
|
+
* that for the common single-filter case, but they decline as soon as
|
|
2657
|
+
* the query carries anything they cannot express: a second attribute
|
|
2658
|
+
* filter (`state is any of system, user`), a group-by, a percentile, a
|
|
2659
|
+
* distribution metric, a `Total` interval. Those queries then fall to
|
|
2660
|
+
* the raw table UNPRUNED, and the scan cost grows with the window —
|
|
2661
|
+
* measured on a production project, one host's `system.cpu.utilization`
|
|
2662
|
+
* with a second attribute filter took ~1.5s over 1 hour but blew
|
|
2663
|
+
* through the 45s `max_execution_time` over 1 week, returning either a
|
|
2664
|
+
* 500 or (under `timeout_overflow_mode = 'break'`) a silently partial
|
|
2665
|
+
* chart. With this prune the same 1-week query returns complete
|
|
2666
|
+
* results in ~2.4s.
|
|
2667
|
+
*
|
|
2668
|
+
* WHY IT IS LOSSLESS: the added predicate can only ever remove rows the
|
|
2669
|
+
* attribute predicate already removed. A row matching
|
|
2670
|
+
* `attributes[<entity attr>] = v` either
|
|
2671
|
+
* - was ingested with the scalar key columns stamped, in which case
|
|
2672
|
+
* its `<keyColumn>` IS `keyFor<type>(projectId, v)` — the ingest
|
|
2673
|
+
* stamp and `keyForValue` are the same canonicalizing function
|
|
2674
|
+
* (see Common/Utils/Telemetry/EntityKey); or
|
|
2675
|
+
* - predates those columns, in which case it reads the non-Nullable
|
|
2676
|
+
* default `''`.
|
|
2677
|
+
* Both are in the emitted `IN` set, so the predicate is a pure
|
|
2678
|
+
* restriction on the scan, not on the result. (This is strictly safer
|
|
2679
|
+
* than the rollup path it backstops, which drops the `''` rows.)
|
|
2680
|
+
*
|
|
2681
|
+
* Applied only after MV routing has declined — adding a key column to
|
|
2682
|
+
* the query beforehand would fail the MVs' `mvQueryableColumns` gate
|
|
2683
|
+
* and disable the fast path this backstops.
|
|
2684
|
+
*/
|
|
2685
|
+
private applyRawEntityKeyPrune(aggregateBy: AggregateBy<Metric>): void {
|
|
2686
|
+
const queryRecord: Record<string, unknown> =
|
|
2687
|
+
(aggregateBy.query as unknown as Record<string, unknown>) || {};
|
|
2688
|
+
|
|
2689
|
+
/*
|
|
2690
|
+
* Entity keys fold the tenant into the hash, so they are only
|
|
2691
|
+
* derivable for a project-scoped query. Dashboard reads always are.
|
|
2692
|
+
*/
|
|
2693
|
+
const projectIdValue: unknown = queryRecord["projectId"];
|
|
2694
|
+
let projectId: string = "";
|
|
2695
|
+
if (projectIdValue instanceof ObjectID) {
|
|
2696
|
+
projectId = projectIdValue.toString();
|
|
2697
|
+
} else if (typeof projectIdValue === "string") {
|
|
2698
|
+
projectId = projectIdValue;
|
|
2699
|
+
}
|
|
2700
|
+
if (!projectId) {
|
|
2701
|
+
return;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
const attrs: unknown = queryRecord["attributes"];
|
|
2705
|
+
if (!attrs || typeof attrs !== "object" || Array.isArray(attrs)) {
|
|
2706
|
+
return;
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
const prunePredicates: Record<string, Includes> = {};
|
|
2710
|
+
|
|
2711
|
+
for (const [attrKey, attrValue] of Object.entries(
|
|
2712
|
+
attrs as Record<string, unknown>,
|
|
2713
|
+
)) {
|
|
2714
|
+
const route: EntityMVRoute | undefined = ENTITY_MV_ROUTES.find(
|
|
2715
|
+
(candidate: EntityMVRoute) => {
|
|
2716
|
+
return candidate.attributeKey === attrKey;
|
|
2717
|
+
},
|
|
2718
|
+
);
|
|
2719
|
+
if (!route) {
|
|
2720
|
+
continue;
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
/*
|
|
2724
|
+
* Never touch a key column the caller already constrained — theirs
|
|
2725
|
+
* is the authoritative predicate, and a second one could only
|
|
2726
|
+
* narrow it further.
|
|
2727
|
+
*/
|
|
2728
|
+
if (queryRecord[route.keyColumn] !== undefined) {
|
|
2729
|
+
continue;
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
// Models without the column (older schema) simply get no prune.
|
|
2733
|
+
if (!this.model.getTableColumn(route.keyColumn)) {
|
|
2734
|
+
continue;
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
const keys: Array<string> | null = this.getEntityKeysForAttributeFilter({
|
|
2738
|
+
route,
|
|
2739
|
+
projectId,
|
|
2740
|
+
attributeValue: attrValue,
|
|
2741
|
+
});
|
|
2742
|
+
if (!keys) {
|
|
2743
|
+
continue;
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
// '' keeps rows ingested before the key columns existed. See above.
|
|
2747
|
+
prunePredicates[route.keyColumn] = new Includes([...keys, ""]);
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
if (Object.keys(prunePredicates).length === 0) {
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
/*
|
|
2755
|
+
* Replace `query` rather than mutating it in place: callers (the API
|
|
2756
|
+
* aggregate cache, the metric-monitor worker) may still hold the
|
|
2757
|
+
* object they passed in. `aggregateBy` itself keeps its identity, so
|
|
2758
|
+
* the point-type / service-key hints keyed on it in WeakMaps survive.
|
|
2759
|
+
*/
|
|
2760
|
+
aggregateBy.query = {
|
|
2761
|
+
...(aggregateBy.query as unknown as Record<string, unknown>),
|
|
2762
|
+
...prunePredicates,
|
|
2763
|
+
} as unknown as typeof aggregateBy.query;
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2572
2766
|
private stripEntityFilterAndTimeFromQuery(query: unknown): typeof query {
|
|
2573
2767
|
if (!query || typeof query !== "object") {
|
|
2574
2768
|
return query;
|
|
@@ -10,6 +10,8 @@ import CreateBy from "../Types/Database/CreateBy";
|
|
|
10
10
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
11
11
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
12
12
|
import DatabaseService from "./DatabaseService";
|
|
13
|
+
import CustomFieldMappingService from "./CustomFieldMappingService";
|
|
14
|
+
import CustomFieldMappingSourceResource from "../../Types/CustomField/CustomFieldMappingSourceResource";
|
|
13
15
|
import MonitorLabelRuleEngineService from "./MonitorLabelRuleEngineService";
|
|
14
16
|
import MonitorOwnerRuleEngineService from "./MonitorOwnerRuleEngineService";
|
|
15
17
|
import MonitorOwnerTeamService from "./MonitorOwnerTeamService";
|
|
@@ -1099,6 +1101,36 @@ export class Service extends DatabaseService<Model> {
|
|
|
1099
1101
|
});
|
|
1100
1102
|
}
|
|
1101
1103
|
|
|
1104
|
+
/*
|
|
1105
|
+
* The "stays in sync" half of custom field value mapping
|
|
1106
|
+
* (OneUptime/oneuptime#3549): alerts, incidents and maintenance events
|
|
1107
|
+
* attached to this monitor whose custom fields are configured to
|
|
1108
|
+
* inherit from it are brought back in line.
|
|
1109
|
+
*
|
|
1110
|
+
* `!== undefined` rather than truthiness: clearing the bag arrives as
|
|
1111
|
+
* `{}` or null, and is exactly the edit worth reacting to. In its own
|
|
1112
|
+
* try/catch because a propagation failure must never fail the
|
|
1113
|
+
* operator's save — the house rule for every side effect in this hook.
|
|
1114
|
+
*/
|
|
1115
|
+
if (onUpdate.updateBy.data.customFields !== undefined) {
|
|
1116
|
+
try {
|
|
1117
|
+
await CustomFieldMappingService.propagateFromSourceRecord({
|
|
1118
|
+
resource: CustomFieldMappingSourceResource.Monitor,
|
|
1119
|
+
sourceId: monitorId,
|
|
1120
|
+
projectId: projectId,
|
|
1121
|
+
});
|
|
1122
|
+
} catch (error) {
|
|
1123
|
+
logger.error(
|
|
1124
|
+
"Custom field value mapping: propagating monitor custom fields failed in MonitorService.onUpdateSuccess",
|
|
1125
|
+
{
|
|
1126
|
+
projectId: projectId?.toString(),
|
|
1127
|
+
monitorId: monitorId?.toString(),
|
|
1128
|
+
} as LogAttributes,
|
|
1129
|
+
);
|
|
1130
|
+
logger.error(error as Error);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1102
1134
|
if (onUpdate.updateBy.data.monitorSteps) {
|
|
1103
1135
|
const validMonitorStepIds: Array<string> = this.extractMonitorStepIds(
|
|
1104
1136
|
onUpdate.updateBy.data.monitorSteps as MonitorSteps | JSONObject,
|