@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
@@ -0,0 +1,667 @@
1
+ import "@testing-library/jest-dom";
2
+ import {
3
+ afterEach,
4
+ beforeEach,
5
+ describe,
6
+ expect,
7
+ jest,
8
+ test,
9
+ } from "@jest/globals";
10
+ import { act, cleanup, render, screen } from "@testing-library/react";
11
+ import React, {
12
+ FunctionComponent,
13
+ ReactElement,
14
+ forwardRef,
15
+ useImperativeHandle,
16
+ } from "react";
17
+
18
+ /*
19
+ * The Dashboard's Enterprise plugin door and the component every enterprise
20
+ * shell renders.
21
+ *
22
+ * A shell (Settings > SSO, the audit log table, ...) stays at its original
23
+ * path in core and renders <EnterprisePluginPage>: the ee plugin when the
24
+ * project may use the feature AND this bundle includes it, the upsell card
25
+ * otherwise. The plugins come from getDashboardPlugins(), which in every
26
+ * Community build - and in this jest config, through its moduleNameMapper -
27
+ * is the empty Community stub.
28
+ *
29
+ * Billing and the edition are pinned in every test: CI's config.env sets
30
+ * BILLING_ENABLED=true.
31
+ */
32
+
33
+ let billingEnabledForTest: boolean = false;
34
+ let enterpriseEditionForTest: boolean = false;
35
+ let currentPlanForTest: string | null = null;
36
+
37
+ const CLOUD_PLAN_ENV: Record<string, string> = {
38
+ SUBSCRIPTION_PLAN_BASIC: "Free,priceMonthlyId1,priceYearlyId1,0,0,1,0",
39
+ SUBSCRIPTION_PLAN_GROWTH: "Growth,priceMonthlyId2,priceYearlyId2,0,0,2,14",
40
+ SUBSCRIPTION_PLAN_SCALE: "Scale,priceMonthlyId3,priceYearlyId3,0,0,3,0",
41
+ SUBSCRIPTION_PLAN_ENTERPRISE:
42
+ "Enterprise,priceMonthlyId4,priceYearlyId4,-1,-1,4,14",
43
+ };
44
+
45
+ jest.mock("../../../UI/Config", () => {
46
+ const actual: Record<string, unknown> = jest.requireActual(
47
+ "../../../UI/Config",
48
+ ) as Record<string, unknown>;
49
+
50
+ const mocked: Record<string, unknown> = { ...actual };
51
+
52
+ Object.defineProperty(mocked, "BILLING_ENABLED", {
53
+ get: (): boolean => {
54
+ return billingEnabledForTest;
55
+ },
56
+ });
57
+
58
+ Object.defineProperty(mocked, "IS_ENTERPRISE_EDITION", {
59
+ get: (): boolean => {
60
+ return enterpriseEditionForTest;
61
+ },
62
+ });
63
+
64
+ mocked["getAllEnvVars"] = (): Record<string, string> => {
65
+ return CLOUD_PLAN_ENV;
66
+ };
67
+
68
+ return mocked;
69
+ });
70
+
71
+ jest.mock("../../../UI/Utils/Project", () => {
72
+ const actual: Record<string, any> = jest.requireActual(
73
+ "../../../UI/Utils/Project",
74
+ ) as Record<string, any>;
75
+
76
+ return {
77
+ __esModule: true,
78
+ ...actual,
79
+ default: {
80
+ ...actual["default"],
81
+ getCurrentPlan: (): string | null => {
82
+ return currentPlanForTest;
83
+ },
84
+ },
85
+ };
86
+ });
87
+
88
+ import EnterprisePluginPage, {
89
+ getUpgradeReason,
90
+ } from "../../../../App/FeatureSet/Dashboard/src/Enterprise/EnterprisePluginPage";
91
+ import { getDashboardPlugins } from "../../../../App/FeatureSet/Dashboard/src/Enterprise/Plugins";
92
+ import {
93
+ DASHBOARD_ENTERPRISE_PLUGIN_KEYS,
94
+ DashboardEnterprisePlugins,
95
+ EnterprisePluginComponent,
96
+ } from "../../../../App/FeatureSet/Dashboard/src/Enterprise/EnterprisePlugins";
97
+ import {
98
+ AUDIT_LOGS_REQUIRED_PLAN,
99
+ IDENTITY_REQUIRED_PLAN,
100
+ } from "../../../../App/FeatureSet/Dashboard/src/Enterprise/EnterpriseEligibility";
101
+ import { EnterpriseUpgradeReason } from "../../../../App/FeatureSet/Dashboard/src/Components/EnterpriseEdition/EnterpriseFeatureUpgrade";
102
+ import AuditLogsEnterpriseUpgrade from "../../../../App/FeatureSet/Dashboard/src/Components/AuditLogs/AuditLogsEnterpriseUpgrade";
103
+ import PageComponentProps from "../../../../App/FeatureSet/Dashboard/src/Pages/PageComponentProps";
104
+ import Route from "../../../Types/API/Route";
105
+ import { PlanType } from "../../../Types/Billing/SubscriptionPlan";
106
+ import IconProp from "../../../Types/Icon/IconProp";
107
+ import ObjectID from "../../../Types/ObjectID";
108
+
109
+ type Deployment = "cloud" | "self-hosted-enterprise" | "self-hosted-community";
110
+
111
+ const pinDeployment: (deployment: Deployment) => void = (
112
+ deployment: Deployment,
113
+ ): void => {
114
+ billingEnabledForTest = deployment === "cloud";
115
+ // The Cloud runs the Enterprise image: its effective edition is true.
116
+ enterpriseEditionForTest = deployment !== "self-hosted-community";
117
+ };
118
+
119
+ const PAGE_PROPS: PageComponentProps = {
120
+ pageRoute: new Route("/dashboard/project-id/settings/sso"),
121
+ currentProject: null,
122
+ hasPaymentMethod: true,
123
+ };
124
+
125
+ const UPSELL: {
126
+ title: string;
127
+ description: string;
128
+ featureName: string;
129
+ benefits: Array<{ icon: IconProp; title: string; subtitle: string }>;
130
+ } = {
131
+ title: "Single Sign On (SSO)",
132
+ description: "Configure SAML SSO for your project.",
133
+ featureName: "SAML Single Sign On",
134
+ benefits: [
135
+ {
136
+ icon: IconProp.Lock,
137
+ title: "Centralized auth",
138
+ subtitle: "Revoke access from one place.",
139
+ },
140
+ ],
141
+ };
142
+
143
+ const FakeSSOPage: FunctionComponent<PageComponentProps> = (
144
+ props: PageComponentProps,
145
+ ): ReactElement => {
146
+ return (
147
+ <div data-testid="fake-sso-plugin">
148
+ {props.pageRoute.toString()}|{String(props.hasPaymentMethod)}
149
+ </div>
150
+ );
151
+ };
152
+
153
+ let lazyLoads: number = 0;
154
+ let releaseLazyPlugin: (() => void) | null = null;
155
+
156
+ /*
157
+ * A React.lazy plugin, the shape ee areas hand over. It counts its loads (an
158
+ * ineligible project must never download the ee chunk) and can be held
159
+ * pending to observe the loading state.
160
+ */
161
+ const makeLazyPlugin: (
162
+ holdUntilReleased: boolean,
163
+ ) => EnterprisePluginComponent<PageComponentProps> = (
164
+ holdUntilReleased: boolean,
165
+ ): EnterprisePluginComponent<PageComponentProps> => {
166
+ return React.lazy(
167
+ async (): Promise<{ default: FunctionComponent<PageComponentProps> }> => {
168
+ lazyLoads += 1;
169
+
170
+ if (holdUntilReleased) {
171
+ await new Promise<void>((resolve: () => void) => {
172
+ releaseLazyPlugin = resolve;
173
+ });
174
+ }
175
+
176
+ return { default: FakeSSOPage };
177
+ },
178
+ );
179
+ };
180
+
181
+ beforeEach(() => {
182
+ billingEnabledForTest = false;
183
+ enterpriseEditionForTest = false;
184
+ currentPlanForTest = null;
185
+ lazyLoads = 0;
186
+ releaseLazyPlugin = null;
187
+ });
188
+
189
+ afterEach(() => {
190
+ cleanup();
191
+ });
192
+
193
+ describe("getUpgradeReason", () => {
194
+ test("an eligible project that still sees the card lacks the Enterprise build, not a plan", () => {
195
+ pinDeployment("cloud");
196
+ expect(getUpgradeReason(true)).toBe(EnterpriseUpgradeReason.Edition);
197
+ });
198
+
199
+ test("an ineligible Cloud project needs a plan", () => {
200
+ pinDeployment("cloud");
201
+ expect(getUpgradeReason(false)).toBe(EnterpriseUpgradeReason.Plan);
202
+ });
203
+
204
+ test("an ineligible self-hosted install needs the Enterprise Edition", () => {
205
+ pinDeployment("self-hosted-community");
206
+ expect(getUpgradeReason(false)).toBe(EnterpriseUpgradeReason.Edition);
207
+ });
208
+ });
209
+
210
+ describe("EnterprisePluginPage", () => {
211
+ test("renders the plugin, with the shell's props, for an eligible Cloud project", () => {
212
+ pinDeployment("cloud");
213
+ currentPlanForTest = PlanType.Scale;
214
+
215
+ render(
216
+ <EnterprisePluginPage
217
+ plugin={FakeSSOPage}
218
+ pluginProps={PAGE_PROPS}
219
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
220
+ upsell={UPSELL}
221
+ />,
222
+ );
223
+
224
+ expect(screen.getByTestId("fake-sso-plugin")).toHaveTextContent(
225
+ "/dashboard/project-id/settings/sso|true",
226
+ );
227
+ expect(screen.queryByText("SAML Single Sign On")).not.toBeInTheDocument();
228
+ });
229
+
230
+ test("shows the plan upsell, and never downloads the plugin, below the tier", () => {
231
+ pinDeployment("cloud");
232
+ currentPlanForTest = PlanType.Growth;
233
+
234
+ render(
235
+ <EnterprisePluginPage
236
+ plugin={makeLazyPlugin(false)}
237
+ pluginProps={PAGE_PROPS}
238
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
239
+ upsell={UPSELL}
240
+ />,
241
+ );
242
+
243
+ expect(screen.getAllByText("Upgrade to Scale")).toHaveLength(2);
244
+ expect(screen.getByText("SAML Single Sign On")).toBeInTheDocument();
245
+ expect(screen.queryByTestId("fake-sso-plugin")).not.toBeInTheDocument();
246
+ expect(lazyLoads).toBe(0);
247
+ });
248
+
249
+ test("uses the page's own tier: Scale is not enough for an Enterprise-tier feature", () => {
250
+ pinDeployment("cloud");
251
+ currentPlanForTest = PlanType.Scale;
252
+
253
+ render(
254
+ <EnterprisePluginPage
255
+ plugin={FakeSSOPage}
256
+ pluginProps={PAGE_PROPS}
257
+ requiredPlan={AUDIT_LOGS_REQUIRED_PLAN}
258
+ upsell={UPSELL}
259
+ />,
260
+ );
261
+
262
+ expect(screen.getAllByText("Upgrade to Enterprise")).toHaveLength(2);
263
+ expect(screen.queryByTestId("fake-sso-plugin")).not.toBeInTheDocument();
264
+ });
265
+
266
+ test("an eligible Cloud project on a Community bundle is pointed at the edition, never told to upgrade", () => {
267
+ pinDeployment("cloud");
268
+ currentPlanForTest = PlanType.Enterprise;
269
+
270
+ render(
271
+ <EnterprisePluginPage
272
+ plugin={undefined}
273
+ pluginProps={PAGE_PROPS}
274
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
275
+ upsell={UPSELL}
276
+ />,
277
+ );
278
+
279
+ expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
280
+ 2,
281
+ );
282
+ expect(screen.queryByText("Upgrade to Scale")).not.toBeInTheDocument();
283
+ });
284
+
285
+ test("self-hosted Enterprise Edition renders the plugin", () => {
286
+ pinDeployment("self-hosted-enterprise");
287
+
288
+ render(
289
+ <EnterprisePluginPage
290
+ plugin={FakeSSOPage}
291
+ pluginProps={PAGE_PROPS}
292
+ requiredPlan={AUDIT_LOGS_REQUIRED_PLAN}
293
+ upsell={UPSELL}
294
+ />,
295
+ );
296
+
297
+ expect(screen.getByTestId("fake-sso-plugin")).toBeInTheDocument();
298
+ });
299
+
300
+ test("self-hosted Community Edition shows the edition upsell, plugin or not", () => {
301
+ pinDeployment("self-hosted-community");
302
+
303
+ render(
304
+ <EnterprisePluginPage
305
+ plugin={FakeSSOPage}
306
+ pluginProps={PAGE_PROPS}
307
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
308
+ upsell={UPSELL}
309
+ />,
310
+ );
311
+
312
+ expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
313
+ 2,
314
+ );
315
+ expect(screen.queryByTestId("fake-sso-plugin")).not.toBeInTheDocument();
316
+ });
317
+
318
+ test("self-hosted Enterprise Edition on a Community bundle shows the edition upsell", () => {
319
+ pinDeployment("self-hosted-enterprise");
320
+
321
+ render(
322
+ <EnterprisePluginPage
323
+ plugin={undefined}
324
+ pluginProps={PAGE_PROPS}
325
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
326
+ upsell={UPSELL}
327
+ />,
328
+ );
329
+
330
+ expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
331
+ 2,
332
+ );
333
+ });
334
+
335
+ test("a lazy plugin shows the in-card loader, then the plugin", async () => {
336
+ pinDeployment("self-hosted-enterprise");
337
+
338
+ render(
339
+ <EnterprisePluginPage
340
+ plugin={makeLazyPlugin(true)}
341
+ pluginProps={PAGE_PROPS}
342
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
343
+ upsell={UPSELL}
344
+ />,
345
+ );
346
+
347
+ expect(await screen.findByTestId("component-loader")).toBeInTheDocument();
348
+ expect(screen.queryByTestId("fake-sso-plugin")).not.toBeInTheDocument();
349
+
350
+ await act(async () => {
351
+ releaseLazyPlugin?.();
352
+ });
353
+
354
+ expect(await screen.findByTestId("fake-sso-plugin")).toBeInTheDocument();
355
+ expect(screen.queryByTestId("component-loader")).not.toBeInTheDocument();
356
+ expect(lazyLoads).toBe(1);
357
+ });
358
+
359
+ test("uses a caller's loading element while the plugin downloads", async () => {
360
+ pinDeployment("self-hosted-enterprise");
361
+
362
+ render(
363
+ <EnterprisePluginPage
364
+ plugin={makeLazyPlugin(true)}
365
+ pluginProps={PAGE_PROPS}
366
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
367
+ upsell={UPSELL}
368
+ loadingElement={<div data-testid="custom-loading" />}
369
+ />,
370
+ );
371
+
372
+ expect(await screen.findByTestId("custom-loading")).toBeInTheDocument();
373
+ expect(screen.queryByTestId("component-loader")).not.toBeInTheDocument();
374
+
375
+ await act(async () => {
376
+ releaseLazyPlugin?.();
377
+ });
378
+
379
+ expect(await screen.findByTestId("fake-sso-plugin")).toBeInTheDocument();
380
+ });
381
+
382
+ test("isEligible overrides the plan and edition check, both ways", () => {
383
+ pinDeployment("cloud");
384
+ currentPlanForTest = PlanType.Free;
385
+
386
+ const { unmount } = render(
387
+ <EnterprisePluginPage
388
+ plugin={FakeSSOPage}
389
+ pluginProps={PAGE_PROPS}
390
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
391
+ upsell={UPSELL}
392
+ isEligible={true}
393
+ />,
394
+ );
395
+ expect(screen.getByTestId("fake-sso-plugin")).toBeInTheDocument();
396
+ unmount();
397
+
398
+ pinDeployment("self-hosted-enterprise");
399
+ render(
400
+ <EnterprisePluginPage
401
+ plugin={FakeSSOPage}
402
+ pluginProps={PAGE_PROPS}
403
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
404
+ upsell={UPSELL}
405
+ isEligible={false}
406
+ />,
407
+ );
408
+ expect(screen.queryByTestId("fake-sso-plugin")).not.toBeInTheDocument();
409
+ expect(screen.getByText("SAML Single Sign On")).toBeInTheDocument();
410
+ });
411
+
412
+ test("renderUpsell replaces the card and is told why it is showing", () => {
413
+ pinDeployment("cloud");
414
+ const reasons: Array<EnterpriseUpgradeReason> = [];
415
+
416
+ const renderAuditUpsell: (
417
+ reason: EnterpriseUpgradeReason,
418
+ ) => ReactElement = (reason: EnterpriseUpgradeReason): ReactElement => {
419
+ reasons.push(reason);
420
+ return (
421
+ <AuditLogsEnterpriseUpgrade
422
+ title="Audit Logs"
423
+ description="Every change made in this project."
424
+ reason={reason}
425
+ />
426
+ );
427
+ };
428
+
429
+ // Below the tier: sell the plan.
430
+ currentPlanForTest = PlanType.Scale;
431
+ const { unmount } = render(
432
+ <EnterprisePluginPage
433
+ plugin={FakeSSOPage}
434
+ pluginProps={PAGE_PROPS}
435
+ requiredPlan={AUDIT_LOGS_REQUIRED_PLAN}
436
+ renderUpsell={renderAuditUpsell}
437
+ />,
438
+ );
439
+ expect(
440
+ screen.getByText(
441
+ "Audit Logs are available on the Enterprise plan. Upgrade to turn on audit logging for this project.",
442
+ ),
443
+ ).toBeInTheDocument();
444
+ unmount();
445
+
446
+ // On the tier, but the bundle has no plugin: the edition, not a plan.
447
+ currentPlanForTest = PlanType.Enterprise;
448
+ render(
449
+ <EnterprisePluginPage
450
+ plugin={undefined}
451
+ pluginProps={PAGE_PROPS}
452
+ requiredPlan={AUDIT_LOGS_REQUIRED_PLAN}
453
+ renderUpsell={renderAuditUpsell}
454
+ />,
455
+ );
456
+ expect(
457
+ screen.getByText(
458
+ "Audit Logs are a OneUptime Enterprise Edition feature. Switch to the Enterprise Edition build to enable audit logging.",
459
+ ),
460
+ ).toBeInTheDocument();
461
+
462
+ expect(reasons).toEqual([
463
+ EnterpriseUpgradeReason.Plan,
464
+ EnterpriseUpgradeReason.Edition,
465
+ ]);
466
+ });
467
+
468
+ test("forwards a ref through to the plugin, lazy or not", async () => {
469
+ pinDeployment("self-hosted-enterprise");
470
+
471
+ /*
472
+ * No contract key takes a ref today (the member compliance status table,
473
+ * the one that did, is imported by ee's Compliance page directly), so the
474
+ * props and handle are this test's own: a future ref-taking plugin must
475
+ * still get the caller's ref.
476
+ */
477
+ interface FakeTableProps {
478
+ teamId: ObjectID;
479
+ }
480
+
481
+ interface FakeTableRef {
482
+ refresh: () => void;
483
+ }
484
+
485
+ /*
486
+ * Spelled out rather than as RefAttributes: since @types/react 18.3
487
+ * RefAttributes also allows legacy string refs, which React.lazy strips -
488
+ * so a lazy forwardRef table would not fit a RefAttributes slot.
489
+ */
490
+ type FakeTablePluginProps = FakeTableProps & {
491
+ ref?: React.Ref<FakeTableRef> | undefined;
492
+ };
493
+
494
+ const refreshes: Array<string> = [];
495
+
496
+ const FakeComplianceTable: React.ForwardRefExoticComponent<
497
+ FakeTableProps & React.RefAttributes<FakeTableRef>
498
+ > = forwardRef<FakeTableRef, FakeTableProps>(
499
+ (props: FakeTableProps, ref: React.Ref<FakeTableRef>): ReactElement => {
500
+ useImperativeHandle(ref, () => {
501
+ return {
502
+ refresh: (): void => {
503
+ refreshes.push(props.teamId.toString());
504
+ },
505
+ };
506
+ });
507
+
508
+ return <div data-testid="fake-compliance-table" />;
509
+ },
510
+ );
511
+ FakeComplianceTable.displayName = "FakeComplianceTable";
512
+
513
+ const teamId: ObjectID = new ObjectID(
514
+ "11111111-1111-4111-8111-111111111111",
515
+ );
516
+
517
+ /*
518
+ * Typed as a contract slot would be: a forwardRef table fits it both
519
+ * eagerly and behind React.lazy (a RefAttributes-typed slot would reject
520
+ * the lazy one under @types/react 18.3, which this package installs).
521
+ */
522
+ const plugins: Array<EnterprisePluginComponent<FakeTablePluginProps>> = [
523
+ FakeComplianceTable,
524
+ React.lazy(async (): Promise<{ default: typeof FakeComplianceTable }> => {
525
+ return { default: FakeComplianceTable };
526
+ }),
527
+ ];
528
+
529
+ for (const plugin of plugins) {
530
+ const tableRef: React.RefObject<FakeTableRef> =
531
+ React.createRef<FakeTableRef>();
532
+
533
+ const { unmount } = render(
534
+ <EnterprisePluginPage<FakeTablePluginProps>
535
+ plugin={plugin}
536
+ pluginProps={{ teamId, ref: tableRef }}
537
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
538
+ upsell={UPSELL}
539
+ />,
540
+ );
541
+
542
+ expect(
543
+ await screen.findByTestId("fake-compliance-table"),
544
+ ).toBeInTheDocument();
545
+
546
+ tableRef.current?.refresh();
547
+ unmount();
548
+ }
549
+
550
+ expect(refreshes).toEqual([teamId.toString(), teamId.toString()]);
551
+ });
552
+ });
553
+
554
+ describe("the Community plugin door (what this jest config resolves)", () => {
555
+ test("getDashboardPlugins() is the empty Community stub", () => {
556
+ const plugins: DashboardEnterprisePlugins = getDashboardPlugins();
557
+
558
+ expect(plugins).toEqual({});
559
+ expect(plugins.buildMarker).toBeUndefined();
560
+
561
+ for (const key of DASHBOARD_ENTERPRISE_PLUGIN_KEYS) {
562
+ expect([key, plugins[key]]).toEqual([key, undefined]);
563
+ }
564
+ });
565
+
566
+ test("returns the same object on every call", () => {
567
+ expect(getDashboardPlugins()).toBe(getDashboardPlugins());
568
+ });
569
+
570
+ test("names every screen a plugin can provide, once", () => {
571
+ expect([...DASHBOARD_ENTERPRISE_PLUGIN_KEYS].sort()).toEqual(
572
+ [
573
+ "AuditLogsTable",
574
+ "SettingsAuditLogsSettings",
575
+ "SettingsOIDC",
576
+ "SettingsSCIM",
577
+ "SettingsSSO",
578
+ "StatusPageOIDC",
579
+ "StatusPageSCIM",
580
+ "StatusPageSSO",
581
+ "TeamCompliance",
582
+ "LicenseManager",
583
+ ].sort(),
584
+ );
585
+ expect(new Set(DASHBOARD_ENTERPRISE_PLUGIN_KEYS).size).toBe(
586
+ DASHBOARD_ENTERPRISE_PLUGIN_KEYS.length,
587
+ );
588
+ // The member status table is only ever rendered by ee's Compliance page.
589
+ expect(DASHBOARD_ENTERPRISE_PLUGIN_KEYS).not.toContain(
590
+ "TeamComplianceStatusTable",
591
+ );
592
+ });
593
+
594
+ test("a shell reading the real door on a Community build shows the upsell even when eligible", () => {
595
+ pinDeployment("cloud");
596
+ currentPlanForTest = PlanType.Enterprise;
597
+
598
+ render(
599
+ <EnterprisePluginPage
600
+ plugin={getDashboardPlugins().SettingsSSO}
601
+ pluginProps={PAGE_PROPS}
602
+ requiredPlan={IDENTITY_REQUIRED_PLAN}
603
+ upsell={UPSELL}
604
+ />,
605
+ );
606
+
607
+ expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
608
+ 2,
609
+ );
610
+ });
611
+ });
612
+
613
+ describe("the plugin door with other plugin modules", () => {
614
+ /*
615
+ * These swap what "@oneuptime/ee-dashboard" resolves to, so they run on a
616
+ * fresh module registry and render nothing afterwards.
617
+ */
618
+ beforeEach(() => {
619
+ jest.resetModules();
620
+ });
621
+
622
+ afterEach(() => {
623
+ jest.dontMock("@oneuptime/ee-dashboard");
624
+ jest.resetModules();
625
+ });
626
+
627
+ test("hands back the Enterprise plugin object as is", async () => {
628
+ const enterprisePlugins: DashboardEnterprisePlugins = {
629
+ buildMarker: "ONEUPTIME_EE_DASHBOARD_PLUGIN_v1",
630
+ SettingsSSO: FakeSSOPage,
631
+ };
632
+
633
+ jest.doMock("@oneuptime/ee-dashboard", () => {
634
+ return { __esModule: true, default: enterprisePlugins };
635
+ });
636
+
637
+ const door: { getDashboardPlugins: () => DashboardEnterprisePlugins } =
638
+ await import(
639
+ "../../../../App/FeatureSet/Dashboard/src/Enterprise/Plugins"
640
+ );
641
+
642
+ expect(door.getDashboardPlugins()).toBe(enterprisePlugins);
643
+ expect(door.getDashboardPlugins().SettingsSSO).toBe(FakeSSOPage);
644
+ });
645
+
646
+ test("fails loudly, naming the rule, when read before the plugin module finished loading", async () => {
647
+ /*
648
+ * What a top-level read sees in the Enterprise bundle's import cycle: the
649
+ * plugin binding is still undefined. A silent {} would quietly turn an
650
+ * Enterprise install into the Community UI.
651
+ */
652
+ jest.doMock("@oneuptime/ee-dashboard", () => {
653
+ return { __esModule: true, default: undefined };
654
+ });
655
+
656
+ const door: { getDashboardPlugins: () => DashboardEnterprisePlugins } =
657
+ await import(
658
+ "../../../../App/FeatureSet/Dashboard/src/Enterprise/Plugins"
659
+ );
660
+
661
+ expect(() => {
662
+ return door.getDashboardPlugins();
663
+ }).toThrow(
664
+ "getDashboardPlugins() ran before the Enterprise plugin module finished loading. Call it inside a render or function body, never at module top level.",
665
+ );
666
+ });
667
+ });