@oneuptime/common 13.0.6 → 13.0.7

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 (589) hide show
  1. package/Models/DatabaseModels/AIAgentOwnerTeam.ts +6 -0
  2. package/Models/DatabaseModels/AIAgentOwnerUser.ts +6 -0
  3. package/Models/DatabaseModels/Alert.ts +12 -0
  4. package/Models/DatabaseModels/AlertEpisodeOwnerTeam.ts +6 -1
  5. package/Models/DatabaseModels/AlertEpisodeOwnerUser.ts +6 -1
  6. package/Models/DatabaseModels/AlertOwnerTeam.ts +6 -1
  7. package/Models/DatabaseModels/AlertOwnerUser.ts +6 -1
  8. package/Models/DatabaseModels/CephClusterOwnerTeam.ts +6 -0
  9. package/Models/DatabaseModels/CephClusterOwnerUser.ts +6 -0
  10. package/Models/DatabaseModels/CloudResourceOwnerTeam.ts +6 -0
  11. package/Models/DatabaseModels/CloudResourceOwnerUser.ts +6 -0
  12. package/Models/DatabaseModels/DashboardOwnerTeam.ts +6 -1
  13. package/Models/DatabaseModels/DashboardOwnerUser.ts +6 -1
  14. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +8 -0
  15. package/Models/DatabaseModels/DockerHostOwnerTeam.ts +6 -0
  16. package/Models/DatabaseModels/DockerHostOwnerUser.ts +6 -0
  17. package/Models/DatabaseModels/DockerSwarmClusterOwnerTeam.ts +6 -0
  18. package/Models/DatabaseModels/DockerSwarmClusterOwnerUser.ts +6 -0
  19. package/Models/DatabaseModels/HostOwnerTeam.ts +6 -0
  20. package/Models/DatabaseModels/HostOwnerUser.ts +6 -0
  21. package/Models/DatabaseModels/Incident.ts +12 -0
  22. package/Models/DatabaseModels/IncidentEpisodeOwnerTeam.ts +6 -1
  23. package/Models/DatabaseModels/IncidentEpisodeOwnerUser.ts +6 -1
  24. package/Models/DatabaseModels/IncidentOwnerTeam.ts +6 -1
  25. package/Models/DatabaseModels/IncidentOwnerUser.ts +6 -1
  26. package/Models/DatabaseModels/IncidentTemplateOwnerTeam.ts +6 -0
  27. package/Models/DatabaseModels/IncidentTemplateOwnerUser.ts +6 -0
  28. package/Models/DatabaseModels/IncomingCallPolicyOwnerTeam.ts +6 -1
  29. package/Models/DatabaseModels/IncomingCallPolicyOwnerUser.ts +6 -1
  30. package/Models/DatabaseModels/IoTFleetOwnerTeam.ts +6 -0
  31. package/Models/DatabaseModels/IoTFleetOwnerUser.ts +6 -0
  32. package/Models/DatabaseModels/KubernetesClusterOwnerTeam.ts +6 -0
  33. package/Models/DatabaseModels/KubernetesClusterOwnerUser.ts +6 -0
  34. package/Models/DatabaseModels/Monitor.ts +2 -3
  35. package/Models/DatabaseModels/MonitorGroupOwnerTeam.ts +6 -0
  36. package/Models/DatabaseModels/MonitorGroupOwnerUser.ts +6 -0
  37. package/Models/DatabaseModels/MonitorOwnerTeam.ts +6 -1
  38. package/Models/DatabaseModels/MonitorOwnerUser.ts +6 -1
  39. package/Models/DatabaseModels/MonitorTemplate.ts +2 -3
  40. package/Models/DatabaseModels/NetworkDeviceOwnerTeam.ts +6 -0
  41. package/Models/DatabaseModels/NetworkDeviceOwnerUser.ts +6 -0
  42. package/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.ts +6 -1
  43. package/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.ts +6 -1
  44. package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerTeam.ts +6 -1
  45. package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerUser.ts +6 -1
  46. package/Models/DatabaseModels/PodmanHostOwnerTeam.ts +6 -0
  47. package/Models/DatabaseModels/PodmanHostOwnerUser.ts +6 -0
  48. package/Models/DatabaseModels/ProbeOwnerTeam.ts +6 -0
  49. package/Models/DatabaseModels/ProbeOwnerUser.ts +6 -0
  50. package/Models/DatabaseModels/ProxmoxClusterOwnerTeam.ts +6 -0
  51. package/Models/DatabaseModels/ProxmoxClusterOwnerUser.ts +6 -0
  52. package/Models/DatabaseModels/RumApplicationOwnerTeam.ts +6 -0
  53. package/Models/DatabaseModels/RumApplicationOwnerUser.ts +6 -0
  54. package/Models/DatabaseModels/RunbookOwnerTeam.ts +6 -1
  55. package/Models/DatabaseModels/RunbookOwnerUser.ts +6 -1
  56. package/Models/DatabaseModels/RunnerOwnerTeam.ts +6 -1
  57. package/Models/DatabaseModels/RunnerOwnerUser.ts +6 -1
  58. package/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam.ts +6 -1
  59. package/Models/DatabaseModels/ScheduledMaintenanceOwnerUser.ts +6 -1
  60. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerTeam.ts +8 -0
  61. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +8 -0
  62. package/Models/DatabaseModels/ServerlessFunctionOwnerTeam.ts +6 -0
  63. package/Models/DatabaseModels/ServerlessFunctionOwnerUser.ts +6 -0
  64. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +6 -1
  65. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +6 -1
  66. package/Models/DatabaseModels/ServiceOwnerTeam.ts +6 -0
  67. package/Models/DatabaseModels/ServiceOwnerUser.ts +6 -0
  68. package/Models/DatabaseModels/StatusPageOwnerTeam.ts +6 -1
  69. package/Models/DatabaseModels/StatusPageOwnerUser.ts +6 -1
  70. package/Models/DatabaseModels/VMwareVCenterOwnerTeam.ts +6 -0
  71. package/Models/DatabaseModels/VMwareVCenterOwnerUser.ts +6 -0
  72. package/Models/DatabaseModels/WorkflowOwnerTeam.ts +6 -1
  73. package/Models/DatabaseModels/WorkflowOwnerUser.ts +6 -1
  74. package/Scripts/benchmark-fanin-capacity.js +2 -2
  75. package/Server/API/AIAgentDataAPI.ts +1 -1
  76. package/Server/API/AIChatAPI.ts +6 -4
  77. package/Server/API/AIInvestigationAPI.ts +7 -0
  78. package/Server/API/StatusPageAPI.ts +13 -0
  79. package/Server/Infrastructure/Postgres/LocalMigrationGenerationDataSource.ts +1 -1
  80. package/Server/Infrastructure/Postgres/SchemaMigrations/1793500000000-MakeOwnerRowsUnique.ts +1057 -0
  81. package/Server/Infrastructure/Postgres/SchemaMigrations/1793700000000-AddAIInvestigationDecision.ts +25 -0
  82. package/Server/Infrastructure/Postgres/SchemaMigrations/1793800000000-RemoveMonitorDescriptionLengthLimit.ts +31 -0
  83. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  84. package/Server/Infrastructure/Postgres/SchemaMigrations/Readme.md +6 -4
  85. package/Server/Middleware/IdentityRateLimit.ts +34 -1
  86. package/Server/Middleware/PublicDashboardRateLimit.ts +169 -39
  87. package/Server/Services/AlertEpisodeService.ts +13 -34
  88. package/Server/Services/AlertGroupingEngineService.ts +7 -4
  89. package/Server/Services/AlertService.ts +13 -32
  90. package/Server/Services/CephClusterOwnerRuleEngineService.ts +18 -10
  91. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +18 -10
  92. package/Server/Services/DashboardOwnerRuleEngineService.ts +18 -10
  93. package/Server/Services/DatabaseService.ts +101 -1
  94. package/Server/Services/DockerHostOwnerRuleEngineService.ts +18 -10
  95. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +18 -10
  96. package/Server/Services/HostOwnerRuleEngineService.ts +18 -10
  97. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +6 -4
  98. package/Server/Services/IncidentEpisodeService.ts +15 -75
  99. package/Server/Services/IncidentGroupingEngineService.ts +7 -4
  100. package/Server/Services/IncidentService.ts +13 -32
  101. package/Server/Services/IncidentTemplateService.ts +13 -36
  102. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +18 -10
  103. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +18 -10
  104. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +18 -10
  105. package/Server/Services/MonitorService.ts +13 -32
  106. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +18 -10
  107. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +18 -10
  108. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +18 -10
  109. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +18 -10
  110. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +18 -10
  111. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +18 -10
  112. package/Server/Services/RunbookOwnerRuleEngineService.ts +18 -10
  113. package/Server/Services/ScheduledMaintenanceService.ts +13 -34
  114. package/Server/Services/ScheduledMaintenanceTemplateService.ts +12 -34
  115. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +18 -10
  116. package/Server/Services/ServiceOwnerRuleEngineService.ts +18 -10
  117. package/Server/Services/StatusPagePrivateUserService.ts +38 -29
  118. package/Server/Services/StatusPagePrivateUserSessionService.ts +49 -1
  119. package/Server/Services/StatusPageService.ts +59 -36
  120. package/Server/Services/UserSessionService.ts +6 -0
  121. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +18 -10
  122. package/Server/Services/WorkflowOwnerRuleEngineService.ts +18 -10
  123. package/Server/Static/Brand/README.md +7 -7
  124. package/Server/Static/Vendor/README.md +7 -7
  125. package/Server/Types/Database/Permissions/OwnedScopePermission.ts +18 -9
  126. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +82 -0
  127. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +21 -8
  128. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +41 -4
  129. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +1 -1
  130. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +1 -1
  131. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +13 -5
  132. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +53 -13
  133. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +51 -14
  134. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +292 -0
  135. package/Server/Utils/AI/SRE/InvestigationQueue.ts +25 -0
  136. package/Server/Utils/AI/Toolbox/Index.ts +43 -13
  137. package/Server/Utils/AI/Toolbox/ResourceTools.ts +952 -0
  138. package/Server/Utils/AI/Toolbox/RumTools.ts +424 -0
  139. package/Server/Utils/AI/Toolbox/ToolTypes.ts +10 -0
  140. package/Server/Utils/AI/Toolbox/TraceTools.ts +2 -1
  141. package/Server/Utils/Database/PostgresErrorTranslator.ts +14 -0
  142. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +137 -126
  143. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +4 -1
  144. package/Server/Utils/Rules/OwnerRuleAssignment.ts +157 -6
  145. package/Server/Utils/Telemetry/TelemetryEntity.ts +205 -6
  146. package/SslCertificates/GlobalSign.crt +26 -0
  147. package/SslCertificates/Readme.md +3 -0
  148. package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +451 -0
  149. package/Tests/App/Dashboard/AIInsightsChatPanel.test.tsx +881 -0
  150. package/Tests/App/Dashboard/AIInsightsPageContext.test.ts +458 -0
  151. package/Tests/App/Dashboard/AIInsightsResourceCitations.test.ts +124 -0
  152. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +798 -0
  153. package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +7 -0
  154. package/Tests/App/Dashboard/DashboardChartWidgetZoom.test.tsx +104 -0
  155. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +156 -64
  156. package/Tests/App/Dashboard/DiscoveryScanStatusMessage.test.tsx +970 -0
  157. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +406 -12
  158. package/Tests/App/Dashboard/EmbeddedMetricEventScope.test.tsx +358 -0
  159. package/Tests/App/Dashboard/ErrorPatternEventScope.test.tsx +148 -0
  160. package/Tests/App/Dashboard/EventOverlayAdditionalResourceScope.test.ts +255 -0
  161. package/Tests/App/Dashboard/EventOverlayScope.test.ts +845 -0
  162. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +903 -0
  163. package/Tests/App/Dashboard/ExternalStatusPageCriteriaFilter.test.ts +3 -3
  164. package/Tests/App/Dashboard/InvestigationDrawer.test.tsx +21 -0
  165. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +761 -0
  166. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +7 -4
  167. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +15 -7
  168. package/Tests/App/Dashboard/MetricsViewerEventScopeNavigation.test.tsx +264 -0
  169. package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +342 -0
  170. package/Tests/App/Dashboard/MonitorTestForm.test.tsx +612 -0
  171. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +301 -0
  172. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +74 -2
  173. package/Tests/App/Dashboard/TextClampLayoutHarness.ts +224 -0
  174. package/Tests/Models/InventoryItemNaming.test.ts +54 -0
  175. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +161 -0
  176. package/Tests/Server/API/AIInvestigationAPI.test.ts +14 -0
  177. package/Tests/Server/API/AIInvestigationAvailabilityAuthorization.test.ts +260 -0
  178. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +133 -0
  179. package/Tests/Server/API/StatusPageMasterPasswordRateLimit.test.ts +482 -0
  180. package/Tests/Server/EnvironmentConfigOnCallCalendarFeed.test.ts +1 -1
  181. package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +1 -1
  182. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +38 -16
  183. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +106 -31
  184. package/Tests/Server/Infrastructure/ExampleDockerfiles.test.ts +46 -12
  185. package/Tests/Server/Infrastructure/Postgres/MonitorDescriptionMigration.test.ts +422 -0
  186. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +1 -1
  187. package/Tests/Server/Infrastructure/ValkeyDeploymentConfig.test.ts +25 -4
  188. package/Tests/Server/Middleware/IdentityRateLimit.test.ts +72 -0
  189. package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +12 -12
  190. package/Tests/Server/Middleware/PublicDashboardRateLimitStatusPage.test.ts +800 -0
  191. package/Tests/Server/Services/AIInvestigationDecisionPostgres.test.ts +346 -0
  192. package/Tests/Server/Services/AddOwnersIdempotency.test.ts +471 -0
  193. package/Tests/Server/Services/DatabaseServiceAutoOwnerOnCreate.test.ts +250 -0
  194. package/Tests/Server/Services/DatabaseServiceUniqueColumnsTogether.test.ts +622 -0
  195. package/Tests/Server/Services/MonitorDescriptionValidation.test.ts +211 -0
  196. package/Tests/Server/Services/MonitorTemplateDescriptionPropagation.test.ts +269 -0
  197. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +504 -0
  198. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +43 -0
  199. package/Tests/Server/Services/SessionRetention.test.ts +334 -0
  200. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +172 -0
  201. package/Tests/Server/Services/StatusPagePrivateUserReadAccess.test.ts +178 -0
  202. package/Tests/Server/Services/StatusPagePrivateUserReadAccessPostgres.test.ts +311 -0
  203. package/Tests/Server/Services/StatusPagePrivateUserSessionService.test.ts +216 -1
  204. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1 -1
  205. package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1 -1
  206. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +626 -0
  207. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +668 -0
  208. package/Tests/Server/Types/Database/Permissions/SelectRejectionMessageContract.test.ts +1 -0
  209. package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1 -1
  210. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +16 -9
  211. package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +137 -1
  212. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +697 -0
  213. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +105 -0
  214. package/Tests/Server/Utils/AI/RemediationHandoff.test.ts +16 -5
  215. package/Tests/Server/Utils/AI/ResourceTools.test.ts +1304 -0
  216. package/Tests/Server/Utils/AI/RumTools.test.ts +769 -0
  217. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +63 -0
  218. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +11 -9
  219. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +62 -45
  220. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +25 -24
  221. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaHumanMessages.test.ts +513 -0
  222. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +2 -2
  223. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +1 -1
  224. package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +9 -9
  225. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +7 -5
  226. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +2 -2
  227. package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +4 -3
  228. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +2 -2
  229. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +3 -2
  230. package/Tests/Server/Utils/Monitor/MonitorCriteriaHumanMessages.test.ts +529 -0
  231. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +412 -4
  232. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingClickhouseIntegration.test.ts +1 -1
  233. package/Tests/Server/Utils/TailwindBuildCopy.test.ts +14 -2
  234. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +235 -0
  235. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +385 -2
  236. package/Tests/Server/Utils/VendorAssets.test.ts +17 -3
  237. package/Tests/Types/AI/AIChatPageContext.test.ts +0 -0
  238. package/Tests/Types/AI/AIResourceContext.test.ts +312 -0
  239. package/Tests/Types/Database/UniqueColumnsTogether.test.ts +100 -0
  240. package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +4 -4
  241. package/Tests/Types/Monitor/MonitorStepRetryPersistence.test.ts +125 -0
  242. package/Tests/Types/WebsiteRequest.test.ts +44 -0
  243. package/Tests/UI/Components/Forms/MonitorDescriptionForm.test.tsx +410 -0
  244. package/Tests/UI/Components/ModelTable/BaseModelTableReadPermissions.test.tsx +439 -0
  245. package/Tests/UI/Components/NavBarMenuSearch.test.tsx +372 -0
  246. package/Tests/UI/EsbuildConfig.test.ts +1 -1
  247. package/Tests/UI/Monitor/MonitorStepRetrySettings.test.tsx +616 -0
  248. package/Tests/UI/ReactRouterSingletonBuild.test.ts +4 -2
  249. package/Tests/UI/Rum/ReplayEngine.test.ts +179 -0
  250. package/Tests/UI/Rum/ReplayHeader.test.tsx +23 -0
  251. package/Tests/UI/Rum/ReplayScrubber.test.tsx +88 -0
  252. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +83 -0
  253. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +33 -0
  254. package/Tests/Utils/API.test.ts +96 -0
  255. package/Tests/Utils/HTTPResponseBodyReader.test.ts +188 -1
  256. package/Tests/Utils/Metrics/MetricEventScopeUrl.test.ts +101 -0
  257. package/Tests/Utils/Monitor/MonitorTestAvailabilityUtil.test.ts +256 -0
  258. package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +105 -0
  259. package/Types/AI/AIChatPageContext.ts +87 -2
  260. package/Types/AI/AIChatTypes.ts +4 -0
  261. package/Types/AI/AIResourceContext.ts +198 -0
  262. package/Types/AI/InvestigationNotStartedReason.ts +30 -0
  263. package/Types/Database/UniqueColumnsTogether.ts +55 -0
  264. package/Types/Metrics/MetricQueryConfigData.ts +8 -0
  265. package/Types/Rum/WebVitals.ts +71 -0
  266. package/Types/WebsiteRequest.ts +2 -0
  267. package/UI/Components/EditionLabel/EditionLabel.tsx +7 -5
  268. package/UI/Components/KeyboardShortcut/Screenshots/README.md +1 -1
  269. package/UI/Components/ModelTable/BaseModelTable.tsx +8 -0
  270. package/UI/Components/Navbar/NavBar.tsx +2 -0
  271. package/UI/Components/Navbar/NavBarMenuModal.tsx +6 -2
  272. package/UI/esbuild-config.js +4 -4
  273. package/Utils/API.ts +10 -1
  274. package/Utils/Dashboard/HtmlWidgetDocument.ts +1 -1
  275. package/Utils/HTTPResponseBodyReader.ts +64 -8
  276. package/Utils/Metrics/MetricExplorerUrl.ts +19 -0
  277. package/Utils/Monitor/MonitorTestAvailabilityUtil.ts +92 -0
  278. package/Utils/Telemetry/HostIpAddresses.ts +46 -2
  279. package/build/dist/Models/DatabaseModels/AIAgentOwnerTeam.js +4 -1
  280. package/build/dist/Models/DatabaseModels/AIAgentOwnerTeam.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/AIAgentOwnerUser.js +4 -1
  282. package/build/dist/Models/DatabaseModels/AIAgentOwnerUser.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/Alert.js +12 -0
  284. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js +3 -1
  286. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js +3 -1
  288. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js +3 -1
  290. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js +3 -1
  292. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/CephClusterOwnerTeam.js +4 -1
  294. package/build/dist/Models/DatabaseModels/CephClusterOwnerTeam.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/CephClusterOwnerUser.js +4 -1
  296. package/build/dist/Models/DatabaseModels/CephClusterOwnerUser.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/CloudResourceOwnerTeam.js +4 -1
  298. package/build/dist/Models/DatabaseModels/CloudResourceOwnerTeam.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/CloudResourceOwnerUser.js +4 -1
  300. package/build/dist/Models/DatabaseModels/CloudResourceOwnerUser.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/DashboardOwnerTeam.js +3 -1
  302. package/build/dist/Models/DatabaseModels/DashboardOwnerTeam.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/DashboardOwnerUser.js +3 -1
  304. package/build/dist/Models/DatabaseModels/DashboardOwnerUser.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +3 -0
  306. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  307. package/build/dist/Models/DatabaseModels/DockerHostOwnerTeam.js +4 -1
  308. package/build/dist/Models/DatabaseModels/DockerHostOwnerTeam.js.map +1 -1
  309. package/build/dist/Models/DatabaseModels/DockerHostOwnerUser.js +4 -1
  310. package/build/dist/Models/DatabaseModels/DockerHostOwnerUser.js.map +1 -1
  311. package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerTeam.js +4 -1
  312. package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerTeam.js.map +1 -1
  313. package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerUser.js +4 -1
  314. package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerUser.js.map +1 -1
  315. package/build/dist/Models/DatabaseModels/HostOwnerTeam.js +4 -1
  316. package/build/dist/Models/DatabaseModels/HostOwnerTeam.js.map +1 -1
  317. package/build/dist/Models/DatabaseModels/HostOwnerUser.js +4 -1
  318. package/build/dist/Models/DatabaseModels/HostOwnerUser.js.map +1 -1
  319. package/build/dist/Models/DatabaseModels/Incident.js +12 -0
  320. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  321. package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerTeam.js +3 -1
  322. package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerTeam.js.map +1 -1
  323. package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerUser.js +3 -1
  324. package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerUser.js.map +1 -1
  325. package/build/dist/Models/DatabaseModels/IncidentOwnerTeam.js +3 -1
  326. package/build/dist/Models/DatabaseModels/IncidentOwnerTeam.js.map +1 -1
  327. package/build/dist/Models/DatabaseModels/IncidentOwnerUser.js +3 -1
  328. package/build/dist/Models/DatabaseModels/IncidentOwnerUser.js.map +1 -1
  329. package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerTeam.js +4 -1
  330. package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerTeam.js.map +1 -1
  331. package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerUser.js +4 -1
  332. package/build/dist/Models/DatabaseModels/IncidentTemplateOwnerUser.js.map +1 -1
  333. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerTeam.js +3 -1
  334. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerTeam.js.map +1 -1
  335. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerUser.js +3 -1
  336. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerUser.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/IoTFleetOwnerTeam.js +4 -1
  338. package/build/dist/Models/DatabaseModels/IoTFleetOwnerTeam.js.map +1 -1
  339. package/build/dist/Models/DatabaseModels/IoTFleetOwnerUser.js +4 -1
  340. package/build/dist/Models/DatabaseModels/IoTFleetOwnerUser.js.map +1 -1
  341. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerTeam.js +4 -1
  342. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerTeam.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerUser.js +4 -1
  344. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerUser.js.map +1 -1
  345. package/build/dist/Models/DatabaseModels/Monitor.js +2 -3
  346. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  347. package/build/dist/Models/DatabaseModels/MonitorGroupOwnerTeam.js +4 -1
  348. package/build/dist/Models/DatabaseModels/MonitorGroupOwnerTeam.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/MonitorGroupOwnerUser.js +4 -1
  350. package/build/dist/Models/DatabaseModels/MonitorGroupOwnerUser.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/MonitorOwnerTeam.js +3 -1
  352. package/build/dist/Models/DatabaseModels/MonitorOwnerTeam.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/MonitorOwnerUser.js +3 -1
  354. package/build/dist/Models/DatabaseModels/MonitorOwnerUser.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -3
  356. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerTeam.js +4 -1
  358. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerTeam.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerUser.js +4 -1
  360. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerUser.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.js +3 -1
  362. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerTeam.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.js +3 -1
  364. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerUser.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerTeam.js +3 -1
  366. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerTeam.js.map +1 -1
  367. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerUser.js +3 -1
  368. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerUser.js.map +1 -1
  369. package/build/dist/Models/DatabaseModels/PodmanHostOwnerTeam.js +4 -1
  370. package/build/dist/Models/DatabaseModels/PodmanHostOwnerTeam.js.map +1 -1
  371. package/build/dist/Models/DatabaseModels/PodmanHostOwnerUser.js +4 -1
  372. package/build/dist/Models/DatabaseModels/PodmanHostOwnerUser.js.map +1 -1
  373. package/build/dist/Models/DatabaseModels/ProbeOwnerTeam.js +4 -1
  374. package/build/dist/Models/DatabaseModels/ProbeOwnerTeam.js.map +1 -1
  375. package/build/dist/Models/DatabaseModels/ProbeOwnerUser.js +4 -1
  376. package/build/dist/Models/DatabaseModels/ProbeOwnerUser.js.map +1 -1
  377. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerTeam.js +4 -1
  378. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerTeam.js.map +1 -1
  379. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerUser.js +4 -1
  380. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerUser.js.map +1 -1
  381. package/build/dist/Models/DatabaseModels/RumApplicationOwnerTeam.js +4 -1
  382. package/build/dist/Models/DatabaseModels/RumApplicationOwnerTeam.js.map +1 -1
  383. package/build/dist/Models/DatabaseModels/RumApplicationOwnerUser.js +4 -1
  384. package/build/dist/Models/DatabaseModels/RumApplicationOwnerUser.js.map +1 -1
  385. package/build/dist/Models/DatabaseModels/RunbookOwnerTeam.js +3 -1
  386. package/build/dist/Models/DatabaseModels/RunbookOwnerTeam.js.map +1 -1
  387. package/build/dist/Models/DatabaseModels/RunbookOwnerUser.js +3 -1
  388. package/build/dist/Models/DatabaseModels/RunbookOwnerUser.js.map +1 -1
  389. package/build/dist/Models/DatabaseModels/RunnerOwnerTeam.js +3 -1
  390. package/build/dist/Models/DatabaseModels/RunnerOwnerTeam.js.map +1 -1
  391. package/build/dist/Models/DatabaseModels/RunnerOwnerUser.js +3 -1
  392. package/build/dist/Models/DatabaseModels/RunnerOwnerUser.js.map +1 -1
  393. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam.js +3 -1
  394. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam.js.map +1 -1
  395. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerUser.js +3 -1
  396. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerUser.js.map +1 -1
  397. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerTeam.js +6 -1
  398. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerTeam.js.map +1 -1
  399. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +6 -1
  400. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js.map +1 -1
  401. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerTeam.js +4 -1
  402. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerTeam.js.map +1 -1
  403. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerUser.js +4 -1
  404. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerUser.js.map +1 -1
  405. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +3 -1
  406. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -1
  407. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +3 -1
  408. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -1
  409. package/build/dist/Models/DatabaseModels/ServiceOwnerTeam.js +4 -1
  410. package/build/dist/Models/DatabaseModels/ServiceOwnerTeam.js.map +1 -1
  411. package/build/dist/Models/DatabaseModels/ServiceOwnerUser.js +4 -1
  412. package/build/dist/Models/DatabaseModels/ServiceOwnerUser.js.map +1 -1
  413. package/build/dist/Models/DatabaseModels/StatusPageOwnerTeam.js +3 -1
  414. package/build/dist/Models/DatabaseModels/StatusPageOwnerTeam.js.map +1 -1
  415. package/build/dist/Models/DatabaseModels/StatusPageOwnerUser.js +3 -1
  416. package/build/dist/Models/DatabaseModels/StatusPageOwnerUser.js.map +1 -1
  417. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js +4 -1
  418. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js.map +1 -1
  419. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js +4 -1
  420. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/WorkflowOwnerTeam.js +3 -1
  422. package/build/dist/Models/DatabaseModels/WorkflowOwnerTeam.js.map +1 -1
  423. package/build/dist/Models/DatabaseModels/WorkflowOwnerUser.js +3 -1
  424. package/build/dist/Models/DatabaseModels/WorkflowOwnerUser.js.map +1 -1
  425. package/build/dist/Server/API/AIAgentDataAPI.js +1 -1
  426. package/build/dist/Server/API/AIChatAPI.js +3 -1
  427. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  428. package/build/dist/Server/API/AIInvestigationAPI.js +3 -0
  429. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  430. package/build/dist/Server/API/StatusPageAPI.js +9 -1
  431. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  432. package/build/dist/Server/Infrastructure/Postgres/LocalMigrationGenerationDataSource.js +1 -1
  433. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793500000000-MakeOwnerRowsUnique.js +602 -0
  434. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793500000000-MakeOwnerRowsUnique.js.map +1 -0
  435. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793700000000-AddAIInvestigationDecision.js +14 -0
  436. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793700000000-AddAIInvestigationDecision.js.map +1 -0
  437. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793800000000-RemoveMonitorDescriptionLengthLimit.js +20 -0
  438. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793800000000-RemoveMonitorDescriptionLengthLimit.js.map +1 -0
  439. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  440. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  441. package/build/dist/Server/Middleware/IdentityRateLimit.js +22 -1
  442. package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
  443. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +117 -36
  444. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -1
  445. package/build/dist/Server/Services/AlertEpisodeService.js +13 -31
  446. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  447. package/build/dist/Server/Services/AlertGroupingEngineService.js +7 -4
  448. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
  449. package/build/dist/Server/Services/AlertService.js +13 -31
  450. package/build/dist/Server/Services/AlertService.js.map +1 -1
  451. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +12 -8
  452. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  453. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +12 -8
  454. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  455. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +12 -8
  456. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  457. package/build/dist/Server/Services/DatabaseService.js +71 -1
  458. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  459. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +12 -8
  460. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  461. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +12 -8
  462. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  463. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +12 -8
  464. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  465. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +6 -4
  466. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  467. package/build/dist/Server/Services/IncidentEpisodeService.js +15 -68
  468. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  469. package/build/dist/Server/Services/IncidentGroupingEngineService.js +7 -4
  470. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  471. package/build/dist/Server/Services/IncidentService.js +13 -31
  472. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  473. package/build/dist/Server/Services/IncidentTemplateService.js +13 -31
  474. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  475. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +12 -8
  476. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  477. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +12 -8
  478. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  479. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +12 -8
  480. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  481. package/build/dist/Server/Services/MonitorService.js +13 -31
  482. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  483. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +12 -8
  484. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  485. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +12 -8
  486. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  487. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +12 -8
  488. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  489. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +12 -8
  490. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  491. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +12 -8
  492. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  493. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +12 -8
  494. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  495. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +12 -8
  496. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  497. package/build/dist/Server/Services/ScheduledMaintenanceService.js +13 -31
  498. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  499. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +12 -29
  500. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  501. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +12 -8
  502. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  503. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +12 -8
  504. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  505. package/build/dist/Server/Services/StatusPagePrivateUserService.js +33 -25
  506. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  507. package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js +36 -1
  508. package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js.map +1 -1
  509. package/build/dist/Server/Services/StatusPageService.js +50 -35
  510. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  511. package/build/dist/Server/Services/UserSessionService.js +5 -0
  512. package/build/dist/Server/Services/UserSessionService.js.map +1 -1
  513. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +12 -8
  514. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
  515. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +12 -8
  516. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  517. package/build/dist/Server/Types/Database/Permissions/OwnedScopePermission.js +15 -10
  518. package/build/dist/Server/Types/Database/Permissions/OwnedScopePermission.js.map +1 -1
  519. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +82 -0
  520. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  521. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +12 -3
  522. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  523. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +32 -4
  524. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  525. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +1 -1
  526. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +1 -1
  527. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +8 -5
  528. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  529. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +33 -13
  530. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  531. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +31 -10
  532. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  533. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +205 -0
  534. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -0
  535. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +13 -0
  536. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  537. package/build/dist/Server/Utils/AI/Toolbox/Index.js +30 -6
  538. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  539. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +721 -0
  540. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -0
  541. package/build/dist/Server/Utils/AI/Toolbox/RumTools.js +330 -0
  542. package/build/dist/Server/Utils/AI/Toolbox/RumTools.js.map +1 -0
  543. package/build/dist/Server/Utils/AI/Toolbox/ToolTypes.js.map +1 -1
  544. package/build/dist/Server/Utils/AI/Toolbox/TraceTools.js +1 -1
  545. package/build/dist/Server/Utils/AI/Toolbox/TraceTools.js.map +1 -1
  546. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +11 -0
  547. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
  548. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +106 -101
  549. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  550. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +4 -2
  551. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  552. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +94 -0
  553. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
  554. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +171 -6
  555. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  556. package/build/dist/Types/AI/AIChatPageContext.js +68 -2
  557. package/build/dist/Types/AI/AIChatPageContext.js.map +1 -1
  558. package/build/dist/Types/AI/AIChatTypes.js +4 -0
  559. package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
  560. package/build/dist/Types/AI/AIResourceContext.js +162 -0
  561. package/build/dist/Types/AI/AIResourceContext.js.map +1 -0
  562. package/build/dist/Types/AI/InvestigationNotStartedReason.js +2 -0
  563. package/build/dist/Types/AI/InvestigationNotStartedReason.js.map +1 -0
  564. package/build/dist/Types/Database/UniqueColumnsTogether.js +19 -0
  565. package/build/dist/Types/Database/UniqueColumnsTogether.js.map +1 -0
  566. package/build/dist/Types/Metrics/MetricQueryConfigData.js.map +1 -1
  567. package/build/dist/Types/Rum/WebVitals.js +64 -0
  568. package/build/dist/Types/Rum/WebVitals.js.map +1 -0
  569. package/build/dist/Types/WebsiteRequest.js +2 -0
  570. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  571. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +7 -5
  572. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  573. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +7 -0
  574. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  575. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  576. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +4 -2
  577. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  578. package/build/dist/Utils/API.js +8 -4
  579. package/build/dist/Utils/API.js.map +1 -1
  580. package/build/dist/Utils/HTTPResponseBodyReader.js +50 -6
  581. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -1
  582. package/build/dist/Utils/Metrics/MetricExplorerUrl.js +14 -3
  583. package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -1
  584. package/build/dist/Utils/Monitor/MonitorTestAvailabilityUtil.js +68 -0
  585. package/build/dist/Utils/Monitor/MonitorTestAvailabilityUtil.js.map +1 -0
  586. package/build/dist/Utils/Telemetry/HostIpAddresses.js +42 -3
  587. package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -1
  588. package/package.json +5 -5
  589. package/test-setup.sh +2 -2
