@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,214 @@
1
+ /** @timezone UTC */
2
+
3
+ import { afterEach, describe, expect, test } from "@jest/globals";
4
+ import "@testing-library/jest-dom";
5
+ import { cleanup, fireEvent, render, screen } from "@testing-library/react";
6
+ import * as React from "react";
7
+ import SecurityEvent from "../../../Models/AnalyticsModels/SecurityEvent";
8
+ import OcsfSeverity from "../../../Types/SecurityEvent/OcsfSeverity";
9
+ import getJestMockFunction, { MockFunction } from "../../MockType";
10
+ import SecurityEventListRow, {
11
+ SECURITY_EVENT_ROW_TEST_ID,
12
+ } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventListRow";
13
+ import { SECURITY_EVENT_VOLUME_COLORS } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventVolume";
14
+
15
+ /*
16
+ * One security event as a dense list row — the shape the logs and traces
17
+ * explorers use, rather than a grid of table cells.
18
+ *
19
+ * Line one is the read that has to work while scrolling: when, how bad, what
20
+ * class, what happened. Line two is the context a responder scans for, and
21
+ * every chip on it is labelled because `svc-deploy` and `web-01` are
22
+ * indistinguishable without one — a SIEM row that shows the wrong side of an
23
+ * interaction is worse than one that shows nothing.
24
+ */
25
+
26
+ function event(fields: Partial<SecurityEvent> = {}): SecurityEvent {
27
+ return Object.assign(new SecurityEvent(), fields);
28
+ }
29
+
30
+ function renderRow(
31
+ securityEvent: SecurityEvent,
32
+ props: { isSelected?: boolean; onClick?: () => void } = {},
33
+ ): void {
34
+ render(<SecurityEventListRow securityEvent={securityEvent} {...props} />);
35
+ }
36
+
37
+ function row(): HTMLElement {
38
+ return screen.getByTestId(SECURITY_EVENT_ROW_TEST_ID);
39
+ }
40
+
41
+ function severityDot(): HTMLElement {
42
+ const dot: Element | null = row().querySelector("span[aria-hidden='true']");
43
+
44
+ if (!dot) {
45
+ throw new Error("The row has no severity dot.");
46
+ }
47
+
48
+ return dot as HTMLElement;
49
+ }
50
+
51
+ afterEach(() => {
52
+ cleanup();
53
+ });
54
+
55
+ describe("what the row says", () => {
56
+ test("reads severity, class and message on one line", () => {
57
+ renderRow(
58
+ event({
59
+ time: new Date("2026-09-17T10:00:00.000Z"),
60
+ severityName: OcsfSeverity.Critical,
61
+ className: "Authentication",
62
+ message: "Failed logon for alice",
63
+ }),
64
+ );
65
+
66
+ expect(row()).toHaveTextContent("Critical");
67
+ expect(row()).toHaveTextContent("Authentication");
68
+ expect(row()).toHaveTextContent("Failed logon for alice");
69
+ });
70
+
71
+ test("only the first line of a multi-line message is shown", () => {
72
+ renderRow(
73
+ event({ message: "Failed logon\n at Authenticator.verify\n at ..." }),
74
+ );
75
+
76
+ expect(row()).toHaveTextContent("Failed logon");
77
+ expect(row()).not.toHaveTextContent("Authenticator.verify");
78
+ });
79
+
80
+ test("an event with no message says so rather than showing a blank line", () => {
81
+ renderRow(event({ className: "Authentication" }));
82
+
83
+ expect(row()).toHaveTextContent("No message recorded");
84
+ });
85
+
86
+ test("labels every identity chip, so the two sides of an interaction stay apart", () => {
87
+ renderRow(
88
+ event({
89
+ principalUser: "alice",
90
+ principalHost: "web-01",
91
+ principalIp: "10.0.0.4",
92
+ targetUser: "root",
93
+ targetHost: "db-01",
94
+ targetIp: "10.0.0.9",
95
+ statusName: "Failure",
96
+ ruleName: "BruteForce",
97
+ vendorName: "Acme",
98
+ }),
99
+ );
100
+
101
+ for (const [label, value] of [
102
+ ["user", "alice"],
103
+ ["host", "web-01"],
104
+ ["ip", "10.0.0.4"],
105
+ ["target user", "root"],
106
+ ["target host", "db-01"],
107
+ ["target ip", "10.0.0.9"],
108
+ ["status", "Failure"],
109
+ ["rule", "BruteForce"],
110
+ ["vendor", "Acme"],
111
+ ]) {
112
+ const labelNode: HTMLElement = screen.getByText(label as string);
113
+ expect(labelNode.parentElement).toHaveTextContent(value as string);
114
+ }
115
+ });
116
+
117
+ test("a field the source did not send gets no chip at all", () => {
118
+ renderRow(event({ principalUser: "alice" }));
119
+
120
+ expect(screen.getByText("user")).toBeInTheDocument();
121
+ expect(screen.queryByText("host")).toBeNull();
122
+ expect(screen.queryByText("target user")).toBeNull();
123
+ expect(screen.queryByText("rule")).toBeNull();
124
+ });
125
+
126
+ test("the time is shown, and an event with none renders without one", () => {
127
+ renderRow(event({ time: new Date("2026-09-17T10:00:00.000Z") }));
128
+
129
+ expect(row().textContent).toContain("2026");
130
+
131
+ cleanup();
132
+ renderRow(event({ message: "no time" }));
133
+
134
+ expect(row()).toHaveTextContent("no time");
135
+ });
136
+ });
137
+
138
+ describe("severity colour", () => {
139
+ test("uses the volume chart's palette, so a colour means one thing on the page", () => {
140
+ renderRow(event({ severityName: OcsfSeverity.Critical }));
141
+
142
+ expect(severityDot()).toHaveStyle({
143
+ backgroundColor: SECURITY_EVENT_VOLUME_COLORS[OcsfSeverity.Critical],
144
+ });
145
+ });
146
+
147
+ /*
148
+ * The column defaults to '' and pre-normalization rows exist. Anything that
149
+ * is not an OCSF name is read as Unknown — the same fallback the volume
150
+ * chart uses, so the chart's total always equals the number of rows listed.
151
+ */
152
+ test("an unrecognised or missing severity reads as Unknown", () => {
153
+ renderRow(event({ severityName: "" as OcsfSeverity }));
154
+
155
+ expect(row()).toHaveTextContent(OcsfSeverity.Unknown);
156
+ expect(severityDot()).toHaveStyle({
157
+ backgroundColor: SECURITY_EVENT_VOLUME_COLORS[OcsfSeverity.Unknown],
158
+ });
159
+
160
+ cleanup();
161
+ renderRow(event({ severityName: "SUPER-BAD" as OcsfSeverity }));
162
+
163
+ expect(row()).toHaveTextContent(OcsfSeverity.Unknown);
164
+ });
165
+
166
+ test.each([
167
+ OcsfSeverity.Fatal,
168
+ OcsfSeverity.Critical,
169
+ OcsfSeverity.High,
170
+ OcsfSeverity.Medium,
171
+ OcsfSeverity.Low,
172
+ OcsfSeverity.Informational,
173
+ OcsfSeverity.Other,
174
+ OcsfSeverity.Unknown,
175
+ ])("%s has its own colour", (severity: OcsfSeverity): void => {
176
+ renderRow(event({ severityName: severity }));
177
+
178
+ expect(severityDot()).toHaveStyle({
179
+ backgroundColor: SECURITY_EVENT_VOLUME_COLORS[severity],
180
+ });
181
+ });
182
+ });
183
+
184
+ describe("opening an event", () => {
185
+ test("the whole row is one button", () => {
186
+ renderRow(event({ message: "Failed logon" }));
187
+
188
+ expect(row().tagName).toBe("BUTTON");
189
+ expect(row()).toHaveAttribute("type", "button");
190
+ });
191
+
192
+ test("clicking it asks the page to open the event", () => {
193
+ const onClick: MockFunction = getJestMockFunction();
194
+
195
+ renderRow(event({ message: "Failed logon" }), {
196
+ onClick: onClick as unknown as () => void,
197
+ });
198
+
199
+ fireEvent.click(row());
200
+
201
+ expect(onClick).toHaveBeenCalledTimes(1);
202
+ });
203
+
204
+ test("the open event is marked, so the list says which one the drawer shows", () => {
205
+ renderRow(event({ message: "Failed logon" }), { isSelected: true });
206
+
207
+ expect(row()).toHaveAttribute("aria-pressed", "true");
208
+
209
+ cleanup();
210
+ renderRow(event({ message: "Failed logon" }));
211
+
212
+ expect(row()).not.toHaveAttribute("aria-pressed");
213
+ });
214
+ });
@@ -15,7 +15,7 @@ import {
15
15
  screen,
16
16
  within,
17
17
  } from "@testing-library/react";
