@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,247 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
2
+ import DatabaseConfig from "../../../../../../Server/DatabaseConfig";
3
+ import ScheduledMaintenanceService from "../../../../../../Server/Services/ScheduledMaintenanceService";
4
+ import SlackActionType from "../../../../../../Server/Utils/Workspace/Slack/Actions/ActionTypes";
5
+ import SlackScheduledMaintenanceMessages from "../../../../../../Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance";
6
+ import Hostname from "../../../../../../Types/API/Hostname";
7
+ import Protocol from "../../../../../../Types/API/Protocol";
8
+ import BadDataException from "../../../../../../Types/Exception/BadDataException";
9
+ import ObjectID from "../../../../../../Types/ObjectID";
10
+ import {
11
+ WorkspaceMessageBlock,
12
+ WorkspaceMessagePayloadButton,
13
+ WorkspacePayloadButtons,
14
+ } from "../../../../../../Types/Workspace/WorkspaceMessagePayload";
15
+
16
+ const getButtons: (
17
+ blocks: Array<WorkspaceMessageBlock>,
18
+ ) => Array<WorkspaceMessagePayloadButton> = (
19
+ blocks: Array<WorkspaceMessageBlock>,
20
+ ): Array<WorkspaceMessagePayloadButton> => {
21
+ return (blocks[1] as WorkspacePayloadButtons).buttons;
22
+ };
23
+
24
+ describe("SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks", () => {
25
+ const projectId: ObjectID = ObjectID.generate();
26
+ const scheduledMaintenanceId: ObjectID = ObjectID.generate();
27
+
28
+ beforeEach(() => {
29
+ jest
30
+ .spyOn(DatabaseConfig, "getHost")
31
+ .mockResolvedValue(new Hostname("oneuptime.test"));
32
+ jest
33
+ .spyOn(DatabaseConfig, "getHttpProtocol")
34
+ .mockResolvedValue(Protocol.HTTPS);
35
+ });
36
+
37
+ afterEach(() => {
38
+ jest.restoreAllMocks();
39
+ });
40
+
41
+ test("returns a divider followed by a single buttons block", async () => {
42
+ const blocks: Array<WorkspaceMessageBlock> =
43
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
44
+ {
45
+ scheduledMaintenanceId,
46
+ projectId,
47
+ },
48
+ );
49
+
50
+ expect(blocks).toHaveLength(2);
51
+ expect(blocks[0]).toEqual({ _type: "WorkspacePayloadDivider" });
52
+ expect(blocks[1]!._type).toBe("WorkspacePayloadButtons");
53
+ });
54
+
55
+ test("emits the 5 buttons in order with the expected action ids and titles", async () => {
56
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
57
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
58
+ {
59
+ scheduledMaintenanceId,
60
+ projectId,
61
+ },
62
+ ),
63
+ );
64
+
65
+ expect(
66
+ buttons.map((button: WorkspaceMessagePayloadButton) => {
67
+ return button.actionId;
68
+ }),
69
+ ).toEqual([
70
+ SlackActionType.ViewScheduledMaintenance,
71
+ SlackActionType.MarkScheduledMaintenanceAsOngoing,
72
+ SlackActionType.MarkScheduledMaintenanceAsComplete,
73
+ SlackActionType.ViewChangeScheduledMaintenanceState,
74
+ SlackActionType.ViewAddScheduledMaintenanceNote,
75
+ ]);
76
+
77
+ expect(
78
+ buttons.map((button: WorkspaceMessagePayloadButton) => {
79
+ return button.title;
80
+ }),
81
+ ).toEqual([
82
+ "🔗 View Event",
83
+ "⌛ Mark as Ongoing",
84
+ "✅ Mark as Completed",
85
+ "➡️ Change State",
86
+ "📄 Add Note",
87
+ ]);
88
+ });
89
+
90
+ test("every button carries the scheduled maintenance id as its value", async () => {
91
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
92
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
93
+ {
94
+ scheduledMaintenanceId,
95
+ projectId,
96
+ },
97
+ ),
98
+ );
99
+
100
+ expect(buttons).toHaveLength(5);
101
+
102
+ for (const button of buttons) {
103
+ expect(button._type).toBe("WorkspaceMessagePayloadButton");
104
+ expect(button.value).toBe(scheduledMaintenanceId.toString());
105
+ expect(button.value).not.toBe(projectId.toString());
106
+ }
107
+ });
108
+
109
+ test("only the view button links to the scheduled maintenance page in the dashboard", async () => {
110
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
111
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
112
+ {
113
+ scheduledMaintenanceId,
114
+ projectId,
115
+ },
116
+ ),
117
+ );
118
+
119
+ expect(buttons[0]!.url?.toString()).toBe(
120
+ `https://oneuptime.test/dashboard/${projectId.toString()}/scheduled-maintenance-events/${scheduledMaintenanceId.toString()}`,
121
+ );
122
+
123
+ for (const button of buttons.slice(1)) {
124
+ expect(button.url).toBeUndefined();
125
+ }
126
+ });
127
+
128
+ test("asks ScheduledMaintenanceService for the link with the project and scheduled maintenance ids", async () => {
129
+ const linkSpy: jest.SpiedFunction<
130
+ typeof ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard
131
+ > = jest.spyOn(
132
+ ScheduledMaintenanceService,
133
+ "getScheduledMaintenanceLinkInDashboard",
134
+ );
135
+
136
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
137
+ {
138
+ scheduledMaintenanceId,
139
+ projectId,
140
+ },
141
+ );
142
+
143
+ expect(linkSpy).toHaveBeenCalledTimes(1);
144
+ expect(linkSpy).toHaveBeenCalledWith(projectId, scheduledMaintenanceId);
145
+ });
146
+
147
+ test("throws BadDataException when the scheduled maintenance id is missing", async () => {
148
+ const linkSpy: jest.SpiedFunction<
149
+ typeof ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard
150
+ > = jest.spyOn(
151
+ ScheduledMaintenanceService,
152
+ "getScheduledMaintenanceLinkInDashboard",
153
+ );
154
+
155
+ await expect(
156
+ SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
157
+ {
158
+ scheduledMaintenanceId: undefined as unknown as ObjectID,
159
+ projectId,
160
+ },
161
+ ),
162
+ ).rejects.toThrow(
163
+ new BadDataException("ScheduledMaintenance ID is required"),
164
+ );
165
+
166
+ expect(linkSpy).not.toHaveBeenCalled();
167
+ });
168
+
169
+ test("throws BadDataException when the project id is missing", async () => {
170
+ await expect(
171
+ SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
172
+ {
173
+ scheduledMaintenanceId,
174
+ projectId: undefined as unknown as ObjectID,
175
+ },
176
+ ),
177
+ ).rejects.toThrow(new BadDataException("projectId is required"));
178
+ });
179
+
180
+ test("propagates a failure while building the dashboard link", async () => {
181
+ jest
182
+ .spyOn(
183
+ ScheduledMaintenanceService,
184
+ "getScheduledMaintenanceLinkInDashboard",
185
+ )
186
+ .mockRejectedValue(new Error("dashboard url unavailable"));
187
+
188
+ await expect(
189
+ SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
190
+ {
191
+ scheduledMaintenanceId,
192
+ projectId,
193
+ },
194
+ ),
195
+ ).rejects.toThrow("dashboard url unavailable");
196
+ });
197
+
198
+ test("builds a fresh block list for each scheduled maintenance", async () => {
199
+ const otherId: ObjectID = ObjectID.generate();
200
+
201
+ const first: Array<WorkspaceMessageBlock> =
202
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
203
+ {
204
+ scheduledMaintenanceId,
205
+ projectId,
206
+ },
207
+ );
208
+ const second: Array<WorkspaceMessageBlock> =
209
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
210
+ {
211
+ scheduledMaintenanceId: otherId,
212
+ projectId,
213
+ },
214
+ );
215
+
216
+ expect(first).not.toBe(second);
217
+ expect(getButtons(first)[0]!.value).toBe(scheduledMaintenanceId.toString());
218
+ expect(getButtons(second)[0]!.value).toBe(otherId.toString());
219
+ expect(getButtons(second)[0]!.url?.toString()).toContain(
220
+ `/scheduled-maintenance-events/${otherId.toString()}`,
221
+ );
222
+ });
223
+
224
+ test("does not offer on-call execution or acknowledge buttons", async () => {
225
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
226
+ await SlackScheduledMaintenanceMessages.getScheduledMaintenanceCreateMessageBlocks(
227
+ {
228
+ scheduledMaintenanceId,
229
+ projectId,
230
+ },
231
+ ),
232
+ );
233
+
234
+ const titles: Array<string> = buttons.map(
235
+ (button: WorkspaceMessagePayloadButton) => {
236
+ return button.title;
237
+ },
238
+ );
239
+
240
+ expect(titles).not.toContain("📞 Execute On Call");
241
+ expect(
242
+ titles.some((title: string) => {
243
+ return title.includes("Acknowledge");
244
+ }),
245
+ ).toBe(false);
246
+ });
247
+ });
@@ -0,0 +1,206 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import AIInsightEvidence, {
3
+ ExceptionInsightEvidence,
4
+ LatencyInsightEvidence,
5
+ LogSpikeInsightEvidence,
6
+ MetricDriftInsightEvidence,
7
+ } from "../../../Types/AI/AIInsightEvidence";
8
+ import AIInsightType from "../../../Types/AI/AIInsightType";
9
+ import { PerformanceFindingType } from "../../../Types/AI/CodeFixTaskContext";
10
+
11
+ /*
12
+ * AIInsightEvidence is the JSON persisted verbatim on AIInsight.evidence and
13
+ * rendered long after the raw ClickHouse signals have expired. It is a pure
14
+ * type module, so these tests pin the wire contract in the two ways that
15
+ * matter: every AIInsightType maps to exactly one evidence section (checked
16
+ * exhaustively by the compiler via Record<AIInsightType, ...>), and each
17
+ * section survives a JSON round trip with its real numbers intact.
18
+ */
19
+
20
+ type EvidenceSection = keyof AIInsightEvidence;
21
+
22
+ /*
23
+ * The compiler rejects this map if an AIInsightType is added without deciding
24
+ * which evidence section carries it, or if a section key is renamed.
25
+ */
26
+ const SECTION_FOR_TYPE: Record<AIInsightType, EvidenceSection> = {
27
+ [AIInsightType.NewException]: "exception",
28
+ [AIInsightType.ExceptionSpike]: "exception",
29
+ [AIInsightType.ErrorLogSpike]: "logSpike",
30
+ [AIInsightType.TraceLatencyRegression]: "latency",
31
+ [AIInsightType.MetricDrift]: "metricDrift",
32
+ };
33
+
34
+ const ALL_SECTIONS: Array<EvidenceSection> = [
35
+ "exception",
36
+ "logSpike",
37
+ "latency",
38
+ "metricDrift",
39
+ ];
40
+
41
+ const setSections: (evidence: AIInsightEvidence) => Array<string> = (
42
+ evidence: AIInsightEvidence,
43
+ ): Array<string> => {
44
+ return Object.keys(evidence).filter((key: string) => {
45
+ return evidence[key as EvidenceSection] !== undefined;
46
+ });
47
+ };
48
+
49
+ const roundTrip: (evidence: AIInsightEvidence) => AIInsightEvidence = (
50
+ evidence: AIInsightEvidence,
51
+ ): AIInsightEvidence => {
52
+ return JSON.parse(JSON.stringify(evidence)) as AIInsightEvidence;
53
+ };
54
+
55
+ const exceptionEvidence: ExceptionInsightEvidence = {
56
+ exceptionMessage: "Cannot read properties of undefined (reading 'id')",
57
+ exceptionType: "TypeError",
58
+ recentOccurrenceCount: 42,
59
+ baselineHourlyAverage: 1.5,
60
+ spikeMultiplier: 28,
61
+ totalOccurrenceCount: 1200,
62
+ distinctExceptionGroupCount: 3,
63
+ firstSeenAt: "2026-09-18T10:00:00.000Z",
64
+ };
65
+
66
+ const logSpikeEvidence: LogSpikeInsightEvidence = {
67
+ recentErrorCount: 900,
68
+ baselineHourlyAverage: 30,
69
+ spikeMultiplier: 30,
70
+ windowMinutes: 60,
71
+ topServices: [
72
+ { serviceName: "checkout", count: 700 },
73
+ { serviceName: "payments", count: 200 },
74
+ ],
75
+ };
76
+
77
+ const latencyEvidence: LatencyInsightEvidence = {
78
+ recentP99Ms: 2400,
79
+ baselineP99Ms: 300,
80
+ regressionMultiplier: 8,
81
+ operationName: "GET /orders",
82
+ sampleTraceId: "4bf92f3577b34da6a3ce929d0e0e4736",
83
+ performanceFindings: [
84
+ {
85
+ findingType: PerformanceFindingType.NPlusOneQuery,
86
+ headline: 'N+1: 27x "SELECT users" under "GET /orders"',
87
+ evidence: "27 sibling spans, 1900ms combined",
88
+ spanCount: 27,
89
+ combinedDurationMs: 1900,
90
+ traceDurationMs: 2400,
91
+ percentOfTrace: 79.2,
92
+ normalizedSpanName: "SELECT users",
93
+ parentSpanName: "GET /orders",
94
+ normalizedDbStatement: "SELECT * FROM users WHERE id = ?",
95
+ dbSystem: "postgresql",
96
+ implicatedSpans: [
97
+ { spanId: "00f067aa0ba902b7", name: "SELECT users", durationMs: 70 },
98
+ ],
99
+ },
100
+ ],
101
+ codeLocations: [
102
+ {
103
+ filePath: "src/orders/list.ts",
104
+ functionName: "listOrders",
105
+ lineNumber: 88,
106
+ },
107
+ ],
108
+ };
109
+
110
+ const metricDriftEvidence: MetricDriftInsightEvidence = {
111
+ metricName: "http.server.request.duration",
112
+ primaryEntityId: "7e6a3c1a-1111-4222-8333-944455556666",
113
+ recentWeekMean: 150,
114
+ priorWeekMean: 100,
115
+ relativeChangePercent: 50,
116
+ recentSampleCount: 10080,
117
+ priorSampleCount: 10080,
118
+ };
119
+
120
+ describe("AIInsightEvidence", () => {
121
+ test("every insight type maps to a known evidence section", () => {
122
+ for (const type of Object.values(AIInsightType)) {
123
+ expect(ALL_SECTIONS).toContain(SECTION_FOR_TYPE[type]);
124
+ }
125
+ });
126
+
127
+ test("every evidence section is used by at least one insight type", () => {
128
+ const used: Set<EvidenceSection> = new Set(Object.values(SECTION_FOR_TYPE));
129
+ expect([...used].sort()).toEqual([...ALL_SECTIONS].sort());
130
+ });
131
+
132
+ test("an empty evidence object is valid (all sections optional)", () => {
133
+ const evidence: AIInsightEvidence = {};
134
+ expect(setSections(evidence)).toEqual([]);
135
+ expect(roundTrip(evidence)).toEqual({});
136
+ });
137
+
138
+ test.each([
139
+ ["exception", { exception: exceptionEvidence }],
140
+ ["logSpike", { logSpike: logSpikeEvidence }],
141
+ ["latency", { latency: latencyEvidence }],
142
+ ["metricDrift", { metricDrift: metricDriftEvidence }],
143
+ ] as Array<[EvidenceSection, AIInsightEvidence]>)(
144
+ "%s evidence survives a JSON round trip with exactly one section set",
145
+ (section: EvidenceSection, evidence: AIInsightEvidence) => {
146
+ expect(setSections(evidence)).toEqual([section]);
147
+ const restored: AIInsightEvidence = roundTrip(evidence);
148
+ expect(restored).toEqual(evidence);
149
+ expect(setSections(restored)).toEqual([section]);
150
+ },
151
+ );
152
+
153
+ test("exception evidence fields are all optional", () => {
154
+ const minimal: ExceptionInsightEvidence = {};
155
+ expect(roundTrip({ exception: minimal })).toEqual({ exception: {} });
156
+ });
157
+
158
+ test("undefined optional fields are dropped by serialisation", () => {
159
+ const evidence: AIInsightEvidence = {
160
+ latency: {
161
+ recentP99Ms: 500,
162
+ baselineP99Ms: 100,
163
+ regressionMultiplier: 5,
164
+ operationName: undefined,
165
+ sampleTraceId: undefined,
166
+ },
167
+ exception: undefined,
168
+ };
169
+ const restored: AIInsightEvidence = roundTrip(evidence);
170
+ expect(Object.keys(restored)).toEqual(["latency"]);
171
+ expect(Object.keys(restored.latency!).sort()).toEqual([
172
+ "baselineP99Ms",
173
+ "recentP99Ms",
174
+ "regressionMultiplier",
175
+ ]);
176
+ });
177
+
178
+ test("the numeric fields keep their exact values through storage", () => {
179
+ const restored: AIInsightEvidence = roundTrip({
180
+ metricDrift: { ...metricDriftEvidence, relativeChangePercent: -12.345 },
181
+ });
182
+ expect(restored.metricDrift?.relativeChangePercent).toBe(-12.345);
183
+ expect(restored.metricDrift?.recentSampleCount).toBe(10080);
184
+ });
185
+
186
+ test("performance findings keep their enum discriminator as a string", () => {
187
+ const restored: AIInsightEvidence = roundTrip({ latency: latencyEvidence });
188
+ expect(restored.latency?.performanceFindings?.[0]?.findingType).toBe(
189
+ "NPlusOneQuery",
190
+ );
191
+ expect(restored.latency?.codeLocations?.[0]?.lineNumber).toBe(88);
192
+ });
193
+
194
+ test("log spike topServices preserves order", () => {
195
+ const restored: AIInsightEvidence = roundTrip({
196
+ logSpike: logSpikeEvidence,
197
+ });
198
+ expect(
199
+ restored.logSpike?.topServices.map(
200
+ (service: { serviceName: string; count: number }) => {
201
+ return service.serviceName;
202
+ },
203
+ ),
204
+ ).toEqual(["checkout", "payments"]);
205
+ });
206
+ });
@@ -0,0 +1,144 @@
1
+ import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
2
+ import DatabaseCommonInteractionPropsUtil from "../../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
3
+ import Exception from "../../../Types/Exception/Exception";
4
+ import ExceptionCode from "../../../Types/Exception/ExceptionCode";
5
+ import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
6
+ import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
7
+ import ObjectID from "../../../Types/ObjectID";
8
+ import UserType from "../../../Types/UserType";
9
+ import { describe, expect, test } from "@jest/globals";
10
+
11
+ /*
12
+ * "No credentials at all" is the one refusal the browser client can recover
13
+ * from. The dashboard's access-token cookie expires with the 15-minute JWT
14
+ * inside it, so an idle tab's next request arrives with no user and no key,
15
+ * and the client refreshes the session and replays the request only when the
16
+ * answer is a 401. isAnonymous decides who is in that bucket and
17
+ * assertCredentialsPresent turns it into the 401; both are shared by
18
+ * CommonAPI, the AI privacy filters and ModelPermission, so a mistake here
19
+ * shows up as a bogus 422 (or a wrongly refreshed API key) everywhere at once.
20
+ */
21
+
22
+ type PropsCase = [string, DatabaseCommonInteractionProps];
23
+
24
+ const anonymousCases: Array<PropsCase> = [
25
+ ["no props at all", {}],
26
+ ["a tenant but no user", { tenantId: ObjectID.generate() }],
27
+ ["an explicitly Public caller", { userType: UserType.Public }],
28
+ [
29
+ "a Public caller with a tenant",
30
+ { tenantId: ObjectID.generate(), userType: UserType.Public },
31
+ ],
32
+ /*
33
+ * userType User without a userId cannot happen through getUserMiddleware,
34
+ * but if it did there is still nobody to scope to.
35
+ */
36
+ ["userType User but no userId", { userType: UserType.User }],
37
+ ];
38
+
39
+ const credentialedCases: Array<PropsCase> = [
40
+ ["a signed-in user", { userId: ObjectID.generate() }],
41
+ [
42
+ "a signed-in user with userType User",
43
+ { userId: ObjectID.generate(), userType: UserType.User },
44
+ ],
45
+ /*
46
+ * A user id wins even over a Public userType: the caller named a user, so
47
+ * this is not an expired session.
48
+ */
49
+ [
50
+ "a user id with a Public userType",
51
+ { userId: ObjectID.generate(), userType: UserType.Public },
52
+ ],
53
+ // A project API key: credentials, but no user.
54
+ [
55
+ "a project API key",
56
+ { tenantId: ObjectID.generate(), userType: UserType.API },
57
+ ],
58
+ // A master API key / master-admin session with no userId on the props.
59
+ ["a master admin userType", { userType: UserType.MasterAdmin }],
60
+ ];
61
+
62
+ describe("DatabaseCommonInteractionPropsUtil.AUTHENTICATION_REQUIRED_MESSAGE", () => {
63
+ test("is the shared login-required sentence", () => {
64
+ expect(
65
+ DatabaseCommonInteractionPropsUtil.AUTHENTICATION_REQUIRED_MESSAGE,
66
+ ).toBe("Authentication required. Please log in to access this resource.");
67
+ });
68
+ });
69
+
70
+ describe("DatabaseCommonInteractionPropsUtil.isAnonymous", () => {
71
+ test.each(anonymousCases)(
72
+ "is true for %s",
73
+ (_label: string, props: DatabaseCommonInteractionProps) => {
74
+ expect(DatabaseCommonInteractionPropsUtil.isAnonymous(props)).toBe(true);
75
+ },
76
+ );
77
+
78
+ test.each(credentialedCases)(
79
+ "is false for %s",
80
+ (_label: string, props: DatabaseCommonInteractionProps) => {
81
+ expect(DatabaseCommonInteractionPropsUtil.isAnonymous(props)).toBe(false);
82
+ },
83
+ );
84
+
85
+ /*
86
+ * isRoot / isMasterAdmin are NOT part of this question - callers that bypass
87
+ * permissions check those themselves before asking. Pinned so nobody folds
88
+ * them in and silently changes every caller's ordering.
89
+ */
90
+ test("does not look at isRoot or isMasterAdmin", () => {
91
+ expect(
92
+ DatabaseCommonInteractionPropsUtil.isAnonymous({ isRoot: true }),
93
+ ).toBe(true);
94
+ expect(
95
+ DatabaseCommonInteractionPropsUtil.isAnonymous({ isMasterAdmin: true }),
96
+ ).toBe(true);
97
+ });
98
+ });
99
+
100
+ describe("DatabaseCommonInteractionPropsUtil.assertCredentialsPresent", () => {
101
+ test.each(anonymousCases)(
102
+ "throws a 401 NotAuthenticatedException for %s",
103
+ (_label: string, props: DatabaseCommonInteractionProps) => {
104
+ let thrown: unknown = undefined;
105
+
106
+ try {
107
+ DatabaseCommonInteractionPropsUtil.assertCredentialsPresent(props);
108
+ } catch (error) {
109
+ thrown = error;
110
+ }
111
+
112
+ expect(thrown).toBeInstanceOf(NotAuthenticatedException);
113
+ expect(thrown).not.toBeInstanceOf(NotAuthorizedException);
114
+ expect((thrown as Exception).code).toBe(
115
+ ExceptionCode.NotAuthenticatedException,
116
+ );
117
+ expect((thrown as Exception).code).toBe(401);
118
+ expect((thrown as Exception).message).toBe(
119
+ DatabaseCommonInteractionPropsUtil.AUTHENTICATION_REQUIRED_MESSAGE,
120
+ );
121
+ },
122
+ );
123
+
124
+ test.each(credentialedCases)(
125
+ "does not throw for %s",
126
+ (_label: string, props: DatabaseCommonInteractionProps) => {
127
+ expect(() => {
128
+ DatabaseCommonInteractionPropsUtil.assertCredentialsPresent(props);
129
+ }).not.toThrow();
130
+ },
131
+ );
132
+
133
+ test("does not mutate the props it is given", () => {
134
+ const props: DatabaseCommonInteractionProps = {
135
+ tenantId: ObjectID.generate(),
136
+ userType: UserType.API,
137
+ };
138
+ const before: string = JSON.stringify(props);
139
+
140
+ DatabaseCommonInteractionPropsUtil.assertCredentialsPresent(props);
141
+
142
+ expect(JSON.stringify(props)).toBe(before);
143
+ });
144
+ });