@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,138 @@
1
+ import HostAddressUtil from "../../Utils/HostAddressUtil";
2
+ import { describe, expect, test } from "@jest/globals";
3
+ import net from "net";
4
+
5
+ /*
6
+ * The two IPv6 text problems that kept being got wrong one call site at a
7
+ * time: brackets are URL syntax rather than part of the address, and
8
+ * "host:port" is ambiguous for IPv6 in a way that does not look wrong.
9
+ */
10
+
11
+ const CUSTOMER_ADDRESS: string = "2001:518:2800:9::2";
12
+
13
+ describe("HostAddressUtil.isIPv6", () => {
14
+ test.each([
15
+ CUSTOMER_ADDRESS,
16
+ `[${CUSTOMER_ADDRESS}]`,
17
+ "::1",
18
+ "[::1]",
19
+ "::",
20
+ "2001:db8::",
21
+ "::ffff:192.0.2.1",
22
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
23
+ ])("%s is IPv6", (value: string) => {
24
+ expect(HostAddressUtil.isIPv6(value)).toBe(true);
25
+ });
26
+
27
+ test.each([
28
+ "192.0.2.1",
29
+ "example.com",
30
+ "localhost",
31
+ "",
32
+ " ",
33
+ "[not-an-address]",
34
+ "2001:db8::1:8443:extra",
35
+ "example.com:8443",
36
+ ])("%s is not IPv6", (value: string) => {
37
+ expect(HostAddressUtil.isIPv6(value)).toBe(false);
38
+ });
39
+ });
40
+
41
+ describe("HostAddressUtil.stripBrackets", () => {
42
+ test("removes the URL brackets from an IPv6 literal", () => {
43
+ expect(HostAddressUtil.stripBrackets(`[${CUSTOMER_ADDRESS}]`)).toBe(
44
+ CUSTOMER_ADDRESS,
45
+ );
46
+ });
47
+
48
+ test("the result is something a socket will accept, which the bracketed form is not", () => {
49
+ /*
50
+ * The point of the whole helper. Node does not strip these itself:
51
+ * net.connect({host: "[::1]"}) goes to the resolver and fails ENOTFOUND.
52
+ */
53
+ expect(net.isIP(`[${CUSTOMER_ADDRESS}]`)).toBe(0);
54
+ expect(
55
+ net.isIP(HostAddressUtil.stripBrackets(`[${CUSTOMER_ADDRESS}]`)),
56
+ ).toBe(6);
57
+ });
58
+
59
+ test("leaves a bare address, an IPv4 address and a DNS name alone", () => {
60
+ expect(HostAddressUtil.stripBrackets(CUSTOMER_ADDRESS)).toBe(
61
+ CUSTOMER_ADDRESS,
62
+ );
63
+ expect(HostAddressUtil.stripBrackets("192.0.2.1")).toBe("192.0.2.1");
64
+ expect(HostAddressUtil.stripBrackets("example.com")).toBe("example.com");
65
+ });
66
+
67
+ test("trims, because a pasted address usually arrives with whitespace", () => {
68
+ expect(HostAddressUtil.stripBrackets(` ${CUSTOMER_ADDRESS}\n`)).toBe(
69
+ CUSTOMER_ADDRESS,
70
+ );
71
+ });
72
+
73
+ test("does NOT launder a bracketed non-address into a bare hostname", () => {
74
+ expect(HostAddressUtil.stripBrackets("[not-an-address]")).toBe(
75
+ "[not-an-address]",
76
+ );
77
+ expect(HostAddressUtil.stripBrackets("[192.0.2.1]")).toBe("[192.0.2.1]");
78
+ });
79
+
80
+ test("handles empty input", () => {
81
+ expect(HostAddressUtil.stripBrackets("")).toBe("");
82
+ });
83
+ });
84
+
85
+ describe("HostAddressUtil.formatHostAndPort", () => {
86
+ test("brackets an IPv6 host so the port separator cannot be read as the address", () => {
87
+ expect(
88
+ HostAddressUtil.formatHostAndPort({ host: CUSTOMER_ADDRESS, port: 179 }),
89
+ ).toBe(`[${CUSTOMER_ADDRESS}]:179`);
90
+ });
91
+
92
+ test("the unbracketed form really is a DIFFERENT valid address, which is why this matters", () => {
93
+ /*
94
+ * Not a cosmetic issue: "2001:518:2800:9::2" + ":179" parses as a real
95
+ * IPv6 address, so an alert naming it sends somebody to the wrong host
96
+ * rather than to something obviously malformed.
97
+ */
98
+ expect(net.isIP(`${CUSTOMER_ADDRESS}:179`)).toBe(6);
99
+ expect(`${CUSTOMER_ADDRESS}:179`).not.toBe(CUSTOMER_ADDRESS);
100
+
101
+ expect(
102
+ HostAddressUtil.formatHostAndPort({ host: CUSTOMER_ADDRESS, port: 179 }),
103
+ ).not.toBe(`${CUSTOMER_ADDRESS}:179`);
104
+ });
105
+
106
+ test("IPv4 and DNS hosts keep the conventional spelling", () => {
107
+ expect(
108
+ HostAddressUtil.formatHostAndPort({ host: "192.0.2.1", port: 179 }),
109
+ ).toBe("192.0.2.1:179");
110
+ expect(
111
+ HostAddressUtil.formatHostAndPort({ host: "example.com", port: "8443" }),
112
+ ).toBe("example.com:8443");
113
+ });
114
+
115
+ test("does not bracket twice", () => {
116
+ expect(
117
+ HostAddressUtil.formatHostAndPort({
118
+ host: `[${CUSTOMER_ADDRESS}]`,
119
+ port: 179,
120
+ }),
121
+ ).toBe(`[${CUSTOMER_ADDRESS}]:179`);
122
+ });
123
+
124
+ test("no port means the bare host, so a stored destination is not rewritten", () => {
125
+ expect(HostAddressUtil.formatHostAndPort({ host: CUSTOMER_ADDRESS })).toBe(
126
+ CUSTOMER_ADDRESS,
127
+ );
128
+ expect(
129
+ HostAddressUtil.formatHostAndPort({ host: CUSTOMER_ADDRESS, port: "" }),
130
+ ).toBe(CUSTOMER_ADDRESS);
131
+ expect(
132
+ HostAddressUtil.formatHostAndPort({
133
+ host: `[${CUSTOMER_ADDRESS}]`,
134
+ port: undefined,
135
+ }),
136
+ ).toBe(CUSTOMER_ADDRESS);
137
+ });
138
+ });
@@ -8,6 +8,7 @@ import Label from "../../Models/DatabaseModels/Label";
8
8
  import Monitor from "../../Models/DatabaseModels/Monitor";
