@oneuptime/common 13.0.8 → 14.0.1

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 (514) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +23 -15
  2. package/Models/DatabaseModels/GlobalConfig.ts +24 -0
  3. package/Models/DatabaseModels/Index.ts +4 -0
  4. package/Models/DatabaseModels/Monitor.ts +3 -2
  5. package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
  6. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +2 -0
  7. package/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.ts +522 -0
  8. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +38 -4
  9. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.ts +603 -0
  10. package/Scripts/generate-service-worker.js +65 -4
  11. package/Server/API/BaseAPI.ts +26 -5
  12. package/Server/API/GlobalConfigAPI.ts +228 -462
  13. package/Server/API/ProjectOIDC.ts +25 -16
  14. package/Server/API/ProjectSSO.ts +24 -16
  15. package/Server/API/StatusPageAPI.ts +100 -42
  16. package/Server/API/TeamMemberAPI.ts +10 -1
  17. package/Server/Enterprise/EnterpriseEdition.ts +649 -0
  18. package/Server/Enterprise/EnterpriseFeature.ts +48 -0
  19. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
  20. package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
  21. package/Server/EnvironmentConfig.ts +147 -2
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.ts +248 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.ts +19 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  26. package/Server/Middleware/UserAuthorization.ts +38 -16
  27. package/Server/Services/AuditLogService.ts +84 -1079
  28. package/Server/Services/DatabaseService.ts +10 -0
  29. package/Server/Services/EnterpriseLicenseService.ts +38 -0
  30. package/Server/Services/GlobalConfigService.ts +80 -1
  31. package/Server/Services/Index.ts +4 -0
  32. package/Server/Services/MonitorProbeService.ts +116 -20
  33. package/Server/Services/MonitorService.ts +59 -6
  34. package/Server/Services/MonitorStatusTimelineService.ts +284 -0
  35. package/Server/Services/MonitorTemplateService.ts +26 -0
  36. package/Server/Services/ProjectService.ts +284 -0
  37. package/Server/Services/RumSessionPinService.ts +25 -6
  38. package/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.ts +385 -0
  39. package/Server/Services/ServiceLevelObjectiveLabelRuleService.ts +51 -0
  40. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +92 -16
  41. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +36 -1
  42. package/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.ts +521 -0
  43. package/Server/Services/ServiceLevelObjectiveOwnerRuleService.ts +51 -0
  44. package/Server/Services/ServiceLevelObjectiveService.ts +28 -0
  45. package/Server/Services/StatusPagePrivateUserService.ts +7 -3
  46. package/Server/Services/StatusPageService.ts +78 -1
  47. package/Server/Services/TeamMemberService.ts +11 -0
  48. package/Server/Services/TeamService.ts +10 -0
  49. package/Server/Services/UserService.ts +10 -17
  50. package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
  51. package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
  52. package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
  53. package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
  54. package/Server/Types/Markdown.ts +41 -0
  55. package/Server/Types/Workflow/Components/Telegram/SendMessageToChat.ts +27 -1
  56. package/Server/Utils/AI/Toolbox/SloTools.ts +1 -0
  57. package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
  58. package/Server/Utils/EditionEnforcement.ts +233 -0
  59. package/Server/Utils/FrontendEnvironment.ts +41 -2
  60. package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
  61. package/Server/Utils/Monitor/AffectedResourceList.ts +148 -0
  62. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +1 -1
  63. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
  64. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +1 -1
  65. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +720 -465
  66. package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
  67. package/Server/Utils/Monitor/RootCauseList.ts +139 -0
  68. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +28 -0
  69. package/Server/Utils/Slo/SloRulePatternValidator.ts +42 -0
  70. package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
  71. package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
  72. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
  73. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
  74. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
  75. package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
  76. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
  77. package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
  78. package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
  79. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
  80. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
  81. package/Tests/App/Dashboard/FeedFilterSortIntegration.test.tsx +1632 -0
  82. package/Tests/App/Dashboard/FeedOptionsLocales.test.ts +250 -0
  83. package/Tests/App/Dashboard/FeedOrdering.test.ts +279 -9
  84. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
  85. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +60 -1
  86. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +594 -3
  87. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
  88. package/Tests/App/Dashboard/ProductOrientation.test.tsx +646 -0
  89. package/Tests/App/Dashboard/ResourceFeed.test.tsx +612 -2
  90. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +30 -0
  91. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +1202 -0
  92. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +52 -1
  93. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
  94. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
  95. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
  96. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
  97. package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
  98. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
  99. package/Tests/App/Dashboard/SloFeed.test.tsx +106 -1
  100. package/Tests/App/Dashboard/SloMonitorRuleCriteria.test.tsx +566 -0
  101. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +6 -4
  102. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +186 -0
  103. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +388 -44
  104. package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +613 -0
  105. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
  106. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
  107. package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
  108. package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
  109. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +0 -8
  110. package/Tests/Models/DatabaseModels/SloLabelAndOwnerRuleModels.test.ts +404 -0
  111. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +17 -1
  112. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  113. package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
  114. package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
  115. package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
  116. package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
  117. package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
  118. package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
  119. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
  120. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
  121. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
  122. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
  123. package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
  124. package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
  125. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
  126. package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
  127. package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
  128. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
  129. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
  130. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  131. package/Tests/Server/Infrastructure/Postgres/AddSloLabelAndOwnerRulesMigration.test.ts +407 -0
  132. package/Tests/Server/Infrastructure/Postgres/AddSloMonitorRuleMonitorTypeMigration.test.ts +171 -0
  133. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +88 -4
  134. package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
  135. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
  136. package/Tests/Server/Services/AuditLogService.test.ts +460 -990
  137. package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
  138. package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +104 -0
  139. package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
  140. package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
  141. package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
  142. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
  143. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
  144. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
  145. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
  146. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +48 -1
  147. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -0
  148. package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
  149. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +1170 -0
  150. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleServices.test.ts +172 -0
  151. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +323 -0
  152. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +115 -0
  153. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleTriggers.test.ts +21 -2
  154. package/Tests/Server/Services/ServiceLevelObjectiveMonitorTypePostgres.test.ts +480 -0
  155. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +162 -0
  156. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
  157. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
  158. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +45 -6
  159. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
  160. package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
  161. package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
  162. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +745 -0
  163. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
  164. package/Tests/Server/Types/Markdown.test.ts +183 -1
  165. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +49 -0
  166. package/Tests/Server/Types/Workflow/Components/TelegramSendMessageToChat.test.ts +331 -0
  167. package/Tests/Server/Utils/AI/SloTools.test.ts +10 -0
  168. package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
  169. package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
  170. package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
  171. package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
  172. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
  173. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
  174. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +1 -1
  175. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +1339 -96
  176. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +1101 -0
  177. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +106 -80
  178. package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
  179. package/Tests/Server/Utils/Monitor/RootCauseList.test.ts +252 -0
  180. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +154 -0
  181. package/Tests/Server/Utils/SSRFProtection.test.ts +111 -0
  182. package/Tests/Server/Utils/Slo/SloRulePatternValidator.test.ts +67 -0
  183. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +213 -0
  184. package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
  185. package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
  186. package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
  187. package/Tests/Types/API/Route.test.ts +56 -0
  188. package/Tests/Types/API/URLSchemeLikePath.test.ts +304 -0
  189. package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
  190. package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
  191. package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
  192. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
  193. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
  194. package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
  195. package/Tests/UI/Components/FeedOptions.test.ts +1404 -0
  196. package/Tests/UI/Components/FeedOptionsButton.test.tsx +2603 -0
  197. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
  198. package/Tests/UI/Components/Icon.test.tsx +26 -0
  199. package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
  200. package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
  201. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  202. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
  203. package/Tests/UI/Components/useFeedItemsViewKey.test.tsx +1017 -0
  204. package/Tests/UI/Components/useFeedOptions.test.tsx +1107 -0
  205. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
  206. package/Tests/Utils/HostAddressUtil.test.ts +138 -0
  207. package/Tests/Utils/LabelRuleImportExport.test.ts +102 -0
  208. package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
  209. package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
  210. package/Tests/Utils/Slo/SloDuration.test.ts +115 -24
  211. package/Tests/Utils/Slo/SloHealth.test.ts +93 -10
  212. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +109 -0
  213. package/Tests/Utils/Slo/SloOverviewText.test.ts +64 -0
  214. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
  215. package/Types/API/Hostname.ts +63 -16
  216. package/Types/API/Route.ts +19 -2
  217. package/Types/API/URL.ts +26 -2
  218. package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
  219. package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
  220. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
  221. package/Types/Database/CanonicalModelInstance.ts +102 -0
  222. package/Types/Database/TableColumn.ts +20 -6
  223. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
  224. package/Types/IP/IPv6.ts +6 -1
  225. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +6 -5
  226. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +9 -0
  227. package/Types/Monitor/MonitorStep.ts +6 -1
  228. package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
  229. package/Types/Permission.ts +90 -0
  230. package/Types/Rules/RuleCriteriaFieldRegistry.ts +11 -0
  231. package/Types/Rules/RuleRun.ts +4 -0
  232. package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
  233. package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
  234. package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
  235. package/UI/Components/Feed/FeedOptions.ts +427 -0
  236. package/UI/Components/Feed/FeedOptionsButton.tsx +692 -0
  237. package/UI/Components/Feed/useFeedItems.ts +28 -9
  238. package/UI/Components/Feed/useFeedOptions.ts +225 -0
  239. package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
  240. package/UI/Components/Icon/Icon.tsx +1 -1
  241. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  242. package/UI/Components/ModelList/ModelList.tsx +11 -1
  243. package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
  244. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
  245. package/UI/esbuild-enterprise.js +263 -0
  246. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
  247. package/Utils/HostAddressUtil.ts +94 -0
  248. package/Utils/LabelRuleImportExport.ts +27 -9
  249. package/Utils/Monitor/MetricValueFormatter.ts +2 -2
  250. package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
  251. package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
  252. package/Utils/Rules/MonitorTypeRuleCriteria.ts +31 -0
  253. package/Utils/Slo/SloDuration.ts +22 -6
  254. package/Utils/Slo/SloHealth.ts +8 -7
  255. package/Utils/Slo/SloMonitorRuleCriteria.ts +33 -1
  256. package/Utils/Slo/SloOverviewText.ts +33 -0
  257. package/Utils/Slo/SloProjection.ts +4 -3
  258. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
  259. package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
  260. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  261. package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
  262. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  263. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  264. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  265. package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
  266. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  267. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
  268. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  269. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +2 -0
  270. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -1
  271. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js +530 -0
  272. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js.map +1 -0
  273. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +39 -4
  274. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -1
  275. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js +612 -0
  276. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js.map +1 -0
  277. package/build/dist/Server/API/BaseAPI.js +26 -5
  278. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  279. package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
  280. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  281. package/build/dist/Server/API/ProjectOIDC.js +24 -16
  282. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  283. package/build/dist/Server/API/ProjectSSO.js +24 -16
  284. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  285. package/build/dist/Server/API/StatusPageAPI.js +93 -43
  286. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  287. package/build/dist/Server/API/TeamMemberAPI.js +8 -1
  288. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  289. package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
  290. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
  291. package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
  292. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
  293. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
  294. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
  295. package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
  296. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
  297. package/build/dist/Server/EnvironmentConfig.js +84 -2
  298. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  299. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
  300. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
  301. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js +93 -0
  302. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js.map +1 -0
  303. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js +12 -0
  304. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js.map +1 -0
  305. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  306. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  307. package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
  308. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  309. package/build/dist/Server/Services/AuditLogService.js +71 -740
  310. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  311. package/build/dist/Server/Services/DatabaseService.js +7 -0
  312. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  313. package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
  314. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  315. package/build/dist/Server/Services/GlobalConfigService.js +63 -0
  316. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  317. package/build/dist/Server/Services/Index.js +4 -0
  318. package/build/dist/Server/Services/Index.js.map +1 -1
  319. package/build/dist/Server/Services/MonitorProbeService.js +90 -17
  320. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  321. package/build/dist/Server/Services/MonitorService.js +48 -6
  322. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  323. package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
  324. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  325. package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
  326. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  327. package/build/dist/Server/Services/ProjectService.js +214 -0
  328. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  329. package/build/dist/Server/Services/RumSessionPinService.js +24 -6
  330. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  331. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js +295 -0
  332. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js.map +1 -0
  333. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js +56 -0
  334. package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js.map +1 -0
  335. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +59 -14
  336. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  337. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +22 -1
  338. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -1
  339. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js +400 -0
  340. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js.map +1 -0
  341. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js +56 -0
  342. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js.map +1 -0
  343. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +21 -0
  344. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  345. package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
  346. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  347. package/build/dist/Server/Services/StatusPageService.js +71 -0
  348. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  349. package/build/dist/Server/Services/TeamMemberService.js +10 -0
  350. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  351. package/build/dist/Server/Services/TeamService.js +9 -0
  352. package/build/dist/Server/Services/TeamService.js.map +1 -1
  353. package/build/dist/Server/Services/UserService.js +10 -16
  354. package/build/dist/Server/Services/UserService.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
  356. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
  358. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
  360. package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
  361. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
  362. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  363. package/build/dist/Server/Types/Markdown.js +31 -0
  364. package/build/dist/Server/Types/Markdown.js.map +1 -1
  365. package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js +20 -1
  366. package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +1 -0
  368. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  369. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
  370. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
  371. package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
  372. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
  373. package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
  374. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
  375. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
  376. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
  377. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +67 -0
  378. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
  379. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +1 -1
  380. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  381. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  382. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +1 -1
  383. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +585 -367
  384. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  385. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
  386. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
  387. package/build/dist/Server/Utils/Monitor/RootCauseList.js +101 -0
  388. package/build/dist/Server/Utils/Monitor/RootCauseList.js.map +1 -0
  389. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +28 -0
  390. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  391. package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js +28 -0
  392. package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js.map +1 -0
  393. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
  394. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  395. package/build/dist/Types/API/Hostname.js +59 -11
  396. package/build/dist/Types/API/Hostname.js.map +1 -1
  397. package/build/dist/Types/API/Route.js +18 -2
  398. package/build/dist/Types/API/Route.js.map +1 -1
  399. package/build/dist/Types/API/URL.js +23 -2
  400. package/build/dist/Types/API/URL.js.map +1 -1
  401. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
  402. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
  403. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
  404. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
  405. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
  406. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
  407. package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
  408. package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
  409. package/build/dist/Types/Database/TableColumn.js +19 -6
  410. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  411. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
  412. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
  413. package/build/dist/Types/IP/IPv6.js +6 -1
  414. package/build/dist/Types/IP/IPv6.js.map +1 -1
  415. package/build/dist/Types/Monitor/MonitorStep.js +5 -0
  416. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  417. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
  418. package/build/dist/Types/Permission.js +84 -0
  419. package/build/dist/Types/Permission.js.map +1 -1
  420. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +11 -0
  421. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  422. package/build/dist/Types/Rules/RuleRun.js +4 -0
  423. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  424. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
  425. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
  426. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
  427. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  428. package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
  429. package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
  430. package/build/dist/UI/Components/Feed/FeedOptions.js +235 -0
  431. package/build/dist/UI/Components/Feed/FeedOptions.js.map +1 -0
  432. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +346 -0
  433. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -0
  434. package/build/dist/UI/Components/Feed/useFeedItems.js +17 -7
  435. package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -1
  436. package/build/dist/UI/Components/Feed/useFeedOptions.js +130 -0
  437. package/build/dist/UI/Components/Feed/useFeedOptions.js.map +1 -0
  438. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
  439. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  440. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  441. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  442. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  443. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  444. package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
  445. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  446. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
  447. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  448. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
  449. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  450. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
  451. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  452. package/build/dist/Utils/HostAddressUtil.js +80 -0
  453. package/build/dist/Utils/HostAddressUtil.js.map +1 -0
  454. package/build/dist/Utils/LabelRuleImportExport.js +22 -6
  455. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  456. package/build/dist/Utils/Monitor/MetricValueFormatter.js +2 -2
  457. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
  458. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
  459. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
  460. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
  461. package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js +18 -0
  462. package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js.map +1 -0
  463. package/build/dist/Utils/Slo/SloDuration.js +13 -5
  464. package/build/dist/Utils/Slo/SloDuration.js.map +1 -1
  465. package/build/dist/Utils/Slo/SloHealth.js +8 -7
  466. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  467. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +16 -1
  468. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -1
  469. package/build/dist/Utils/Slo/SloOverviewText.js +16 -0
  470. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -1
  471. package/build/dist/Utils/Slo/SloProjection.js.map +1 -1
  472. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  473. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
  474. package/jest.config.json +3 -1
  475. package/package.json +1 -1
  476. package/test-setup.sh +103 -34
  477. package/tsconfig.json +13 -0
  478. package/Server/API/EnterpriseLicenseAPI.ts +0 -925
  479. package/Server/API/TeamComplianceAPI.ts +0 -158
  480. package/Server/Middleware/SCIMAuthorization.ts +0 -141
  481. package/Server/Services/TeamComplianceService.ts +0 -733
  482. package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
  483. package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
  484. package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
  485. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
  486. package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
  487. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
  488. package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
  489. package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
  490. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
  491. package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
  492. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
  493. package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
  494. package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
  495. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
  496. package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
  497. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
  498. package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
  499. package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
  500. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
  501. package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
  502. package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
  503. package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
  504. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
  505. package/build/dist/Server/Services/TeamComplianceService.js +0 -537
  506. package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
  507. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
  508. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
  509. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
  510. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
  511. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
  512. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
  513. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
  514. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
