@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,708 @@
1
+ import { mockRouter } from "./Helpers";
2
+ import "../../../Server/API/AIInvestigationAPI";
3
+ import "../../../Server/API/AIInsightAPI";
4
+ import "../../../Server/API/AIReadinessAPI";
5
+ import "../../../Server/API/AutoRemediationAPI";
6
+ import CodeFixRunAPI from "../../../Server/API/CodeFixRunAPI";
7
+ import CommonAPI from "../../../Server/API/CommonAPI";
8
+ import UserMiddleware from "../../../Server/Middleware/UserAuthorization";
9
+ import AIInsightService from "../../../Server/Services/AIInsightService";
10
+ import AIRunEventService from "../../../Server/Services/AIRunEventService";
11
+ import AIRunService from "../../../Server/Services/AIRunService";
12
+ import AlertService from "../../../Server/Services/AlertService";
13
+ import AutoRemediationSuggestionService from "../../../Server/Services/AutoRemediationSuggestionService";
14
+ import IncidentService from "../../../Server/Services/IncidentService";
15
+ import LlmLogService from "../../../Server/Services/LlmLogService";
16
+ import ProjectService from "../../../Server/Services/ProjectService";
17
+ import RunbookRuleEngineService from "../../../Server/Services/RunbookRuleEngineService";
18
+ import ServiceService from "../../../Server/Services/ServiceService";
19
+ import SpanService from "../../../Server/Services/SpanService";
20
+ import CodeFixReadiness from "../../../Server/Utils/AI/CodeFix/CodeFixReadiness";
21
+ import FixFromIncidentTaskTrigger from "../../../Server/Utils/AI/SRE/FixFromIncidentTaskTrigger";
22
+ import FixPerformanceTaskTrigger from "../../../Server/Utils/AI/SRE/FixPerformanceTaskTrigger";
23
+ import InvestigationEligibility from "../../../Server/Utils/AI/SRE/InvestigationEligibility";
24
+ import TelemetryImprovementTaskTrigger from "../../../Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger";
25
+ import AIToolbox from "../../../Server/Utils/AI/Toolbox/Index";
26
+ import CommandPlanExecutor from "../../../Server/Utils/AutoRemediation/CommandPlanExecutor";
27
+ import {
28
+ ExpressRequest,
29
+ ExpressResponse,
30
+ NextFunction,
31
+ } from "../../../Server/Utils/Express";
32
+ import Response from "../../../Server/Utils/Response";
33
+ import AIInsightHumanVerdict from "../../../Types/AI/AIInsightHumanVerdict";
34
+ import AIRunHumanVerdict from "../../../Types/AI/AIRunHumanVerdict";
35
+ import CodeFixTaskType from "../../../Types/AI/CodeFixTaskType";
36
+ import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
37
+ import Dictionary from "../../../Types/Dictionary";
38
+ import ExceptionCode from "../../../Types/Exception/ExceptionCode";
39
+ import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
40
+ import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
41
+ import { JSONObject } from "../../../Types/JSON";
42
+ import ObjectID from "../../../Types/ObjectID";
43
+ import Permission, {
44
+ UserPermission,
45
+ UserTenantAccessPermission,
46
+ } from "../../../Types/Permission";
47
+ import UserType from "../../../Types/UserType";
48
+
49
+ jest.mock("../../../Server/Utils/Express", () => {
50
+ return {
51
+ getRouter: () => {
52
+ return mockRouter;
53
+ },
54
+ };
55
+ });
56
+
57
+ jest.mock("../../../Server/Utils/Response", () => {
58
+ return {
59
+ sendJsonObjectResponse: jest.fn(),
60
+ sendErrorResponse: jest.fn(),
61
+ };
62
+ });
63
+
64
+ /*
65
+ * The customer report behind this file: a Dashboard tab left open past the
66
+ * 15-minute access-token lifetime, one click, and "You are not authorized to
67
+ * access this project's data." The access-token cookie expires together with
68
+ * the JWT inside it, so the browser had simply stopped sending it.
69
+ * getUserMiddleware lets such a request through as Public - no userId, but
70
+ * the page's tenantid header - and every route below then answered it 422
71
+ * with the message above. The browser client (Common/UI/Utils/API/API.ts)
72
+ * refreshes the session and replays the request on a 401 and on nothing
73
+ * else, so a signed-in user was left looking at an authorization error.
74
+ *
75
+ * These are the AI and automation routes that act AS A PERSON (they record
76
+ * who confirmed, approved, dismissed or asked), so each requires a logged-in
77
+ * user and each now goes through CommonAPI.assertAuthenticatedUser:
78
+ *
79
+ * - no credentials at all -> 401 NotAuthenticatedException
80
+ * - a project API key (no user) -> 422 NotAuthorizedException, unchanged.
81
+ * A key is authenticated; a 401 would only send its client off to
82
+ * refresh a session it never had.
83
+ * - a logged-in user -> on to the route's own access check.
84
+ *
85
+ * Every refusal is also asserted to happen before any read, write, AI call
86
+ * or command execution.
87
+ */
88
+
89
+ const PROJECT_ID: ObjectID = new ObjectID(
90
+ "11111111-1111-4111-8111-111111111111",
91
+ );
92
+ const USER_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
93
+ const SUBJECT_ID: ObjectID = new ObjectID(
94
+ "33333333-3333-4333-8333-333333333333",
95
+ );
96
+ const RUN_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
97
+ const INSIGHT_ID: ObjectID = new ObjectID(
98
+ "55555555-5555-4555-8555-555555555555",
99
+ );
100
+ const SUGGESTION_ID: ObjectID = new ObjectID(
101
+ "66666666-6666-4666-8666-666666666666",
102
+ );
103
+ const SERVICE_ID: ObjectID = new ObjectID(
104
+ "77777777-7777-4777-8777-777777777777",
105
+ );
106
+
107
+ const USER_SESSION_REQUIRED: string = "A logged-in user session is required.";
108
+
109
+ // Every read, write, AI call or execution these routes can reach.
110
+ type SideEffect =
111
+ | "incidentRead"
112
+ | "alertRead"
113
+ | "investigationRunsRead"
114
+ | "investigationRunRead"
115
+ | "investigationVerdictWrite"
116
+ | "runEventsRead"
117
+ | "notStartedReasonRead"
118
+ | "toolExecution"
119
+ | "spansRead"
120
+ | "serviceRead"
121
+ | "fixTaskCreate"
122
+ | "performanceFixTaskCreate"
123
+ | "telemetryTaskCreate"
124
+ | "insightRead"
125
+ | "insightVerdictWrite"
126
+ | "insightResolve"
127
+ | "insightReopen"
128
+ | "insightTriageRead"
129
+ | "suggestionRead"
130
+ | "suggestionTransition"
131
+ | "commandPlanExecution"
132
+ | "runbookStart"
133
+ | "projectRead"
134
+ | "llmLogsRead"
135
+ | "readinessRead";
136
+
137
+ type HumanOnlyRoute = {
138
+ uri: string;
139
+ params: Dictionary<string>;
140
+
141
+ // A well-formed body, so a refusal is about the caller and never the input.
142
+ body: JSONObject;
143
+
144
+ // What a project API key is told: authenticated, but not a person.
145
+ notAUserMessage: string;
146
+
147
+ // The access-checked read a logged-in caller reaches first.
148
+ firstRead: SideEffect;
149
+ };
150
+
151
+ const AI_INVESTIGATION_ROUTES: Array<HumanOnlyRoute> = [
152
+ {
153
+ uri: "/ai-investigation/incident",
154
+ params: {},
155
+ body: { incidentId: SUBJECT_ID.toString() },
156
+ notAUserMessage: USER_SESSION_REQUIRED,
157
+ firstRead: "incidentRead",
158
+ },
159
+ {
160
+ uri: "/ai-investigation/alert",
161
+ params: {},
162
+ body: { alertId: SUBJECT_ID.toString() },
163
+ notAUserMessage: USER_SESSION_REQUIRED,
164
+ firstRead: "alertRead",
165
+ },
166
+ {
167
+ uri: "/ai-investigation/evidence",
168
+ params: {},
169
+ body: {
170
+ subjectType: "incident",
171
+ subjectId: SUBJECT_ID.toString(),
172
+ investigationRunId: RUN_ID.toString(),
173
+ citationId: "C1",
174
+ },
175
+ notAUserMessage: USER_SESSION_REQUIRED,
176
+ firstRead: "incidentRead",
177
+ },
178
+ {
179
+ uri: "/ai-investigation/verdict",
180
+ params: {},
181
+ body: {
182
+ subjectType: "incident",
183
+ subjectId: SUBJECT_ID.toString(),
184
+ investigationRunId: RUN_ID.toString(),
185
+ verdict: AIRunHumanVerdict.Confirmed,
186
+ },
187
+ notAUserMessage: USER_SESSION_REQUIRED,
188
+ firstRead: "incidentRead",
189
+ },
190
+ {
191
+ uri: "/ai-investigation/create-fix-task",
192
+ params: {},
193
+ body: {
194
+ subjectType: "alert",
195
+ subjectId: SUBJECT_ID.toString(),
196
+ investigationRunId: RUN_ID.toString(),
197
+ },
198
+ notAUserMessage: USER_SESSION_REQUIRED,
199
+ firstRead: "alertRead",
200
+ },
201
+ {
202
+ uri: "/ai-investigation/create-performance-fix-task",
203
+ params: {},
204
+ body: { traceId: "4bf92f3577b34da6a3ce929d0e0e4736" },
205
+ notAUserMessage: USER_SESSION_REQUIRED,
206
+ firstRead: "spansRead",
207
+ },
208
+ {
209
+ uri: "/ai-investigation/create-telemetry-improvement-task",
210
+ params: {},
211
+ body: {
212
+ telemetryServiceId: SERVICE_ID.toString(),
213
+ taskType: CodeFixTaskType.ImproveLogging,
214
+ },
215
+ notAUserMessage: USER_SESSION_REQUIRED,
216
+ firstRead: "serviceRead",
217
+ },
218
+ ];
219
+
220
+ const AI_INSIGHT_ROUTES: Array<HumanOnlyRoute> = [
221
+ {
222
+ uri: "/ai-insight/verdict",
223
+ params: {},
224
+ body: {
225
+ insightId: INSIGHT_ID.toString(),
226
+ verdict: AIInsightHumanVerdict.Confirmed,
227
+ },
228
+ notAUserMessage: USER_SESSION_REQUIRED,
229
+ firstRead: "insightRead",
230
+ },
231
+ {
232
+ uri: "/ai-insight/resolve",
233
+ params: {},
234
+ body: { insightId: INSIGHT_ID.toString() },
235
+ notAUserMessage: USER_SESSION_REQUIRED,
236
+ firstRead: "insightRead",
237
+ },
238
+ {
239
+ uri: "/ai-insight/reopen",
240
+ params: {},
241
+ body: { insightId: INSIGHT_ID.toString() },
242
+ notAUserMessage: USER_SESSION_REQUIRED,
243
+ firstRead: "insightRead",
244
+ },
245
+ {
246
+ uri: "/ai-insight/triage-run",
247
+ params: {},
248
+ body: { insightId: INSIGHT_ID.toString() },
249
+ notAUserMessage: USER_SESSION_REQUIRED,
250
+ firstRead: "insightRead",
251
+ },
252
+ ];
253
+
254
+ const AUTO_REMEDIATION_ROUTES: Array<HumanOnlyRoute> = [
255
+ {
256
+ uri: "/auto-remediation/approve",
257
+ params: {},
258
+ body: { suggestionId: SUGGESTION_ID.toString() },
259
+ notAUserMessage: USER_SESSION_REQUIRED,
260
+ firstRead: "suggestionRead",
261
+ },
262
+ {
263
+ uri: "/auto-remediation/dismiss",
264
+ params: {},
265
+ body: { suggestionId: SUGGESTION_ID.toString() },
266
+ notAUserMessage: USER_SESSION_REQUIRED,
267
+ firstRead: "suggestionRead",
268
+ },
269
+ ];
270
+
271
+ const CODE_FIX_RUN_ROUTES: Array<HumanOnlyRoute> = [
272
+ {
273
+ uri: "/code-fix-run/get/:runId",
274
+ params: { runId: RUN_ID.toString() },
275
+ body: {},
276
+ notAUserMessage: USER_SESSION_REQUIRED,
277
+ firstRead: "projectRead",
278
+ },
279
+ {
280
+ uri: "/code-fix-run/logs/:runId",
281
+ params: { runId: RUN_ID.toString() },
282
+ body: {},
283
+ notAUserMessage: USER_SESSION_REQUIRED,
284
+ firstRead: "projectRead",
285
+ },
286
+ ];
287
+
288
+ const AI_READINESS_ROUTES: Array<HumanOnlyRoute> = [
289
+ {
290
+ uri: "/ai-readiness/code-fix",
291
+ params: {},
292
+ body: {},
293
+ // This route words its refusal for its own page.
294
+ notAUserMessage: "AI readiness requires a logged-in user session.",
295
+ firstRead: "readinessRead",
296
+ },
297
+ ];
298
+
299
+ const ALL_ROUTES: Array<HumanOnlyRoute> = [
300
+ ...AI_INVESTIGATION_ROUTES,
301
+ ...AI_INSIGHT_ROUTES,
302
+ ...AUTO_REMEDIATION_ROUTES,
303
+ ...CODE_FIX_RUN_ROUTES,
304
+ ...AI_READINESS_ROUTES,
305
+ ];
306
+
307
+ function tenantPermissions(
308
+ permissions: Array<Permission>,
309
+ ): Dictionary<UserTenantAccessPermission> {
310
+ const dictionary: Dictionary<UserTenantAccessPermission> = {};
311
+
312
+ dictionary[PROJECT_ID.toString()] = {
313
+ _type: "UserTenantAccessPermission",
314
+ projectId: PROJECT_ID,
315
+ permissions: permissions.map((permission: Permission) => {
316
+ return {
317
+ _type: "UserPermission",
318
+ permission: permission,
319
+ labelIds: [],
320
+ isBlockPermission: false,
321
+ } as UserPermission;
322
+ }),
323
+ isBlockPermission: false,
324
+ } as UserTenantAccessPermission;
325
+
326
+ return dictionary;
327
+ }
328
+
329
+ /*
330
+ * The request an expired session produces, as getDatabaseCommonInteractionProps
331
+ * builds it: Public, no user, the page's tenantid header.
332
+ */
333
+ function expiredSessionProps(): DatabaseCommonInteractionProps {
334
+ return {
335
+ tenantId: PROJECT_ID,
336
+ userType: UserType.Public,
337
+ userId: undefined,
338
+ userTenantAccessPermission: undefined,
339
+ };
340
+ }
341
+
342
+ /*
343
+ * A project API key: no userId, userType API, and the grants
344
+ * ProjectMiddleware attached to the key itself - here, everything.
345
+ */
346
+ function apiKeyProps(): DatabaseCommonInteractionProps {
347
+ return {
348
+ tenantId: PROJECT_ID,
349
+ userType: UserType.API,
350
+ userId: undefined,
351
+ userTenantAccessPermission: tenantPermissions([Permission.ProjectOwner]),
352
+ };
353
+ }
354
+
355
+ // A signed-in project owner whose session is still valid.
356
+ function memberProps(): DatabaseCommonInteractionProps {
357
+ return {
358
+ tenantId: PROJECT_ID,
359
+ userType: UserType.User,
360
+ userId: USER_ID,
361
+ userTenantAccessPermission: tenantPermissions([Permission.ProjectOwner]),
362
+ };
363
+ }
364
+
365
+ function withProps(props: DatabaseCommonInteractionProps): void {
366
+ jest
367
+ .spyOn(CommonAPI, "getDatabaseCommonInteractionProps")
368
+ .mockResolvedValue(props);
369
+ }
370
+
371
+ type RouteCall = {
372
+ thrown: unknown;
373
+ nextCallCount: number;
374
+ };
375
+
376
+ async function callRoute(route: HumanOnlyRoute): Promise<RouteCall> {
377
+ const req: ExpressRequest = {
378
+ params: route.params,
379
+ query: {},
380
+ body: route.body,
381
+ headers: {},
382
+ } as unknown as ExpressRequest;
383
+
384
+ const next: jest.Mock = jest.fn();
385
+
386
+ await mockRouter
387
+ .match("post", route.uri)
388
+ .handlerFunction(
389
+ req,
390
+ {} as ExpressResponse,
391
+ next as unknown as NextFunction,
392
+ );
393
+
394
+ return {
395
+ thrown: next.mock.calls[0] ? next.mock.calls[0][0] : undefined,
396
+ nextCallCount: next.mock.calls.length,
397
+ };
398
+ }
399
+
400
+ let sideEffects: Record<SideEffect, jest.SpyInstance>;
401
+
402
+ /*
403
+ * Every downstream call is stubbed to something harmless ("not found",
404
+ * "nothing to do"), so no path can fall through to a real database, model
405
+ * provider or Runner, and each one can be asserted as never reached.
406
+ */
407
+ function stubSideEffects(): Record<SideEffect, jest.SpyInstance> {
408
+ return {
409
+ incidentRead: jest
410
+ .spyOn(IncidentService, "findOneById")
411
+ .mockResolvedValue(null),
412
+ alertRead: jest.spyOn(AlertService, "findOneById").mockResolvedValue(null),
413
+ investigationRunsRead: jest
414
+ .spyOn(AIRunService, "findBy")
415
+ .mockResolvedValue([]),
416
+ investigationRunRead: jest
417
+ .spyOn(AIRunService, "findOneBy")
418
+ .mockResolvedValue(null),
419
+ investigationVerdictWrite: jest
420
+ .spyOn(AIRunService, "applyHumanVerdictToInvestigation")
421
+ .mockResolvedValue(undefined as never),
422
+ runEventsRead: jest
423
+ .spyOn(AIRunEventService, "findBy")
424
+ .mockResolvedValue([]),
425
+ notStartedReasonRead: jest
426
+ .spyOn(InvestigationEligibility, "getNotStartedReason")
427
+ .mockResolvedValue(undefined as never),
428
+ toolExecution: jest
429
+ .spyOn(AIToolbox, "executeTool")
430
+ .mockResolvedValue(undefined as never),
431
+ spansRead: jest.spyOn(SpanService, "findBy").mockResolvedValue([]),
432
+ serviceRead: jest
433
+ .spyOn(ServiceService, "findOneById")
434
+ .mockResolvedValue(null),
435
+ fixTaskCreate: jest
436
+ .spyOn(FixFromIncidentTaskTrigger, "createFixTaskFromInvestigation")
437
+ .mockResolvedValue(undefined as never),
438
+ performanceFixTaskCreate: jest
439
+ .spyOn(FixPerformanceTaskTrigger, "createPerformanceFixTaskFromTrace")
440
+ .mockResolvedValue(undefined as never),
441
+ telemetryTaskCreate: jest
442
+ .spyOn(TelemetryImprovementTaskTrigger, "createTelemetryImprovementTask")
443
+ .mockResolvedValue(undefined as never),
444
+ insightRead: jest
445
+ .spyOn(AIInsightService, "findOneById")
446
+ .mockResolvedValue(null),
447
+ insightVerdictWrite: jest
448
+ .spyOn(AIInsightService, "applyHumanVerdict")
449
+ .mockResolvedValue(undefined as never),
450
+ insightResolve: jest
451
+ .spyOn(AIInsightService, "resolveInsight")
452
+ .mockResolvedValue(undefined as never),
453
+ insightReopen: jest
454
+ .spyOn(AIInsightService, "reopenInsight")
455
+ .mockResolvedValue(undefined as never),
456
+ insightTriageRead: jest
457
+ .spyOn(AIInsightService, "getLatestTriageRunWithEvents")
458
+ .mockResolvedValue(undefined as never),
459
+ suggestionRead: jest
460
+ .spyOn(AutoRemediationSuggestionService, "findOneById")
461
+ .mockResolvedValue(null),
462
+ suggestionTransition: jest
463
+ .spyOn(AutoRemediationSuggestionService, "attemptStatusTransition")
464
+ .mockResolvedValue(0),
465
+ commandPlanExecution: jest
466
+ .spyOn(CommandPlanExecutor, "executeApprovedPlan")
467
+ .mockResolvedValue(undefined as never),
468
+ runbookStart: jest
469
+ .spyOn(RunbookRuleEngineService, "startRunbookFor")
470
+ .mockResolvedValue(undefined as never),
471
+ projectRead: jest
472
+ .spyOn(ProjectService, "findOneById")
473
+ .mockResolvedValue(null),
474
+ llmLogsRead: jest.spyOn(LlmLogService, "findBy").mockResolvedValue([]),
475
+ readinessRead: jest
476
+ .spyOn(CodeFixReadiness, "getProjectReadiness")
477
+ .mockResolvedValue({ ready: true, checks: [] } as never),
478
+ };
479
+ }
480
+
481
+ function expectNothingReached(): void {
482
+ for (const name of Object.keys(sideEffects) as Array<SideEffect>) {
483
+ expect({ [name]: sideEffects[name].mock.calls.length }).toEqual({
484
+ [name]: 0,
485
+ });
486
+ }
487
+
488
+ expect(Response.sendJsonObjectResponse).not.toHaveBeenCalled();
489
+ expect(Response.sendErrorResponse).not.toHaveBeenCalled();
490
+ }
491
+
492
+ function expectAuthenticationRequired(call: RouteCall): void {
493
+ expect(call.nextCallCount).toBe(1);
494
+ expect(call.thrown).toBeInstanceOf(NotAuthenticatedException);
495
+ expect(call.thrown).not.toBeInstanceOf(NotAuthorizedException);
496
+ expect((call.thrown as NotAuthenticatedException).code).toBe(
497
+ ExceptionCode.NotAuthenticatedException,
498
+ );
499
+ expect((call.thrown as NotAuthenticatedException).message).toBe(
500
+ CommonAPI.AUTHENTICATION_REQUIRED_MESSAGE,
501
+ );
502
+ }
503
+
504
+ beforeAll(() => {
505
+ new CodeFixRunAPI();
506
+ });
507
+
508
+ beforeEach(() => {
509
+ jest.restoreAllMocks();
510
+ jest.clearAllMocks();
511
+ sideEffects = stubSideEffects();
512
+ });
513
+
514
+ afterEach(() => {
515
+ jest.restoreAllMocks();
516
+ });
517
+
518
+ describe("the table covers every route these APIs register", () => {
519
+ /*
520
+ * A new person-only route added to one of these APIs must join the table
521
+ * (and so inherit every assertion below) or fail here.
522
+ */
523
+ test("every /ai-investigation, /ai-insight, /auto-remediation, /code-fix-run and /ai-readiness route is in the table", () => {
524
+ const prefixes: Array<string> = [
525
+ "/ai-investigation/",
526
+ "/ai-insight/",
527
+ "/auto-remediation/",
528
+ "/code-fix-run/",
529
+ "/ai-readiness/",
530
+ ];
531
+
532
+ const registered: Array<string> = mockRouter.routes
533
+ .filter((route: { uri: string }) => {
534
+ return prefixes.some((prefix: string) => {
535
+ return route.uri.startsWith(prefix);
536
+ });
537
+ })
538
+ .map((route: { uri: string }) => {
539
+ return route.uri;
540
+ })
541
+ .sort();
542
+
543
+ const covered: Array<string> = ALL_ROUTES.map((route: HumanOnlyRoute) => {
544
+ return route.uri;
545
+ }).sort();
546
+
547
+ expect(registered).toEqual(covered);
548
+ });
549
+ });
550
+
551
+ describe.each(ALL_ROUTES)(
552
+ "POST $uri with an expired session",
553
+ (route: HumanOnlyRoute) => {
554
+ /*
555
+ * getUserMiddleware is a context loader, not a gate, which is why the
556
+ * handler has to answer the anonymous caller itself.
557
+ */
558
+ test("is mounted behind getUserMiddleware, so an anonymous request reaches the handler", () => {
559
+ expect(mockRouter.match("post", route.uri).middlewares).toEqual([
560
+ UserMiddleware.getUserMiddleware,
561
+ ]);
562
+ });
563
+
564
+ test("answers a caller with no credentials (only a tenantid header) with 401, not 422", async () => {
565
+ withProps(expiredSessionProps());
566
+
567
+ const call: RouteCall = await callRoute(route);
568
+
569
+ expectAuthenticationRequired(call);
570
+ expectNothingReached();
571
+ });
572
+
573
+ test("answers a caller with no credentials and no tenantid header with 401, not 400", async () => {
574
+ withProps({ userType: UserType.Public });
575
+
576
+ const call: RouteCall = await callRoute(route);
577
+
578
+ expectAuthenticationRequired(call);
579
+ expectNothingReached();
580
+ });
581
+
582
+ test("answers a caller getUserMiddleware left unclassified with 401", async () => {
583
+ withProps({ tenantId: PROJECT_ID });
584
+
585
+ const call: RouteCall = await callRoute(route);
586
+
587
+ expectAuthenticationRequired(call);
588
+ expectNothingReached();
589
+ });
590
+
591
+ /*
592
+ * Tenant grants on a request with no user, no key and no master-admin
593
+ * session prove nothing about who sent it.
594
+ */
595
+ test("does not let stray tenant permissions stand in for a credential", async () => {
596
+ withProps({
597
+ ...expiredSessionProps(),
598
+ userTenantAccessPermission: tenantPermissions([
599
+ Permission.ProjectOwner,
600
+ ]),
601
+ });
602
+
603
+ const call: RouteCall = await callRoute(route);
604
+
605
+ expectAuthenticationRequired(call);
606
+ expectNothingReached();
607
+ });
608
+
609
+ test("still refuses a project API key with 422 - it is authenticated, just not a person", async () => {
610
+ withProps(apiKeyProps());
611
+
612
+ const call: RouteCall = await callRoute(route);
613
+
614
+ expect(call.nextCallCount).toBe(1);
615
+ expect(call.thrown).toBeInstanceOf(NotAuthorizedException);
616
+ expect(call.thrown).not.toBeInstanceOf(NotAuthenticatedException);
617
+ expect((call.thrown as NotAuthorizedException).code).toBe(
618
+ ExceptionCode.NotAuthorizedException,
619
+ );
620
+ expect((call.thrown as NotAuthorizedException).message).toBe(
621
+ route.notAUserMessage,
622
+ );
623
+ expectNothingReached();
624
+ });
625
+
626
+ test("lets a signed-in user through to the route's own access check", async () => {
627
+ withProps(memberProps());
628
+
629
+ const call: RouteCall = await callRoute(route);
630
+
631
+ expect(sideEffects[route.firstRead]).toHaveBeenCalled();
632
+ expect(call.thrown).not.toBeInstanceOf(NotAuthenticatedException);
633
+ expect((call.thrown as Error | undefined)?.message).not.toBe(
634
+ route.notAUserMessage,
635
+ );
636
+ });
637
+ },
638
+ );
639
+
640
+ /*
641
+ * The refusal must not depend on the body. An expired session replays
642
+ * exactly what the page sent, and the client can only recover from a 401 -
643
+ * so an anonymous caller is told to authenticate even when its body would
644
+ * also have been rejected.
645
+ */
646
+ describe.each(ALL_ROUTES)(
647
+ "POST $uri - order of checks",
648
+ (route: HumanOnlyRoute) => {
649
+ test("an anonymous caller with an empty body still gets 401 rather than a validation error", async () => {
650
+ withProps(expiredSessionProps());
651
+
652
+ const call: RouteCall = await callRoute({
653
+ ...route,
654
+ body: {},
655
+ params: {},
656
+ });
657
+
658
+ expectAuthenticationRequired(call);
659
+ expectNothingReached();
660
+ });
661
+ },
662
+ );
663
+
664
+ describe("the refusals end-users actually hit", () => {
665
+ test("a signed-in user on /ai-readiness/code-fix gets the readiness report", async () => {
666
+ withProps(memberProps());
667
+
668
+ const call: RouteCall = await callRoute(
669
+ AI_READINESS_ROUTES[0] as HumanOnlyRoute,
670
+ );
671
+
672
+ expect(call.nextCallCount).toBe(0);
673
+ expect(sideEffects.readinessRead).toHaveBeenCalledWith({
674
+ projectId: PROJECT_ID,
675
+ });
676
+ expect(Response.sendJsonObjectResponse).toHaveBeenCalledTimes(1);
677
+ });
678
+
679
+ test("the code-fix-run access check reads the project under the user's own props", async () => {
680
+ const props: DatabaseCommonInteractionProps = memberProps();
681
+ withProps(props);
682
+
683
+ await callRoute(CODE_FIX_RUN_ROUTES[0] as HumanOnlyRoute);
684
+
685
+ expect(sideEffects.projectRead).toHaveBeenCalledWith(
686
+ expect.objectContaining({ id: PROJECT_ID, props: props }),
687
+ );
688
+ });
689
+
690
+ test("an AI insight action by a signed-in user is recorded against that user", async () => {
691
+ withProps(memberProps());
692
+ sideEffects.insightRead.mockResolvedValue({ id: INSIGHT_ID } as never);
693
+ sideEffects.insightResolve.mockResolvedValue({
694
+ insightId: INSIGHT_ID,
695
+ status: "Resolved",
696
+ } as never);
697
+
698
+ const call: RouteCall = await callRoute(
699
+ AI_INSIGHT_ROUTES[1] as HumanOnlyRoute,
700
+ );
701
+
702
+ expect(call.nextCallCount).toBe(0);
703
+ expect(sideEffects.insightResolve).toHaveBeenCalledWith({
704
+ insightId: INSIGHT_ID,
705
+ byUserId: USER_ID,
706
+ });
707
+ });
708
+ });