@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,459 @@
1
+ import DatabaseRequestType from "../../../../../Server/Types/BaseDatabase/DatabaseRequestType";
2
+ import AccessControlPermission from "../../../../../Server/Types/Database/Permissions/AccessControlPermission";
3
+ import CreatePermission from "../../../../../Server/Types/Database/Permissions/CreatePermission";
4
+ import DeletePermission from "../../../../../Server/Types/Database/Permissions/DeletePermission";
5
+ import ReadPermission from "../../../../../Server/Types/Database/Permissions/ReadPermission";
6
+ import TablePermission from "../../../../../Server/Types/Database/Permissions/TablePermission";
7
+ import UpdatePermission from "../../../../../Server/Types/Database/Permissions/UpdatePermission";
8
+ import QueryUtil from "../../../../../Server/Types/Database/QueryUtil";
9
+ import Incident from "../../../../../Models/DatabaseModels/Incident";
10
+ import Label from "../../../../../Models/DatabaseModels/Label";
11
+ import DatabaseCommonInteractionProps from "../../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
12
+ import NotAuthorizedException from "../../../../../Types/Exception/NotAuthorizedException";
13
+ import ObjectID from "../../../../../Types/ObjectID";
14
+ import Permission, {
15
+ UserPermission,
16
+ UserTenantAccessPermission,
17
+ } from "../../../../../Types/Permission";
18
+
19
+ /*
20
+ * AccessTokenService.refreshUserTenantAccessPermission emits one row per
21
+ * TeamPermission across every team the user belongs to, without merging or
22
+ * ordering them. The same permission can therefore be blocked twice: once by
23
+ * a team that scopes the block to some labels and once by a team that blocks
24
+ * it outright. The table-wide block must win no matter which row comes first.
25
+ */
26
+ describe("TablePermission.checkTableLevelBlockPermissions", () => {
27
+ const projectId: ObjectID = ObjectID.generate();
28
+ const userId: ObjectID = ObjectID.generate();
29
+ const labelA: ObjectID = ObjectID.generate();
30
+ const labelB: ObjectID = ObjectID.generate();
31
+
32
+ function makeProps(
33
+ permissions: Array<UserPermission>,
34
+ ): DatabaseCommonInteractionProps {
35
+ const tenantPermission: UserTenantAccessPermission = {
36
+ projectId,
37
+ _type: "UserTenantAccessPermission",
38
+ permissions,
39
+ };
40
+
41
+ return {
42
+ userId,
43
+ tenantId: projectId,
44
+ userTenantAccessPermission: {
45
+ [projectId.toString()]: tenantPermission,
46
+ },
47
+ };
48
+ }
49
+
50
+ function blockPermission(
51
+ permission: Permission,
52
+ labelIds: Array<ObjectID> | undefined,
53
+ ): UserPermission {
54
+ return {
55
+ _type: "UserPermission",
56
+ permission,
57
+ labelIds: labelIds as Array<ObjectID>,
58
+ isBlockPermission: true,
59
+ };
60
+ }
61
+
62
+ function allowPermission(
63
+ permission: Permission,
64
+ labelIds: Array<ObjectID>,
65
+ ): UserPermission {
66
+ return {
67
+ _type: "UserPermission",
68
+ permission,
69
+ labelIds,
70
+ isBlockPermission: false,
71
+ };
72
+ }
73
+
74
+ function incidentWithLabels(labelIds: Array<ObjectID>): Incident {
75
+ const incident: Incident = new Incident();
76
+ incident.labels = labelIds.map((id: ObjectID) => {
77
+ const label: Label = new Label();
78
+ label.id = id;
79
+ return label;
80
+ });
81
+ return incident;
82
+ }
83
+
84
+ const requestTypes: Array<DatabaseRequestType> = [
85
+ DatabaseRequestType.Create,
86
+ DatabaseRequestType.Read,
87
+ DatabaseRequestType.Update,
88
+ DatabaseRequestType.Delete,
89
+ ];
90
+
91
+ afterEach(() => {
92
+ jest.restoreAllMocks();
93
+ });
94
+
95
+ describe("with a single block row", () => {
96
+ it.each(requestTypes)(
97
+ "refuses %s when the block row carries no labels",
98
+ (type: DatabaseRequestType) => {
99
+ expect(() => {
100
+ TablePermission.checkTableLevelBlockPermissions(
101
+ Incident,
102
+ makeProps([blockPermission(Permission.ProjectMember, [])]),
103
+ type,
104
+ );
105
+ }).toThrow(NotAuthorizedException);
106
+ },
107
+ );
108
+
109
+ it.each(requestTypes)(
110
+ "does not refuse %s outright when the block row carries labels",
111
+ (type: DatabaseRequestType) => {
112
+ expect(() => {
113
+ TablePermission.checkTableLevelBlockPermissions(
114
+ Incident,
115
+ makeProps([blockPermission(Permission.ProjectMember, [labelA])]),
116
+ type,
117
+ );
118
+ }).not.toThrow();
119
+ },
120
+ );
121
+
122
+ it("treats a block row whose labelIds is missing as table-wide", () => {
123
+ expect(() => {
124
+ TablePermission.checkTableLevelBlockPermissions(
125
+ Incident,
126
+ makeProps([blockPermission(Permission.ProjectMember, undefined)]),
127
+ DatabaseRequestType.Read,
128
+ );
129
+ }).toThrow(NotAuthorizedException);
130
+ });
131
+ });
132
+
133
+ describe("with several block rows for the same permission", () => {
134
+ it.each(requestTypes)(
135
+ "refuses %s when a labelled block row comes before an unlabelled one",
136
+ (type: DatabaseRequestType) => {
137
+ expect(() => {
138
+ TablePermission.checkTableLevelBlockPermissions(
139
+ Incident,
140
+ makeProps([
141
+ blockPermission(Permission.ProjectMember, [labelA]),
142
+ blockPermission(Permission.ProjectMember, []),
143
+ ]),
144
+ type,
145
+ );
146
+ }).toThrow(NotAuthorizedException);
147
+ },
148
+ );
149
+
150
+ it.each(requestTypes)(
151
+ "refuses %s when the unlabelled block row comes first",
152
+ (type: DatabaseRequestType) => {
153
+ expect(() => {
154
+ TablePermission.checkTableLevelBlockPermissions(
155
+ Incident,
156
+ makeProps([
157
+ blockPermission(Permission.ProjectMember, []),
158
+ blockPermission(Permission.ProjectMember, [labelA]),
159
+ ]),
160
+ type,
161
+ );
162
+ }).toThrow(NotAuthorizedException);
163
+ },
164
+ );
165
+
166
+ it("refuses when the unlabelled row is buried behind several labelled ones", () => {
167
+ expect(() => {
168
+ TablePermission.checkTableLevelBlockPermissions(
169
+ Incident,
170
+ makeProps([
171
+ blockPermission(Permission.ProjectMember, [labelA]),
172
+ blockPermission(Permission.ProjectMember, [labelB]),
173
+ blockPermission(Permission.ProjectMember, [labelA, labelB]),
174
+ blockPermission(Permission.ProjectMember, undefined),
175
+ ]),
176
+ DatabaseRequestType.Update,
177
+ );
178
+ }).toThrow(NotAuthorizedException);
179
+ });
180
+
181
+ it("leaves the request to the label check when every block row carries labels", () => {
182
+ expect(() => {
183
+ TablePermission.checkTableLevelBlockPermissions(
184
+ Incident,
185
+ makeProps([
186
+ blockPermission(Permission.ProjectMember, [labelA]),
187
+ blockPermission(Permission.ProjectMember, [labelB]),
188
+ ]),
189
+ DatabaseRequestType.Read,
190
+ );
191
+ }).not.toThrow();
192
+ });
193
+
194
+ it("names the blocked permission in the refusal", () => {
195
+ expect(() => {
196
+ TablePermission.checkTableLevelBlockPermissions(
197
+ Incident,
198
+ makeProps([
199
+ blockPermission(Permission.ProjectMember, [labelA]),
200
+ blockPermission(Permission.ProjectMember, []),
201
+ ]),
202
+ DatabaseRequestType.Delete,
203
+ );
204
+ }).toThrow(
205
+ `${Permission.ProjectMember} is in your team's permission block list.`,
206
+ );
207
+ });
208
+ });
209
+
210
+ describe("with block rows for different permissions of the model", () => {
211
+ it("refuses when another permission of the model is blocked table-wide", () => {
212
+ expect(() => {
213
+ TablePermission.checkTableLevelBlockPermissions(
214
+ Incident,
215
+ makeProps([
216
+ blockPermission(Permission.ProjectMember, [labelA]),
217
+ blockPermission(Permission.IncidentMember, []),
218
+ ]),
219
+ DatabaseRequestType.Update,
220
+ );
221
+ }).toThrow(
222
+ `${Permission.IncidentMember} is in your team's permission block list.`,
223
+ );
224
+ });
225
+
226
+ /*
227
+ * IncidentViewer is only in Incident's read list, so a table-wide block on
228
+ * it takes reading away and leaves the other operations alone.
229
+ */
230
+ it.each([
231
+ { type: DatabaseRequestType.Read, refused: true },
232
+ { type: DatabaseRequestType.Create, refused: false },
233
+ { type: DatabaseRequestType.Update, refused: false },
234
+ { type: DatabaseRequestType.Delete, refused: false },
235
+ ])(
236
+ "matches block rows against the $type permission list only",
237
+ ({ type, refused }: { type: DatabaseRequestType; refused: boolean }) => {
238
+ const check: () => void = (): void => {
239
+ TablePermission.checkTableLevelBlockPermissions(
240
+ Incident,
241
+ makeProps([
242
+ blockPermission(Permission.ProjectMember, [labelA]),
243
+ blockPermission(Permission.IncidentViewer, []),
244
+ ]),
245
+ type,
246
+ );
247
+ };
248
+
249
+ if (refused) {
250
+ expect(check).toThrow(NotAuthorizedException);
251
+ } else {
252
+ expect(check).not.toThrow();
253
+ }
254
+ },
255
+ );
256
+ });
257
+
258
+ describe("rows that must not trigger a table-wide block", () => {
259
+ it("ignores an unlabelled block row for a permission the model does not use", () => {
260
+ expect(() => {
261
+ TablePermission.checkTableLevelBlockPermissions(
262
+ Incident,
263
+ makeProps([
264
+ blockPermission(Permission.ProjectMember, [labelA]),
265
+ blockPermission(Permission.MonitorViewer, []),
266
+ ]),
267
+ DatabaseRequestType.Read,
268
+ );
269
+ }).not.toThrow();
270
+ });
271
+
272
+ it("ignores an unlabelled allow row for the blocked permission", () => {
273
+ expect(() => {
274
+ TablePermission.checkTableLevelBlockPermissions(
275
+ Incident,
276
+ makeProps([
277
+ blockPermission(Permission.ProjectMember, [labelA]),
278
+ allowPermission(Permission.ProjectMember, []),
279
+ ]),
280
+ DatabaseRequestType.Read,
281
+ );
282
+ }).not.toThrow();
283
+ });
284
+ });
285
+
286
+ /*
287
+ * Every CRUD entry point relies on this helper for the table-wide case: the
288
+ * read query rewrite and the update/delete label check only look at block
289
+ * rows that carry labels, so a missed unlabelled row is never enforced
290
+ * anywhere else.
291
+ */
292
+ describe("through the CRUD entry points", () => {
293
+ /*
294
+ * The user is granted the permission table-wide, so any refusal below can
295
+ * only come from the block rows.
296
+ */
297
+ const grant: UserPermission = allowPermission(Permission.ProjectMember, []);
298
+ const mixedBlockRows: Array<UserPermission> = [
299
+ grant,
300
+ blockPermission(Permission.ProjectMember, [labelA]),
301
+ blockPermission(Permission.ProjectMember, []),
302
+ ];
303
+
304
+ it("allows update and delete when only the grant is present", async () => {
305
+ await expect(
306
+ UpdatePermission.checkUpdatePermissionByModel({
307
+ modelType: Incident,
308
+ fetchModelWithAccessControlIds: async () => {
309
+ return incidentWithLabels([labelB]);
310
+ },
311
+ props: makeProps([grant]),
312
+ }),
313
+ ).resolves.toBeUndefined();
314
+
315
+ await expect(
316
+ DeletePermission.checkDeletePermissionByModel({
317
+ modelType: Incident,
318
+ fetchModelWithAccessControlIds: async () => {
319
+ return incidentWithLabels([labelB]);
320
+ },
321
+ props: makeProps([grant]),
322
+ }),
323
+ ).resolves.toBeUndefined();
324
+ });
325
+
326
+ it("refuses create", () => {
327
+ expect(() => {
328
+ CreatePermission.checkCreateBlockPermissions(
329
+ Incident,
330
+ makeProps(mixedBlockRows),
331
+ );
332
+ }).toThrow(NotAuthorizedException);
333
+ });
334
+
335
+ it("refuses read instead of only filtering the labelled rows out", async () => {
336
+ jest.spyOn(QueryUtil, "getManyToManyRelationMetadata").mockReturnValue({
337
+ joinTableName: "IncidentLabel",
338
+ ownerColumnName: "incidentId",
339
+ relationColumnName: "labelId",
340
+ });
341
+
342
+ await expect(
343
+ ReadPermission.checkReadBlockPermission(
344
+ Incident,
345
+ { projectId } as any,
346
+ makeProps(mixedBlockRows),
347
+ ),
348
+ ).rejects.toThrow(NotAuthorizedException);
349
+ });
350
+
351
+ it("refuses update of a record that carries none of the blocked labels", async () => {
352
+ const fetchModel: jest.Mock = jest.fn(async () => {
353
+ return incidentWithLabels([labelB]);
354
+ });
355
+
356
+ await expect(
357
+ UpdatePermission.checkUpdatePermissionByModel({
358
+ modelType: Incident,
359
+ fetchModelWithAccessControlIds: fetchModel,
360
+ props: makeProps(mixedBlockRows),
361
+ }),
362
+ ).rejects.toThrow(NotAuthorizedException);
363
+ });
364
+
365
+ it("refuses delete of a record that carries none of the blocked labels", async () => {
366
+ const fetchModel: jest.Mock = jest.fn(async () => {
367
+ return incidentWithLabels([labelB]);
368
+ });
369
+
370
+ await expect(
371
+ DeletePermission.checkDeletePermissionByModel({
372
+ modelType: Incident,
373
+ fetchModelWithAccessControlIds: fetchModel,
374
+ props: makeProps(mixedBlockRows),
375
+ }),
376
+ ).rejects.toThrow(NotAuthorizedException);
377
+ });
378
+
379
+ it("refuses before loading the record for a label comparison", async () => {
380
+ const fetchModel: jest.Mock = jest.fn(async () => {
381
+ return incidentWithLabels([]);
382
+ });
383
+
384
+ await expect(
385
+ AccessControlPermission.checkAccessControlBlockPermissionByModel({
386
+ modelType: Incident,
387
+ fetchModelWithAccessControlIds: fetchModel,
388
+ type: DatabaseRequestType.Update,
389
+ props: makeProps(mixedBlockRows),
390
+ }),
391
+ ).rejects.toThrow(NotAuthorizedException);
392
+ expect(fetchModel).not.toHaveBeenCalled();
393
+ });
394
+
395
+ it.each([{ isRoot: true }, { isMasterAdmin: true }])(
396
+ "still lets %o requests through",
397
+ async (bypass: DatabaseCommonInteractionProps) => {
398
+ const props: DatabaseCommonInteractionProps = {
399
+ ...makeProps(mixedBlockRows),
400
+ ...bypass,
401
+ };
402
+
403
+ expect(() => {
404
+ CreatePermission.checkCreateBlockPermissions(Incident, props);
405
+ }).not.toThrow();
406
+
407
+ await expect(
408
+ ReadPermission.checkReadBlockPermission(
409
+ Incident,
410
+ { projectId } as any,
411
+ props,
412
+ ),
413
+ ).resolves.toBeDefined();
414
+
415
+ await expect(
416
+ AccessControlPermission.checkAccessControlBlockPermissionByModel({
417
+ modelType: Incident,
418
+ fetchModelWithAccessControlIds: jest.fn(),
419
+ type: DatabaseRequestType.Delete,
420
+ props,
421
+ }),
422
+ ).resolves.toBeUndefined();
423
+ },
424
+ );
425
+ });
426
+
427
+ describe("label-scoped blocks keep working after the table-level check", () => {
428
+ const labelledBlockRows: Array<UserPermission> = [
429
+ blockPermission(Permission.ProjectMember, [labelA]),
430
+ blockPermission(Permission.IncidentMember, [labelB]),
431
+ ];
432
+
433
+ it("refuses update of a record that carries a blocked label", async () => {
434
+ await expect(
435
+ AccessControlPermission.checkAccessControlBlockPermissionByModel({
436
+ modelType: Incident,
437
+ fetchModelWithAccessControlIds: async () => {
438
+ return incidentWithLabels([labelB]);
439
+ },
440
+ type: DatabaseRequestType.Update,
441
+ props: makeProps(labelledBlockRows),
442
+ }),
443
+ ).rejects.toThrow(NotAuthorizedException);
444
+ });
445
+
446
+ it("allows update of a record that carries none of the blocked labels", async () => {
447
+ await expect(
448
+ AccessControlPermission.checkAccessControlBlockPermissionByModel({
449
+ modelType: Incident,
450
+ fetchModelWithAccessControlIds: async () => {
451
+ return incidentWithLabels([ObjectID.generate()]);
452
+ },
453
+ type: DatabaseRequestType.Update,
454
+ props: makeProps(labelledBlockRows),
455
+ }),
456
+ ).resolves.toBeUndefined();
457
+ });
458
+ });
459
+ });
@@ -16,12 +16,30 @@ import NotEqual from "../../../../Types/BaseDatabase/NotEqual";
16
16
  import NotNull from "../../../../Types/BaseDatabase/NotNull";