@@ -1,10 +1,49 @@
1
- import { getFrontendEnvVars } from "../EnvironmentConfig";
1
+ import {
2
+ getFrontendEnvVars,
3
+ isEnterpriseEditionRequested,
4
+ } from "../EnvironmentConfig";
5
+ import EnterpriseEdition from "../Enterprise/EnterpriseEdition";
2
6
  import { ExpressRequest, ExpressResponse } from "./Express";
3
7
  import Response from "./Response";
8
+ import { JSONObject } from "../../Types/JSON";
4
9
 
5
10
  export const FRONTEND_ENVIRONMENT_CACHE_CONTROL: string =
6
11
  "private, no-store, no-cache, must-revalidate";
7
12
 
13
+ /*
14
+ * The edition the frontends are told about is the EFFECTIVE one: whether the
15
+ * enterprise module actually loaded in this process, not what the raw
16
+ * IS_ENTERPRISE_EDITION variable claims. A Community image with a leftover
17
+ * IS_ENTERPRISE_EDITION=true must not show enterprise pages whose server
18
+ * routes do not exist; ENTERPRISE_EDITION_REQUESTED_BUT_NOT_LOADED lets the
19
+ * admin UI explain that mismatch to a master admin instead.
20
+ *
21
+ * "Requested" is EnvironmentConfig's isEnterpriseEditionRequested, the same
22
+ * definition the App's boot guard uses: an explicit ONEUPTIME_EDITION=community
23
+ * withdraws the request, so the Enterprise image (which bakes
24
+ * IS_ENTERPRISE_EDITION=true) run as the Community Edition on purpose is not
25
+ * told to switch images. It is read on every call, like the rest of the
26
+ * environment served here.
27
+ */
28
+ export const getFrontendEnvironmentVariables: () => JSONObject =
29
+ (): JSONObject => {
30
+ const frontendEnv: JSONObject = getFrontendEnvVars();
31
+ const isEnterpriseEditionLoaded: boolean = EnterpriseEdition.isLoaded();
32
+ const isEnterpriseEditionExpected: boolean = isEnterpriseEditionRequested(
33
+ process.env,
34
+ );
35
+
36
+ frontendEnv["IS_ENTERPRISE_EDITION"] = isEnterpriseEditionLoaded
37
+ ? "true"
38
+ : "false";
39
+ frontendEnv["ENTERPRISE_EDITION_REQUESTED_BUT_NOT_LOADED"] =
40
+ isEnterpriseEditionExpected && !isEnterpriseEditionLoaded
41
+ ? "true"
42
+ : "false";
43
+
44
+ return frontendEnv;
45
+ };
46
+
8
47
  /*
9
48
  * The combined App server and the five standalone frontend servers must emit
10
49
  * exactly the same environment payload. Keeping the serializer here prevents
@@ -19,7 +58,7 @@ if(!window.process){
19
58
  if(!window.process.env){
20
59
  window.process.env = {}
21
60
  }
22
- window.process.env = ${JSON.stringify(getFrontendEnvVars())};
61
+ window.process.env = ${JSON.stringify(getFrontendEnvironmentVariables())};
23
62
  `;
24
63
  };
25
64
 
@@ -2,38 +2,14 @@ import Redis, { ClientType } from "../../Infrastructure/Redis";
2
2
  import Dictionary from "../../../Types/Dictionary";
3
3
 
4
4
  /*
5
- * Where the previous counter sample is kept so a later run can turn Redis'
6
- * monotonic counters into "did this happen since we last looked".
5
+ * What a single Redis/Valkey INFO call reports, for the admin health API
6
+ * (packages/App/API/AdminHealth.ts).
7
7
  *
8
- * Redis stores its own history here on purpose: the counters and the sample
9
- * then share a lifetime, so a Redis restart clears both together and cannot
10
- * leave a stale baseline that fabricates an enormous delta. The uptime guard
11
- * below covers the case where the sample somehow outlives a restart anyway.
12
- *
13
- * Under memory pressure with an eviction policy this key can itself be evicted,
14
- * which costs one interval of eviction detection: the next run finds no sample,
15
- * re-seeds it, and reports deltas again from there.
16
- */
17
- const COUNTER_SAMPLE_KEY: string = "oneuptime-instance-health-redis-sample";
18
- const COUNTER_SAMPLE_TTL_IN_SECONDS: number = 60 * 60;
19
-
20
- /*
21
- * The minimum age of the baseline the counter deltas are measured against, so
22
- * every evaluation answers "did this happen in at least the last half hour"
23
- * rather than "did it happen in the last five minutes".
24
- *
25
- * That span is what keeps an edge-triggered signal from flapping. Evictions
26
- * arriving in bursts would otherwise clear on the first quiet tick and fire
27
- * again on the next, emailing every other cycle.
28
- *
29
- * Two samples are kept rather than one because a single rolling baseline is a
30
- * TUMBLING window, not a sliding one: the tick immediately after a roll would
31
- * compare against a five-minute-old sample and a lone quiet tick there would
32
- * resolve the notification, re-notifying on the next burst of the same ongoing
33
- * incident. Measuring against the OLDER of two samples makes the lookback
34
- * always at least this long (and at most twice it).
8
+ * The counter history that turns INFO's cumulative totals into "did this
9
+ * happen recently" belongs to the Enterprise instance-health worker and lives
10
+ * next to it in ee/Server/Workers/InstanceHealth/RedisHealth.ts, which reads
11
+ * INFO through readInfoSnapshot below.
35
12
  */
