@oneuptime/common 13.0.7 → 13.0.8

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 (463) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +1 -1
  2. package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +1 -1
  3. package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +1 -1
  4. package/Server/API/AIBillingAPI.ts +1 -0
  5. package/Server/API/AIInsightAPI.ts +1 -4
  6. package/Server/API/AIInvestigationAPI.ts +1 -4
  7. package/Server/API/AIReadinessAPI.ts +4 -5
  8. package/Server/API/AlertAPI.ts +1 -0
  9. package/Server/API/AutoRemediationAPI.ts +1 -4
  10. package/Server/API/BaseAPI.ts +13 -0
  11. package/Server/API/BaseAnalyticsAPI.ts +80 -9
  12. package/Server/API/BillingAPI.ts +2 -0
  13. package/Server/API/BillingInvoiceAPI.ts +1 -0
  14. package/Server/API/BillingPaymentMethodAPI.ts +2 -0
  15. package/Server/API/CodeFixRunAPI.ts +1 -3
  16. package/Server/API/CommonAPI.ts +68 -4
  17. package/Server/API/DashboardAPI.ts +12 -12
  18. package/Server/API/GlobalConfigAPI.ts +17 -0
  19. package/Server/API/IncidentAPI.ts +2 -0
  20. package/Server/API/IncidentEpisodeAPI.ts +1 -0
  21. package/Server/API/NotificationAPI.ts +1 -0
  22. package/Server/API/OnCallCalendarAPI.ts +4 -5
  23. package/Server/API/OnCallDutyPolicyAPI.ts +7 -0
  24. package/Server/API/OnCallReadinessAPI.ts +4 -1
  25. package/Server/API/OnCallScheduleTimelineAPI.ts +731 -0
  26. package/Server/API/ProjectAPI.ts +1 -0
  27. package/Server/API/ScheduledMaintenanceAPI.ts +1 -0
  28. package/Server/API/StatusPageAPI.ts +161 -32
  29. package/Server/API/TeamMemberAPI.ts +3 -0
  30. package/Server/API/UserCallAPI.ts +2 -0
  31. package/Server/API/UserEmailAPI.ts +2 -0
  32. package/Server/API/UserIncomingCallNumberAPI.ts +2 -0
  33. package/Server/API/UserMicrosoftTeamsAPI.ts +1 -0
  34. package/Server/API/UserSlackAPI.ts +1 -0
  35. package/Server/API/UserSmsAPI.ts +2 -0
  36. package/Server/API/UserTotpAuthAPI.ts +1 -0
  37. package/Server/API/UserWebAuthnAPI.ts +2 -0
  38. package/Server/API/UserWebhookAPI.ts +1 -0
  39. package/Server/API/UserWhatsAppAPI.ts +2 -0
  40. package/Server/Middleware/MasterAdminAuthorization.ts +13 -2
  41. package/Server/Middleware/UserAuthorization.ts +79 -5
  42. package/Server/Services/ApiKeyPermissionService.ts +101 -4
  43. package/Server/Services/DatabaseService.ts +245 -0
  44. package/Server/Services/DetectionRuleService.ts +5 -4
  45. package/Server/Services/OnCallDutyPolicyChildService.ts +261 -0
  46. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -2
  47. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -2
  48. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -2
  49. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -2
  50. package/Server/Services/PayAsYouGoBillingService.ts +23 -28
  51. package/Server/Services/ProjectService.ts +18 -0
  52. package/Server/Services/RumSessionPinService.ts +274 -22
  53. package/Server/Services/TeamPermissionService.ts +120 -26
  54. package/Server/Services/ThreatIntelFeedService.ts +6 -3
  55. package/Server/Types/Database/Permissions/BasePermission.ts +9 -7
  56. package/Server/Types/Database/Permissions/Index.ts +75 -11
  57. package/Server/Types/Database/Permissions/TablePermission.ts +24 -28
  58. package/Server/Utils/AI/AIChatPrivacyFilter.ts +8 -0
  59. package/Server/Utils/AI/AIRunPrivacyFilter.ts +8 -0
  60. package/Server/Utils/MasterAdminPageAccess.ts +61 -0
  61. package/Server/Utils/Monitor/MonitorAlert.ts +3 -1
  62. package/Server/Utils/Monitor/MonitorIncident.ts +3 -1
  63. package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1 -1
  64. package/Server/Utils/Realtime.ts +163 -45
  65. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +11 -28
  66. package/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.ts +170 -0
  67. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +1 -1
  68. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +6 -2
  69. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.ts +10 -9
  70. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +1059 -0
  71. package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +376 -0
  72. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +757 -0
  73. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +307 -0
  74. package/Tests/App/Dashboard/ArgumentsFormGroupByUnlistedAttributes.test.tsx +131 -0
  75. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +1 -1
  76. package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +9 -1
  77. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +24 -0
  78. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +162 -8
  79. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +105 -6
  80. package/Tests/App/Dashboard/EntityFilterDropdownUnlistedSelection.test.tsx +434 -0
  81. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +276 -1
  82. package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +9 -1
  83. package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +58 -42
  84. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +42 -5
  85. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +34 -23
  86. package/Tests/App/Dashboard/ScheduleTimeline.test.tsx +1580 -0
  87. package/Tests/App/Dashboard/ScheduleTimelineAPI.test.ts +280 -0
  88. package/Tests/App/Dashboard/ScheduleTimelineModel.test.ts +673 -0
  89. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +95 -68
  90. package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +86 -3
  91. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +28 -3
  92. package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +761 -0
  93. package/Tests/App/Dashboard/SecurityEventsGuideContent.test.ts +1313 -0
  94. package/Tests/App/Dashboard/SecurityEventsHowItWorksCard.test.tsx +536 -0
  95. package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +222 -0
  96. package/Tests/App/Dashboard/SecurityEventsThreatIntelPage.test.tsx +199 -0
  97. package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +321 -0
  98. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +171 -36
  99. package/Tests/App/Dashboard/SloViewSideMenu.test.tsx +215 -0
  100. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +40 -3
  101. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +12 -4
  102. package/Tests/App/PublicDashboard/PublicDashboardWidgetListAuth.test.tsx +623 -0
  103. package/Tests/Models/OnCallCalendarFeedModels.test.ts +23 -1
  104. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +138 -5
  105. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +187 -0
  106. package/Tests/Server/API/AIInvestigationAvailabilityAuthorization.test.ts +51 -3
  107. package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +55 -2
  108. package/Tests/Server/API/BaseAnalyticsAPIAggregateCache.test.ts +729 -0
  109. package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +93 -7
  110. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +36 -3
  111. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +1003 -24
  112. package/Tests/Server/API/DashboardPublicRateLimit.test.ts +6 -3
  113. package/Tests/Server/API/ExpiredSessionAIRoutes.test.ts +708 -0
  114. package/Tests/Server/API/ExpiredSessionCustomRoutes.test.ts +928 -0
  115. package/Tests/Server/API/ExpiredSessionMonitorTemplate.test.ts +319 -0
  116. package/Tests/Server/API/ExpiredSessionOnCallDutyPolicy.test.ts +336 -0
  117. package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +820 -0
  118. package/Tests/Server/API/GlobalConfigLicense.test.ts +140 -0
  119. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +115 -12
  120. package/Tests/Server/API/OnCallCalendarAPI.test.ts +375 -8
  121. package/Tests/Server/API/OnCallReadinessAPI.test.ts +175 -17
  122. package/Tests/Server/API/OnCallScheduleTimelineAPI.test.ts +1513 -0
  123. package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +119 -7
  124. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +111 -4
  125. package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +615 -0
  126. package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +89 -2
  127. package/Tests/Server/API/SessionReplayAPI.test.ts +121 -0
  128. package/Tests/Server/API/StatusPageMasterPasswordRateLimit.test.ts +4 -2
  129. package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +441 -0
  130. package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +664 -0
  131. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +7 -0
  132. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +6 -0
  133. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +65 -4
  134. package/Tests/Server/API/UserProjectsAPI.test.ts +63 -3
  135. package/Tests/Server/API/UserTotpAuthAPI.test.ts +48 -2
  136. package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +11 -2
  137. package/Tests/Server/API/UserWebAuthnBackupCodeMinting.test.ts +46 -3
  138. package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +18 -2
  139. package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +24 -7
  140. package/Tests/Server/Middleware/ExpiredSessionUserMiddleware.test.ts +563 -0
  141. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +299 -19
  142. package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +453 -0
  143. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +24 -0
  144. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +2 -0
  145. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +3 -3
  146. package/Tests/Server/Services/DatabaseServiceCreateSuppliedId.test.ts +147 -0
  147. package/Tests/Server/Services/DatabaseServiceLoginBeforeHooks.test.ts +1078 -0
  148. package/Tests/Server/Services/DatabaseServiceTenantRelationGuard.test.ts +259 -0
  149. package/Tests/Server/Services/DatabaseServiceWriteOperatorValues.test.ts +147 -0
  150. package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +115 -1
  151. package/Tests/Server/Services/OnCallChildCreateAuthorizationPostgres.test.ts +711 -0
  152. package/Tests/Server/Services/OnCallDutyPolicyChildService.test.ts +733 -0
  153. package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +190 -140
  154. package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +4 -9
  155. package/Tests/Server/Services/PermissionBlockDeletion.test.ts +780 -0
  156. package/Tests/Server/Services/PermissionBlockDeletionPostgres.test.ts +628 -0
  157. package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +77 -1
  158. package/Tests/Server/Services/RumSessionPinCreatePermission.test.ts +715 -0
  159. package/Tests/Server/Services/TeamMemberMultiTenantReadPostgres.test.ts +394 -0
  160. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +6 -0
  161. package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +131 -0
  162. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +13 -2
  163. package/Tests/Server/Types/Database/Permissions/ModelPermissionAnonymousRefusal.test.ts +518 -0
  164. package/Tests/Server/Types/Database/Permissions/MultiTenantPermissions.test.ts +350 -0
  165. package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +282 -25
  166. package/Tests/Server/Types/Database/Permissions/TableLevelBlockPermission.test.ts +459 -0
  167. package/Tests/Server/Utils/AI/AIRunPrivacyFilter.test.ts +101 -9
  168. package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +88 -4
  169. package/Tests/Server/Utils/AI/Toolbox/ExceptionTools.test.ts +459 -0
  170. package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +794 -0
  171. package/Tests/Server/Utils/AI/Toolbox/RecentChangesTools.test.ts +574 -0
  172. package/Tests/Server/Utils/AI/Toolbox/SecurityEventTools.test.ts +596 -0
  173. package/Tests/Server/Utils/CaptchaRequestAndLogging.test.ts +395 -0
  174. package/Tests/Server/Utils/MasterAdminPageAccess.test.ts +251 -0
  175. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +616 -0
  176. package/Tests/Server/Utils/Realtime.test.ts +502 -0
  177. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorSeverity.test.ts +216 -0
  178. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +142 -0
  179. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.test.ts +140 -0
  180. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepairClickhouseIntegration.test.ts +542 -0
  181. package/Tests/Server/Utils/Telemetry/ChangeEventRow.test.ts +743 -0
  182. package/Tests/Server/Utils/Telemetry/RuntimeMetrics.test.ts +465 -0
  183. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.test.ts +202 -0
  184. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.test.ts +194 -0
  185. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.test.ts +231 -0
  186. package/Tests/Server/Utils/Workspace/Slack/Messages/Alert.test.ts +194 -0
  187. package/Tests/Server/Utils/Workspace/Slack/Messages/AlertEpisode.test.ts +194 -0
  188. package/Tests/Server/Utils/Workspace/Slack/Messages/Incident.test.ts +194 -0
  189. package/Tests/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.test.ts +194 -0
  190. package/Tests/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.test.ts +247 -0
  191. package/Tests/Types/AI/AIInsightEvidence.test.ts +206 -0
  192. package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtilAnonymous.test.ts +144 -0
  193. package/Tests/Types/Call/CallProvider.test.ts +528 -0
  194. package/Tests/Types/Kubernetes/KubernetesCostIngest.test.ts +236 -0
  195. package/Tests/Types/OnCallDutyPolicy/ScheduleTimeline.test.ts +736 -0
  196. package/Tests/Types/OnCallDutyPolicy/ScheduleTimelineLayout.test.ts +996 -0
  197. package/Tests/Types/SecurityEvent/SigmaRule.test.ts +142 -0
  198. package/Tests/Types/Workflow/Components/JSON.test.ts +182 -0
  199. package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +116 -1
  200. package/Tests/UI/Components/Dropdown/DropdownAsyncOptions.test.tsx +81 -0
  201. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +89 -1
  202. package/Tests/UI/Components/EventAttachmentList.test.tsx +174 -0
  203. package/Tests/UI/Components/Forms/BasicFormBurnRateTemplateDefaults.test.tsx +395 -0
  204. package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +286 -0
  205. package/Tests/UI/Components/Forms/FormSummary.test.tsx +128 -0
  206. package/Tests/UI/Components/ModelTable/BaseModelTableQueryChange.test.tsx +365 -0
  207. package/Tests/UI/Components/OpenAuthenticatedUrl.test.ts +358 -0
  208. package/Tests/UI/Components/SessionAwareImage.test.tsx +496 -0
  209. package/Tests/UI/Components/TelemetryHistogramZeroBuckets.test.tsx +190 -0
  210. package/Tests/UI/Components/TooltipInteractive.test.tsx +97 -0
  211. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardInstallGuidance.test.tsx +1 -1
  212. package/Tests/UI/Monitor/EvaluationLogListTimestamps.test.tsx +367 -0
  213. package/Tests/UI/Utils/API/BaseAPIRefreshSession.test.ts +1087 -0
  214. package/Tests/UI/Utils/API/DashboardHost.ts +12 -0
  215. package/Tests/UI/Utils/API/FakeAxiosServer.ts +183 -0
  216. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  217. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  218. package/Tests/UI/Utils/Cookie.test.ts +440 -0
  219. package/Tests/UI/Utils/ModelAPIRequestClient.test.ts +278 -0
  220. package/Tests/UI/Utils/Navigation.test.ts +33 -0
  221. package/Tests/UI/Utils/PricingPlan.test.ts +295 -0
  222. package/Tests/UI/Utils/Realtime.test.ts +759 -0
  223. package/Tests/UI/Utils/Telemetry/Telemetry.test.ts +500 -0
  224. package/Tests/Utils/APIInstanceDispatch.test.ts +311 -0
  225. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizerSeverity.test.ts +565 -0
  226. package/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.ts +40 -0
  227. package/Types/Monitor/MonitorEvaluationSummary.ts +3 -0
  228. package/Types/OnCallDutyPolicy/ScheduleTimeline.ts +507 -0
  229. package/Types/OnCallDutyPolicy/ScheduleTimelineLayout.ts +589 -0
  230. package/Types/Realtime/EventName.ts +11 -0
  231. package/Types/SecurityEvent/DetectionFindingConstants.ts +14 -0
  232. package/Types/SecurityEvent/OcsfSeverity.ts +31 -26
  233. package/Types/SecurityEvent/SigmaRule.ts +51 -0
  234. package/Types/SecurityEvent/ThreatIntelConstants.ts +18 -0
  235. package/UI/Components/AttachmentList/EventAttachmentList.tsx +30 -2
  236. package/UI/Components/Dashboard/DashboardVariableControl.tsx +12 -2
  237. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  238. package/UI/Components/EditionLabel/EditionLabel.tsx +12 -0
  239. package/UI/Components/EventItem/EventItem.tsx +12 -1
  240. package/UI/Components/Forms/BasicForm.tsx +151 -126
  241. package/UI/Components/Forms/CollapsibleFormSection.tsx +63 -0
  242. package/UI/Components/Forms/Fields/FormField.tsx +10 -4
  243. package/UI/Components/Forms/FormSummary.tsx +7 -0
  244. package/UI/Components/Forms/Types/Field.ts +10 -0
  245. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +2 -1
  246. package/UI/Components/Markdown.tsx/SessionAwareImage.tsx +122 -0
  247. package/UI/Components/ModelTable/BaseModelTable.tsx +34 -5
  248. package/UI/Components/ModelTable/TableView.tsx +1 -1
  249. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +8 -1
  250. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  251. package/UI/Utils/API/API.ts +173 -12
  252. package/UI/Utils/API/RequestOptions.ts +11 -0
  253. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +31 -7
  254. package/UI/Utils/ModelAPI/ModelAPI.ts +30 -9
  255. package/UI/Utils/Navigation.ts +9 -0
  256. package/UI/Utils/OpenAuthenticatedUrl.ts +154 -0
  257. package/UI/Utils/Realtime.ts +176 -30
  258. package/Utils/API.ts +14 -5
  259. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +157 -7
  260. package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +9 -17
  261. package/Utils/Slo/SloBurnRateTemplate.ts +2 -2
  262. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +1 -1
  263. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -1
  264. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +1 -1
  265. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -1
  266. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +1 -1
  267. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -1
  268. package/build/dist/Server/API/AIBillingAPI.js +1 -1
  269. package/build/dist/Server/API/AIBillingAPI.js.map +1 -1
  270. package/build/dist/Server/API/AIInsightAPI.js +1 -4
  271. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  272. package/build/dist/Server/API/AIInvestigationAPI.js +1 -4
  273. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  274. package/build/dist/Server/API/AIReadinessAPI.js +1 -3
  275. package/build/dist/Server/API/AIReadinessAPI.js.map +1 -1
  276. package/build/dist/Server/API/AlertAPI.js +1 -1
  277. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  278. package/build/dist/Server/API/AutoRemediationAPI.js +1 -4
  279. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  280. package/build/dist/Server/API/BaseAPI.js +12 -0
  281. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  282. package/build/dist/Server/API/BaseAnalyticsAPI.js +55 -10
  283. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  284. package/build/dist/Server/API/BillingAPI.js +2 -2
  285. package/build/dist/Server/API/BillingAPI.js.map +1 -1
  286. package/build/dist/Server/API/BillingInvoiceAPI.js +1 -1
  287. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  288. package/build/dist/Server/API/BillingPaymentMethodAPI.js +2 -2
  289. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  290. package/build/dist/Server/API/CodeFixRunAPI.js +1 -3
  291. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
  292. package/build/dist/Server/API/CommonAPI.js +50 -5
  293. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  294. package/build/dist/Server/API/DashboardAPI.js +12 -12
  295. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  296. package/build/dist/Server/API/GlobalConfigAPI.js +12 -0
  297. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  298. package/build/dist/Server/API/IncidentAPI.js +2 -2
  299. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  300. package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
  301. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  302. package/build/dist/Server/API/NotificationAPI.js +1 -1
  303. package/build/dist/Server/API/NotificationAPI.js.map +1 -1
  304. package/build/dist/Server/API/OnCallCalendarAPI.js +1 -4
  305. package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -1
  306. package/build/dist/Server/API/OnCallDutyPolicyAPI.js +6 -0
  307. package/build/dist/Server/API/OnCallDutyPolicyAPI.js.map +1 -1
  308. package/build/dist/Server/API/OnCallReadinessAPI.js +4 -1
  309. package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -1
  310. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +494 -0
  311. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -0
  312. package/build/dist/Server/API/ProjectAPI.js +1 -1
  313. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  314. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
  315. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  316. package/build/dist/Server/API/StatusPageAPI.js +125 -33
  317. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  318. package/build/dist/Server/API/TeamMemberAPI.js +3 -3
  319. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  320. package/build/dist/Server/API/UserCallAPI.js +2 -2
  321. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  322. package/build/dist/Server/API/UserEmailAPI.js +2 -2
  323. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  324. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +2 -2
  325. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  326. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +1 -1
  327. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -1
  328. package/build/dist/Server/API/UserSlackAPI.js +1 -1
  329. package/build/dist/Server/API/UserSlackAPI.js.map +1 -1
  330. package/build/dist/Server/API/UserSmsAPI.js +2 -2
  331. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  332. package/build/dist/Server/API/UserTotpAuthAPI.js +1 -1
  333. package/build/dist/Server/API/UserTotpAuthAPI.js.map +1 -1
  334. package/build/dist/Server/API/UserWebAuthnAPI.js +2 -2
  335. package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
  336. package/build/dist/Server/API/UserWebhookAPI.js +1 -1
  337. package/build/dist/Server/API/UserWebhookAPI.js.map +1 -1
  338. package/build/dist/Server/API/UserWhatsAppAPI.js +2 -2
  339. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  340. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -2
  341. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  342. package/build/dist/Server/Middleware/UserAuthorization.js +64 -4
  343. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  344. package/build/dist/Server/Services/ApiKeyPermissionService.js +80 -4
  345. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  346. package/build/dist/Server/Services/DatabaseService.js +171 -0
  347. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  348. package/build/dist/Server/Services/DetectionRuleService.js +4 -4
  349. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
  350. package/build/dist/Server/Services/OnCallDutyPolicyChildService.js +170 -0
  351. package/build/dist/Server/Services/OnCallDutyPolicyChildService.js.map +1 -0
  352. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -2
  353. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  354. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +2 -2
  355. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  356. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -2
  357. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  358. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -2
  359. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  360. package/build/dist/Server/Services/PayAsYouGoBillingService.js +20 -27
  361. package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -1
  362. package/build/dist/Server/Services/ProjectService.js +17 -0
  363. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  364. package/build/dist/Server/Services/RumSessionPinService.js +180 -16
  365. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  366. package/build/dist/Server/Services/TeamPermissionService.js +89 -27
  367. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  368. package/build/dist/Server/Services/ThreatIntelFeedService.js +5 -4
  369. package/build/dist/Server/Services/ThreatIntelFeedService.js.map +1 -1
  370. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +9 -6
  371. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  372. package/build/dist/Server/Types/Database/Permissions/Index.js +60 -6
  373. package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
  374. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +14 -13
  375. package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
  376. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +7 -0
  377. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -1
  378. package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js +7 -0
  379. package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js.map +1 -1
  380. package/build/dist/Server/Utils/MasterAdminPageAccess.js +39 -0
  381. package/build/dist/Server/Utils/MasterAdminPageAccess.js.map +1 -0
  382. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +3 -1
  383. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  384. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +3 -1
  385. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  386. package/build/dist/Server/Utils/Realtime.js +126 -37
  387. package/build/dist/Server/Utils/Realtime.js.map +1 -1
  388. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +7 -25
  389. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
  390. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js +127 -0
  391. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js.map +1 -0
  392. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +1 -1
  393. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
  394. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +3 -2
  395. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js.map +1 -1
  396. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js +4 -8
  397. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js.map +1 -1
  398. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js +31 -1
  399. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js.map +1 -1
  400. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js +321 -0
  401. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js.map +1 -0
  402. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js +372 -0
  403. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js.map +1 -0
  404. package/build/dist/Types/Realtime/EventName.js +10 -0
  405. package/build/dist/Types/Realtime/EventName.js.map +1 -1
  406. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +11 -0
  407. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
  408. package/build/dist/Types/SecurityEvent/OcsfSeverity.js +30 -25
  409. package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -1
  410. package/build/dist/Types/SecurityEvent/SigmaRule.js +47 -0
  411. package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -1
  412. package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js +14 -0
  413. package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js.map +1 -1
  414. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +9 -4
  415. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -1
  416. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +10 -2
  417. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -1
  418. package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -1
  419. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  420. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +11 -0
  421. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  422. package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
  423. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  424. package/build/dist/UI/Components/Forms/BasicForm.js +70 -64
  425. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  426. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +27 -0
  427. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -0
  428. package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -7
  429. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  430. package/build/dist/UI/Components/Forms/FormSummary.js +7 -0
  431. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  432. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +2 -1
  433. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  434. package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js +84 -0
  435. package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js.map +1 -0
  436. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +14 -1
  437. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  438. package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
  439. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  440. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -1
  441. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  442. package/build/dist/UI/Components/Tooltip/Tooltip.js +2 -1
  443. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  444. package/build/dist/UI/Utils/API/API.js +143 -19
  445. package/build/dist/UI/Utils/API/API.js.map +1 -1
  446. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +21 -7
  447. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  448. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +26 -9
  449. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  450. package/build/dist/UI/Utils/Navigation.js +8 -0
  451. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  452. package/build/dist/UI/Utils/OpenAuthenticatedUrl.js +92 -0
  453. package/build/dist/UI/Utils/OpenAuthenticatedUrl.js.map +1 -0
  454. package/build/dist/UI/Utils/Realtime.js +120 -15
  455. package/build/dist/UI/Utils/Realtime.js.map +1 -1
  456. package/build/dist/Utils/API.js +13 -5
  457. package/build/dist/Utils/API.js.map +1 -1
  458. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +123 -6
  459. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
  460. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +4 -18
  461. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -1
  462. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +2 -2
  463. package/package.json +1 -1
