@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,576 +0,0 @@
1
- import EnterpriseLicenseInstanceSummary from "../../Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary";
2
- import EnterpriseLicenseSeatsUtil, {
3
- SeatUsage,
4
- SeatUsageInput,
5
- } from "../../Utils/EnterpriseLicense/EnterpriseLicenseSeats";
6
- import { describe, expect, it } from "@jest/globals";
7
-
8
- /*
9
- * The arithmetic behind "you cannot add another user".
10
- *
11
- * An enterprise license is bought for a number of users and shared by every
12
- * instance the customer runs on that key. Until now nothing on the customer's
13
- * side acted on that number — the limit was mirrored into GlobalConfig, drawn
14
- * on a progress bar, and otherwise ignored, so a 50-seat license and a 5000-
15
- * seat license behaved identically.
16
- *
17
- * Deciding whether one more user fits is not a comparison, because neither
18
- * number this installation holds is the answer:
19
- *
20
- * localUserCount live, and blind to the customer's other instances.
21
- * aggregatedUserCount deduplicated across every instance, and up to a day
22
- * old — so it does not know about the person being
23
- * invited right now, which is the only person the check
24
- * is about.
25
- *
26
- * These tests pin how those are combined, and — at least as importantly — pin
27
- * which way every "cannot tell" case is allowed to fall. Under-enforcing is
28
- * corrected by the next daily report. Over-enforcing locks a paying customer
29
- * out of their own installation, so no missing, malformed or contradictory
30
- * field is allowed to invent seats that are not there.
31
- */
32
-
33
- type MakeInstanceFunction = (
34
- overrides?: Partial<EnterpriseLicenseInstanceSummary>,
35
- ) => EnterpriseLicenseInstanceSummary;
36
-
37
- const makeInstance: MakeInstanceFunction = (
38
- overrides?: Partial<EnterpriseLicenseInstanceSummary>,
39
- ): EnterpriseLicenseInstanceSummary => {
40
- return {
41
- instanceId: "instance-1",
42
- host: "oneuptime.acme.internal",
43
- userCount: 10,
44
- isCountedTowardsUsage: true,
45
- lastReportedAt: "2026-01-01T00:00:00.000Z",
46
- version: "12.0.30",
47
- ...overrides,
48
- };
49
- };
50
-
51
- type SeatsFunction = (input: Partial<SeatUsageInput>) => SeatUsage;
52
-
53
- const seats: SeatsFunction = (input: Partial<SeatUsageInput>): SeatUsage => {
54
- return EnterpriseLicenseSeatsUtil.getSeatUsage({
55
- localUserCount: 0,
56
- ...input,
57
- } as SeatUsageInput);
58
- };
59
-
60
- describe("EnterpriseLicenseSeatsUtil - is there a limit at all", () => {
61
- it("does not enforce when the license carries no seat limit", () => {
62
- const usage: SeatUsage = seats({ userLimit: null, localUserCount: 9999 });
63
-
64
- expect(usage.isEnforced).toBe(false);
65
- expect(usage.userLimit).toBeNull();
66
- expect(usage.seatsRemaining).toBeNull();
67
- expect(usage.hasSeatForNewUser).toBe(true);
68
- });
69
-
70
- it("does not enforce when the seat limit was never set", () => {
71
- expect(seats({ localUserCount: 9999 }).isEnforced).toBe(false);
72
- expect(
73
- seats({ userLimit: undefined, localUserCount: 9999 }).isEnforced,
74
- ).toBe(false);
75
- });
76
-
77
- /*
78
- * Zero is read as "no limit", matching the license modal and the breach
79
- * notification job, both of which treat userLimit <= 0 as nothing to measure
80
- * against. Reading it as "nobody may have an account" would leave a stray
81
- * zero — a bad import, a half-filled form on oneuptime.com — unable to create
82
- * even the first user of an installation.
83
- */
84
- it("treats a zero seat limit as no limit rather than no seats", () => {
85
- const usage: SeatUsage = seats({ userLimit: 0, localUserCount: 0 });
86
-
87
- expect(usage.isEnforced).toBe(false);
88
- expect(usage.hasSeatForNewUser).toBe(true);
89
- });
90
-
91
- it("ignores a negative seat limit", () => {
92
- expect(seats({ userLimit: -10, localUserCount: 5 }).isEnforced).toBe(false);
93
- });
94
-
95
- it.each([
96
- ["a fractional limit", 10.5],
97
- ["infinity", Number.POSITIVE_INFINITY],
98
- ["NaN", Number.NaN],
99
- ])("ignores %s as a seat limit", (_label: string, userLimit: number) => {
100
- expect(seats({ userLimit: userLimit, localUserCount: 5 }).isEnforced).toBe(
101
- false,
102
- );
103
- });
104
-
105
- it("ignores a seat limit that is not a number at all", () => {
106
- expect(
107
- seats({
108
- userLimit: "150" as unknown as number,
109
- localUserCount: 5,
110
- }).isEnforced,
111
- ).toBe(false);
112
- });
113
-
114
- it("enforces the smallest real limit there is", () => {
115
- expect(seats({ userLimit: 1, localUserCount: 0 }).hasSeatForNewUser).toBe(
116
- true,
117
- );
118
- expect(seats({ userLimit: 1, localUserCount: 1 }).hasSeatForNewUser).toBe(
119
- false,
120
- );
121
- });
122
- });
123
-
124
- describe("EnterpriseLicenseSeatsUtil - a single instance", () => {
125
- it("has room while users are below the limit", () => {
126
- const usage: SeatUsage = seats({ userLimit: 10, localUserCount: 7 });
127
-
128
- expect(usage.isEnforced).toBe(true);
129
- expect(usage.seatsInUse).toBe(7);
130
- expect(usage.seatsRemaining).toBe(3);
131
- expect(usage.hasSeatForNewUser).toBe(true);
132
- });
133
-
134
- /*
135
- * The boundary the whole feature turns on. A license bought for 10 users
136
- * covers the 10th; it is the 11th that has to be refused.
137
- */
138
- it("refuses the user that would step past the limit", () => {
139
- expect(seats({ userLimit: 10, localUserCount: 9 }).hasSeatForNewUser).toBe(
140
- true,
141
- );
142
- expect(seats({ userLimit: 10, localUserCount: 10 }).hasSeatForNewUser).toBe(
143
- false,
144
- );
145
- });
146
-
147
- it("reports no seats remaining rather than a negative number when over the limit", () => {
148
- const usage: SeatUsage = seats({ userLimit: 10, localUserCount: 25 });
149
-
150
- expect(usage.seatsInUse).toBe(25);
151
- expect(usage.seatsRemaining).toBe(0);
152
- expect(usage.hasSeatForNewUser).toBe(false);
153
- });
154
-
155
- it("still reports usage on an unlimited license, it just never blocks", () => {
156
- const usage: SeatUsage = seats({ userLimit: null, localUserCount: 25 });
157
-
158
- expect(usage.seatsInUse).toBe(25);
159
- expect(usage.hasSeatForNewUser).toBe(true);
160
- });
161
-
162
- it.each([
163
- ["a negative count", -5],
164
- ["a fractional count", 4.5],
165
- ["NaN", Number.NaN],
166
- ])(
167
- "falls back to zero local users for %s",
168
- (_label: string, localUserCount: number) => {
169
- expect(
170
- seats({ userLimit: 10, localUserCount: localUserCount }).seatsInUse,
171
- ).toBe(0);
172
- },
173
- );
174
- });
175
-
176
- describe("EnterpriseLicenseSeatsUtil - the licence-wide count", () => {
177
- /*
178
- * The aggregate is the only number that knows about the customer's other
179
- * instances, so it has to be able to exhaust the limit on its own — even
180
- * though this installation has barely any users of its own.
181
- */
182
- it("blocks on the licence-wide count even when this instance is nearly empty", () => {
183
- const usage: SeatUsage = seats({
184
- userLimit: 100,
185
- localUserCount: 3,
186
- aggregatedUserCount: 100,
187
- });
188
-
189
- expect(usage.seatsInUse).toBe(100);
190
- expect(usage.hasSeatForNewUser).toBe(false);
191
- });
192
-
193
- /*
194
- * And the live local count has to be able to exhaust it on its own too: the
195
- * aggregate is up to a day old, so it is systematically behind on exactly
196
- * the users this check exists to catch.
197
- */
198
- it("blocks on the live local count even when the last report was lower", () => {
199
- const usage: SeatUsage = seats({
200
- userLimit: 100,
201
- localUserCount: 100,
202
- aggregatedUserCount: 12,
203
- });
204
-
205
- expect(usage.seatsInUse).toBe(100);
206
- expect(usage.hasSeatForNewUser).toBe(false);
207
- });
208
-
209
- it.each([
210
- ["null", null],
211
- ["undefined", undefined],
212
- ["a negative number", -1],
213
- ["a fraction", 12.5],
214
- ["a string", "12" as unknown as number],
215
- ])(
216
- "ignores a licence-wide count of %s and falls back to the local one",
217
- (_label: string, aggregatedUserCount: number | null | undefined) => {
218
- const usage: SeatUsage = seats({
219
- userLimit: 100,
220
- localUserCount: 40,
221
- aggregatedUserCount: aggregatedUserCount,
222
- });
223
-
224
- expect(usage.seatsInUse).toBe(40);
225
- expect(usage.hasSeatForNewUser).toBe(true);
226
- },
227
- );
228
- });
229
-
230
- describe("EnterpriseLicenseSeatsUtil - several instances on one licence", () => {
231
- /*
232
- * The case the whole instance breakdown exists for. Two instances share a
233
- * 100-seat license: this one has 60 users, the other 30, and 10 people have
234
- * accounts on both. oneuptime.com deduplicates that to 80.
235
- *
236
- * Neither number alone is right here — 60 lets the customer overshoot, 80 is
237
- * a day stale. Subtracting this instance's last reported count from the
238
- * aggregate leaves the 20 seats that are somebody else's, and adding the
239
- * live local count back gives a figure that is current here and complete
240
- * everywhere else.
241
- */
242
- it("adds this instance's live users to the seats other instances hold", () => {
243
- const usage: SeatUsage = seats({
244
- userLimit: 100,
245
- localUserCount: 60,
246
- aggregatedUserCount: 80,
247
- thisInstanceId: "instance-1",
248
- instances: [
249
- makeInstance({ instanceId: "instance-1", userCount: 60 }),
250
- makeInstance({ instanceId: "instance-2", userCount: 30 }),
251
- ],
252
- });
253
-
254
- expect(usage.seatsUsedByOtherInstances).toBe(20);
255
- expect(usage.seatsInUse).toBe(80);
256
- expect(usage.seatsRemaining).toBe(20);
257
- expect(usage.hasSeatForNewUser).toBe(true);
258
- });
259
-
260
- it("sees users added here since the last report, which the aggregate cannot", () => {
261
- const usage: SeatUsage = seats({
262
- userLimit: 100,
263
- // 25 people signed up since the report that said 60.
264
- localUserCount: 85,
265
- aggregatedUserCount: 80,
266
- thisInstanceId: "instance-1",
267
- instances: [
268
- makeInstance({ instanceId: "instance-1", userCount: 60 }),
269
- makeInstance({ instanceId: "instance-2", userCount: 30 }),
270
- ],
271
- });
272
-
273
- expect(usage.seatsInUse).toBe(105);
274
- expect(usage.seatsRemaining).toBe(0);
275
- expect(usage.hasSeatForNewUser).toBe(false);
276
- });
277
-
278
- it("counts users deleted here since the last report back off the total", () => {
279
- const usage: SeatUsage = seats({
280
- userLimit: 100,
281
- localUserCount: 40,
282
- aggregatedUserCount: 80,
283
- thisInstanceId: "instance-1",
284
- instances: [
285
- makeInstance({ instanceId: "instance-1", userCount: 60 }),
286
- makeInstance({ instanceId: "instance-2", userCount: 30 }),
287
- ],
288
- });
289
-
290
- // 20 seats elsewhere + 40 live here. The stale 80 no longer decides it.
291
- expect(usage.seatsInUse).toBe(60);
292
- expect(usage.hasSeatForNewUser).toBe(true);
293
- });
294
-
295
- /*
296
- * Complete overlap: the same 60 people on both instances is 60 seats, not
297
- * 120. Subtracting our own reported count is what stops this instance being
298
- * charged twice for its own users.
299
- */
300
- it("does not double-count users who exist on more than one instance", () => {
301
- const usage: SeatUsage = seats({
302
- userLimit: 100,
303
- localUserCount: 60,
304
- aggregatedUserCount: 60,
305
- thisInstanceId: "instance-1",
306
- instances: [
307
- makeInstance({ instanceId: "instance-1", userCount: 60 }),
308
- makeInstance({ instanceId: "instance-2", userCount: 60 }),
309
- ],
310
- });
311
-
312
- expect(usage.seatsUsedByOtherInstances).toBe(0);
313
- expect(usage.seatsInUse).toBe(60);
314
- expect(usage.hasSeatForNewUser).toBe(true);
315
- });
316
-
317
- /*
318
- * The stale licence-wide figure is deliberately NOT allowed to outvote the
319
- * live local count once the breakdown makes it decomposable. Freeing seats by
320
- * deleting users has to free them now, not at the next daily report - which
321
- * is the difference between a limit and a lockout.
322
- */
323
- it("does not let the stale licence-wide figure hold seats that were just freed", () => {
324
- const usage: SeatUsage = seats({
325
- userLimit: 80,
326
- localUserCount: 40,
327
- aggregatedUserCount: 80,
328
- thisInstanceId: "instance-1",
329
- instances: [
330
- makeInstance({ instanceId: "instance-1", userCount: 60 }),
331
- makeInstance({ instanceId: "instance-2", userCount: 30 }),
332
- ],
333
- });
334
-
335
- expect(usage.seatsInUse).toBe(60);
336
- expect(usage.hasSeatForNewUser).toBe(true);
337
- });
338
-
339
- it("never lets other instances hold a negative number of seats", () => {
340
- const usage: SeatUsage = seats({
341
- userLimit: 100,
342
- localUserCount: 70,
343
- // Our own last report is somehow larger than the licence-wide total.
344
- aggregatedUserCount: 40,
345
- thisInstanceId: "instance-1",
346
- instances: [makeInstance({ instanceId: "instance-1", userCount: 70 })],
347
- });
348
-
349
- expect(usage.seatsUsedByOtherInstances).toBe(0);
350
- expect(usage.seatsInUse).toBe(70);
351
- });
352
-
353
- it("does not subtract this installation's stale count from an active-only aggregate", () => {
354
- const usage: SeatUsage = seats({
355
- userLimit: 100,
356
- localUserCount: 80,
357
- aggregatedUserCount: 100,
358
- thisInstanceId: "instance-1",
359
- instances: [
360
- makeInstance({
361
- instanceId: "instance-1",
362
- userCount: 80,
363
- isCountedTowardsUsage: false,
364
- }),
365
- makeInstance({
366
- instanceId: "instance-2",
367
- userCount: 100,
368
- isCountedTowardsUsage: true,
369
- }),
370
- ],
371
- });
372
-
373
- expect(usage.seatsUsedByOtherInstances).toBe(0);
374
- expect(usage.seatsInUse).toBe(100);
375
- expect(usage.hasSeatForNewUser).toBe(false);
376
- });
377
-
378
- it("does not double-count overlapping users when this installation is inactive", () => {
379
- const usage: SeatUsage = seats({
380
- userLimit: 100,
381
- localUserCount: 80,
382
- aggregatedUserCount: 80,
383
- thisInstanceId: "instance-1",
384
- instances: [
385
- makeInstance({
386
- instanceId: "instance-1",
387
- userCount: 80,
388
- isCountedTowardsUsage: false,
389
- }),
390
- makeInstance({
391
- instanceId: "instance-2",
392
- userCount: 80,
393
- isCountedTowardsUsage: true,
394
- }),
395
- ],
396
- });
397
-
398
- expect(usage.seatsInUse).toBe(80);
399
- expect(usage.hasSeatForNewUser).toBe(true);
400
- });
401
-
402
- it("retains subtraction for older license servers without activity provenance", () => {
403
- const usage: SeatUsage = seats({
404
- userLimit: 150,
405
- localUserCount: 80,
406
- aggregatedUserCount: 100,
407
- thisInstanceId: "instance-1",
408
- instances: [
409
- makeInstance({
410
- instanceId: "instance-1",
411
- userCount: 80,
412
- isCountedTowardsUsage: undefined,
413
- }),
414
- ],
415
- });
416
-
417
- expect(usage.seatsUsedByOtherInstances).toBe(20);
418
- expect(usage.seatsInUse).toBe(100);
419
- });
420
- });
421
-
422
- describe("EnterpriseLicenseSeatsUtil - when the topology cannot be read", () => {
423
- /*
424
- * Every branch here resolves to "assume nothing is held elsewhere". That is
425
- * the under-enforcing direction on purpose: the daily report corrects an
426
- * undercount, and nothing corrects an installation that has wrongly locked
427
- * its administrator out of adding users.
428
- */
429
- it.each([
430
- ["there is no instance list", undefined],
431
- ["the instance list is null", null],
432
- ["the instance list is empty", []],
433
- ])(
434
- "attributes nothing to other instances when %s",
435
- (
436
- _label: string,
437
- instances: Array<EnterpriseLicenseInstanceSummary> | null | undefined,
438
- ) => {
439
- const usage: SeatUsage = seats({
440
- userLimit: 100,
441
- localUserCount: 20,
442
- aggregatedUserCount: 80,
443
- thisInstanceId: "instance-1",
444
- instances: instances,
445
- });
446
-
447
- expect(usage.seatsUsedByOtherInstances).toBe(0);
448
- expect(usage.seatsInUse).toBe(80);
449
- },
450
- );
451
-
452
- it("attributes nothing to other instances when this instance has no id", () => {
453
- const usage: SeatUsage = seats({
454
- userLimit: 100,
455
- localUserCount: 20,
456
- aggregatedUserCount: 80,
457
- thisInstanceId: null,
458
- instances: [makeInstance({ instanceId: "instance-2", userCount: 80 })],
459
- });
460
-
461
- expect(usage.seatsUsedByOtherInstances).toBe(0);
462
- expect(usage.seatsInUse).toBe(80);
463
- });
464
-
465
- /*
466
- * The dangerous reading of "we are not in the list" is "then the whole
467
- * aggregate belongs to somebody else". It is right for an instance that has
468
- * genuinely never registered, and catastrophic for one whose instance id
469
- * changed after its users had already been counted under the old one — that
470
- * installation would be charged twice for every user it has and could lock
471
- * itself out. It is not taken.
472
- */
473
- it("does not assume the whole aggregate is somebody else's when this instance is missing from the list", () => {
474
- const usage: SeatUsage = seats({
475
- userLimit: 100,
476
- localUserCount: 80,
477
- aggregatedUserCount: 80,
478
- thisInstanceId: "instance-that-was-renamed",
479
- instances: [makeInstance({ instanceId: "instance-1", userCount: 80 })],
480
- });
481
-
482
- expect(usage.seatsUsedByOtherInstances).toBe(0);
483
- expect(usage.seatsInUse).toBe(80);
484
- expect(usage.hasSeatForNewUser).toBe(true);
485
- });
486
-
487
- it.each([
488
- ["null", null],
489
- ["a fraction", 12.5 as unknown as number],
490
- ["a string", "60" as unknown as number],
491
- ])(
492
- "attributes nothing to other instances when our own reported count is %s",
493
- (_label: string, userCount: number | null) => {
494
- const usage: SeatUsage = seats({
495
- userLimit: 100,
496
- localUserCount: 20,
497
- aggregatedUserCount: 80,
498
- thisInstanceId: "instance-1",
499
- instances: [
500
- makeInstance({ instanceId: "instance-1", userCount: userCount }),
501
- ],
502
- });
503
-
504
- expect(usage.seatsUsedByOtherInstances).toBe(0);
505
- expect(usage.seatsInUse).toBe(80);
506
- },
507
- );
508
-
509
- it("survives a malformed entry in the instance list", () => {
510
- const usage: SeatUsage = seats({
511
- userLimit: 100,
512
- localUserCount: 60,
513
- aggregatedUserCount: 80,
514
- thisInstanceId: "instance-1",
515
- instances: [
516
- null as unknown as EnterpriseLicenseInstanceSummary,
517
- makeInstance({ instanceId: "instance-1", userCount: 60 }),
518
- ],
519
- });
520
-
521
- expect(usage.seatsUsedByOtherInstances).toBe(20);
522
- expect(usage.seatsInUse).toBe(80);
523
- });
524
-
525
- it("matches this instance by its id even with surrounding whitespace", () => {
526
- const usage: SeatUsage = seats({
527
- userLimit: 100,
528
- localUserCount: 60,
529
- aggregatedUserCount: 80,
530
- thisInstanceId: " instance-1 ",
531
- instances: [makeInstance({ instanceId: "instance-1", userCount: 60 })],
532
- });
533
-
534
- expect(usage.seatsUsedByOtherInstances).toBe(20);
535
- });
536
- });
537
-
538
- describe("EnterpriseLicenseSeatsUtil - the message an administrator reads", () => {
539
- it("names the limit, the usage and what to do about it", () => {
540
- const message: string =
541
- EnterpriseLicenseSeatsUtil.getSeatLimitReachedMessage({
542
- seatsInUse: 150,
543
- userLimit: 150,
544
- });
545
-
546
- expect(message).toContain("150");
547
- expect(message).toContain("sales@oneuptime.com");
548
- expect(message).toContain("Refresh license");
549
- });
550
-
551
- it("does not say 1 users", () => {
552
- const message: string =
553
- EnterpriseLicenseSeatsUtil.getSeatLimitReachedMessage({
554
- seatsInUse: 1,
555
- userLimit: 1,
556
- });
557
-
558
- expect(message).toContain("1-user limit");
559
- expect(message).not.toContain("1 users");
560
- });
561
-
562
- /*
563
- * The message is shown to a person who is being told no. It must not read
564
- * like a bug, so it always states both halves of the arithmetic.
565
- */
566
- it("states the usage even when it exceeds the limit", () => {
567
- const message: string =
568
- EnterpriseLicenseSeatsUtil.getSeatLimitReachedMessage({
569
- seatsInUse: 212,
570
- userLimit: 150,
571
- });
572
-
573
- expect(message).toContain("150");
574
- expect(message).toContain("212");
575
- });
576
- });