18
- import React, { ReactElement } from "react";
18
+ import React from "react";
19
19
  import { MemoryRouter } from "react-router-dom";
20
20
  import getJestMockFunction, { MockFunction } from "../../MockType";
21
21
 
@@ -29,32 +29,8 @@ import getJestMockFunction, { MockFunction } from "../../MockType";
29
29
  * one line, and an outline button pinned to the left edge.
30
30
  */
31
31
 
32
- type CapturedTableProps = {
33
- id?: string;
34
- noItemsMessage?: ReactElement;
35
- showRefreshButton?: boolean;
36
- query?: Record<string, unknown>;
37
- };
38
-
39
- let capturedTableProps: CapturedTableProps | null = null;
40
32
  const navigateMock: MockFunction = getJestMockFunction();
41
33
 
42
- jest.mock("../../../UI/Components/ModelTable/AnalyticsModelTable", () => {
43
- return {
44
- __esModule: true,
45
- default: (props: CapturedTableProps): ReactElement => {
46
- capturedTableProps = props;
47
- const react: typeof React = jest.requireActual("react") as typeof React;
48
-
49
- return react.createElement(
50
- "div",
51
- { "data-testid": "security-events-analytics-table" },
52
- props.noItemsMessage || null,
53
- );
54
- },
55
- };
56
- });
57
-
58
34
  jest.mock("../../../UI/Utils/Navigation", () => {
59
35
  return {
60
36
  __esModule: true,
@@ -78,7 +54,6 @@ jest.mock("../../../UI/Utils/Navigation", () => {
78
54
  import SecurityEventsEmptyState, {
79
55
  SECURITY_EVENTS_EMPTY_STATE_ID,
80
56
  } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventsEmptyState";
81
- import SecurityEventsTable from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventsTable";
82
57
  import PageMap from "../../../../App/FeatureSet/Dashboard/src/Utils/PageMap";
83
58
  import RouteMap, {
84
59
  RouteUtil,
@@ -114,7 +89,6 @@ function navigatedTo(): Array<string> {
114
89
  }
115
90
 
116
91
  beforeEach((): void => {
117
- capturedTableProps = null;
118
92
  navigateMock.mockReset();
119
93
  jest.spyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(PROJECT_ID);
120
94
  });
@@ -249,59 +223,3 @@ describe("SecurityEventsEmptyState", () => {
249
223
  expect(navigateMock).not.toHaveBeenCalled();
250
224
  });
251
225
  });
252
-
253
- describe("SecurityEventsTable empty state wiring", () => {
254
- test("hands the table the Security Events empty state by default", () => {
255
- render(
256
- <MemoryRouter>
257
- <SecurityEventsTable query={{ projectId: PROJECT_ID }} />
258
- </MemoryRouter>,
259
- );
260
-
261
- expect(capturedTableProps).not.toBeNull();
262
- expect(capturedTableProps?.id).toBe("security-events-table");
263
- expect(capturedTableProps?.query).toEqual({ projectId: PROJECT_ID });
264
- /*
265
- * The page's Refresh re-reads a relative window from now and recounts
266
- * the volume chart; the table's own could only re-list its old window.
267
- */
268
- expect(capturedTableProps?.showRefreshButton).toBe(false);
269
- expect(capturedTableProps?.noItemsMessage?.type).toBe(
270
- SecurityEventsEmptyState,
271
- );
272
-
273
- const table: HTMLElement = screen.getByTestId(
274
- "security-events-analytics-table",
275
- );
276
- expect(
277
- within(table).getByRole("heading", { name: "No security events yet" }),
278
- ).toBeInTheDocument();
279
- expect(
280
- within(table).getByRole("button", { name: "Read the setup guide" }),
281
- ).toBeInTheDocument();
282
- expect(
283
- within(table).getByRole("button", {
284
- name: "Connect a security product",
285
- }),
286
- ).toBeInTheDocument();
287
- });
288
-
289
- test("a page that knows events exist can swap in its own message", () => {
290
- render(
291
- <MemoryRouter>
292
- <SecurityEventsTable
293
- query={{ projectId: PROJECT_ID }}
294
- noItemsMessage={<p>Nothing in this window</p>}
295
- />
296
- </MemoryRouter>,
297
- );
298
-
299
- const table: HTMLElement = screen.getByTestId(
300
- "security-events-analytics-table",
301
- );
302
- expect(within(table).getByText("Nothing in this window")).toBeVisible();
303
- expect(
304
- within(table).queryByRole("heading", { name: "No security events yet" }),
305
- ).toBeNull();
306
- });
307
- });
@@ -0,0 +1,248 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
2
+ import "@testing-library/jest-dom";
3
+ import { act, cleanup, render } from "@testing-library/react";
4
+ import * as React from "react";
5
+ import { MemoryRouter } from "react-router-dom";
6
+ import SecurityEventsNavTabs from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventsNavTabs";
7
+ import { getSecurityEventsBreadcrumbs } from "../../../../App/FeatureSet/Dashboard/src/Utils/Breadcrumbs/SecurityEventsBreadcrumbs";
8
+ import PageMap from "../../../../App/FeatureSet/Dashboard/src/Utils/PageMap";
9
+ import { RouteUtil } from "../../../../App/FeatureSet/Dashboard/src/Utils/RouteMap";
10
+ import {
11
+ SecurityEventsTabKey,
12
+ getActiveSecurityEventsTab,
13
+ } from "../../../../App/FeatureSet/Dashboard/src/Utils/SecurityEventsNavigation";
14
+ import { writeTelemetryViewerUrlState } from "../../../../App/FeatureSet/Dashboard/src/Utils/TelemetryViewerUrlState";
15
+ import Link from "../../../Types/Link";
16
+ import { goTo, PROJECT_ID, routeFor } from "./SideMenuHarness";
17
+
18
+ /*
19
+ * The Security Events destinations, as header tabs.
20
+ *
21
+ * They used to be a left side menu, which put this product out of step with
22
+ * every other telemetry signal — Logs, Traces, Metrics and Exceptions all
23
+ * carry theirs in the page header through the same shared TelemetryNavTabs.
24
+ * What is pinned here is what the move must not lose: every destination still
25
+ * reachable exactly once, the tab you are on highlighted, the labels still
26
+ * matching their breadcrumb leaves, and the Events tab carrying the slice the
27
+ * reader is looking at so switching away and back does not silently reset it.
28
+ */
29
+
30
+ interface ExpectedTab {
31
+ label: string;
32
+ pageMapKey: string;
33
+ tab: SecurityEventsTabKey;
34
+ }
35
+
36
+ const EXPECTED_TABS: Array<ExpectedTab> = [
37
+ { label: "Events", pageMapKey: PageMap.SECURITY_EVENTS, tab: "events" },
38
+ {
39
+ label: "Correlate",
40
+ pageMapKey: PageMap.SECURITY_EVENTS_CORRELATE,
41
+ tab: "correlate",
42
+ },
43
+ {
44
+ label: "Detection Rules",
45
+ pageMapKey: PageMap.SECURITY_EVENTS_DETECTION_RULES,
46
+ tab: "detection-rules",
47
+ },
48
+ {
49
+ label: "Threat Intel",
50
+ pageMapKey: PageMap.SECURITY_EVENTS_THREAT_INTEL,
51
+ tab: "threat-intel",
52
+ },
53
+ {
54
+ label: "Monitors",
55
+ pageMapKey: PageMap.SECURITY_EVENTS_MONITORS,
56
+ tab: "monitors",
57
+ },
58
+ {
59
+ label: "Connections",
60
+ pageMapKey: PageMap.SECURITY_EVENTS_CONNECTIONS,
61
+ tab: "connections",
62
+ },
63
+ {
64
+ label: "Setup Guide",
65
+ pageMapKey: PageMap.SECURITY_EVENTS_DOCUMENTATION,
66
+ tab: "setup",
67
+ },
68
+ ];
69
+
70
+ function renderTabs(active: SecurityEventsTabKey): void {
71
+ render(
72
+ <MemoryRouter>
73
+ <SecurityEventsNavTabs active={active} />
74
+ </MemoryRouter>,
75
+ );
76
+ }
77
+
78
+ function anchors(): Array<HTMLAnchorElement> {
79
+ return Array.from(document.querySelectorAll("a"));
80
+ }
81
+
82
+ function labels(): Array<string> {
83
+ return anchors().map((anchor: HTMLAnchorElement): string => {
84
+ return anchor.textContent?.trim() ?? "";
85
+ });
86
+ }
87
+
88
+ function hrefs(): Array<string> {
89
+ return anchors().map((anchor: HTMLAnchorElement): string => {
90
+ return anchor.getAttribute("href") ?? "";
91
+ });
92
+ }
93
+
94
+ function anchorFor(label: string): HTMLAnchorElement {
95
+ const anchor: HTMLAnchorElement | undefined = anchors().find(
96
+ (candidate: HTMLAnchorElement): boolean => {
97
+ return candidate.textContent?.trim() === label;
98
+ },
99
+ );
100
+
101
+ if (!anchor) {
102
+ throw new Error(
103
+ `No tab labelled "${label}". Tabs rendered: ${labels().join(", ")}`,
104
+ );
105
+ }
106
+
107
+ return anchor;
108
+ }
109
+
110
+ beforeEach(() => {
111
+ goTo(`/dashboard/${PROJECT_ID}/security-events`);
112
+ });
113
+
114
+ afterEach(() => {
115
+ cleanup();
116
+ });
117
+
118
+ describe("Security Events header tabs", () => {
119
+ test("every destination is a tab, in the intended order", () => {
120
+ renderTabs("events");
121
+
122
+ expect(labels()).toEqual(
123
+ EXPECTED_TABS.map((tab: ExpectedTab): string => {
124
+ return tab.label;
125
+ }),
126
+ );
127
+ });
128
+
129
+ test("keeps all seven routes reachable exactly once, with icons", () => {
130
+ renderTabs("events");
131
+
132
+ const expectedHrefs: Array<string> = EXPECTED_TABS.map(
133
+ (tab: ExpectedTab): string => {
134
+ return routeFor(tab.pageMapKey);
135
+ },
136
+ );
137
+
138
+ expect(anchors()).toHaveLength(7);
139
+ expect(hrefs()).toEqual(expectedHrefs);
140
+ expect(new Set(hrefs()).size).toBe(hrefs().length);
141
+ expect(new Set(labels()).size).toBe(labels().length);
142
+
143
+ for (const anchor of anchors()) {
144
+ expect(anchor.querySelector("svg")).not.toBeNull();
145
+ }
146
+ });
147
+
148
+ /*
149
+ * A ":projectId" left in an href is the classic failure of these menus: the
150
+ * link renders, reads correctly, and navigates to a page that cannot load.
151
+ */
152
+ test("every href is resolved against the current project", () => {
153
+ renderTabs("events");
154
+
155
+ for (const href of hrefs()) {
156
+ expect(href.startsWith(`/dashboard/${PROJECT_ID}/`)).toBe(true);
157
+ expect(href).not.toContain(":projectId");
158
+ }
159
+ });
160
+
161
+ test.each(EXPECTED_TABS)(
162
+ "$label is the highlighted tab when it is the active one",
163
+ (tab: ExpectedTab): void => {
164
+ renderTabs(tab.tab);
165
+
166
+ const anchor: HTMLAnchorElement = anchorFor(tab.label);
167
+
168
+ expect(anchor).toHaveClass("bg-indigo-50");
169
+ expect(anchor).toHaveClass("text-indigo-700");
170
+ expect(
171
+ Array.from(document.querySelectorAll("a.bg-indigo-50")),
172
+ ).toHaveLength(1);
173
+ },
174
+ );
175
+
176
+ test.each(EXPECTED_TABS)(
177
+ "the route of $label resolves back to its own tab",
178
+ (tab: ExpectedTab): void => {
179
+ expect(getActiveSecurityEventsTab(routeFor(tab.pageMapKey))).toBe(
180
+ tab.tab,
181
+ );
182
+ },
183
+ );
184
+
185
+ test("every tab label matches its breadcrumb leaf", () => {
186
+ for (const tab of EXPECTED_TABS) {
187
+ const trail: Array<Link> | undefined = getSecurityEventsBreadcrumbs(
188
+ RouteUtil.getRouteString(tab.pageMapKey as never),
189
+ );
190
+
191
+ expect(trail).toBeDefined();
192
+ expect(trail?.[trail.length - 1]?.title).toBe(
193
+ tab.pageMapKey === PageMap.SECURITY_EVENTS
194
+ ? "Security Events"
195
+ : tab.label,
196
+ );
197
+ }
198
+ });
199
+ });
200
+
201
+ describe("the Events tab carries the slice the reader is looking at", () => {
202
+ /*
203
+ * Only the Events tab is backed by an explorer, so it is the only tab whose
204
+ * link can describe a slice. Handing a `filters` payload to Detection Rules
205
+ * or Connections would put params on a URL nothing there reads — and
206
+ * re-emit them on the way back as if the user had set them there.
207
+ */
208
+ test("carries the window and chips onto the Events link, and onto no other", () => {
209
+ goTo(`/dashboard/${PROJECT_ID}/security-events/correlate`);
210
+
211
+ act(() => {
212
+ writeTelemetryViewerUrlState({
213
+ range: "PAST_ONE_WEEK",
214
+ filters: JSON.stringify([["severityName", "Critical"]]),
215
+ search: "failed logon",
216
+ });
217
+ });
218
+
219
+ renderTabs("correlate");
220
+
221
+ const eventsHref: string = anchorFor("Events").getAttribute("href") ?? "";
222
+ const params: URLSearchParams = new URLSearchParams(
223
+ eventsHref.slice(eventsHref.indexOf("?")),
224
+ );
225
+
226
+ expect(params.get("range")).toBe("PAST_ONE_WEEK");
227
+ expect(JSON.parse(params.get("filters") as string)).toEqual([
228
+ ["severityName", "Critical"],
229
+ ]);
230
+ expect(params.get("search")).toBe("failed logon");
231
+
232
+ for (const label of ["Correlate", "Detection Rules", "Connections"]) {
233
+ expect(anchorFor(label).getAttribute("href")).not.toContain("?");
234
+ }
235
+ });
236
+
237
+ test("an unscoped page leaves every href bare", () => {
238
+ act(() => {
239
+ writeTelemetryViewerUrlState({});
240
+ });
241
+
242
+ renderTabs("events");
243
+
244
+ for (const href of hrefs()) {
245
+ expect(href).not.toContain("?");
246
+ }
247
+ });
248
+ });