@@ -0,0 +1,142 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import {
3
+ SIGMA_DEFAULT_LEVEL,
4
+ SIGMA_LEVEL_TO_OCSF_SEVERITY,
5
+ SIGMA_SUPPORTED_MODIFIERS,
6
+ SigmaLevel,
7
+ isSevereSigmaLevel,
8
+ } from "../../../Types/SecurityEvent/SigmaRule";
9
+ import OcsfSeverity, {
10
+ OcsfSeverityId,
11
+ } from "../../../Types/SecurityEvent/OcsfSeverity";
12
+ import {
13
+ DETECTION_EVALUATION_INTERVAL_MAX_IN_MINUTES,
14
+ DETECTION_EVALUATION_INTERVAL_MIN_IN_MINUTES,
15
+ DETECTION_MAX_GROUPS_PER_EVALUATION,
16
+ DETECTION_MAX_LOOKBACK_IN_MINUTES,
17
+ } from "../../../Types/SecurityEvent/DetectionFindingConstants";
18
+ import {
19
+ THREAT_INTEL_DEFAULT_POLL_INTERVAL_IN_MINUTES,
20
+ THREAT_INTEL_FIRST_MATCH_WINDOW_IN_MINUTES,
21
+ THREAT_INTEL_MATCH_MAX_LOOKBACK_IN_MINUTES,
22
+ THREAT_INTEL_MAX_INDICATORS_PER_EVALUATION,
23
+ THREAT_INTEL_POLL_INTERVAL_MAX_IN_MINUTES,
24
+ THREAT_INTEL_POLL_INTERVAL_MIN_IN_MINUTES,
25
+ } from "../../../Types/SecurityEvent/ThreatIntelConstants";
26
+
27
+ /*
28
+ * The Sigma level map, modifier list and engine limits used to be private
29
+ * to the evaluator, parser and matcher. They now live in Types so the
30
+ * dashboard's guides can render them — which makes them a contract, and
31
+ * these are its invariants.
32
+ */
33
+
34
+ const LEVELS_IN_RISING_ORDER: Array<SigmaLevel> = [
35
+ SigmaLevel.Informational,
36
+ SigmaLevel.Low,
37
+ SigmaLevel.Medium,
38
+ SigmaLevel.High,
39
+ SigmaLevel.Critical,
40
+ ];
41
+
42
+ describe("SIGMA_LEVEL_TO_OCSF_SEVERITY", () => {
43
+ test("maps every Sigma level", () => {
44
+ expect(Object.keys(SIGMA_LEVEL_TO_OCSF_SEVERITY).sort()).toEqual(
45
+ Object.values(SigmaLevel).sort(),
46
+ );
47
+ });
48
+
49
+ test("maps each level to the OCSF severity of the same name", () => {
50
+ expect(SIGMA_LEVEL_TO_OCSF_SEVERITY).toEqual({
51
+ [SigmaLevel.Informational]: OcsfSeverity.Informational,
52
+ [SigmaLevel.Low]: OcsfSeverity.Low,
53
+ [SigmaLevel.Medium]: OcsfSeverity.Medium,
54
+ [SigmaLevel.High]: OcsfSeverity.High,
55
+ [SigmaLevel.Critical]: OcsfSeverity.Critical,
56
+ });
57
+ });
58
+
59
+ test("a more severe level never maps to a less severe OCSF severity", () => {
60
+ const ids: Array<number> = LEVELS_IN_RISING_ORDER.map(
61
+ (level: SigmaLevel): number => {
62
+ return OcsfSeverityId[SIGMA_LEVEL_TO_OCSF_SEVERITY[level]];
63
+ },
64
+ );
65
+
66
+ for (let index: number = 1; index < ids.length; index++) {
67
+ expect(ids[index]!).toBeGreaterThan(ids[index - 1]!);
68
+ }
69
+ });
70
+ });
71
+
72
+ describe("isSevereSigmaLevel", () => {
73
+ test.each(LEVELS_IN_RISING_ORDER)("%s", (level: SigmaLevel) => {
74
+ expect(isSevereSigmaLevel(level)).toBe(
75
+ level === SigmaLevel.High || level === SigmaLevel.Critical,
76
+ );
77
+ });
78
+ });
79
+
80
+ describe("SIGMA_DEFAULT_LEVEL", () => {
81
+ test("is a real level, and the middle one", () => {
82
+ expect(Object.values(SigmaLevel)).toContain(SIGMA_DEFAULT_LEVEL);
83
+ expect(SIGMA_DEFAULT_LEVEL).toBe(SigmaLevel.Medium);
84
+ });
85
+ });
86
+
87
+ describe("SIGMA_SUPPORTED_MODIFIERS", () => {
88
+ test("has no duplicates and only lowercase names, as the parser lowercases input", () => {
89
+ expect(new Set(SIGMA_SUPPORTED_MODIFIERS).size).toBe(
90
+ SIGMA_SUPPORTED_MODIFIERS.length,
91
+ );
92
+
93
+ for (const modifier of SIGMA_SUPPORTED_MODIFIERS) {
94
+ expect(modifier).toBe(modifier.toLowerCase());
95
+ }
96
+ });
97
+ });
98
+
99
+ describe("engine limits", () => {
100
+ test("detection rule interval bounds are ordered and whole", () => {
101
+ expect(Number.isInteger(DETECTION_EVALUATION_INTERVAL_MIN_IN_MINUTES)).toBe(
102
+ true,
103
+ );
104
+ expect(DETECTION_EVALUATION_INTERVAL_MIN_IN_MINUTES).toBeGreaterThanOrEqual(
105
+ 1,
106
+ );
107
+ expect(DETECTION_EVALUATION_INTERVAL_MAX_IN_MINUTES).toBeGreaterThan(
108
+ DETECTION_EVALUATION_INTERVAL_MIN_IN_MINUTES,
109
+ );
110
+ });
111
+
112
+ test("a rule at its longest interval still fits in one lookback", () => {
113
+ expect(DETECTION_MAX_LOOKBACK_IN_MINUTES).toBeGreaterThanOrEqual(
114
+ DETECTION_EVALUATION_INTERVAL_MAX_IN_MINUTES,
115
+ );
116
+ });
117
+
118
+ test("threat intel's default poll interval is inside its bounds", () => {
119
+ expect(
120
+ THREAT_INTEL_DEFAULT_POLL_INTERVAL_IN_MINUTES,
121
+ ).toBeGreaterThanOrEqual(THREAT_INTEL_POLL_INTERVAL_MIN_IN_MINUTES);
122
+ expect(THREAT_INTEL_DEFAULT_POLL_INTERVAL_IN_MINUTES).toBeLessThanOrEqual(
123
+ THREAT_INTEL_POLL_INTERVAL_MAX_IN_MINUTES,
124
+ );
125
+ });
126
+
127
+ test("the matcher's first window fits inside its lookback cap", () => {
128
+ expect(THREAT_INTEL_FIRST_MATCH_WINDOW_IN_MINUTES).toBeLessThanOrEqual(
129
+ THREAT_INTEL_MATCH_MAX_LOOKBACK_IN_MINUTES,
130
+ );
131
+ });
132
+
133
+ test("per-run caps are positive whole numbers", () => {
134
+ for (const cap of [
135
+ DETECTION_MAX_GROUPS_PER_EVALUATION,
136
+ THREAT_INTEL_MAX_INDICATORS_PER_EVALUATION,
137
+ ]) {
138
+ expect(Number.isInteger(cap)).toBe(true);
139
+ expect(cap).toBeGreaterThan(0);
140
+ }
141
+ });
142
+ });
@@ -0,0 +1,182 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import JsonComponents from "../../../../Types/Workflow/Components/JSON";
3
+ import AllComponents from "../../../../Types/Workflow/Components";
4
+ import ComponentID from "../../../../Types/Workflow/ComponentID";
5
+ import ComponentMetadata, {
6
+ Argument,
7
+ ComponentInputType,
8
+ ComponentType,
9
+ Port,
10
+ ReturnValue,
11
+ } from "../../../../Types/Workflow/Component";
12
+ import IconProp from "../../../../Types/Icon/IconProp";
13
+
14
+ /*
15
+ * The JSON workflow block catalog. The server-side runners
16
+ * (Server/Types/Workflow/Components/JSON/*) look their metadata up here by
17
+ * ComponentID and then read args / emit return values / choose ports by the
18
+ * ids declared below, so a renamed id silently breaks saved workflows.
19
+ */
20
+
21
+ const findComponent: (id: ComponentID) => ComponentMetadata = (
22
+ id: ComponentID,
23
+ ): ComponentMetadata => {
24
+ const component: ComponentMetadata | undefined = JsonComponents.find(
25
+ (item: ComponentMetadata) => {
26
+ return item.id === id;
27
+ },
28
+ );
29
+ if (!component) {
30
+ throw new Error(`Component ${id} not found`);
31
+ }
32
+ return component;
33
+ };
34
+
35
+ const argumentIds: (component: ComponentMetadata) => Array<string> = (
36
+ component: ComponentMetadata,
37
+ ): Array<string> => {
38
+ return component.arguments.map((argument: Argument) => {
39
+ return argument.id;
40
+ });
41
+ };
42
+
43
+ const returnValueIds: (component: ComponentMetadata) => Array<string> = (
44
+ component: ComponentMetadata,
45
+ ): Array<string> => {
46
+ return component.returnValues.map((returnValue: ReturnValue) => {
47
+ return returnValue.id;
48
+ });
49
+ };
50
+
51
+ const portIds: (ports: Array<Port>) => Array<string> = (
52
+ ports: Array<Port>,
53
+ ): Array<string> => {
54
+ return ports.map((port: Port) => {
55
+ return port.id;
56
+ });
57
+ };
58
+
59
+ describe("Workflow JSON components", () => {
60
+ test("exports exactly the three JSON blocks in order", () => {
61
+ expect(
62
+ JsonComponents.map((component: ComponentMetadata) => {
63
+ return component.id;
64
+ }),
65
+ ).toEqual([
66
+ ComponentID.JsonToText,
67
+ ComponentID.TextToJson,
68
+ ComponentID.MergeJson,
69
+ ]);
70
+ });
71
+
72
+ test("ids resolve to the expected stable string values", () => {
73
+ expect(ComponentID.JsonToText).toBe("json-to-text");
74
+ expect(ComponentID.TextToJson).toBe("text-to-json");
75
+ expect(ComponentID.MergeJson).toBe("merge-json");
76
+ });
77
+
78
+ test("component ids are unique", () => {
79
+ const ids: Array<string> = JsonComponents.map(
80
+ (component: ComponentMetadata) => {
81
+ return component.id;
82
+ },
83
+ );
84
+ expect(new Set(ids).size).toBe(ids.length);
85
+ });
86
+
87
+ test.each(JsonComponents)(
88
+ "$id shares the JSON category, icon and component type",
89
+ (component: ComponentMetadata) => {
90
+ expect(component.category).toBe("JSON");
91
+ expect(component.iconProp).toBe(IconProp.JSON);
92
+ expect(component.componentType).toBe(ComponentType.Component);
93
+ expect(component.title.trim().length).toBeGreaterThan(0);
94
+ expect(component.description.trim().length).toBeGreaterThan(0);
95
+ },
96
+ );
97
+
98
+ test.each(JsonComponents)(
99
+ "$id has a single 'in' port and success / error out ports",
100
+ (component: ComponentMetadata) => {
101
+ expect(portIds(component.inPorts)).toEqual(["in"]);
102
+ expect(portIds(component.outPorts)).toEqual(["success", "error"]);
103
+ for (const port of [...component.inPorts, ...component.outPorts]) {
104
+ expect(port.title.length).toBeGreaterThan(0);
105
+ expect(port.description.length).toBeGreaterThan(0);
106
+ }
107
+ },
108
+ );
109
+
110
+ test.each(JsonComponents)(
111
+ "$id marks every argument and return value as required",
112
+ (component: ComponentMetadata) => {
113
+ for (const argument of component.arguments) {
114
+ expect(argument.required).toBe(true);
115
+ }
116
+ for (const returnValue of component.returnValues) {
117
+ expect(returnValue.required).toBe(true);
118
+ }
119
+ },
120
+ );
121
+
122
+ test.each(JsonComponents)(
123
+ "$id has unique argument and return value ids",
124
+ (component: ComponentMetadata) => {
125
+ const args: Array<string> = argumentIds(component);
126
+ const returns: Array<string> = returnValueIds(component);
127
+ expect(new Set(args).size).toBe(args.length);
128
+ expect(new Set(returns).size).toBe(returns.length);
129
+ },
130
+ );
131
+
132
+ test("JSON to Text takes JSON 'json' and returns Text 'text'", () => {
133
+ const component: ComponentMetadata = findComponent(ComponentID.JsonToText);
134
+ expect(component.title).toBe("JSON to Text");
135
+ expect(argumentIds(component)).toEqual(["json"]);
136
+ expect(component.arguments[0]!.type).toBe(ComponentInputType.JSON);
137
+ expect(returnValueIds(component)).toEqual(["text"]);
138
+ expect(component.returnValues[0]!.type).toBe(ComponentInputType.Text);
139
+ });
140
+
141
+ test("Text to JSON takes Text 'text' and returns JSON 'json'", () => {
142
+ const component: ComponentMetadata = findComponent(ComponentID.TextToJson);
143
+ expect(component.title).toBe("Text to JSON");
144
+ expect(argumentIds(component)).toEqual(["text"]);
145
+ expect(component.arguments[0]!.type).toBe(ComponentInputType.Text);
146
+ expect(returnValueIds(component)).toEqual(["json"]);
147
+ expect(component.returnValues[0]!.type).toBe(ComponentInputType.JSON);
148
+ });
149
+
150
+ test("Merge JSON takes two JSON args 'json1' / 'json2' and returns JSON 'json'", () => {
151
+ const component: ComponentMetadata = findComponent(ComponentID.MergeJson);
152
+ expect(component.title).toBe("Merge JSON");
153
+ expect(argumentIds(component)).toEqual(["json1", "json2"]);
154
+ for (const argument of component.arguments) {
155
+ expect(argument.type).toBe(ComponentInputType.JSON);
156
+ }
157
+ expect(
158
+ component.arguments.map((argument: Argument) => {
159
+ return argument.name;
160
+ }),
161
+ ).toEqual(["JSON 1", "JSON 2"]);
162
+ expect(returnValueIds(component)).toEqual(["json"]);
163
+ expect(component.returnValues[0]!.type).toBe(ComponentInputType.JSON);
164
+ });
165
+
166
+ test("every JSON block is registered in the global component catalog", () => {
167
+ for (const component of JsonComponents) {
168
+ expect(AllComponents).toContain(component);
169
+ }
170
+ });
171
+
172
+ test("no other workflow block reuses a JSON block id", () => {
173
+ for (const component of JsonComponents) {
174
+ const matches: Array<ComponentMetadata> = AllComponents.filter(
175
+ (item: ComponentMetadata) => {
176
+ return item.id === component.id;
177
+ },
178
+ );
179
+ expect(matches).toHaveLength(1);
180
+ }
181
+ });
182
+ });
@@ -2,9 +2,10 @@ import BasicForm from "../../../UI/Components/Forms/BasicForm";
2
2
  import Fields from "../../../UI/Components/Forms/Types/Fields";