@@ -0,0 +1,422 @@
1
+ import { RemoveMonitorDescriptionLengthLimit1793800000000 } from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/1793800000000-RemoveMonitorDescriptionLengthLimit";
2
+ import SchemaMigrations from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/Index";
3
+ import ObjectID from "../../../../Types/ObjectID";
4
+ import {
5
+ afterAll,
6
+ afterEach,
7
+ beforeAll,
8
+ beforeEach,
9
+ describe,
10
+ expect,
11
+ test,
12
+ } from "@jest/globals";
13
+ import { DataSource, MigrationInterface, QueryRunner } from "typeorm";
14
+
15
+ interface DescriptionColumn {
16
+ table: string;
17
+ column: string;
18
+ }
19
+
20
+ interface StoredDescription {
21
+ _id: number;
22
+ description: string | null;
23
+ }
24
+
25
+ const DESCRIPTION_COLUMNS: ReadonlyArray<DescriptionColumn> = [
26
+ { table: "Monitor", column: "description" },
27
+ { table: "MonitorTemplate", column: "monitorDescription" },
28
+ ];
29
+
30
+ async function queriesFor(direction: "up" | "down"): Promise<Array<string>> {
31
+ const statements: Array<string> = [];
32
+ const runner: QueryRunner = {
33
+ query: async (statement: string): Promise<void> => {
34
+ statements.push(statement);
35
+ },
36
+ } as unknown as QueryRunner;
37
+
38
+ await new RemoveMonitorDescriptionLengthLimit1793800000000()[direction](
39
+ runner,
40
+ );
41
+ return statements;
42
+ }
43
+
44
+ describe("monitor description migration", () => {
45
+ test.each(["up", "down"] as const)(
46
+ "%s changes types in place without deleting or truncating descriptions",
47
+ async (direction: "up" | "down") => {
48
+ const statements: Array<string> = await queriesFor(direction);
49
+ const type: string =
50
+ direction === "up" ? "text" : "character varying(500)";
51
+
52
+ /*
53
+ * TypeORM generates DROP/ADD for this type change unless corrected.
54
+ * The exact ALTER contract also excludes a truncating rollback cast.
55
+ */
56
+ expect(statements).toHaveLength(DESCRIPTION_COLUMNS.length);
57
+ for (const { table, column } of DESCRIPTION_COLUMNS) {
58
+ expect(statements).toContain(
59
+ `ALTER TABLE "${table}" ALTER COLUMN "${column}" TYPE ${type}`,
60
+ );
61
+ }
62
+ expect(statements.join("\n")).not.toMatch(/DROP COLUMN|TRUNCATE|USING/i);
63
+ },
64
+ );
65
+
66
+ test("is registered exactly once so existing databases receive the change", () => {
67
+ expect(
68
+ SchemaMigrations.filter(
69
+ (migration: new () => MigrationInterface): boolean => {
70
+ return migration === RemoveMonitorDescriptionLengthLimit1793800000000;
71
+ },
72
+ ),
73
+ ).toHaveLength(1);
74
+ });
75
+ });
76
+
77
+ /*
78
+ * Opt in with RUN_POSTGRES_MONITOR_DESCRIPTION_MIGRATION_TESTS=true and the
79
+ * normal database credentials. Every test uses a transaction inside a unique
80
+ * schema, and the connection's search_path excludes public to protect app data.
81
+ */
82
+ const describePostgres: typeof describe.skip =
83
+ process.env["RUN_POSTGRES_MONITOR_DESCRIPTION_MIGRATION_TESTS"] === "true"
84
+ ? describe
85
+ : describe.skip;
86
+
87
+ function descriptionDatabase(schema: string): DataSource {
88
+ return new DataSource({
89
+ type: "postgres",
90
+ host:
91
+ process.env["MONITOR_DESCRIPTION_MIGRATION_TEST_DATABASE_HOST"] ||
92
+ "localhost",
93
+ port: Number(
94
+ process.env["MONITOR_DESCRIPTION_MIGRATION_TEST_DATABASE_PORT"] || "5400",
95
+ ),
96
+ username: process.env["DATABASE_USERNAME"] || "postgres",
97
+ password: process.env["DATABASE_PASSWORD"] || "password",
98
+ database: process.env["DATABASE_NAME"] || "oneuptimedb",
99
+ entities: [],
100
+ migrations: [RemoveMonitorDescriptionLengthLimit1793800000000],
101
+ schema,
102
+ synchronize: false,
103
+ extra: { options: `-c search_path=${schema}` },
104
+ });
105
+ }
106
+
107
+ describePostgres("monitor descriptions against Postgres", () => {
108
+ const schema: string = `monitor_description_${ObjectID.generate().toString().replace(/-/g, "")}`;
109
+ const migration: RemoveMonitorDescriptionLengthLimit1793800000000 =
110
+ new RemoveMonitorDescriptionLengthLimit1793800000000();
111
+ const existingDescriptions: ReadonlyArray<string | null> = [
112
+ null,
113
+ "",
114
+ "Monitor for pod CPU saturation",
115
+ "監視 café 🚀".repeat(20),
116
+ "x".repeat(500),
117
+ ];
118
+ let database: DataSource;
119
+ let runner: QueryRunner;
120
+
121
+ async function rows(
122
+ column: DescriptionColumn,
123
+ ): Promise<Array<StoredDescription>> {
124
+ return runner.query(
125
+ `SELECT "_id", "${column.column}" AS description FROM "${column.table}" ORDER BY "_id"`,
126
+ );
127
+ }
128
+
129
+ beforeAll(async () => {
130
+ database = descriptionDatabase(schema);
131
+ await database.initialize();
132
+ await database.query(`CREATE SCHEMA "${schema}"`);
133
+ runner = database.createQueryRunner();
134
+ await runner.connect();
135
+ const currentSchema: Array<{ current_schema: string }> = await runner.query(
136
+ "SELECT current_schema()",
137
+ );
138
+ expect(currentSchema[0]?.current_schema).toBe(schema);
139
+ });
140
+
141
+ beforeEach(async () => {
142
+ await runner.startTransaction();
143
+ for (const { table, column } of DESCRIPTION_COLUMNS) {
144
+ await runner.query(
145
+ `CREATE TABLE "${table}" ("_id" integer PRIMARY KEY, "${column}" character varying(500))`,
146
+ );
147
+ for (const [index, description] of existingDescriptions.entries()) {
148
+ await runner.query(
149
+ `INSERT INTO "${table}" ("_id", "${column}") VALUES ($1, $2)`,
150
+ [index, description],
151
+ );
152
+ }
153
+ }
154
+ });
155
+
156
+ afterEach(async () => {
157
+ if (runner?.isTransactionActive) {
158
+ await runner.rollbackTransaction();
159
+ }
160
+ });
161
+
162
+ afterAll(async () => {
163
+ if (runner) {
164
+ await runner.release();
165
+ }
166
+ if (database?.isInitialized) {
167
+ await database.query(`DROP SCHEMA IF EXISTS "${schema}" CASCADE`);
168
+ await database.destroy();
169
+ }
170
+ });
171
+
172
+ test("preserves existing null, empty, Unicode and 500-character values through migration and rollback", async () => {
173
+ const expected: Array<StoredDescription> = existingDescriptions.map(
174
+ (description: string | null, index: number): StoredDescription => {
175
+ return { _id: index, description };
176
+ },
177
+ );
178
+
179
+ await migration.up(runner);
180
+ for (const column of DESCRIPTION_COLUMNS) {
181
+ expect(await rows(column)).toEqual(expected);
182
+ const types: Array<{
183
+ data_type: string;
184
+ character_maximum_length: number | null;
185
+ }> = await runner.query(
186
+ "SELECT data_type, character_maximum_length FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3",
187
+ [schema, column.table, column.column],
188
+ );
189
+ expect(types).toEqual([
190
+ { data_type: "text", character_maximum_length: null },
191
+ ]);
192
+ }
193
+
194
+ await migration.down(runner);
195
+ for (const column of DESCRIPTION_COLUMNS) {
196
+ expect(await rows(column)).toEqual(expected);
197
+ }
198
+ });
199
+
200
+ test.each(DESCRIPTION_COLUMNS)(
201
+ "stores and updates long descriptions in $table",
202
+ async (column: DescriptionColumn) => {
203
+ await migration.up(runner);
204
+ const descriptions: ReadonlyArray<string> = [
205
+ "a".repeat(501),
206
+ "b".repeat(100_000),
207
+ "## 監視 🚀\nCPU > 90% — café\n".repeat(1_000),
208
+ ];
209
+
210
+ for (const [index, description] of descriptions.entries()) {
211
+ const id: number = 100 + index;
212
+ const inserted: Array<StoredDescription> = await runner.query(
213
+ `INSERT INTO "${column.table}" ("_id", "${column.column}") VALUES ($1, $2) RETURNING "_id", "${column.column}" AS description`,
214
+ [id, description],
215
+ );
216
+ expect(inserted).toEqual([{ _id: id, description }]);
217
+
218
+ const updatedDescription: string = `${description}\nUpdated description`;
219
+ await runner.query(
220
+ `UPDATE "${column.table}" SET "${column.column}" = $1 WHERE "_id" = $2`,
221
+ [updatedDescription, id],
222
+ );
223
+ expect(await rows(column)).toContainEqual({
224
+ _id: id,
225
+ description: updatedDescription,
226
+ });
227
+ }
228
+ },
229
+ );
230
+
231
+ test.each(DESCRIPTION_COLUMNS)(
232
+ "refuses rollback with an oversized $table description instead of discarding it",
233
+ async (column: DescriptionColumn) => {
234
+ await migration.up(runner);
235
+ const description: string = "x".repeat(501);
236
+ await runner.query(
237
+ `INSERT INTO "${column.table}" ("_id", "${column.column}") VALUES ($1, $2)`,
238
+ [100, description],
239
+ );
240
+
241
+ /*
242
+ * Match the transaction TypeORM uses for an actual rollback. The nested
243
+ * savepoint lets us verify the retained data after the expected failure.
244
+ */
245
+ await runner.startTransaction();
246
+ try {
247
+ await expect(migration.down(runner)).rejects.toThrow(
248
+ /value too long for type character varying\(500\)/,
249
+ );
250
+ } finally {
251
+ await runner.rollbackTransaction();
252
+ }
253
+ expect(await rows(column)).toContainEqual({ _id: 100, description });
254
+ },
255
+ );
256
+ });
257
+
258
+ describePostgres("monitor description startup migrations", () => {
259
+ let database: DataSource;
260
+ let schema: string;
261
+ const migrationName: string =
262
+ "RemoveMonitorDescriptionLengthLimit1793800000000";
263
+ const originalDescription: string = "x".repeat(500);
264
+
265
+ async function expectColumnTypes(
266
+ dataType: string,
267
+ maximumLength: number | null,
268
+ ): Promise<void> {
269
+ for (const column of DESCRIPTION_COLUMNS) {
270
+ const result: Array<{
271
+ data_type: string;
272
+ character_maximum_length: number | null;
273
+ }> = await database.query(
274
+ "SELECT data_type, character_maximum_length FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3",
275
+ [schema, column.table, column.column],
276
+ );
277
+ expect(result).toEqual([
278
+ { data_type: dataType, character_maximum_length: maximumLength },
279
+ ]);
280
+ }
281
+ }
282
+
283
+ async function expectStoredDescriptions(description: string): Promise<void> {
284
+ for (const column of DESCRIPTION_COLUMNS) {
285
+ expect(
286
+ await database.query(
287
+ `SELECT "${column.column}" AS description FROM "${column.table}" WHERE "_id" = 1`,
288
+ ),
289
+ ).toEqual([{ description }]);
290
+ }
291
+ }
292
+
293
+ beforeEach(async () => {
294
+ schema = `monitor_description_startup_${ObjectID.generate().toString().replace(/-/g, "")}`;
295
+ database = descriptionDatabase(schema);
296
+ await database.initialize();
297
+ await database.query(`CREATE SCHEMA "${schema}"`);
298
+ expect(await database.query("SELECT current_schema()")).toEqual([
299
+ { current_schema: schema },
300
+ ]);
301
+ for (const column of DESCRIPTION_COLUMNS) {
302
+ await database.query(
303
+ `CREATE TABLE "${column.table}" ("_id" integer PRIMARY KEY, "${column.column}" character varying(500))`,
304
+ );
305
+ await database.query(
306
+ `INSERT INTO "${column.table}" ("_id", "${column.column}") VALUES ($1, $2)`,
307
+ [1, originalDescription],
308
+ );
309
+ }
310
+ });
311
+
312
+ afterEach(async () => {
313
+ if (database?.isInitialized) {
314
+ await database.query(`DROP SCHEMA IF EXISTS "${schema}" CASCADE`);
315
+ await database.destroy();
316
+ }
317
+ });
318
+
319
+ test("runs once through TypeORM and preserves long values on the next startup", async () => {
320
+ expect(await database.runMigrations({ transaction: "all" })).toHaveLength(
321
+ 1,
322
+ );
323
+ await expectColumnTypes("text", null);
324
+ await expectStoredDescriptions(originalDescription);
325
+
326
+ const description: string = "## Runbook 監視 🚀\nCPU > 90%\n".repeat(1_000);
327
+ for (const column of DESCRIPTION_COLUMNS) {
328
+ await database.query(
329
+ `UPDATE "${column.table}" SET "${column.column}" = $1 WHERE "_id" = 1`,
330
+ [description],
331
+ );
332
+ }
333
+
334
+ expect(await database.runMigrations({ transaction: "all" })).toEqual([]);
335
+ expect(await database.query('SELECT "name" FROM "migrations"')).toEqual([
336
+ { name: migrationName },
337
+ ]);
338
+ await expectStoredDescriptions(description);
339
+ });
340
+
341
+ test("can be rolled back and applied again without changing existing descriptions", async () => {
342
+ await database.runMigrations({ transaction: "all" });
343
+ await database.undoLastMigration({ transaction: "all" });
344
+
345
+ await expectColumnTypes("character varying", 500);
346
+ await expectStoredDescriptions(originalDescription);
347
+ expect(await database.query('SELECT "name" FROM "migrations"')).toEqual([]);
348
+
349
+ expect(await database.runMigrations({ transaction: "all" })).toHaveLength(
350
+ 1,
351
+ );
352
+ await expectColumnTypes("text", null);
353
+ await expectStoredDescriptions(originalDescription);
354
+ });
355
+
356
+ test.each(DESCRIPTION_COLUMNS)(
357
+ "failed rollback keeps both columns and migration history intact for an oversized $table description",
358
+ async (column: DescriptionColumn) => {
359
+ await database.runMigrations({ transaction: "all" });
360
+ const description: string = "x".repeat(501);
361
+ await database.query(
362
+ `UPDATE "${column.table}" SET "${column.column}" = $1 WHERE "_id" = 1`,
363
+ [description],
364
+ );
365
+
366
+ await expect(
367
+ database.undoLastMigration({ transaction: "all" }),
368
+ ).rejects.toThrow(/value too long for type character varying\(500\)/);
369
+
370
+ await expectColumnTypes("text", null);
371
+ expect(await database.query('SELECT "name" FROM "migrations"')).toEqual([
372
+ { name: migrationName },
373
+ ]);
374
+ for (const storedColumn of DESCRIPTION_COLUMNS) {
375
+ expect(
376
+ await database.query(
377
+ `SELECT "${storedColumn.column}" AS description FROM "${storedColumn.table}" WHERE "_id" = 1`,
378
+ ),
379
+ ).toEqual([
380
+ {
381
+ description:
382
+ storedColumn.table === column.table
383
+ ? description
384
+ : originalDescription,
385
+ },
386
+ ]);
387
+ }
388
+
389
+ // Correcting the oversized value makes the same rollback safe to retry.
390
+ await database.query(
391
+ `UPDATE "${column.table}" SET "${column.column}" = $1 WHERE "_id" = 1`,
392
+ [originalDescription],
393
+ );
394
+ await database.undoLastMigration({ transaction: "all" });
395
+ await expectColumnTypes("character varying", 500);
396
+ await expectStoredDescriptions(originalDescription);
397
+ },
398
+ );
399
+
400
+ test("rolls back the first column change if migration of the second column fails", async () => {
401
+ await database.query(
402
+ 'ALTER TABLE "Monitor" RENAME COLUMN "description" TO "legacyDescription"',
403
+ );
404
+
405
+ await expect(
406
+ database.runMigrations({ transaction: "all" }),
407
+ ).rejects.toThrow(/column "description".*does not exist/);
408
+
409
+ expect(await database.query('SELECT "name" FROM "migrations"')).toEqual([]);
410
+ await database.query(
411
+ 'ALTER TABLE "Monitor" RENAME COLUMN "legacyDescription" TO "description"',
412
+ );
413
+ await expectColumnTypes("character varying", 500);
414
+ await expectStoredDescriptions(originalDescription);
415
+
416
+ expect(await database.runMigrations({ transaction: "all" })).toHaveLength(
417
+ 1,
418
+ );
419
+ await expectColumnTypes("text", null);
420
+ await expectStoredDescriptions(originalDescription);
421
+ });
422
+ });
@@ -3,7 +3,7 @@ import fs from "fs";
3
3
  import path from "path";
