@oneuptime/common 12.0.32 → 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/AnalyticsModels/Span.ts +14 -0
- package/Models/DatabaseModels/AlertCustomField.ts +77 -3
- package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
- package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/Index.ts +10 -0
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/Monitor.ts +76 -0
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
- package/Models/DatabaseModels/NetworkDevice.ts +176 -1
- package/Models/DatabaseModels/NetworkSite.ts +201 -2
- package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
- package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
- package/Models/DatabaseModels/RumApplication.ts +6 -6
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
- package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamMember.ts +0 -9
- package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamPermission.ts +3 -24
- package/Models/DatabaseModels/TelemetryException.ts +119 -0
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
- package/Models/DatabaseModels/UserTelegram.ts +0 -4
- package/Scripts/benchmark-fanin-capacity.js +181 -0
- package/Server/API/EnterpriseLicenseAPI.ts +391 -64
- package/Server/API/LlmProviderAPI.ts +137 -22
- 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 +49 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
- 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 +20 -0
- package/Server/Infrastructure/QueueWorker.ts +59 -23
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
- package/Server/Middleware/ProjectAuthorization.ts +11 -0
- package/Server/Middleware/SCIMAuthorization.ts +12 -0
- package/Server/Middleware/TelemetryIngest.ts +464 -7
- package/Server/Services/AIBillingService.ts +101 -27
- 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/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -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/Index.ts +10 -0
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +175 -21
- package/Server/Services/MonitorStatusTimelineService.ts +150 -8
- package/Server/Services/MonitorTemplateService.ts +217 -1
- package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
- package/Server/Services/NetworkAlertPolicyService.ts +944 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +87 -35
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
- package/Server/Services/NetworkDeviceService.ts +1032 -73
- package/Server/Services/NetworkSiteService.ts +1502 -129
- package/Server/Services/NetworkSiteTypeService.ts +1216 -0
- package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
- package/Server/Services/NotificationService.ts +118 -28
- package/Server/Services/ProjectService.ts +127 -48
- 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/StatusPagePrivateUserService.ts +103 -3
- package/Server/Services/TeamMemberService.ts +78 -0
- package/Server/Services/TeamPermissionService.ts +235 -3
- package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
- package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
- package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
- package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
- package/Server/Services/UserNotificationSettingService.ts +90 -25
- package/Server/Services/UserService.ts +95 -0
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/QueryHelper.ts +4 -2
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
- package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
- package/Server/Utils/APIKey/AccessPermission.ts +5 -2
- package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
- 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/DataSource/HttpFetch.ts +9 -2
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +131 -0
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +925 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
- package/Server/Utils/FrontendEnvironment.ts +40 -0
- package/Server/Utils/LLM/LLMService.ts +78 -0
- package/Server/Utils/LogRedaction.ts +28 -0
- package/Server/Utils/Logger.ts +90 -1
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
- package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +159 -15
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +72 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
- package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
- package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
- package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
- package/Server/Utils/OutboundUserAgent.ts +152 -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 +53 -36
- package/Server/Utils/TelegramVerificationToken.ts +185 -0
- package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
- package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/SpanUtil.ts +33 -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/Telemetry.ts +198 -51
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +975 -95
- package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
- package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
- package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +486 -9
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
- package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
- package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
- package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
- package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
- package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
- package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
- package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
- package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
- package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
- package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
- package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
- package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
- package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
- package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -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/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
- package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -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/AIChatPrivacyPin.test.ts +560 -0
- 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/BillingRechargeOwnerEmailGuards.test.ts +783 -0
- 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/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
- package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
- package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
- package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
- package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +273 -5
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
- package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
- package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
- package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
- package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
- package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
- package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
- package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
- package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
- package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
- package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
- package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
- package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -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/UserEmailChangePasswordResetExpiry.test.ts +472 -0
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +997 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +110 -1
- package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
- package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
- package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -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/Captcha.test.ts +422 -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/DataSource/HttpFetch.test.ts +96 -2
- package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +828 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
- 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/LoggerFaultDemotion.test.ts +346 -0
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
- package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
- package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
- package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
- package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
- package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
- package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -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/ErrorClassResolver.test.ts +298 -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/Telemetry.test.ts +456 -66
- 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/DatabaseMetricCatalog.test.ts +388 -0
- 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/MonitorStepDatabaseMonitor.test.ts +243 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
- 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/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
- package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -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/Telemetry/ErrorClass.test.ts +483 -0
- package/Tests/Types/WebsiteRequest.test.ts +285 -3
- package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
- 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 +43 -12
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
- package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
- package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
- package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -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/UI/Utils/PageScrollLock.test.tsx +377 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
- package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
- package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
- package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
- package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
- package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
- package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
- package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
- package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
- package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -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/CaptureSpanExportGating.test.ts +145 -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/AI/ExceptionAIClassification.ts +10 -24
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
- package/Types/Exception/ApiException.ts +10 -0
- package/Types/Exception/BadDataException.ts +11 -0
- package/Types/Exception/BadRequestException.ts +11 -0
- package/Types/Exception/Exception.ts +65 -0
- package/Types/Exception/ForbiddenException.ts +10 -0
- package/Types/Exception/NotAuthenticatedException.ts +10 -0
- package/Types/Exception/NotAuthorizedException.ts +10 -0
- package/Types/Exception/NotFoundException.ts +11 -0
- package/Types/Exception/PayloadTooLargeException.ts +11 -0
- package/Types/Exception/PaymentRequiredException.ts +10 -0
- package/Types/Exception/ServiceUnavailableException.ts +10 -0
- package/Types/Exception/SsoAuthorizationException.ts +10 -0
- package/Types/Exception/TenantNotFoundException.ts +11 -0
- package/Types/Exception/TimeoutException.ts +10 -0
- package/Types/Exception/TooManyRequestsException.ts +10 -0
- package/Types/Exception/UnableToReachServer.ts +10 -0
- package/Types/Exception/WebsiteRequestException.ts +10 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSONFunctions.ts +189 -43
- package/Types/Monitor/CephAlertTemplates.ts +157 -195
- package/Types/Monitor/CriteriaFilter.ts +60 -2
- package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
- 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/MonitorCriteriaInstance.ts +76 -0
- package/Types/Monitor/MonitorMetricType.ts +71 -0
- package/Types/Monitor/MonitorStep.ts +76 -0
- package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
- package/Types/Monitor/MonitorType.ts +47 -1
- package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
- package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
- package/Types/Monitor/RumAlertTemplates.ts +46 -7
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
- package/Types/Monitor/SqlConnectionConfig.ts +31 -0
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
- package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
- package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
- package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
- package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
- package/Types/Permission.ts +90 -0
- package/Types/Probe/ProbeMonitorResponse.ts +16 -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/ErrorClass.ts +274 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
- package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
- package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
- package/Types/Telemetry/UnitOfWork.ts +59 -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/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -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/Modal/Modal.tsx +2 -8
- 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 +88 -0
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
- package/UI/Components/SideMenu/SideMenu.tsx +123 -5
- package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
- package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
- package/UI/Components/SideOver/SideOver.tsx +21 -20
- 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/PageScrollLock.ts +79 -3
- package/UI/Utils/PermissionGate.ts +61 -0
- package/UI/Utils/SensitiveUrlToken.ts +112 -0
- package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
- package/UI/Utils/Telemetry/Telemetry.ts +10 -8
- package/UI/Utils/TestLLMProvider.ts +11 -0
- package/Utils/API.ts +129 -3
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/Monitor/MonitorMetricType.ts +153 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
- package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
- package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
- package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
- package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
- package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -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/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.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/EnterpriseLicense.js +59 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.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/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.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/Monitor.js +75 -0
- package/build/dist/Models/DatabaseModels/Monitor.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/NetworkAlertPolicy.js +713 -0
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
- 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/TelemetryException.js +123 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.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/UserNotificationEmailRollupBatch.js +363 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +108 -13
- package/build/dist/Server/API/LlmProviderAPI.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 +41 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
- 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 +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +52 -12
- 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/BearerTokenAuthorization.js +12 -0
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +326 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIBillingService.js +70 -16
- package/build/dist/Server/Services/AIBillingService.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/EnterpriseLicenseInstanceService.js +167 -0
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +133 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +32 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -0
- package/build/dist/Server/Services/Index.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 +148 -21
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +89 -36
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
- package/build/dist/Server/Services/NotificationService.js +80 -17
- package/build/dist/Server/Services/NotificationService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +88 -30
- 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/StatusPagePrivateUserService.js +92 -2
- package/build/dist/Server/Services/StatusPagePrivateUserService.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/UserNotificationEmailRollupBatchService.js +76 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +66 -20
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +90 -0
- package/build/dist/Server/Services/UserService.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 +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.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/Billing/BillingFailureNoticeThrottle.js +59 -0
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
- 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/DataSource/HttpFetch.js +2 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +124 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +733 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
- package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +28 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +73 -1
- 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/DatabaseMonitorCriteria.js +141 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.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/MonitorCriteriaDataExtractor.js +7 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +125 -13
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +54 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
- package/build/dist/Server/Utils/OutboundUserAgent.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 +41 -28
- 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/CaptureSpan.js +28 -8
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.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/SpanUtil.js +29 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry.js +162 -46
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- 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/AI/ExceptionAIClassification.js +10 -24
- package/build/dist/Types/AI/ExceptionAIClassification.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/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
- package/build/dist/Types/Exception/ApiException.js +9 -0
- package/build/dist/Types/Exception/ApiException.js.map +1 -1
- package/build/dist/Types/Exception/BadDataException.js +10 -0
- package/build/dist/Types/Exception/BadDataException.js.map +1 -1
- package/build/dist/Types/Exception/BadRequestException.js +10 -0
- package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
- package/build/dist/Types/Exception/Exception.js +56 -0
- package/build/dist/Types/Exception/Exception.js.map +1 -1
- package/build/dist/Types/Exception/ForbiddenException.js +9 -0
- package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
- package/build/dist/Types/Exception/NotFoundException.js +10 -0
- package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
- package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
- package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
- package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
- package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
- package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
- package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/TimeoutException.js +9 -0
- package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
- package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
- package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
- package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
- package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
- package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/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/CriteriaFilter.js +45 -2
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
- 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/MonitorCriteriaInstance.js +70 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +54 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +45 -1
- package/build/dist/Types/Monitor/MonitorType.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/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
- package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.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/Permission.js +80 -0
- package/build/dist/Types/Permission.js.map +1 -1
- 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/ErrorClass.js +216 -0
- package/build/dist/Types/Telemetry/ErrorClass.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/Telemetry/UnitOfWork.js +59 -0
- package/build/dist/Types/Telemetry/UnitOfWork.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/CommandPalette/CommandPalette.js +2 -7
- package/build/dist/UI/Components/CommandPalette/CommandPalette.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/EditionLabel/EditionLabel.js +3 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- 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/Modal/Modal.js +2 -7
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- 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 +77 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
- package/build/dist/UI/Components/SideOver/SideOver.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/PageScrollLock.js +31 -3
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +42 -1
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
- package/build/dist/UI/Utils/SensitiveUrlToken.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/UI/Utils/TestLLMProvider.js +4 -5
- package/build/dist/UI/Utils/TestLLMProvider.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/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.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/Monitor/MonitorMetricType.js +109 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.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 +2 -2
|
@@ -33,9 +33,13 @@ import ProjectService from "../Services/ProjectService";
|
|
|
33
33
|
import SessionReplayIdentity from "../Utils/SessionReplay/SessionReplayIdentity";
|
|
34
34
|
import SessionReplayTargeting from "../Utils/SessionReplay/SessionReplayTargeting";
|
|
35
35
|
import SessionReplayUsage from "../Utils/SessionReplay/SessionReplayUsage";
|
|
36
|
-
import RumSessionReplayViewService from "../Services/RumSessionReplayViewService";
|
|
37
|
-
import SessionReplayReadService, { DEFAULT_SESSION_REPLAY_LIST_LIMIT, MAX_SESSION_REPLAY_FOR_EXCEPTION_LIMIT, } from "../Utils/SessionReplay/SessionReplayReadService";
|
|
38
|
-
import
|
|
36
|
+
import RumSessionReplayViewService, { normalizeSecondsWatched, } from "../Services/RumSessionReplayViewService";
|
|
37
|
+
import SessionReplayReadService, { DEFAULT_SESSION_REPLAY_LIST_LIMIT, MAX_SESSION_REPLAY_FOR_EXCEPTION_LIMIT, MAX_SESSION_REPLAY_LIST_LIMIT, SESSION_REPLAY_EXCEPTION_WINDOW_PADDING_MS, } from "../Utils/SessionReplay/SessionReplayReadService";
|
|
38
|
+
import SessionReplayHealthCounters from "../Utils/SessionReplay/SessionReplayHealthCounters";
|
|
39
|
+
import { isSessionErased } from "../Utils/SessionReplay/SessionReplayErasureTombstone";
|
|
40
|
+
import NotFoundException from "../../Types/Exception/NotFoundException";
|
|
41
|
+
import { DEFAULT_SESSION_REPLAY_MAX_BYTES_PER_PROJECT_PER_DAY, MAX_SESSION_REPLAY_CHUNKS_PER_READ, MAX_SESSION_REPLAY_READ_BYTES, SESSION_REPLAY_LIST_SEARCH_MAX_LENGTH, SESSION_REPLAY_LIST_SEARCH_MAX_WINDOW_DAYS, SESSION_REPLAY_MAX_SESSION_MS, SESSION_REPLAY_MAX_TAG_KEYS, SESSION_REPLAY_MAX_TAG_KEY_LENGTH, SESSION_REPLAY_MAX_TAG_VALUE_LENGTH, SESSION_REPLAY_MAX_USER_REF_LENGTH, } from "../../Types/Rum/SessionReplay";
|
|
42
|
+
import { SESSION_REPLAY_SORT_BY_VALUES, parseSessionReplayListCursor, } from "../../Types/Rum/SessionReplayApi";
|
|
39
43
|
const router = Express.getRouter();
|
|
40
44
|
const createTelemetryReadAccessGuard = (signalReadPermission) => {
|
|
41
45
|
return [
|
|
@@ -2269,8 +2273,49 @@ const isApplicationInSessionReplayScope = (data) => {
|
|
|
2269
2273
|
return applicationLabelIds.includes(labelId.toString());
|
|
2270
2274
|
});
|
|
2271
2275
|
};
|
|
2272
|
-
|
|
2273
|
-
|
|
2276
|
+
/*
|
|
2277
|
+
* Returns the application so callers that need its labels for a second,
|
|
2278
|
+
* narrower decision (the identity column) do not have to load it twice.
|
|
2279
|
+
*/
|
|
2280
|
+
/*
|
|
2281
|
+
* Process-local memory of what the two playback hot paths re-derive on
|
|
2282
|
+
* every call: which application a session belongs to (a ClickHouse GROUP
|
|
2283
|
+
* BY over the header table) and which labels that application carries (a
|
|
2284
|
+
* Postgres lookup). A 480-chunk session is 60 chunk pages, and a live
|
|
2285
|
+
* player heartbeats every 15s; without this every one of those paid both
|
|
2286
|
+
* lookups again for an answer that had not changed.
|
|
2287
|
+
*
|
|
2288
|
+
* What is cached is the DATA, never the decision: the label intersection
|
|
2289
|
+
* is recomputed against the caller's current permissions on every
|
|
2290
|
+
* request, so a revoked grant takes effect immediately. A label edit on
|
|
2291
|
+
* the application, or a header re-resolution, lags by at most the TTL -
|
|
2292
|
+
* the same lag the ingest gate's policy cache already accepts. The
|
|
2293
|
+
* manifest route always resolves fresh (a live session's header changes)
|
|
2294
|
+
* and refills the entries the chunk and heartbeat routes then read.
|
|
2295
|
+
*/
|
|
2296
|
+
const SESSION_REPLAY_AUTHORIZATION_CACHE_TTL_MS = 30 * 1000;
|
|
2297
|
+
const MAX_SESSION_REPLAY_AUTHORIZATION_CACHE_ENTRIES = 2000;
|
|
2298
|
+
const rumApplicationCache = new Map();
|
|
2299
|
+
const sessionHeaderCache = new Map();
|
|
2300
|
+
const boundedCacheSet = (map, key, value) => {
|
|
2301
|
+
if (map.size >= MAX_SESSION_REPLAY_AUTHORIZATION_CACHE_ENTRIES &&
|
|
2302
|
+
!map.has(key)) {
|
|
2303
|
+
const oldest = map.keys().next().value;
|
|
2304
|
+
if (oldest !== undefined) {
|
|
2305
|
+
map.delete(oldest);
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
map.delete(key);
|
|
2309
|
+
map.set(key, value);
|
|
2310
|
+
};
|
|
2311
|
+
const loadRumApplicationForAccess = async (data) => {
|
|
2312
|
+
const cacheKey = `${data.projectId.toString()}:${data.rumApplicationId.toString()}`;
|
|
2313
|
+
if (data.allowCached) {
|
|
2314
|
+
const cached = rumApplicationCache.get(cacheKey);
|
|
2315
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
2316
|
+
return cached.application;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2274
2319
|
const application = await RumApplicationService.findOneBy({
|
|
2275
2320
|
query: {
|
|
2276
2321
|
_id: data.rumApplicationId.toString(),
|
|
@@ -2286,6 +2331,21 @@ const assertSessionReplayApplicationAccess = async (data) => {
|
|
|
2286
2331
|
isRoot: true,
|
|
2287
2332
|
},
|
|
2288
2333
|
});
|
|
2334
|
+
if (application) {
|
|
2335
|
+
boundedCacheSet(rumApplicationCache, cacheKey, {
|
|
2336
|
+
application: application,
|
|
2337
|
+
expiresAt: Date.now() + SESSION_REPLAY_AUTHORIZATION_CACHE_TTL_MS,
|
|
2338
|
+
});
|
|
2339
|
+
}
|
|
2340
|
+
return application;
|
|
2341
|
+
};
|
|
2342
|
+
const assertSessionReplayApplicationAccess = async (data) => {
|
|
2343
|
+
const scope = getSessionReplayLabelScope(data.databaseProps, data.permissions);
|
|
2344
|
+
const application = await loadRumApplicationForAccess({
|
|
2345
|
+
projectId: data.projectId,
|
|
2346
|
+
rumApplicationId: data.rumApplicationId,
|
|
2347
|
+
allowCached: data.allowCached === true,
|
|
2348
|
+
});
|
|
2289
2349
|
/*
|
|
2290
2350
|
* An application that does not exist in this project is refused the
|
|
2291
2351
|
* same way an out-of-scope one is, so the endpoint cannot be used to
|
|
@@ -2367,21 +2427,177 @@ const resolveAccessibleRumApplicationIds = async (data) => {
|
|
|
2367
2427
|
}
|
|
2368
2428
|
return { applicationIds: accessibleIds, isTruncated: isTruncated };
|
|
2369
2429
|
};
|
|
2370
|
-
|
|
2371
|
-
|
|
2430
|
+
/*
|
|
2431
|
+
* Why a sessionId has no playable header. Each answer carries a
|
|
2432
|
+
* different code word in its message so a client can tell them apart
|
|
2433
|
+
* without parsing prose, and each is a 404: the id was well-formed, there
|
|
2434
|
+
* is simply nothing at it.
|
|
2435
|
+
*/
|
|
2436
|
+
const GENERIC_MISSING_SESSION_MESSAGE = "not-found: No session replay exists with this id in this project.";
|
|
2437
|
+
const isApplicationInSessionReplayScopeById = async (data) => {
|
|
2438
|
+
let scope;
|
|
2439
|
+
try {
|
|
2440
|
+
scope = getSessionReplayLabelScope(data.databaseProps, SESSION_REPLAY_PAYLOAD_PERMISSIONS);
|
|
2441
|
+
}
|
|
2442
|
+
catch (_a) {
|
|
2443
|
+
/* A scope this path cannot enforce is refused, never widened. */
|
|
2444
|
+
return false;
|
|
2445
|
+
}
|
|
2446
|
+
if (scope.isUnrestricted) {
|
|
2447
|
+
return true;
|
|
2448
|
+
}
|
|
2449
|
+
if (!ObjectID.isValidUUID(data.rumApplicationId)) {
|
|
2450
|
+
return false;
|
|
2451
|
+
}
|
|
2452
|
+
const application = await loadRumApplicationForAccess({
|
|
2453
|
+
projectId: data.projectId,
|
|
2454
|
+
rumApplicationId: new ObjectID(data.rumApplicationId),
|
|
2455
|
+
allowCached: true,
|
|
2456
|
+
});
|
|
2457
|
+
if (!application) {
|
|
2458
|
+
return false;
|
|
2459
|
+
}
|
|
2460
|
+
return isApplicationInSessionReplayScope({
|
|
2461
|
+
scope: scope,
|
|
2462
|
+
application: application,
|
|
2463
|
+
});
|
|
2464
|
+
};
|
|
2465
|
+
const explainMissingSession = async (data) => {
|
|
2466
|
+
/*
|
|
2467
|
+
* The expired header is resolved FIRST, and not because it is the more
|
|
2468
|
+
* likely answer: it is the only lookup that names an application, and
|
|
2469
|
+
* nothing specific may be disclosed until that application has been
|
|
2470
|
+
* authorized.
|
|
2471
|
+
*
|
|
2472
|
+
* The expiry answer carries the recording's existence, when it started
|
|
2473
|
+
* and what retention the owning application runs. Answered before the
|
|
2474
|
+
* access check - which is where it used to sit, since this runs on the
|
|
2475
|
+
* path where getSessionHeader found nothing to authorize AGAINST - it let
|
|
2476
|
+
* a label-scoped reviewer probe session ids and learn all three for
|
|
2477
|
+
* applications outside their scope. That is precisely the existence
|
|
2478
|
+
* probing assertSessionReplayApplicationAccess refuses "the same way" for
|
|
2479
|
+
* a session that DOES exist.
|
|
2480
|
+
*
|
|
2481
|
+
* This read is deliberately retention-free (an expired row is the whole
|
|
2482
|
+
* point), so it is the one place a scope check has to be written out by
|
|
2483
|
+
* hand rather than inherited from resolveAuthorizedSession.
|
|
2484
|
+
*/
|
|
2485
|
+
const expired = await SessionReplayReadService.getExpiredSessionInfo({
|
|
2372
2486
|
projectId: data.projectId,
|
|
2373
2487
|
sessionId: data.sessionId,
|
|
2488
|
+
rumApplicationId: data.rumApplicationId,
|
|
2374
2489
|
});
|
|
2490
|
+
if (expired && expired.rumApplicationId) {
|
|
2491
|
+
if (!(await isApplicationInSessionReplayScopeById({
|
|
2492
|
+
projectId: data.projectId,
|
|
2493
|
+
rumApplicationId: expired.rumApplicationId,
|
|
2494
|
+
databaseProps: data.databaseProps,
|
|
2495
|
+
}))) {
|
|
2496
|
+
return new NotFoundException(GENERIC_MISSING_SESSION_MESSAGE);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
/*
|
|
2500
|
+
* Erasure is checked only once the caller is entitled to a specific
|
|
2501
|
+
* answer. An erased session may still have a header row until the
|
|
2502
|
+
* ClickHouse mutation lands, and "expired" would be the wrong story for
|
|
2503
|
+
* a recording that was deliberately destroyed - so it is reported ahead
|
|
2504
|
+
* of expiry. The tombstone throws when Redis cannot answer; that is a
|
|
2505
|
+
* "cannot tell", which falls through to the header-based answers.
|
|
2506
|
+
*/
|
|
2507
|
+
let isErased = false;
|
|
2508
|
+
try {
|
|
2509
|
+
isErased = await isSessionErased({
|
|
2510
|
+
projectId: data.projectId.toString(),
|
|
2511
|
+
sessionId: data.sessionId,
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2514
|
+
catch (_a) {
|
|
2515
|
+
isErased = false;
|
|
2516
|
+
}
|
|
2517
|
+
if (isErased) {
|
|
2518
|
+
return new NotFoundException("erased: This recording was erased by a data subject request and cannot be played back.");
|
|
2519
|
+
}
|
|
2520
|
+
if (expired) {
|
|
2521
|
+
const retentionDays = Math.max(1, Math.round((expired.expiresAt.getTime() - expired.startTime.getTime()) /
|
|
2522
|
+
(24 * 60 * 60 * 1000)));
|
|
2523
|
+
return new NotFoundException(`expired: This recording expired on ${expired.expiresAt.toISOString()} under the application's ${retentionDays}-day retention. Its session signals may still be available from logs, traces and exceptions.`);
|
|
2524
|
+
}
|
|
2525
|
+
return new NotFoundException(GENERIC_MISSING_SESSION_MESSAGE);
|
|
2526
|
+
};
|
|
2527
|
+
const resolveAuthorizedSession = async (data) => {
|
|
2528
|
+
const headerCacheKey = `${data.projectId.toString()}:${data.sessionId}:${data.rumApplicationId ? data.rumApplicationId.toString() : ""}`;
|
|
2529
|
+
let header = null;
|
|
2530
|
+
if (data.allowCached) {
|
|
2531
|
+
const cached = sessionHeaderCache.get(headerCacheKey);
|
|
2532
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
2533
|
+
header = cached.header;
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2375
2536
|
if (!header) {
|
|
2376
|
-
|
|
2537
|
+
header = await SessionReplayReadService.getSessionHeader({
|
|
2538
|
+
projectId: data.projectId,
|
|
2539
|
+
sessionId: data.sessionId,
|
|
2540
|
+
rumApplicationId: data.rumApplicationId,
|
|
2541
|
+
});
|
|
2542
|
+
if (header) {
|
|
2543
|
+
boundedCacheSet(sessionHeaderCache, headerCacheKey, {
|
|
2544
|
+
header: header,
|
|
2545
|
+
expiresAt: Date.now() + SESSION_REPLAY_AUTHORIZATION_CACHE_TTL_MS,
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2377
2548
|
}
|
|
2378
|
-
|
|
2549
|
+
if (!header) {
|
|
2550
|
+
throw await explainMissingSession({
|
|
2551
|
+
projectId: data.projectId,
|
|
2552
|
+
sessionId: data.sessionId,
|
|
2553
|
+
rumApplicationId: data.rumApplicationId,
|
|
2554
|
+
databaseProps: data.databaseProps,
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2557
|
+
const application = await assertSessionReplayApplicationAccess({
|
|
2379
2558
|
projectId: data.projectId,
|
|
2380
2559
|
rumApplicationId: new ObjectID(header.rumApplicationId),
|
|
2381
2560
|
databaseProps: data.databaseProps,
|
|
2382
2561
|
permissions: SESSION_REPLAY_PAYLOAD_PERMISSIONS,
|
|
2562
|
+
allowCached: data.allowCached,
|
|
2383
2563
|
});
|
|
2384
|
-
return header;
|
|
2564
|
+
return { header: header, application: application };
|
|
2565
|
+
};
|
|
2566
|
+
const readOptionalObjectIdFromBody = (body, key) => {
|
|
2567
|
+
const value = body[key];
|
|
2568
|
+
if (value === undefined || value === null || value === "") {
|
|
2569
|
+
return undefined;
|
|
2570
|
+
}
|
|
2571
|
+
if (typeof value !== "string" || !ObjectID.isValidUUID(value)) {
|
|
2572
|
+
throw new BadDataException(`${key} is not a valid id`);
|
|
2573
|
+
}
|
|
2574
|
+
return new ObjectID(value);
|
|
2575
|
+
};
|
|
2576
|
+
const readOptionalDateFromBody = (body, key) => {
|
|
2577
|
+
const value = body[key];
|
|
2578
|
+
if (value === undefined || value === null || value === "") {
|
|
2579
|
+
return undefined;
|
|
2580
|
+
}
|
|
2581
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
2582
|
+
throw new BadDataException(`${key} must be an ISO-8601 timestamp`);
|
|
2583
|
+
}
|
|
2584
|
+
const parsed = typeof value === "number"
|
|
2585
|
+
? new Date(value)
|
|
2586
|
+
: OneUptimeDate.fromString(value);
|
|
2587
|
+
if (!Number.isFinite(parsed.getTime())) {
|
|
2588
|
+
throw new BadDataException(`${key} must be an ISO-8601 timestamp`);
|
|
2589
|
+
}
|
|
2590
|
+
return parsed;
|
|
2591
|
+
};
|
|
2592
|
+
const readLimitFromBody = (body, defaultLimit, maxLimit) => {
|
|
2593
|
+
const value = body["limit"];
|
|
2594
|
+
if (value === undefined || value === null) {
|
|
2595
|
+
return defaultLimit;
|
|
2596
|
+
}
|
|
2597
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
|
|
2598
|
+
throw new BadDataException(`limit must be a whole number between 1 and ${maxLimit}`);
|
|
2599
|
+
}
|
|
2600
|
+
return Math.min(value, maxLimit);
|
|
2385
2601
|
};
|
|
2386
2602
|
const readObjectIdFromBody = (body, key) => {
|
|
2387
2603
|
const value = body[key];
|
|
@@ -2393,23 +2609,91 @@ const readObjectIdFromBody = (body, key) => {
|
|
|
2393
2609
|
}
|
|
2394
2610
|
return new ObjectID(value);
|
|
2395
2611
|
};
|
|
2612
|
+
/*
|
|
2613
|
+
* A session id is 32 hex characters minted in the browser. The cap is
|
|
2614
|
+
* generous rather than exact - older recorders and hand-written API
|
|
2615
|
+
* callers exist - but it is a cap: an unbounded caller-supplied string
|
|
2616
|
+
* reaches ClickHouse as a bound parameter on a hot path.
|
|
2617
|
+
*/
|
|
2618
|
+
const MAX_SESSION_REPLAY_SESSION_ID_LENGTH = 128;
|
|
2396
2619
|
const readSessionIdFromBody = (body) => {
|
|
2397
2620
|
const sessionId = body["sessionId"];
|
|
2398
2621
|
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
2399
2622
|
throw new BadDataException("sessionId is required");
|
|
2400
2623
|
}
|
|
2624
|
+
if (sessionId.length > MAX_SESSION_REPLAY_SESSION_ID_LENGTH) {
|
|
2625
|
+
throw new BadDataException(`sessionId must be at most ${MAX_SESSION_REPLAY_SESSION_ID_LENGTH} characters.`);
|
|
2626
|
+
}
|
|
2401
2627
|
return sessionId;
|
|
2402
2628
|
};
|
|
2629
|
+
/*
|
|
2630
|
+
* Caps on the list's filter inputs.
|
|
2631
|
+
*
|
|
2632
|
+
* Every array filter becomes an `IN (...)` inside a HAVING, which
|
|
2633
|
+
* ClickHouse evaluates per GROUP over the whole window - so the cost of a
|
|
2634
|
+
* request is the caller's array length times the number of sessions in
|
|
2635
|
+
* range. Uncapped, one request carrying tens of thousands of browser names
|
|
2636
|
+
* is a cheap denial of service against the list for any holder of the list
|
|
2637
|
+
* permission. The limits are far above any real UI: the filter panel
|
|
2638
|
+
* offers a couple of dozen browsers, and no session has more than a
|
|
2639
|
+
* handful of routes.
|
|
2640
|
+
*
|
|
2641
|
+
* Values are TRUNCATED and the array is SLICED rather than refused: an
|
|
2642
|
+
* over-long value simply cannot match anything a bounded column holds, so
|
|
2643
|
+
* a 400 would add nothing but a confusing error.
|
|
2644
|
+
*/
|
|
2645
|
+
const MAX_SESSION_REPLAY_FILTER_ARRAY_LENGTH = 50;
|
|
2646
|
+
const MAX_SESSION_REPLAY_FILTER_VALUE_LENGTH = 256;
|
|
2403
2647
|
const readStringArrayFromBody = (body, key) => {
|
|
2404
2648
|
const value = body[key];
|
|
2405
2649
|
if (!Array.isArray(value)) {
|
|
2406
2650
|
return undefined;
|
|
2407
2651
|
}
|
|
2408
|
-
const strings =
|
|
2409
|
-
|
|
2410
|
-
|
|
2652
|
+
const strings = [];
|
|
2653
|
+
for (const item of value) {
|
|
2654
|
+
if (typeof item !== "string" || item.length === 0) {
|
|
2655
|
+
continue;
|
|
2656
|
+
}
|
|
2657
|
+
strings.push(item.substring(0, MAX_SESSION_REPLAY_FILTER_VALUE_LENGTH));
|
|
2658
|
+
if (strings.length >= MAX_SESSION_REPLAY_FILTER_ARRAY_LENGTH) {
|
|
2659
|
+
break;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2411
2662
|
return strings.length > 0 ? strings : undefined;
|
|
2412
2663
|
};
|
|
2664
|
+
const readBoundedStringFromBody = (body, key) => {
|
|
2665
|
+
const value = body[key];
|
|
2666
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
2667
|
+
return undefined;
|
|
2668
|
+
}
|
|
2669
|
+
return value.substring(0, MAX_SESSION_REPLAY_FILTER_VALUE_LENGTH);
|
|
2670
|
+
};
|
|
2671
|
+
const readTagFilterFromBody = (filters) => {
|
|
2672
|
+
const value = filters["tags"];
|
|
2673
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
2674
|
+
return undefined;
|
|
2675
|
+
}
|
|
2676
|
+
const tags = {};
|
|
2677
|
+
let count = 0;
|
|
2678
|
+
for (const key of Object.keys(value)) {
|
|
2679
|
+
const entry = value[key];
|
|
2680
|
+
if (typeof entry !== "string" || key.length === 0) {
|
|
2681
|
+
continue;
|
|
2682
|
+
}
|
|
2683
|
+
if (count >= SESSION_REPLAY_MAX_TAG_KEYS) {
|
|
2684
|
+
break;
|
|
2685
|
+
}
|
|
2686
|
+
tags[key.substring(0, SESSION_REPLAY_MAX_TAG_KEY_LENGTH)] = entry.substring(0, SESSION_REPLAY_MAX_TAG_VALUE_LENGTH);
|
|
2687
|
+
count++;
|
|
2688
|
+
}
|
|
2689
|
+
return count > 0 ? tags : undefined;
|
|
2690
|
+
};
|
|
2691
|
+
const isBindableCursorSortValue = (cursor, sortBy) => {
|
|
2692
|
+
if (sortBy === "startTime") {
|
|
2693
|
+
return Number.isFinite(new Date(cursor.sortValue).getTime());
|
|
2694
|
+
}
|
|
2695
|
+
return cursor.sortValue >= 0;
|
|
2696
|
+
};
|
|
2413
2697
|
// --- Session Replay List Endpoint ---
|
|
2414
2698
|
router.post("/telemetry/rum/session-replay/list", ...requireSessionReplayListAccess, async (req, res, next) => {
|
|
2415
2699
|
try {
|
|
@@ -2433,12 +2717,29 @@ router.post("/telemetry/rum/session-replay/list", ...requireSessionReplayListAcc
|
|
|
2433
2717
|
databaseProps: databaseProps,
|
|
2434
2718
|
permissions: SESSION_REPLAY_LIST_PERMISSIONS,
|
|
2435
2719
|
});
|
|
2436
|
-
const startTime = body
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2720
|
+
const startTime = readOptionalDateFromBody(body, "startTime") ||
|
|
2721
|
+
OneUptimeDate.addRemoveDays(OneUptimeDate.getCurrentDate(), -7);
|
|
2722
|
+
const endTime = readOptionalDateFromBody(body, "endTime") ||
|
|
2723
|
+
OneUptimeDate.getCurrentDate();
|
|
2724
|
+
/*
|
|
2725
|
+
* An inverted window matches nothing, and an empty list with a 200
|
|
2726
|
+
* is exactly the answer a client cannot distinguish from "no
|
|
2727
|
+
* sessions" - so it is a 400 with the reason instead.
|
|
2728
|
+
*/
|
|
2729
|
+
if (startTime.getTime() > endTime.getTime()) {
|
|
2730
|
+
return Response.sendErrorResponse(req, res, new BadDataException("startTime must not be after endTime"));
|
|
2731
|
+
}
|
|
2732
|
+
const limit = readLimitFromBody(body, DEFAULT_SESSION_REPLAY_LIST_LIMIT, MAX_SESSION_REPLAY_LIST_LIMIT);
|
|
2733
|
+
const rawSortBy = body["sortBy"];
|
|
2734
|
+
if (rawSortBy !== undefined &&
|
|
2735
|
+
rawSortBy !== null &&
|
|
2736
|
+
(typeof rawSortBy !== "string" ||
|
|
2737
|
+
!SESSION_REPLAY_SORT_BY_VALUES.includes(rawSortBy))) {
|
|
2738
|
+
return Response.sendErrorResponse(req, res, new BadDataException(`sortBy must be one of ${SESSION_REPLAY_SORT_BY_VALUES.join(", ")}.`));
|
|
2739
|
+
}
|
|
2740
|
+
const sortBy = typeof rawSortBy === "string"
|
|
2741
|
+
? rawSortBy
|
|
2742
|
+
: "startTime";
|
|
2442
2743
|
/*
|
|
2443
2744
|
* The narrower identity ACL, resolved BEFORE the filters are built.
|
|
2444
2745
|
*
|
|
@@ -2473,7 +2774,29 @@ router.post("/telemetry/rum/session-replay/list", ...requireSessionReplayListAcc
|
|
|
2473
2774
|
!SessionReplayIdentity.isUsableUserRef(rawFilters["identifiedUserRef"])) {
|
|
2474
2775
|
return Response.sendErrorResponse(req, res, new BadDataException(`identifiedUserRef must be a non-empty string of at most ${SESSION_REPLAY_MAX_USER_REF_LENGTH} characters.`));
|
|
2475
2776
|
}
|
|
2476
|
-
|
|
2777
|
+
/*
|
|
2778
|
+
* A filter the server understood but did not apply, named in the
|
|
2779
|
+
* response.
|
|
2780
|
+
*
|
|
2781
|
+
* The identity filter is gated on the narrower identity permission.
|
|
2782
|
+
* Dropping it silently is the dangerous half of that gate: the
|
|
2783
|
+
* request "show me jane@example.com's sessions" then answers 200 with
|
|
2784
|
+
* EVERY session in the application, and the caller has no way to tell
|
|
2785
|
+
* - least of all when the application has no sessions at all, where
|
|
2786
|
+
* even inspecting the rows cannot reveal it. A support engineer opens
|
|
2787
|
+
* the wrong recording, and each opening writes an audit row against a
|
|
2788
|
+
* real end user.
|
|
2789
|
+
*
|
|
2790
|
+
* Answered as data rather than as a 403 because the rest of the list
|
|
2791
|
+
* IS something the caller may read: the page renders the sessions and
|
|
2792
|
+
* says the filter was ignored, instead of failing outright.
|
|
2793
|
+
*/
|
|
2794
|
+
const ignoredFilters = [];
|
|
2795
|
+
if (!includeIdentifiedUserLabel &&
|
|
2796
|
+
SessionReplayIdentity.isUsableUserRef(rawFilters["identifiedUserRef"])) {
|
|
2797
|
+
ignoredFilters.push("identifiedUserRef");
|
|
2798
|
+
}
|
|
2799
|
+
const filters = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (typeof rawFilters["hasError"] === "boolean" && {
|
|
2477
2800
|
hasError: rawFilters["hasError"],
|
|
2478
2801
|
})), (typeof rawFilters["hasFrustration"] === "boolean" && {
|
|
2479
2802
|
hasFrustration: rawFilters["hasFrustration"],
|
|
@@ -2495,31 +2818,92 @@ router.post("/telemetry/rum/session-replay/list", ...requireSessionReplayListAcc
|
|
|
2495
2818
|
projectId: projectId,
|
|
2496
2819
|
userRef: rawFilters["identifiedUserRef"],
|
|
2497
2820
|
}),
|
|
2498
|
-
})), (
|
|
2821
|
+
})), (readBoundedStringFromBody(rawFilters, "identifiedUserKey") &&
|
|
2499
2822
|
!SessionReplayIdentity.isUsableUserRef(rawFilters["identifiedUserRef"]) && {
|
|
2500
|
-
identifiedUserKey: rawFilters
|
|
2501
|
-
})), (
|
|
2502
|
-
route: rawFilters
|
|
2503
|
-
})), (typeof rawFilters["minDurationMs"] === "number" &&
|
|
2823
|
+
identifiedUserKey: readBoundedStringFromBody(rawFilters, "identifiedUserKey"),
|
|
2824
|
+
})), (readBoundedStringFromBody(rawFilters, "route") && {
|
|
2825
|
+
route: readBoundedStringFromBody(rawFilters, "route"),
|
|
2826
|
+
})), (typeof rawFilters["minDurationMs"] === "number" &&
|
|
2827
|
+
Number.isFinite(rawFilters["minDurationMs"]) && {
|
|
2504
2828
|
minDurationMs: rawFilters["minDurationMs"],
|
|
2829
|
+
})), (typeof rawFilters["hasIdentifiedUser"] === "boolean" && {
|
|
2830
|
+
hasIdentifiedUser: rawFilters["hasIdentifiedUser"],
|
|
2831
|
+
})), (typeof rawFilters["isPlayable"] === "boolean" && {
|
|
2832
|
+
isPlayable: rawFilters["isPlayable"],
|
|
2833
|
+
})), (typeof rawFilters["hasTraces"] === "boolean" && {
|
|
2834
|
+
hasTraces: rawFilters["hasTraces"],
|
|
2835
|
+
})), (typeof rawFilters["urlPrefix"] === "string" &&
|
|
2836
|
+
rawFilters["urlPrefix"].length > 0 && {
|
|
2837
|
+
urlPrefix: rawFilters["urlPrefix"].substring(0, SESSION_REPLAY_LIST_SEARCH_MAX_LENGTH),
|
|
2838
|
+
})), (readTagFilterFromBody(rawFilters) && {
|
|
2839
|
+
tags: readTagFilterFromBody(rawFilters),
|
|
2505
2840
|
}));
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2841
|
+
/*
|
|
2842
|
+
* Free text is the one predicate that cannot use an index: it is a
|
|
2843
|
+
* substring scan of every header in the window. The string cap
|
|
2844
|
+
* keeps each comparison cheap; the window cap keeps the number of
|
|
2845
|
+
* comparisons bounded, and is answered with its own message so the
|
|
2846
|
+
* list can say "narrow the range" rather than "no sessions".
|
|
2847
|
+
*/
|
|
2848
|
+
const rawSearch = rawFilters["search"];
|
|
2849
|
+
if (rawSearch !== undefined && rawSearch !== null && rawSearch !== "") {
|
|
2850
|
+
if (typeof rawSearch !== "string") {
|
|
2851
|
+
return Response.sendErrorResponse(req, res, new BadDataException("search must be a string"));
|
|
2515
2852
|
}
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2853
|
+
if (rawSearch.length > SESSION_REPLAY_LIST_SEARCH_MAX_LENGTH) {
|
|
2854
|
+
return Response.sendErrorResponse(req, res, new BadDataException(`search must be at most ${SESSION_REPLAY_LIST_SEARCH_MAX_LENGTH} characters.`));
|
|
2855
|
+
}
|
|
2856
|
+
const windowMs = endTime.getTime() - startTime.getTime();
|
|
2857
|
+
if (windowMs >
|
|
2858
|
+
SESSION_REPLAY_LIST_SEARCH_MAX_WINDOW_DAYS * 24 * 60 * 60 * 1000) {
|
|
2859
|
+
return Response.sendErrorResponse(req, res, new BadDataException(`Search covers at most ${SESSION_REPLAY_LIST_SEARCH_MAX_WINDOW_DAYS} days at a time. Narrow the range to search it.`));
|
|
2860
|
+
}
|
|
2861
|
+
if (rawSearch.trim().length > 0) {
|
|
2862
|
+
filters.search = rawSearch.trim();
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
/*
|
|
2866
|
+
* Both cursor shapes are accepted: the legacy {startTimeUnixMs,
|
|
2867
|
+
* sessionId} one an older Dashboard or a bookmark still sends (it
|
|
2868
|
+
* means "newest first"), and the sorted one. A cursor for a
|
|
2869
|
+
* different ordering than the one requested is refused by the
|
|
2870
|
+
* service rather than silently mis-paged.
|
|
2871
|
+
*/
|
|
2872
|
+
const cursor = body["cursor"] !== undefined && body["cursor"] !== null
|
|
2873
|
+
? parseSessionReplayListCursor(body["cursor"])
|
|
2874
|
+
: null;
|
|
2875
|
+
if (body["cursor"] !== undefined &&
|
|
2876
|
+
body["cursor"] !== null &&
|
|
2877
|
+
(cursor === null || !isBindableCursorSortValue(cursor, sortBy))) {
|
|
2878
|
+
return Response.sendErrorResponse(req, res, new BadDataException("cursor must be the nextCursor of a previous page."));
|
|
2879
|
+
}
|
|
2880
|
+
const result = await SessionReplayReadService.listSessions(Object.assign(Object.assign({ projectId: projectId, rumApplicationId: rumApplicationId, startTime: startTime, endTime: endTime, filters: filters, limit: limit, sortBy: sortBy }, (cursor !== null && { cursor })), { includeIdentifiedUserLabel: includeIdentifiedUserLabel }));
|
|
2881
|
+
/*
|
|
2882
|
+
* The legacy cursor shape is still EMITTED for the newest-first sort
|
|
2883
|
+
* so an older Dashboard keeps paging; every other sort emits the
|
|
2884
|
+
* generalised shape, which such a client never asks for.
|
|
2885
|
+
*/
|
|
2886
|
+
const nextCursor = result.nextCursor
|
|
2887
|
+
? sortBy === "startTime"
|
|
2888
|
+
? {
|
|
2889
|
+
startTimeUnixMs: result.nextCursor.sortValue,
|
|
2890
|
+
sessionId: result.nextCursor.sessionId,
|
|
2891
|
+
}
|
|
2892
|
+
: {
|
|
2893
|
+
sortBy: result.nextCursor.sortBy,
|
|
2894
|
+
sortValue: result.nextCursor.sortValue,
|
|
2895
|
+
sessionId: result.nextCursor.sessionId,
|
|
2896
|
+
}
|
|
2897
|
+
: null;
|
|
2520
2898
|
return Response.sendJsonObjectResponse(req, res, {
|
|
2521
2899
|
sessions: result.sessions,
|
|
2522
|
-
nextCursor:
|
|
2900
|
+
nextCursor: nextCursor,
|
|
2901
|
+
/*
|
|
2902
|
+
* Always present, empty when everything asked for was applied, so a
|
|
2903
|
+
* client can read it without having to distinguish "no ignored
|
|
2904
|
+
* filters" from "an older server that never said".
|
|
2905
|
+
*/
|
|
2906
|
+
ignoredFilters: ignoredFilters,
|
|
2523
2907
|
});
|
|
2524
2908
|
}
|
|
2525
2909
|
catch (err) {
|
|
@@ -2537,11 +2921,18 @@ router.post("/telemetry/rum/session-replay/manifest", ...requireSessionReplayPay
|
|
|
2537
2921
|
const projectId = databaseProps.tenantId;
|
|
2538
2922
|
const body = req.body;
|
|
2539
2923
|
const sessionId = readSessionIdFromBody(body);
|
|
2540
|
-
|
|
2924
|
+
/*
|
|
2925
|
+
* Optional disambiguator, validated but NOT trusted: the header it
|
|
2926
|
+
* selects still names the application that gets authorized.
|
|
2927
|
+
*/
|
|
2928
|
+
const requestedApplicationId = readOptionalObjectIdFromBody(body, "rumApplicationId");
|
|
2929
|
+
const authorized = await resolveAuthorizedSession({
|
|
2541
2930
|
projectId: projectId,
|
|
2542
2931
|
sessionId: sessionId,
|
|
2543
2932
|
databaseProps: databaseProps,
|
|
2933
|
+
rumApplicationId: requestedApplicationId,
|
|
2544
2934
|
});
|
|
2935
|
+
const header = authorized.header;
|
|
2545
2936
|
/*
|
|
2546
2937
|
* The authorized application, resolved server-side from the header.
|
|
2547
2938
|
* Every chunk-table read below is pinned to it: that table's replace
|
|
@@ -2551,44 +2942,108 @@ router.post("/telemetry/rum/session-replay/manifest", ...requireSessionReplayPay
|
|
|
2551
2942
|
*/
|
|
2552
2943
|
const authorizedApplicationId = new ObjectID(header.rumApplicationId);
|
|
2553
2944
|
/*
|
|
2554
|
-
*
|
|
2555
|
-
*
|
|
2556
|
-
*
|
|
2557
|
-
*
|
|
2945
|
+
* A live-session poll reuses the view row the first read created.
|
|
2946
|
+
*
|
|
2947
|
+
* The player re-fetches the manifest every 30s while a session is
|
|
2948
|
+
* still recording, and each of those is the same person continuing
|
|
2949
|
+
* the same viewing, not a new disclosure. Writing a row per poll
|
|
2950
|
+
* would turn one viewing into dozens of audit entries and bury the
|
|
2951
|
+
* signal the audit exists for. The row is reused ONLY when the
|
|
2952
|
+
* caller proves it is theirs (looked up by viewedByUserId) AND it
|
|
2953
|
+
* is for this session; anything else - somebody else's viewId, a
|
|
2954
|
+
* different session, an id that no longer exists - is a fresh
|
|
2955
|
+
* recordView, exactly as if isRefresh had not been sent.
|
|
2558
2956
|
*/
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
:
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
}
|
|
2957
|
+
let viewId = null;
|
|
2958
|
+
const isRefresh = body["isRefresh"] === true;
|
|
2959
|
+
const refreshViewId = isRefresh
|
|
2960
|
+
? readOptionalObjectIdFromBody(body, "viewId")
|
|
2961
|
+
: undefined;
|
|
2962
|
+
if (refreshViewId && databaseProps.userId) {
|
|
2963
|
+
const ownView = await RumSessionReplayViewService.findOwnView({
|
|
2964
|
+
viewId: refreshViewId,
|
|
2965
|
+
projectId: projectId,
|
|
2966
|
+
viewedByUserId: databaseProps.userId,
|
|
2967
|
+
sessionId: sessionId,
|
|
2968
|
+
});
|
|
2969
|
+
if (ownView &&
|
|
2970
|
+
ownView.id &&
|
|
2971
|
+
ownView.rumApplicationId &&
|
|
2972
|
+
ownView.rumApplicationId.toString() ===
|
|
2973
|
+
authorizedApplicationId.toString()) {
|
|
2974
|
+
viewId = ownView.id.toString();
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
if (viewId === null) {
|
|
2978
|
+
/*
|
|
2979
|
+
* The audit row is written BEFORE the manifest is built, not
|
|
2980
|
+
* after. A read that fails halfway through still happened, and
|
|
2981
|
+
* an audit that only records successful reads is an audit an
|
|
2982
|
+
* attacker can evade by aborting the request.
|
|
2983
|
+
*
|
|
2984
|
+
* linkedIncidentId is validated rather than constructed blindly:
|
|
2985
|
+
* ObjectID's constructor checks nothing, and a malformed id would
|
|
2986
|
+
* fail the audit insert - and with it the playback it audits. A
|
|
2987
|
+
* bad link is dropped; the view is still recorded.
|
|
2988
|
+
*/
|
|
2989
|
+
const rawLinkedIncidentId = body["linkedIncidentId"];
|
|
2990
|
+
const view = await RumSessionReplayViewService.recordView({
|
|
2991
|
+
projectId: projectId,
|
|
2992
|
+
rumApplicationId: authorizedApplicationId,
|
|
2993
|
+
sessionId: sessionId,
|
|
2994
|
+
viewedByUserId: databaseProps.userId,
|
|
2995
|
+
ipAddress: getClientIp(req),
|
|
2996
|
+
userAgent: typeof req.headers["user-agent"] === "string"
|
|
2997
|
+
? req.headers["user-agent"]
|
|
2998
|
+
: undefined,
|
|
2999
|
+
accessReason: typeof body["accessReason"] === "string"
|
|
3000
|
+
? body["accessReason"]
|
|
3001
|
+
: undefined,
|
|
3002
|
+
linkedIncidentId: typeof rawLinkedIncidentId === "string" &&
|
|
3003
|
+
ObjectID.isValidUUID(rawLinkedIncidentId)
|
|
3004
|
+
? new ObjectID(rawLinkedIncidentId)
|
|
3005
|
+
: undefined,
|
|
3006
|
+
linkedExceptionFingerprint: typeof body["linkedExceptionFingerprint"] === "string" &&
|
|
3007
|
+
body["linkedExceptionFingerprint"].length > 0
|
|
3008
|
+
? body["linkedExceptionFingerprint"]
|
|
3009
|
+
: undefined,
|
|
3010
|
+
});
|
|
3011
|
+
viewId = view.id ? view.id.toString() : null;
|
|
3012
|
+
}
|
|
2579
3013
|
const manifest = await SessionReplayReadService.getManifest({
|
|
2580
3014
|
header: header,
|
|
2581
3015
|
projectId: projectId,
|
|
2582
3016
|
rumApplicationId: authorizedApplicationId,
|
|
2583
3017
|
sessionId: sessionId,
|
|
2584
3018
|
});
|
|
3019
|
+
/*
|
|
3020
|
+
* The identity columns are read by a SEPARATE statement that runs
|
|
3021
|
+
* only after the narrower identity check passes for the application
|
|
3022
|
+
* the caller was just authorized against. Nothing above named them,
|
|
3023
|
+
* so a caller without the permission never causes a statement that
|
|
3024
|
+
* touches identifiedUserLabel or identifiedUserTraits to exist.
|
|
3025
|
+
*/
|
|
3026
|
+
let identity = null;
|
|
3027
|
+
if (canReadIdentifiedUserLabel({
|
|
3028
|
+
databaseProps: databaseProps,
|
|
3029
|
+
application: authorized.application,
|
|
3030
|
+
})) {
|
|
3031
|
+
identity = await SessionReplayReadService.getSessionIdentity({
|
|
3032
|
+
projectId: projectId,
|
|
3033
|
+
rumApplicationId: authorizedApplicationId,
|
|
3034
|
+
sessionId: sessionId,
|
|
3035
|
+
});
|
|
3036
|
+
}
|
|
3037
|
+
const responseHeader = identity
|
|
3038
|
+
? Object.assign(Object.assign({}, manifest.header), { identifiedUserLabel: identity.identifiedUserLabel, identifiedUserTraits: identity.identifiedUserTraits }) : manifest.header;
|
|
2585
3039
|
return Response.sendJsonObjectResponse(req, res, {
|
|
2586
3040
|
/*
|
|
2587
3041
|
* viewId is echoed back so the player's heartbeat can advance the
|
|
2588
|
-
* very row this read created, instead of guessing at
|
|
3042
|
+
* very row this read created (or reused), instead of guessing at
|
|
3043
|
+
* one.
|
|
2589
3044
|
*/
|
|
2590
|
-
viewId:
|
|
2591
|
-
header:
|
|
3045
|
+
viewId: viewId,
|
|
3046
|
+
header: responseHeader,
|
|
2592
3047
|
tabs: manifest.tabs,
|
|
2593
3048
|
isChunkIndexTruncated: manifest.isChunkIndexTruncated,
|
|
2594
3049
|
});
|
|
@@ -2631,12 +3086,22 @@ router.post("/telemetry/rum/session-replay/chunks", ...requireSessionReplayPaylo
|
|
|
2631
3086
|
if (chunkIndexes.length > MAX_SESSION_REPLAY_CHUNKS_PER_READ) {
|
|
2632
3087
|
return Response.sendErrorResponse(req, res, new BadDataException(`A maximum of ${MAX_SESSION_REPLAY_CHUNKS_PER_READ} chunks may be requested at a time.`));
|
|
2633
3088
|
}
|
|
2634
|
-
|
|
3089
|
+
/*
|
|
3090
|
+
* Served from the 30s authorization cache: a session is 60 chunk
|
|
3091
|
+
* pages at most, and re-aggregating its header plus re-loading the
|
|
3092
|
+
* application's labels for every one of them is what made seeks
|
|
3093
|
+
* stutter. The label decision itself is still made against the
|
|
3094
|
+
* caller's current permissions on every request.
|
|
3095
|
+
*/
|
|
3096
|
+
const authorized = await resolveAuthorizedSession({
|
|
2635
3097
|
projectId: projectId,
|
|
2636
3098
|
sessionId: sessionId,
|
|
2637
3099
|
databaseProps: databaseProps,
|
|
3100
|
+
rumApplicationId: readOptionalObjectIdFromBody(body, "rumApplicationId"),
|
|
3101
|
+
allowCached: true,
|
|
2638
3102
|
});
|
|
2639
|
-
const
|
|
3103
|
+
const header = authorized.header;
|
|
3104
|
+
const read = await SessionReplayReadService.getChunks({
|
|
2640
3105
|
projectId: projectId,
|
|
2641
3106
|
/* Always the application the caller was authorized against. */
|
|
2642
3107
|
rumApplicationId: new ObjectID(header.rumApplicationId),
|
|
@@ -2656,18 +3121,26 @@ router.post("/telemetry/rum/session-replay/chunks", ...requireSessionReplayPaylo
|
|
|
2656
3121
|
const frames = [];
|
|
2657
3122
|
/*
|
|
2658
3123
|
* The byte cap is re-checked here against the bytes actually being
|
|
2659
|
-
* framed, not only against what the
|
|
2660
|
-
*
|
|
2661
|
-
*
|
|
2662
|
-
*
|
|
3124
|
+
* framed, not only against what the read service believed. This is
|
|
3125
|
+
* the last place the size of the response is knowable, so it is the
|
|
3126
|
+
* one place a cap on the response can be absolute regardless of how
|
|
3127
|
+
* stored size was estimated upstream. Like the service, it answers
|
|
3128
|
+
* with the prefix that fits rather than refusing - and never with
|
|
3129
|
+
* nothing: a single chunk is bounded by the ingest cap, and a chunk
|
|
3130
|
+
* that could never be served would dead-end playback at it forever.
|
|
2663
3131
|
*/
|
|
2664
3132
|
let responseBytes = 0;
|
|
2665
|
-
|
|
3133
|
+
const omittedChunkIndexes = [...read.omittedChunkIndexes];
|
|
3134
|
+
for (const chunk of read.chunks) {
|
|
2666
3135
|
const payloadBuffer = Buffer.from(chunk.payload, "utf8");
|
|
2667
|
-
|
|
2668
|
-
if (
|
|
2669
|
-
|
|
3136
|
+
const framedBytes = payloadBuffer.length + 8;
|
|
3137
|
+
if (frames.length > 0 &&
|
|
3138
|
+
(responseBytes + framedBytes > MAX_SESSION_REPLAY_READ_BYTES ||
|
|
3139
|
+
omittedChunkIndexes.length > 0)) {
|
|
3140
|
+
omittedChunkIndexes.push(chunk.chunkIndex);
|
|
3141
|
+
continue;
|
|
2670
3142
|
}
|
|
3143
|
+
responseBytes += framedBytes;
|
|
2671
3144
|
const headerBuffer = Buffer.alloc(8);
|
|
2672
3145
|
headerBuffer.writeUInt32LE(chunk.chunkIndex, 0);
|
|
2673
3146
|
headerBuffer.writeUInt32LE(payloadBuffer.length, 4);
|
|
@@ -2676,6 +3149,18 @@ router.post("/telemetry/rum/session-replay/chunks", ...requireSessionReplayPaylo
|
|
|
2676
3149
|
const responseBody = Buffer.concat(frames);
|
|
2677
3150
|
res.setHeader("Content-Type", "application/octet-stream");
|
|
2678
3151
|
res.setHeader("Content-Length", responseBody.length.toString());
|
|
3152
|
+
/*
|
|
3153
|
+
* Which requested chunks exist but were left out for size, so a
|
|
3154
|
+
* client that cares can ask for them in a smaller page instead of
|
|
3155
|
+
* reading their absence as a gap in the recording.
|
|
3156
|
+
*/
|
|
3157
|
+
if (omittedChunkIndexes.length > 0) {
|
|
3158
|
+
res.setHeader("X-OneUptime-Replay-Omitted-Chunks", omittedChunkIndexes
|
|
3159
|
+
.sort((a, b) => {
|
|
3160
|
+
return a - b;
|
|
3161
|
+
})
|
|
3162
|
+
.join(","));
|
|
3163
|
+
}
|
|
2679
3164
|
/*
|
|
2680
3165
|
* A recording is personal data. Nothing about it may sit in a
|
|
2681
3166
|
* shared cache, and the browser should not keep it on disk either.
|
|
@@ -2704,13 +3189,16 @@ router.post("/telemetry/rum/session-replay/heartbeat", ...requireSessionReplayPa
|
|
|
2704
3189
|
return Response.sendErrorResponse(req, res, new BadDataException("secondsWatched must be a number"));
|
|
2705
3190
|
}
|
|
2706
3191
|
/*
|
|
2707
|
-
*
|
|
2708
|
-
*
|
|
2709
|
-
*
|
|
2710
|
-
*
|
|
2711
|
-
*
|
|
3192
|
+
* SEMANTICS: secondsWatched is the cumulative seconds of footage the
|
|
3193
|
+
* player has PLAYED for this view (accumulated client-side while
|
|
3194
|
+
* playback runs, scaled by speed), not the furthest offset reached.
|
|
3195
|
+
* Floored to the 15s heartbeat cadence and clamped by the service,
|
|
3196
|
+
* which is monotonic and writes nothing when the value does not
|
|
3197
|
+
* advance, so a chatty client costs at most one UPDATE per 15
|
|
3198
|
+
* seconds watched without any server-side timer or cross-pod
|
|
3199
|
+
* throttle state.
|
|
2712
3200
|
*/
|
|
2713
|
-
const throttledSeconds =
|
|
3201
|
+
const throttledSeconds = normalizeSecondsWatched(secondsWatched);
|
|
2714
3202
|
/*
|
|
2715
3203
|
* secondsWatched is a privacy control, not telemetry: it is shown on
|
|
2716
3204
|
* the player as "who watched how much of this recording". Scoping
|
|
@@ -2723,24 +3211,16 @@ router.post("/telemetry/rum/session-replay/heartbeat", ...requireSessionReplayPa
|
|
|
2723
3211
|
* viewId belonging to anyone else matches nothing and is refused
|
|
2724
3212
|
* indistinguishably from one that does not exist - and the
|
|
2725
3213
|
* application it points at is authorized exactly as a payload read
|
|
2726
|
-
* would be.
|
|
3214
|
+
* would be. That ONE lookup also carries the row's current figure,
|
|
3215
|
+
* so a heartbeat that does not advance it ends here with no write.
|
|
2727
3216
|
*/
|
|
2728
3217
|
if (!databaseProps.userId) {
|
|
2729
3218
|
return Response.sendErrorResponse(req, res, new NotAuthorizedException("You do not have access to this session replay view."));
|
|
2730
3219
|
}
|
|
2731
|
-
const view = await RumSessionReplayViewService.
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
viewedByUserId: databaseProps.userId,
|
|
2736
|
-
},
|
|
2737
|
-
select: {
|
|
2738
|
-
_id: true,
|
|
2739
|
-
rumApplicationId: true,
|
|
2740
|
-
},
|
|
2741
|
-
props: {
|
|
2742
|
-
isRoot: true,
|
|
2743
|
-
},
|
|
3220
|
+
const view = await RumSessionReplayViewService.findOwnView({
|
|
3221
|
+
viewId: viewId,
|
|
3222
|
+
projectId: projectId,
|
|
3223
|
+
viewedByUserId: databaseProps.userId,
|
|
2744
3224
|
});
|
|
2745
3225
|
if (!view || !view.rumApplicationId) {
|
|
2746
3226
|
return Response.sendErrorResponse(req, res, new NotAuthorizedException("You do not have access to this session replay view."));
|
|
@@ -2750,14 +3230,85 @@ router.post("/telemetry/rum/session-replay/heartbeat", ...requireSessionReplayPa
|
|
|
2750
3230
|
rumApplicationId: view.rumApplicationId,
|
|
2751
3231
|
databaseProps: databaseProps,
|
|
2752
3232
|
permissions: SESSION_REPLAY_PAYLOAD_PERMISSIONS,
|
|
3233
|
+
allowCached: true,
|
|
2753
3234
|
});
|
|
3235
|
+
const currentSecondsWatched = view.secondsWatched || 0;
|
|
2754
3236
|
await RumSessionReplayViewService.recordSecondsWatched({
|
|
2755
3237
|
viewId: viewId,
|
|
2756
3238
|
projectId: projectId,
|
|
2757
3239
|
secondsWatched: throttledSeconds,
|
|
3240
|
+
currentSecondsWatched: currentSecondsWatched,
|
|
2758
3241
|
});
|
|
2759
3242
|
return Response.sendJsonObjectResponse(req, res, {
|
|
2760
|
-
secondsWatched: throttledSeconds,
|
|
3243
|
+
secondsWatched: Math.max(currentSecondsWatched, throttledSeconds),
|
|
3244
|
+
});
|
|
3245
|
+
}
|
|
3246
|
+
catch (err) {
|
|
3247
|
+
next(err);
|
|
3248
|
+
}
|
|
3249
|
+
});
|
|
3250
|
+
// --- Session Replay Views Endpoint ---
|
|
3251
|
+
/*
|
|
3252
|
+
* Who has watched this recording. The audit table has been written on
|
|
3253
|
+
* every manifest read since the feature shipped and nothing surfaced it;
|
|
3254
|
+
* the player header now can. Payload permission, because the list of
|
|
3255
|
+
* viewers is a fact about a recording of a real person and belongs to
|
|
3256
|
+
* the people who may watch it. Pinned to the application the session was
|
|
3257
|
+
* authorized under: sessionId is only unique within an application.
|
|
3258
|
+
*/
|
|
3259
|
+
const MAX_SESSION_REPLAY_VIEWS_LIMIT = 50;
|
|
3260
|
+
router.post("/telemetry/rum/session-replay/views", ...requireSessionReplayPayloadAccess, async (req, res, next) => {
|
|
3261
|
+
try {
|
|
3262
|
+
const databaseProps = await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
3263
|
+
if (!(databaseProps === null || databaseProps === void 0 ? void 0 : databaseProps.tenantId)) {
|
|
3264
|
+
return Response.sendErrorResponse(req, res, new BadDataException("Invalid Project ID"));
|
|
3265
|
+
}
|
|
3266
|
+
assertSessionReplayPlan(databaseProps);
|
|
3267
|
+
const projectId = databaseProps.tenantId;
|
|
3268
|
+
const body = req.body;
|
|
3269
|
+
const sessionId = readSessionIdFromBody(body);
|
|
3270
|
+
const authorized = await resolveAuthorizedSession({
|
|
3271
|
+
projectId: projectId,
|
|
3272
|
+
sessionId: sessionId,
|
|
3273
|
+
databaseProps: databaseProps,
|
|
3274
|
+
rumApplicationId: readOptionalObjectIdFromBody(body, "rumApplicationId"),
|
|
3275
|
+
allowCached: true,
|
|
3276
|
+
});
|
|
3277
|
+
const views = await RumSessionReplayViewService.getViewsForSession({
|
|
3278
|
+
projectId: projectId,
|
|
3279
|
+
rumApplicationId: new ObjectID(authorized.header.rumApplicationId),
|
|
3280
|
+
sessionId: sessionId,
|
|
3281
|
+
limit: readLimitFromBody(body, MAX_SESSION_REPLAY_VIEWS_LIMIT, MAX_SESSION_REPLAY_VIEWS_LIMIT),
|
|
3282
|
+
});
|
|
3283
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
3284
|
+
views: views.map((view) => {
|
|
3285
|
+
var _a;
|
|
3286
|
+
return {
|
|
3287
|
+
id: view.id ? view.id.toString() : null,
|
|
3288
|
+
viewedAt: view.viewedAt ? view.viewedAt.toISOString() : null,
|
|
3289
|
+
secondsWatched: (_a = view.secondsWatched) !== null && _a !== void 0 ? _a : 0,
|
|
3290
|
+
accessReason: view.accessReason || "",
|
|
3291
|
+
viewedByUserId: view.viewedByUserId
|
|
3292
|
+
? view.viewedByUserId.toString()
|
|
3293
|
+
: null,
|
|
3294
|
+
viewedByUser: view.viewedByUser
|
|
3295
|
+
? {
|
|
3296
|
+
id: view.viewedByUser.id
|
|
3297
|
+
? view.viewedByUser.id.toString()
|
|
3298
|
+
: null,
|
|
3299
|
+
name: view.viewedByUser.name
|
|
3300
|
+
? view.viewedByUser.name.toString()
|
|
3301
|
+
: "",
|
|
3302
|
+
email: view.viewedByUser.email
|
|
3303
|
+
? view.viewedByUser.email.toString()
|
|
3304
|
+
: "",
|
|
3305
|
+
profilePictureId: view.viewedByUser.profilePictureId
|
|
3306
|
+
? view.viewedByUser.profilePictureId.toString()
|
|
3307
|
+
: null,
|
|
3308
|
+
}
|
|
3309
|
+
: null,
|
|
3310
|
+
};
|
|
3311
|
+
}),
|
|
2761
3312
|
});
|
|
2762
3313
|
}
|
|
2763
3314
|
catch (err) {
|
|
@@ -2788,15 +3339,34 @@ router.post("/telemetry/rum/session-replay/for-exception", ...requireSessionRepl
|
|
|
2788
3339
|
databaseProps: databaseProps,
|
|
2789
3340
|
permissions: SESSION_REPLAY_LIST_PERMISSIONS,
|
|
2790
3341
|
});
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
3342
|
+
let startTime = readOptionalDateFromBody(body, "startTime");
|
|
3343
|
+
let endTime = readOptionalDateFromBody(body, "endTime");
|
|
3344
|
+
/*
|
|
3345
|
+
* The exception page knows WHEN the error happened. A session that
|
|
3346
|
+
* contains that moment started at most one maximum session length
|
|
3347
|
+
* before it (plus skew padding), so the window is derived from the
|
|
3348
|
+
* moment rather than left to the 30-day default - a fraction of
|
|
3349
|
+
* the partitions, and the card finds the session of THIS instance
|
|
3350
|
+
* rather than the newest session that ever hit the fingerprint.
|
|
3351
|
+
*/
|
|
3352
|
+
const rawErrorTime = body["errorTimeUnixMs"];
|
|
3353
|
+
if (startTime === undefined &&
|
|
3354
|
+
endTime === undefined &&
|
|
3355
|
+
typeof rawErrorTime === "number" &&
|
|
3356
|
+
Number.isFinite(rawErrorTime) &&
|
|
3357
|
+
rawErrorTime > 0) {
|
|
3358
|
+
startTime = new Date(rawErrorTime -
|
|
3359
|
+
SESSION_REPLAY_MAX_SESSION_MS -
|
|
3360
|
+
SESSION_REPLAY_EXCEPTION_WINDOW_PADDING_MS);
|
|
3361
|
+
endTime = new Date(rawErrorTime + SESSION_REPLAY_EXCEPTION_WINDOW_PADDING_MS);
|
|
3362
|
+
}
|
|
3363
|
+
if (startTime && endTime && startTime.getTime() > endTime.getTime()) {
|
|
3364
|
+
return Response.sendErrorResponse(req, res, new BadDataException("startTime must not be after endTime"));
|
|
3365
|
+
}
|
|
3366
|
+
/* Pin to the session the caller already knows threw, when it does. */
|
|
3367
|
+
const pinnedSessionId = body["sessionId"];
|
|
3368
|
+
const sessions = await SessionReplayReadService.getSessionsForException(Object.assign(Object.assign(Object.assign(Object.assign({ projectId: projectId, exceptionFingerprint: fingerprint, accessibleRumApplicationIds: accessibleApplications.applicationIds }, (startTime !== undefined && { startTime })), (endTime !== undefined && { endTime })), (typeof pinnedSessionId === "string" &&
|
|
3369
|
+
pinnedSessionId.length > 0 && { sessionId: pinnedSessionId })), { limit: readLimitFromBody(body, MAX_SESSION_REPLAY_FOR_EXCEPTION_LIMIT, MAX_SESSION_REPLAY_FOR_EXCEPTION_LIMIT) }));
|
|
2800
3370
|
return Response.sendJsonObjectResponse(req, res, {
|
|
2801
3371
|
sessions: sessions,
|
|
2802
3372
|
/*
|
|
@@ -2863,9 +3433,20 @@ router.post("/telemetry/rum/session-replay/ingest-status", ...requireSessionRepl
|
|
|
2863
3433
|
sessionReplayAllowedOrigins: true,
|
|
2864
3434
|
sessionReplaySamplePercentage: true,
|
|
2865
3435
|
sessionReplayCaptureTrigger: true,
|
|
3436
|
+
sessionReplayConsentMode: true,
|
|
3437
|
+
sessionReplayMaskingMode: true,
|
|
3438
|
+
sessionReplayRetentionInDays: true,
|
|
2866
3439
|
sessionReplayMonthlyBudgetInGB: true,
|
|
2867
3440
|
sessionReplayLastChunkReceivedAt: true,
|
|
2868
3441
|
sessionReplayBudgetExceededAt: true,
|
|
3442
|
+
/*
|
|
3443
|
+
* Stamped by the /config route on every recorder load (through
|
|
3444
|
+
* the throttled updateLastSeen path), so this is "when did the
|
|
3445
|
+
* recorder last run on the customer's site" - the fact that
|
|
3446
|
+
* separates "never installed" from "installed but uploading
|
|
3447
|
+
* nothing".
|
|
3448
|
+
*/
|
|
3449
|
+
lastSeenAt: true,
|
|
2869
3450
|
},
|
|
2870
3451
|
props: {
|
|
2871
3452
|
isRoot: true,
|
|
@@ -2885,12 +3466,36 @@ router.post("/telemetry/rum/session-replay/ingest-status", ...requireSessionRepl
|
|
|
2885
3466
|
isRoot: true,
|
|
2886
3467
|
},
|
|
2887
3468
|
});
|
|
2888
|
-
const
|
|
3469
|
+
const appIdentifier = String(application["appIdentifier"] || "");
|
|
3470
|
+
/*
|
|
3471
|
+
* Every counter below is independent and every one answers null on
|
|
3472
|
+
* its own failure: the Redis-backed ones when Redis is down, the
|
|
3473
|
+
* ClickHouse-backed summary when the query fails. null is rendered
|
|
3474
|
+
* as "unknown", never as 0 - "nothing was refused" and "we could
|
|
3475
|
+
* not count" are different diagnoses.
|
|
3476
|
+
*/
|
|
3477
|
+
const [projectBytesUsedToday, applicationBytesUsedThisMonth, refusalsLast24h, dropsLast24h, activity,] = await Promise.all([
|
|
2889
3478
|
SessionReplayUsage.getProjectBytesUsedToday(projectId),
|
|
2890
3479
|
SessionReplayUsage.getApplicationBytesUsedThisMonth({
|
|
2891
3480
|
projectId: projectId,
|
|
2892
3481
|
rumApplicationId: rumApplicationId,
|
|
2893
3482
|
}),
|
|
3483
|
+
appIdentifier
|
|
3484
|
+
? SessionReplayHealthCounters.readRefusalsLast24h({
|
|
3485
|
+
projectId: projectId,
|
|
3486
|
+
appIdentifier: appIdentifier,
|
|
3487
|
+
})
|
|
3488
|
+
: Promise.resolve(null),
|
|
3489
|
+
appIdentifier
|
|
3490
|
+
? SessionReplayHealthCounters.readDropsLast24h({
|
|
3491
|
+
projectId: projectId,
|
|
3492
|
+
appIdentifier: appIdentifier,
|
|
3493
|
+
})
|
|
3494
|
+
: Promise.resolve(null),
|
|
3495
|
+
SessionReplayReadService.getApplicationActivitySummary({
|
|
3496
|
+
projectId: projectId,
|
|
3497
|
+
rumApplicationId: rumApplicationId,
|
|
3498
|
+
}),
|
|
2894
3499
|
]);
|
|
2895
3500
|
/*
|
|
2896
3501
|
* Same env var, same default, as the value the ingest gate enforces
|
|
@@ -2902,10 +3507,23 @@ router.post("/telemetry/rum/session-replay/ingest-status", ...requireSessionRepl
|
|
|
2902
3507
|
? dailyCapEnv
|
|
2903
3508
|
: DEFAULT_SESSION_REPLAY_MAX_BYTES_PER_PROJECT_PER_DAY;
|
|
2904
3509
|
const applicationView = application;
|
|
3510
|
+
const toIsoOrNull = (value) => {
|
|
3511
|
+
if (value instanceof Date) {
|
|
3512
|
+
return Number.isFinite(value.getTime()) ? value.toISOString() : null;
|
|
3513
|
+
}
|
|
3514
|
+
if (typeof value === "string" && value.length > 0) {
|
|
3515
|
+
const parsed = Date.parse(value);
|
|
3516
|
+
return Number.isFinite(parsed)
|
|
3517
|
+
? new Date(parsed).toISOString()
|
|
3518
|
+
: null;
|
|
3519
|
+
}
|
|
3520
|
+
return null;
|
|
3521
|
+
};
|
|
3522
|
+
const retentionInDays = applicationView["sessionReplayRetentionInDays"];
|
|
2905
3523
|
return Response.sendJsonObjectResponse(req, res, {
|
|
2906
3524
|
isProjectAllowed: Boolean(project === null || project === void 0 ? void 0 : project["isSessionReplayAllowed"]),
|
|
2907
3525
|
isApplicationEnabled: Boolean(applicationView["isSessionReplayEnabled"]),
|
|
2908
|
-
appIdentifier:
|
|
3526
|
+
appIdentifier: appIdentifier,
|
|
2909
3527
|
allowedOrigins: (applicationView["sessionReplayAllowedOrigins"] ||
|
|
2910
3528
|
[]),
|
|
2911
3529
|
samplePercentage: Number(applicationView["sessionReplaySamplePercentage"] || 0),
|
|
@@ -2918,6 +3536,48 @@ router.post("/telemetry/rum/session-replay/ingest-status", ...requireSessionRepl
|
|
|
2918
3536
|
dailyByteLimit: dailyByteLimit,
|
|
2919
3537
|
applicationBytesUsedThisMonth: applicationBytesUsedThisMonth,
|
|
2920
3538
|
monthlyBudgetInGB: (_a = applicationView["sessionReplayMonthlyBudgetInGB"]) !== null && _a !== void 0 ? _a : null,
|
|
3539
|
+
/*
|
|
3540
|
+
* ---- Additive: the rest of RecordingHealthStatus. ----
|
|
3541
|
+
* Every timestamp is ISO-8601 or null; every counter is a number
|
|
3542
|
+
* or null (unknown). The Dashboard parses this with
|
|
3543
|
+
* parseRecordingHealthStatus and diagnoses it with
|
|
3544
|
+
* diagnoseRecordingHealth.
|
|
3545
|
+
*/
|
|
3546
|
+
consentMode: String(applicationView["sessionReplayConsentMode"] || ""),
|
|
3547
|
+
maskingMode: String(applicationView["sessionReplayMaskingMode"] || ""),
|
|
3548
|
+
retentionInDays: typeof retentionInDays === "number" &&
|
|
3549
|
+
Number.isFinite(retentionInDays)
|
|
3550
|
+
? retentionInDays
|
|
3551
|
+
: null,
|
|
3552
|
+
publishedRecorderVersion: SessionReplayReadService.getPublishedRecorderVersion(),
|
|
3553
|
+
lastConfigFetchAt: toIsoOrNull(applicationView["lastSeenAt"]),
|
|
3554
|
+
lastSessionStartedAt: activity.lastSessionStartedAt
|
|
3555
|
+
? activity.lastSessionStartedAt.toISOString()
|
|
3556
|
+
: null,
|
|
3557
|
+
sessionsLast24h: activity.sessionsLast24h,
|
|
3558
|
+
playableSessionsLast24h: activity.playableSessionsLast24h,
|
|
3559
|
+
/*
|
|
3560
|
+
* What the newest session's recorder said it could capture.
|
|
3561
|
+
*
|
|
3562
|
+
* This is the row the docs point operators at for spotting a stale
|
|
3563
|
+
* cached recorder artifact ("click labels: no"); without it the
|
|
3564
|
+
* health card and the installation test both said "not reported
|
|
3565
|
+
* yet" for every application forever, which reads as a bug rather
|
|
3566
|
+
* than as information. null (not []) when there is no session, when
|
|
3567
|
+
* the newest one predates the attribute, or when the query failed -
|
|
3568
|
+
* all three are "we cannot say", never "this recorder can do
|
|
3569
|
+
* nothing". It rides on the last-session query the summary already
|
|
3570
|
+
* runs, so the row costs no extra ClickHouse round trip.
|
|
3571
|
+
*/
|
|
3572
|
+
recorderCapabilities: activity.recorderCapabilities,
|
|
3573
|
+
refusalsLast24h: refusalsLast24h,
|
|
3574
|
+
/*
|
|
3575
|
+
* Kept apart from refusals: a refusal was answered to the
|
|
3576
|
+
* recorder, a drop happened after a 202 inside the worker. "12
|
|
3577
|
+
* chunks dropped after acceptance: scrub-incomplete" is a
|
|
3578
|
+
* different sentence from "212 uploads refused".
|
|
3579
|
+
*/
|
|
3580
|
+
dropsLast24h: dropsLast24h,
|
|
2921
3581
|
});
|
|
2922
3582
|
}
|
|
2923
3583
|
catch (err) {
|