3
3
  import FormFieldSchemaType from "../../../UI/Components/Forms/Types/FormFieldSchemaType";
4
4
  import FormValues from "../../../UI/Components/Forms/Types/FormValues";
5
+ import { FormStep } from "../../../UI/Components/Forms/Types/FormStep";
5
6
  import { DropdownOption } from "../../../UI/Components/Dropdown/Dropdown";
6
7
  import ObjectID from "../../../Types/ObjectID";
7
- import { render, screen } from "@testing-library/react";
8
+ import { act, render, screen, within } from "@testing-library/react";
8
9
  import userEvent from "@testing-library/user-event";
9
10
  import * as React from "react";
10
11
  import { describe, expect, test } from "@jest/globals";
@@ -164,4 +165,118 @@ describe("BasicForm dropdown initial-value normalization", () => {
164
165
 
165
166
  expect(submitted["snmpVersion"]).toBeUndefined();
166
167
  });
168
+
169
+ test("preserves all multiselect IDs when available options contain only some selections", async () => {
170
+ const submitted: FormValues<any> = await submitForm(
171
+ { owners: ["unavailable-owner", "available-owner"] },
172
+ [
173
+ {
174
+ field: { owners: true },
175
+ title: "Owners",
176
+ fieldType: FormFieldSchemaType.MultiSelectDropdown,
177
+ dropdownOptions: [
178
+ { label: "Available Owner", value: "available-owner" },
179
+ ],
180
+ },
181
+ ],
182
+ );
183
+
184
+ expect(submitted["owners"]).toEqual([
185
+ "unavailable-owner",
186
+ "available-owner",
187
+ ]);
188
+ });
189
+
190
+ test("preserves and canonicalizes multiselect ObjectIDs before options load", async () => {
191
+ const firstId: ObjectID = new ObjectID(
192
+ "3f1b6b0e-0000-4000-8000-000000000003",
193
+ );
194
+ const secondId: ObjectID = new ObjectID(
195
+ "3f1b6b0e-0000-4000-8000-000000000004",
196
+ );
197
+ const submitted: FormValues<any> = await submitForm(
198
+ { owners: [firstId, secondId] } as unknown as FormValues<any>,
199
+ [
200
+ {
201
+ field: { owners: true },
202
+ title: "Owners",
203
+ fieldType: FormFieldSchemaType.MultiSelectDropdown,
204
+ },
205
+ ],
206
+ );
207
+
208
+ expect(submitted["owners"]).toEqual([
209
+ firstId.toString(),
210
+ secondId.toString(),
211
+ ]);
212
+ });
213
+
214
+ test("keeps saved owners visible and submitted when their step loads options after initialization", async () => {
215
+ const onSubmit: MockFunction = getJestMockFunction();
216
+ const ownerId: string = "3f1b6b0e-0000-4000-8000-000000000005";
217
+ let resolveOptions: (options: Array<DropdownOption>) => void = () => {};
218
+ const optionsLoaded: Promise<Array<DropdownOption>> = new Promise(
219
+ (resolve: (options: Array<DropdownOption>) => void) => {
220
+ resolveOptions = resolve;
221
+ },
222
+ );
223
+ const steps: Array<FormStep<FormValues<any>>> = [
224
+ { id: "details", title: "Details" },
225
+ { id: "owners", title: "Owner Settings" },
226
+ ];
227
+ const fields: Fields<FormValues<any>> = [
228
+ {
229
+ field: { title: true },
230
+ title: "Rule Title",
231
+ fieldType: FormFieldSchemaType.Text,
232
+ stepId: "details",
233
+ },
234
+ {
235
+ field: { owners: true },
236
+ title: "Owners",
237
+ fieldType: FormFieldSchemaType.MultiSelectDropdown,
238
+ stepId: "owners",
239
+ fetchDropdownOptions: async (): Promise<Array<DropdownOption>> => {
240
+ return optionsLoaded;
241
+ },
242
+ },
243
+ ];
244
+ const user: ReturnType<typeof userEvent.setup> = userEvent.setup({
245
+ delay: null,
246
+ });
247
+
248
+ render(
249
+ <BasicForm
250
+ fields={fields}
251
+ steps={steps}
252
+ initialValues={{ title: "Existing rule", owners: [ownerId] }}
253
+ onSubmit={onSubmit}
254
+ submitButtonText="Save"
255
+ disableAutofocus={true}
256
+ />,
257
+ );
258
+
259
+ await screen.findByRole("textbox", { name: /^Rule Title/ });
260
+ await user.click(screen.getByRole("button", { name: "Next" }));
261
+ await screen.findByRole("combobox", { name: /^Owners/ });
262
+ await act(async () => {
263
+ resolveOptions([{ label: "Saved Owner", value: ownerId }]);
264
+ await optionsLoaded;
265
+ });
266
+
267
+ expect(await screen.findByText("Saved Owner")).toBeTruthy();
268
+ await user.click(
269
+ within(screen.getByRole("navigation", { name: "Progress" })).getByText(
270
+ "Details",
271
+ ),
272
+ );
273
+ await user.click(screen.getByRole("button", { name: "Next" }));
274
+ expect(await screen.findByText("Saved Owner")).toBeTruthy();
275
+ await user.click(screen.getByRole("button", { name: "Save" }));
276
+
277
+ expect(onSubmit.mock.calls[0]?.[0]).toEqual({
278
+ title: "Existing rule",
279
+ owners: [ownerId],
280
+ });
281
+ });
167
282
  });