4
4
  import yaml from "js-yaml";
5
5
 
6
- const REPO_ROOT: string = path.resolve(__dirname, "../../../..");
6
+ const REPO_ROOT: string = path.resolve(__dirname, "../../../../..");
7
7
  const COMPOSE_PATH: string = path.join(REPO_ROOT, "docker-compose.base.yml");
8
8
  const EXAMPLE_ENV_PATH: string = path.join(REPO_ROOT, "config.example.env");
9
9
  const HELM_VALUES_PATH: string = path.join(
@@ -22,12 +22,18 @@ import yaml from "js-yaml";
22
22
  * config.env upgrade path by Tests/Ops/MergeEnvTemplateRenames.test.js.
23
23
  */
24
24
 
25
- const REPO_ROOT: string = path.resolve(__dirname, "../../../..");
25
+ const REPO_ROOT: string = path.resolve(__dirname, "../../../../..");
26
26
  const BASE_COMPOSE_PATH: string = path.join(
27
27
  REPO_ROOT,
28
28
  "docker-compose.base.yml",
29
29
  );
30
30
  const EXAMPLE_ENV_PATH: string = path.join(REPO_ROOT, "config.example.env");
31
+ const BILLING_OVERLAY_PATH: string = path.join(
32
+ REPO_ROOT,
33
+ "packages",
34
+ "E2E",
35
+ "docker-compose.billing.yml",
36
+ );
31
37
  const HELM_VALUES_PATH: string = path.join(
32
38
  REPO_ROOT,
33
39
  "HelmChart",
@@ -36,11 +42,10 @@ const HELM_VALUES_PATH: string = path.join(
36
42
  "values.yaml",
37
43
  );
38
44
 
39
- // The three compose files an operator actually invokes; each extends the base.
45
+ // The compose files an operator actually invokes; each extends the base.
40
46
  const OVERLAY_COMPOSE_FILES: Array<string> = [
41
47
  "docker-compose.yml",
42
- "docker-compose.dev.yml",
43
- "docker-compose.billing.yml",
48
+ "Scripts/Dev/docker-compose.dev.yml",
44
49
  ];
45
50
 
46
51
  // Every cache setting, by the suffix the two spellings share.
@@ -61,6 +66,7 @@ interface ComposeService {
61
66
  healthcheck?: { test?: Array<string> };
62
67
  networks?: Record<string, { aliases?: Array<string> } | null>;
63
68
  extends?: { file?: string; service?: string };
69
+ depends_on?: Record<string, { condition?: string }>;
64
70
  }
65
71
 
66
72
  interface ComposeFile {
@@ -224,6 +230,21 @@ describe("valkey cache and queue backend", () => {
224
230
  },
225
231
  );
226
232
 
233
+ /*
234
+ * The SaaS CI stack layers packages/E2E/docker-compose.billing.yml on top of
235
+ * docker-compose.yml, so it takes valkey from there; the container it adds
236
+ * has to wait on that service by its current name.
237
+ */
238
+ test("the billing overlay's home container waits on the valkey service", () => {
239
+ const overlay: ComposeFile = readCompose(BILLING_OVERLAY_PATH);
240
+
241
+ expect(overlay.services["redis"]).toBeUndefined();
242
+ expect(overlay.services["home"]?.depends_on?.["valkey"]?.condition).toBe(
243
+ "service_healthy",
244
+ );
245
+ expect(overlay.services["home"]?.depends_on?.["redis"]).toBeUndefined();
246
+ });
247
+
227
248
  /*
228
249
  * Compose and Helm claim in their comments to run the same engine version.
229
250
  * Nothing enforces that but this: the two drift apart the first time only one
@@ -557,6 +557,18 @@ describe("IdentityRateLimit", () => {
557
557
  });
558
558
  });
559
559
 
560
+ it("ships the documented status page login budget", () => {
561
+ expect(
562
+ IdentityRateLimit.getBucketConfig(
563
+ IdentityRateLimitBucket.StatusPageLogin,
564
+ ),
565
+ ).toEqual({
566
+ windowSeconds: WINDOW_SECONDS,
567
+ perAccountLimit: PER_ACCOUNT_LIMIT,
568
+ perIpLimit: PER_IP_LIMIT,
569
+ });
570
+ });
571
+
560
572
  it("falls back to the login budget for an unknown bucket", () => {
561
573
  expect(
562
574
  IdentityRateLimit.getBucketConfig(
@@ -734,10 +746,70 @@ describe("IdentityRateLimit", () => {
734
746
  await consume({ bucket: IdentityRateLimitBucket.Login });
735
747
  await consume({ bucket: IdentityRateLimitBucket.TwoFactor });
736
748
  await consume({ bucket: IdentityRateLimitBucket.BackupCode });
749
+ await consume({ bucket: IdentityRateLimitBucket.StatusPageLogin });
737
750
 
738
751
  expect(client.keysMatching(":login:")).toHaveLength(2);
739
752
  expect(client.keysMatching(":two-factor:")).toHaveLength(2);
740
753
  expect(client.keysMatching(":backup-code:")).toHaveLength(2);
754
+ expect(client.keysMatching(":status-page-login:")).toHaveLength(2);
755
+ });
756
+
757
+ /*
758
+ * Status page private users and dashboard users are different accounts
759
+ * that can share an email address and an office. Guessing at one login
760
+ * must not refuse the other, in either direction.
761
+ */
762
+ it("does not let dashboard /login attempts refuse a status page login", async () => {
763
+ for (let i: number = 0; i < PER_IP_LIMIT + 1; i++) {
764
+ await consume({ bucket: IdentityRateLimitBucket.Login });
765
+ }
766
+
767
+ expect(
768
+ (await consume({ bucket: IdentityRateLimitBucket.StatusPageLogin }))
769
+ .outcome,
770
+ ).toBe(IdentityRateLimitOutcome.Allowed);
771
+ });
772
+
773
+ it("does not let status page login attempts refuse a dashboard /login", async () => {
774
+ for (let i: number = 0; i < PER_IP_LIMIT + 1; i++) {
775
+ await consume({ bucket: IdentityRateLimitBucket.StatusPageLogin });
776
+ }
777
+
778
+ expect(
779
+ (await consume({ bucket: IdentityRateLimitBucket.Login })).outcome,
780
+ ).toBe(IdentityRateLimitOutcome.Allowed);
781
+ });
782
+
783
+ it("bounds status page password guessing on its own counters", async () => {
784
+ for (let i: number = 0; i < PER_ACCOUNT_LIMIT; i++) {
785
+ expect(
786
+ (await consume({ bucket: IdentityRateLimitBucket.StatusPageLogin }))
787
+ .outcome,
788
+ ).toBe(IdentityRateLimitOutcome.Allowed);
789
+ }
790
+
791
+ const refused: IdentityRateLimitDecision = await consume({
792
+ bucket: IdentityRateLimitBucket.StatusPageLogin,
793
+ });
794
+
795
+ expect(refused.outcome).toBe(IdentityRateLimitOutcome.RateLimited);
796
+ expect(refused.scope).toBe(IdentityRateLimitScope.Account);
797
+
798
+ let ipRefused: IdentityRateLimitDecision | null = null;
799
+
800
+ for (let i: number = 0; i < PER_IP_LIMIT + 1; i++) {
801
+ const decision: IdentityRateLimitDecision = await consume({
802
+ accountKey: `rotating-${i}@example.com`,
803
+ clientIp: "198.51.100.4",
804
+ bucket: IdentityRateLimitBucket.StatusPageLogin,
805
+ });
806
+
807
+ if (decision.outcome === IdentityRateLimitOutcome.RateLimited) {
808
+ ipRefused = decision;
809
+ }
810
+ }
811
+
812
+ expect(ipRefused?.scope).toBe(IdentityRateLimitScope.Ip);
741
813
  });
742
814
  });
743
815
 
@@ -246,7 +246,7 @@ describe("PublicDashboardRateLimit", () => {
246
246
  clientIp?: string;
247
247
  }) => {
248
248
  return PublicDashboardRateLimit.consume({
249
- dashboardKey: data.dashboardKey || "id:dashboard-a",
249
+ resourceKey: data.dashboardKey || "id:dashboard-a",
250
250
  clientIp: data.clientIp || "203.0.113.7",
251
251
  bucket: PublicDashboardRateLimitBucket.Read,
252
252
  });
@@ -811,7 +811,7 @@ describe("PublicDashboardRateLimit", () => {
811
811
  const consumePassword: () => Promise<PublicDashboardRateLimitDecision> =
812
812
  () => {
813
813
  return PublicDashboardRateLimit.consume({
814
- dashboardKey: "id:dashboard-a",
814
+ resourceKey: "id:dashboard-a",
815
815
  clientIp: "203.0.113.7",
816
816
  bucket: PublicDashboardRateLimitBucket.MasterPassword,
817
817
  });
@@ -851,7 +851,7 @@ describe("PublicDashboardRateLimit", () => {
851
851
  for (let i: number = 0; i < MASTER_PASSWORD_PER_IP_LIMIT + 5; i++) {
852
852
  const decision: PublicDashboardRateLimitDecision =
853
853
  await PublicDashboardRateLimit.consume({
854
- dashboardKey: `id:dashboard-${i}`,
854
+ resourceKey: `id:dashboard-${i}`,
855
855
  clientIp: "203.0.113.7",
856
856
  bucket: PublicDashboardRateLimitBucket.MasterPassword,
857
857
  });
@@ -903,7 +903,7 @@ describe("PublicDashboardRateLimit", () => {
903
903
  i++
904
904
  ) {
905
905
  await PublicDashboardRateLimit.consume({
906
- dashboardKey: "id:dashboard-a",
906
+ resourceKey: "id:dashboard-a",
907
907
  clientIp: "203.0.113.7",
908
908
  bucket: PublicDashboardRateLimitBucket.MasterPassword,
909
909
  });
@@ -1441,7 +1441,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1441
1441
  expect(
1442
1442
  (
1443
1443
  await limiter.consume({
1444
- dashboardKey: "id:a",
1444
+ resourceKey: "id:a",
1445
1445
  clientIp: "203.0.113.7",
1446
1446
  bucket: PublicDashboardRateLimitBucket.Read,
1447
1447
  })
@@ -1452,7 +1452,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1452
1452
  expect(
1453
1453
  (
1454
1454
  await limiter.consume({
1455
- dashboardKey: "id:a",
1455
+ resourceKey: "id:a",
1456
1456
  clientIp: "203.0.113.7",
1457
1457
  bucket: PublicDashboardRateLimitBucket.Read,
1458
1458
  })
@@ -1469,7 +1469,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1469
1469
 
1470
1470
  for (let i: number = 0; i < 6; i++) {
1471
1471
  const decision: PublicDashboardRateLimitDecision = await limiter.consume({
1472
- dashboardKey: `id:rotating-${i}`,
1472
+ resourceKey: `id:rotating-${i}`,
1473
1473
  clientIp: "203.0.113.7",
1474
1474
  bucket: PublicDashboardRateLimitBucket.Read,
1475
1475
  });
@@ -1492,7 +1492,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1492
1492
 
1493
1493
  for (let i: number = 0; i < 2; i++) {
1494
1494
  await limiter.consume({
1495
- dashboardKey: "id:a",
1495
+ resourceKey: "id:a",
1496
1496
  clientIp: "203.0.113.7",
1497
1497
  bucket: PublicDashboardRateLimitBucket.MasterPassword,
1498
1498
  });
@@ -1501,7 +1501,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1501
1501
  expect(
1502
1502
  (
1503
1503
  await limiter.consume({
1504
- dashboardKey: "id:a",
1504
+ resourceKey: "id:a",
1505
1505
  clientIp: "203.0.113.7",
1506
1506
  bucket: PublicDashboardRateLimitBucket.MasterPassword,
1507
1507
  })
@@ -1517,7 +1517,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1517
1517
 
1518
1518
  for (let i: number = 0; i < READ_PER_DASHBOARD_LIMIT; i++) {
1519
1519
  await limiter.consume({
1520
- dashboardKey: "id:a",
1520
+ resourceKey: "id:a",
1521
1521
  clientIp: "203.0.113.7",
1522
1522
  bucket: PublicDashboardRateLimitBucket.Read,
1523
1523
  });
@@ -1526,7 +1526,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1526
1526
  expect(
1527
1527
  (
1528
1528
  await limiter.consume({
1529
- dashboardKey: "id:a",
1529
+ resourceKey: "id:a",
1530
1530
  clientIp: "203.0.113.7",
1531
1531
  bucket: PublicDashboardRateLimitBucket.Read,
1532
1532
  })
@@ -1543,7 +1543,7 @@ describe("PublicDashboardRateLimit configuration", () => {
1543
1543
  expect(
1544
1544
  (
1545
1545
  await limiter.consume({
1546
- dashboardKey: "id:a",
1546
+ resourceKey: "id:a",
1547
1547
  clientIp: "203.0.113.7",
1548
1548
  bucket: PublicDashboardRateLimitBucket.Read,
1549
1549
  })