@oneuptime/common 12.0.33 → 12.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (652) 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/IncidentCustomField.ts +77 -3
  6. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  7. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  8. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  9. package/Models/DatabaseModels/RumApplication.ts +6 -6
  10. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  11. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  12. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  13. package/Models/DatabaseModels/TeamMember.ts +0 -9
  14. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  15. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  16. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  17. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  18. package/Scripts/benchmark-fanin-capacity.js +181 -0
  19. package/Server/API/TelemetryAPI.ts +1284 -164
  20. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  21. package/Server/API/UserTelegramAPI.ts +48 -4
  22. package/Server/EnvironmentConfig.ts +35 -2
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  28. package/Server/Infrastructure/QueueWorker.ts +20 -14
  29. package/Server/Infrastructure/Semaphore.ts +2 -0
  30. package/Server/Middleware/TelemetryIngest.ts +453 -7
  31. package/Server/Services/AccessTokenService.ts +1 -0
  32. package/Server/Services/AlertCustomFieldService.ts +98 -0
  33. package/Server/Services/AlertService.ts +37 -0
  34. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  35. package/Server/Services/CustomFieldMappingService.ts +879 -0
  36. package/Server/Services/GlobalConfigService.ts +194 -0
  37. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  38. package/Server/Services/IncidentService.ts +35 -0
  39. package/Server/Services/MetricService.ts +194 -0
  40. package/Server/Services/MonitorService.ts +32 -0
  41. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
  42. package/Server/Services/ProjectService.ts +22 -0
  43. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  44. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  45. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  46. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  47. package/Server/Services/TeamMemberService.ts +78 -0
  48. package/Server/Services/TeamPermissionService.ts +235 -3
  49. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  50. package/Server/Services/UserNotificationSettingService.ts +34 -6
  51. package/Server/Services/UserTelegramService.ts +326 -5
  52. package/Server/Types/Database/QueryHelper.ts +2 -0
  53. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  54. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  55. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  56. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  57. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  58. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
  59. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
  60. package/Server/Utils/FrontendEnvironment.ts +40 -0
  61. package/Server/Utils/LogRedaction.ts +20 -0
  62. package/Server/Utils/Logger.ts +11 -0
  63. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
  64. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  65. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  66. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
  67. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  68. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
  69. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  70. package/Server/Utils/SSRFProtection.ts +217 -10
  71. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  72. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  73. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  74. package/Server/Utils/StartServer.ts +2 -17
  75. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  76. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  77. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  78. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  79. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  80. package/Server/Utils/VM/VMAPI.ts +1 -0
  81. package/Server/Utils/VM/VMRunner.ts +975 -95
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  83. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  84. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
  85. package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
  86. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  87. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  88. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  89. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  90. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  91. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  92. package/Tests/ResponsiveVisibility.test.ts +115 -0
  93. package/Tests/ResponsiveVisibility.ts +183 -0
  94. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  95. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  96. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  97. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  98. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
  99. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  100. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  101. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  102. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  103. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  104. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  105. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  106. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  107. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  108. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  109. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  110. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  111. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  112. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  113. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  114. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
  115. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  116. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  117. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  118. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  119. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  120. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  121. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  122. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
  123. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
  124. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  125. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  126. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  127. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  128. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  129. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  130. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  131. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  132. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
  133. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  134. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
  135. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  136. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  137. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  138. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
  139. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  140. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
  141. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  142. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  143. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  144. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  145. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  146. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  147. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  148. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  149. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  150. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  151. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  152. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  153. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  154. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  155. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  156. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  157. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  158. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  159. package/Tests/Types/JSONFunctions.test.ts +260 -0
  160. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  161. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  162. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  163. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  164. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  165. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  166. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  167. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  168. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  169. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  170. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  171. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  172. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  173. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  174. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  175. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  176. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  177. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  178. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  179. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  180. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  181. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  182. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  183. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  184. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  185. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  186. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  187. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  188. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  189. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  190. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  191. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  192. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  193. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  194. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  195. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  196. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  197. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
  198. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  199. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  200. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  201. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  202. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  203. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  204. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  205. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  206. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  207. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  208. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  209. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  210. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  211. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  212. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  213. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  214. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  215. package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
  216. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  217. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  218. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  219. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  220. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  221. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  222. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  223. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  224. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  225. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  226. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  227. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  228. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  229. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  230. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  231. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  232. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  233. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  234. package/Tests/Utils/API.test.ts +308 -0
  235. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  236. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  237. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  238. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  239. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  240. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  241. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  242. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  243. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  244. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  245. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  246. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  247. package/Types/Icon/IconProp.ts +1 -0
  248. package/Types/JSONFunctions.ts +189 -43
  249. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  250. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  251. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  252. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  253. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  254. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  255. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  256. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  257. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  258. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  259. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  260. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  261. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  262. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  263. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  264. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  265. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  266. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  267. package/Types/Rum/SessionReplay.ts +209 -0
  268. package/Types/Rum/SessionReplayApi.ts +722 -0
  269. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  270. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  271. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  272. package/Types/Rum/SessionReplayHealth.ts +238 -0
  273. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  274. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  275. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  276. package/Types/WebsiteRequest.ts +85 -3
  277. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  278. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  279. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  280. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  281. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  282. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  283. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  284. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
  285. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  286. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  287. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  288. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  289. package/UI/Components/Header/Header.tsx +25 -9
  290. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  291. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  292. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  293. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  294. package/UI/Components/Icon/Icon.tsx +11 -0
  295. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  296. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  297. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  298. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  299. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  300. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  301. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  302. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  303. package/UI/Components/ModelTable/Column.ts +15 -0
  304. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  305. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  306. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  307. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  308. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  309. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  310. package/UI/Components/Table/CellClassName.ts +81 -0
  311. package/UI/Components/Table/TableRow.tsx +20 -14
  312. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  313. package/UI/Components/Table/Types/Column.ts +36 -0
  314. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  315. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  316. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  317. package/UI/Components/Workflow/Workflow.tsx +47 -18
  318. package/UI/Config.ts +15 -33
  319. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  320. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  321. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  322. package/Utils/API.ts +129 -3
  323. package/Utils/HTTPResponseBodyReader.ts +221 -0
  324. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  325. package/Utils/Rum/ChunkMath.ts +106 -0
  326. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  327. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  328. package/Utils/Schema/ModelSchema.ts +1 -0
  329. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  330. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  331. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  332. package/Utils/ValueFormatter.ts +35 -1
  333. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  334. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  335. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  336. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  338. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  339. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  340. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  341. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  342. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  344. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  345. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  346. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  347. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  348. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  350. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  352. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  354. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  356. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  358. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  360. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  362. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  366. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  367. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  368. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  369. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  370. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  371. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  372. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  373. package/build/dist/Server/EnvironmentConfig.js +29 -2
  374. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  375. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  376. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  377. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  378. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  379. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  380. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  381. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  382. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  383. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  384. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  385. package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
  386. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  387. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  388. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  389. package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
  390. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  391. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  392. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  393. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  394. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  395. package/build/dist/Server/Services/AlertService.js +34 -0
  396. package/build/dist/Server/Services/AlertService.js.map +1 -1
  397. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  398. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  399. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  400. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  401. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  402. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  403. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  404. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  405. package/build/dist/Server/Services/IncidentService.js +32 -0
  406. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  407. package/build/dist/Server/Services/MetricService.js +163 -0
  408. package/build/dist/Server/Services/MetricService.js.map +1 -1
  409. package/build/dist/Server/Services/MonitorService.js +29 -0
  410. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  411. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
  412. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  413. package/build/dist/Server/Services/ProjectService.js +22 -0
  414. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  415. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  416. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  417. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  418. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  419. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  420. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  421. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  422. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  423. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  424. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  425. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  426. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  427. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  428. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  429. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
  430. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  431. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  432. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  433. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  434. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  435. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  436. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  437. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  438. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  439. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  440. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  441. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  442. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  443. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  444. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
  445. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
  446. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
  447. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  448. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  449. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  450. package/build/dist/Server/Utils/LogRedaction.js +20 -0
  451. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  452. package/build/dist/Server/Utils/Logger.js +10 -0
  453. package/build/dist/Server/Utils/Logger.js.map +1 -1
  454. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
  455. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  456. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  457. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  458. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  460. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
  461. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  462. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  464. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
  465. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  466. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  467. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  468. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  469. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  470. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  471. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  472. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  473. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  474. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  475. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  476. package/build/dist/Server/Utils/StartServer.js +3 -14
  477. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  478. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  479. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  480. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  481. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  482. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  483. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  484. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  485. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  486. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  487. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  488. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  489. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  490. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  491. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  492. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  493. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  494. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  495. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  496. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  497. package/build/dist/Types/Icon/IconProp.js +1 -0
  498. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  499. package/build/dist/Types/JSONFunctions.js +118 -37
  500. package/build/dist/Types/JSONFunctions.js.map +1 -1
  501. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  502. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  503. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  504. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  505. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  506. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  507. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  508. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  509. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  510. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  511. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  512. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  513. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  514. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  515. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  516. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  517. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  518. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  519. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  520. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  521. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  522. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  523. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  524. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  525. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  526. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  527. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  528. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  529. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  530. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  531. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  532. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  533. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  534. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  535. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  536. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  537. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  538. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  539. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  540. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  541. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  542. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  543. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  544. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  545. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  546. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  547. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  548. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  549. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  550. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  551. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  552. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  553. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  554. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  555. package/build/dist/Types/WebsiteRequest.js +55 -3
  556. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  558. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  560. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  562. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  564. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  565. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  566. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  567. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  568. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  569. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  570. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
  571. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  572. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  573. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  574. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  575. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  576. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  577. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  578. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  579. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  580. package/build/dist/UI/Components/Header/Header.js +2 -3
  581. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  582. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  583. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  584. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  585. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  586. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  587. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  588. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  589. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  590. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  591. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  592. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  593. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  594. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  595. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  596. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  597. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  598. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  599. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  600. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  601. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  602. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  603. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  604. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
  605. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  606. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  607. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  608. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  609. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  610. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  611. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  612. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  613. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  614. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  615. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  616. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  617. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  618. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  619. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  620. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  621. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  622. package/build/dist/UI/Config.js +10 -20
  623. package/build/dist/UI/Config.js.map +1 -1
  624. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  625. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  626. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  627. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  628. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  629. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  630. package/build/dist/Utils/API.js +67 -5
  631. package/build/dist/Utils/API.js.map +1 -1
  632. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  633. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  634. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  635. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  636. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  637. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  638. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  639. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  640. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  641. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  642. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  643. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  644. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  645. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  646. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  647. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  648. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  649. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  650. package/build/dist/Utils/ValueFormatter.js +32 -1
  651. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  652. package/package.json +1 -1