@@ -0,0 +1,81 @@
1
+ import Dropdown, {
2
+ DropdownOption,
3
+ } from "../../../../UI/Components/Dropdown/Dropdown";
4
+ import getJestMockFunction, { MockFunction } from "../../../MockType";
5
+ import "@testing-library/jest-dom";
6
+ import { render, RenderResult, screen } from "@testing-library/react";
7
+ import React from "react";
8
+ import { describe, expect, test } from "@jest/globals";
9
+
10
+ describe("Dropdown asynchronous options", () => {
11
+ const owner: DropdownOption = { value: "owner-1", label: "Saved Owner" };
12
+
13
+ test("resolves a controlled multiselect's unchanged IDs when options arrive", () => {
14
+ const onChange: MockFunction = getJestMockFunction();
15
+ // BasicForm passes the stored IDs, before their option labels are fetched.
16
+ const value: Array<DropdownOption> = [
17
+ owner.value,
18
+ ] as unknown as Array<DropdownOption>;
19
+ const { rerender }: RenderResult = render(
20
+ <Dropdown
21
+ isMultiSelect={true}
22
+ options={[]}
23
+ value={value}
24
+ onChange={onChange}
25
+ />,
26
+ );
27
+
28
+ expect(screen.queryByText(owner.label)).not.toBeInTheDocument();
29
+ rerender(
30
+ <Dropdown
31
+ isMultiSelect={true}
32
+ options={[owner]}
33
+ value={value}
34
+ onChange={onChange}
35
+ />,
36
+ );
37
+
38
+ expect(screen.getByText(owner.label)).toBeVisible();
39
+ expect(
40
+ screen.getByRole("button", { name: "Remove Saved Owner" }),
41
+ ).toBeVisible();
42
+ expect(onChange).not.toHaveBeenCalled();
43
+ });
44
+
45
+ test("resolves a controlled single value when options arrive", () => {
46
+ const value: DropdownOption = owner.value as unknown as DropdownOption;
47
+ const { rerender }: RenderResult = render(
48
+ <Dropdown options={[]} value={value} />,
49
+ );
50
+
51
+ rerender(<Dropdown options={[owner]} value={value} />);
52
+
53
+ expect(screen.getByText(owner.label)).toBeVisible();
54
+ });
55
+
56
+ test("does not clear an uncontrolled selection when its options refresh", () => {
57
+ const { rerender }: RenderResult = render(
58
+ <Dropdown options={[owner]} initialValue={owner} />,
59
+ );
60
+
61
+ rerender(
62
+ <Dropdown
63
+ options={[owner, { value: "owner-2", label: "Another Owner" }]}
64
+ initialValue={owner}
65
+ />,
66
+ );
67
+
68
+ expect(screen.getByText(owner.label)).toBeVisible();
69
+ expect(screen.queryByText("Another Owner")).not.toBeInTheDocument();
70
+ });
71
+
72
+ test("still clears a controlled selection when its value becomes undefined", () => {
73
+ const { rerender }: RenderResult = render(
74
+ <Dropdown options={[owner]} value={owner} />,
75
+ );
76
+
77
+ rerender(<Dropdown options={[owner]} value={undefined} />);
78
+
79
+ expect(screen.queryByText(owner.label)).not.toBeInTheDocument();
80
+ });
81
+ });
@@ -3,7 +3,13 @@ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
3
3
  import HTTPResponse from "../../../Types/API/HTTPResponse";
