@oneuptime/common 12.0.33 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (877) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  4. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  5. package/Models/DatabaseModels/GlobalConfig.ts +12 -12
  6. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  7. package/Models/DatabaseModels/InventoryItem.ts +44 -1
  8. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  9. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  10. package/Models/DatabaseModels/NetworkDevice.ts +126 -0
  11. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  12. package/Models/DatabaseModels/RumApplication.ts +6 -6
  13. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  14. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  15. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  16. package/Models/DatabaseModels/TeamMember.ts +0 -9
  17. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  18. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  19. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  20. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  21. package/Scripts/benchmark-fanin-capacity.js +181 -0
  22. package/Server/API/TelemetryAPI.ts +1284 -164
  23. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  24. package/Server/API/UserTelegramAPI.ts +48 -4
  25. package/Server/EnvironmentConfig.ts +82 -18
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.ts +25 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  32. package/Server/Infrastructure/QueueWorker.ts +20 -14
  33. package/Server/Infrastructure/Redis.ts +8 -8
  34. package/Server/Infrastructure/Semaphore.ts +2 -0
  35. package/Server/Infrastructure/Status.ts +10 -4
  36. package/Server/Middleware/TelemetryIngest.ts +453 -7
  37. package/Server/Services/AccessTokenService.ts +1 -0
  38. package/Server/Services/AlertCustomFieldService.ts +98 -0
  39. package/Server/Services/AlertService.ts +37 -0
  40. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  41. package/Server/Services/CustomFieldMappingService.ts +879 -0
  42. package/Server/Services/DatabaseService.ts +65 -13
  43. package/Server/Services/GlobalConfigService.ts +194 -0
  44. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  45. package/Server/Services/IncidentService.ts +35 -0
  46. package/Server/Services/InventoryItemService.ts +31 -1
  47. package/Server/Services/MetricService.ts +194 -0
  48. package/Server/Services/MonitorService.ts +32 -0
  49. package/Server/Services/MonitorTemplateService.ts +140 -19
  50. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +427 -66
  51. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +87 -2
  52. package/Server/Services/NetworkDeviceService.ts +69 -0
  53. package/Server/Services/ProjectService.ts +22 -0
  54. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  55. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  56. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  57. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  58. package/Server/Services/TeamMemberService.ts +78 -0
  59. package/Server/Services/TeamPermissionService.ts +235 -3
  60. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  61. package/Server/Services/UserNotificationRuleService.ts +76 -25
  62. package/Server/Services/UserNotificationSettingService.ts +34 -6
  63. package/Server/Services/UserTelegramService.ts +326 -5
  64. package/Server/Types/Database/Permissions/ReadPermission.ts +45 -5
  65. package/Server/Types/Database/QueryHelper.ts +2 -0
  66. package/Server/Types/Database/QueryUtil.ts +56 -0
  67. package/Server/Types/Markdown.ts +93 -1
  68. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  69. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  70. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  71. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  72. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +82 -17
  73. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  74. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
  75. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +67 -5
  76. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +2 -2
  77. package/Server/Utils/FrontendEnvironment.ts +40 -0
  78. package/Server/Utils/LogRedaction.ts +20 -0
  79. package/Server/Utils/Logger.ts +11 -0
  80. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +394 -86
  81. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  82. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +31 -5
  83. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  84. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +312 -52
  85. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +82 -9
  86. package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +16 -7
  87. package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +29 -17
  88. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +107 -48
  89. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  90. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
  91. package/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.ts +158 -0
  92. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +27 -0
  93. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  94. package/Server/Utils/SSRFProtection.ts +217 -10
  95. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  96. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  97. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  98. package/Server/Utils/StartServer.ts +2 -17
  99. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  100. package/Server/Utils/Telemetry/EntityRegistry.ts +11 -1
  101. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  102. package/Server/Utils/Telemetry/TelemetryEntity.ts +83 -9
  103. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  104. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  105. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  106. package/Server/Utils/VM/VMAPI.ts +1 -0
  107. package/Server/Utils/VM/VMRunner.ts +975 -95
  108. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  109. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +32 -0
  110. package/Tests/App/Dashboard/AdoptedDeviceDrawer.test.tsx +374 -0
  111. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  112. package/Tests/App/Dashboard/DashboardLabelVariables.test.tsx +580 -0
  113. package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +438 -0
  114. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +5 -2
  115. package/Tests/App/Dashboard/DeviceAttachmentCard.test.tsx +273 -0
  116. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +505 -0
  117. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
  118. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +163 -0
  119. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +401 -0
  120. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +232 -0
  121. package/Tests/App/Dashboard/InventoryItems.test.tsx +201 -0
  122. package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +798 -0
  123. package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +320 -0
  124. package/Tests/App/Dashboard/NetworkTopologyToolbar.test.tsx +275 -0
  125. package/Tests/App/Dashboard/OnCallCalendarFeedEmptyState.test.tsx +975 -0
  126. package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +63 -0
  127. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +626 -0
  128. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +348 -0
  129. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +331 -0
  130. package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +603 -0
  131. package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +324 -0
  132. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +13 -4
  133. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  134. package/Tests/App/StatusPage/StatusPageOidcOrigin.test.tsx +223 -0
  135. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  136. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  137. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  138. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  139. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  140. package/Tests/Models/InventoryItemStatus.test.ts +147 -0
  141. package/Tests/Models/NetworkDeviceMacAddressColumn.test.ts +294 -0
  142. package/Tests/ResponsiveVisibility.test.ts +115 -0
  143. package/Tests/ResponsiveVisibility.ts +183 -0
  144. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +129 -0
  145. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  146. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  147. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  148. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  149. package/Tests/Server/EnvironmentConfigValkey.test.ts +227 -0
  150. package/Tests/Server/Infrastructure/Postgres/AddMacAddressToNetworkDeviceMigration.test.ts +365 -0
  151. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +241 -0
  152. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  153. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  154. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  155. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  156. package/Tests/Server/Infrastructure/ValkeyDeploymentConfig.test.ts +265 -0
  157. package/Tests/Server/Middleware/HttpMetricsMiddleware.test.ts +382 -0
  158. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  159. package/Tests/Server/Middleware/SCIMAuthorization.test.ts +525 -0
  160. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  161. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  162. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  163. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  164. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  165. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  166. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  167. package/Tests/Server/Services/DatabaseServiceAggregateBy.test.ts +291 -56
  168. package/Tests/Server/Services/DatabaseServiceSortTiebreaker.test.ts +151 -0
  169. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  170. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  171. package/Tests/Server/Services/InventoryItemManualCreate.test.ts +105 -0
  172. package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +178 -0
  173. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  174. package/Tests/Server/Services/MonitorTemplateServiceCustomFieldSync.test.ts +502 -0
  175. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1351 -74
  176. package/Tests/Server/Services/NetworkDeviceDiscoveryScanRegistration.test.ts +520 -0
  177. package/Tests/Server/Services/NetworkDeviceMacAddressNormalization.test.ts +572 -0
  178. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  179. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  180. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  181. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  182. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  183. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  184. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  185. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
  186. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
  187. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  188. package/Tests/Server/Types/Database/InventoryStatusPostgres.test.ts +368 -0
  189. package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +261 -14
  190. package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroups.test.ts +169 -0
  191. package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroupsPostgres.test.ts +297 -0
  192. package/Tests/Server/Types/Markdown.test.ts +194 -1
  193. package/Tests/Server/Types/Workflow/Components/IncomingWebhookUtils.test.ts +279 -0
  194. package/Tests/Server/Types/Workflow/Components/TextToJson.test.ts +212 -0
  195. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  196. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  197. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  198. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  199. package/Tests/Server/Utils/CustomField/CustomFieldMappingRegistry.test.ts +436 -0
  200. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  201. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +214 -0
  202. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  203. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  204. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +2 -2
  205. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  206. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +10 -3
  207. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
  208. package/Tests/Server/Utils/EventLoop.test.ts +359 -0
  209. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  210. package/Tests/Server/Utils/JsonWebToken.test.ts +30 -0
  211. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  212. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  213. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +242 -0
  214. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +590 -0
  215. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +29 -0
  216. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  217. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +30 -6
  218. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +246 -0
  219. package/Tests/Server/Utils/Monitor/MonitorCriteriaEmailEvalLogAgreement.test.ts +280 -0
  220. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +659 -8
  221. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +570 -0
  222. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +30 -5
  223. package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +68 -21
  224. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +36 -19
  225. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  226. package/Tests/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.test.ts +573 -0
  227. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +317 -0
  228. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  229. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  230. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  231. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  232. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  233. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  234. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  235. package/Tests/Server/Utils/Telemetry/ContextSpanProcessor.test.ts +281 -0
  236. package/Tests/Server/Utils/Telemetry/InventoryDuplicateIdentity.test.ts +316 -0
  237. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  238. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +111 -8
  239. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  240. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  241. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  242. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  243. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  244. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  245. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  246. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  247. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  248. package/Tests/Types/Database/IncludesAnyOfGroups.test.ts +106 -0
  249. package/Tests/Types/JSONFunctions.test.ts +300 -0
  250. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  251. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  252. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  253. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  254. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  255. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  256. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  257. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  258. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  259. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  260. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  261. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  262. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  263. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  264. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  265. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  266. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  267. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  268. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  269. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  270. package/Tests/Types/NetworkAutomation/AutoImportRunMerge.test.ts +235 -0
  271. package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +66 -0
  272. package/Tests/Types/NetworkAutomation/RuleRunResultDescribe.test.ts +309 -1
  273. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  274. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  275. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  276. package/Tests/Types/Telemetry/InventoryLiveness.test.ts +99 -0
  277. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  278. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  279. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  280. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  281. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  282. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +160 -0
  283. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  284. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  285. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  286. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  287. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  288. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  289. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  290. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  291. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  292. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
  293. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  294. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  295. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  296. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  297. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  298. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  299. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  300. package/Tests/UI/ReactRouterSingletonBuild.test.ts +133 -0
  301. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  302. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  303. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  304. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  305. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  306. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  307. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  308. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  309. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  310. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  311. package/Tests/UI/Rum/ReplayHeader.test.tsx +719 -0
  312. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  313. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  314. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  315. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +514 -0
  316. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  317. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  318. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  319. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  320. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  321. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  322. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  323. package/Tests/UI/Rum/ReplayTimeFormat.test.ts +94 -0
  324. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  325. package/Tests/UI/Rum/ReplayUi.test.tsx +559 -0
  326. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  327. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  328. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  329. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  330. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  331. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  332. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
  333. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -0
  334. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  335. package/Tests/Utils/API.test.ts +308 -0
  336. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +11 -1
  337. package/Tests/Utils/Dashboard/LabelVariable.test.ts +257 -0
  338. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +144 -14
  339. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  340. package/Tests/Utils/MetricUnitUtil.test.ts +81 -0
  341. package/Tests/Utils/Monitor/DeviceMacLearningUtil.test.ts +497 -0
  342. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +546 -0
  343. package/Tests/Utils/Monitor/MonitorTemplateCustomFieldUtil.test.ts +218 -0
  344. package/Tests/Utils/Monitor/NetworkTopologyEndpointAdoption.test.ts +1755 -0
  345. package/Tests/Utils/NetworkAutomation/AutoImportRunChain.test.ts +320 -0
  346. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  347. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  348. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  349. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  350. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  351. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  352. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  353. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  354. package/Types/BaseDatabase/IncludesAnyOfGroups.ts +77 -0
  355. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  356. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  357. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  358. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  359. package/Types/Dashboard/DashboardComponents/DashboardMonitorListComponent.ts +1 -0
  360. package/Types/Dashboard/DashboardVariable.ts +8 -0
  361. package/Types/Icon/IconProp.ts +1 -0
  362. package/Types/JSON.ts +4 -0
  363. package/Types/JSONFunctions.ts +205 -43
  364. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  365. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  366. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  367. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  368. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  369. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  370. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  371. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  372. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  373. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  374. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  375. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  376. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  377. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  378. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  379. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  380. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
  381. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  382. package/Types/NetworkAutomation/RuleRunResult.ts +402 -13
  383. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  384. package/Types/Rum/SessionReplay.ts +209 -0
  385. package/Types/Rum/SessionReplayApi.ts +722 -0
  386. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  387. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  388. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  389. package/Types/Rum/SessionReplayHealth.ts +238 -0
  390. package/Types/SerializableObjectDictionary.ts +4 -0
  391. package/Types/Telemetry/InventoryLiveness.ts +56 -0
  392. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  393. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  394. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  395. package/Types/WebsiteRequest.ts +85 -3
  396. package/UI/Components/CSVFileUpload/CSVFileUpload.tsx +9 -2
  397. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  398. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  399. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  400. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  401. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  402. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  403. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  404. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +189 -46
  405. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  406. package/UI/Components/Dashboard/DashboardVariableControl.tsx +285 -0
  407. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  408. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  409. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  410. package/UI/Components/Header/Header.tsx +25 -9
  411. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  412. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  413. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  414. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  415. package/UI/Components/Icon/Icon.tsx +11 -0
  416. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  417. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  418. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  419. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  420. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  421. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  422. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  423. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  424. package/UI/Components/ModelTable/Column.ts +15 -0
  425. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  426. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  427. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  428. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  429. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  430. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  431. package/UI/Components/Table/CellClassName.ts +81 -0
  432. package/UI/Components/Table/TableRow.tsx +20 -14
  433. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  434. package/UI/Components/Table/Types/Column.ts +36 -0
  435. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  436. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  437. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  438. package/UI/Components/Workflow/Workflow.tsx +47 -18
  439. package/UI/Config.ts +15 -33
  440. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  441. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  442. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  443. package/UI/esbuild-config.js +6 -0
  444. package/Utils/API.ts +129 -3
  445. package/Utils/Dashboard/Components/DashboardMonitorListComponent.ts +12 -1
  446. package/Utils/Dashboard/LabelVariable.ts +152 -0
  447. package/Utils/Dashboard/VariableUrlState.ts +27 -5
  448. package/Utils/HTTPResponseBodyReader.ts +221 -0
  449. package/Utils/MetricUnitUtil.ts +34 -0
  450. package/Utils/Monitor/DeviceMacLearningUtil.ts +177 -0
  451. package/Utils/Monitor/MetricValueFormatter.ts +342 -0
  452. package/Utils/Monitor/MonitorTemplateCustomFieldUtil.ts +124 -0
  453. package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +7 -2
  454. package/Utils/Monitor/NetworkTopologyUtil.ts +693 -0
  455. package/Utils/NetworkAutomation/AutoImportRunChain.ts +138 -0
  456. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  457. package/Utils/Rum/ChunkMath.ts +106 -0
  458. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  459. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  460. package/Utils/Schema/ModelSchema.ts +1 -0
  461. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  462. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  463. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  464. package/Utils/ValueFormatter.ts +35 -1
  465. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  466. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  467. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  468. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  469. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  470. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  471. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  472. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  473. package/build/dist/Models/DatabaseModels/GlobalConfig.js +12 -12
  474. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  475. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  476. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  477. package/build/dist/Models/DatabaseModels/InventoryItem.js +34 -1
  478. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
  479. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  480. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  481. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  482. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  483. package/build/dist/Models/DatabaseModels/NetworkDevice.js +128 -0
  484. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  485. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  486. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  487. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  488. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  489. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  490. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  491. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  492. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  493. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  494. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  495. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  496. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  497. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  498. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  499. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  500. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  501. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  502. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  503. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  504. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  505. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  506. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  507. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  508. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  509. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  510. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  511. package/build/dist/Server/EnvironmentConfig.js +73 -14
  512. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  513. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  514. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  515. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  516. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  517. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  518. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  519. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  520. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  521. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js +14 -0
  522. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js.map +1 -0
  523. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  524. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  525. package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
  526. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  527. package/build/dist/Server/Infrastructure/Redis.js +8 -8
  528. package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
  529. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  530. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  531. package/build/dist/Server/Infrastructure/Status.js +10 -4
  532. package/build/dist/Server/Infrastructure/Status.js.map +1 -1
  533. package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
  534. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  535. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  536. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  537. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  538. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  539. package/build/dist/Server/Services/AlertService.js +34 -0
  540. package/build/dist/Server/Services/AlertService.js.map +1 -1
  541. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  542. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  543. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  544. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  545. package/build/dist/Server/Services/DatabaseService.js +58 -13
  546. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  547. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  548. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  549. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  550. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  551. package/build/dist/Server/Services/IncidentService.js +32 -0
  552. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  553. package/build/dist/Server/Services/InventoryItemService.js +28 -1
  554. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  555. package/build/dist/Server/Services/MetricService.js +163 -0
  556. package/build/dist/Server/Services/MetricService.js.map +1 -1
  557. package/build/dist/Server/Services/MonitorService.js +29 -0
  558. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  559. package/build/dist/Server/Services/MonitorTemplateService.js +116 -17
  560. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  561. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +349 -64
  562. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  563. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +65 -0
  564. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  565. package/build/dist/Server/Services/NetworkDeviceService.js +54 -0
  566. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  567. package/build/dist/Server/Services/ProjectService.js +22 -0
  568. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  569. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  570. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  571. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  572. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  573. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  574. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  575. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  576. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  577. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  578. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  579. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  580. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  581. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  582. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  583. package/build/dist/Server/Services/UserNotificationRuleService.js +60 -25
  584. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  585. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
  586. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  587. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  588. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  589. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +29 -4
  590. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  591. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  592. package/build/dist/Server/Types/Database/QueryUtil.js +36 -0
  593. package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
  594. package/build/dist/Server/Types/Markdown.js +75 -0
  595. package/build/dist/Server/Types/Markdown.js.map +1 -1
  596. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  597. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  598. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  599. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  600. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  601. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  602. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  603. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  604. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +53 -18
  605. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  606. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  607. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  608. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
  609. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
  610. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +54 -3
  611. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  612. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +2 -2
  613. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -1
  614. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  615. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  616. package/build/dist/Server/Utils/LogRedaction.js +20 -0
  617. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  618. package/build/dist/Server/Utils/Logger.js +10 -0
  619. package/build/dist/Server/Utils/Logger.js.map +1 -1
  620. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +323 -81
  621. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  622. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  623. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  624. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +29 -5
  625. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  626. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  627. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  628. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +254 -48
  629. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  630. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +58 -9
  631. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  632. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +9 -3
  633. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
  634. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +26 -12
  635. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
  636. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +74 -33
  637. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  638. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  639. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  640. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
  641. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  642. package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js +114 -0
  643. package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js.map +1 -0
  644. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +25 -0
  645. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  646. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  647. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  648. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  649. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  650. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  651. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  652. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  653. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  654. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  655. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  656. package/build/dist/Server/Utils/StartServer.js +3 -14
  657. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  658. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  659. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  660. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +9 -1
  661. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  662. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  663. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  664. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +70 -13
  665. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  666. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  667. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  668. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  669. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  670. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  671. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  672. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  673. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  674. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  675. package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js +54 -0
  676. package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js.map +1 -0
  677. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  678. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  679. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  680. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  681. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  682. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  683. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  684. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  685. package/build/dist/Types/Dashboard/DashboardVariable.js +1 -0
  686. package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -1
  687. package/build/dist/Types/Icon/IconProp.js +1 -0
  688. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  689. package/build/dist/Types/JSON.js +1 -0
  690. package/build/dist/Types/JSON.js.map +1 -1
  691. package/build/dist/Types/JSONFunctions.js +131 -37
  692. package/build/dist/Types/JSONFunctions.js.map +1 -1
  693. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  694. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  695. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  696. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  697. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  698. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  699. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  700. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  701. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  702. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  703. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  704. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  705. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  706. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  707. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  708. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  709. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  710. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  711. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  712. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  713. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  714. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  715. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  716. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  717. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  718. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  719. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  720. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  721. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  722. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  723. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  724. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  725. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  726. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  727. package/build/dist/Types/NetworkAutomation/RuleRunResult.js +291 -6
  728. package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
  729. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  730. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  731. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  732. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  733. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  734. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  735. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  736. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  737. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  738. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  739. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  740. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  741. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  742. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  743. package/build/dist/Types/SerializableObjectDictionary.js +4 -0
  744. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  745. package/build/dist/Types/Telemetry/InventoryLiveness.js +37 -0
  746. package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -0
  747. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  748. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  749. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  750. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  751. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  752. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  753. package/build/dist/Types/WebsiteRequest.js +55 -3
  754. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  755. package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js +7 -0
  756. package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js.map +1 -1
  757. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  758. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  759. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  760. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  761. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  762. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  763. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  764. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  765. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  766. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  767. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  768. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  769. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  770. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +89 -8
  771. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  772. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  773. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  774. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +137 -0
  775. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -0
  776. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  777. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  778. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  779. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  780. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  781. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  782. package/build/dist/UI/Components/Header/Header.js +2 -3
  783. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  784. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  785. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  786. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  787. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  788. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  789. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  790. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  791. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  792. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  793. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  794. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  795. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  796. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  797. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  798. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  799. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  800. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  801. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  802. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  803. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  804. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  805. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  806. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
  807. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  808. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  809. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  810. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  811. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  812. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  813. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  814. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  815. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  816. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  817. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  818. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  819. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  820. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  821. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  822. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  823. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  824. package/build/dist/UI/Config.js +10 -20
  825. package/build/dist/UI/Config.js.map +1 -1
  826. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  827. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  828. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  829. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  830. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  831. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  832. package/build/dist/Utils/API.js +67 -5
  833. package/build/dist/Utils/API.js.map +1 -1
  834. package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js +9 -1
  835. package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js.map +1 -1
  836. package/build/dist/Utils/Dashboard/LabelVariable.js +96 -0
  837. package/build/dist/Utils/Dashboard/LabelVariable.js.map +1 -0
  838. package/build/dist/Utils/Dashboard/VariableUrlState.js +19 -4
  839. package/build/dist/Utils/Dashboard/VariableUrlState.js.map +1 -1
  840. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  841. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  842. package/build/dist/Utils/MetricUnitUtil.js +26 -0
  843. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  844. package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js +112 -0
  845. package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js.map +1 -0
  846. package/build/dist/Utils/Monitor/MetricValueFormatter.js +276 -0
  847. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -0
  848. package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js +101 -0
  849. package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js.map +1 -0
  850. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +7 -2
  851. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
  852. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +484 -0
  853. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  854. package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js +59 -0
  855. package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js.map +1 -0
  856. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  857. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  858. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  859. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  860. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  861. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  862. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  863. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  864. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  865. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  866. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  867. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  868. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  869. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  870. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  871. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  872. package/build/dist/Utils/ValueFormatter.js +32 -1
  873. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  874. package/jest.config.json +2 -0
  875. package/package.json +1 -1
  876. package/test-setup.sh +9 -9
  877. package/tsconfig.json +51 -11