17
17
  import Search from "../../../../Types/BaseDatabase/Search";
18
18
  import DatabaseCommonInteractionProps from "../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
19
+ import DatabaseCommonInteractionPropsUtil from "../../../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
20
+ import Exception from "../../../../Types/Exception/Exception";
21
+ import ExceptionCode from "../../../../Types/Exception/ExceptionCode";
22
+ import NotAuthenticatedException from "../../../../Types/Exception/NotAuthenticatedException";
19
23
  import NotAuthorizedException from "../../../../Types/Exception/NotAuthorizedException";
20
24
  import ObjectID from "../../../../Types/ObjectID";
21
25
  import { UserTenantAccessPermission } from "../../../../Types/Permission";
26
+ import UserType from "../../../../Types/UserType";
22
27
  import { describe, expect, test } from "@jest/globals";
23
28
  import { FindOperator } from "typeorm";
24
29
 
30
+ // Runs `fn` and returns what it threw; fails the test if it returned.
31
+ const thrownBy: (fn: () => unknown) => Exception = (
32
+ fn: () => unknown,
33
+ ): Exception => {
34
+ try {
35
+ fn();
36
+ } catch (error) {
37
+ return error as Exception;
38
+ }
39
+
40
+ throw new Error("Expected the call to throw, but it returned normally.");
41
+ };
42
+
25
43
  /*
26
44
  * The forced privacy clause must survive every operator a client can smuggle
27
45
  * into query.runType. BaseAPI.getList takes `query` straight from the request
@@ -125,23 +143,97 @@ describe("getAIRunPrivacyRaw", () => {
125
143
  * project fix history — access neither /ai-run nor /code-fix-run grants.
126
144
  */