4
4
  import { JSONObject } from "../../../Types/JSON";
5
5
  import "@testing-library/jest-dom";
6
- import { fireEvent, render, screen, waitFor } from "@testing-library/react";
6
+ import {
7
+ act,
8
+ fireEvent,
9
+ render,
10
+ screen,
11
+ waitFor,
12
+ } from "@testing-library/react";
7
13
  import React from "react";
8
14
  import { beforeEach, describe, expect, it } from "@jest/globals";
9
15
 
@@ -30,6 +36,7 @@ import { beforeEach, describe, expect, it } from "@jest/globals";
30
36
  let isEnterpriseEdition: boolean = true;
31
37
  let billingEnabled: boolean = false;
32
38
  let isMasterAdmin: boolean = true;
39
+ let isLoggedIn: boolean = true;
33
40
 
34
41
  /*
35
42
  * Object.defineProperty rather than getters in an object literal: this file is
@@ -65,6 +72,9 @@ jest.mock("../../../UI/Utils/User", () => {
65
72
  isMasterAdmin: (): boolean => {
66
73
  return isMasterAdmin;
67
74
  },
75
+ isLoggedIn: (): boolean => {
76
+ return isLoggedIn;
77
+ },
68
78
  },
69
79
  };
70
80
  });
@@ -159,12 +169,89 @@ const openDialog: OpenDialogFunction = async (): Promise<void> => {
159
169
  fireEvent.click(screen.getByRole("button", { name: /Enterprise Edition/i }));
160
170
  };
161
171
 
172
+ /*
173
+ * The license GET also serves the login page, so on its own the server answers
174
+ * a caller with no session with the reduced anonymous payload and a 200. Inside
175
+ * a signed-in app that caller is this component with an expired session, and
176
+ * the reduced payload reads as "no license, no instances". Sending
177
+ * `signedIn=true` makes the server answer 401 instead, which the API client
178
+ * refreshes and replays. On the login page (nobody signed in) the flag must
179
+ * NOT be sent, or the page would get a 401 instead of the edition pill.
180
+ */
181
+ describe("EditionLabel - telling the license route we expect to be signed in", () => {
182
+ type LicenseGetFunction = () => FetchCall;
183
+
184
+ const licenseGet: LicenseGetFunction = (): FetchCall => {
185
+ const call: FetchCall | undefined = fetchCalls.find(
186
+ (candidate: FetchCall): boolean => {
187
+ return (
188
+ candidate.method === "GET" &&
189
+ candidate.url.includes("/global-config/license")
190
+ );
191
+ },
192
+ );
193
+
194
+ expect(call).toBeDefined();
195
+
196
+ return call as FetchCall;
197
+ };
198
+
199
+ type RenderAndSettleFunction = () => Promise<void>;
200
+
201
+ /*
202
+ * Renders and waits for the license GET, then lets the response's state
203
+ * updates land inside act() so they do not spill past the end of the test.
204
+ */
205
+ const renderAndSettle: RenderAndSettleFunction = async (): Promise<void> => {
206
+ render(<EditionLabel />);
207
+
208
+ await waitFor(() => {
209
+ expect(fetchCalls.length).toBeGreaterThan(0);
210
+ });
211
+
212
+ await act(async () => {
213
+ await new Promise<void>((resolve: () => void) => {
214
+ setTimeout(resolve, 0);
215
+ });
216
+ });
217
+ };
218
+
219
+ beforeEach(() => {
220
+ fetchCalls.length = 0;
221
+ isEnterpriseEdition = true;
222
+ billingEnabled = false;
223
+ isMasterAdmin = true;
224
+ isLoggedIn = true;
225
+ respond = (): HTTPResponse<JSONObject> => {
226
+ return new HTTPResponse<JSONObject>(200, licensePayload(), {});
227
+ };
228
+ });
229
+
230
+ it("adds signedIn=true to the license fetch when a user is logged in", async () => {
231
+ isLoggedIn = true;
232
+
233
+ await renderAndSettle();
234
+
235
+ expect(licenseGet().url).toContain("signedIn=true");
236
+ });
237
+
238
+ it("does not add signedIn to the license fetch when nobody is logged in", async () => {
239
+ isLoggedIn = false;
240
+
241
+ await renderAndSettle();
242
+
243
+ expect(licenseGet().url).toContain("/global-config/license");
244
+ expect(licenseGet().url).not.toContain("signedIn");
245
+ });
246
+ });
247
+
162
248
  describe("EditionLabel - refreshing the license", () => {
163
249
  beforeEach(() => {
164
250
  fetchCalls.length = 0;
165
251
  isEnterpriseEdition = true;
166
252
  billingEnabled = false;
167
253
  isMasterAdmin = true;
254
+ isLoggedIn = true;
168
255
  respond = (): HTTPResponse<JSONObject> => {
169
256
  return new HTTPResponse<JSONObject>(200, licensePayload(), {});
170
257
  };
@@ -311,6 +398,7 @@ describe("EditionLabel - what an exhausted seat limit looks like", () => {
311
398
  isEnterpriseEdition = true;
312
399
  billingEnabled = false;
313
400
  isMasterAdmin = true;
401
+ isLoggedIn = true;
314
402
  respond = (): HTTPResponse<JSONObject> => {
315
403
  return new HTTPResponse<JSONObject>(200, licensePayload(), {});
316
404
  };