@@ -0,0 +1,998 @@
1
+ import { Service as TelemetryIngestionKeyServiceType } from "../../../Server/Services/TelemetryIngestionKeyService";
2
+ import Model from "../../../Models/DatabaseModels/TelemetryIngestionKey";
3
+ import CreateBy from "../../../Server/Types/Database/CreateBy";
4
+ import UpdateBy from "../../../Server/Types/Database/UpdateBy";
5
+ import DeleteBy from "../../../Server/Types/Database/DeleteBy";
6
+ import Query from "../../../Server/Types/Database/Query";
7
+ import {
8
+ OnCreate,
9
+ OnDelete,
10
+ OnUpdate,
11
+ } from "../../../Server/Types/Database/Hooks";
12
+ import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
13
+ import BadDataException from "../../../Types/Exception/BadDataException";
14
+ import ColumnLength from "../../../Types/Database/ColumnLength";
15
+ import ObjectID from "../../../Types/ObjectID";
16
+ import TelemetryIngestionKeyType from "../../../Types/Telemetry/TelemetryIngestionKeyType";
17
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
18
+ import { beforeEach, describe, expect, jest, test } from "@jest/globals";
19
+
20
+ /*
21
+ * WHAT THIS FILE IS DEFENDING
22
+ *
23
+ * The one rule that makes a Browser ingestion key safe to publish at all: it
24
+ * cannot be created, and cannot be left, without an origin allowlist.
25
+ *
26
+ * A Browser key is pasted into public page source. "Secret" is a fiction for
27
+ * it - anyone who views source has the bearer token - so the ONLY thing
28
+ * standing between a scraped key and forged telemetry written into a
29
+ * customer's project is the list of origins the key is bound to. There is no
30
+ * safe permissive default for that list, which is why an empty one is refused
31
+ * at the write path rather than defaulted to "any origin": a Browser key with
32
+ * no origins is precisely the credential this whole feature exists to stop
33
+ * shipping.
34
+ *
35
+ * Postgres cannot express "non-empty only when keyType is Browser", so the
36
+ * service layer is the only place the rule lives on the write side. These
37
+ * tests therefore go through the real onBeforeCreate / onBeforeUpdate hooks.
38
+ *
39
+ * Three further things are pinned here because each of them fails silently:
40
+ *
41
+ * 1. keyType is IMMUTABLE. Browser -> Server strips the origin binding off
42
+ * a key that is still sitting in a public page; Server -> Browser breaks
43
+ * a collector that has shipped traces for a year the moment it sends
44
+ * from no Origin. The column declares `update: []`, but that is an
45
+ * API-layer control - an internal caller reaching for updateOneById
46
+ * bypasses it, so the service refuses the patch too.
47
+ * 2. THE BACKWARDS-COMPATIBILITY CONTRACT. A create with no keyType is a
48
+ * Server key, needs no allowlist, and behaves exactly as every key that
49
+ * existed before this shipped. Rows that predate the column read back
50
+ * with keyType NULL and must not be mistaken for Browser keys by the
51
+ * "you may not empty this list" guard.
52
+ * 3. COST. The guard that refuses an empty allowlist has to read the rows
53
+ * the update matches. That read must happen ONLY when the patch actually
54
+ * empties the list - the common update (rename, toggle isEnabled, set an
55
+ * expiry) must not start paying a query for a rule it cannot break.
56
+ *
57
+ * Nothing here touches Postgres or Redis: the hooks are invoked directly on a
58
+ * fresh service instance whose findBy/findOneBy are stubbed.
59
+ */
60
+
61
+ const KEY_ID: ObjectID = new ObjectID("11111111-1111-4111-8111-111111111111");
62
+ const SECOND_KEY_ID: ObjectID = new ObjectID(
63
+ "22222222-2222-4222-8222-222222222222",
64
+ );
65
+ const PROJECT_ID: ObjectID = new ObjectID(
66
+ "33333333-3333-4333-8333-333333333333",
67
+ );
68
+ const OTHER_PROJECT_ID: ObjectID = new ObjectID(
69
+ "44444444-4444-4444-8444-444444444444",
70
+ );
71
+
72
+ const HOUR_MS: number = 60 * 60 * 1000;
73
+
74
+ type ServiceInternals = {
75
+ onBeforeCreate: (createBy: CreateBy<Model>) => Promise<OnCreate<Model>>;
76
+ onBeforeUpdate: (updateBy: UpdateBy<Model>) => Promise<OnUpdate<Model>>;
77
+ onBeforeDelete: (deleteBy: DeleteBy<Model>) => Promise<OnDelete<Model>>;
78
+ policyCache: {
79
+ set: (key: string, value: null, ttlMs: number) => void;
80
+ size: () => number;
81
+ };
82
+ };
83
+
84
+ /*
85
+ * Typed loosely on purpose: jest.spyOn's SpiedFunction and this repo's
86
+ * @types/jest disagree about the optionality of mock.lastCall, and nothing
87
+ * below needs more than mockResolvedValue and the recorded calls.
88
+ */
89
+ type FindSpy = {
90
+ mockResolvedValue: (value: never) => unknown;
91
+ mock: { calls: Array<Array<unknown>> };
92
+ };
93
+
94
+ interface Harness {
95
+ internals: ServiceInternals;
96
+ findBy: FindSpy;
97
+ findOneBy: FindSpy;
98
+ }
99
+
100
+ beforeEach(() => {
101
+ jest.restoreAllMocks();
102
+ });
103
+
104
+ function buildService(): Harness {
105
+ const service: TelemetryIngestionKeyServiceType =
106
+ new TelemetryIngestionKeyServiceType();
107
+
108
+ const findBy: FindSpy = jest.spyOn(service, "findBy") as unknown as FindSpy;
109
+ findBy.mockResolvedValue([] as never);
110
+
111
+ const findOneBy: FindSpy = jest.spyOn(
112
+ service,
113
+ "findOneBy",
114
+ ) as unknown as FindSpy;
115
+ findOneBy.mockResolvedValue(null as never);
116
+
117
+ return {
118
+ internals: service as unknown as ServiceInternals,
119
+ findBy: findBy,
120
+ findOneBy: findOneBy,
121
+ };
122
+ }
123
+
124
+ /*
125
+ * The realistic create payload: a model instance, which is what the API layer
126
+ * hands the service. Every declared column is an OWN property on it (each is
127
+ * initialised to `undefined` in the class body), so this shape - not a
128
+ * hand-built bag - is what the hook's hasOwnProperty guards actually meet.
129
+ */
130
+ function createByModel(payload: Record<string, unknown>): CreateBy<Model> {
131
+ return {
132
+ data: Object.assign(new Model(), payload) as Model,
133
+ props: { isRoot: true },
134
+ };
135
+ }
136
+
137
+ /*
138
+ * A payload with no own property for the columns it does not mention, which
139
+ * is what an internal caller building a literal produces.
140
+ */
141
+ function createByBag(payload: Record<string, unknown>): CreateBy<Model> {
142
+ return {
143
+ data: payload as unknown as Model,
144
+ props: { isRoot: true },
145
+ };
146
+ }
147
+
148
+ function updateByBag(
149
+ payload: Record<string, unknown>,
150
+ query: Query<Model> = { _id: KEY_ID.toString() },
151
+ props: DatabaseCommonInteractionProps = { isRoot: true },
152
+ ): UpdateBy<Model> {
153
+ return {
154
+ query: query,
155
+ data: payload,
156
+ props: props,
157
+ limit: LIMIT_PER_PROJECT,
158
+ skip: 0,
159
+ } as unknown as UpdateBy<Model>;
160
+ }
161
+
162
+ /*
163
+ * A row as the pre-read sees it. `keyTypeValue` is deliberately `unknown` so a
164
+ * legacy row - written before the column existed, and therefore NULL - can be
165
+ * modelled exactly.
166
+ */
167
+ function affectedRow(id: ObjectID, keyTypeValue: unknown): Model {
168
+ const row: Model = new Model(id);
169
+ (row as unknown as Record<string, unknown>)["keyType"] = keyTypeValue;
170
+ return row;
171
+ }
172
+
173
+ function writtenValues(createBy: CreateBy<Model>): Record<string, unknown> {
174
+ return createBy.data as unknown as Record<string, unknown>;
175
+ }
176
+
177
+ describe("TelemetryIngestionKeyService.onBeforeCreate - a Browser key cannot be created without an origin allowlist", () => {
178
+ /*
179
+ * Every shape a "no origins" allowlist arrives in. [""] and [" "] matter
180
+ * as much as [] does: a blank entry is dropped by the matcher, so a list of
181
+ * blanks is non-empty in the database and matches nothing at ingest time -
182
+ * a published key that appears configured and is bound to nothing.
183
+ */
184
+ const emptyAllowLists: Array<[string, Record<string, unknown>]> = [
185
+ ["absent from the payload", {}],
186
+ ["explicitly null", { allowedOrigins: null }],
187
+ ["an empty array", { allowedOrigins: [] }],
188
+ ["an array holding one empty string", { allowedOrigins: [""] }],
189
+ ["an array holding one blank string", { allowedOrigins: [" "] }],
190
+ [
191
+ "an array of nothing but blanks",
192
+ { allowedOrigins: ["", " ", "\t", "\n"] },
193
+ ],
194
+ ];
195
+
196
+ test.each(emptyAllowLists)(
197
+ "refuses a Browser key whose allowed origins are %s",
198
+ async (_label: string, payload: Record<string, unknown>): Promise<void> => {
199
+ const { internals }: Harness = buildService();
200
+
201
+ const createBy: CreateBy<Model> = createByModel({
202
+ keyType: TelemetryIngestionKeyType.Browser,
203
+ ...payload,
204
+ });
205
+
206
+ await expect(internals.onBeforeCreate(createBy)).rejects.toThrow(
207
+ BadDataException,
208
+ );
209
+ await expect(internals.onBeforeCreate(createBy)).rejects.toThrow(
210
+ "must list at least one allowed origin",
211
+ );
212
+ },
213
+ );
214
+
215
+ test("refuses a Browser key when allowedOrigins is not an own property of the payload at all", async () => {
216
+ const { internals }: Harness = buildService();
217
+
218
+ await expect(
219
+ internals.onBeforeCreate(
220
+ createByBag({ keyType: TelemetryIngestionKeyType.Browser }),
221
+ ),
222
+ ).rejects.toThrow("must list at least one allowed origin");
223
+ });
224
+ });
225
+
226
+ describe("TelemetryIngestionKeyService.onBeforeCreate - allowlist entries are validated, and the refusal names the entry", () => {
227
+ /*
228
+ * Each of these is something a customer plainly meant but that `matches`
229
+ * will never accept, so storing it hands them an allowlist entry that
230
+ * silently matches nothing. The message has to name the offending entry:
231
+ * "one of your origins is wrong" is unfixable advice on a list of ten.
232
+ */
233
+ const invalidOrigins: Array<string> = [
234
+ "app.example.com",
235
+ "https://app.example.com/some/path",
236
+ "https://*",
237
+ "https://a.*.example.com",
238
+ "https://*example.com",
239
+ "ftp://example.com",
240
+ "https://user@example.com",
241
+ "https://example.com:70000",
242
+ ];
243
+
244
+ test.each(invalidOrigins)(
245
+ "refuses %s and says so by name",
246
+ async (badOrigin: string): Promise<void> => {
247
+ const { internals }: Harness = buildService();
248
+
249
+ const createBy: CreateBy<Model> = createByModel({
250
+ keyType: TelemetryIngestionKeyType.Browser,
251
+ allowedOrigins: [badOrigin],
252
+ });
253
+
254
+ await expect(internals.onBeforeCreate(createBy)).rejects.toThrow(
255
+ BadDataException,
256
+ );
257
+ await expect(internals.onBeforeCreate(createBy)).rejects.toThrow(
258
+ badOrigin,
259
+ );
260
+ },
261
+ );
262
+
263
+ test("names the offending entry rather than the first entry when a good origin precedes a bad one", async () => {
264
+ const { internals }: Harness = buildService();
265
+
266
+ const createBy: CreateBy<Model> = createByModel({
267
+ keyType: TelemetryIngestionKeyType.Browser,
268
+ allowedOrigins: ["https://good.example.com", "https://*"],
269
+ });
270
+
271
+ await expect(internals.onBeforeCreate(createBy)).rejects.toThrow(
272
+ "https://*",
273
+ );
274
+
275
+ let message: string = "";
276
+ try {
277
+ await internals.onBeforeCreate(createBy);
278
+ } catch (err) {
279
+ message = (err as Error).message;
280
+ }
281
+
282
+ expect(message).toContain("https://*");
283
+ expect(message).not.toContain("good.example.com");
284
+ });
285
+
286
+ test("refuses an allowedOrigins that is not a list at all", async () => {
287
+ const { internals }: Harness = buildService();
288
+
289
+ await expect(
290
+ internals.onBeforeCreate(
291
+ createByModel({
292
+ keyType: TelemetryIngestionKeyType.Browser,
293
+ allowedOrigins: "https://app.example.com",
294
+ }),
295
+ ),
296
+ ).rejects.toThrow("must be a list of origins");
297
+ });
298
+
299
+ test("refuses an allowlist entry that is not text", async () => {
300
+ const { internals }: Harness = buildService();
301
+
302
+ await expect(
303
+ internals.onBeforeCreate(
304
+ createByModel({
305
+ keyType: TelemetryIngestionKeyType.Browser,
306
+ allowedOrigins: [{ origin: "https://app.example.com" }],
307
+ }),
308
+ ),
309
+ ).rejects.toThrow("must be text");
310
+ });
311
+
312
+ /*
313
+ * Validated on a Server key too, even though a Server key never enforces
314
+ * them. A list typed in "for later" that is quietly full of entries which
315
+ * can never match is a trap that only springs the day the customer decides
316
+ * to rely on it.
317
+ */
318
+ test("validates the allowlist on a Server key as well, even though it is not required there", async () => {
319
+ const { internals }: Harness = buildService();
320
+
321
+ await expect(
322
+ internals.onBeforeCreate(
323
+ createByModel({
324
+ keyType: TelemetryIngestionKeyType.Server,
325
+ allowedOrigins: ["https://a.*.example.com"],
326
+ }),
327
+ ),
328
+ ).rejects.toThrow("https://a.*.example.com");
329
+ });
330
+ });
331
+
332
+ describe("TelemetryIngestionKeyService.onBeforeCreate - the other constrained columns", () => {
333
+ test("refuses a pinned service name longer than the column can hold", async () => {
334
+ const { internals }: Harness = buildService();
335
+
336
+ await expect(
337
+ internals.onBeforeCreate(
338
+ createByModel({
339
+ pinnedServiceName: "a".repeat(ColumnLength.ShortText + 1),
340
+ }),
341
+ ),
342
+ ).rejects.toThrow(
343
+ `cannot be longer than ${ColumnLength.ShortText} characters`,
344
+ );
345
+ });
346
+
347
+ test("refuses a pinned service name that is not text", async () => {
348
+ const { internals }: Harness = buildService();
349
+
350
+ await expect(
351
+ internals.onBeforeCreate(createByModel({ pinnedServiceName: 42 })),
352
+ ).rejects.toThrow("must be text");
353
+ });
354
+
355
+ /*
356
+ * DELIBERATELY NOT A REFUSAL. A blank pinned service name means "not
357
+ * pinned", and is normalised to null rather than rejected, because "" and
358
+ * " " are exactly what an emptied form field posts - refusing them would
359
+ * leave a customer who once pinned a service name unable to ever unpin it.
360
+ * A Browser key does not require a pin (TelemetryIngestionKeyGuard never
361
+ * consults one), so accepting blank as "no pin" gives up nothing.
362
+ */
363
+ test("treats a blank pinned service name as no pin rather than refusing it", async () => {
364
+ const { internals }: Harness = buildService();
365
+
366
+ const createBy: CreateBy<Model> = createByModel({
367
+ pinnedServiceName: " ",
368
+ });
369
+
370
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
371
+ expect(writtenValues(createBy)["pinnedServiceName"]).toBeNull();
372
+ });
373
+
374
+ const invalidLimits: Array<[string, unknown]> = [
375
+ ["zero", 0],
376
+ ["negative", -1],
377
+ ["fractional", 1.5],
378
+ ["NaN", Number.NaN],
379
+ ["text", "not-a-number"],
380
+ ["an object", {}],
381
+ ];
382
+
383
+ test.each(invalidLimits)(
384
+ "refuses a requests-per-minute limit that is %s",
385
+ async (_label: string, limit: unknown): Promise<void> => {
386
+ const { internals }: Harness = buildService();
387
+
388
+ await expect(
389
+ internals.onBeforeCreate(
390
+ createByModel({ requestsPerMinuteLimit: limit }),
391
+ ),
392
+ ).rejects.toThrow("whole number greater than 0");
393
+ },
394
+ );
395
+
396
+ /*
397
+ * Refused rather than accepted-and-immediately-dead. Saving a past expiry
398
+ * bricks the key on save, and the symptom - telemetry stops, key still
399
+ * looks fine in the list - costs an afternoon to diagnose.
400
+ */
401
+ test("refuses an expiry that is already in the past", async () => {
402
+ const { internals }: Harness = buildService();
403
+
404
+ await expect(
405
+ internals.onBeforeCreate(
406
+ createByModel({ expiresAt: new Date(Date.now() - HOUR_MS) }),
407
+ ),
408
+ ).rejects.toThrow("must be in the future");
409
+ });
410
+ });
411
+
412
+ describe("TelemetryIngestionKeyService.onBeforeCreate - what must keep working", () => {
413
+ /*
414
+ * THE BACKWARDS-COMPATIBILITY STORY, at the write path. A create with no
415
+ * key type is a Server key, and a Server key needs no allowlist. If this
416
+ * ever starts defaulting to Browser - or starts demanding origins - every
417
+ * existing integration that creates keys breaks at once.
418
+ */
419
+ test("a create with no key type is written as a Server key", async () => {
420
+ const { internals }: Harness = buildService();
421
+
422
+ const createBy: CreateBy<Model> = createByModel({});
423
+
424
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
425
+ expect(writtenValues(createBy)["keyType"]).toBe(
426
+ TelemetryIngestionKeyType.Server,
427
+ );
428
+ });
429
+
430
+ test("an empty-string key type is written as a Server key rather than refused", async () => {
431
+ const { internals }: Harness = buildService();
432
+
433
+ const createBy: CreateBy<Model> = createByModel({ keyType: "" });
434
+
435
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
436
+ expect(writtenValues(createBy)["keyType"]).toBe(
437
+ TelemetryIngestionKeyType.Server,
438
+ );
439
+ });
440
+
441
+ /*
442
+ * An unrecognised type is refused rather than coerced: "I asked for a
443
+ * Browser key and got a Server key" is a security surprise, not a typo to
444
+ * paper over.
445
+ */
446
+ test("an unrecognised key type is refused, not silently coerced to Server", async () => {
447
+ const { internals }: Harness = buildService();
448
+
449
+ await expect(
450
+ internals.onBeforeCreate(createByModel({ keyType: "browser" })),
451
+ ).rejects.toThrow("is not a valid ingestion key type");
452
+ });
453
+
454
+ test("a Server key with no allowed origins is created - the overwhelmingly common case", async () => {
455
+ const { internals }: Harness = buildService();
456
+
457
+ const createBy: CreateBy<Model> = createByModel({
458
+ keyType: TelemetryIngestionKeyType.Server,
459
+ });
460
+
461
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
462
+ expect(writtenValues(createBy)["keyType"]).toBe(
463
+ TelemetryIngestionKeyType.Server,
464
+ );
465
+ });
466
+
467
+ test("a Server key may still carry a valid allowlist", async () => {
468
+ const { internals }: Harness = buildService();
469
+
470
+ const createBy: CreateBy<Model> = createByModel({
471
+ keyType: TelemetryIngestionKeyType.Server,
472
+ allowedOrigins: ["https://app.example.com"],
473
+ });
474
+
475
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
476
+ expect(writtenValues(createBy)["allowedOrigins"]).toEqual([
477
+ "https://app.example.com",
478
+ ]);
479
+ });
480
+
481
+ test("a Browser key with a single valid origin is created", async () => {
482
+ const { internals }: Harness = buildService();
483
+
484
+ const createBy: CreateBy<Model> = createByModel({
485
+ keyType: TelemetryIngestionKeyType.Browser,
486
+ allowedOrigins: ["https://app.example.com"],
487
+ });
488
+
489
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
490
+ expect(writtenValues(createBy)["keyType"]).toBe(
491
+ TelemetryIngestionKeyType.Browser,
492
+ );
493
+ expect(writtenValues(createBy)["allowedOrigins"]).toEqual([
494
+ "https://app.example.com",
495
+ ]);
496
+ });
497
+
498
+ test("a Browser key with several valid origins keeps all of them", async () => {
499
+ const { internals }: Harness = buildService();
500
+
501
+ const createBy: CreateBy<Model> = createByModel({
502
+ keyType: TelemetryIngestionKeyType.Browser,
503
+ allowedOrigins: [
504
+ "https://app.example.com",
505
+ "https://*.example.com",
506
+ "http://localhost:3000",
507
+ ],
508
+ });
509
+
510
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
511
+ expect(writtenValues(createBy)["allowedOrigins"]).toEqual([
512
+ "https://app.example.com",
513
+ "https://*.example.com",
514
+ "http://localhost:3000",
515
+ ]);
516
+ });
517
+
518
+ /*
519
+ * Stored in the form the matcher compares against, so what the dashboard
520
+ * lists is exactly what will be matched at ingest time. A pasted
521
+ * "https://App.Example.com/" that silently never matches is a total ingest
522
+ * failure whose only symptom is a trailing character.
523
+ */
524
+ test("origins are stored canonicalised and de-duplicated", async () => {
525
+ const { internals }: Harness = buildService();
526
+
527
+ const createBy: CreateBy<Model> = createByModel({
528
+ keyType: TelemetryIngestionKeyType.Browser,
529
+ allowedOrigins: [
530
+ " HTTPS://App.Example.com/ ",
531
+ "https://app.example.com",
532
+ "",
533
+ ],
534
+ });
535
+
536
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
537
+ expect(writtenValues(createBy)["allowedOrigins"]).toEqual([
538
+ "https://app.example.com",
539
+ ]);
540
+ });
541
+
542
+ test("a valid pinned service name is trimmed before it is written", async () => {
543
+ const { internals }: Harness = buildService();
544
+
545
+ const createBy: CreateBy<Model> = createByModel({
546
+ pinnedServiceName: " checkout-web ",
547
+ });
548
+
549
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
550
+ expect(writtenValues(createBy)["pinnedServiceName"]).toBe("checkout-web");
551
+ });
552
+
553
+ test("a valid requests-per-minute limit passes through unchanged", async () => {
554
+ const { internals }: Harness = buildService();
555
+
556
+ const createBy: CreateBy<Model> = createByModel({
557
+ requestsPerMinuteLimit: 1200,
558
+ });
559
+
560
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
561
+ expect(writtenValues(createBy)["requestsPerMinuteLimit"]).toBe(1200);
562
+ });
563
+
564
+ test("a future expiry passes through unchanged", async () => {
565
+ const { internals }: Harness = buildService();
566
+
567
+ const expiresAt: Date = new Date(Date.now() + HOUR_MS);
568
+ const createBy: CreateBy<Model> = createByModel({ expiresAt: expiresAt });
569
+
570
+ await expect(internals.onBeforeCreate(createBy)).resolves.toBeDefined();
571
+ expect((writtenValues(createBy)["expiresAt"] as Date).getTime()).toBe(
572
+ expiresAt.getTime(),
573
+ );
574
+ });
575
+
576
+ /*
577
+ * Pre-existing behaviour that the new validation must not have displaced:
578
+ * the secret is generated server-side when the caller does not supply one.
579
+ * A key created without one would be unusable, and - worse - a caller could
580
+ * not tell that from a key created with one.
581
+ */
582
+ test("the secret key is still generated when the payload does not carry one", async () => {
583
+ const { internals }: Harness = buildService();
584
+
585
+ const createBy: CreateBy<Model> = createByModel({
586
+ keyType: TelemetryIngestionKeyType.Browser,
587
+ allowedOrigins: ["https://app.example.com"],
588
+ });
589
+
590
+ await internals.onBeforeCreate(createBy);
591
+
592
+ const secretKey: unknown = writtenValues(createBy)["secretKey"];
593
+ expect(secretKey).toBeInstanceOf(ObjectID);
594
+ expect((secretKey as ObjectID).toString().length).toBeGreaterThan(0);
595
+ });
596
+
597
+ test("a supplied secret key is left alone", async () => {
598
+ const { internals }: Harness = buildService();
599
+
600
+ const supplied: ObjectID = ObjectID.generate();
601
+ const createBy: CreateBy<Model> = createByModel({ secretKey: supplied });
602
+
603
+ await internals.onBeforeCreate(createBy);
604
+
605
+ expect((writtenValues(createBy)["secretKey"] as ObjectID).toString()).toBe(
606
+ supplied.toString(),
607
+ );
608
+ });
609
+ });
610
+
611
+ describe("TelemetryIngestionKeyService.onBeforeUpdate - the key type is immutable", () => {
612
+ const keyTypePatches: Array<[string, TelemetryIngestionKeyType]> = [
613
+ ["Server -> Browser", TelemetryIngestionKeyType.Browser],
614
+ ["Browser -> Server", TelemetryIngestionKeyType.Server],
615
+ ];
616
+
617
+ test.each(keyTypePatches)(
618
+ "refuses a patch that changes the key type (%s) and tells the customer to create a new key",
619
+ async (
620
+ _label: string,
621
+ keyType: TelemetryIngestionKeyType,
622
+ ): Promise<void> => {
623
+ const { internals }: Harness = buildService();
624
+
625
+ await expect(
626
+ internals.onBeforeUpdate(updateByBag({ keyType: keyType })),
627
+ ).rejects.toThrow(BadDataException);
628
+ await expect(
629
+ internals.onBeforeUpdate(updateByBag({ keyType: keyType })),
630
+ ).rejects.toThrow("Create a new ingestion key instead");
631
+ },
632
+ );
633
+
634
+ test("refuses the patch even when the key type is bundled with an otherwise harmless edit", async () => {
635
+ const { internals }: Harness = buildService();
636
+
637
+ await expect(
638
+ internals.onBeforeUpdate(
639
+ updateByBag({
640
+ name: "renamed",
641
+ keyType: TelemetryIngestionKeyType.Server,
642
+ }),
643
+ ),
644
+ ).rejects.toThrow("Create a new ingestion key instead");
645
+ });
646
+
647
+ /*
648
+ * A patch built from a model instance carries every column as an own
649
+ * property with the value `undefined`. That is an absence, not a change,
650
+ * and treating it as one would refuse every ordinary edit posted from a
651
+ * hydrated entity.
652
+ */
653
+ test("an undefined key type on a model-shaped patch is an absence, not a change", async () => {
654
+ const { internals }: Harness = buildService();
655
+
656
+ const patch: Record<string, unknown> = Object.assign(
657
+ new Model(),
658
+ {},
659
+ ) as unknown as Record<string, unknown>;
660
+ patch["name"] = "renamed";
661
+
662
+ await expect(
663
+ internals.onBeforeUpdate(updateByBag(patch)),
664
+ ).resolves.toBeDefined();
665
+ });
666
+ });
667
+
668
+ describe("TelemetryIngestionKeyService.onBeforeUpdate - the allowlist cannot be emptied on a Browser key", () => {
669
+ const emptyingPatches: Array<[string, unknown]> = [
670
+ ["an empty array", []],
671
+ ["null", null],
672
+ ["a list of blanks", ["", " "]],
673
+ ];
674
+
675
+ test.each(emptyingPatches)(
676
+ "refuses to clear the allowlist with %s when an affected row is a Browser key",
677
+ async (_label: string, allowedOrigins: unknown): Promise<void> => {
678
+ const { internals, findBy }: Harness = buildService();
679
+
680
+ findBy.mockResolvedValue([
681
+ affectedRow(KEY_ID, TelemetryIngestionKeyType.Browser),
682
+ ] as never);
683
+
684
+ await expect(
685
+ internals.onBeforeUpdate(
686
+ updateByBag({ allowedOrigins: allowedOrigins }),
687
+ ),
688
+ ).rejects.toThrow(BadDataException);
689
+ await expect(
690
+ internals.onBeforeUpdate(
691
+ updateByBag({ allowedOrigins: allowedOrigins }),
692
+ ),
693
+ ).rejects.toThrow("must keep at least one allowed origin");
694
+ },
695
+ );
696
+
697
+ test("the refusal names the key that blocked it, so a bulk update can be fixed", async () => {
698
+ const { internals, findBy }: Harness = buildService();
699
+
700
+ findBy.mockResolvedValue([
701
+ affectedRow(SECOND_KEY_ID, TelemetryIngestionKeyType.Server),
702
+ affectedRow(KEY_ID, TelemetryIngestionKeyType.Browser),
703
+ ] as never);
704
+
705
+ await expect(
706
+ internals.onBeforeUpdate(updateByBag({ allowedOrigins: [] })),
707
+ ).rejects.toThrow(KEY_ID.toString());
708
+ });
709
+
710
+ test("allows the allowlist to be cleared when every affected row is a Server key", async () => {
711
+ const { internals, findBy }: Harness = buildService();
712
+
713
+ findBy.mockResolvedValue([
714
+ affectedRow(KEY_ID, TelemetryIngestionKeyType.Server),
715
+ affectedRow(SECOND_KEY_ID, TelemetryIngestionKeyType.Server),
716
+ ] as never);
717
+
718
+ const updateBy: UpdateBy<Model> = updateByBag({ allowedOrigins: [] });
719
+
720
+ await expect(internals.onBeforeUpdate(updateBy)).resolves.toBeDefined();
721
+ expect(
722
+ (updateBy.data as unknown as Record<string, unknown>)["allowedOrigins"],
723
+ ).toEqual([]);
724
+ });
725
+
726
+ /*
727
+ * THE BACKWARDS-COMPATIBILITY CONTRACT, on the guard itself. Every key that
728
+ * existed before this shipped reads back with keyType NULL. Those are
729
+ * Server keys, and clearing an allowlist they never had must not be refused
730
+ * because the guard could not recognise them.
731
+ */
732
+ test("a legacy row with a NULL key type is treated as a Server key by the guard", async () => {
733
+ const { internals, findBy }: Harness = buildService();
734
+
735
+ findBy.mockResolvedValue([
736
+ affectedRow(KEY_ID, null),
737
+ affectedRow(SECOND_KEY_ID, undefined),
738
+ ] as never);
739
+
740
+ await expect(
741
+ internals.onBeforeUpdate(updateByBag({ allowedOrigins: [] })),
742
+ ).resolves.toBeDefined();
743
+ });
744
+
745
+ test("accepts a valid non-empty allowlist on a Browser key", async () => {
746
+ const { internals, findBy }: Harness = buildService();
747
+
748
+ const updateBy: UpdateBy<Model> = updateByBag({
749
+ allowedOrigins: [" HTTPS://App.Example.com/ ", "https://*.example.com"],
750
+ });
751
+
752
+ await expect(internals.onBeforeUpdate(updateBy)).resolves.toBeDefined();
753
+ expect(
754
+ (updateBy.data as unknown as Record<string, unknown>)["allowedOrigins"],
755
+ ).toEqual(["https://app.example.com", "https://*.example.com"]);
756
+
757
+ /*
758
+ * A non-empty list is legal on both key types, so it must not pay for the
759
+ * pre-read either.
760
+ */
761
+ expect(findBy.mock.calls).toHaveLength(0);
762
+ });
763
+
764
+ /*
765
+ * The pre-read is a policy check, so it runs as root - it has to see every
766
+ * row the update will touch, including ones the caller could not read. That
767
+ * makes tenant scoping load-bearing: without it a broad query would be
768
+ * checked against another project's Browser keys.
769
+ */
770
+ test("the pre-read is scoped to the caller's tenant when the query does not name a project", async () => {
771
+ const { internals, findBy }: Harness = buildService();
772
+
773
+ await internals.onBeforeUpdate(
774
+ updateByBag({ allowedOrigins: [] }, { _id: KEY_ID.toString() }, {
775
+ tenantId: PROJECT_ID,
776
+ } as DatabaseCommonInteractionProps),
777
+ );
778
+
779
+ expect(findBy.mock.calls).toHaveLength(1);
780
+ const call: {
781
+ query: Record<string, unknown>;
782
+ props: { isRoot?: boolean };
783
+ } = findBy.mock.calls[0]![0] as {
784
+ query: Record<string, unknown>;
785
+ props: { isRoot?: boolean };
786
+ };
787
+ expect((call.query["projectId"] as ObjectID).toString()).toBe(
788
+ PROJECT_ID.toString(),
789
+ );
790
+ expect(call.props.isRoot).toBe(true);
791
+ });
792
+
793
+ test("a project named by the query itself is not overwritten by the caller's tenant", async () => {
794
+ const { internals, findBy }: Harness = buildService();
795
+
796
+ await internals.onBeforeUpdate(
797
+ updateByBag({ allowedOrigins: [] }, { projectId: OTHER_PROJECT_ID }, {
798
+ tenantId: PROJECT_ID,
799
+ } as DatabaseCommonInteractionProps),
800
+ );
801
+
802
+ const call: { query: Record<string, unknown> } = findBy.mock
803
+ .calls[0]![0] as { query: Record<string, unknown> };
804
+ expect((call.query["projectId"] as ObjectID).toString()).toBe(
805
+ OTHER_PROJECT_ID.toString(),
806
+ );
807
+ });
808
+ });
809
+
810
+ describe("TelemetryIngestionKeyService.onBeforeUpdate - the other constrained columns", () => {
811
+ test("refuses an invalid origin pattern and names it", async () => {
812
+ const { internals }: Harness = buildService();
813
+
814
+ await expect(
815
+ internals.onBeforeUpdate(
816
+ updateByBag({ allowedOrigins: ["https://exa_mple.com"] }),
817
+ ),
818
+ ).rejects.toThrow("https://exa_mple.com");
819
+ });
820
+
821
+ test("refuses a pinned service name longer than the column can hold", async () => {
822
+ const { internals }: Harness = buildService();
823
+
824
+ await expect(
825
+ internals.onBeforeUpdate(
826
+ updateByBag({
827
+ pinnedServiceName: "a".repeat(ColumnLength.ShortText + 1),
828
+ }),
829
+ ),
830
+ ).rejects.toThrow(
831
+ `cannot be longer than ${ColumnLength.ShortText} characters`,
832
+ );
833
+ });
834
+
835
+ /*
836
+ * The other half of "blank means unpin": on update it is the ONLY way a
837
+ * customer can remove a pin they no longer want.
838
+ */
839
+ test("a blank pinned service name clears the pin instead of being refused", async () => {
840
+ const { internals }: Harness = buildService();
841
+
842
+ const updateBy: UpdateBy<Model> = updateByBag({ pinnedServiceName: " " });
843
+
844
+ await expect(internals.onBeforeUpdate(updateBy)).resolves.toBeDefined();
845
+ expect(
846
+ (updateBy.data as unknown as Record<string, unknown>)[
847
+ "pinnedServiceName"
848
+ ],
849
+ ).toBeNull();
850
+ });
851
+
852
+ test("refuses a requests-per-minute limit that is not a whole number above zero", async () => {
853
+ const { internals }: Harness = buildService();
854
+
855
+ await expect(
856
+ internals.onBeforeUpdate(updateByBag({ requestsPerMinuteLimit: 0 })),
857
+ ).rejects.toThrow("whole number greater than 0");
858
+ await expect(
859
+ internals.onBeforeUpdate(updateByBag({ requestsPerMinuteLimit: -5 })),
860
+ ).rejects.toThrow("whole number greater than 0");
861
+ await expect(
862
+ internals.onBeforeUpdate(updateByBag({ requestsPerMinuteLimit: 2.5 })),
863
+ ).rejects.toThrow("whole number greater than 0");
864
+ });
865
+
866
+ test("refuses an expiry that is already in the past", async () => {
867
+ const { internals }: Harness = buildService();
868
+
869
+ await expect(
870
+ internals.onBeforeUpdate(
871
+ updateByBag({ expiresAt: new Date(Date.now() - HOUR_MS) }),
872
+ ),
873
+ ).rejects.toThrow("must be in the future");
874
+ });
875
+
876
+ test("accepts a future expiry and a positive limit together", async () => {
877
+ const { internals }: Harness = buildService();
878
+
879
+ const expiresAt: Date = new Date(Date.now() + HOUR_MS);
880
+ const updateBy: UpdateBy<Model> = updateByBag({
881
+ expiresAt: expiresAt,
882
+ requestsPerMinuteLimit: 6000,
883
+ });
884
+
885
+ await expect(internals.onBeforeUpdate(updateBy)).resolves.toBeDefined();
886
+
887
+ const written: Record<string, unknown> = updateBy.data as unknown as Record<
888
+ string,
889
+ unknown
890
+ >;
891
+ expect((written["expiresAt"] as Date).getTime()).toBe(expiresAt.getTime());
892
+ expect(written["requestsPerMinuteLimit"]).toBe(6000);
893
+ });
894
+ });
895
+
896
+ describe("TelemetryIngestionKeyService.onBeforeUpdate - the common update path pays nothing extra", () => {
897
+ /*
898
+ * The pre-read exists for exactly one rule: "you may not empty a Browser
899
+ * key's allowlist". Every other edit - rename, toggle isEnabled, set an
900
+ * expiry, set a limit - cannot break that rule and must not issue a query
901
+ * to prove it. This path runs on every dashboard save; a stray SELECT here
902
+ * is a permanent tax paid for a case that is not in play.
903
+ */
904
+ const cheapPatches: Array<[string, Record<string, unknown>]> = [
905
+ ["a rename", { name: "renamed" }],
906
+ ["the kill switch", { isEnabled: false }],
907
+ ["an expiry", { expiresAt: new Date(Date.now() + HOUR_MS) }],
908
+ ["a rate limit", { requestsPerMinuteLimit: 6000 }],
909
+ ["a pinned service name", { pinnedServiceName: "checkout-web" }],
910
+ ];
911
+
912
+ test.each(cheapPatches)(
913
+ "issues no pre-read query for a patch that only sets %s",
914
+ async (_label: string, payload: Record<string, unknown>): Promise<void> => {
915
+ const { internals, findBy, findOneBy }: Harness = buildService();
916
+
917
+ await expect(
918
+ internals.onBeforeUpdate(updateByBag(payload)),
919
+ ).resolves.toBeDefined();
920
+
921
+ expect(findBy.mock.calls).toHaveLength(0);
922
+ expect(findOneBy.mock.calls).toHaveLength(0);
923
+ },
924
+ );
925
+
926
+ test("issues no pre-read query for a model-shaped patch whose allowedOrigins is merely undefined", async () => {
927
+ const { internals, findBy, findOneBy }: Harness = buildService();
928
+
929
+ const patch: Record<string, unknown> = Object.assign(
930
+ new Model(),
931
+ {},
932
+ ) as unknown as Record<string, unknown>;
933
+ patch["isEnabled"] = false;
934
+
935
+ await expect(
936
+ internals.onBeforeUpdate(updateByBag(patch)),
937
+ ).resolves.toBeDefined();
938
+
939
+ expect(findBy.mock.calls).toHaveLength(0);
940
+ expect(findOneBy.mock.calls).toHaveLength(0);
941
+ });
942
+ });
943
+
944
+ describe("TelemetryIngestionKeyService - the policy cache is invalidated on write", () => {
945
+ /*
946
+ * Pre-existing behaviour that must survive the new validation. The cached
947
+ * policy now carries the kill switch, the expiry, the allowlist and the
948
+ * rate limit, so almost any edit invalidates it - and a revoked or
949
+ * disabled key that keeps working for a minute longer than the operator
950
+ * believes is the failure this cache is allowed to have only because it is
951
+ * cleared here.
952
+ */
953
+ function seedCache(internals: ServiceInternals): void {
954
+ internals.policyCache.set("seeded-entry", null, 60 * 1000);
955
+ expect(internals.policyCache.size()).toBe(1);
956
+ }
957
+
958
+ test("an accepted update clears the cache", async () => {
959
+ const { internals }: Harness = buildService();
960
+ seedCache(internals);
961
+
962
+ await internals.onBeforeUpdate(updateByBag({ isEnabled: false }));
963
+
964
+ expect(internals.policyCache.size()).toBe(0);
965
+ });
966
+
967
+ test("a delete clears the cache", async () => {
968
+ const { internals }: Harness = buildService();
969
+ seedCache(internals);
970
+
971
+ await internals.onBeforeDelete({
972
+ query: { _id: KEY_ID.toString() },
973
+ props: { isRoot: true },
974
+ limit: LIMIT_PER_PROJECT,
975
+ skip: 0,
976
+ } as unknown as DeleteBy<Model>);
977
+
978
+ expect(internals.policyCache.size()).toBe(0);
979
+ });
980
+
981
+ /*
982
+ * A rejected update must NOT churn the cache: throwing away every cached
983
+ * policy in the process sends the whole ingest fleet back to Postgres, and
984
+ * a caller retrying a bad patch could do that repeatedly.
985
+ */
986
+ test("a rejected update leaves the cache alone", async () => {
987
+ const { internals }: Harness = buildService();
988
+ seedCache(internals);
989
+
990
+ await expect(
991
+ internals.onBeforeUpdate(
992
+ updateByBag({ keyType: TelemetryIngestionKeyType.Browser }),
993
+ ),
994
+ ).rejects.toThrow(BadDataException);
995
+
996
+ expect(internals.policyCache.size()).toBe(1);
997
+ });
998
+ });