@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,335 @@
|
|
|
1
|
+
import CustomFieldType from "../../../Types/CustomField/CustomFieldType";
|
|
2
|
+
import { getCustomFieldMappingCompatibilityError } from "../../../Types/CustomField/CustomFieldValueMapping";
|
|
3
|
+
import {
|
|
4
|
+
CustomFieldMappingSourceInfo,
|
|
5
|
+
getCustomFieldMappingSources,
|
|
6
|
+
} from "../../../Types/CustomField/CustomFieldMappingCatalog";
|
|
7
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
8
|
+
import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
|
|
9
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
10
|
+
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
11
|
+
import CreateBy from "../../Types/Database/CreateBy";
|
|
12
|
+
import UpdateBy from "../../Types/Database/UpdateBy";
|
|
13
|
+
import {
|
|
14
|
+
CustomFieldMappingSourceEntry,
|
|
15
|
+
CustomFieldMappingTargetEntry,
|
|
16
|
+
getCustomFieldMappingTarget,
|
|
17
|
+
} from "./CustomFieldMappingRegistry";
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* Validation for the "map this field's value from a related resource"
|
|
21
|
+
* configuration, run when a custom field DEFINITION is saved.
|
|
22
|
+
*
|
|
23
|
+
* This is the only moment a person is present to fix a bad mapping, and it is
|
|
24
|
+
* worth being strict here because nothing downstream can be. The server never
|
|
25
|
+
* validates a custom field VALUE against its definition — a dropdown value
|
|
26
|
+
* that is not in the option list is accepted, stored, drawn as an uncoloured
|
|
27
|
+
* badge, and cannot be filtered for, because the facet's option list is built
|
|
28
|
+
* from the target definition. A mapping that copies "AWS" into a field
|
|
29
|
+
* offering only "Acme"/"Globex" would manufacture exactly that, silently, on
|
|
30
|
+
* every alert.
|
|
31
|
+
*
|
|
32
|
+
* The checks:
|
|
33
|
+
* - the resource must be one this definition's resource can actually reach
|
|
34
|
+
* - the source field must exist in the source's definition table
|
|
35
|
+
* - both sides must declare a field type, and it must be the same type
|
|
36
|
+
* - for dropdowns, every option the source can hold must be offered here
|
|
37
|
+
*
|
|
38
|
+
* A definition with no mapping configured skips all of it and costs nothing.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
export interface CustomFieldMappingDefinitionState {
|
|
42
|
+
projectId?: ObjectID | undefined;
|
|
43
|
+
customFieldType?: CustomFieldType | undefined;
|
|
44
|
+
dropdownOptions?: string | undefined;
|
|
45
|
+
mapFromResourceType?: string | undefined;
|
|
46
|
+
mapFromCustomFieldName?: string | undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type NormalizeCustomFieldMappingFunction = (
|
|
50
|
+
data: Record<string, unknown>,
|
|
51
|
+
) => void;
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Turning a mapping off has to clear BOTH columns, and `showIf` will not do it
|
|
55
|
+
* for us: it hides the "field to copy from" input but BasicForm still posts the
|
|
56
|
+
* whole value bag, so clearing "Map value from" leaves the field name behind.
|
|
57
|
+
* A half-set mapping is not a state anything downstream should reason about.
|
|
58
|
+
*
|
|
59
|
+
* What this deliberately does NOT do is treat "absent" as "cleared". An update
|
|
60
|
+
* payload is a PARTIAL: changing only the source field name says nothing about
|
|
61
|
+
* the resource, and reading that as "turn the mapping off" would silently
|
|
62
|
+
* delete a working mapping every time someone repointed it at another field.
|
|
63
|
+
* Only an explicitly emptied key clears anything; the merged result is what
|
|
64
|
+
* gets validated, by the caller.
|
|
65
|
+
*/
|
|
66
|
+
export const normalizeCustomFieldMappingPayload: NormalizeCustomFieldMappingFunction =
|
|
67
|
+
(data: Record<string, unknown>): void => {
|
|
68
|
+
const resource: unknown = data["mapFromResourceType"];
|
|
69
|
+
const fieldName: unknown = data["mapFromCustomFieldName"];
|
|
70
|
+
|
|
71
|
+
type IsClearedFunction = (value: unknown) => boolean;
|
|
72
|
+
|
|
73
|
+
const isCleared: IsClearedFunction = (value: unknown): boolean => {
|
|
74
|
+
if (value === undefined) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return typeof value !== "string" || value.trim().length === 0;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
if (isCleared(resource) || isCleared(fieldName)) {
|
|
82
|
+
data["mapFromResourceType"] = null;
|
|
83
|
+
data["mapFromCustomFieldName"] = null;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (resource !== undefined) {
|
|
88
|
+
data["mapFromResourceType"] = (resource as string).trim();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (fieldName !== undefined) {
|
|
92
|
+
data["mapFromCustomFieldName"] = (fieldName as string).trim();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
type ValidateStateFunction = (data: {
|
|
97
|
+
target: CustomFieldMappingTargetEntry;
|
|
98
|
+
state: CustomFieldMappingDefinitionState;
|
|
99
|
+
}) => Promise<void>;
|
|
100
|
+
|
|
101
|
+
const validateState: ValidateStateFunction = async (data: {
|
|
102
|
+
target: CustomFieldMappingTargetEntry;
|
|
103
|
+
state: CustomFieldMappingDefinitionState;
|
|
104
|
+
}): Promise<void> => {
|
|
105
|
+
const resource: string | undefined = data.state.mapFromResourceType;
|
|
106
|
+
const sourceFieldName: string | undefined = data.state.mapFromCustomFieldName;
|
|
107
|
+
|
|
108
|
+
if (!resource && !sourceFieldName) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* Half a mapping is rejected rather than quietly stored. It resolves nothing,
|
|
114
|
+
* and the settings table would show a field claiming to be mapped to nowhere.
|
|
115
|
+
*/
|
|
116
|
+
if (!resource || !sourceFieldName) {
|
|
117
|
+
throw new BadDataException(
|
|
118
|
+
"Choose both the resource to copy this field's value from and the field to copy, or leave both empty to enter values by hand.",
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const info: CustomFieldMappingSourceInfo | undefined =
|
|
123
|
+
getCustomFieldMappingSources(data.target.definitionTableName).find(
|
|
124
|
+
(candidate: CustomFieldMappingSourceInfo) => {
|
|
125
|
+
return candidate.resource === resource;
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if (!info) {
|
|
130
|
+
throw new BadDataException(
|
|
131
|
+
`${data.target.targetName} custom fields cannot take their value from "${resource}".`,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const source: CustomFieldMappingSourceEntry | undefined =
|
|
136
|
+
data.target.sources.find((candidate: CustomFieldMappingSourceEntry) => {
|
|
137
|
+
return candidate.info.resource === resource;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (!source) {
|
|
141
|
+
throw new BadDataException(
|
|
142
|
+
`${data.target.targetName} custom fields cannot take their value from "${resource}".`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!data.state.projectId) {
|
|
147
|
+
throw new BadDataException(
|
|
148
|
+
"ProjectId is required to map a custom field's value from another resource.",
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const sourceDefinitions: Array<BaseModel> = await source
|
|
153
|
+
.getSourceDefinitionService()
|
|
154
|
+
.findBy({
|
|
155
|
+
query: {
|
|
156
|
+
projectId: data.state.projectId,
|
|
157
|
+
name: sourceFieldName,
|
|
158
|
+
},
|
|
159
|
+
select: {
|
|
160
|
+
name: true,
|
|
161
|
+
customFieldType: true,
|
|
162
|
+
dropdownOptions: true,
|
|
163
|
+
},
|
|
164
|
+
limit: 1,
|
|
165
|
+
skip: 0,
|
|
166
|
+
props: {
|
|
167
|
+
isRoot: true,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const sourceDefinition: BaseModel | undefined = sourceDefinitions[0];
|
|
172
|
+
|
|
173
|
+
if (!sourceDefinition) {
|
|
174
|
+
throw new BadDataException(
|
|
175
|
+
`${info.title} does not have a custom field called "${sourceFieldName}". Create it first, or choose a different field.`,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const compatibilityError: string | null =
|
|
180
|
+
getCustomFieldMappingCompatibilityError({
|
|
181
|
+
targetFieldType: data.state.customFieldType,
|
|
182
|
+
sourceFieldType: (sourceDefinition as any)["customFieldType"],
|
|
183
|
+
targetDropdownOptions: data.state.dropdownOptions,
|
|
184
|
+
sourceDropdownOptions: (sourceDefinition as any)["dropdownOptions"],
|
|
185
|
+
sourceFieldName: sourceFieldName,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (compatibilityError) {
|
|
189
|
+
throw new BadDataException(compatibilityError);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export type ValidateCustomFieldMappingOnCreateFunction = (data: {
|
|
194
|
+
definitionModelType: { new (): BaseModel };
|
|
195
|
+
createBy: CreateBy<any>;
|
|
196
|
+
}) => Promise<void>;
|
|
197
|
+
|
|
198
|
+
export const validateCustomFieldMappingOnCreate: ValidateCustomFieldMappingOnCreateFunction =
|
|
199
|
+
async (data: {
|
|
200
|
+
definitionModelType: { new (): BaseModel };
|
|
201
|
+
createBy: CreateBy<any>;
|
|
202
|
+
}): Promise<void> => {
|
|
203
|
+
normalizeCustomFieldMappingPayload(
|
|
204
|
+
data.createBy.data as unknown as Record<string, unknown>,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const target: CustomFieldMappingTargetEntry | undefined =
|
|
208
|
+
getCustomFieldMappingTarget(new data.definitionModelType().tableName!);
|
|
209
|
+
|
|
210
|
+
if (!target) {
|
|
211
|
+
/*
|
|
212
|
+
* Six of the nine definition tables carry the columns for lockstep with
|
|
213
|
+
* their siblings but have no reachable source. Refusing a value there is
|
|
214
|
+
* better than accepting one that could never resolve.
|
|
215
|
+
*/
|
|
216
|
+
if ((data.createBy.data as any)["mapFromResourceType"]) {
|
|
217
|
+
throw new BadDataException(
|
|
218
|
+
"Custom fields on this resource cannot take their value from another resource.",
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
await validateState({
|
|
226
|
+
target: target,
|
|
227
|
+
state: {
|
|
228
|
+
projectId:
|
|
229
|
+
(data.createBy.props.tenantId as ObjectID | undefined) ||
|
|
230
|
+
(data.createBy.data as any)["projectId"],
|
|
231
|
+
customFieldType: (data.createBy.data as any)["customFieldType"],
|
|
232
|
+
dropdownOptions: (data.createBy.data as any)["dropdownOptions"],
|
|
233
|
+
mapFromResourceType: (data.createBy.data as any)["mapFromResourceType"],
|
|
234
|
+
mapFromCustomFieldName: (data.createBy.data as any)[
|
|
235
|
+
"mapFromCustomFieldName"
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export type ValidateCustomFieldMappingOnUpdateFunction = (data: {
|
|
242
|
+
definitionModelType: { new (): BaseModel };
|
|
243
|
+
definitionService: {
|
|
244
|
+
findBy: (input: any) => Promise<Array<any>>;
|
|
245
|
+
};
|
|
246
|
+
updateBy: UpdateBy<any>;
|
|
247
|
+
}) => Promise<void>;
|
|
248
|
+
|
|
249
|
+
export const validateCustomFieldMappingOnUpdate: ValidateCustomFieldMappingOnUpdateFunction =
|
|
250
|
+
async (data: {
|
|
251
|
+
definitionModelType: { new (): BaseModel };
|
|
252
|
+
definitionService: {
|
|
253
|
+
findBy: (input: any) => Promise<Array<any>>;
|
|
254
|
+
};
|
|
255
|
+
updateBy: UpdateBy<any>;
|
|
256
|
+
}): Promise<void> => {
|
|
257
|
+
normalizeCustomFieldMappingPayload(
|
|
258
|
+
data.updateBy.data as unknown as Record<string, unknown>,
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const payload: Record<string, unknown> = data.updateBy
|
|
262
|
+
.data as unknown as Record<string, unknown>;
|
|
263
|
+
|
|
264
|
+
const touchesMapping: boolean = [
|
|
265
|
+
"mapFromResourceType",
|
|
266
|
+
"mapFromCustomFieldName",
|
|
267
|
+
"customFieldType",
|
|
268
|
+
"dropdownOptions",
|
|
269
|
+
].some((key: string) => {
|
|
270
|
+
return payload[key] !== undefined;
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
if (!touchesMapping) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const target: CustomFieldMappingTargetEntry | undefined =
|
|
278
|
+
getCustomFieldMappingTarget(new data.definitionModelType().tableName!);
|
|
279
|
+
|
|
280
|
+
if (!target) {
|
|
281
|
+
if (payload["mapFromResourceType"]) {
|
|
282
|
+
throw new BadDataException(
|
|
283
|
+
"Custom fields on this resource cannot take their value from another resource.",
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/*
|
|
291
|
+
* The payload is a PARTIAL: changing only the source field name must still
|
|
292
|
+
* be checked against the type and options already stored on the row. And
|
|
293
|
+
* narrowing the target's dropdown options must be checked against a
|
|
294
|
+
* mapping that was valid when it was saved.
|
|
295
|
+
*/
|
|
296
|
+
const existingRows: Array<BaseModel> = await data.definitionService.findBy({
|
|
297
|
+
query: data.updateBy.query,
|
|
298
|
+
select: {
|
|
299
|
+
projectId: true,
|
|
300
|
+
customFieldType: true,
|
|
301
|
+
dropdownOptions: true,
|
|
302
|
+
mapFromResourceType: true,
|
|
303
|
+
mapFromCustomFieldName: true,
|
|
304
|
+
},
|
|
305
|
+
limit: LIMIT_PER_PROJECT,
|
|
306
|
+
skip: 0,
|
|
307
|
+
props: {
|
|
308
|
+
isRoot: true,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
for (const row of existingRows) {
|
|
313
|
+
const merged: CustomFieldMappingDefinitionState = {
|
|
314
|
+
projectId: (row as any)["projectId"],
|
|
315
|
+
customFieldType:
|
|
316
|
+
payload["customFieldType"] !== undefined
|
|
317
|
+
? (payload["customFieldType"] as CustomFieldType)
|
|
318
|
+
: (row as any)["customFieldType"],
|
|
319
|
+
dropdownOptions:
|
|
320
|
+
payload["dropdownOptions"] !== undefined
|
|
321
|
+
? (payload["dropdownOptions"] as string)
|
|
322
|
+
: (row as any)["dropdownOptions"],
|
|
323
|
+
mapFromResourceType:
|
|
324
|
+
payload["mapFromResourceType"] !== undefined
|
|
325
|
+
? (payload["mapFromResourceType"] as string) || undefined
|
|
326
|
+
: (row as any)["mapFromResourceType"],
|
|
327
|
+
mapFromCustomFieldName:
|
|
328
|
+
payload["mapFromCustomFieldName"] !== undefined
|
|
329
|
+
? (payload["mapFromCustomFieldName"] as string) || undefined
|
|
330
|
+
: (row as any)["mapFromCustomFieldName"],
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
await validateState({ target: target, state: merged });
|
|
334
|
+
}
|
|
335
|
+
};
|
|
@@ -67,6 +67,19 @@ export interface EgressGuardOptions {
|
|
|
67
67
|
* to "Data source".
|
|
68
68
|
*/
|
|
69
69
|
targetLabel?: string | undefined;
|
|
70
|
+
/*
|
|
71
|
+
* Optional operator guidance appended only when a PRIVATE-tier address is
|
|
72
|
+
* refused. It is deliberately omitted for loopback/link-local/reserved
|
|
73
|
+
* ranges because those cannot be opened by the private-network switch.
|
|
74
|
+
*/
|
|
75
|
+
privateNetworkHint?: string | undefined;
|
|
76
|
+
/*
|
|
77
|
+
* Detailed DNS failures and address-policy reasons are useful to operators,
|
|
78
|
+
* but tenant-facing callers can compare them to enumerate internal names.
|
|
79
|
+
* Defaults to true for backwards compatibility; shared-probe monitor
|
|
80
|
+
* requests set it to false and receive one indistinguishable failure.
|
|
81
|
+
*/
|
|
82
|
+
includeResolvedAddressInError?: boolean | undefined;
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
export interface PinnedAgents {
|
|
@@ -96,6 +109,7 @@ const DEFAULT_TARGET_LABEL: string = "Data source";
|
|
|
96
109
|
export interface AddressVerdict {
|
|
97
110
|
blocked: boolean;
|
|
98
111
|
reason?: string | undefined;
|
|
112
|
+
isPrivateNetwork?: boolean | undefined;
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
const DNS_LOOKUP_TIMEOUT_IN_MS: number = 5000;
|
|
@@ -111,6 +125,9 @@ type RangeSpec = [string, number, string];
|
|
|
111
125
|
const ALWAYS_BLOCKED_IPV4_RANGE_SPECS: Array<RangeSpec> = [
|
|
112
126
|
["127.0.0.0", 8, "loopback address"],
|
|
113
127
|
["169.254.0.0", 16, "link-local address (cloud metadata range)"],
|
|
128
|
+
["100.100.100.200", 32, "cloud metadata address"],
|
|
129
|
+
["168.63.129.16", 32, "cloud platform metadata address"],
|
|
130
|
+
["192.0.0.192", 32, "cloud metadata address"],
|
|
114
131
|
["0.0.0.0", 8, "unspecified address"],
|
|
115
132
|
["224.0.0.0", 4, "multicast address"],
|
|
116
133
|
["240.0.0.0", 4, "reserved address"],
|
|
@@ -195,7 +212,11 @@ export default class DataSourceEgressGuard {
|
|
|
195
212
|
if (blockPrivateAddresses) {
|
|
196
213
|
for (const range of this.buildRanges(PRIVATE_IPV4_RANGE_SPECS)) {
|
|
197
214
|
if (this.isInRange(ipAsInt, range)) {
|
|
198
|
-
return {
|
|
215
|
+
return {
|
|
216
|
+
blocked: true,
|
|
217
|
+
reason: range.reason,
|
|
218
|
+
isPrivateNetwork: true,
|
|
219
|
+
};
|
|
199
220
|
}
|
|
200
221
|
}
|
|
201
222
|
}
|
|
@@ -309,6 +330,80 @@ export default class DataSourceEgressGuard {
|
|
|
309
330
|
return { blocked: true, reason: "loopback address" };
|
|
310
331
|
}
|
|
311
332
|
|
|
333
|
+
const groups: Array<number> = expanded.split(":").map((group: string) => {
|
|
334
|
+
return parseInt(group, 16);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
/*
|
|
338
|
+
* These cloud-local IPv6 endpoints expose instance metadata or workload
|
|
339
|
+
* credentials. They remain forbidden even when a self-hosted operator
|
|
340
|
+
* explicitly enables ordinary private-network monitor targets.
|
|
341
|
+
*/
|
|
342
|
+
if (groups[0] === 0xfd00 && groups[1] === 0x0ec2) {
|
|
343
|
+
return { blocked: true, reason: "cloud metadata address" };
|
|
344
|
+
}
|
|
345
|
+
if (expanded === "fd20:00ce:0000:0000:0000:0000:0000:0254") {
|
|
346
|
+
return { blocked: true, reason: "cloud metadata address" };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
* RFC 8215 reserves 64:ff9b:1::/48 for locally assigned IPv4/IPv6
|
|
351
|
+
* translation. Its IPv4 layout is operator-defined, so it cannot be
|
|
352
|
+
* decoded safely here and the special-use prefix is refused wholesale.
|
|
353
|
+
* RFC 2765's legacy IPv4-translated prefix receives the same treatment.
|
|
354
|
+
*/
|
|
355
|
+
if (
|
|
356
|
+
expanded.startsWith("0064:ff9b:0001:") ||
|
|
357
|
+
expanded.startsWith("0000:0000:0000:0000:ffff:0000:")
|
|
358
|
+
) {
|
|
359
|
+
return { blocked: true, reason: "IPv4 translation address" };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const embeddedIpv4: (highGroupIndex: number, invert?: boolean) => string = (
|
|
363
|
+
highGroupIndex: number,
|
|
364
|
+
invert: boolean = false,
|
|
365
|
+
): string => {
|
|
366
|
+
let high: number = groups[highGroupIndex]!;
|
|
367
|
+
let low: number = groups[highGroupIndex + 1]!;
|
|
368
|
+
|
|
369
|
+
if (invert) {
|
|
370
|
+
high ^= 0xffff;
|
|
371
|
+
low ^= 0xffff;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return `${high >> 8}.${high & 0xff}.${low >> 8}.${low & 0xff}`;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
/*
|
|
378
|
+
* Deprecated IPv4-compatible ::/96 addresses are still understood by
|
|
379
|
+
* network stacks. Classify the IPv4 destination they carry rather than
|
|
380
|
+
* accepting the globally-looking IPv6 wrapper.
|
|
381
|
+
*/
|
|
382
|
+
if (
|
|
383
|
+
groups.slice(0, 6).every((group: number) => {
|
|
384
|
+
return group === 0;
|
|
385
|
+
})
|
|
386
|
+
) {
|
|
387
|
+
return this.checkIpv4(embeddedIpv4(6), blockPrivateAddresses);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// 6to4 (2002::/16) stores its IPv4 gateway in the next 32 bits.
|
|
391
|
+
if (groups[0] === 0x2002) {
|
|
392
|
+
return this.checkIpv4(embeddedIpv4(1), blockPrivateAddresses);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/*
|
|
396
|
+
* Teredo (2001:0000::/32) carries both a server IPv4 address and a
|
|
397
|
+
* bitwise-inverted client IPv4 address. Either endpoint being forbidden
|
|
398
|
+
* is enough to reject the route.
|
|
399
|
+
*/
|
|
400
|
+
if (groups[0] === 0x2001 && groups[1] === 0) {
|
|
401
|
+
return this.getStrictestVerdict(
|
|
402
|
+
this.checkIpv4(embeddedIpv4(2), blockPrivateAddresses),
|
|
403
|
+
this.checkIpv4(embeddedIpv4(6, true), blockPrivateAddresses),
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
|
|
312
407
|
const firstGroup: number = parseInt(expanded.substring(0, 4), 16);
|
|
313
408
|
// fe80::/10 link-local.
|
|
314
409
|
if ((firstGroup & 0xffc0) === 0xfe80) {
|
|
@@ -322,17 +417,52 @@ export default class DataSourceEgressGuard {
|
|
|
322
417
|
if (blockPrivateAddresses) {
|
|
323
418
|
// fc00::/7 unique-local.
|
|
324
419
|
if ((firstGroup & 0xfe00) === 0xfc00) {
|
|
325
|
-
return {
|
|
420
|
+
return {
|
|
421
|
+
blocked: true,
|
|
422
|
+
reason: "private network address",
|
|
423
|
+
isPrivateNetwork: true,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
// fec0::/10 deprecated site-local addresses are still routed in places.
|
|
427
|
+
if ((firstGroup & 0xffc0) === 0xfec0) {
|
|
428
|
+
return {
|
|
429
|
+
blocked: true,
|
|
430
|
+
reason: "private network address",
|
|
431
|
+
isPrivateNetwork: true,
|
|
432
|
+
};
|
|
326
433
|
}
|
|
327
434
|
// 2001:db8::/32 documentation.
|
|
328
435
|
if (expanded.startsWith("2001:0db8:")) {
|
|
329
|
-
return {
|
|
436
|
+
return {
|
|
437
|
+
blocked: true,
|
|
438
|
+
reason: "documentation address",
|
|
439
|
+
isPrivateNetwork: true,
|
|
440
|
+
};
|
|
330
441
|
}
|
|
331
442
|
}
|
|
332
443
|
|
|
333
444
|
return { blocked: false };
|
|
334
445
|
}
|
|
335
446
|
|
|
447
|
+
private static getStrictestVerdict(
|
|
448
|
+
left: AddressVerdict,
|
|
449
|
+
right: AddressVerdict,
|
|
450
|
+
): AddressVerdict {
|
|
451
|
+
if (left.blocked && !left.isPrivateNetwork) {
|
|
452
|
+
return left;
|
|
453
|
+
}
|
|
454
|
+
if (right.blocked && !right.isPrivateNetwork) {
|
|
455
|
+
return right;
|
|
456
|
+
}
|
|
457
|
+
if (left.blocked) {
|
|
458
|
+
return left;
|
|
459
|
+
}
|
|
460
|
+
if (right.blocked) {
|
|
461
|
+
return right;
|
|
462
|
+
}
|
|
463
|
+
return { blocked: false };
|
|
464
|
+
}
|
|
465
|
+
|
|
336
466
|
/*
|
|
337
467
|
* Verdict for a single literal IP address under the given (or derived)
|
|
338
468
|
* policy. Exposed for tests and for connectors that receive addresses
|
|
@@ -413,7 +543,9 @@ export default class DataSourceEgressGuard {
|
|
|
413
543
|
const verdict: AddressVerdict = this.checkAddress(bareHostname, options);
|
|
414
544
|
if (verdict.blocked) {
|
|
415
545
|
throw new BadDataException(
|
|
416
|
-
`${label} host ${bareHostname} is not allowed: ${verdict.reason}
|
|
546
|
+
`${label} host ${bareHostname} is not allowed: ${verdict.reason}.${
|
|
547
|
+
verdict.isPrivateNetwork ? options?.privateNetworkHint || "" : ""
|
|
548
|
+
}`,
|
|
417
549
|
);
|
|
418
550
|
}
|
|
419
551
|
return [{ address: bareHostname, family: net.isIP(bareHostname) }];
|
|
@@ -429,6 +561,11 @@ export default class DataSourceEgressGuard {
|
|
|
429
561
|
try {
|
|
430
562
|
addresses = await resolveFunction(bareHostname);
|
|
431
563
|
} catch (error) {
|
|
564
|
+
if (options?.includeResolvedAddressInError === false) {
|
|
565
|
+
throw new BadDataException(
|
|
566
|
+
`${label} host ${bareHostname} could not be reached.`,
|
|
567
|
+
);
|
|
568
|
+
}
|
|
432
569
|
throw new BadDataException(
|
|
433
570
|
`Could not resolve ${label.toLowerCase()} host ${bareHostname}: ${
|
|
434
571
|
error instanceof Error ? error.message : String(error)
|
|
@@ -437,6 +574,11 @@ export default class DataSourceEgressGuard {
|
|
|
437
574
|
}
|
|
438
575
|
|
|
439
576
|
if (addresses.length === 0) {
|
|
577
|
+
if (options?.includeResolvedAddressInError === false) {
|
|
578
|
+
throw new BadDataException(
|
|
579
|
+
`${label} host ${bareHostname} could not be reached.`,
|
|
580
|
+
);
|
|
581
|
+
}
|
|
440
582
|
throw new BadDataException(
|
|
441
583
|
`Could not resolve ${label.toLowerCase()} host ${bareHostname}.`,
|
|
442
584
|
);
|
|
@@ -448,8 +590,15 @@ export default class DataSourceEgressGuard {
|
|
|
448
590
|
options,
|
|
449
591
|
);
|
|
450
592
|
if (verdict.blocked) {
|
|
593
|
+
if (options?.includeResolvedAddressInError === false) {
|
|
594
|
+
throw new BadDataException(
|
|
595
|
+
`${label} host ${bareHostname} could not be reached.`,
|
|
596
|
+
);
|
|
597
|
+
}
|
|
451
598
|
throw new BadDataException(
|
|
452
|
-
`${label} host ${bareHostname} resolves to ${resolved.address}, which is not allowed: ${verdict.reason}
|
|
599
|
+
`${label} host ${bareHostname} resolves to ${resolved.address}, which is not allowed: ${verdict.reason}.${
|
|
600
|
+
verdict.isPrivateNetwork ? options?.privateNetworkHint || "" : ""
|
|
601
|
+
}`,
|
|
453
602
|
);
|
|
454
603
|
}
|
|
455
604
|
}
|
|
@@ -510,20 +659,40 @@ export default class DataSourceEgressGuard {
|
|
|
510
659
|
): EgressLookupFunction {
|
|
511
660
|
return (
|
|
512
661
|
_hostname: string,
|
|
513
|
-
lookupOptions: {
|
|
662
|
+
lookupOptions: {
|
|
663
|
+
all?: boolean | undefined;
|
|
664
|
+
family?: number | undefined;
|
|
665
|
+
},
|
|
514
666
|
callback: EgressLookupCallback,
|
|
515
667
|
): void => {
|
|
668
|
+
const wantedFamily: number | undefined = lookupOptions?.family;
|
|
669
|
+
const usableAddresses: Array<ResolvedAddress> =
|
|
670
|
+
wantedFamily === 4 || wantedFamily === 6
|
|
671
|
+
? addresses.filter((resolved: ResolvedAddress) => {
|
|
672
|
+
return resolved.family === wantedFamily;
|
|
673
|
+
})
|
|
674
|
+
: addresses;
|
|
675
|
+
|
|
676
|
+
if (usableAddresses.length === 0) {
|
|
677
|
+
const error: NodeJS.ErrnoException = new Error(
|
|
678
|
+
`No IPv${wantedFamily} address is available for the validated host.`,
|
|
679
|
+
);
|
|
680
|
+
error.code = "ENOTFOUND";
|
|
681
|
+
callback(error, "");
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
|
|
516
685
|
if (lookupOptions && lookupOptions.all) {
|
|
517
686
|
callback(
|
|
518
687
|
null,
|
|
519
|
-
|
|
688
|
+
usableAddresses.map((resolved: ResolvedAddress) => {
|
|
520
689
|
return { address: resolved.address, family: resolved.family };
|
|
521
690
|
}),
|
|
522
691
|
);
|
|
523
692
|
return;
|
|
524
693
|
}
|
|
525
694
|
|
|
526
|
-
const first: ResolvedAddress =
|
|
695
|
+
const first: ResolvedAddress = usableAddresses[0]!;
|
|
527
696
|
callback(null, first.address, first.family);
|
|
528
697
|
};
|
|
529
698
|
}
|
|
@@ -19,13 +19,46 @@ export const ROLLUP_SWEEP_LOCK_NAMESPACE: string = "Workers.Cron";
|
|
|
19
19
|
/*
|
|
20
20
|
* The FIRST BURST_THRESHOLD rollup-eligible owner emails for one
|
|
21
21
|
* (project, user, address, category) inside BURST_WINDOW_MINUTES are sent
|
|
22
|
-
* immediately; the next one and everything after it is coalesced.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* immediately; the next one and everything after it is coalesced.
|
|
23
|
+
*
|
|
24
|
+
* THE WINDOW IS THIRTY MINUTES BECAUSE TEN CANNOT SEE A SLOW FLAP.
|
|
25
|
+
*
|
|
26
|
+
* The flood this feature exists for is not a spike. The recommendation
|
|
27
|
+
* monitors fixed in RecommendationCriteriaBuilder.ts produced 39 owner emails
|
|
28
|
+
* - 19 open, 20 resolve - from ONE monitor in under two hours: about 3.3
|
|
29
|
+
* items per ten minutes. Both event types are RollupCategory.Alerts, so they
|
|
30
|
+
* share one counter, and 3.3 sits under a trip point of four. A rate like
|
|
31
|
+
* that is invisible to a ten-minute window and obvious to a thirty-minute
|
|
32
|
+
* one, which sees the same flap as about ten items and coalesces from the
|
|
33
|
+
* fifth onwards.
|
|
34
|
+
*
|
|
35
|
+
* Stated precisely, because the number deserves it: rollup did not exist
|
|
36
|
+
* while that cluster was flapping. This is what a ten-minute window WOULD
|
|
37
|
+
* have missed, not a throttle that was observed to fail. The flapping itself
|
|
38
|
+
* is fixed at source; this is the second line of defence, and it is worth
|
|
39
|
+
* sizing against the case that actually got through.
|
|
40
|
+
*
|
|
41
|
+
* WHAT IT COSTS. A row is written for every eligible email, deferred ones
|
|
42
|
+
* included, so the counter tracks the true arrival rate and does not decay
|
|
43
|
+
* while a bucket is being coalesced. Tripling the window therefore triples
|
|
44
|
+
* how long the throttle REMEMBERS: a project with three separate incidents in
|
|
45
|
+
* half an hour now has the third one's CREATION email deferred by
|
|
46
|
+
* FLUSH_AFTER_MINUTES, not merely the tail of the second. That is the real
|
|
47
|
+
* trade, and it is reversible with the same one-line edit.
|
|
48
|
+
*
|
|
49
|
+
* Four survives the change because it still covers one incident's whole
|
|
50
|
+
* normal lifecycle (created -> acknowledged -> resolved) plus one more event.
|
|
51
|
+
* What it no longer promises is headroom for a SECOND unrelated incident in
|
|
52
|
+
* the same window; that is the cost above, and it is deliberate.
|
|
53
|
+
*
|
|
54
|
+
* Nothing is dropped - deferred items arrive together FLUSH_AFTER_MINUTES
|
|
55
|
+
* later - and no page is affected, because escalation notifications call
|
|
56
|
+
* MailService directly from UserNotificationRuleService and never reach this
|
|
57
|
+
* code at all. The per-user opt-out EmailRollupWriter consults still wins
|
|
58
|
+
* over both numbers.
|
|
26
59
|
*/
|
|
27
60
|
export const BURST_THRESHOLD: number = 4;
|
|
28
|
-
export const BURST_WINDOW_MINUTES: number =
|
|
61
|
+
export const BURST_WINDOW_MINUTES: number = 30;
|
|
29
62
|
|
|
30
63
|
/*
|
|
31
64
|
* A deferred item is due once it is this old. Also the claim-epoch length,
|