@oneuptime/common 12.0.33 → 13.0.0
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/GlobalConfig.ts +12 -12
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/InventoryItem.ts +44 -1
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/NetworkDevice.ts +126 -0
- 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 +82 -18
- 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/1791700000000-AddMacAddressToNetworkDevice.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Infrastructure/QueueWorker.ts +20 -14
- package/Server/Infrastructure/Redis.ts +8 -8
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Infrastructure/Status.ts +10 -4
- 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/DatabaseService.ts +65 -13
- package/Server/Services/GlobalConfigService.ts +194 -0
- package/Server/Services/IncidentCustomFieldService.ts +98 -0
- package/Server/Services/IncidentService.ts +35 -0
- package/Server/Services/InventoryItemService.ts +31 -1
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +32 -0
- package/Server/Services/MonitorTemplateService.ts +140 -19
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +427 -66
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +87 -2
- package/Server/Services/NetworkDeviceService.ts +69 -0
- 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/UserNotificationRuleService.ts +76 -25
- package/Server/Services/UserNotificationSettingService.ts +34 -6
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/Permissions/ReadPermission.ts +45 -5
- package/Server/Types/Database/QueryHelper.ts +2 -0
- package/Server/Types/Database/QueryUtil.ts +56 -0
- package/Server/Types/Markdown.ts +93 -1
- 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/Dashboard/PublicDashboardResourceListPolicy.ts +82 -17
- package/Server/Utils/DataSource/EgressGuard.ts +177 -8
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +67 -5
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +2 -2
- 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 +394 -86
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +31 -5
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +312 -52
- package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +82 -9
- package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +16 -7
- package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +29 -17
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +107 -48
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
- package/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.ts +158 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +27 -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/EntityRegistry.ts +11 -1
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +83 -9
- 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/AddNeighborToMonitoringModal.test.tsx +32 -0
- package/Tests/App/Dashboard/AdoptedDeviceDrawer.test.tsx +374 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DashboardLabelVariables.test.tsx +580 -0
- package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +438 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +5 -2
- package/Tests/App/Dashboard/DeviceAttachmentCard.test.tsx +273 -0
- package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +505 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +163 -0
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +401 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +232 -0
- package/Tests/App/Dashboard/InventoryItems.test.tsx +201 -0
- package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +798 -0
- package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +320 -0
- package/Tests/App/Dashboard/NetworkTopologyToolbar.test.tsx +275 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedEmptyState.test.tsx +975 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +63 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +626 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +348 -0
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +331 -0
- package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +603 -0
- package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +324 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +13 -4
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageOidcOrigin.test.tsx +223 -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/Models/InventoryItemStatus.test.ts +147 -0
- package/Tests/Models/NetworkDeviceMacAddressColumn.test.ts +294 -0
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +129 -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/EnvironmentConfigValkey.test.ts +227 -0
- package/Tests/Server/Infrastructure/Postgres/AddMacAddressToNetworkDeviceMigration.test.ts +365 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +241 -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/Infrastructure/ValkeyDeploymentConfig.test.ts +265 -0
- package/Tests/Server/Middleware/HttpMetricsMiddleware.test.ts +382 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +525 -0
- 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/DatabaseServiceAggregateBy.test.ts +291 -56
- package/Tests/Server/Services/DatabaseServiceSortTiebreaker.test.ts +151 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +105 -0
- package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +178 -0
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/MonitorTemplateServiceCustomFieldSync.test.ts +502 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1351 -74
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanRegistration.test.ts +520 -0
- package/Tests/Server/Services/NetworkDeviceMacAddressNormalization.test.ts +572 -0
- 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/Types/Database/InventoryStatusPostgres.test.ts +368 -0
- package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +261 -14
- package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroups.test.ts +169 -0
- package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroupsPostgres.test.ts +297 -0
- package/Tests/Server/Types/Markdown.test.ts +194 -1
- package/Tests/Server/Types/Workflow/Components/IncomingWebhookUtils.test.ts +279 -0
- package/Tests/Server/Types/Workflow/Components/TextToJson.test.ts +212 -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/CustomFieldMappingRegistry.test.ts +436 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +214 -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 +2 -2
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +10 -3
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
- package/Tests/Server/Utils/EventLoop.test.ts +359 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +30 -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/CompareCriteria.test.ts +242 -0
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +590 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +29 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +30 -6
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +246 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEmailEvalLogAgreement.test.ts +280 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +659 -8
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +570 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +30 -5
- package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +68 -21
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +36 -19
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.test.ts +573 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +317 -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/ContextSpanProcessor.test.ts +281 -0
- package/Tests/Server/Utils/Telemetry/InventoryDuplicateIdentity.test.ts +316 -0
- package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +111 -8
- 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/Database/IncludesAnyOfGroups.test.ts +106 -0
- package/Tests/Types/JSONFunctions.test.ts +300 -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/NetworkAutomation/AutoImportRunMerge.test.ts +235 -0
- package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +66 -0
- package/Tests/Types/NetworkAutomation/RuleRunResultDescribe.test.ts +309 -1
- 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/Telemetry/InventoryLiveness.test.ts +99 -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/CustomFieldsDetail.test.tsx +160 -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/ReactRouterSingletonBuild.test.ts +133 -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 +719 -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/ReplayPlayerChrome.test.tsx +514 -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/ReplayTimeFormat.test.ts +94 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +559 -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/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -0
- package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +11 -1
- package/Tests/Utils/Dashboard/LabelVariable.test.ts +257 -0
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +144 -14
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/MetricUnitUtil.test.ts +81 -0
- package/Tests/Utils/Monitor/DeviceMacLearningUtil.test.ts +497 -0
- package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +546 -0
- package/Tests/Utils/Monitor/MonitorTemplateCustomFieldUtil.test.ts +218 -0
- package/Tests/Utils/Monitor/NetworkTopologyEndpointAdoption.test.ts +1755 -0
- package/Tests/Utils/NetworkAutomation/AutoImportRunChain.test.ts +320 -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/BaseDatabase/IncludesAnyOfGroups.ts +77 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardMonitorListComponent.ts +1 -0
- package/Types/Dashboard/DashboardVariable.ts +8 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSON.ts +4 -0
- package/Types/JSONFunctions.ts +205 -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/SnmpMonitor/NetworkTopology.ts +13 -0
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NetworkAutomation/RuleRunResult.ts +402 -13
- 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/SerializableObjectDictionary.ts +4 -0
- package/Types/Telemetry/InventoryLiveness.ts +56 -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/CSVFileUpload/CSVFileUpload.tsx +9 -2
- 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 +189 -46
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/Dashboard/DashboardVariableControl.tsx +285 -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/UI/esbuild-config.js +6 -0
- package/Utils/API.ts +129 -3
- package/Utils/Dashboard/Components/DashboardMonitorListComponent.ts +12 -1
- package/Utils/Dashboard/LabelVariable.ts +152 -0
- package/Utils/Dashboard/VariableUrlState.ts +27 -5
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/MetricUnitUtil.ts +34 -0
- package/Utils/Monitor/DeviceMacLearningUtil.ts +177 -0
- package/Utils/Monitor/MetricValueFormatter.ts +342 -0
- package/Utils/Monitor/MonitorTemplateCustomFieldUtil.ts +124 -0
- package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +7 -2
- package/Utils/Monitor/NetworkTopologyUtil.ts +693 -0
- package/Utils/NetworkAutomation/AutoImportRunChain.ts +138 -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/GlobalConfig.js +12 -12
- package/build/dist/Models/DatabaseModels/GlobalConfig.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/InventoryItem.js +34 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.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/NetworkDevice.js +128 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.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 +73 -14
- 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/1791700000000-AddMacAddressToNetworkDevice.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -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/Redis.js +8 -8
- package/build/dist/Server/Infrastructure/Redis.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/Infrastructure/Status.js +10 -4
- package/build/dist/Server/Infrastructure/Status.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/DatabaseService.js +58 -13
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- 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/InventoryItemService.js +28 -1
- package/build/dist/Server/Services/InventoryItemService.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/MonitorTemplateService.js +116 -17
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +349 -64
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +65 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +54 -0
- package/build/dist/Server/Services/NetworkDeviceService.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/UserNotificationRuleService.js +60 -25
- package/build/dist/Server/Services/UserNotificationRuleService.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/Permissions/ReadPermission.js +29 -4
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryUtil.js +36 -0
- package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +75 -0
- package/build/dist/Server/Types/Markdown.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/Dashboard/PublicDashboardResourceListPolicy.js +53 -18
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- 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 +54 -3
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +2 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.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 +323 -81
- 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/Criteria/MetricMonitorCriteria.js +29 -5
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.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 +254 -48
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +58 -9
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +9 -3
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +26 -12
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +74 -33
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.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/NetworkDeviceMacLearningUtil.js +114 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +25 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.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/EntityRegistry.js +9 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- 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/TelemetryEntity.js +70 -13
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- 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/BaseDatabase/IncludesAnyOfGroups.js +54 -0
- package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js.map +1 -0
- 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/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardVariable.js +1 -0
- package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSON.js +1 -0
- package/build/dist/Types/JSON.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +131 -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/NetworkAutomation/RuleRunResult.js +291 -6
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
- 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/SerializableObjectDictionary.js +4 -0
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/InventoryLiveness.js +37 -0
- package/build/dist/Types/Telemetry/InventoryLiveness.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/CSVFileUpload/CSVFileUpload.js +7 -0
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.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 +89 -8
- 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/Dashboard/DashboardVariableControl.js +137 -0
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.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/Dashboard/Components/DashboardMonitorListComponent.js +9 -1
- package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/LabelVariable.js +96 -0
- package/build/dist/Utils/Dashboard/LabelVariable.js.map +1 -0
- package/build/dist/Utils/Dashboard/VariableUrlState.js +19 -4
- package/build/dist/Utils/Dashboard/VariableUrlState.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/MetricUnitUtil.js +26 -0
- package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js +112 -0
- package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +276 -0
- package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js +101 -0
- package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +7 -2
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +484 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js +59 -0
- package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.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/jest.config.json +2 -0
- package/package.json +1 -1
- package/test-setup.sh +9 -9
- package/tsconfig.json +51 -11
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
import CreateBy from "../Types/Database/CreateBy";
|
|
2
2
|
import DeleteBy from "../Types/Database/DeleteBy";
|
|
3
|
+
import Query from "../Types/Database/Query";
|
|
3
4
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
4
5
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
5
6
|
import DatabaseService from "./DatabaseService";
|
|
6
7
|
import ObjectID from "../../Types/ObjectID";
|
|
8
|
+
import OneUptimeDate from "../../Types/Date";
|
|
7
9
|
import Model from "../../Models/DatabaseModels/TelemetryIngestionKey";
|
|
8
10
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
9
11
|
import InMemoryTTLCache from "../Infrastructure/InMemoryTTLCache";
|
|
12
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
13
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
14
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
15
|
+
import TelemetryIngestionKeyPolicy from "../../Types/Telemetry/TelemetryIngestionKeyPolicy";
|
|
16
|
+
import TelemetryIngestionKeyType from "../../Types/Telemetry/TelemetryIngestionKeyType";
|
|
17
|
+
import OriginAllowList from "../../Utils/Telemetry/OriginAllowList";
|
|
18
|
+
import logger from "../Utils/Logger";
|
|
10
19
|
import { createHash } from "crypto";
|
|
11
20
|
|
|
12
21
|
/*
|
|
13
22
|
* 60s is the worst-case staleness on any single API node after a key is
|
|
14
23
|
* revoked from the dashboard. We invalidate in-process immediately on
|
|
15
24
|
* delete/update; this TTL is the upper bound for *other* processes.
|
|
25
|
+
*
|
|
26
|
+
* This bound now covers more than "which project does this token belong to":
|
|
27
|
+
* it also covers the kill switch, the expiry, the origin allowlist and the
|
|
28
|
+
* rate limit. That is a deliberate trade. Turning a compromised key off still
|
|
29
|
+
* takes effect within a minute everywhere, which is fast enough for a control
|
|
30
|
+
* whose whole point is to stop a leak that has already happened, and paying a
|
|
31
|
+
* Postgres round trip per ingest request to shave that to zero would cost far
|
|
32
|
+
* more than it buys on a path that runs thousands of times a second.
|
|
16
33
|
*/
|
|
17
34
|
const POSITIVE_TTL_MS: number = 60 * 1000;
|
|
18
35
|
/*
|
|
@@ -21,10 +38,82 @@ const POSITIVE_TTL_MS: number = 60 * 1000;
|
|
|
21
38
|
*/
|
|
22
39
|
const NEGATIVE_TTL_MS: number = 10 * 1000;
|
|
23
40
|
|
|
41
|
+
/*
|
|
42
|
+
* How often a single key's lastUsedAt column may be rewritten, per process.
|
|
43
|
+
*
|
|
44
|
+
* lastUsedAt answers one question - "is anything still using this key, so can
|
|
45
|
+
* I rotate or delete it?" - and five minutes of resolution answers it
|
|
46
|
+
* perfectly. Writing on every ingest request would put a single-row UPDATE on
|
|
47
|
+
* the hottest path in the product and turn the busiest keys into a Postgres
|
|
48
|
+
* lock convoy, which is a real outage in exchange for a column nobody reads
|
|
49
|
+
* more than once a quarter.
|
|
50
|
+
*/
|
|
51
|
+
const LAST_USED_THROTTLE_MS: number = 5 * 60 * 1000;
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Ceiling on the number of distinct key ids the throttle map tracks.
|
|
55
|
+
*
|
|
56
|
+
* Only ids that resolved from a real row ever reach markUsed, so this map
|
|
57
|
+
* cannot be grown by an attacker throwing junk tokens at the ingest endpoint -
|
|
58
|
+
* those never authenticate. It is bounded anyway because "the input is
|
|
59
|
+
* trusted" is exactly the assumption that ages badly: a future caller that
|
|
60
|
+
* stamps on a different id, or an installation with an unusual number of keys,
|
|
61
|
+
* must not be able to turn a bookkeeping optimisation into an unbounded
|
|
62
|
+
* process-lifetime leak. Overflowing the bound costs one extra UPDATE per
|
|
63
|
+
* evicted key, which is nothing.
|
|
64
|
+
*/
|
|
65
|
+
const LAST_USED_THROTTLE_MAX_KEYS: number = 5000;
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Postgres `integer` upper bound. requestsPerMinuteLimit is a Number column,
|
|
69
|
+
* so anything above this is a database-level error; catching it here turns an
|
|
70
|
+
* ugly 500 into a sentence the customer can act on.
|
|
71
|
+
*/
|
|
72
|
+
const MAX_REQUESTS_PER_MINUTE_LIMIT: number = 2147483647;
|
|
73
|
+
|
|
74
|
+
/*
|
|
75
|
+
* What actually lives in the cache: a flat, primitive-only snapshot rather
|
|
76
|
+
* than the policy object itself.
|
|
77
|
+
*
|
|
78
|
+
* Two reasons, both learned from the previous shape of this cache (which
|
|
79
|
+
* stored `projectId.toString()` and rebuilt an ObjectID on read, for the same
|
|
80
|
+
* reason):
|
|
81
|
+
*
|
|
82
|
+
* 1. Callers get a fresh object every time, so nothing on the ingest path
|
|
83
|
+
* can mutate a cached entry - pushing onto `allowedOrigins`, say - and
|
|
84
|
+
* silently change the policy every other request on that pod sees for the
|
|
85
|
+
* next minute.
|
|
86
|
+
* 2. It keeps the entries small and free of live model instances, so a
|
|
87
|
+
* cached policy cannot accidentally keep a whole hydrated entity (or a
|
|
88
|
+
* column nobody meant to expose, such as the secret) alive in memory.
|
|
89
|
+
*/
|
|
90
|
+
interface CachedIngestionKeyPolicy {
|
|
91
|
+
ingestionKeyId: string;
|
|
92
|
+
projectId: string;
|
|
93
|
+
keyType: TelemetryIngestionKeyType;
|
|
94
|
+
allowedOrigins: Array<string>;
|
|
95
|
+
pinnedServiceName: string | null;
|
|
96
|
+
isEnabled: boolean;
|
|
97
|
+
expiresAtIso: string | null;
|
|
98
|
+
requestsPerMinuteLimit: number | null;
|
|
99
|
+
}
|
|
100
|
+
|
|
24
101
|
export class Service extends DatabaseService<Model> {
|
|
25
|
-
private
|
|
102
|
+
private policyCache: InMemoryTTLCache<CachedIngestionKeyPolicy | null> =
|
|
26
103
|
new InMemoryTTLCache(10_000);
|
|
27
104
|
|
|
105
|
+
/*
|
|
106
|
+
* Per-key throttle for the lastUsedAt stamp. Deliberately in-process rather
|
|
107
|
+
* than in GlobalCache/Redis (which is how RumApplicationService throttles
|
|
108
|
+
* its equivalent health columns): the cost of getting it wrong here is one
|
|
109
|
+
* extra single-row UPDATE per pod per five minutes, and that is not worth
|
|
110
|
+
* putting a Redis round trip - or a Redis dependency - in front of a
|
|
111
|
+
* bookkeeping write on the ingest path. The ingest path must keep working
|
|
112
|
+
* when Redis is down.
|
|
113
|
+
*/
|
|
114
|
+
private lastUsedWriteThrottle: InMemoryTTLCache<boolean> =
|
|
115
|
+
new InMemoryTTLCache(LAST_USED_THROTTLE_MAX_KEYS);
|
|
116
|
+
|
|
28
117
|
public constructor() {
|
|
29
118
|
super(Model);
|
|
30
119
|
}
|
|
@@ -37,6 +126,69 @@ export class Service extends DatabaseService<Model> {
|
|
|
37
126
|
createBy.data.secretKey = ObjectID.generate();
|
|
38
127
|
}
|
|
39
128
|
|
|
129
|
+
/*
|
|
130
|
+
* The typed model surface (PartialEntity/QueryDeepPartialEntity) widens
|
|
131
|
+
* every property into a union with `() => string` and `null`, which makes
|
|
132
|
+
* reading a value for validation a pile of casts at each site. Read the
|
|
133
|
+
* payload once as an untyped bag instead; every value is checked before it
|
|
134
|
+
* is used, and every value written back is the checked, normalised one.
|
|
135
|
+
*/
|
|
136
|
+
const data: Record<string, unknown> = createBy.data as unknown as Record<
|
|
137
|
+
string,
|
|
138
|
+
unknown
|
|
139
|
+
>;
|
|
140
|
+
|
|
141
|
+
const keyType: TelemetryIngestionKeyType = this.resolveKeyTypeForCreate(
|
|
142
|
+
data["keyType"],
|
|
143
|
+
);
|
|
144
|
+
data["keyType"] = keyType;
|
|
145
|
+
|
|
146
|
+
const allowedOrigins: Array<string> = this.validateAllowedOrigins(
|
|
147
|
+
data["allowedOrigins"],
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
* A Browser key with no origin allowlist is precisely the credential this
|
|
152
|
+
* feature exists to stop shipping: a bearer token sitting in public page
|
|
153
|
+
* source that anyone who views source may write telemetry with. There is
|
|
154
|
+
* no permissive default that would be safe, so it is refused at creation
|
|
155
|
+
* rather than defaulted to one.
|
|
156
|
+
*
|
|
157
|
+
* A Server key keeps the historical behaviour - no origin binding at all,
|
|
158
|
+
* because a collector or a backend process does not send an Origin header
|
|
159
|
+
* in the first place - but its patterns are still validated so that a list
|
|
160
|
+
* typed in "for later" is not quietly full of entries that can never
|
|
161
|
+
* match.
|
|
162
|
+
*/
|
|
163
|
+
if (
|
|
164
|
+
keyType === TelemetryIngestionKeyType.Browser &&
|
|
165
|
+
allowedOrigins.length === 0
|
|
166
|
+
) {
|
|
167
|
+
throw new BadDataException(
|
|
168
|
+
"A Browser ingestion key must list at least one allowed origin. A key that is published in a web page can be copied by anyone who views the source, so the origins it may be used from are the only thing that makes it safe to publish.",
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (Object.prototype.hasOwnProperty.call(data, "allowedOrigins")) {
|
|
173
|
+
data["allowedOrigins"] = allowedOrigins;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(data, "pinnedServiceName")) {
|
|
177
|
+
data["pinnedServiceName"] = this.validatePinnedServiceName(
|
|
178
|
+
data["pinnedServiceName"],
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (Object.prototype.hasOwnProperty.call(data, "requestsPerMinuteLimit")) {
|
|
183
|
+
data["requestsPerMinuteLimit"] = this.validateRequestsPerMinuteLimit(
|
|
184
|
+
data["requestsPerMinuteLimit"],
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (Object.prototype.hasOwnProperty.call(data, "expiresAt")) {
|
|
189
|
+
data["expiresAt"] = this.validateExpiresAt(data["expiresAt"]);
|
|
190
|
+
}
|
|
191
|
+
|
|
40
192
|
return { createBy, carryForward: null };
|
|
41
193
|
}
|
|
42
194
|
|
|
@@ -48,7 +200,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
48
200
|
* We don't know which secretKey(s) are being deleted without an extra
|
|
49
201
|
* query; clear the whole cache. Key deletes are rare so this is cheap.
|
|
50
202
|
*/
|
|
51
|
-
this.
|
|
203
|
+
this.policyCache.clear();
|
|
52
204
|
return { deleteBy, carryForward: null };
|
|
53
205
|
}
|
|
54
206
|
|
|
@@ -56,31 +208,115 @@ export class Service extends DatabaseService<Model> {
|
|
|
56
208
|
protected override async onBeforeUpdate(
|
|
57
209
|
updateBy: UpdateBy<Model>,
|
|
58
210
|
): Promise<OnUpdate<Model>> {
|
|
211
|
+
const data: Record<string, unknown> = updateBy.data as unknown as Record<
|
|
212
|
+
string,
|
|
213
|
+
unknown
|
|
214
|
+
>;
|
|
215
|
+
|
|
216
|
+
/*
|
|
217
|
+
* "Touched" means the property is present in the patch with a value that
|
|
218
|
+
* is not `undefined`. An explicit `null` IS a touch - it is how a cleared
|
|
219
|
+
* form field arrives - and must be validated and normalised like any other
|
|
220
|
+
* value, not skipped as if it were absent.
|
|
221
|
+
*/
|
|
222
|
+
const isTouched: (key: string) => boolean = (key: string): boolean => {
|
|
223
|
+
return (
|
|
224
|
+
Object.prototype.hasOwnProperty.call(data, key) &&
|
|
225
|
+
data[key] !== undefined
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
* Service-layer backstop for the immutability of keyType.
|
|
231
|
+
*
|
|
232
|
+
* @ColumnAccessControl already declares `update: []` on the column, but
|
|
233
|
+
* that is an API-layer control: it stops a dashboard or API caller, not an
|
|
234
|
+
* internal service that reaches for updateOneById directly. Since flipping
|
|
235
|
+
* a live key's type silently changes what a credential already deployed in
|
|
236
|
+
* production is allowed to do - in either direction, and in the
|
|
237
|
+
* Browser -> Server direction it strips the origin binding off a key that
|
|
238
|
+
* is still sitting in a public page - the rule is enforced here too, where
|
|
239
|
+
* every write path passes through and where it can be tested.
|
|
240
|
+
*/
|
|
241
|
+
if (isTouched("keyType")) {
|
|
242
|
+
throw new BadDataException(
|
|
243
|
+
"The key type cannot be changed after the key is created. Create a new ingestion key instead.",
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (isTouched("allowedOrigins")) {
|
|
248
|
+
const allowedOrigins: Array<string> = this.validateAllowedOrigins(
|
|
249
|
+
data["allowedOrigins"],
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
/*
|
|
253
|
+
* Only an EMPTY new list needs to know what kind of keys are being
|
|
254
|
+
* updated, so the extra read is paid for only then. A non-empty list is
|
|
255
|
+
* valid on both key types, and the overwhelmingly common update (rename,
|
|
256
|
+
* toggle isEnabled, set an expiry) does not touch allowedOrigins at all
|
|
257
|
+
* and therefore reads nothing extra.
|
|
258
|
+
*/
|
|
259
|
+
if (allowedOrigins.length === 0) {
|
|
260
|
+
await this.assertNoBrowserKeyIsBeingUpdated(updateBy);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
data["allowedOrigins"] = allowedOrigins;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (isTouched("pinnedServiceName")) {
|
|
267
|
+
data["pinnedServiceName"] = this.validatePinnedServiceName(
|
|
268
|
+
data["pinnedServiceName"],
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (isTouched("requestsPerMinuteLimit")) {
|
|
273
|
+
data["requestsPerMinuteLimit"] = this.validateRequestsPerMinuteLimit(
|
|
274
|
+
data["requestsPerMinuteLimit"],
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (isTouched("expiresAt")) {
|
|
279
|
+
data["expiresAt"] = this.validateExpiresAt(data["expiresAt"]);
|
|
280
|
+
}
|
|
281
|
+
|
|
59
282
|
/*
|
|
60
|
-
* Same reasoning as onBeforeDelete.
|
|
61
|
-
*
|
|
283
|
+
* Same reasoning as onBeforeDelete. The cached policy now carries the kill
|
|
284
|
+
* switch, the expiry, the origin allowlist and the rate limit, so almost
|
|
285
|
+
* any edit to this table invalidates it - clearing wholesale stays the
|
|
286
|
+
* right call, and doing it after validation avoids churning the cache for
|
|
287
|
+
* an update that is about to be rejected.
|
|
62
288
|
*/
|
|
63
|
-
this.
|
|
289
|
+
this.policyCache.clear();
|
|
64
290
|
return { updateBy, carryForward: null };
|
|
65
291
|
}
|
|
66
292
|
|
|
67
293
|
/**
|
|
68
|
-
* Resolve an ingestion token to
|
|
69
|
-
* in-process cache to keep the hot ingest path off
|
|
70
|
-
* for unknown
|
|
71
|
-
* TTL).
|
|
294
|
+
* Resolve an ingestion token to the full policy the ingest guards need,
|
|
295
|
+
* with a short-lived in-process cache to keep the hot ingest path off
|
|
296
|
+
* Postgres. Returns null for unknown or malformed tokens (also cached, for a
|
|
297
|
+
* shorter TTL).
|
|
298
|
+
*
|
|
299
|
+
* A returned policy is NOT a decision: a disabled or expired key still
|
|
300
|
+
* resolves. Enforcement belongs to the caller, which knows which ingest
|
|
301
|
+
* surface it is and can therefore say *why* a request was refused.
|
|
72
302
|
*/
|
|
73
303
|
@CaptureSpan()
|
|
74
|
-
public async
|
|
304
|
+
public async getPolicyFromSecretKey(
|
|
75
305
|
secretKey: string,
|
|
76
|
-
): Promise<
|
|
306
|
+
): Promise<TelemetryIngestionKeyPolicy | null> {
|
|
307
|
+
/*
|
|
308
|
+
* The cache is keyed on a hash of the token, never the token itself. An
|
|
309
|
+
* in-memory map is dumped by a heap snapshot, a core file or a debugger,
|
|
310
|
+
* and a live ingestion secret is not something to leave lying in one.
|
|
311
|
+
*/
|
|
77
312
|
const cacheKey: string = createHash("sha256")
|
|
78
313
|
.update(secretKey)
|
|
79
314
|
.digest("hex");
|
|
80
315
|
|
|
81
|
-
const cached:
|
|
316
|
+
const cached: CachedIngestionKeyPolicy | null | undefined =
|
|
317
|
+
this.policyCache.get(cacheKey);
|
|
82
318
|
if (cached !== undefined) {
|
|
83
|
-
return cached === null ? null :
|
|
319
|
+
return cached === null ? null : this.hydratePolicy(cached);
|
|
84
320
|
}
|
|
85
321
|
|
|
86
322
|
let secretKeyObjectId: ObjectID;
|
|
@@ -88,13 +324,22 @@ export class Service extends DatabaseService<Model> {
|
|
|
88
324
|
ObjectID.validateUUID(secretKey);
|
|
89
325
|
secretKeyObjectId = new ObjectID(secretKey);
|
|
90
326
|
} catch {
|
|
91
|
-
this.
|
|
327
|
+
this.policyCache.set(cacheKey, null, NEGATIVE_TTL_MS);
|
|
92
328
|
return null;
|
|
93
329
|
}
|
|
94
330
|
|
|
95
331
|
const token: Model | null = await this.findOneBy({
|
|
96
332
|
query: { secretKey: secretKeyObjectId },
|
|
97
|
-
select: {
|
|
333
|
+
select: {
|
|
334
|
+
_id: true,
|
|
335
|
+
projectId: true,
|
|
336
|
+
keyType: true,
|
|
337
|
+
allowedOrigins: true,
|
|
338
|
+
pinnedServiceName: true,
|
|
339
|
+
isEnabled: true,
|
|
340
|
+
expiresAt: true,
|
|
341
|
+
requestsPerMinuteLimit: true,
|
|
342
|
+
},
|
|
98
343
|
props: { isRoot: true },
|
|
99
344
|
});
|
|
100
345
|
|
|
@@ -102,13 +347,471 @@ export class Service extends DatabaseService<Model> {
|
|
|
102
347
|
| ObjectID
|
|
103
348
|
| undefined;
|
|
104
349
|
|
|
105
|
-
if (!projectId) {
|
|
106
|
-
this.
|
|
350
|
+
if (!token || !projectId) {
|
|
351
|
+
this.policyCache.set(cacheKey, null, NEGATIVE_TTL_MS);
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const snapshot: CachedIngestionKeyPolicy = this.toCachedPolicy(
|
|
356
|
+
token,
|
|
357
|
+
projectId,
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
this.policyCache.set(cacheKey, snapshot, POSITIVE_TTL_MS);
|
|
361
|
+
return this.hydratePolicy(snapshot);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Resolve an ingestion token to its projectId.
|
|
366
|
+
*
|
|
367
|
+
* Unchanged in signature and in meaning: it is a LOOKUP, and it answers
|
|
368
|
+
* "which project owns this token" for any token that exists. It deliberately
|
|
369
|
+
* does NOT enforce the kill switch or the expiry.
|
|
370
|
+
*
|
|
371
|
+
* That restraint is the point. Several callers (gRPC, MQTT, session replay,
|
|
372
|
+
* OTLP) use this to decide whether a connection is authenticated at all, and
|
|
373
|
+
* each of them refuses disabled/expired keys explicitly, with a message that
|
|
374
|
+
* names the surface. Quietly folding those checks into a method whose name
|
|
375
|
+
* promises only a lookup would make "key not found" and "key switched off"
|
|
376
|
+
* indistinguishable in every one of those call sites - and would change the
|
|
377
|
+
* behaviour of any caller that has not been updated yet.
|
|
378
|
+
*/
|
|
379
|
+
@CaptureSpan()
|
|
380
|
+
public async getProjectIdFromSecretKey(
|
|
381
|
+
secretKey: string,
|
|
382
|
+
): Promise<ObjectID | null> {
|
|
383
|
+
const policy: TelemetryIngestionKeyPolicy | null =
|
|
384
|
+
await this.getPolicyFromSecretKey(secretKey);
|
|
385
|
+
|
|
386
|
+
if (!policy) {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return policy.projectId;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Record that this key was just used, at most once per key per
|
|
395
|
+
* LAST_USED_THROTTLE_MS per process.
|
|
396
|
+
*
|
|
397
|
+
* Fire-and-forget in the strongest sense: it swallows every error it can
|
|
398
|
+
* produce. A failure to write a bookkeeping timestamp must never be able to
|
|
399
|
+
* reject telemetry that was otherwise accepted - dropped spans are not
|
|
400
|
+
* replayed, so turning "the UPDATE failed" into "the customer lost data" is
|
|
401
|
+
* the worst possible trade for a column that exists to help with key
|
|
402
|
+
* rotation hygiene.
|
|
403
|
+
*
|
|
404
|
+
* Modelled on RumApplicationService.markSessionReplayChunkReceived, with the
|
|
405
|
+
* same three properties: throttled, hook-free, and updatedAt-preserving.
|
|
406
|
+
*/
|
|
407
|
+
@CaptureSpan()
|
|
408
|
+
public async markUsed(ingestionKeyId: ObjectID): Promise<void> {
|
|
409
|
+
if (!ingestionKeyId) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const throttleKey: string = ingestionKeyId.toString();
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
if (this.lastUsedWriteThrottle.get(throttleKey) !== undefined) {
|
|
417
|
+
return; // written recently by this process
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/*
|
|
421
|
+
* Claim the throttle slot BEFORE the write, not after. Ingest is
|
|
422
|
+
* concurrent, so a dozen requests for the same key can be in this method
|
|
423
|
+
* at once; claiming first means they collapse to one UPDATE instead of a
|
|
424
|
+
* dozen. If the write then fails, the cost is a missing stamp for five
|
|
425
|
+
* minutes, which is exactly the resolution this column has anyway.
|
|
426
|
+
*/
|
|
427
|
+
this.lastUsedWriteThrottle.set(throttleKey, true, LAST_USED_THROTTLE_MS);
|
|
428
|
+
|
|
429
|
+
/*
|
|
430
|
+
* Hook-free single-statement UPDATE:
|
|
431
|
+
*
|
|
432
|
+
* - no hooks, so this does not clear the policy cache. That is
|
|
433
|
+
* deliberate: lastUsedAt is not part of the policy, and invalidating
|
|
434
|
+
* every cached key every five minutes because of a passive stamp
|
|
435
|
+
* would send the ingest path back to Postgres for nothing.
|
|
436
|
+
* - skipUpdateDateColumn, so a liveness stamp does not masquerade as a
|
|
437
|
+
* configuration change to anything watching updatedAt.
|
|
438
|
+
*/
|
|
439
|
+
await this.updateColumnsByIdWithoutHooks({
|
|
440
|
+
id: ingestionKeyId,
|
|
441
|
+
data: {
|
|
442
|
+
lastUsedAt: OneUptimeDate.getCurrentDate(),
|
|
443
|
+
},
|
|
444
|
+
skipUpdateDateColumn: true,
|
|
445
|
+
});
|
|
446
|
+
} catch (err) {
|
|
447
|
+
logger.warn(
|
|
448
|
+
`TelemetryIngestionKeyService: could not stamp lastUsedAt for ingestion key ${throttleKey}`,
|
|
449
|
+
);
|
|
450
|
+
logger.warn(err);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/*
|
|
455
|
+
* Build the cacheable snapshot from a row.
|
|
456
|
+
*
|
|
457
|
+
* Every field is normalised here rather than at the point of use, so there
|
|
458
|
+
* is exactly one place that decides what a missing or malformed column
|
|
459
|
+
* means, and so the ingest guards can be written against a total type
|
|
460
|
+
* instead of a pile of optionals.
|
|
461
|
+
*/
|
|
462
|
+
private toCachedPolicy(
|
|
463
|
+
token: Model,
|
|
464
|
+
projectId: ObjectID,
|
|
465
|
+
): CachedIngestionKeyPolicy {
|
|
466
|
+
/*
|
|
467
|
+
* THE BACKWARDS-COMPATIBILITY HINGE.
|
|
468
|
+
*
|
|
469
|
+
* Every TelemetryIngestionKey that exists today was written before the
|
|
470
|
+
* keyType column did, so it reads back as NULL (or, on a node whose model
|
|
471
|
+
* metadata is momentarily behind a rolling deploy, as absent). Anything
|
|
472
|
+
* that is not exactly "Browser" resolves to Server, which is the
|
|
473
|
+
* historical behaviour in full: no origin checks, every ingest surface, no
|
|
474
|
+
* default rate limit, no pinned service name.
|
|
475
|
+
*
|
|
476
|
+
* Written as an allowlist of the ONE restrictive value rather than a
|
|
477
|
+
* lookup that falls back on failure, so that a typo, a truncated column, a
|
|
478
|
+
* partially applied migration or a hand-edited row can never accidentally
|
|
479
|
+
* relax a Browser key into a Server key. The failure direction here is
|
|
480
|
+
* always towards "behaves like it always did", never towards "quietly
|
|
481
|
+
* gained privileges".
|
|
482
|
+
*/
|
|
483
|
+
const keyType: TelemetryIngestionKeyType =
|
|
484
|
+
token.keyType === TelemetryIngestionKeyType.Browser
|
|
485
|
+
? TelemetryIngestionKeyType.Browser
|
|
486
|
+
: TelemetryIngestionKeyType.Server;
|
|
487
|
+
|
|
488
|
+
/*
|
|
489
|
+
* Blank entries are dropped, not just non-strings. OriginAllowList.matches
|
|
490
|
+
* skips a blank pattern, so a list of [""] would match nothing while still
|
|
491
|
+
* being non-empty - and "non-empty" is what the ingest guard checks before
|
|
492
|
+
* it decides a Browser key is configured at all. Dropping blanks here
|
|
493
|
+
* makes those two agree: a non-empty list always contains at least one
|
|
494
|
+
* pattern that can actually match.
|
|
495
|
+
*/
|
|
496
|
+
const rawAllowedOrigins: unknown = token.allowedOrigins;
|
|
497
|
+
const allowedOrigins: Array<string> = Array.isArray(rawAllowedOrigins)
|
|
498
|
+
? (rawAllowedOrigins as Array<unknown>)
|
|
499
|
+
.filter((entry: unknown): boolean => {
|
|
500
|
+
return typeof entry === "string" && entry.trim().length > 0;
|
|
501
|
+
})
|
|
502
|
+
.map((entry: unknown): string => {
|
|
503
|
+
return entry as string;
|
|
504
|
+
})
|
|
505
|
+
: [];
|
|
506
|
+
|
|
507
|
+
const rawPinnedServiceName: unknown = token.pinnedServiceName;
|
|
508
|
+
const pinnedServiceName: string | null =
|
|
509
|
+
typeof rawPinnedServiceName === "string" &&
|
|
510
|
+
rawPinnedServiceName.trim().length > 0
|
|
511
|
+
? rawPinnedServiceName.trim()
|
|
512
|
+
: null;
|
|
513
|
+
|
|
514
|
+
/*
|
|
515
|
+
* Only an explicit `false` disables a key. A row that predates the column
|
|
516
|
+
* reads back NULL and must stay enabled - the alternative would take every
|
|
517
|
+
* existing installation's telemetry offline the moment this ships, which
|
|
518
|
+
* is the one outcome this whole change is not allowed to have.
|
|
519
|
+
*/
|
|
520
|
+
const isEnabled: boolean = token.isEnabled !== false;
|
|
521
|
+
|
|
522
|
+
/*
|
|
523
|
+
* A value that will not parse is treated as "no expiry" rather than "expired".
|
|
524
|
+
* It cannot arise from a TIMESTAMPTZ column, so the only way to get here is
|
|
525
|
+
* a corrupt or hand-written row, and refusing a customer's live telemetry
|
|
526
|
+
* because a date column is unreadable is a worse failure than honouring the
|
|
527
|
+
* historical never-expires behaviour.
|
|
528
|
+
*/
|
|
529
|
+
let expiresAtIso: string | null = null;
|
|
530
|
+
if (token.expiresAt) {
|
|
531
|
+
const expiresAt: Date = OneUptimeDate.fromString(token.expiresAt);
|
|
532
|
+
if (expiresAt instanceof Date && !Number.isNaN(expiresAt.getTime())) {
|
|
533
|
+
expiresAtIso = expiresAt.toISOString();
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/*
|
|
538
|
+
* 0, a negative number or garbage all resolve to null - "no explicit limit
|
|
539
|
+
* configured" - not to "block everything". Neither can be written through
|
|
540
|
+
* this service (create/update reject them), so reaching here means a
|
|
541
|
+
* legacy or hand-edited row, and reading such a row as a total block would
|
|
542
|
+
* silently black out a customer's ingest. Null instead means a Browser key
|
|
543
|
+
* falls back to the shipped default and a Server key stays unlimited,
|
|
544
|
+
* which is what the column's own documentation promises.
|
|
545
|
+
*/
|
|
546
|
+
const rawRequestsPerMinuteLimit: unknown = token.requestsPerMinuteLimit;
|
|
547
|
+
const requestsPerMinuteLimit: number | null =
|
|
548
|
+
typeof rawRequestsPerMinuteLimit === "number" &&
|
|
549
|
+
Number.isFinite(rawRequestsPerMinuteLimit) &&
|
|
550
|
+
rawRequestsPerMinuteLimit > 0
|
|
551
|
+
? Math.floor(rawRequestsPerMinuteLimit)
|
|
552
|
+
: null;
|
|
553
|
+
|
|
554
|
+
/*
|
|
555
|
+
* `_id` is the primary key and is always selected, so a row without one
|
|
556
|
+
* cannot come back from a real query. The resolver still has to be total,
|
|
557
|
+
* though, and returning null for a row that plainly exists would turn a
|
|
558
|
+
* shape surprise into a complete ingest outage for that key. Falling back
|
|
559
|
+
* to the zero id keeps the key working and degrades only the two things
|
|
560
|
+
* that are keyed on the id: the rate-limit bucket (which would be shared)
|
|
561
|
+
* and the lastUsedAt stamp (whose UPDATE would match no row). Neither is a
|
|
562
|
+
* security control - the kill switch, the expiry and the origin allowlist
|
|
563
|
+
* all come from the row's own columns.
|
|
564
|
+
*/
|
|
565
|
+
const ingestionKeyId: string = token._id
|
|
566
|
+
? token._id.toString()
|
|
567
|
+
: ObjectID.getZeroObjectID().toString();
|
|
568
|
+
|
|
569
|
+
return {
|
|
570
|
+
ingestionKeyId: ingestionKeyId,
|
|
571
|
+
projectId: projectId.toString(),
|
|
572
|
+
keyType: keyType,
|
|
573
|
+
allowedOrigins: allowedOrigins,
|
|
574
|
+
pinnedServiceName: pinnedServiceName,
|
|
575
|
+
isEnabled: isEnabled,
|
|
576
|
+
expiresAtIso: expiresAtIso,
|
|
577
|
+
requestsPerMinuteLimit: requestsPerMinuteLimit,
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/*
|
|
582
|
+
* Rebuild a live policy from a snapshot. The array is copied and the
|
|
583
|
+
* ObjectIDs/Date are reconstructed so that a caller holding a policy cannot
|
|
584
|
+
* reach back into the cache and mutate what every other request on this pod
|
|
585
|
+
* will see for the rest of the TTL.
|
|
586
|
+
*/
|
|
587
|
+
private hydratePolicy(
|
|
588
|
+
cached: CachedIngestionKeyPolicy,
|
|
589
|
+
): TelemetryIngestionKeyPolicy {
|
|
590
|
+
return {
|
|
591
|
+
ingestionKeyId: new ObjectID(cached.ingestionKeyId),
|
|
592
|
+
projectId: new ObjectID(cached.projectId),
|
|
593
|
+
keyType: cached.keyType,
|
|
594
|
+
allowedOrigins: [...cached.allowedOrigins],
|
|
595
|
+
pinnedServiceName: cached.pinnedServiceName,
|
|
596
|
+
isEnabled: cached.isEnabled,
|
|
597
|
+
expiresAt: cached.expiresAtIso ? new Date(cached.expiresAtIso) : null,
|
|
598
|
+
requestsPerMinuteLimit: cached.requestsPerMinuteLimit,
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/*
|
|
603
|
+
* Unlike the read path - which forgives anything, because an existing row
|
|
604
|
+
* must keep working - the write path is strict. A key type it does not
|
|
605
|
+
* recognise is refused rather than silently coerced to Server, because
|
|
606
|
+
* "I asked for a Browser key and got a Server key" is a security surprise,
|
|
607
|
+
* not a typo the system should paper over.
|
|
608
|
+
*/
|
|
609
|
+
private resolveKeyTypeForCreate(value: unknown): TelemetryIngestionKeyType {
|
|
610
|
+
if (value === undefined || value === null || value === "") {
|
|
611
|
+
return TelemetryIngestionKeyType.Server;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
if (value === TelemetryIngestionKeyType.Browser) {
|
|
615
|
+
return TelemetryIngestionKeyType.Browser;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (value === TelemetryIngestionKeyType.Server) {
|
|
619
|
+
return TelemetryIngestionKeyType.Server;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
throw new BadDataException(
|
|
623
|
+
`"${String(value)}" is not a valid ingestion key type. Use "${
|
|
624
|
+
TelemetryIngestionKeyType.Server
|
|
625
|
+
}" or "${TelemetryIngestionKeyType.Browser}".`,
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/*
|
|
630
|
+
* Validate and canonicalise an allowlist.
|
|
631
|
+
*
|
|
632
|
+
* Entries are stored in the same normalised form the matcher compares
|
|
633
|
+
* against (trimmed, lowercased, no trailing slash) and exact duplicates are
|
|
634
|
+
* collapsed, so what the customer sees listed in the dashboard is exactly
|
|
635
|
+
* what will be matched at ingest time. An origin's scheme and host are
|
|
636
|
+
* case-insensitive, so lowercasing changes nothing about what the entry
|
|
637
|
+
* means - it only removes a class of "why doesn't this match?" support
|
|
638
|
+
* question that has no visible cause.
|
|
639
|
+
*/
|
|
640
|
+
private validateAllowedOrigins(value: unknown): Array<string> {
|
|
641
|
+
if (value === undefined || value === null) {
|
|
642
|
+
return [];
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (!Array.isArray(value)) {
|
|
646
|
+
throw new BadDataException(
|
|
647
|
+
'Allowed origins must be a list of origins, for example ["https://app.example.com"].',
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
const normalized: Array<string> = [];
|
|
652
|
+
const seen: Set<string> = new Set();
|
|
653
|
+
|
|
654
|
+
for (const entry of value as Array<unknown>) {
|
|
655
|
+
if (typeof entry !== "string") {
|
|
656
|
+
throw new BadDataException(
|
|
657
|
+
"Every allowed origin must be text, with one origin per entry.",
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (!entry.trim()) {
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
const validationError: string | null =
|
|
666
|
+
OriginAllowList.validateOriginPattern(entry);
|
|
667
|
+
|
|
668
|
+
if (validationError) {
|
|
669
|
+
throw new BadDataException(validationError);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const canonical: string = OriginAllowList.normalizeOrigin(entry);
|
|
673
|
+
|
|
674
|
+
if (seen.has(canonical)) {
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
seen.add(canonical);
|
|
679
|
+
normalized.push(canonical);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
return normalized;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/*
|
|
686
|
+
* Blank means "clear it", not "reject it". An emptied text field arrives as
|
|
687
|
+
* "" or null, and refusing that would leave a customer who pinned a service
|
|
688
|
+
* name unable to ever unpin it through the dashboard. Anything non-blank has
|
|
689
|
+
* to fit the column, since a silently truncated service name would pin
|
|
690
|
+
* telemetry to a name that matches nothing the customer expects.
|
|
691
|
+
*/
|
|
692
|
+
private validatePinnedServiceName(value: unknown): string | null {
|
|
693
|
+
if (value === undefined || value === null) {
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
if (typeof value !== "string") {
|
|
698
|
+
throw new BadDataException("The pinned service name must be text.");
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
const trimmed: string = value.trim();
|
|
702
|
+
|
|
703
|
+
if (!trimmed) {
|
|
107
704
|
return null;
|
|
108
705
|
}
|
|
109
706
|
|
|
110
|
-
|
|
111
|
-
|
|
707
|
+
if (trimmed.length > ColumnLength.ShortText) {
|
|
708
|
+
throw new BadDataException(
|
|
709
|
+
`The pinned service name cannot be longer than ${ColumnLength.ShortText} characters.`,
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
return trimmed;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
private validateRequestsPerMinuteLimit(value: unknown): number | null {
|
|
717
|
+
if (value === undefined || value === null || value === "") {
|
|
718
|
+
return null;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
const limit: number = typeof value === "number" ? value : Number(value);
|
|
722
|
+
|
|
723
|
+
if (!Number.isFinite(limit) || !Number.isInteger(limit) || limit <= 0) {
|
|
724
|
+
throw new BadDataException(
|
|
725
|
+
"The requests per minute limit must be a whole number greater than 0. Leave it empty to use the default for the key type.",
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
if (limit > MAX_REQUESTS_PER_MINUTE_LIMIT) {
|
|
730
|
+
throw new BadDataException(
|
|
731
|
+
`The requests per minute limit cannot be greater than ${MAX_REQUESTS_PER_MINUTE_LIMIT}.`,
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
return limit;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
private validateExpiresAt(value: unknown): Date | null {
|
|
739
|
+
if (value === undefined || value === null || value === "") {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
let expiresAt: Date;
|
|
744
|
+
|
|
745
|
+
try {
|
|
746
|
+
expiresAt = OneUptimeDate.fromString(value as string | Date);
|
|
747
|
+
} catch {
|
|
748
|
+
throw new BadDataException("The expiry date is not a valid date.");
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
if (!(expiresAt instanceof Date) || Number.isNaN(expiresAt.getTime())) {
|
|
752
|
+
throw new BadDataException("The expiry date is not a valid date.");
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/*
|
|
756
|
+
* Refused rather than accepted-and-immediately-dead. Saving an expiry in
|
|
757
|
+
* the past silently bricks the key, and the symptom - telemetry stops
|
|
758
|
+
* arriving, with a key that still looks fine in the list - is exactly the
|
|
759
|
+
* kind of failure that costs an afternoon to diagnose.
|
|
760
|
+
*/
|
|
761
|
+
if (!OneUptimeDate.isInTheFuture(expiresAt)) {
|
|
762
|
+
throw new BadDataException(
|
|
763
|
+
"The expiry date must be in the future. A key that expires in the past would stop accepting telemetry as soon as it is saved.",
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
return expiresAt;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/*
|
|
771
|
+
* Refuse to empty the allowlist when any row the update matches is a Browser
|
|
772
|
+
* key.
|
|
773
|
+
*
|
|
774
|
+
* The database cannot express "non-empty only when keyType is Browser", and
|
|
775
|
+
* an update patch does not carry the key type (it cannot - keyType is
|
|
776
|
+
* immutable and therefore never in the patch), so the affected rows have to
|
|
777
|
+
* be read. Only _id and keyType are selected; nothing here needs anything
|
|
778
|
+
* else.
|
|
779
|
+
*
|
|
780
|
+
* The read runs as root because it is a policy check, not a data return: it
|
|
781
|
+
* must see every row the update will actually touch, including ones the
|
|
782
|
+
* caller could not read. The caller's tenant is still applied when the query
|
|
783
|
+
* does not name a project itself, so a broad query cannot be tricked into
|
|
784
|
+
* failing this check because of some other project's key.
|
|
785
|
+
*/
|
|
786
|
+
private async assertNoBrowserKeyIsBeingUpdated(
|
|
787
|
+
updateBy: UpdateBy<Model>,
|
|
788
|
+
): Promise<void> {
|
|
789
|
+
const query: Query<Model> = { ...updateBy.query };
|
|
790
|
+
|
|
791
|
+
if (!query.projectId && updateBy.props.tenantId) {
|
|
792
|
+
query.projectId = updateBy.props.tenantId;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const affectedKeys: Array<Model> = await this.findBy({
|
|
796
|
+
query: query,
|
|
797
|
+
select: {
|
|
798
|
+
_id: true,
|
|
799
|
+
keyType: true,
|
|
800
|
+
},
|
|
801
|
+
props: {
|
|
802
|
+
isRoot: true,
|
|
803
|
+
},
|
|
804
|
+
skip: 0,
|
|
805
|
+
limit: LIMIT_PER_PROJECT,
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
for (const affectedKey of affectedKeys) {
|
|
809
|
+
if (affectedKey.keyType === TelemetryIngestionKeyType.Browser) {
|
|
810
|
+
throw new BadDataException(
|
|
811
|
+
`A Browser ingestion key must keep at least one allowed origin. Clearing the list would stop the key accepting any telemetry - turn the key off or delete it instead. (Key ID: ${affectedKey._id})`,
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
112
815
|
}
|
|
113
816
|
}
|
|
114
817
|
|