127
145
  test("rejects a caller with no user, even though CodeFix runs are shared", () => {
146
+ /*
147
+ * userType API is what ProjectAuthorization stamps on a key-authenticated
148
+ * request. Without it the props would read as anonymous (no credentials
149
+ * at all) and get the 401 below instead of this 422.
150
+ */
128
151
  const apiKeyShapedProps: DatabaseCommonInteractionProps = {
129
152
  tenantId: ObjectID.generate(),
153
+ userType: UserType.API,
130
154
  userTenantAccessPermission: {} as {
131
155
  [tenantId: string]: UserTenantAccessPermission;
132
156
  },
133
157
  };
134
158
 
135
- expect(() => {
136
- return getAIRunPrivacyRaw(apiKeyShapedProps);
137
- }).toThrow(NotAuthorizedException);
138
-
139
- expect(() => {
140
- return applyAIRunPrivacyFilter(
141
- { runType: AIRunType.CodeFix },
142
- apiKeyShapedProps,
159
+ for (const error of [
160
+ thrownBy(() => {
161
+ return getAIRunPrivacyRaw(apiKeyShapedProps);
162
+ }),
163
+ thrownBy(() => {
164
+ return applyAIRunPrivacyFilter(
165
+ { runType: AIRunType.CodeFix },
166
+ apiKeyShapedProps,
167
+ );
168
+ }),
169
+ ]) {
170
+ expect(error).toBeInstanceOf(NotAuthorizedException);
171
+ expect(error).not.toBeInstanceOf(NotAuthenticatedException);
172
+ expect(error.code).toBe(ExceptionCode.NotAuthorizedException);
173
+ expect(error.code).toBe(422);
174
+ expect(error.message).toBe(
175
+ "AI runs are personal and can only be accessed by the user who created them.",
143
176
  );
144
- }).toThrow(NotAuthorizedException);
177
+ }
178
+ });
179
+
180
+ /*
181
+ * No credentials at all is a signed-in user whose access-token cookie
182
+ * expired. The browser client refreshes the session and replays only on a
183
+ * 401, so this must not be the 422 an API key gets above.
184
+ */
185
+ test.each([
186
+ ["no props at all", {}],
187
+ [
188
+ "a tenant and tenant permissions but no user and no userType",
189
+ {
190
+ tenantId: ObjectID.generate(),
191
+ userTenantAccessPermission: {} as {
192
+ [tenantId: string]: UserTenantAccessPermission;
193
+ },
194
+ },
195
+ ],
196
+ [
197
+ "an explicitly Public caller",
198
+ { tenantId: ObjectID.generate(), userType: UserType.Public },
199
+ ],
200
+ ])(
201
+ "answers an anonymous caller (%s) with 401",
202
+ (_label: string, props: DatabaseCommonInteractionProps) => {
203
+ for (const error of [
204
+ thrownBy(() => {
205
+ return getAIRunPrivacyRaw(props);
206
+ }),
207
+ thrownBy(() => {
208
+ return applyAIRunPrivacyFilter({ runType: AIRunType.CodeFix }, props);
209
+ }),
210
+ ]) {
211
+ expect(error).toBeInstanceOf(NotAuthenticatedException);
212
+ expect(error).not.toBeInstanceOf(NotAuthorizedException);
213
+ expect(error.code).toBe(ExceptionCode.NotAuthenticatedException);
214
+ expect(error.code).toBe(401);
215
+ expect(error.message).toBe(
216
+ DatabaseCommonInteractionPropsUtil.AUTHENTICATION_REQUIRED_MESSAGE,
217
+ );
218
+ }
219
+ },
220
+ );
221
+
222
+ test("a signed-in user still gets the clause, not a refusal", () => {
223
+ const signedInUserId: ObjectID = ObjectID.generate();
224
+
225
+ const filtered: Record<string, unknown> = applyAIRunPrivacyFilter(
226
+ {},
227
+ { userId: signedInUserId, userType: UserType.User },
228
+ );
229
+
230
+ expect(filtered["runType"]).toBeInstanceOf(FindOperator);
231
+ expect(render(filtered["runType"])).toContain(`"AIRun"."userId"`);
232
+ });
233
+
234
+ test("root and master admin without a user are not refused", () => {
235
+ expect(applyAIRunPrivacyFilter({}, { isRoot: true })).toEqual({});
236
+ expect(applyAIRunPrivacyFilter({}, { isMasterAdmin: true })).toEqual({});
145
237
  });
146
238
  });
147
239