@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,362 @@
1
+ import UserNotificationSettingService from "../../../../Server/Services/UserNotificationSettingService";
2
+ import EmailRollupFlushRunner, {
3
+ RollupSweepStats,
4
+ } from "../../../../Server/Utils/EmailRollup/EmailRollupFlushRunner";
5
+ import { CLAIM_EPOCH_MINUTES } from "../../../../Server/Utils/EmailRollup/EmailRollupConstants";
6
+ import { RollupBatchStatus } from "../../../../Models/DatabaseModels/UserNotificationEmailRollupBatch";
7
+ import OneUptimeDate from "../../../../Types/Date";
8
+ import Email from "../../../../Types/Email";
9
+ import RollupCategory from "../../../../Types/NotificationSetting/NotificationEmailRollupCategory";
10
+ import NotificationSettingEventType from "../../../../Types/NotificationSetting/NotificationSettingEventType";
11
+ import ObjectID from "../../../../Types/ObjectID";
12
+ import {
13
+ FakeItemRow,
14
+ FakeRow,
15
+ RollupHarness,
16
+ SentRollupMail,
17
+ emptyRollupHarness,
18
+ installRollupHarness,
19
+ pendingItems,
20
+ seedItem,
21
+ seedNotificationSetting,
22
+ seedProject,
23
+ seedVerifiedEmail,
24
+ } from "./EmailRollupTestHarness";
25
+ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
26
+
27
+ const PROJECT_ID: ObjectID = new ObjectID(
28
+ "11111111-1111-4111-8111-111111111111",
29
+ );
30
+ const USER_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
31
+ const OTHER_PROJECT_ID: ObjectID = new ObjectID(
32
+ "44444444-4444-4444-8444-444444444444",
33
+ );
34
+ const OTHER_USER_ID: ObjectID = new ObjectID(
35
+ "33333333-3333-4333-8333-333333333333",
36
+ );
37
+ const TO_EMAIL: Email = new Email("owner@example.com");
38
+ const OTHER_EMAIL: Email = new Email("second-owner@example.com");
39
+ const NOW: Date = OneUptimeDate.fromString("2026-09-03T17:07:30.000Z");
40
+ const CREATED_EVENT: NotificationSettingEventType =
41
+ NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION;
42
+ const STATE_CHANGED_EVENT: NotificationSettingEventType =
43
+ NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION;
44
+ const ALERT_EVENT: NotificationSettingEventType =
45
+ NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION;
46
+
47
+ describe("EmailRollupFlushRunner - preferences changed while email is queued", () => {
48
+ let harness: RollupHarness;
49
+
50
+ beforeEach(() => {
51
+ harness = emptyRollupHarness();
52
+ installRollupHarness(harness);
53
+ seedProject(harness, { projectId: PROJECT_ID, name: "Acme" });
54
+ seedVerifiedEmail(harness, {
55
+ projectId: PROJECT_ID,
56
+ userId: USER_ID,
57
+ email: TO_EMAIL,
58
+ });
59
+ });
60
+
61
+ afterEach(() => {
62
+ jest.restoreAllMocks();
63
+ });
64
+
65
+ function seedDue(
66
+ data: {
67
+ subject?: string | undefined;
68
+ eventType?: NotificationSettingEventType | undefined;
69
+ rollupCategory?: RollupCategory | undefined;
70
+ projectId?: ObjectID | undefined;
71
+ userId?: ObjectID | undefined;
72
+ toEmail?: Email | undefined;
73
+ } = {},
74
+ ): FakeItemRow {
75
+ return seedItem(harness, {
76
+ projectId: data.projectId ?? PROJECT_ID,
77
+ userId: data.userId ?? USER_ID,
78
+ toEmail: data.toEmail ?? TO_EMAIL,
79
+ createdAt: OneUptimeDate.addRemoveMinutes(NOW, -12),
80
+ subject: data.subject,
81
+ eventType: data.eventType,
82
+ rollupCategory: data.rollupCategory,
83
+ });
84
+ }
85
+
86
+ function getSetting(eventType: NotificationSettingEventType): FakeRow {
87
+ return harness.notificationSettings.find((row: FakeRow): boolean => {
88
+ return (
89
+ row["eventType"] === eventType &&
90
+ String(row["projectId"]) === PROJECT_ID.toString() &&
91
+ String(row["userId"]) === USER_ID.toString()
92
+ );
93
+ })!;
94
+ }
95
+
96
+ test("a mixed batch omits muted events and reports only delivered notifications", async () => {
97
+ seedDue({ subject: "Checkout is down" });
98
+ seedDue({
99
+ subject: "Muted incident state change",
100
+ eventType: STATE_CHANGED_EVENT,
101
+ });
102
+ seedDue({
103
+ subject: "CPU is high",
104
+ eventType: ALERT_EVENT,
105
+ rollupCategory: RollupCategory.Alerts,
106
+ });
107
+ getSetting(STATE_CHANGED_EVENT)["alertByEmail"] = false;
108
+
109
+ const stats: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
110
+ now: NOW,
111
+ });
112
+
113
+ expect(stats.sent).toBe(1);
114
+ expect(harness.sent).toHaveLength(1);
115
+ const mail: SentRollupMail = harness.sent[0]!;
116
+ expect(mail.subject).toBe("[Acme] 2 notifications: 1 Alerts, 1 Incidents");
117
+ expect(mail.vars["summaryCount"]).toBe("2 notifications");
118
+ expect(JSON.stringify(mail.vars)).toContain("Checkout is down");
119
+ expect(JSON.stringify(mail.vars)).toContain("CPU is high");
120
+ expect(JSON.stringify(mail.vars)).not.toContain(
121
+ "Muted incident state change",
122
+ );
123
+ expect(harness.batches[0]!.itemCount).toBe(2);
124
+ expect(pendingItems(harness)).toHaveLength(0);
125
+ expect(harness.items).toHaveLength(3);
126
+ expect(harness.callLog).toEqual(["preferences", "stamp", "send"]);
127
+ });
128
+
129
+ test.each([false, null, undefined])(
130
+ "an event whose email preference is %s is skipped even if other channels remain enabled",
131
+ async (alertByEmail: boolean | null | undefined) => {
132
+ seedDue();
133
+ const setting: FakeRow = getSetting(CREATED_EVENT);
134
+ setting["alertByEmail"] = alertByEmail;
135
+ setting["alertByPush"] = true;
136
+ setting["alertBySMS"] = true;
137
+
138
+ const stats: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
139
+ now: NOW,
140
+ });
141
+
142
+ expect(stats.skipped).toBe(1);
143
+ expect(stats.sent).toBe(0);
144
+ expect(harness.sendAttempts).toHaveLength(0);
145
+ expect(harness.batches[0]!.status).toBe(RollupBatchStatus.Skipped);
146
+ expect(harness.batches[0]!.itemCount).toBe(0);
147
+ expect(harness.batches[0]!.sentAt).toBeNull();
148
+ expect(harness.batches[0]!.statusMessage).toContain("no longer enabled");
149
+ expect(pendingItems(harness)).toHaveLength(0);
150
+ expect(setting["alertByPush"]).toBe(true);
151
+ expect(setting["alertBySMS"]).toBe(true);
152
+ },
153
+ );
154
+
155
+ test("deleting a preference removes that event from an otherwise enabled batch", async () => {
156
+ seedDue({ subject: "Deleted subscription" });
157
+ seedDue({
158
+ subject: "Still subscribed",
159
+ eventType: STATE_CHANGED_EVENT,
160
+ });
161
+ harness.notificationSettings = harness.notificationSettings.filter(
162
+ (row: FakeRow): boolean => {
163
+ return row["eventType"] !== CREATED_EVENT;
164
+ },
165
+ );
166
+
167
+ await EmailRollupFlushRunner.runSweep({ now: NOW });
168
+
169
+ expect(harness.sent).toHaveLength(1);
170
+ expect(harness.sent[0]!.subject).toContain("Still subscribed");
171
+ expect(JSON.stringify(harness.sent[0]!.vars)).not.toContain(
172
+ "Deleted subscription",
173
+ );
174
+ expect(harness.batches[0]!.itemCount).toBe(1);
175
+ });
176
+
177
+ test("an absent preference is not replaced by another user's or project's enabled preference", async () => {
178
+ seedDue();
179
+ harness.notificationSettings = [];
180
+ seedNotificationSetting(harness, {
181
+ projectId: OTHER_PROJECT_ID,
182
+ userId: USER_ID,
183
+ eventType: CREATED_EVENT,
184
+ });
185
+ seedNotificationSetting(harness, {
186
+ projectId: PROJECT_ID,
187
+ userId: OTHER_USER_ID,
188
+ eventType: CREATED_EVENT,
189
+ });
190
+
191
+ const stats: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
192
+ now: NOW,
193
+ });
194
+
195
+ expect(stats.skipped).toBe(1);
196
+ expect(harness.sendAttempts).toHaveLength(0);
197
+ expect(UserNotificationSettingService.findBy).toHaveBeenCalledWith({
198
+ query: {
199
+ projectId: PROJECT_ID,
200
+ userId: USER_ID,
201
+ alertByEmail: true,
202
+ },
203
+ select: { eventType: true },
204
+ limit: expect.any(Number),
205
+ skip: 0,
206
+ props: { isRoot: true },
207
+ });
208
+ });
209
+
210
+ test("muting one recipient leaves other users and other projects subscribed", async () => {
211
+ seedProject(harness, { projectId: OTHER_PROJECT_ID, name: "Beta" });
212
+ seedVerifiedEmail(harness, {
213
+ projectId: OTHER_PROJECT_ID,
214
+ userId: USER_ID,
215
+ email: TO_EMAIL,
216
+ });
217
+ seedVerifiedEmail(harness, {
218
+ projectId: PROJECT_ID,
219
+ userId: OTHER_USER_ID,
220
+ email: OTHER_EMAIL,
221
+ });
222
+ seedDue({ subject: "Muted in Acme" });
223
+ seedDue({ subject: "Enabled in Beta", projectId: OTHER_PROJECT_ID });
224
+ seedDue({
225
+ subject: "Enabled for another user",
226
+ userId: OTHER_USER_ID,
227
+ toEmail: OTHER_EMAIL,
228
+ });
229
+ getSetting(CREATED_EVENT)["alertByEmail"] = false;
230
+
231
+ const stats: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
232
+ now: NOW,
233
+ });
234
+
235
+ expect(stats.skipped).toBe(1);
236
+ expect(stats.sent).toBe(2);
237
+ expect(
238
+ harness.sent.map((mail: SentRollupMail): string => {
239
+ return mail.subject;
240
+ }),
241
+ ).toEqual(
242
+ expect.arrayContaining([
243
+ expect.stringContaining("Enabled in Beta"),
244
+ expect.stringContaining("Enabled for another user"),
245
+ ]),
246
+ );
247
+ expect(JSON.stringify(harness.sent)).not.toContain("Muted in Acme");
248
+ });
249
+
250
+ test("a fully muted batch stays consumed after email is enabled again", async () => {
251
+ seedDue();
252
+ getSetting(CREATED_EVENT)["alertByEmail"] = false;
253
+ await EmailRollupFlushRunner.runSweep({ now: NOW });
254
+ getSetting(CREATED_EVENT)["alertByEmail"] = true;
255
+
256
+ const later: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
257
+ now: OneUptimeDate.addRemoveMinutes(NOW, CLAIM_EPOCH_MINUTES),
258
+ });
259
+
260
+ expect(later.bucketsDue).toBe(0);
261
+ expect(harness.batches).toHaveLength(1);
262
+ expect(harness.sendAttempts).toHaveLength(0);
263
+ });
264
+
265
+ test("the most recent preference is used when email is enabled again before the flush", async () => {
266
+ seedDue();
267
+ getSetting(CREATED_EVENT)["alertByEmail"] = false;
268
+ getSetting(CREATED_EVENT)["alertByEmail"] = true;
269
+
270
+ await EmailRollupFlushRunner.runSweep({ now: NOW });
271
+
272
+ expect(harness.sent).toHaveLength(1);
273
+ expect(harness.batches[0]!.itemCount).toBe(1);
274
+ });
275
+
276
+ test("a preference lookup failure preserves pending items and retries once in the next epoch", async () => {
277
+ seedDue({ subject: "Keep for retry" });
278
+ seedDue({ subject: "Also keep for retry" });
279
+ jest
280
+ .spyOn(UserNotificationSettingService, "findBy")
281
+ .mockRejectedValueOnce(new Error("preferences read timed out"));
282
+
283
+ const failed: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
284
+ now: NOW,
285
+ });
286
+
287
+ expect(failed.failed).toBe(1);
288
+ expect(harness.batches[0]!.status).toBe(RollupBatchStatus.Failed);
289
+ expect(harness.batches[0]!.itemCount).toBe(0);
290
+ expect(harness.batches[0]!.statusMessage).toBe(
291
+ "preferences read timed out",
292
+ );
293
+ expect(pendingItems(harness)).toHaveLength(2);
294
+ expect(
295
+ harness.items.every((item: FakeItemRow): boolean => {
296
+ return item.rollupBatchId === null;
297
+ }),
298
+ ).toBe(true);
299
+ expect(harness.itemUpdateByCalls).toBe(0);
300
+ expect(harness.sendAttempts).toHaveLength(0);
301
+
302
+ const sameEpoch: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
303
+ now: NOW,
304
+ });
305
+ expect(sameEpoch.claimCollisions).toBe(1);
306
+ expect(UserNotificationSettingService.findBy).toHaveBeenCalledTimes(1);
307
+
308
+ await EmailRollupFlushRunner.runSweep({
309
+ now: OneUptimeDate.addRemoveMinutes(NOW, CLAIM_EPOCH_MINUTES),
310
+ });
311
+
312
+ expect(harness.batches).toHaveLength(2);
313
+ expect(harness.batches[1]!.status).toBe(RollupBatchStatus.Sent);
314
+ expect(harness.batches[1]!.itemCount).toBe(2);
315
+ expect(harness.sent).toHaveLength(1);
316
+ expect(pendingItems(harness)).toHaveLength(0);
317
+ });
318
+
319
+ test("a preference lookup failure does not prevent another recipient's delivery", async () => {
320
+ seedDue();
321
+ seedVerifiedEmail(harness, {
322
+ projectId: PROJECT_ID,
323
+ userId: OTHER_USER_ID,
324
+ email: OTHER_EMAIL,
325
+ });
326
+ seedDue({ userId: OTHER_USER_ID, toEmail: OTHER_EMAIL });
327
+ jest
328
+ .spyOn(UserNotificationSettingService, "findBy")
329
+ .mockRejectedValueOnce(new Error("preferences read timed out"));
330
+
331
+ const stats: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
332
+ now: NOW,
333
+ });
334
+
335
+ expect(stats.failed).toBe(1);
336
+ expect(stats.sent).toBe(1);
337
+ expect(harness.sent[0]!.toEmail).toBe(OTHER_EMAIL.toString());
338
+ expect(pendingItems(harness)).toHaveLength(1);
339
+ expect(pendingItems(harness)[0]!.userId).toBe(USER_ID);
340
+ });
341
+
342
+ test("a failed send records only the enabled items that were attempted", async () => {
343
+ seedDue();
344
+ seedDue({ eventType: STATE_CHANGED_EVENT });
345
+ getSetting(STATE_CHANGED_EVENT)["alertByEmail"] = false;
346
+ harness.failSend = (): Error => {
347
+ return new Error("mail transport unavailable");
348
+ };
349
+
350
+ const stats: RollupSweepStats = await EmailRollupFlushRunner.runSweep({
351
+ now: NOW,
352
+ });
353
+
354
+ expect(stats.failed).toBe(1);
355
+ expect(harness.batches[0]!.status).toBe(RollupBatchStatus.Failed);
356
+ expect(harness.batches[0]!.itemCount).toBe(1);
357
+ expect(harness.sendAttempts[0]!.vars["summaryCount"]).toBe(
358
+ "1 notification",
359
+ );
360
+ expect(pendingItems(harness)).toHaveLength(0);
361
+ });
362
+ });
@@ -7,6 +7,7 @@ import ProjectService from "../../../../Server/Services/ProjectService";
7
7
  import UserEmailService from "../../../../Server/Services/UserEmailService";
