@oneuptime/common 12.0.33 → 12.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/RumSession.ts +117 -1
- package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
- package/Models/DatabaseModels/AlertCustomField.ts +77 -3
- package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
- package/Models/DatabaseModels/RumApplication.ts +6 -6
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
- package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamMember.ts +0 -9
- package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamPermission.ts +3 -24
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
- package/Models/DatabaseModels/UserTelegram.ts +0 -4
- package/Scripts/benchmark-fanin-capacity.js +181 -0
- package/Server/API/TelemetryAPI.ts +1284 -164
- package/Server/API/UserNotificationSettingAPI.ts +55 -0
- package/Server/API/UserTelegramAPI.ts +48 -4
- package/Server/EnvironmentConfig.ts +35 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/QueueWorker.ts +20 -14
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Middleware/TelemetryIngest.ts +453 -7
- package/Server/Services/AccessTokenService.ts +1 -0
- package/Server/Services/AlertCustomFieldService.ts +98 -0
- package/Server/Services/AlertService.ts +37 -0
- package/Server/Services/ApiKeyPermissionService.ts +461 -29
- package/Server/Services/CustomFieldMappingService.ts +879 -0
- package/Server/Services/GlobalConfigService.ts +194 -0
- package/Server/Services/IncidentCustomFieldService.ts +98 -0
- package/Server/Services/IncidentService.ts +35 -0
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +32 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
- package/Server/Services/ProjectService.ts +22 -0
- package/Server/Services/RoutineEmailSettingsService.ts +73 -0
- package/Server/Services/RumSessionReplayViewService.ts +104 -24
- package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
- package/Server/Services/ScheduledMaintenanceService.ts +32 -0
- package/Server/Services/TeamMemberService.ts +78 -0
- package/Server/Services/TeamPermissionService.ts +235 -3
- package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
- package/Server/Services/UserNotificationSettingService.ts +34 -6
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/QueryHelper.ts +2 -0
- package/Server/Utils/APIKey/AccessPermission.ts +5 -2
- package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
- package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
- package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
- package/Server/Utils/DataSource/EgressGuard.ts +177 -8
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
- package/Server/Utils/FrontendEnvironment.ts +40 -0
- package/Server/Utils/LogRedaction.ts +20 -0
- package/Server/Utils/Logger.ts +11 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
- package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
- package/Server/Utils/SSRFProtection.ts +217 -10
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
- package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
- package/Server/Utils/StartServer.ts +2 -17
- package/Server/Utils/TelegramVerificationToken.ts +185 -0
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
- package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +975 -95
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
- package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
- package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
- package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
- package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
- package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
- package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
- package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
- package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
- package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
- package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
- package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
- package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
- package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
- package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
- package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
- package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
- package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
- package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
- package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
- package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
- package/Tests/Types/JSONFunctions.test.ts +260 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
- package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
- package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
- package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
- package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
- package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
- package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
- package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
- package/Tests/Types/WebsiteRequest.test.ts +285 -3
- package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
- package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
- package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
- package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
- package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
- package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
- package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
- package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
- package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
- package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
- package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
- package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
- package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
- package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
- package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
- package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
- package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
- package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
- package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
- package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
- package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
- package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
- package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
- package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
- package/Tests/Utils/ValueFormatter.test.ts +148 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSONFunctions.ts +189 -43
- package/Types/Monitor/CephAlertTemplates.ts +157 -195
- package/Types/Monitor/DockerAlertTemplates.ts +338 -128
- package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
- package/Types/Monitor/HostAlertTemplates.ts +302 -130
- package/Types/Monitor/IotAlertTemplates.ts +112 -104
- package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
- package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
- package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
- package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
- package/Types/Monitor/RumAlertTemplates.ts +46 -7
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
- package/Types/Rum/SessionReplay.ts +209 -0
- package/Types/Rum/SessionReplayApi.ts +722 -0
- package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
- package/Types/Rum/SessionReplayConsentMode.ts +11 -7
- package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
- package/Types/Rum/SessionReplayHealth.ts +238 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
- package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
- package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
- package/Types/WebsiteRequest.ts +85 -3
- package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
- package/UI/Components/Charts/Line/LineChart.tsx +13 -2
- package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
- package/UI/Components/Charts/Utils/XAxis.ts +217 -0
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
- package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
- package/UI/Components/Header/Header.tsx +25 -9
- package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
- package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
- package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
- package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
- package/UI/Components/Icon/Icon.tsx +11 -0
- package/UI/Components/JSONTable/JSONTable.tsx +2 -2
- package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
- package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
- package/UI/Components/ModelTable/Column.ts +15 -0
- package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
- package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
- package/UI/Components/Table/CellClassName.ts +81 -0
- package/UI/Components/Table/TableRow.tsx +20 -14
- package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
- package/UI/Components/Table/Types/Column.ts +36 -0
- package/UI/Components/Tooltip/Tooltip.tsx +11 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
- package/UI/Components/Workflow/NodePlacement.ts +57 -0
- package/UI/Components/Workflow/Workflow.tsx +47 -18
- package/UI/Config.ts +15 -33
- package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
- package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
- package/UI/Utils/Telemetry/Telemetry.ts +10 -8
- package/Utils/API.ts +129 -3
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
- package/Utils/Rum/ChunkMath.ts +106 -0
- package/Utils/Rum/SessionReplayHealth.ts +732 -0
- package/Utils/Rum/SessionReplayStringMap.ts +226 -0
- package/Utils/Schema/ModelSchema.ts +1 -0
- package/Utils/StatusPage/ResourceSearch.ts +290 -0
- package/Utils/Telemetry/OriginAllowList.ts +355 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
- package/Utils/ValueFormatter.ts +35 -1
- package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
- package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
- package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +769 -109
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
- package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
- package/build/dist/Server/API/UserTelegramAPI.js +28 -6
- package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +29 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +1 -0
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
- package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +34 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
- package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
- package/build/dist/Server/Services/GlobalConfigService.js +133 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +32 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +163 -0
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +29 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
- package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
- package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
- package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +62 -2
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +166 -3
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +257 -4
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +20 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +10 -0
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
- package/build/dist/Server/Utils/SSRFProtection.js +136 -9
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +3 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
- package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +118 -37
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
- package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
- package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
- package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
- package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +117 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
- package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Types/WebsiteRequest.js +55 -3
- package/build/dist/Types/WebsiteRequest.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
- package/build/dist/UI/Components/Header/Header.js +2 -3
- package/build/dist/UI/Components/Header/Header.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +5 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
- package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
- package/build/dist/UI/Components/Table/CellClassName.js +55 -0
- package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
- package/build/dist/UI/Components/Table/TableRow.js +16 -13
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
- package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Config.js +10 -20
- package/build/dist/UI/Config.js.map +1 -1
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
- package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Utils/API.js +67 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
- package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
- package/build/dist/Utils/Rum/ChunkMath.js +76 -0
- package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
- package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
- package/build/dist/Utils/ValueFormatter.js +32 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Origin allowlist matching and validation, shared by every surface that has
|
|
3
|
+
* to decide "is this browser allowed to write into this project?".
|
|
4
|
+
*
|
|
5
|
+
* This module is deliberately PURE and isomorphic - no server imports, no
|
|
6
|
+
* Redis, no models - because the same rules have to hold in three places that
|
|
7
|
+
* cannot share a runtime:
|
|
8
|
+
*
|
|
9
|
+
* 1. the ingest path, where a forged request is rejected,
|
|
10
|
+
* 2. the Dashboard form, where a customer types a pattern and must be told
|
|
11
|
+
* immediately that it will never match anything,
|
|
12
|
+
* 3. tests, which need to pin the semantics without booting a server.
|
|
13
|
+
*
|
|
14
|
+
* The matching half is NOT new behaviour. It is lifted verbatim from
|
|
15
|
+
* SessionReplayGateCache.isOriginAllowed, which now delegates here, so the
|
|
16
|
+
* two surfaces cannot drift apart - a browser ingestion key that accepts an
|
|
17
|
+
* origin the session-replay gate refuses (or the reverse) would be a
|
|
18
|
+
* confusing and exploitable split.
|
|
19
|
+
*
|
|
20
|
+
* ONE THING IS DELIBERATELY NOT IN HERE: the "empty allowlist means what?"
|
|
21
|
+
* decision. `matches` answers false for an empty list and lets the caller
|
|
22
|
+
* decide, because the two callers need OPPOSITE defaults and encoding either
|
|
23
|
+
* one here would silently break the other:
|
|
24
|
+
*
|
|
25
|
+
* - session replay ships with an empty allowlist and treats it as "any
|
|
26
|
+
* origin", so that the feature works the moment a customer pastes the
|
|
27
|
+
* snippet (see the long comment in SessionReplayGateCache);
|
|
28
|
+
* - a Browser telemetry ingestion key REQUIRES a non-empty allowlist and
|
|
29
|
+
* treats empty as "nothing is allowed", because a public key with no
|
|
30
|
+
* origin binding is exactly the credential we are trying to stop
|
|
31
|
+
* shipping.
|
|
32
|
+
*/
|
|
33
|
+
/*
|
|
34
|
+
* Hoisted rather than written inline at each call site: none carries the `g`
|
|
35
|
+
* flag, so `.test` is stateless and one compiled instance is safe to share,
|
|
36
|
+
* and a named constant reads better at the branch than a bare literal.
|
|
37
|
+
*/
|
|
38
|
+
const WHITESPACE_ANYWHERE: RegExp = /\s/;
|
|
39
|
+
const DIGITS_ONLY: RegExp = /^[0-9]+$/;
|
|
40
|
+
const HOST_LABEL_CHARACTERS: RegExp = /^[a-z0-9-]+$/;
|
|
41
|
+
|
|
42
|
+
export default class OriginAllowList {
|
|
43
|
+
/*
|
|
44
|
+
* Canonical form for comparison: trimmed, lowercased, with trailing
|
|
45
|
+
* slashes removed.
|
|
46
|
+
*
|
|
47
|
+
* The trailing-slash strip is here because browsers and hand-written config
|
|
48
|
+
* disagree about it. `window.location.origin` and the `Origin` request
|
|
49
|
+
* header never carry one, but a customer copying a URL out of the address
|
|
50
|
+
* bar almost always pastes "https://app.example.com/". Treating those as
|
|
51
|
+
* different origins produces a silent, total ingest failure whose only
|
|
52
|
+
* symptom is a missing character, which is a miserable thing to debug.
|
|
53
|
+
*
|
|
54
|
+
* All trailing slashes are stripped rather than exactly one: "https://x//"
|
|
55
|
+
* is malformed either way, and collapsing it costs nothing.
|
|
56
|
+
*
|
|
57
|
+
* The strip is a backwards index walk rather than the obvious
|
|
58
|
+
* `.replace(/\/+$/, "")`. That regex is quadratic on a string of many
|
|
59
|
+
* slashes - the engine retries the anchored `\/+` from every position and
|
|
60
|
+
* each attempt rescans to the end - and the string here is the `Origin`
|
|
61
|
+
* REQUEST HEADER, which an attacker sets to whatever they like. A header of
|
|
62
|
+
* slashes would burn CPU on the ingest path before the allowlist is ever
|
|
63
|
+
* consulted. The loop below is linear and has identical semantics.
|
|
64
|
+
*/
|
|
65
|
+
public static normalizeOrigin(origin: string): string {
|
|
66
|
+
if (typeof origin !== "string") {
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const trimmed: string = origin.trim().toLowerCase();
|
|
71
|
+
|
|
72
|
+
if (!trimmed) {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let end: number = trimmed.length;
|
|
77
|
+
|
|
78
|
+
while (end > 0 && trimmed.charAt(end - 1) === "/") {
|
|
79
|
+
end--;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return trimmed.substring(0, end);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* Is `origin` covered by `allowList`?
|
|
87
|
+
*
|
|
88
|
+
* Exact origin match, case-insensitive, plus a single leading "*." host
|
|
89
|
+
* wildcard so a customer with per-tenant subdomains does not have to
|
|
90
|
+
* enumerate thousands of them. Deliberately no scheme wildcard and no path
|
|
91
|
+
* matching: an allowlist entry is an origin, and anything looser would
|
|
92
|
+
* defeat the point of having one. The port is part of the origin and must
|
|
93
|
+
* match, so "https://example.com" does not cover "https://example.com:8443".
|
|
94
|
+
*
|
|
95
|
+
* Returns false for an empty allowlist and for a missing/blank origin. The
|
|
96
|
+
* empty-list answer is NOT a policy statement (see the class comment) - it
|
|
97
|
+
* is "this list matched nothing", and the caller decides what that means.
|
|
98
|
+
*/
|
|
99
|
+
public static matches(
|
|
100
|
+
origin: string | undefined | null,
|
|
101
|
+
allowList: ReadonlyArray<string>,
|
|
102
|
+
): boolean {
|
|
103
|
+
if (!allowList || allowList.length === 0) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!origin) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const normalizedOrigin: string = this.normalizeOrigin(origin);
|
|
112
|
+
|
|
113
|
+
if (!normalizedOrigin) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
for (const allowed of allowList) {
|
|
118
|
+
if (typeof allowed !== "string") {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const normalizedAllowed: string = this.normalizeOrigin(allowed);
|
|
123
|
+
|
|
124
|
+
if (!normalizedAllowed) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (normalizedAllowed === normalizedOrigin) {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const wildcardIndex: number = normalizedAllowed.indexOf("://*.");
|
|
133
|
+
|
|
134
|
+
if (wildcardIndex === -1) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const scheme: string = normalizedAllowed.substring(0, wildcardIndex + 3);
|
|
139
|
+
const suffix: string = normalizedAllowed.substring(wildcardIndex + 4);
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* `suffix` keeps its leading dot, and the length check requires at
|
|
143
|
+
* least one character of subdomain in front of it. Those two details
|
|
144
|
+
* are the whole security value of this branch:
|
|
145
|
+
*
|
|
146
|
+
* - keeping the dot stops "https://*.example.com" from matching
|
|
147
|
+
* "https://evilexample.com", an attacker-registrable domain;
|
|
148
|
+
* - the length check stops it from matching the bare apex
|
|
149
|
+
* "https://example.com", which the customer did not list.
|
|
150
|
+
*
|
|
151
|
+
* Do not "simplify" either of them away.
|
|
152
|
+
*/
|
|
153
|
+
if (
|
|
154
|
+
normalizedOrigin.startsWith(scheme) &&
|
|
155
|
+
normalizedOrigin.endsWith(suffix) &&
|
|
156
|
+
normalizedOrigin.length > scheme.length + suffix.length
|
|
157
|
+
) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* Validate one allowlist PATTERN at the point a human types it, and return
|
|
167
|
+
* a human-readable reason it will never work - or null when it is fine.
|
|
168
|
+
*
|
|
169
|
+
* This is intentionally stricter than `matches` needs it to be. `matches`
|
|
170
|
+
* is a hot-path predicate that quietly answers false for garbage; that is
|
|
171
|
+
* correct at ingest time but terrible at configuration time, where a
|
|
172
|
+
* mistyped entry looks exactly like a working one until production
|
|
173
|
+
* telemetry disappears. Everything below is a case where the customer
|
|
174
|
+
* plainly meant something we will not do.
|
|
175
|
+
*
|
|
176
|
+
* ACCEPTED
|
|
177
|
+
* https://app.example.com exact origin
|
|
178
|
+
* http://localhost:3000 http and an explicit port
|
|
179
|
+
* https://*.example.com single leading host wildcard
|
|
180
|
+
* https://*.example.com:8443 wildcard plus port
|
|
181
|
+
* https://app.example.com/ one trailing slash (stripped)
|
|
182
|
+
* http://127.0.0.1:8080 IPv4 literal
|
|
183
|
+
* http://*.localhost single-label suffix (dev setups are
|
|
184
|
+
* real; no public-suffix check is
|
|
185
|
+
* attempted because it is wrong more
|
|
186
|
+
* often than right on internal TLDs)
|
|
187
|
+
*
|
|
188
|
+
* REJECTED
|
|
189
|
+
* "" / " " empty
|
|
190
|
+
* app.example.com no scheme - ambiguous, and an origin
|
|
191
|
+
* without a scheme is not an origin
|
|
192
|
+
* ftp://example.com non-http(s) scheme
|
|
193
|
+
* ws://example.com ditto - browsers do not send these as
|
|
194
|
+
* the Origin of an ingest request
|
|
195
|
+
* https://user@example.com userinfo; the authority must be host
|
|
196
|
+
* (+ optional port) and nothing else
|
|
197
|
+
* https://example.com/path path - an Origin header never has one,
|
|
198
|
+
* so this can only ever fail to match
|
|
199
|
+
* https://example.com?a=b query
|
|
200
|
+
* https://example.com#frag fragment
|
|
201
|
+
* https://example.com// more than one trailing slash
|
|
202
|
+
* https://* bare wildcard - "allow the entire
|
|
203
|
+
* internet" is never what was meant, and
|
|
204
|
+
* if it were, the honest way to say it is
|
|
205
|
+
* to leave the list empty
|
|
206
|
+
* https://*. wildcard with no suffix, same problem
|
|
207
|
+
* https://a.*.example.com wildcard outside the first label - not
|
|
208
|
+
* supported by `matches`, so it would
|
|
209
|
+
* silently match nothing
|
|
210
|
+
* https://*example.com wildcard not followed by a dot; this is
|
|
211
|
+
* the "evilexample.com" trap and is
|
|
212
|
+
* rejected rather than reinterpreted
|
|
213
|
+
* https://exa mple.com whitespace inside
|
|
214
|
+
* https://example.com:0 port out of range
|
|
215
|
+
* https://example.com:70000 port out of range
|
|
216
|
+
* https://example.com:abc non-numeric port
|
|
217
|
+
* https://example..com empty label
|
|
218
|
+
* https://-example.com label starting or ending with "-"
|
|
219
|
+
* https://exa_mple.com character not legal in a hostname
|
|
220
|
+
*/
|
|
221
|
+
public static validateOriginPattern(pattern: string): string | null {
|
|
222
|
+
if (typeof pattern !== "string") {
|
|
223
|
+
return "Origin must be text.";
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const trimmed: string = pattern.trim();
|
|
227
|
+
|
|
228
|
+
if (!trimmed) {
|
|
229
|
+
return "Origin cannot be empty.";
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/*
|
|
233
|
+
* Whitespace is checked on the TRIMMED value, so surrounding spaces are
|
|
234
|
+
* forgiven (normalizeOrigin drops them anyway) while interior spaces -
|
|
235
|
+
* which are always a typo or a paste of two entries into one field - are
|
|
236
|
+
* refused.
|
|
237
|
+
*/
|
|
238
|
+
if (WHITESPACE_ANYWHERE.test(trimmed)) {
|
|
239
|
+
return `"${trimmed}" cannot contain spaces. Enter one origin per entry.`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const value: string = trimmed.toLowerCase();
|
|
243
|
+
|
|
244
|
+
const schemeSeparatorIndex: number = value.indexOf("://");
|
|
245
|
+
|
|
246
|
+
if (schemeSeparatorIndex === -1) {
|
|
247
|
+
return `"${trimmed}" must start with http:// or https://.`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const scheme: string = value.substring(0, schemeSeparatorIndex);
|
|
251
|
+
|
|
252
|
+
if (scheme !== "http" && scheme !== "https") {
|
|
253
|
+
return `"${trimmed}" must use the http:// or https:// scheme.`;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
let authority: string = value.substring(schemeSeparatorIndex + 3);
|
|
257
|
+
|
|
258
|
+
/*
|
|
259
|
+
* Exactly one trailing slash is tolerated and dropped here. Anything else
|
|
260
|
+
* after the authority is rejected below rather than ignored: silently
|
|
261
|
+
* discarding a path would accept "https://example.com/only-this-app" and
|
|
262
|
+
* then match the whole origin, which is looser than what was written.
|
|
263
|
+
*/
|
|
264
|
+
if (authority.endsWith("/")) {
|
|
265
|
+
authority = authority.substring(0, authority.length - 1);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (!authority) {
|
|
269
|
+
return `"${trimmed}" is missing a host.`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (authority.includes("/")) {
|
|
273
|
+
return `"${trimmed}" must not contain a path. Use just the origin, for example https://app.example.com.`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (authority.includes("?")) {
|
|
277
|
+
return `"${trimmed}" must not contain a query string.`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (authority.includes("#")) {
|
|
281
|
+
return `"${trimmed}" must not contain a fragment.`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (authority.includes("@")) {
|
|
285
|
+
return `"${trimmed}" must not contain a username or password.`;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
let host: string = authority;
|
|
289
|
+
|
|
290
|
+
/*
|
|
291
|
+
* Split on the LAST colon so a future IPv6 literal fails on the host
|
|
292
|
+
* charset check below with a clear message, rather than being silently
|
|
293
|
+
* chopped in half at its first colon and reported as a bad port.
|
|
294
|
+
*/
|
|
295
|
+
const portSeparatorIndex: number = authority.lastIndexOf(":");
|
|
296
|
+
|
|
297
|
+
if (portSeparatorIndex !== -1) {
|
|
298
|
+
host = authority.substring(0, portSeparatorIndex);
|
|
299
|
+
|
|
300
|
+
const portText: string = authority.substring(portSeparatorIndex + 1);
|
|
301
|
+
|
|
302
|
+
if (!DIGITS_ONLY.test(portText)) {
|
|
303
|
+
return `"${trimmed}" has an invalid port. The port must be a number between 1 and 65535.`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const port: number = Number(portText);
|
|
307
|
+
|
|
308
|
+
if (port < 1 || port > 65535) {
|
|
309
|
+
return `"${trimmed}" has a port outside the valid range 1-65535.`;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!host) {
|
|
314
|
+
return `"${trimmed}" is missing a host.`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
let hostWithoutWildcard: string = host;
|
|
318
|
+
|
|
319
|
+
if (host.startsWith("*.")) {
|
|
320
|
+
hostWithoutWildcard = host.substring(2);
|
|
321
|
+
|
|
322
|
+
if (!hostWithoutWildcard) {
|
|
323
|
+
return `"${trimmed}" needs a domain after the wildcard, for example https://*.example.com.`;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/*
|
|
328
|
+
* Any remaining "*" is either a bare wildcard host, a wildcard that is not
|
|
329
|
+
* followed by a dot, or a wildcard in a later label. `matches` supports
|
|
330
|
+
* none of those, so accepting them would hand the customer an allowlist
|
|
331
|
+
* entry that matches nothing at all.
|
|
332
|
+
*/
|
|
333
|
+
if (hostWithoutWildcard.includes("*")) {
|
|
334
|
+
return `"${trimmed}" may only use a wildcard as the first label, written as "*." - for example https://*.example.com.`;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const labels: Array<string> = hostWithoutWildcard.split(".");
|
|
338
|
+
|
|
339
|
+
for (const label of labels) {
|
|
340
|
+
if (!label) {
|
|
341
|
+
return `"${trimmed}" has an empty part in its host name.`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (!HOST_LABEL_CHARACTERS.test(label)) {
|
|
345
|
+
return `"${trimmed}" contains a character that is not valid in a host name.`;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (label.startsWith("-") || label.endsWith("-")) {
|
|
349
|
+
return `"${trimmed}" has a host name part that starts or ends with "-".`;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The keyboard and screen reader behaviour of the day-by-day uptime strip.
|
|
3
|
+
*
|
|
4
|
+
* The strip is one bar per day - ninety of them on a default status page, and
|
|
5
|
+
* one strip per resource. That shape rules out the obvious accessibility fix
|
|
6
|
+
* of making every bar a tab stop: a page with twenty resources would put
|
|
7
|
+
* eighteen hundred stops between the visitor and the footer. The strip is
|
|
8
|
+
* therefore a composite widget with a roving tabindex - one stop for the whole
|
|
9
|
+
* strip, arrow keys to move within it - which is the pattern ARIA prescribes
|
|
10
|
+
* for exactly this.
|
|
11
|
+
*
|
|
12
|
+
* Everything here is pure so the navigation maths and the wording of the
|
|
13
|
+
* accessible names can be tested without a renderer.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import UptimeHistoryLabels, {
|
|
17
|
+
DefaultUptimeHistoryLabels,
|
|
18
|
+
} from "../../Types/Monitor/UptimeHistoryLabels";
|
|
19
|
+
|
|
20
|
+
export default class DayUptimeGraphUtil {
|
|
21
|
+
/* How far PageUp / PageDown jump. A week reads naturally on a daily strip. */
|
|
22
|
+
public static readonly PageJumpInDays: number = 7;
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* Where focus goes for a key pressed on the bar at `currentIndex`, or null
|
|
26
|
+
* when the key is not one this widget handles - in which case the caller
|
|
27
|
+
* must leave the event alone so that Tab, Enter and Space keep their normal
|
|
28
|
+
* meaning.
|
|
29
|
+
*
|
|
30
|
+
* Movement clamps rather than wraps. Wrapping a ninety day history would
|
|
31
|
+
* jump from today to three months ago on one arrow press, which reads as a
|
|
32
|
+
* glitch rather than as navigation.
|
|
33
|
+
*/
|
|
34
|
+
public static getNextFocusIndex(data: {
|
|
35
|
+
key: string;
|
|
36
|
+
currentIndex: number;
|
|
37
|
+
barCount: number;
|
|
38
|
+
}): number | null {
|
|
39
|
+
if (data.barCount <= 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const lastIndex: number = data.barCount - 1;
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* A caller whose index has drifted out of range (the window shrank under
|
|
47
|
+
* it, say) is still owed sane movement, so clamp before moving rather
|
|
48
|
+
* than after.
|
|
49
|
+
*/
|
|
50
|
+
const current: number = Math.min(Math.max(data.currentIndex, 0), lastIndex);
|
|
51
|
+
|
|
52
|
+
let next: number | null = null;
|
|
53
|
+
|
|
54
|
+
switch (data.key) {
|
|
55
|
+
case "ArrowRight":
|
|
56
|
+
case "ArrowDown":
|
|
57
|
+
next = current + 1;
|
|
58
|
+
break;
|
|
59
|
+
case "ArrowLeft":
|
|
60
|
+
case "ArrowUp":
|
|
61
|
+
next = current - 1;
|
|
62
|
+
break;
|
|
63
|
+
case "Home":
|
|
64
|
+
next = 0;
|
|
65
|
+
break;
|
|
66
|
+
case "End":
|
|
67
|
+
next = lastIndex;
|
|
68
|
+
break;
|
|
69
|
+
case "PageDown":
|
|
70
|
+
next = current + this.PageJumpInDays;
|
|
71
|
+
break;
|
|
72
|
+
case "PageUp":
|
|
73
|
+
next = current - this.PageJumpInDays;
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return Math.min(Math.max(next, 0), lastIndex);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* The strip's single tab stop. Today is the bar a visitor wants first, so
|
|
84
|
+
* that is where focus lands before anything has been focused, and it is
|
|
85
|
+
* also where focus lands again if the window shrinks under a stored index.
|
|
86
|
+
*/
|
|
87
|
+
public static getActiveBarIndex(data: {
|
|
88
|
+
storedIndex: number | null;
|
|
89
|
+
barCount: number;
|
|
90
|
+
}): number {
|
|
91
|
+
if (data.barCount <= 0) {
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const lastIndex: number = data.barCount - 1;
|
|
96
|
+
|
|
97
|
+
if (data.storedIndex === null) {
|
|
98
|
+
return lastIndex;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return Math.min(Math.max(data.storedIndex, 0), lastIndex);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public static getBarTabIndex(data: {
|
|
105
|
+
index: number;
|
|
106
|
+
activeIndex: number;
|
|
107
|
+
}): number {
|
|
108
|
+
return data.index === data.activeIndex ? 0 : -1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
* Uptime the way it is said out loud rather than the way it is drawn.
|
|
113
|
+
* Trailing zeroes are noise in a screen reader ("ninety nine point nine
|
|
114
|
+
* zero percent"), and a bar that is a hair under 100 must not be read as
|
|
115
|
+
* 100 - "100% uptime" on a day that had an outage is a wrong statement, not
|
|
116
|
+
* a rounding.
|
|
117
|
+
*/
|
|
118
|
+
public static formatUptimePercentForLabel(percent: number): string {
|
|
119
|
+
if (!Number.isFinite(percent)) {
|
|
120
|
+
return "0";
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const clamped: number = Math.min(Math.max(percent, 0), 100);
|
|
124
|
+
|
|
125
|
+
if (clamped === 100) {
|
|
126
|
+
return "100";
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const rounded: number = Math.round(clamped * 100) / 100;
|
|
130
|
+
|
|
131
|
+
if (rounded >= 100) {
|
|
132
|
+
return "99.99";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Drop a trailing ".0" / ".00" so whole numbers read as whole numbers.
|
|
136
|
+
return String(parseFloat(rounded.toFixed(2)));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public static getDayAriaLabel(data: {
|
|
140
|
+
dateLabel: string;
|
|
141
|
+
hasEvents: boolean;
|
|
142
|
+
uptimePercent: number;
|
|
143
|
+
incidentCount: number;
|
|
144
|
+
labels?: UptimeHistoryLabels | undefined;
|
|
145
|
+
}): string {
|
|
146
|
+
const labels: UptimeHistoryLabels =
|
|
147
|
+
data.labels || DefaultUptimeHistoryLabels;
|
|
148
|
+
|
|
149
|
+
const incidentCount: number = Math.max(data.incidentCount, 0);
|
|
150
|
+
const hasIncidents: boolean = incidentCount > 0;
|
|
151
|
+
|
|
152
|
+
if (!data.hasEvents) {
|
|
153
|
+
return this.interpolate(
|
|
154
|
+
hasIncidents
|
|
155
|
+
? labels.dayLabelNoDataWithIncidents
|
|
156
|
+
: labels.dayLabelNoData,
|
|
157
|
+
{
|
|
158
|
+
date: data.dateLabel,
|
|
159
|
+
total: String(incidentCount),
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return this.interpolate(
|
|
165
|
+
hasIncidents ? labels.dayLabelWithIncidents : labels.dayLabel,
|
|
166
|
+
{
|
|
167
|
+
date: data.dateLabel,
|
|
168
|
+
uptime: this.formatUptimePercentForLabel(data.uptimePercent),
|
|
169
|
+
total: String(incidentCount),
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public static getGraphAriaLabel(data: {
|
|
175
|
+
dayCount: number;
|
|
176
|
+
labels?: UptimeHistoryLabels | undefined;
|
|
177
|
+
}): string {
|
|
178
|
+
const labels: UptimeHistoryLabels =
|
|
179
|
+
data.labels || DefaultUptimeHistoryLabels;
|
|
180
|
+
|
|
181
|
+
return this.interpolate(labels.graphLabel, {
|
|
182
|
+
total: String(Math.max(data.dayCount, 0)),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/*
|
|
187
|
+
* The same {{placeholder}} shape i18next uses, so a caller can hand these
|
|
188
|
+
* strings straight from a translation file. Replacing rather than
|
|
189
|
+
* formatting keeps this dependency-free and keeps a missing placeholder
|
|
190
|
+
* from throwing on a half translated locale - the worst case is a literal
|
|
191
|
+
* "{{uptime}}" in a label, not a page that fails to render.
|
|
192
|
+
*/
|
|
193
|
+
private static interpolate(
|
|
194
|
+
template: string,
|
|
195
|
+
values: Record<string, string>,
|
|
196
|
+
): string {
|
|
197
|
+
let result: string = template;
|
|
198
|
+
|
|
199
|
+
for (const key of Object.keys(values)) {
|
|
200
|
+
result = result.split(`{{${key}}}`).join(values[key] as string);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
}
|
package/Utils/ValueFormatter.ts
CHANGED
|
@@ -686,17 +686,51 @@ export default class ValueFormatter {
|
|
|
686
686
|
* [0, 1] ratio. Pair with unit "1" to render values as percentages.
|
|
687
687
|
*
|
|
688
688
|
* Conventions covered:
|
|
689
|
-
* - OTel `.utilization` (system.cpu.utilization,
|
|
689
|
+
* - OTel `.utilization` (system.cpu.utilization, …)
|
|
690
690
|
* - OTel `.ratio` and `.fraction` (db.client.connection.usage_ratio, …)
|
|
691
691
|
* - Prometheus-style `_utilization` / `_ratio` / `_fraction` suffixes
|
|
692
692
|
* - Plain `_percent` / `.percent` / `_percentage` / `.percentage` names
|
|
693
693
|
*
|
|
694
694
|
* Adding a new suffix is one regex edit — no per-metric allowlist.
|
|
695
|
+
*
|
|
696
|
+
* The two kubeletstats exclusions below are not taste. The receiver
|
|
697
|
+
* emits `k8s.pod.cpu.utilization` and `k8s.node.cpu.utilization` as CPU
|
|
698
|
+
* *cores in use* (UsageNanoCores / 1e9) carrying unit "1", despite the
|
|
699
|
+
* `.utilization` name. Four other places in this repo already say so:
|
|
700
|
+
* the header comment on Pages/Kubernetes/Utils/KubernetesCpuUtils.ts,
|
|
701
|
+
* OtelMetricsIngestService.cpuCoresToPercent (which divides by
|
|
702
|
+
* k8s.node.allocatable_cpu rather than multiplying by 100), the "CPU
|
|
703
|
+
* widgets show cores, not a percent" note in DashboardTemplates.ts, and
|
|
704
|
+
* the highCpuTemplate description in KubernetesAlertTemplates.ts
|
|
705
|
+
* ("the raw k8s.node.cpu.utilization metric is a misnamed cores gauge,
|
|
706
|
+
* not a percent"). Matching them here multiplies cores by 100 — which is
|
|
707
|
+
* what rendered 0.1831 cores as "18.31%" on the same evaluation page
|
|
708
|
+
* that showed the pod at 91.55% of its CPU limit.
|
|
709
|
+
*
|
|
710
|
+
* The exclusion is anchored to those two exact names, so the genuine
|
|
711
|
+
* ratio metrics from the same receiver — k8s.pod.cpu_limit_utilization,
|
|
712
|
+
* k8s.container.cpu_request_utilization and friends — still match and
|
|
713
|
+
* still render as percents.
|
|
714
|
+
*
|
|
715
|
+
* `container.cpu.utilization` is DELIBERATELY not excluded. That exact
|
|
716
|
+
* metric name is emitted both by kubeletstats (cores) and by
|
|
717
|
+
* docker_stats, and this repo does not currently agree with itself on
|
|
718
|
+
* the docker_stats scale — OtelMetricsIngestService.cpuValueToPercent
|
|
719
|
+
* multiplies the raw value by 100 while Pages/Docker/View/Containers.tsx
|
|
720
|
+
* renders the same raw value with a "%" suffix and no scaling.
|
|
721
|
+
* Excluding it here would silently pick a side of that contradiction.
|
|
695
722
|
*/
|
|
696
723
|
public static isFractionMetric(metricName: string | undefined): boolean {
|
|
697
724
|
if (!metricName) {
|
|
698
725
|
return false;
|
|
699
726
|
}
|
|
727
|
+
|
|
728
|
+
const kubeletstatsCoresGaugeMisnamedAsUtilization: RegExp =
|
|
729
|
+
/^k8s\.(node|pod)\.cpu\.utilization$/i;
|
|
730
|
+
if (kubeletstatsCoresGaugeMisnamedAsUtilization.test(metricName.trim())) {
|
|
731
|
+
return false;
|
|
732
|
+
}
|
|
733
|
+
|
|
700
734
|
const fractionMetricSuffixRegex: RegExp =
|
|
701
735
|
/[._](utilization|ratio|fraction|percent|percentage)$/i;
|
|
702
736
|
return fractionMetricSuffixRegex.test(metricName);
|