36
- export const COUNTER_WINDOW_IN_SECONDS: number = 30 * 60;
37
13
 
38
14
  // Everything a single INFO call reports, with no history involved.
39
15
  export interface RedisInfoSnapshot {
@@ -56,36 +32,6 @@ export interface RedisInfoSnapshot {
56
32
  uptimeInSeconds: number;
57
33
  }
58
34
 
59
- export interface RedisHealthSnapshot extends RedisInfoSnapshot {
60
- /*
61
- * Increase over the baseline. null when this run has no baseline it can trust
62
- * — no stored sample, or Redis restarted and reset the counters.
63
- */
64
- evictedKeysDelta: number | null;
65
- rejectedConnectionsDelta: number | null;
66
- /*
67
- * How far back the deltas above actually reach, so messages can state the
68
- * real span instead of quoting a nominal constant. null alongside null deltas.
69
- */
70
- counterWindowInSeconds: number | null;
71
- }
72
-
73
- export interface RedisCounterSample {
74
- evictedKeys: number;
75
- rejectedConnections: number;
76
- uptimeInSeconds: number;
77
- }
78
-
79
- /*
80
- * The two retained samples. Deltas are measured against `older`, which keeps
81
- * the lookback at least COUNTER_WINDOW_IN_SECONDS at every tick; `newer` is the
82
- * one promoted to `older` at the next roll.
83
- */
84
- export interface RedisCounterSamples {
85
- older: RedisCounterSample;
86
- newer: RedisCounterSample;
87
- }
88
-
89
35
  /*
90
36
  * INFO is a flat `field:value` document split into `# Section` blocks. Section
91
37
  * headers and comment lines are dropped; field names are unique across sections
@@ -191,144 +137,11 @@ async function getMaxClients(
191
137
  return null;
192
138
  }
193
139
 
194
- function parseCounterSample(value: unknown): RedisCounterSample | null {
195
- if (!value || typeof value !== "object" || Array.isArray(value)) {
196
- return null;
197
- }
198
-
199
- const sample: Record<string, unknown> = value as Record<string, unknown>;
200
- const evictedKeys: number = Number(sample["evictedKeys"]);
201
- const rejectedConnections: number = Number(sample["rejectedConnections"]);
202
- const uptimeInSeconds: number = Number(sample["uptimeInSeconds"]);
203
-
204
- if (
205
- !Number.isFinite(evictedKeys) ||
206
- !Number.isFinite(rejectedConnections) ||
207
- !Number.isFinite(uptimeInSeconds)
208
- ) {
209
- return null;
210
- }
211
-
212
- return { evictedKeys, rejectedConnections, uptimeInSeconds };
213
- }
214
-
215
- async function readCounterSamples(
216
- client: ClientType,
217
- ): Promise<RedisCounterSamples | null> {
218
- try {
219
- const raw: string | null = await client.get(COUNTER_SAMPLE_KEY);
220
-
221
- if (!raw) {
222
- return null;
223
- }
224
-
225
- const parsed: unknown = JSON.parse(raw);
226
-
227
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
228
- return null;
229
- }
230
-
231
- const stored: Record<string, unknown> = parsed as Record<string, unknown>;
232
- const older: RedisCounterSample | null = parseCounterSample(
233
- stored["older"],
234
- );
235
- const newer: RedisCounterSample | null = parseCounterSample(
236
- stored["newer"],
237
- );
238
-
239
- if (older && newer) {
240
- return { older, newer };
241
- }
242
-
243
- /*
244
- * A single-sample payload is what the previous release wrote. Treat it as
245
- * both ends of the pair so an upgrade keeps its baseline instead of going
246
- * blind for a window.
247
- */
248
- const legacy: RedisCounterSample | null = parseCounterSample(parsed);
249
-
250
- return legacy ? { older: legacy, newer: legacy } : null;
251
- } catch {
252
- // A missing or unreadable sample simply means no delta this run.
253
- return null;
254
- }
255
- }
256
-
257
140
  /*
258
- * Returns whether the baseline was actually stored. The caller needs to know,
259
- * because a write can fail for a reason that does not stop the key from being
260
- * kept alive by other means — see getRedisHealthSnapshot.
141
+ * One INFO read, plus the CONFIG fallback for maxclients. Exported so the
142
+ * Enterprise worker's snapshot reads Redis exactly the way this file does.
261
143
  */