8
8
  import UserNotificationEmailRollupBatchService from "../../../../Server/Services/UserNotificationEmailRollupBatchService";
9
9
  import UserNotificationEmailRollupItemService from "../../../../Server/Services/UserNotificationEmailRollupItemService";
10
+ import UserNotificationSettingService from "../../../../Server/Services/UserNotificationSettingService";
10
11
  import logger from "../../../../Server/Utils/Logger";
11
12
  import UserNotificationEmailRollupBatch, {
12
13
  RollupBatchStatus,
@@ -102,6 +103,8 @@ export interface RollupHarness {
102
103
  batches: Array<FakeBatchRow>;
103
104
  // UserEmail rows: { _id, id, userId, projectId, isVerified, email }.
104
105
  userEmails: Array<FakeRow>;
106
+ // Current event preferences; queued events start enabled at enqueue time.
107
+ notificationSettings: Array<FakeRow>;
105
108
  // Project rows: { _id, id, name }.
106
109
  projects: Array<FakeRow>;
107
110
 
@@ -114,7 +117,8 @@ export interface RollupHarness {
114
117
 
115
118
  /*
116
119
  * An ordered trace of the collaborator calls whose ORDER is load-bearing.
117
- * "stamp" is pushed by the item updateBy, "send" by MailService.sendMail:
120
+ * "preferences" is pushed by the settings read, "stamp" by the item
121
+ * updateBy, and "send" by MailService.sendMail:
118
122
  * stamp-before-send is the property that stops a permanently failing send
119
123
  * re-spamming an address every epoch, and it is only observable as an
120
124
  * ordering.
@@ -165,6 +169,7 @@ export function emptyRollupHarness(): RollupHarness {
165
169
  items: [],
166
170
  batches: [],
167
171
  userEmails: [],
172
+ notificationSettings: [],
168
173
  projects: [],
169
174
  sendAttempts: [],
170
175
  sent: [],
@@ -367,9 +372,55 @@ export function seedItem(
367
372
 
368
373
  harness.items.push(row);
369
374
 
375
+ /*
376
+ * An owner email only enters the queue when its event is enabled. Seed that
377
+ * initial preference once; tests can then disable or remove it before the
378
+ * flush to exercise changes made while the email was waiting.
379
+ */
380
+ const hasSetting: boolean = harness.notificationSettings.some(
381
+ (setting: FakeRow): boolean => {
382
+ return (
383
+ toKey(setting["projectId"]) === toKey(row.projectId) &&
384
+ toKey(setting["userId"]) === toKey(row.userId) &&
385
+ setting["eventType"] === row.eventType
386
+ );
387
+ },
388
+ );
389
+
390
+ if (!hasSetting) {
391
+ seedNotificationSetting(harness, {
392
+ projectId: row.projectId,
393
+ userId: row.userId,
394
+ eventType: row.eventType,
395
+ });
396
+ }
397
+
370
398
  return row;
371
399
  }
372
400
 
401
+ export function seedNotificationSetting(
402
+ harness: RollupHarness,
403
+ data: {
404
+ projectId: ObjectID;
405
+ userId: ObjectID;
406
+ eventType: NotificationSettingEventType;
407
+ alertByEmail?: boolean | undefined;
408
+ },
409
+ ): FakeRow {
410
+ const id: ObjectID = ObjectID.generate();
411
+ const setting: FakeRow = {
412
+ _id: id,
413
+ id: id,
414
+ projectId: data.projectId,
415
+ userId: data.userId,
416
+ eventType: data.eventType,
417
+ alertByEmail: data.alertByEmail ?? true,
418
+ };
419
+
420
+ harness.notificationSettings.push(setting);
421
+ return setting;
422
+ }
423
+
373
424
  export function seedVerifiedEmail(
374
425
  harness: RollupHarness,
375
426
  data: {
@@ -649,6 +700,31 @@ export function installRollupHarness(harness: RollupHarness): void {
649
700
 
650
701
  // -- The recipient re-validation ----------------------------------------
651
702
 
703
+ jest
704
+ .spyOn(UserNotificationSettingService, "findBy")
705
+ .mockImplementation(((args: {
706
+ query?: Record<string, unknown>;
707
+ select?: Record<string, unknown>;
708
+ limit?: unknown;
709
+ skip?: number;
710
+ }) => {
711
+ harness.callLog.push("preferences");
712
+ const matched: Array<FakeRow> = harness.notificationSettings.filter(
713
+ (row: FakeRow): boolean => {
714
+ return matchesQuery(args.query, row);
715
+ },
716
+ );
717
+ const skip: number = args.skip ?? 0;
718
+
719
+ return Promise.resolve(
720
+ matched
721
+ .slice(skip, skip + toLimit(args.limit, matched.length))
722
+ .map((row: FakeRow): FakeRow => {
723
+ return applySelect(row, args.select);
724
+ }),
725
+ );
726
+ }) as never);
727
+
652
728
  jest.spyOn(UserEmailService, "findBy").mockImplementation(((args: {
653
729
  query?: Record<string, unknown>;
654
730
  select?: Record<string, unknown>;
@@ -0,0 +1,190 @@
1
+ import { afterEach, describe, expect, test, jest } from "@jest/globals";
2
+ import type {
3
+ ExpressRequest,
4
+ ExpressResponse,
5
+ } from "../../../Server/Utils/Express";
6
+
7
+ const MANAGED_KEYS: Array<string> = [
8
+ "HOST",
9
+ "PUBLIC_TEST_SETTING",
10
+ "OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT",
11
+ "OPENTELEMETRY_EXPORTER_OTLP_HEADERS",
12
+ "PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT",
13
+ "PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_BROWSER_INGESTION_KEY",
14
+ "PUBLIC_OTEL_EXPORTER_OTLP_HEADERS",
15
+ ];
16
+
17
+ const originalEnv: NodeJS.ProcessEnv = { ...process.env };
18
+
19
+ interface BrowserWindow {
20
+ process?: {
21
+ env?: Record<string, unknown>;
22
+ };
23
+ }
24
+
25
+ async function render(
26
+ overrides: Record<string, string | undefined>,
27
+ initialWindow: BrowserWindow = {},
28
+ ): Promise<{ script: string; window: BrowserWindow }> {
29
+ for (const key of MANAGED_KEYS) {
30
+ delete process.env[key];
31
+ }
32
+
33
+ for (const [key, value] of Object.entries(overrides)) {
34
+ if (typeof value === "undefined") {
35
+ delete process.env[key];
36
+ } else {
37
+ process.env[key] = value;
38
+ }
39
+ }
40
+
41
+ jest.resetModules();
42
+ const { getFrontendEnvironmentScript } = await import(
43
+ "../../../Server/Utils/FrontendEnvironment"
44
+ );
45
+ const script: string = getFrontendEnvironmentScript();
46
+
47
+ new Function("window", script)(initialWindow);
48
+
49
+ return { script, window: initialWindow };
50
+ }
51
+
52
+ afterEach(() => {
53
+ process.env = { ...originalEnv };
54
+ jest.resetModules();
55
+ });
56
+
57
+ describe("frontend environment script serialization", () => {
58
+ test("creates window.process and window.process.env when neither exists", async () => {
59
+ const result: Awaited<ReturnType<typeof render>> = await render({
60
+ HOST: "oneuptime.example.com",
61
+ });
62
+
63
+ expect(result.window.process?.env).toMatchObject({
64
+ HOST: "oneuptime.example.com",
65
+ });
66
+ });
67
+
68
+ test("replaces a stale pre-existing environment snapshot", async () => {
69
+ const initialWindow: BrowserWindow = {
70
+ process: { env: { STALE_SECRET: "must-disappear" } },
71
+ };
72
+ const result: Awaited<ReturnType<typeof render>> = await render(
73
+ { HOST: "fresh.example.com" },
74
+ initialWindow,
75
+ );
76
+
77
+ expect(result.window.process?.env).toMatchObject({
78
+ HOST: "fresh.example.com",
79
+ });
80
+ expect(result.window.process?.env).not.toHaveProperty("STALE_SECRET");
81
+ });
82
+
83
+ test("does not reflect a backend bearer token in either script bytes or runtime values", async () => {
84
+ const sentinel: string =
85
+ 'super-secret-\\"token\\nwith-special-characters-and-123456';
86
+ const result: Awaited<ReturnType<typeof render>> = await render({
87
+ OPENTELEMETRY_EXPORTER_OTLP_HEADERS: `authorization=Bearer ${sentinel}`,
88
+ });
89
+
90
+ expect(result.script).not.toContain("authorization");
91
+ expect(result.script).not.toContain("super-secret");
92
+ expect(JSON.stringify(result.window.process?.env)).not.toContain(
93
+ "super-secret",
94
+ );
95
+ });
96
+
97
+ test("does not reflect a backend endpoint that may contain URL credentials", async () => {
98
+ const result: Awaited<ReturnType<typeof render>> = await render({
99
+ OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT:
100
+ "https://server-user:server-password@collector.internal:4318",
101
+ });
102
+
103
+ expect(result.script).not.toContain("server-user");
104
+ expect(result.script).not.toContain("server-password");
105
+ });
106
+
107
+ test("does not serialize a PUBLIC_-prefixed standard OTLP header alias", async () => {
108
+ const result: Awaited<ReturnType<typeof render>> = await render({
109
+ PUBLIC_OTEL_EXPORTER_OTLP_HEADERS:
110
+ "authorization=Bearer public-alias-secret",
111
+ });
112
+
113
+ expect(result.script).not.toContain("public-alias-secret");
114
+ expect(result.window.process?.env).not.toHaveProperty(
115
+ "PUBLIC_OTEL_EXPORTER_OTLP_HEADERS",
116
+ );
117
+ });
118
+
119
+ test("serializes the public browser endpoint and origin-bound Browser key", async () => {
120
+ const result: Awaited<ReturnType<typeof render>> = await render({
121
+ PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT:
122
+ "https://ingest.example.com:4318",
123
+ PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_BROWSER_INGESTION_KEY:
124
+ "public-browser-key",
125
+ });
126
+
127
+ expect(result.window.process?.env).toMatchObject({
128
+ PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT:
129
+ "https://ingest.example.com:4318",
130
+ PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_BROWSER_INGESTION_KEY:
131
+ "public-browser-key",
132
+ });
133
+ });
134
+
135
+ test("serializes hostile-looking public text as data without breaking the script", async () => {
136
+ const unusualPublicValue: string = '</script>";window.pwned=true;//';
137
+ const result: Awaited<ReturnType<typeof render>> = await render({
138
+ PUBLIC_TEST_SETTING: unusualPublicValue,
139
+ });
140
+
141
+ expect(result.window.process?.env?.["PUBLIC_TEST_SETTING"]).toBe(
142
+ unusualPublicValue,
143
+ );
144
+ expect((result.window as BrowserWindow & { pwned?: boolean }).pwned).toBe(
145
+ undefined,
146
+ );
147
+ });
148
+
149
+ test("emits a valid empty telemetry configuration when all telemetry values are unset", async () => {
150
+ const result: Awaited<ReturnType<typeof render>> = await render({});
151
+
152
+ expect(result.window.process?.env).not.toHaveProperty(
153
+ "OPENTELEMETRY_EXPORTER_OTLP_HEADERS",
154
+ );
155
+ expect(result.window.process?.env).not.toHaveProperty(
156
+ "PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_BROWSER_INGESTION_KEY",
157
+ );
158
+ });
159
+
160
+ test("marks the complete environment response private and non-cacheable", async () => {
161
+ jest.resetModules();
162
+ const {
163
+ FRONTEND_ENVIRONMENT_CACHE_CONTROL,
164
+ sendFrontendEnvironmentResponse,
165
+ } = await import("../../../Server/Utils/FrontendEnvironment");
166
+ const setHeader: ReturnType<typeof jest.fn> = jest.fn();
167
+ const writeHead: ReturnType<typeof jest.fn> = jest.fn();
168
+ const end: ReturnType<typeof jest.fn> = jest.fn();
169
+ const response: ExpressResponse = {
170
+ setHeader,
171
+ writeHead,
172
+ end,
173
+ } as unknown as ExpressResponse;
174
+
175
+ sendFrontendEnvironmentResponse({} as unknown as ExpressRequest, response);
176
+
177
+ expect(setHeader).toHaveBeenCalledWith(
178
+ "Cache-Control",
179
+ FRONTEND_ENVIRONMENT_CACHE_CONTROL,
180
+ );
181
+ expect(FRONTEND_ENVIRONMENT_CACHE_CONTROL).toContain("private");
182
+ expect(FRONTEND_ENVIRONMENT_CACHE_CONTROL).toContain("no-store");
183
+ expect(setHeader).toHaveBeenCalledWith("Pragma", "no-cache");
184
+ expect(setHeader).toHaveBeenCalledWith("Expires", "0");
185
+ expect(writeHead).toHaveBeenCalledWith(200, {
186
+ "Content-Type": "text/javascript",
187
+ });
188
+ expect(end).toHaveBeenCalledTimes(1);
189
+ });
190
+ });