@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
@@ -12,8 +12,10 @@ import { describe, expect, test } from "@jest/globals";
12
12
  * consumer, which is why a monitor on a non-443 port could never connect —
13
13
  * see https://github.com/OneUptime/oneuptime/issues/3225.
14
14
  *
15
- * fromString() is NOT a substitute: it splits on the FIRST colon, which
16
- * mangles every IPv6 literal.
15
+ * fromString() used not to be a substitute: it split on the FIRST colon,
16
+ * which mangled every IPv6 literal. It now delegates IPv6 authorities here
17
+ * instead, so the two agree on addresses; they still differ on a DNS host,
18
+ * where fromString keeps its own splitting and its own userinfo handling.
17
19
  */
18
20
  describe("Hostname.fromAuthority", () => {
19
21
  describe("host and port", () => {
@@ -141,18 +143,26 @@ describe("Hostname.fromAuthority", () => {
141
143
  });
142
144
 
143
145
  describe("contrast with fromString", () => {
144
- test("fromString rejects an IPv6 literal that fromAuthority handles", () => {
146
+ test("fromString now agrees with fromAuthority on an IPv6 literal", () => {
145
147
  /*
146
- * Pinned deliberately: it documents WHY fromAuthority exists, and
147
- * guards against someone 'simplifying' one into the other.
148
+ * This case used to be pinned the other way round: fromString split on
149
+ * the FIRST colon, so "[::1]:8443" became a host of "[" and the setter
150
+ * threw. Worse, the unbracketed spelling did NOT throw -- it returned
151
+ * host "2001" / port 518 for "2001:518:2800:9::2" and a monitor was
152
+ * saved pointing at a host nobody typed.
148
153
  *
149
- * fromString splits on the FIRST colon, so "[::1]:8443" becomes a
150
- * host of "[" - which the Hostname setter rejects outright.
154
+ * fromString delegates IPv6 authorities to fromAuthority now, so the
155
+ * two agree. Kept as a contrast test so a future 'simplification' that
156
+ * reintroduces the split fails here.
151
157
  */
152
158
  expect(Hostname.fromAuthority("[::1]:8443").hostname).toBe("[::1]");
153
- expect(() => {
154
- return Hostname.fromString("[::1]:8443");
155
- }).toThrow();
159
+ expect(Hostname.fromString("[::1]:8443").hostname).toBe("[::1]");
160
+ expect(Hostname.fromString("[::1]:8443").port?.toNumber()).toBe(8443);
161
+
162
+ expect(Hostname.fromString("2001:518:2800:9::2").hostname).toBe(
163
+ "2001:518:2800:9::2",
164
+ );
165
+ expect(Hostname.fromString("2001:518:2800:9::2").port).toBeUndefined();
156
166
  });
157
167
 
158
168
  test("both agree on the simple host:port case", () => {
@@ -0,0 +1,149 @@
1
+ import Hostname from "../../../Types/API/Hostname";
2
+ import URL from "../../../Types/API/URL";
3
+ import { describe, expect, test } from "@jest/globals";
4
+ import net from "net";
5
+
6
+ /*
7
+ * Hostname's handling of IPv6 literals.
8
+ *
9
+ * fromString used to split on the FIRST colon, which is meaningless for an
10
+ * address made of colons. The damage was silent rather than loud: for the
11
+ * customer address reported below it
12
+ * returned host "2001" with port 518 — both legal — so nothing threw and the
13
+ * value the operator typed was simply gone.
14
+ */
15
+
16
+ const CUSTOMER_ADDRESS: string = "2001:518:2800:9::2";
17
+
18
+ describe("Hostname.fromString with an IPv6 literal", () => {
19
+ test("keeps the whole address instead of its first two groups", () => {
20
+ const hostname: Hostname = Hostname.fromString(CUSTOMER_ADDRESS);
21
+
22
+ expect(hostname.hostname).toBe(CUSTOMER_ADDRESS);
23
+ expect(hostname.port).toBeUndefined();
24
+ expect(hostname.toString()).toBe(CUSTOMER_ADDRESS);
25
+ });
26
+
27
+ test("specifically, it is not 2001 port 518", () => {
28
+ const hostname: Hostname = Hostname.fromString(CUSTOMER_ADDRESS);
29
+
30
+ expect(hostname.hostname).not.toBe("2001");
31
+ expect(hostname.port?.toNumber()).not.toBe(518);
32
+ });
33
+
34
+ test("trims, so a pasted address keeps working", () => {
35
+ expect(Hostname.fromString(` ${CUSTOMER_ADDRESS}\n`).hostname).toBe(
36
+ CUSTOMER_ADDRESS,
37
+ );
38
+ });
39
+
40
+ test.each([
41
+ "::1",
42
+ "::",
43
+ "2001:db8::",
44
+ "::ffff:192.0.2.1",
45
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
46
+ ])("survives the compressed form %s", (address: string) => {
47
+ expect(Hostname.fromString(address).hostname).toBe(address);
48
+ });
49
+
50
+ test("a bracketed literal keeps its brackets and gives up its port", () => {
51
+ const hostname: Hostname = Hostname.fromString(`[${CUSTOMER_ADDRESS}]:179`);
52
+
53
+ expect(hostname.hostname).toBe(`[${CUSTOMER_ADDRESS}]`);
54
+ expect(hostname.port?.toNumber()).toBe(179);
55
+ });
56
+
57
+ test("a value with two colons that is NOT an address is rejected rather than silently split", () => {
58
+ expect(() => {
59
+ return Hostname.fromString("example.com:80:90");
60
+ }).toThrow();
61
+ });
62
+ });
63
+
64
+ describe("Hostname.fromString — IPv4 and DNS are unchanged", () => {
65
+ test.each([
66
+ ["example.com", "example.com", undefined],
67
+ ["example.com:8443", "example.com", 8443],
68
+ ["192.0.2.1", "192.0.2.1", undefined],
69
+ ["192.0.2.1:179", "192.0.2.1", 179],
70
+ ["localhost:3000", "localhost", 3000],
71
+ ])(
72
+ "%s parses to host %s",
73
+ (value: string, expectedHost: string, expectedPort?: number) => {
74
+ const hostname: Hostname = Hostname.fromString(value);
75
+
76
+ expect(hostname.hostname).toBe(expectedHost);
77
+ expect(hostname.port?.toNumber()).toBe(expectedPort);
78
+ },
79
+ );
80
+ });
81
+
82
+ describe("Hostname.toString with a port", () => {
83
+ test("brackets an IPv6 host, because the unbracketed form is a different address", () => {
84
+ const hostname: Hostname = new Hostname(CUSTOMER_ADDRESS, 179);
85
+
86
+ expect(hostname.toString()).toBe(`[${CUSTOMER_ADDRESS}]:179`);
87
+
88
+ // What it used to produce, and why that was not merely ugly:
89
+ expect(net.isIP(`${CUSTOMER_ADDRESS}:179`)).toBe(6);
90
+ expect(hostname.toString()).not.toBe(`${CUSTOMER_ADDRESS}:179`);
91
+ });
92
+
93
+ test("the bracketed form re-parses to the same host and port", () => {
94
+ const roundTripped: Hostname = Hostname.fromString(
95
+ new Hostname(CUSTOMER_ADDRESS, 179).toString(),
96
+ );
97
+
98
+ expect(roundTripped.hostname).toBe(`[${CUSTOMER_ADDRESS}]`);
99
+ expect(roundTripped.port?.toNumber()).toBe(179);
100
+ });
101
+
102
+ test("an IPv4 or DNS host keeps the conventional spelling", () => {
103
+ expect(new Hostname("192.0.2.1", 179).toString()).toBe("192.0.2.1:179");
104
+ expect(new Hostname("example.com", 8443).toString()).toBe(
105
+ "example.com:8443",
106
+ );
107
+ });
108
+
109
+ test("without a port the host is returned exactly as held", () => {
110
+ expect(new Hostname(CUSTOMER_ADDRESS).toString()).toBe(CUSTOMER_ADDRESS);
111
+ expect(Hostname.fromAuthority("[::1]").toString()).toBe("[::1]");
112
+ });
113
+ });
114
+
115
+ describe("Hostname.isValid validates the address, not just its characters", () => {
116
+ test.each([CUSTOMER_ADDRESS, "::1", "[::1]", "[::1]:8080", "2001:db8::"])(
117
+ "accepts %s",
118
+ (value: string) => {
119
+ expect(Hostname.isValid(value)).toBe(true);
120
+ },
121
+ );
122
+
123
+ test.each([
124
+ "::::",
125
+ "2001:db8:::1",
126
+ "[not-an-address]",
127
+ "gggg::1",
128
+ "2001:db8::1::2",
129
+ ])(
130
+ "rejects %s, which the old character allowlist let through",
131
+ (value: string) => {
132
+ expect(Hostname.isValid(value)).toBe(false);
133
+ },
134
+ );
135
+ });
136
+
137
+ describe("URL.toString still emits a valid authority for an IPv6 host", () => {
138
+ test("brackets survive a round trip", () => {
139
+ expect(
140
+ URL.fromString(`https://[${CUSTOMER_ADDRESS}]/health`).toString(),
141
+ ).toBe(`https://[${CUSTOMER_ADDRESS}]/health`);
142
+ });
143
+
144
+ test("a bracketed host with a port survives a round trip", () => {
145
+ expect(
146
+ URL.fromString(`https://[${CUSTOMER_ADDRESS}]:8443/x`).toString(),
147
+ ).toBe(`https://[${CUSTOMER_ADDRESS}]:8443/x`);
148
+ });
149
+ });
@@ -59,4 +59,60 @@ describe("Route", () => {
59
59
  ])("preserves legitimate colon use in %s", (routeValue: string) => {
60
60
  expect(new Route(routeValue).toString()).toBe(routeValue);
61
61
  });
62
+
63
+ /*
64
+ * A Telegram token segment is scheme-like when it stands alone, so it is
65
+ * refused bare - but with its leading "/" it is an ordinary absolute path.
66
+ * URL.fromString relies on exactly this to keep Telegram URLs parseable.
67
+ */
68
+ test("accepts a token-like first segment once it has a leading slash", () => {
69
+ expect(() => {
70
+ return new Route("bot123456:ABC-def_ghi/sendMessage");
71
+ }).toThrowError(BadDataException);
72
+
73
+ expect(new Route("/bot123456:ABC-def_ghi/sendMessage").toString()).toBe(
74
+ "/bot123456:ABC-def_ghi/sendMessage",
75
+ );
76
+ });
77
+
78
+ test("addRoute prefixes the slash before validating a token-like string", () => {
79
+ expect(new Route("").addRoute("bot123456:ABC/sendMessage").toString()).toBe(
80
+ "/bot123456:ABC/sendMessage",
81
+ );
82
+ expect(new Route("/api").addRoute("bot1:x").toString()).toBe("/api/bot1:x");
83
+ });
84
+
85
+ test.each([
86
+ ["javascript:alert(1)", true],
87
+ ["JaVaScRiPt:alert(1)", true],
88
+ ["https://example.com", true],
89
+ ["bot123:ABC/sendMessage", true],
90
+ ["a.b+c-d:e", true],
91
+ ["/bot123:ABC/sendMessage", false],
92
+ ["api/:resourceId", false],
93
+ [":resourceId", false],
94
+ ["1:2/x", false],
95
+ ["_matrix/!room:server", false],
96
+ ["#frag:ment", false],
97
+ ["?next=a:b", false],
98
+ ["", false],
99
+ ])("hasSchemePrefix(%s) is %s", (routeValue: string, expected: boolean) => {
100
+ expect(Route.hasSchemePrefix(routeValue)).toBe(expected);
101
+ });
102
+
103
+ test.each(["/~user", "/files/~backup", "/a~b", "~user/hook", "/p?x=~y"])(
104
+ "accepts the unreserved character '~' in %s",
105
+ (routeValue: string) => {
106
+ expect(new Route(routeValue).toString()).toBe(routeValue);
107
+ },
108
+ );
109
+
110
+ test.each(["/a b", "/a|b", "/a`b", '/a"b', "/a<b", "/a>b", "/a\\b", "/a^b"])(
111
+ "still refuses the non-path character in %s",
112
+ (routeValue: string) => {
113
+ expect(() => {
114
+ return new Route(routeValue);
115
+ }).toThrowError(BadDataException);
116
+ },
117
+ );
62
118
  });
@@ -0,0 +1,304 @@
1
+ import Hostname from "../../../Types/API/Hostname";
2
+ import Protocol from "../../../Types/API/Protocol";
3
+ import Route from "../../../Types/API/Route";
4
+ import URL from "../../../Types/API/URL";
5
+ import BadDataException from "../../../Types/Exception/BadDataException";
6
+ import { describe, expect, test } from "@jest/globals";
7
+
8
+ /*
9
+ * Route refuses any value that starts with a scheme ("javascript:...", but
10
+ * equally "bot123:ABC/sendMessage"), so a scheme can never reach a navigation
11
+ * sink. URL.fromString stores a parsed path WITHOUT the "/" that separates it
12
+ * from the authority, and handed that bare path to Route. So any URL whose
13
+ * first path segment contains a ":" stopped parsing:
14
+ *
15
+ * URL.fromString("https://api.telegram.org/bot123:ABC/sendMessage")
16
+ * => BadDataException "Invalid route: bot123:ABC/sendMessage"
17
+ *
18
+ * Telegram puts the bot token - always "<id>:<secret>" - in exactly that
19
+ * segment. That broke the Telegram workflow component (and put the token in
20
+ * the run log), every API component call to Telegram, and every sandboxed
21
+ * axios call to Telegram, where the SSRF guard's parse failure surfaced as
22
+ * "Request URL is not a valid URL".
23
+ */
24
+
25
+ // Same shape as a real token: 10-digit bot id, 35-character secret.
26
+ const BOT_TOKEN: string = "8000000001:AAFakeFakeFakeFakeFakeFakeFake_-12345";
27
+ const TELEGRAM_URL: string = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
28
+
29
+ describe("URL.fromString - Telegram Bot API URLs", () => {
30
+ test("parses the sendMessage URL instead of throwing Invalid route", () => {
31
+ expect(() => {
32
+ return URL.fromString(TELEGRAM_URL);
33
+ }).not.toThrow();
34
+ });
35
+
36
+ test("round-trips to exactly the string that was parsed", () => {
37
+ expect(URL.fromString(TELEGRAM_URL).toString()).toBe(TELEGRAM_URL);
38
+ });
39
+
40
+ test("puts the whole bot token in the path, not in the host or port", () => {
41
+ const url: URL = URL.fromString(TELEGRAM_URL);
42
+
43
+ expect(url.protocol).toBe(Protocol.HTTPS);
44
+ expect(url.hostname.hostname).toBe("api.telegram.org");
45
+ expect(url.hostname.port).toBeUndefined();
46
+ expect(url.route.toString()).toBe(`/bot${BOT_TOKEN}/sendMessage`);
47
+ });
48
+
49
+ test("agrees with the WHATWG parser the HTTP client uses", () => {
50
+ const whatwg: globalThis.URL = new globalThis.URL(TELEGRAM_URL);
51
+ const url: URL = URL.fromString(TELEGRAM_URL);
52
+
53
+ expect(url.hostname.hostname).toBe(whatwg.hostname);
54
+ expect(url.route.toString()).toBe(whatwg.pathname);
55
+ expect(url.toString()).toBe(whatwg.href);
56
+ });
57
+
58
+ test.each([
59
+ "getMe",
60
+ "sendMessage",
61
+ "sendPhoto",
62
+ "getUpdates",
63
+ "setWebhook",
64
+ "getWebhookInfo",
65
+ ])("parses the %s method URL", (method: string) => {
66
+ const raw: string = `https://api.telegram.org/bot${BOT_TOKEN}/${method}`;
67
+
68
+ expect(URL.fromString(raw).toString()).toBe(raw);
69
+ });
70
+
71
+ test("keeps query parameters on a Telegram URL", () => {
72
+ const raw: string = `${TELEGRAM_URL}?chat_id=@mychannel&text=hello`;
73
+ const url: URL = URL.fromString(raw);
74
+
75
+ expect(url.route.toString()).toBe(`/bot${BOT_TOKEN}/sendMessage`);
76
+ expect(url.getQueryParam("chat_id")).toBe("@mychannel");
77
+ expect(url.getQueryParam("text")).toBe("hello");
78
+ expect(url.toString()).toBe(raw);
79
+ });
80
+
81
+ test("keeps the file download path, whose token is not the first segment", () => {
82
+ const raw: string = `https://api.telegram.org/file/bot${BOT_TOKEN}/photos/file_1.jpg`;
83
+
84
+ expect(URL.fromString(raw).toString()).toBe(raw);
85
+ });
86
+
87
+ test("fromStringLenient returns a real URL, not a malformed placeholder", () => {
88
+ const url: URL = URL.fromStringLenient(TELEGRAM_URL);
89
+
90
+ expect(url.isMalformed()).toBe(false);
91
+ expect(url.hostname.hostname).toBe("api.telegram.org");
92
+ expect(url.toString()).toBe(TELEGRAM_URL);
93
+ });
94
+
95
+ test("survives fromURL, toJSON and fromJSON", () => {
96
+ const url: URL = URL.fromString(TELEGRAM_URL);
97
+
98
+ expect(URL.fromURL(url).toString()).toBe(TELEGRAM_URL);
99
+
100
+ const revived: URL = URL.fromJSON(url.toJSON());
101
+ expect(revived.isMalformed()).toBe(false);
102
+ expect(revived.toString()).toBe(TELEGRAM_URL);
103
+ });
104
+
105
+ test("removeQueryString keeps the token path", () => {
106
+ const url: URL = URL.fromString(`${TELEGRAM_URL}?chat_id=1`);
107
+
108
+ expect(url.removeQueryString().toString()).toBe(TELEGRAM_URL);
109
+ });
110
+
111
+ test("addQueryParam appends to a Telegram URL", () => {
112
+ const url: URL = URL.fromString(TELEGRAM_URL).addQueryParam(
113
+ "chat_id",
114
+ "@my channel",
115
+ true,
116
+ );
117
+
118
+ expect(url.toString()).toBe(`${TELEGRAM_URL}?chat_id=%40my%20channel`);
119
+ });
120
+
121
+ test("getLastRoute reads the method and the token segment", () => {
122
+ const url: URL = URL.fromString(TELEGRAM_URL);
123
+
124
+ expect(url.getLastRoute()?.toString()).toBe("/sendMessage");
125
+ expect(url.getLastRoute(1)?.toString()).toBe(`/bot${BOT_TOKEN}`);
126
+ });
127
+ });
128
+
129
+ describe("URL.fromString - any first path segment containing a ':'", () => {
130
+ test.each([
131
+ ["an id:secret pair", "https://example.com/abc:def"],
132
+ ["a URN", "https://example.com/urn:uuid:6e8bc430-9c3a-11d9-9669"],
133
+ ["a trailing slash", "https://example.com/bot1:abc/"],
134
+ ["a single segment", "https://example.com/bot1:abc"],
135
+ ["a port", "https://example.com:8443/bot1:abc/sendMessage"],
136
+ ["userinfo", "https://user:pw@example.com/bot1:abc/sendMessage"],
137
+ ["plain http", "http://example.com/bot1:abc/sendMessage"],
138
+ ["a fragment", "https://example.com/bot1:abc/sendMessage#top"],
139
+ ["a query", "https://example.com/bot1:abc/sendMessage?a=1&b=2"],
140
+ ["a dotted scheme-like name", "https://example.com/a.b+c-d:e/f"],
141
+ ])("parses and round-trips a path with %s", (_label: string, raw: string) => {
142
+ const url: URL = URL.fromString(raw);
143
+
144
+ expect(url.toString()).toBe(raw);
145
+ });
146
+
147
+ test("an uppercase scheme on the URL is normalised, the path is kept", () => {
148
+ const url: URL = URL.fromString(
149
+ "HTTPS://api.telegram.org/bot1:abc/sendMessage",
150
+ );
151
+
152
+ expect(url.toString()).toBe(
153
+ "https://api.telegram.org/bot1:abc/sendMessage",
154
+ );
155
+ });
156
+
157
+ test("a path that merely looks like a dangerous scheme stays a path", () => {
158
+ /*
159
+ * Before Route refused scheme-like values this parsed to a route of
160
+ * "javascript:alert(1)" - a value that is a live href on its own. It now
161
+ * keeps its "/", so the Route is a same-origin path and can never be
162
+ * mistaken for a scheme by anything that renders it.
163
+ */
164
+ const url: URL = URL.fromString("https://example.com/javascript:alert(1)");
165
+ const route: string = url.route.toString();
166
+
167
+ expect(url.hostname.hostname).toBe("example.com");
168
+ expect(route).toBe("/javascript:alert(1)");
169
+ expect(route.startsWith("/")).toBe(true);
170
+ expect(Route.hasSchemePrefix(route)).toBe(false);
171
+ expect(url.toString()).toBe("https://example.com/javascript:alert(1)");
172
+ });
173
+
174
+ test.each([
175
+ "https://example.com/bot1:abc/sendMessage",
176
+ "https://example.com/mailto:someone@example.com",
177
+ "https://example.com/data:text/plain,hi",
178
+ "https://example.com/urn:isbn:0451450523",
179
+ ])("the route of %s is never itself scheme-like", (raw: string) => {
180
+ expect(Route.hasSchemePrefix(URL.fromString(raw).route.toString())).toBe(
181
+ false,
182
+ );
183
+ });
184
+
185
+ test("the host is still read off the authority, never off the path", () => {
186
+ // The ":" in the path must not be mistaken for a host:port separator.
187
+ const url: URL = URL.fromString("https://10.0.0.5/bot1:80/sendMessage");
188
+
189
+ expect(url.hostname.hostname).toBe("10.0.0.5");
190
+ expect(url.hostname.port).toBeUndefined();
191
+ });
192
+ });
193
+
194
+ describe("URL.fromString - paths that already parsed are unchanged", () => {
195
+ /*
196
+ * The leading "/" is only kept when dropping it would make the path read as
197
+ * a scheme. Every other path keeps the bare representation it always had,
198
+ * so nothing that read url.route before this change sees a different value.
199
+ */
200
+ test.each([
201
+ ["https://example.com/api/v1/items", "api/v1/items"],
202
+ ["https://example.com/docs#section", "docs#section"],
203
+ ["https://example.com#section", "#section"],
204
+ ["https://example.com/p/", "p/"],
205
+ ["https://vision.googleapis.com/v1/images:annotate", "v1/images:annotate"],
206
+ ["https://example.com/api/:resourceId", "api/:resourceId"],
207
+ ["https://example.com/1:2/x", "1:2/x"],
208
+ [
209
+ "https://example.com/_matrix/client/v3/rooms/!r:m.org",
210
+ "_matrix/client/v3/rooms/!r:m.org",
211
+ ],
212
+ ["https://example.com/:leading-colon", ":leading-colon"],
213
+ ["https://example.com/events?at=12:30", "events"],
214
+ ["https://example.com", ""],
215
+ ["https://example.com/", ""],
216
+ ])("%s keeps route %s", (raw: string, expectedRoute: string) => {
217
+ expect(URL.fromString(raw).route.toString()).toBe(expectedRoute);
218
+ });
219
+ });
220
+
221
+ describe("URL.fromString - '~' in a path", () => {
222
+ /*
223
+ * "~" is an RFC 3986 unreserved character, but Route's character allowlist
224
+ * left it out, so "https://example.com/~user" could not be parsed - and the
225
+ * sandboxed axios bridge refused it as "Request URL is not a valid URL".
226
+ */
227
+ test.each([
228
+ "https://example.com/~user/hook",
229
+ "https://example.com/files/~backup",
230
+ "https://example.com/a~b/c",
231
+ "https://example.com/path?x=~y",
232
+ ])("parses and round-trips %s", (raw: string) => {
233
+ expect(URL.fromString(raw).toString()).toBe(raw);
234
+ });
235
+ });
236
+
237
+ describe("URL.addRoute with a scheme-like segment", () => {
238
+ test("appends a string segment that starts with a token", () => {
239
+ const url: URL = URL.fromString("https://api.telegram.org").addRoute(
240
+ `bot${BOT_TOKEN}/sendMessage`,
241
+ );
242
+
243
+ expect(url.toString()).toBe(TELEGRAM_URL);
244
+ });
245
+
246
+ test("appends the same segment given with its leading slash", () => {
247
+ const url: URL = URL.fromString("https://api.telegram.org").addRoute(
248
+ `/bot${BOT_TOKEN}/sendMessage`,
249
+ );
250
+
251
+ expect(url.toString()).toBe(TELEGRAM_URL);
252
+ });
253
+
254
+ test("appends a method to a URL that already ends in the token", () => {
255
+ const url: URL = URL.fromString(
256
+ `https://api.telegram.org/bot${BOT_TOKEN}`,
257
+ ).addRoute("sendMessage");
258
+
259
+ expect(url.toString()).toBe(TELEGRAM_URL);
260
+ });
261
+
262
+ test("appends to a URL built from the constructor", () => {
263
+ const url: URL = new URL(
264
+ Protocol.HTTPS,
265
+ new Hostname("api.telegram.org"),
266
+ ).addRoute(`bot${BOT_TOKEN}/sendMessage`);
267
+
268
+ expect(url.toString()).toBe(TELEGRAM_URL);
269
+ });
270
+
271
+ test("still behaves as before for an ordinary segment", () => {
272
+ expect(
273
+ URL.fromString("https://example.com/api").addRoute("v1/items").toString(),
274
+ ).toBe("https://example.com/api/v1/items");
275
+ expect(
276
+ URL.fromString("https://example.com/api").addRoute("/v1").toString(),
277
+ ).toBe("https://example.com/api/v1");
278
+ });
279
+
280
+ test("still refuses characters no route may contain", () => {
281
+ expect(() => {
282
+ URL.fromString("https://example.com").addRoute("a b");
283
+ }).toThrowError(BadDataException);
284
+ });
285
+ });
286
+
287
+ describe("URL.fromString - the scheme checks are not loosened", () => {
288
+ test.each([
289
+ "javascript:alert(1)",
290
+ "data:text/html,<script>alert(1)</script>",
291
+ "file:///etc/passwd",
292
+ "ftp://example.com/bot1:abc/sendMessage",
293
+ ])("still refuses %s", (raw: string) => {
294
+ expect(() => {
295
+ return URL.fromString(raw);
296
+ }).toThrowError(BadDataException);
297
+ });
298
+
299
+ test("a bare scheme-like Route is still refused on its own", () => {
300
+ expect(() => {
301
+ return new Route(`bot${BOT_TOKEN}/sendMessage`);
302
+ }).toThrowError(BadDataException);
303
+ });
304
+ });