9
9
  import MonitorLabelRule from "../../Models/DatabaseModels/MonitorLabelRule";
10
10
  import NetworkDeviceLabelRule from "../../Models/DatabaseModels/NetworkDeviceLabelRule";
11
+ import ServiceLevelObjectiveLabelRule from "../../Models/DatabaseModels/ServiceLevelObjectiveLabelRule";
11
12
  import TableColumnType from "../../Types/Database/TableColumnType";
12
13
  import FilterCondition from "../../Types/Filter/FilterCondition";
13
14
  import { JSONObject } from "../../Types/JSON";
@@ -175,6 +176,11 @@ const criteriaByType: Record<string, [string, string, string]> = {
175
176
  "serviceDescriptionPattern",
176
177
  "serviceLabels",
177
178
  ],
179
+ ServiceLevelObjectiveLabelRule: [
180
+ "serviceLevelObjectiveNamePattern",
181
+ "serviceLevelObjectiveDescriptionPattern",
182
+ "serviceLevelObjectiveLabels",
183
+ ],
178
184
  StatusPageLabelRule: [
179
185
  "statusPageNamePattern",
180
186
  "statusPageDescriptionPattern",
@@ -590,6 +596,102 @@ describe("portable label rule files", () => {
590
596
  },
591
597
  );
592
598
 
599
+ /*
600
+ * SLO label rules match patterns the way network device rules do - a regex,
601
+ * with a '*' wildcard fallback, on the trimmed pattern - so the two trade
602
+ * any pattern, and both refuse one whose meaning a regex-only rule type
603
+ * would change.
604
+ */
605
+ test("preserves wildcard SLO patterns when importing SLO rules", () => {
606
+ expect(
607
+ parse(
608
+ [{ ...base, serviceLevelObjectiveNamePattern: "*checkout*" }],
609
+ ServiceLevelObjectiveLabelRule,
610
+ ).items[0]!.json["serviceLevelObjectiveNamePattern"],
611
+ ).toBe("*checkout*");
612
+ });
613
+
614
+ test.each([
615
+ [NetworkDeviceLabelRule, ServiceLevelObjectiveLabelRule],
616
+ [ServiceLevelObjectiveLabelRule, NetworkDeviceLabelRule],
617
+ ])(
618
+ "moves a wildcard between %p and %p without changing its meaning",
619
+ (source: DatabaseBaseModelType, destination: DatabaseBaseModelType) => {
620
+ const sourceField: string =
621
+ source === NetworkDeviceLabelRule
622
+ ? "networkDeviceNamePattern"
623
+ : "serviceLevelObjectiveNamePattern";
624
+ const destinationField: string =
625
+ destination === NetworkDeviceLabelRule
626
+ ? "networkDeviceNamePattern"
627
+ : "serviceLevelObjectiveNamePattern";
628
+
629
+ expect(
630
+ parse([{ ...base, [sourceField]: "*edge*" }], source, destination)
631
+ .items[0]!.json[destinationField],
632
+ ).toBe("*edge*");
633
+ },
634
+ );
635
+
636
+ test.each(["*checkout*", "checkout.*", " checkout ", " "])(
637
+ "rejects moving the SLO pattern %p to a regex-only rule type",
638
+ (pattern: string) => {
639
+ expect(() => {
640
+ parse(
641
+ [{ ...base, serviceLevelObjectiveNamePattern: pattern }],
642
+ ServiceLevelObjectiveLabelRule,
643
+ MonitorLabelRule,
644
+ );
645
+ }).toThrow("without changing its meaning");
646
+ },
647
+ );
648
+
649
+ test.each(["checkout.*", " checkout "])(
650
+ "rejects importing the regex %p into the broader SLO matcher",
651
+ (pattern: string) => {
652
+ expect(() => {
653
+ parse(
654
+ [{ ...base, monitorNamePattern: pattern }],
655
+ MonitorLabelRule,
656
+ ServiceLevelObjectiveLabelRule,
657
+ );
658
+ }).toThrow("without changing its meaning");
659
+ },
660
+ );
661
+
662
+ test("moves a plain SLO pattern to a regex-only rule type", () => {
663
+ expect(
664
+ parse(
665
+ [{ ...base, serviceLevelObjectiveNamePattern: "^checkout-" }],
666
+ ServiceLevelObjectiveLabelRule,
667
+ MonitorLabelRule,
668
+ ).items[0]!.json["monitorNamePattern"],
669
+ ).toBe("^checkout-");
670
+ });
671
+
672
+ test("accepts a wildcard, but not an invalid pattern, for SLO rules", () => {
673
+ expect(() => {
674
+ parse(
675
+ [{ ...base, serviceLevelObjectiveDescriptionPattern: "*tier 1*" }],
676
+ ServiceLevelObjectiveLabelRule,
677
+ );
678
+ }).not.toThrow();
679
+
680
+ expect(() => {
681
+ parse(
682
+ [{ ...base, serviceLevelObjectiveDescriptionPattern: "tier-(1" }],
683
+ ServiceLevelObjectiveLabelRule,
684
+ );
685
+ }).toThrow("is not a valid regular expression or wildcard pattern");
686
+ });
687
+
688
+ // A regex-only rule type still refuses the wildcard syntax outright.
689
+ test("still rejects a bare wildcard for a regex-only rule type", () => {
690
+ expect(() => {
691
+ parse([{ ...base, monitorNamePattern: "*checkout*" }], MonitorLabelRule);
692
+ }).toThrow("is not a valid regular expression.");
693
+ });
694
+
593
695
  test("preserves wildcard network patterns when importing network rules", () => {
594
696
  expect(
595
697
  parse(
@@ -0,0 +1,313 @@
1
+ import Hostname from "../../../Types/API/Hostname";
2
+ import URL from "../../../Types/API/URL";
3
+ import IP from "../../../Types/IP/IP";
4
+ import MonitorType from "../../../Types/Monitor/MonitorType";
5
+ import MonitorDestinationUtil, {
6
+ ParsedMonitorDestination,
7
+ } from "../../../Utils/Monitor/MonitorDestinationUtil";
8
+ import { describe, expect, test } from "@jest/globals";
9
+
10
+ /*
11
+ * What the dashboard's destination field does with what somebody typed.
12
+ *
13
+ * This exists because of a customer who had working monitors on their IPv4
14
+ * BGP endpoints, added the IPv6 ones, and could not get them to work
15
+ * Their test address, used verbatim throughout this file, was
16
+ * 2001:518:2800:9::2.
17
+ *
18
+ * The failure was not that IPv6 was rejected. It was that an IPv6 address
19
+ * with a trailing space — which is what copying one out of a looking glass,
20
+ * a router config or a terminal gives you — was SILENTLY TRUNCATED to
21
+ * "2001:518" and saved, with no error shown. The identical IPv4 paste worked,
22
+ * because "1.1.1.1 " has no colon to split on.
23
+ *
24
+ * Every "the customer's address" case below failed before the fix.
25
+ */
26
+
27
+ const CUSTOMER_ADDRESS: string = "2001:518:2800:9::2";
28
+
29
+ function parse(
30
+ value: string,
31
+ monitorType: MonitorType,
32
+ ): ParsedMonitorDestination {
33
+ return MonitorDestinationUtil.parse({
34
+ value: value,
35
+ monitorType: monitorType,
36
+ });
37
+ }
38
+
39
+ const HOST_MONITOR_TYPES: Array<MonitorType> = [
40
+ MonitorType.IP,
41
+ MonitorType.Ping,
42
+ MonitorType.Port,
43
+ ];
44
+
45
+ describe("MonitorDestinationUtil.parse — the customer's IPv6 BGP endpoint", () => {
46
+ for (const monitorType of HOST_MONITOR_TYPES) {
47
+ describe(`${monitorType} monitor`, () => {
48
+ test("keeps the address exactly as typed", () => {
49
+ const parsed: ParsedMonitorDestination = parse(
50
+ CUSTOMER_ADDRESS,
51
+ monitorType,
52
+ );
53
+
54
+ expect(parsed.error).toBeNull();
55
+ expect(parsed.destination).toBeInstanceOf(IP);
56
+ expect(parsed.destination?.toString()).toBe(CUSTOMER_ADDRESS);
57
+ });
58
+
59
+ test("a trailing space does not truncate it to its first two groups", () => {
60
+ /*
61
+ * THE BUG. "2001:518:2800:9::2 " missed IP.isIP (which does not
62
+ * trim), fell through to Hostname.fromString, and came back as host
63
+ * "2001" with port 518. 518 is a legal port, so nothing threw and
64
+ * the operator was shown no error at all.
65
+ */
66
+ const parsed: ParsedMonitorDestination = parse(
67
+ `${CUSTOMER_ADDRESS} `,
68
+ monitorType,
69
+ );
70
+
71
+ expect(parsed.error).toBeNull();
72
+ expect(parsed.destination?.toString()).toBe(CUSTOMER_ADDRESS);
73
+ expect(parsed.destination?.toString()).not.toBe("2001:518");
74
+ });
75
+
76
+ test("a leading space or a trailing newline is tolerated the same way", () => {
77
+ expect(
78
+ parse(` ${CUSTOMER_ADDRESS}`, monitorType).destination?.toString(),
79
+ ).toBe(CUSTOMER_ADDRESS);
80
+ expect(
81
+ parse(`${CUSTOMER_ADDRESS}\n`, monitorType).destination?.toString(),
82
+ ).toBe(CUSTOMER_ADDRESS);
83
+ });
84
+
85
+ test("the bracketed spelling is accepted and stored bare", () => {
86
+ /*
87
+ * "[2001:518:2800:9::2]" is how the address is written inside a URL,
88
+ * so it is a form people have to hand. It used to produce the
89
+ * baffling "Hostname [2001 is not in valid format." on Ping/Port.
90
+ */
91
+ const parsed: ParsedMonitorDestination = parse(
92
+ `[${CUSTOMER_ADDRESS}]`,
93
+ monitorType,
94
+ );
95
+
96
+ expect(parsed.error).toBeNull();
97
+ expect(parsed.destination?.toString()).toBe(CUSTOMER_ADDRESS);
98
+ });
99
+
100
+ test("the equivalent IPv4 paste keeps behaving exactly as it always did", () => {
101
+ expect(parse("192.0.2.1", monitorType).destination?.toString()).toBe(
102
+ "192.0.2.1",
103
+ );
104
+ expect(parse("192.0.2.1 ", monitorType).destination?.toString()).toBe(
105
+ "192.0.2.1",
106
+ );
107
+ });
108
+
109
+ test("an address that is genuinely malformed is reported, not stored", () => {
110
+ const parsed: ParsedMonitorDestination = parse(
111
+ "2001:518:2800:9:::2",
112
+ monitorType,
113
+ );
114
+
115
+ expect(parsed.destination).toBeUndefined();
116
+ expect(parsed.error).toBeTruthy();
117
+ });
118
+
119
+ test("an empty field is a missing destination, not a parse failure", () => {
120
+ expect(parse(" ", monitorType)).toEqual({
121
+ destination: undefined,
122
+ error: "Destination is required",
123
+ });
124
+ });
125
+ });
126
+ }
127
+
128
+ describe("every prefix of the address as it is typed", () => {
129
+ /*
130
+ * Typing left to right passes through "2001:518:2800:9::", which IS a
131
+ * real address. The form used to write each parse into the step and
132
+ * never clear it, so a prefix that parsed could outlive the keystrokes
133
+ * after it. What matters here is that no prefix EVER parses to something
134
+ * that is not what was typed.
135
+ */
136
+ test("a prefix either fails to parse or parses to itself — never to something else", () => {
137
+ for (let i: number = 1; i <= CUSTOMER_ADDRESS.length; i++) {
138
+ const prefix: string = CUSTOMER_ADDRESS.substring(0, i);
139
+
140
+ for (const monitorType of HOST_MONITOR_TYPES) {
141
+ const parsed: ParsedMonitorDestination = parse(prefix, monitorType);
142
+
143
+ if (parsed.destination) {
144
+ expect(parsed.destination.toString()).toBe(prefix);
145
+ }
146
+ }
147
+ }
148
+ });
149
+
150
+ test("the COMPLETE address never parses to 2001:518, however it is spelled", () => {
151
+ /*
152
+ * "2001:518" on its own is a legitimate parse of the prefix "2001:518"
153
+ * — the operator really had typed only that. What must never happen is
154
+ * the complete address arriving and 2001:518 being what gets stored.
155
+ */
156
+ const spellings: Array<string> = [
157
+ CUSTOMER_ADDRESS,
158
+ `${CUSTOMER_ADDRESS} `,
159
+ ` ${CUSTOMER_ADDRESS}`,
160
+ `${CUSTOMER_ADDRESS}\n`,
161
+ `\t${CUSTOMER_ADDRESS}\t`,
162
+ `[${CUSTOMER_ADDRESS}]`,
163
+ ` [${CUSTOMER_ADDRESS}] `,
164
+ ];
165
+
166
+ for (const spelling of spellings) {
167
+ for (const monitorType of HOST_MONITOR_TYPES) {
168
+ expect(parse(spelling, monitorType).destination?.toString()).toBe(
169
+ CUSTOMER_ADDRESS,
170
+ );
171
+ }
172
+ }
173
+ });
174
+ });
175
+ });
176
+
177
+ describe("MonitorDestinationUtil.parse — hostnames still work", () => {
178
+ test("a DNS name is a Hostname", () => {
179
+ const parsed: ParsedMonitorDestination = parse(
180
+ "rs1.example.net",
181
+ MonitorType.Ping,
182
+ );
183
+
184
+ expect(parsed.error).toBeNull();
185
+ expect(parsed.destination).toBeInstanceOf(Hostname);
186
+ expect(parsed.destination?.toString()).toBe("rs1.example.net");
187
+ });
188
+
189
+ test("a pasted 'host:port' is split, not stored as a host with a colon in its name", () => {
190
+ /*
191
+ * `new Hostname("rs1.example.net:179")` would happily store the whole
192
+ * authority AS THE HOST, and the socket would then go looking for a DNS
193
+ * name with a colon in it.
194
+ */
195
+ const parsed: ParsedMonitorDestination = parse(
196
+ "rs1.example.net:179",
197
+ MonitorType.Port,
198
+ );
199
+
200
+ expect(parsed.error).toBeNull();
201
+ expect((parsed.destination as Hostname).hostname).toBe("rs1.example.net");
202
+ expect((parsed.destination as Hostname).port?.toNumber()).toBe(179);
203
+ });
204
+
205
+ test("a bracketed IPv6 host WITH a port is split the same way", () => {
206
+ const parsed: ParsedMonitorDestination = parse(
207
+ `[${CUSTOMER_ADDRESS}]:179`,
208
+ MonitorType.Port,
209
+ );
210
+
211
+ expect(parsed.error).toBeNull();
212
+ expect((parsed.destination as Hostname).port?.toNumber()).toBe(179);
213
+ });
214
+
215
+ test("an IP monitor rejects a DNS name, as it always has", () => {
216
+ expect(
217
+ parse("rs1.example.net", MonitorType.IP).destination,
218
+ ).toBeUndefined();
219
+ });
220
+ });
221
+
222
+ describe("MonitorDestinationUtil.parse — URL monitor types", () => {
223
+ const URL_MONITOR_TYPES: Array<MonitorType> = [
224
+ MonitorType.Website,
225
+ MonitorType.API,
226
+ MonitorType.SSLCertificate,
227
+ ];
228
+
229
+ for (const monitorType of URL_MONITOR_TYPES) {
230
+ test(`${monitorType}: a bracketed IPv6 URL round-trips`, () => {
231
+ const parsed: ParsedMonitorDestination = parse(
232
+ `https://[${CUSTOMER_ADDRESS}]/health`,
233
+ monitorType,
234
+ );
235
+
236
+ expect(parsed.error).toBeNull();
237
+ expect(parsed.destination).toBeInstanceOf(URL);
238
+ expect(parsed.destination?.toString()).toBe(
239
+ `https://[${CUSTOMER_ADDRESS}]/health`,
240
+ );
241
+ });
242
+
243
+ test(`${monitorType}: a BARE IPv6 URL is bracketed rather than stored unusable`, () => {
244
+ /*
245
+ * "https://2001:518:2800:9::2/" is not a URL — the first colon reads
246
+ * as the port separator, and every HTTP client rejects it. The field
247
+ * used to accept it verbatim and the monitor then failed forever.
248
+ */
249
+ const parsed: ParsedMonitorDestination = parse(
250
+ `https://${CUSTOMER_ADDRESS}/`,
251
+ monitorType,
252
+ );
253
+
254
+ expect(parsed.error).toBeNull();
255
+ expect(parsed.destination?.toString()).toBe(
256
+ `https://[${CUSTOMER_ADDRESS}]/`,
257
+ );
258
+ });
259
+
260
+ test(`${monitorType}: an IPv4 or DNS URL is left byte for byte alone`, () => {
261
+ expect(
262
+ parse(
263
+ "https://example.com:8443/x?y=1",
264
+ monitorType,
265
+ ).destination?.toString(),
266
+ ).toBe("https://example.com:8443/x?y=1");
267
+ expect(
268
+ parse("https://192.0.2.1/health", monitorType).destination?.toString(),
269
+ ).toBe("https://192.0.2.1/health");
270
+ });
271
+ }
272
+ });
273
+
274
+ describe("MonitorDestinationUtil.toUrlWithBracketedIpv6Host", () => {
275
+ const bracket: (value: string) => string = (value: string): string => {
276
+ return MonitorDestinationUtil.toUrlWithBracketedIpv6Host(value);
277
+ };
278
+
279
+ test("brackets a bare IPv6 host", () => {
280
+ expect(bracket(`https://${CUSTOMER_ADDRESS}`)).toBe(
281
+ `https://[${CUSTOMER_ADDRESS}]`,
282
+ );
283
+ });
284
+
285
+ test("keeps the path, query and fragment where they were", () => {
286
+ expect(bracket(`https://${CUSTOMER_ADDRESS}/a/b?c=1#d`)).toBe(
287
+ `https://[${CUSTOMER_ADDRESS}]/a/b?c=1#d`,
288
+ );
289
+ });
290
+
291
+ test("does not bracket twice", () => {
292
+ expect(bracket(`https://[${CUSTOMER_ADDRESS}]/a`)).toBe(
293
+ `https://[${CUSTOMER_ADDRESS}]/a`,
294
+ );
295
+ });
296
+
297
+ test("keeps userinfo outside the brackets", () => {
298
+ expect(bracket(`https://user:token@${CUSTOMER_ADDRESS}/a`)).toBe(
299
+ `https://user:token@[${CUSTOMER_ADDRESS}]/a`,
300
+ );
301
+ });
302
+
303
+ test("leaves a DNS or IPv4 URL untouched", () => {
304
+ expect(bracket("https://example.com:8443/x")).toBe(
305
+ "https://example.com:8443/x",
306
+ );
307
+ expect(bracket("http://192.0.2.1/x")).toBe("http://192.0.2.1/x");
308
+ });
309
+
310
+ test("leaves a host:port that only looks address-ish untouched", () => {
311
+ expect(bracket("https://localhost:3000")).toBe("https://localhost:3000");
312
+ });
313
+ });