262
- async function writeCounterSamples(
263
- client: ClientType,
264
- samples: RedisCounterSamples,
265
- ): Promise<boolean> {
266
- try {
267
- await client.set(
268
- COUNTER_SAMPLE_KEY,
269
- JSON.stringify(samples),
270
- "EX",
271
- COUNTER_SAMPLE_TTL_IN_SECONDS,
272
- );
273
- return true;
274
- } catch {
275
- /*
276
- * Losing the baseline must never fail the health evaluation that produced
277
- * this snapshot, so the error is swallowed and reported through the return.
278
- */
279
- return false;
280
- }
281
- }
282
-
283
- // Keep a baseline alive across the runs that do not rewrite it.
284
- async function refreshCounterSampleTtl(client: ClientType): Promise<void> {
285
- try {
286
- await client.expire(COUNTER_SAMPLE_KEY, COUNTER_SAMPLE_TTL_IN_SECONDS);
287
- } catch {
288
- // Same reasoning as writeCounterSamples: never fail the evaluation over this.
289
- }
290
- }
291
-
292
- /*
293
- * The pair rolls only once the NEWER sample has aged past the window, which
294
- * promotes it to `older` and starts a fresh one. Deltas are always measured
295
- * against `older`, so the lookback never drops below the window. Redis' own
296
- * uptime measures that age, which avoids trusting either machine's clock.
297
- */
298
- export function shouldRollCounterSamples(data: {
299
- previous: RedisCounterSamples | null;
300
- currentUptimeInSeconds: number;
301
- didRestart: boolean;
302
- }): boolean {
303
- if (!data.previous || data.didRestart) {
304
- return true;
305
- }
306
-
307
- return (
308
- data.currentUptimeInSeconds - data.previous.newer.uptimeInSeconds >=
309
- COUNTER_WINDOW_IN_SECONDS
310
- );
311
- }
312
-
313
- /*
314
- * Compare a monotonic counter against its previous value. A decrease, or a
315
- * shorter uptime than the sample was taken at, means Redis restarted and the
316
- * counter began again from zero — the difference is meaningless, so report no
317
- * delta rather than a fabricated spike.
318
- */
319
- export function getCounterDelta(data: {
320
- current: number;
321
- previous: number;
322
- didRestart: boolean;
323
- }): number | null {
324
- if (data.didRestart || data.current < data.previous) {
325
- return null;
326
- }
327
-
328
- return data.current - data.previous;
329
- }
330
-
331
- async function readInfoSnapshot(
144
+ export async function readInfoSnapshot(
332
145
  client: ClientType,
333
146
  ): Promise<RedisInfoSnapshot> {
334
147
  const info: Dictionary<string> = parseRedisInfo(await client.info());
@@ -341,9 +154,9 @@ async function readInfoSnapshot(
341
154
 
342
155
  /*
343
156
  * Read-only view for the admin health API. It deliberately does NOT touch the
344
- * stored counter sample: advancing that baseline here would consume the delta
345
- * the worker needs, so a page refresh could hide an eviction burst from the
346
- * notification that exists to catch it.
157
+ * counter sample the Enterprise health worker keeps: advancing that baseline
158
+ * here would consume the delta the worker needs, so a page refresh could hide
159
+ * an eviction burst from the notification that exists to catch it.
347
160
  */
348
161
  export async function getRedisInfoSnapshot(): Promise<RedisInfoSnapshot | null> {
349
162
  const client: ClientType | null = Redis.getClient();
@@ -354,81 +167,3 @@ export async function getRedisInfoSnapshot(): Promise<RedisInfoSnapshot | null>
354
167
 
355
168
  return await readInfoSnapshot(client);
356
169
  }
357
-
358
- /*
359
- * The evaluating worker's view: the same INFO read, plus the counter deltas
360
- * that turn cumulative totals into "did this happen in roughly the last
361
- * COUNTER_WINDOW_IN_SECONDS". Returns null when Redis is unreachable, which the
362
- * caller treats as "cannot evaluate" rather than "healthy".
363
- */
364
- export async function getRedisHealthSnapshot(): Promise<RedisHealthSnapshot | null> {
365
- const client: ClientType | null = Redis.getClient();
366
-
367
- if (!client || !Redis.isConnected()) {
368
- return null;
369
- }
370
-
371
- const snapshot: RedisInfoSnapshot = await readInfoSnapshot(client);
372
-
373
- const previousSamples: RedisCounterSamples | null =
374
- await readCounterSamples(client);
375
- const didRestart: boolean = Boolean(
376
- previousSamples &&
377
- previousSamples.older.uptimeInSeconds > snapshot.uptimeInSeconds,
378
- );
379
- // Deltas always measure against the older half, never the freshly rolled one.
380
- const baseline: RedisCounterSample | null = previousSamples
381
- ? previousSamples.older
382
- : null;
383
-
384
- const current: RedisCounterSample = {
385
- evictedKeys: snapshot.evictedKeys,
386
- rejectedConnections: snapshot.rejectedConnections,
387
- uptimeInSeconds: snapshot.uptimeInSeconds,
388
- };
389
- const wantsRoll: boolean = shouldRollCounterSamples({
390
- previous: previousSamples,
391
- currentUptimeInSeconds: snapshot.uptimeInSeconds,
392
- didRestart,
393
- });
394
- const didRoll: boolean = wantsRoll
395
- ? await writeCounterSamples(client, {
396
- older: previousSamples && !didRestart ? previousSamples.newer : current,
397
- newer: current,
398
- })
399
- : false;
400
-
401
- /*
402
- * Keep the existing samples alive whenever they were not rolled — including
403
- * when the roll FAILED, which is the case that matters most. Under the
404
- * noeviction policy Redis rejects SET once it is out of memory but still
405
- * serves EXPIRE, so letting a failed write skip the refresh would expire the
406
- * baseline precisely when memory is full: eviction detection would then go
407
- * permanently blind at the moment it is needed, because every later write
408
- * fails the same way and the key never returns.
409
- */
410
- if (!didRoll) {
411
- await refreshCounterSampleTtl(client);
412
- }
413
-
414
- return {
415
- ...snapshot,
416
- counterWindowInSeconds: baseline
417
- ? snapshot.uptimeInSeconds - baseline.uptimeInSeconds
418
- : null,
419
- evictedKeysDelta: baseline
420
- ? getCounterDelta({
421
- current: snapshot.evictedKeys,
422
- previous: baseline.evictedKeys,
423
- didRestart,
424
- })
425
- : null,
426
- rejectedConnectionsDelta: baseline
427
- ? getCounterDelta({
428
- current: snapshot.rejectedConnections,
429
- previous: baseline.rejectedConnections,
430
- didRestart,
431
- })
432
- : null,
433
- };
434
- }
@@ -0,0 +1,148 @@
1
+ import { escapeMarkdownInline } from "../../../Utils/Markdown/MarkdownEscape";
2
+ import RootCauseList, {
3
+ RootCauseListDetail,
4
+ RootCauseListItem,
5
+ } from "./RootCauseList";
6
+
7
+ /*
8
+ * The "Affected Resources" block of a platform monitor's root cause.
9
+ *
10
+ * Kubernetes, Proxmox, VMware, Docker Swarm and Ceph monitors each attach a
11
+ * per-resource breakdown to the incident / alert they open, and each one
12
+ * used to render it as a GitHub-flavoured table: up to six columns of long,
13
+ * unbreakable identifiers (pod names, node names, pool paths). That table
14
+ * is read in three places, and it read badly in all of them:
15
+ *
16
+ * - the email: the DetailBox card leaves roughly 416px for the root
17
+ * cause, so every cell wrapped mid-identifier and a ten-row table
18
+ * became a wall of fragments,
19
+ * - Slack: mrkdwn has no tables, so the incident feed posted the raw
20
+ * "| … |" pipe rows, and convertMarkdownToSlackRichText unrolled each
21
+ * row into a "_Row 1_" block of "*Header:* value" lines,
22
+ * - the dashboard: the widest column decided the layout, and a single
23
+ * long node name squeezed the rest into two-line cells.
24
+ *
25
+ * So the breakdown is a ranked list instead. Each resource is one numbered
26
+ * item — worst first, the same order the table used — that says what the
27
+ * resource is, names it, and gives its value:
28
+ *
29
+ * 1. **Pod** `checkout-7d9f` — **3**
30
+ * - Namespace: `payments`
31
+ * - Deployment: `checkout`
32
+ * - Node: `gke-prod-pool-1-abcd`
33
+ *
34
+ * and the rest of its identity sits underneath as labelled bullets. A
35
+ * missing attribute is simply left out, where the table had to print "-".
36
+ *
37
+ * The list itself is a RootCauseList, the shape the Breaching Samples block
38
+ * of a metric monitor's root cause uses too.
39
+ */
40
+
41
+ export interface AffectedResourceListDetail {
42
+ // Plain text. Escaped when rendered.
43
+ label: string;
44
+ // Markdown, rendered as-is. An empty value drops the whole detail.
45
+ value: string;
46
+ }
47
+
48
+ export interface AffectedResourceListEntry {
49
+ // Plain text, e.g. "Pod" or "Virtual Machine". Escaped when rendered.
50
+ kind: string;
51
+ // Markdown, normally built with AffectedResourceList.code().
52
+ name: string;
53
+ // Markdown — the formatted metric value.
54
+ value: string;
55
+ details: Array<AffectedResourceListDetail>;
56
+ }
57
+
58
+ export default class AffectedResourceList {
59
+ // How many resources the list shows before it summarises the rest.
60
+ public static readonly MAX_ENTRIES: number = 10;
61
+
62
+ public static render(input: {
63
+ // Plain text, e.g. "Affected Resources".
64
+ heading: string;
65
+ // Plain text, e.g. "affected resources" in "... and 3 more affected resources".
66
+ overflowNoun: string;
67
+ // Every resource that qualified for the list, including those not shown.
68
+ totalCount: number;
69
+ // The resources to show, already sorted worst first.
70
+ entries: Array<AffectedResourceListEntry>;
71
+ }): string {
72
+ const items: Array<RootCauseListItem> = input.entries.map(
73
+ (entry: AffectedResourceListEntry): RootCauseListItem => {
74
+ /*
75
+ * The kind is bold so each item's first line stands out from the
76
+ * detail bullets under it — the value at the end of the line is
77
+ * bold too, so the eye lands on what it is and how bad it is.
78
+ */
79
+ const kind: string = escapeMarkdownInline(entry.kind).trim();
80
+
81
+ return {
82
+ title: [kind ? `**${kind}**` : "", entry.name.trim()]
83
+ .filter((part: string): boolean => {
84
+ return part.length > 0;
85
+ })
86
+ .join(" "),
87
+ value: entry.value,
88
+ details: entry.details.map(
89
+ (detail: AffectedResourceListDetail): RootCauseListDetail => {
90
+ return {
91
+ label: escapeMarkdownInline(detail.label),
92
+ value: detail.value,
93
+ };
94
+ },
95
+ ),
96
+ };
97
+ },
98
+ );
99
+
100
+ const lines: Array<string> = [RootCauseList.render(items)];
101
+
102
+ const hiddenCount: number = input.totalCount - input.entries.length;
103
+
104
+ if (hiddenCount > 0) {
105
+ /*
106
+ * The blank line matters: without it the summary is a lazy
107
+ * continuation of the last item's final bullet, not a paragraph of
108
+ * its own.
109
+ */
110
+ lines.push("");
111
+ lines.push(
112
+ `*... and ${hiddenCount} more ${escapeMarkdownInline(input.overflowNoun)}*`,
113
+ );
114
+ }
115
+
116
+ return `\n\n**${escapeMarkdownInline(input.heading)}** (${input.totalCount} total)\n\n${lines.join("\n")}`;
117
+ }
118
+
119
+ /*
120
+ * A resource identifier as an inline code span. The identifiers come from
121
+ * telemetry attributes, and a VMware VM or a Proxmox guest can be named
122
+ * anything — RootCauseList.code keeps a name with backticks or line breaks
123
+ * inside its span.
124
+ */
125
+ public static code(value: string | undefined | null): string {
126
+ return RootCauseList.code(value);
127
+ }
128
+
129
+ /*
130
+ * A display name alongside the identifier it abbreviates — a Proxmox
131
+ * guest's name and its `qemu/100` id, a Ceph pool's name and number, a
132
+ * vSphere resource pool's name and inventory path. Either half may be
133
+ * missing; when both are the same only one is shown.
134
+ */
135
+ public static codeWithId(input: {
136
+ name?: string | undefined;
137
+ id?: string | undefined;
138
+ }): string {
139
+ const name: string = AffectedResourceList.code(input.name);
140
+ const id: string = AffectedResourceList.code(input.id);
141
+
142
+ if (name && id && name !== id) {
143
+ return `${name} (${id})`;
144
+ }
145
+
146
+ return name || id;
147
+ }
148
+ }
@@ -984,7 +984,7 @@ export default class CompareCriteria {
984
984
  * reads naturally ("is 42, 55, 60"). For larger arrays, summarize
985
985
  * — dumping 30+ numbers on one line makes the root cause unreadable
986
986
  * and the detailed breakdown is shown in the Breaching Samples
987
- * table below.
987
+ * list below.
988
988
  */
989
989
  const MAX_INLINE: number = 5;
990
990
 
@@ -17,6 +17,7 @@ import MetricService from "../../../Services/MetricService";
17
17
  import CaptureSpan from "../../Telemetry/CaptureSpan";
18
18
  import InBetween from "../../../../Types/BaseDatabase/InBetween";
19
19
  import CronTab from "../../CronTab";
20
+ import MonitoringIntervalUtil from "../../../../Utils/Monitor/MonitoringIntervalUtil";
20
21
  import logger from "../../Logger";
21
22
 
22
23
  /**
@@ -488,8 +489,16 @@ export default class EvaluateOverTime {
488
489
  monitoringInterval?: string | undefined;
489
490
  sortedSampleTimes: Array<number>;
490
491
  }): number | null {
492
+ /*
493
+ * Through the normalizer first: a monitor storing "5m" has a perfectly
494
+ * well-defined cadence, and treating it as "cadence unknown" made
495
+ * over-time windows fall back to guessing from the data.
496
+ */
491
497
  const configuredIntervalInSeconds: number | null =
492
- CronTab.getIntervalInSeconds(data.monitoringInterval);
498
+ CronTab.getIntervalInSeconds(
499
+ MonitoringIntervalUtil.toCronOrNull(data.monitoringInterval) ||
500
+ data.monitoringInterval,
501
+ );
493
502
 
494
503
  if (configuredIntervalInSeconds !== null) {
495
504
  return configuredIntervalInSeconds;
@@ -1004,7 +1004,7 @@ export default class MetricMonitorCriteria {
1004
1004
  const sigmaAbs: number = Math.abs(firstBreach.sigma);
1005
1005
 
1006
1006
  /*
1007
- * Same rendering as the breaching-samples table and the comparison
1007
+ * Same rendering as the breaching-samples list and the comparison
1008
1008
  * sentence — an anomaly on a memory metric reads "1.07 GB", not
1009
1009
  * "1073741824.000 By". σ is a count of standard deviations, not a
1010
1010
  * quantity in the metric's unit, so it stays a bare number; the