@@ -0,0 +1,528 @@
1
+ import {
2
+ afterEach,
3
+ beforeEach,
4
+ describe,
5
+ expect,
6
+ jest,
7
+ test,
8
+ } from "@jest/globals";
9
+
10
+ /*
11
+ * The per-key ceiling that makes a Browser ingestion key safe to publish.
12
+ *
13
+ * A browser key lives in the page: anyone who views source has it. The origin
14
+ * allowlist bounds WHO can replay a scraped key, but nothing except this
15
+ * counter bounds HOW MUCH they can push once they satisfy it - and unbounded
16
+ * write volume into a customer's project is poisoned dashboards, forged spans
17
+ * and, on a metered plan, their bill.
18
+ *
19
+ * Four properties decide whether that ceiling is real, and each is a silent
20
+ * failure if it regresses:
21
+ *
22
+ * 1. Off-by-one. The Nth request in a window of N must be ADMITTED; only
23
+ * N + 1 is refused. A limiter that refuses the Nth quietly sells every
24
+ * customer one request per minute less than the number on their key.
25
+ * 2. EXPIRE is issued ONLY on the write that created the counter. Re-issued
26
+ * on every increment it slides the TTL forward for as long as the load
27
+ * continues, so a fixed window under sustained traffic NEVER resets - a
28
+ * key that tripped its limit once can never recover, which is exactly the
29
+ * state an attacker's loop produces. Pinned here on the mock call counts,
30
+ * because it is invisible from the return value.
31
+ * 3. The counter keeps incrementing on REJECTED requests. Being refused must
32
+ * not hand the hammering client a fresh allowance.
33
+ * 4. It FAILS OPEN. No Redis client, a disconnected Redis, or an INCR that
34
+ * throws all resolve to CounterUnavailable and never propagate - the
35
+ * caller admits the request. Failing closed would turn a Redis blip into
36
+ * permanent, unreplayable telemetry loss for every paying customer at the
37
+ * moment their dashboards are needed most.
38
+ *
39
+ * Date.now is pinned throughout so the minute bucket and the retry-after are
40
+ * facts of the test rather than of whichever second of the real minute the
41
+ * suite happened to run in. Redis is mocked at the module boundary: nothing
42
+ * here touches a real Redis, a real Postgres or the network.
43
+ */
44
+
45
+ jest.mock("../../../../Server/Infrastructure/Redis", () => {
46
+ return {
47
+ __esModule: true,
48
+ default: {
49
+ getClient: jest.fn(),
50
+ isConnected: jest.fn(),
51
+ },
52
+ };
53
+ });
54
+
55
+ jest.mock("../../../../Server/Utils/Logger", () => {
56
+ return {
57
+ __esModule: true,
58
+ default: {
59
+ debug: jest.fn(),
60
+ info: jest.fn(),
61
+ warn: jest.fn(),
62
+ error: jest.fn(),
63
+ },
64
+ getLogAttributesFromRequest: jest.fn().mockReturnValue({}),
65
+ };
66
+ });
67
+
68
+ import Redis from "../../../../Server/Infrastructure/Redis";
69
+ import logger from "../../../../Server/Utils/Logger";
70
+ import TelemetryIngestionKeyRateLimiter, {
71
+ TelemetryIngestionKeyLimitDecision,
72
+ TelemetryIngestionKeyLimitOutcome,
73
+ } from "../../../../Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter";
74
+ import ObjectID from "../../../../Types/ObjectID";
75
+
76
+ type MockedFn = ReturnType<typeof jest.fn>;
77
+
78
+ const getClientMock: MockedFn = Redis.getClient as unknown as MockedFn;
79
+ const isConnectedMock: MockedFn = Redis.isConnected as unknown as MockedFn;
80
+ const loggerErrorMock: MockedFn = logger.error as unknown as MockedFn;
81
+
82
+ /* Constants baked into the limiter, named once so a change is a deliberate edit here too. */
83
+ const RATE_KEY_PREFIX: string = "telemetry:ingestkey:rate:";
84
+ const RATE_TTL_SECONDS: number = 120;
85
+ const WINDOW_MS: number = 60000;
86
+
87
+ interface RecordedExpire {
88
+ key: string;
89
+ ttlSeconds: number;
90
+ }
91
+
92
+ /*
93
+ * A fake that behaves like a Redis counter rather than a bag of assertions:
94
+ * INCR really increments and EXPIRE really records a TTL, so the window and
95
+ * pinning tests exercise the limiter's arithmetic instead of restating it.
96
+ */
97
+ class FakeRedisClient {
98
+ public counters: Map<string, number> = new Map();
99
+ public incrKeys: Array<string> = [];
100
+ public expires: Array<RecordedExpire> = [];
101
+
102
+ /* Set to make the next incr() reject, for the fail-open tests. */
103
+ public failNextIncr: Error | null = null;
104
+
105
+ public async incr(key: string): Promise<number> {
106
+ this.incrKeys.push(key);
107
+
108
+ if (this.failNextIncr) {
109
+ const error: Error = this.failNextIncr;
110
+ this.failNextIncr = null;
111
+ throw error;
112
+ }
113
+
114
+ const next: number = (this.counters.get(key) || 0) + 1;
115
+ this.counters.set(key, next);
116
+
117
+ return next;
118
+ }
119
+
120
+ public async expire(key: string, ttlSeconds: number): Promise<number> {
121
+ this.expires.push({ key, ttlSeconds });
122
+
123
+ return 1;
124
+ }
125
+
126
+ public expiresForKey(key: string): Array<RecordedExpire> {
127
+ return this.expires.filter((recorded: RecordedExpire) => {
128
+ return recorded.key === key;
129
+ });
130
+ }
131
+ }
132
+
133
+ describe("TelemetryIngestionKeyRateLimiter", () => {
134
+ const KEY_ID: ObjectID = new ObjectID("11111111-1111-1111-1111-111111111111");
135
+ const OTHER_KEY_ID: ObjectID = new ObjectID(
136
+ "22222222-2222-2222-2222-222222222222",
137
+ );
138
+
139
+ let client: FakeRedisClient;
140
+ let nowSpy: ReturnType<typeof jest.spyOn>;
141
+ let currentTime: number;
142
+
143
+ beforeEach(() => {
144
+ jest.clearAllMocks();
145
+
146
+ client = new FakeRedisClient();
147
+ getClientMock.mockReturnValue(client);
148
+ isConnectedMock.mockReturnValue(true);
149
+
150
+ /*
151
+ * Pinned to the exact start of a minute bucket so the bucket number and
152
+ * the retry-after are deterministic. Tests that care about where in the
153
+ * window they sit move it themselves.
154
+ */
155
+ currentTime = 1_700_000_000_000;
156
+ currentTime = currentTime - (currentTime % WINDOW_MS);
157
+
158
+ nowSpy = jest.spyOn(Date, "now").mockImplementation(() => {
159
+ return currentTime;
160
+ });
161
+ });
162
+
163
+ afterEach(() => {
164
+ nowSpy.mockRestore();
165
+ });
166
+
167
+ const consume: (data: {
168
+ ingestionKeyId?: ObjectID;
169
+ limitPerMinute?: number;
170
+ }) => Promise<TelemetryIngestionKeyLimitDecision> = (data: {
171
+ ingestionKeyId?: ObjectID;
172
+ limitPerMinute?: number;
173
+ }): Promise<TelemetryIngestionKeyLimitDecision> => {
174
+ return TelemetryIngestionKeyRateLimiter.consume({
175
+ ingestionKeyId: data.ingestionKeyId || KEY_ID,
176
+ limitPerMinute:
177
+ typeof data.limitPerMinute === "number" ? data.limitPerMinute : 10,
178
+ });
179
+ };
180
+
181
+ const expectedKeyFor: (keyId: ObjectID, atMs: number) => string = (
182
+ keyId: ObjectID,
183
+ atMs: number,
184
+ ): string => {
185
+ return `${RATE_KEY_PREFIX}${keyId.toString()}:${Math.floor(
186
+ atMs / WINDOW_MS,
187
+ )}`;
188
+ };
189
+
190
+ describe("the allowance boundary", () => {
191
+ test("admits a request under the limit and gives it no retry-after", async () => {
192
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
193
+ limitPerMinute: 10,
194
+ });
195
+
196
+ expect(decision.outcome).toBe(TelemetryIngestionKeyLimitOutcome.Allowed);
197
+ expect(decision.retryAfterSeconds).toBeUndefined();
198
+ expect(decision.isFirstRejectionInWindow).toBeUndefined();
199
+ });
200
+
201
+ /*
202
+ * The off-by-one. A limit of N means N requests get through, so the Nth
203
+ * must be Allowed.
204
+ */
205
+ test("admits the Nth request in a window of N", async () => {
206
+ const limit: number = 5;
207
+ const outcomes: Array<TelemetryIngestionKeyLimitOutcome> = [];
208
+
209
+ for (let index: number = 0; index < limit; index++) {
210
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
211
+ limitPerMinute: limit,
212
+ });
213
+
214
+ outcomes.push(decision.outcome);
215
+ }
216
+
217
+ expect(outcomes).toEqual([
218
+ TelemetryIngestionKeyLimitOutcome.Allowed,
219
+ TelemetryIngestionKeyLimitOutcome.Allowed,
220
+ TelemetryIngestionKeyLimitOutcome.Allowed,
221
+ TelemetryIngestionKeyLimitOutcome.Allowed,
222
+ TelemetryIngestionKeyLimitOutcome.Allowed,
223
+ ]);
224
+ });
225
+
226
+ test("refuses the N+1th request in a window of N", async () => {
227
+ const limit: number = 5;
228
+
229
+ for (let index: number = 0; index < limit; index++) {
230
+ await consume({ limitPerMinute: limit });
231
+ }
232
+
233
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
234
+ limitPerMinute: limit,
235
+ });
236
+
237
+ expect(decision.outcome).toBe(
238
+ TelemetryIngestionKeyLimitOutcome.RateLimited,
239
+ );
240
+ });
241
+
242
+ /*
243
+ * Sampled at several offsets into the window, including both edges, so a
244
+ * constant that happens to fall in range cannot pass this.
245
+ */
246
+ test("tells a refused caller to come back within the minute, never sooner than a second", async () => {
247
+ const windowStart: number =
248
+ 1_700_000_000_000 - (1_700_000_000_000 % WINDOW_MS);
249
+
250
+ const offsetsIntoWindow: Array<number> = [
251
+ 0, 1, 999, 30_000, 59_000, 59_999,
252
+ ];
253
+
254
+ for (const offset of offsetsIntoWindow) {
255
+ client = new FakeRedisClient();
256
+ getClientMock.mockReturnValue(client);
257
+ currentTime = windowStart + offset;
258
+
259
+ await consume({ limitPerMinute: 1 });
260
+
261
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
262
+ limitPerMinute: 1,
263
+ });
264
+
265
+ expect(decision.outcome).toBe(
266
+ TelemetryIngestionKeyLimitOutcome.RateLimited,
267
+ );
268
+ expect(decision.retryAfterSeconds).toBeGreaterThanOrEqual(1);
269
+ expect(decision.retryAfterSeconds).toBeLessThanOrEqual(60);
270
+ }
271
+ });
272
+
273
+ /*
274
+ * A non-positive or non-finite limit is a bad row or a caller bug, not a
275
+ * customer asking for a total blackout of their own ingest. It reads as
276
+ * "no limit" and short-circuits before Redis is touched.
277
+ */
278
+ test("treats a non-positive or non-finite limit as no limit and never touches Redis", async () => {
279
+ const badLimits: Array<number> = [
280
+ 0,
281
+ -1,
282
+ Number.NaN,
283
+ Number.POSITIVE_INFINITY,
284
+ ];
285
+
286
+ for (const limit of badLimits) {
287
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
288
+ limitPerMinute: limit,
289
+ });
290
+
291
+ expect(decision.outcome).toBe(
292
+ TelemetryIngestionKeyLimitOutcome.Allowed,
293
+ );
294
+ }
295
+
296
+ expect(client.incrKeys).toHaveLength(0);
297
+ expect(getClientMock).not.toHaveBeenCalled();
298
+ });
299
+ });
300
+
301
+ describe("the fixed window does not slide", () => {
302
+ /*
303
+ * THE bug this suite exists for. EXPIRE belongs only on the write that
304
+ * created the counter; issued on every increment it pushes the TTL out for
305
+ * as long as traffic continues, so the window never rolls and a key that
306
+ * tripped its limit once under load stays refused forever.
307
+ */
308
+ test("issues EXPIRE only on the write that created the counter", async () => {
309
+ const limit: number = 3;
310
+
311
+ for (let index: number = 0; index < 10; index++) {
312
+ await consume({ limitPerMinute: limit });
313
+ }
314
+
315
+ const key: string = expectedKeyFor(KEY_ID, currentTime);
316
+
317
+ expect(client.incrKeys).toHaveLength(10);
318
+ expect(client.expiresForKey(key)).toHaveLength(1);
319
+ expect(client.expiresForKey(key)[0]?.ttlSeconds).toBe(RATE_TTL_SECONDS);
320
+ });
321
+
322
+ test("issues EXPIRE once more for the next window's own counter", async () => {
323
+ await consume({ limitPerMinute: 3 });
324
+ await consume({ limitPerMinute: 3 });
325
+
326
+ const firstKey: string = expectedKeyFor(KEY_ID, currentTime);
327
+
328
+ currentTime = currentTime + WINDOW_MS;
329
+
330
+ await consume({ limitPerMinute: 3 });
331
+ await consume({ limitPerMinute: 3 });
332
+
333
+ const secondKey: string = expectedKeyFor(KEY_ID, currentTime);
334
+
335
+ expect(secondKey).not.toBe(firstKey);
336
+ expect(client.expiresForKey(firstKey)).toHaveLength(1);
337
+ expect(client.expiresForKey(secondKey)).toHaveLength(1);
338
+ expect(client.expires).toHaveLength(2);
339
+ });
340
+
341
+ test("hands the key a fresh allowance once the minute bucket rolls", async () => {
342
+ const limit: number = 2;
343
+
344
+ await consume({ limitPerMinute: limit });
345
+ await consume({ limitPerMinute: limit });
346
+
347
+ const refused: TelemetryIngestionKeyLimitDecision = await consume({
348
+ limitPerMinute: limit,
349
+ });
350
+
351
+ expect(refused.outcome).toBe(
352
+ TelemetryIngestionKeyLimitOutcome.RateLimited,
353
+ );
354
+
355
+ currentTime = currentTime + WINDOW_MS;
356
+
357
+ const afterRoll: TelemetryIngestionKeyLimitDecision = await consume({
358
+ limitPerMinute: limit,
359
+ });
360
+
361
+ expect(afterRoll.outcome).toBe(TelemetryIngestionKeyLimitOutcome.Allowed);
362
+ });
363
+
364
+ /*
365
+ * Standard fixed-window behaviour, and the point of it: a client hammering
366
+ * a scraped key keeps its own window pinned rather than being handed a
367
+ * fresh allowance for free by virtue of having been refused.
368
+ */
369
+ test("keeps counting rejected requests, so hammering does not buy a fresh allowance", async () => {
370
+ const limit: number = 1;
371
+ const key: string = expectedKeyFor(KEY_ID, currentTime);
372
+
373
+ await consume({ limitPerMinute: limit });
374
+
375
+ for (let index: number = 0; index < 5; index++) {
376
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
377
+ limitPerMinute: limit,
378
+ });
379
+
380
+ expect(decision.outcome).toBe(
381
+ TelemetryIngestionKeyLimitOutcome.RateLimited,
382
+ );
383
+ }
384
+
385
+ expect(client.counters.get(key)).toBe(6);
386
+ });
387
+ });
388
+
389
+ describe("counter keying", () => {
390
+ test("keys the counter on the ingestion key id and the current minute bucket", async () => {
391
+ await consume({ limitPerMinute: 10 });
392
+
393
+ expect(client.incrKeys).toEqual([
394
+ `${RATE_KEY_PREFIX}${KEY_ID.toString()}:${currentTime / WINDOW_MS}`,
395
+ ]);
396
+ });
397
+
398
+ test("does not let two ingestion keys share a counter", async () => {
399
+ const limit: number = 1;
400
+
401
+ await consume({ ingestionKeyId: KEY_ID, limitPerMinute: limit });
402
+
403
+ const sameKeyAgain: TelemetryIngestionKeyLimitDecision = await consume({
404
+ ingestionKeyId: KEY_ID,
405
+ limitPerMinute: limit,
406
+ });
407
+
408
+ const otherKey: TelemetryIngestionKeyLimitDecision = await consume({
409
+ ingestionKeyId: OTHER_KEY_ID,
410
+ limitPerMinute: limit,
411
+ });
412
+
413
+ expect(sameKeyAgain.outcome).toBe(
414
+ TelemetryIngestionKeyLimitOutcome.RateLimited,
415
+ );
416
+ expect(otherKey.outcome).toBe(TelemetryIngestionKeyLimitOutcome.Allowed);
417
+ expect(client.counters.get(expectedKeyFor(KEY_ID, currentTime))).toBe(2);
418
+ expect(
419
+ client.counters.get(expectedKeyFor(OTHER_KEY_ID, currentTime)),
420
+ ).toBe(1);
421
+ });
422
+ });
423
+
424
+ describe("first rejection in the window", () => {
425
+ /*
426
+ * A refused caller keeps knocking, so a caller that logged every refusal
427
+ * would answer an ingest flood with a log flood. Exactly one line per key
428
+ * per minute is what an operator needs to see WHICH key is being abused.
429
+ */
430
+ test("marks only the request that crossed the line", async () => {
431
+ const limit: number = 2;
432
+
433
+ await consume({ limitPerMinute: limit });
434
+ await consume({ limitPerMinute: limit });
435
+
436
+ const first: TelemetryIngestionKeyLimitDecision = await consume({
437
+ limitPerMinute: limit,
438
+ });
439
+ const second: TelemetryIngestionKeyLimitDecision = await consume({
440
+ limitPerMinute: limit,
441
+ });
442
+ const third: TelemetryIngestionKeyLimitDecision = await consume({
443
+ limitPerMinute: limit,
444
+ });
445
+
446
+ expect(first.isFirstRejectionInWindow).toBe(true);
447
+ expect(second.isFirstRejectionInWindow).toBe(false);
448
+ expect(third.isFirstRejectionInWindow).toBe(false);
449
+ });
450
+
451
+ test("marks the crossing again in the next window", async () => {
452
+ const limit: number = 1;
453
+
454
+ await consume({ limitPerMinute: limit });
455
+ await consume({ limitPerMinute: limit });
456
+
457
+ currentTime = currentTime + WINDOW_MS;
458
+
459
+ await consume({ limitPerMinute: limit });
460
+
461
+ const crossing: TelemetryIngestionKeyLimitDecision = await consume({
462
+ limitPerMinute: limit,
463
+ });
464
+
465
+ expect(crossing.outcome).toBe(
466
+ TelemetryIngestionKeyLimitOutcome.RateLimited,
467
+ );
468
+ expect(crossing.isFirstRejectionInWindow).toBe(true);
469
+ });
470
+ });
471
+
472
+ describe("fails open when the counter is unavailable", () => {
473
+ test("reports CounterUnavailable when there is no Redis client", async () => {
474
+ getClientMock.mockReturnValue(null);
475
+
476
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
477
+ limitPerMinute: 1,
478
+ });
479
+
480
+ expect(decision.outcome).toBe(
481
+ TelemetryIngestionKeyLimitOutcome.CounterUnavailable,
482
+ );
483
+ expect(decision.retryAfterSeconds).toBeUndefined();
484
+ });
485
+
486
+ test("reports CounterUnavailable when Redis is not connected", async () => {
487
+ isConnectedMock.mockReturnValue(false);
488
+
489
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
490
+ limitPerMinute: 1,
491
+ });
492
+
493
+ expect(decision.outcome).toBe(
494
+ TelemetryIngestionKeyLimitOutcome.CounterUnavailable,
495
+ );
496
+ expect(client.incrKeys).toHaveLength(0);
497
+ });
498
+
499
+ test("swallows a failing INCR rather than letting it reach the ingest route", async () => {
500
+ client.failNextIncr = new Error(
501
+ "READONLY You can't write against a read only replica.",
502
+ );
503
+
504
+ const decision: TelemetryIngestionKeyLimitDecision = await consume({
505
+ limitPerMinute: 1,
506
+ });
507
+
508
+ expect(decision.outcome).toBe(
509
+ TelemetryIngestionKeyLimitOutcome.CounterUnavailable,
510
+ );
511
+ expect(loggerErrorMock).not.toHaveBeenCalled();
512
+ });
513
+
514
+ test("counts normally again on the request after a transient INCR failure", async () => {
515
+ client.failNextIncr = new Error("connection reset by peer");
516
+
517
+ await consume({ limitPerMinute: 1 });
518
+
519
+ const afterRecovery: TelemetryIngestionKeyLimitDecision = await consume({
520
+ limitPerMinute: 1,
521
+ });
522
+
523
+ expect(afterRecovery.outcome).toBe(
524
+ TelemetryIngestionKeyLimitOutcome.Allowed,
525
+ );
526
+ });
527
+ });
528
+ });
@@ -0,0 +1,56 @@
1
+ import { afterEach, describe, expect, test } from "@jest/globals";
2
+ import Telemetry from "../../../Server/Utils/Telemetry";
3
+
4
+ const originalEnv: NodeJS.ProcessEnv = { ...process.env };
5
+
6
+ afterEach(() => {
7
+ process.env = { ...originalEnv };
8
+ });
9
+
10
+ describe("server telemetry exporter environment", () => {
11
+ test("continues to read generic backend exporter headers", () => {
12
+ process.env["OPENTELEMETRY_EXPORTER_OTLP_HEADERS"] =
13
+ "authorization=Bearer server-secret;x-oneuptime-token=server-key";
14
+
15
+ expect(Telemetry.getHeaders()).toEqual({
16
+ authorization: "Bearer server-secret",
17
+ "x-oneuptime-token": "server-key",
18
+ });
19
+ });
20
+
21
+ test("does not treat the public Browser key as server authorization", () => {
22
+ delete process.env["OPENTELEMETRY_EXPORTER_OTLP_HEADERS"];
23
+ process.env["PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_BROWSER_INGESTION_KEY"] =
24
+ "public-browser-key";
25
+
26
+ expect(Telemetry.getHeaders()).toEqual({});
27
+ });
28
+
29
+ test("returns no backend headers for an unset or blank value", () => {
30
+ delete process.env["OPENTELEMETRY_EXPORTER_OTLP_HEADERS"];
31
+ expect(Telemetry.getHeaders()).toEqual({});
32
+
33
+ process.env["OPENTELEMETRY_EXPORTER_OTLP_HEADERS"] = "";
34
+ expect(Telemetry.getHeaders()).toEqual({});
35
+ });
36
+
37
+ test("continues to read the generic backend exporter endpoint", () => {
38
+ process.env["OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT"] =
39
+ "https://collector.internal:4318";
40
+
41
+ expect(Telemetry.getOtlpEndpoint()?.toString()).toBe(
42
+ "https://collector.internal:4318/",
43
+ );
44
+ expect(Telemetry.getOltpTracesEndpoint()?.toString()).toBe(
45
+ "https://collector.internal:4318/v1/traces",
46
+ );
47
+ });
48
+
49
+ test("does not use the public browser endpoint as the server endpoint", () => {
50
+ delete process.env["OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT"];
51
+ process.env["PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT"] =
52
+ "https://browser-collector.example.com:4318";
53
+
54
+ expect(Telemetry.getOtlpEndpoint()).toBeNull();
55
+ });
56
+ });
@@ -0,0 +1,74 @@
1
+ import VMRunner from "../../../../Server/Utils/VM/VMRunner";
2
+ import ReturnResult from "../../../../Types/IsolatedVM/ReturnResult";
3
+ import { describe, expect, test } from "@jest/globals";
4
+
5
+ /*
6
+ * Regression guard for the host-bridge stall.
7
+ *
8
+ * Every bridge the sandbox has - axios, sleep, the log sink - is an
9
+ * isolated-vm async callback: the isolate posts a call onto Node's thread,
10
+ * Node answers it, and the isolate resumes. Each hop only advances when the
11
+ * event loop takes a turn, and a loop with nothing else pending sleeps until
12
+ * its NEXT TIMER rather than turning again.
13
+ *
14
+ * Without a ticker to wake it, the nearest timer was usually the sandbox's own
15
+ * 20s overall timeout, so `await sleep(0)` - and a request the SSRF guard
16
+ * refuses synchronously, in microseconds - came back twenty seconds later as
17
+ * "Script execution timed out". That is what failed the VMRunner SSRF suite on
18
+ * CI while it passed on a developer's machine, where an editor or a watcher
19
+ * happened to keep the loop busy.
20
+ *
21
+ * The budget below is deliberately loose. A fixed run measures single-digit
22
+ * milliseconds per round trip; the regression measured hundreds to twenty
23
+ * thousand. Anything between leaves this test alone.
24
+ */
25
+
26
+ const ROUND_TRIPS: number = 12;
27
+
28
+ /*
29
+ * Generous enough to absorb a loaded CI runner (the fixed path needs ~10ms per
30
+ * run), tight enough that the stall - which costs at least 100ms per run, and
31
+ * routinely a full second - cannot fit inside it.
32
+ */
33
+ const BUDGET_MS: number = 3000;
34
+
35
+ describe("VMRunner host bridge latency", () => {
36
+ test("a sandbox round trip does not wait for an unrelated timer", async () => {
37
+ const started: number = Date.now();
38
+
39
+ for (let index: number = 0; index < ROUND_TRIPS; index++) {
40
+ const result: ReturnResult = await VMRunner.runCodeInSandbox({
41
+ code: "await sleep(0); return 'done';",
42
+ options: { timeout: 15000 },
43
+ });
44
+
45
+ /* The point is that it finished at all, quickly, and with an answer. */
46
+ expect(result.scriptError).toBeUndefined();
47
+ expect(result.returnValue).toBe("done");
48
+ }
49
+
50
+ const elapsed: number = Date.now() - started;
51
+
52
+ expect(elapsed).toBeLessThan(BUDGET_MS);
53
+ }, 60000);
54
+
55
+ test("a request the guard refuses comes back without a host round-trip stall", async () => {
56
+ const started: number = Date.now();
57
+
58
+ for (let index: number = 0; index < ROUND_TRIPS; index++) {
59
+ const result: ReturnResult = await VMRunner.runCodeInSandbox({
60
+ /*
61
+ * Protocol-relative, so resolveEffectiveRequestUrl rejects it before
62
+ * DNS or a socket: the only cost here is the isolate <-> host hops.
63
+ */
64
+ code: "try { return await axios.get('//169.254.169.254/latest/meta-data/'); } catch (error) { return 'refused'; }",
65
+ options: { timeout: 15000 },
66
+ });
67
+
68
+ expect(result.scriptError).toBeUndefined();
69
+ expect(result.returnValue).toBe("refused");
70
+ }
71
+
72
+ expect(Date.now() - started).toBeLessThan(BUDGET_MS);
73
+ }, 60000);
74
+ });