@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,465 @@
1
+ import {
2
+ afterEach,
3
+ beforeEach,
4
+ describe,
5
+ expect,
6
+ jest,
7
+ test,
8
+ } from "@jest/globals";
9
+ import type { Mock } from "jest-mock";
10
+ import type { Attributes, ObservableResult } from "@opentelemetry/api";
11
+ import type RuntimeMetricsType from "../../../../Server/Utils/Telemetry/RuntimeMetrics";
12
+
13
+ /*
14
+ * RuntimeMetrics registers the process-level observable gauges (memory, CPU,
15
+ * event-loop lag, uptime). Dashboards key off these metric NAMES and UNITS,
16
+ * and the callbacks do a little math (CPU deltas, ns -> ms), so both are
17
+ * pinned here. Telemetry, the logger and perf_hooks are mocked: no exporter
18
+ * or real event-loop histogram is involved.
19
+ */
20
+
21
+ type GaugeCallback = (result: ObservableResult<Attributes>) => void;
22
+
23
+ interface GaugeRegistration {
24
+ name: string;
25
+ description: string;
26
+ unit: string;
27
+ callback: GaugeCallback;
28
+ }
29
+
30
+ interface FakeHistogram {
31
+ mean: number;
32
+ max: number;
33
+ percentile: Mock<(p: number) => number>;
34
+ reset: Mock<() => void>;
35
+ enable: Mock<() => boolean>;
36
+ }
37
+
38
+ interface Observation {
39
+ value: number;
40
+ attributes: Attributes | undefined;
41
+ }
42
+
43
+ const mockIsMetricsEnabled: Mock<() => boolean> = jest.fn(() => {
44
+ return true;
45
+ });
46
+ const mockGetObservableGauge: Mock<(data: GaugeRegistration) => unknown> =
47
+ jest.fn((_data: GaugeRegistration) => {
48
+ return {};
49
+ });
50
+ const mockLoggerError: Mock<(message: unknown) => void> = jest.fn();
51
+
52
+ const mockHistogram: FakeHistogram = {
53
+ mean: 0,
54
+ max: 0,
55
+ percentile: jest.fn((_p: number) => {
56
+ return 0;
57
+ }),
58
+ reset: jest.fn(),
59
+ enable: jest.fn(() => {
60
+ return true;
61
+ }),
62
+ };
63
+ const mockMonitorEventLoopDelay: Mock<
64
+ (options: { resolution: number }) => FakeHistogram
65
+ > = jest.fn((_options: { resolution: number }) => {
66
+ return mockHistogram;
67
+ });
68
+
69
+ jest.mock("perf_hooks", () => {
70
+ return {
71
+ __esModule: true,
72
+ monitorEventLoopDelay: (options: { resolution: number }) => {
73
+ return mockMonitorEventLoopDelay(options);
74
+ },
75
+ };
76
+ });
77
+
78
+ jest.mock("../../../../Server/Utils/Telemetry", () => {
79
+ return {
80
+ __esModule: true,
81
+ default: {
82
+ isMetricsEnabled: () => {
83
+ return mockIsMetricsEnabled();
84
+ },
85
+ getObservableGauge: (data: GaugeRegistration) => {
86
+ return mockGetObservableGauge(data);
87
+ },
88
+ },
89
+ };
90
+ });
91
+
92
+ jest.mock("../../../../Server/Utils/Logger", () => {
93
+ return {
94
+ __esModule: true,
95
+ default: {
96
+ error: (message: unknown) => {
97
+ mockLoggerError(message);
98
+ },
99
+ debug: jest.fn(),
100
+ info: jest.fn(),
101
+ warn: jest.fn(),
102
+ },
103
+ };
104
+ });
105
+
106
+ const EXPECTED_GAUGES: Array<{ name: string; unit: string }> = [
107
+ { name: "process.runtime.nodejs.memory.heap.used", unit: "By" },
108
+ { name: "process.runtime.nodejs.memory.heap.total", unit: "By" },
109
+ { name: "process.runtime.nodejs.memory.rss", unit: "By" },
110
+ { name: "process.runtime.nodejs.memory.external", unit: "By" },
111
+ { name: "process.runtime.nodejs.cpu.utilization", unit: "1" },
112
+ { name: "process.runtime.nodejs.eventloop.lag", unit: "ms" },
113
+ { name: "process.runtime.nodejs.uptime", unit: "s" },
114
+ ];
115
+
116
+ /*
117
+ * RuntimeMetrics keeps its "initialized" flag and CPU/histogram state in
118
+ * static fields, so each test loads a fresh copy of the module.
119
+ */
120
+ const loadRuntimeMetrics: () => typeof RuntimeMetricsType =
121
+ (): typeof RuntimeMetricsType => {
122
+ let loaded: typeof RuntimeMetricsType | undefined;
123
+ jest.isolateModules(() => {
124
+ loaded =
125
+ // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
126
+ require("../../../../Server/Utils/Telemetry/RuntimeMetrics").default;
127
+ });
128
+ if (!loaded) {
129
+ throw new Error("Failed to load RuntimeMetrics");
130
+ }
131
+ return loaded;
132
+ };
133
+
134
+ const registrations: () => Array<GaugeRegistration> =
135
+ (): Array<GaugeRegistration> => {
136
+ return mockGetObservableGauge.mock.calls.map(
137
+ (call: [GaugeRegistration]) => {
138
+ return call[0];
139
+ },
140
+ );
141
+ };
142
+
143
+ const gauge: (name: string) => GaugeRegistration = (
144
+ name: string,
145
+ ): GaugeRegistration => {
146
+ const found: GaugeRegistration | undefined = registrations().find(
147
+ (registration: GaugeRegistration) => {
148
+ return registration.name === name;
149
+ },
150
+ );
151
+ if (!found) {
152
+ throw new Error(`Gauge ${name} was not registered`);
153
+ }
154
+ return found;
155
+ };
156
+
157
+ const observe: (name: string) => Array<Observation> = (
158
+ name: string,
159
+ ): Array<Observation> => {
160
+ const observations: Array<Observation> = [];
161
+ const result: ObservableResult<Attributes> = {
162
+ observe: (value: number, attributes?: Attributes) => {
163
+ observations.push({ value, attributes });
164
+ },
165
+ };
166
+ gauge(name).callback(result);
167
+ return observations;
168
+ };
169
+
170
+ describe("RuntimeMetrics", () => {
171
+ beforeEach(() => {
172
+ mockIsMetricsEnabled.mockReset();
173
+ mockIsMetricsEnabled.mockReturnValue(true);
174
+ mockGetObservableGauge.mockReset();
175
+ mockGetObservableGauge.mockReturnValue({});
176
+ mockLoggerError.mockReset();
177
+ mockMonitorEventLoopDelay.mockClear();
178
+ mockHistogram.mean = 0;
179
+ mockHistogram.max = 0;
180
+ mockHistogram.percentile.mockReset();
181
+ mockHistogram.percentile.mockReturnValue(0);
182
+ mockHistogram.reset.mockClear();
183
+ mockHistogram.enable.mockClear();
184
+ });
185
+
186
+ afterEach(() => {
187
+ jest.restoreAllMocks();
188
+ });
189
+
190
+ describe("init", () => {
191
+ test("registers nothing when metrics are disabled", () => {
192
+ mockIsMetricsEnabled.mockReturnValue(false);
193
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
194
+
195
+ RuntimeMetrics.init();
196
+
197
+ expect(mockGetObservableGauge).not.toHaveBeenCalled();
198
+ expect(mockMonitorEventLoopDelay).not.toHaveBeenCalled();
199
+ });
200
+
201
+ test("a disabled init does not latch — enabling later registers the gauges", () => {
202
+ mockIsMetricsEnabled.mockReturnValue(false);
203
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
204
+ RuntimeMetrics.init();
205
+
206
+ mockIsMetricsEnabled.mockReturnValue(true);
207
+ RuntimeMetrics.init();
208
+
209
+ expect(mockGetObservableGauge).toHaveBeenCalledTimes(
210
+ EXPECTED_GAUGES.length,
211
+ );
212
+ });
213
+
214
+ test("registers every runtime gauge with its name and unit", () => {
215
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
216
+ RuntimeMetrics.init();
217
+
218
+ expect(
219
+ registrations().map((registration: GaugeRegistration) => {
220
+ return { name: registration.name, unit: registration.unit };
221
+ }),
222
+ ).toEqual(EXPECTED_GAUGES);
223
+
224
+ for (const registration of registrations()) {
225
+ expect(registration.description.length).toBeGreaterThan(0);
226
+ expect(typeof registration.callback).toBe("function");
227
+ }
228
+ });
229
+
230
+ test("starts the event-loop monitor with 20ms resolution and enables it", () => {
231
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
232
+ RuntimeMetrics.init();
233
+
234
+ expect(mockMonitorEventLoopDelay).toHaveBeenCalledTimes(1);
235
+ expect(mockMonitorEventLoopDelay).toHaveBeenCalledWith({
236
+ resolution: 20,
237
+ });
238
+ expect(mockHistogram.enable).toHaveBeenCalledTimes(1);
239
+ });
240
+
241
+ test("is idempotent once initialized", () => {
242
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
243
+ RuntimeMetrics.init();
244
+ RuntimeMetrics.init();
245
+ RuntimeMetrics.init();
246
+
247
+ expect(mockGetObservableGauge).toHaveBeenCalledTimes(
248
+ EXPECTED_GAUGES.length,
249
+ );
250
+ expect(mockMonitorEventLoopDelay).toHaveBeenCalledTimes(1);
251
+ // Once initialized, the enabled check is not even consulted again.
252
+ expect(mockIsMetricsEnabled).toHaveBeenCalledTimes(1);
253
+ });
254
+
255
+ test("logs and swallows a registration failure, and retries on the next init", () => {
256
+ mockGetObservableGauge.mockImplementationOnce(() => {
257
+ throw new Error("meter exploded");
258
+ });
259
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
260
+
261
+ expect(() => {
262
+ RuntimeMetrics.init();
263
+ }).not.toThrow();
264
+
265
+ expect(mockLoggerError).toHaveBeenCalledWith(
266
+ "Failed to initialize Node.js runtime metrics",
267
+ );
268
+ expect(mockLoggerError).toHaveBeenCalledWith(
269
+ expect.objectContaining({ message: "meter exploded" }),
270
+ );
271
+
272
+ mockGetObservableGauge.mockClear();
273
+ RuntimeMetrics.init();
274
+
275
+ // Not latched as initialized, so the gauges are registered on retry...
276
+ expect(mockGetObservableGauge).toHaveBeenCalledTimes(
277
+ EXPECTED_GAUGES.length,
278
+ );
279
+ // ...but the event-loop histogram created by the first attempt is reused.
280
+ expect(mockMonitorEventLoopDelay).toHaveBeenCalledTimes(1);
281
+ });
282
+ });
283
+
284
+ describe("memory and uptime gauges", () => {
285
+ test("observe the current process.memoryUsage() fields", () => {
286
+ jest.spyOn(process, "memoryUsage").mockReturnValue({
287
+ heapUsed: 111,
288
+ heapTotal: 222,
289
+ rss: 333,
290
+ external: 444,
291
+ arrayBuffers: 555,
292
+ });
293
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
294
+ RuntimeMetrics.init();
295
+
296
+ expect(observe("process.runtime.nodejs.memory.heap.used")).toEqual([
297
+ { value: 111, attributes: undefined },
298
+ ]);
299
+ expect(observe("process.runtime.nodejs.memory.heap.total")).toEqual([
300
+ { value: 222, attributes: undefined },
301
+ ]);
302
+ expect(observe("process.runtime.nodejs.memory.rss")).toEqual([
303
+ { value: 333, attributes: undefined },
304
+ ]);
305
+ expect(observe("process.runtime.nodejs.memory.external")).toEqual([
306
+ { value: 444, attributes: undefined },
307
+ ]);
308
+ });
309
+
310
+ test("uptime observes process.uptime() in seconds", () => {
311
+ jest.spyOn(process, "uptime").mockReturnValue(1234.5);
312
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
313
+ RuntimeMetrics.init();
314
+
315
+ expect(observe("process.runtime.nodejs.uptime")).toEqual([
316
+ { value: 1234.5, attributes: undefined },
317
+ ]);
318
+ });
319
+ });
320
+
321
+ describe("cpu utilization gauge", () => {
322
+ const CPU_GAUGE: string = "process.runtime.nodejs.cpu.utilization";
323
+
324
+ let nowNs: bigint;
325
+ let cpu: NodeJS.CpuUsage;
326
+
327
+ beforeEach(() => {
328
+ nowNs = BigInt(1_000_000_000_000);
329
+ cpu = { user: 1_000_000, system: 500_000 };
330
+ jest.spyOn(process.hrtime, "bigint").mockImplementation(() => {
331
+ return nowNs;
332
+ });
333
+ jest.spyOn(process, "cpuUsage").mockImplementation(() => {
334
+ return { ...cpu };
335
+ });
336
+ });
337
+
338
+ test("the first sample only primes the baseline and reports 0", () => {
339
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
340
+ RuntimeMetrics.init();
341
+
342
+ expect(observe(CPU_GAUGE)).toEqual([{ value: 0, attributes: undefined }]);
343
+ });
344
+
345
+ test("reports (user + system delta) / wall-clock elapsed", () => {
346
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
347
+ RuntimeMetrics.init();
348
+ observe(CPU_GAUGE); // prime
349
+
350
+ // 1s of wall clock, 0.5s user + 0.25s system CPU.
351
+ nowNs += BigInt(1_000_000_000);
352
+ cpu = { user: cpu.user + 500_000, system: cpu.system + 250_000 };
353
+
354
+ const observations: Array<Observation> = observe(CPU_GAUGE);
355
+ expect(observations).toHaveLength(1);
356
+ expect(observations[0]!.value).toBeCloseTo(0.75, 10);
357
+ });
358
+
359
+ test("can exceed 1 when several cores are busy", () => {
360
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
361
+ RuntimeMetrics.init();
362
+ observe(CPU_GAUGE);
363
+
364
+ nowNs += BigInt(1_000_000_000);
365
+ cpu = { user: cpu.user + 3_000_000, system: cpu.system + 500_000 };
366
+
367
+ expect(observe(CPU_GAUGE)[0]!.value).toBeCloseTo(3.5, 10);
368
+ });
369
+
370
+ test("each sample is relative to the previous one, not the first", () => {
371
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
372
+ RuntimeMetrics.init();
373
+ observe(CPU_GAUGE);
374
+
375
+ nowNs += BigInt(1_000_000_000);
376
+ cpu = { user: cpu.user + 1_000_000, system: cpu.system };
377
+ expect(observe(CPU_GAUGE)[0]!.value).toBeCloseTo(1, 10);
378
+
379
+ nowNs += BigInt(2_000_000_000);
380
+ cpu = { user: cpu.user + 500_000, system: cpu.system + 500_000 };
381
+ expect(observe(CPU_GAUGE)[0]!.value).toBeCloseTo(0.5, 10);
382
+ });
383
+
384
+ test("reports 0 when no wall-clock time has elapsed (no divide-by-zero)", () => {
385
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
386
+ RuntimeMetrics.init();
387
+ observe(CPU_GAUGE);
388
+
389
+ cpu = { user: cpu.user + 1_000, system: cpu.system };
390
+ expect(observe(CPU_GAUGE)).toEqual([{ value: 0, attributes: undefined }]);
391
+ });
392
+
393
+ test("sub-microsecond elapsed time is treated as no elapsed time", () => {
394
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
395
+ RuntimeMetrics.init();
396
+ observe(CPU_GAUGE);
397
+
398
+ nowNs += BigInt(999); // < 1µs, truncates to 0 micros
399
+ cpu = { user: cpu.user + 10, system: cpu.system };
400
+ expect(observe(CPU_GAUGE)).toEqual([{ value: 0, attributes: undefined }]);
401
+ });
402
+
403
+ test("a zero-elapsed sample does not reset the baseline", () => {
404
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
405
+ RuntimeMetrics.init();
406
+ observe(CPU_GAUGE);
407
+
408
+ cpu = { user: cpu.user + 250_000, system: cpu.system };
409
+ observe(CPU_GAUGE); // elapsed 0 -> 0, baseline kept
410
+
411
+ nowNs += BigInt(1_000_000_000);
412
+ cpu = { user: cpu.user + 250_000, system: cpu.system };
413
+ // Measured against the original baseline: 0.5s CPU over 1s.
414
+ expect(observe(CPU_GAUGE)[0]!.value).toBeCloseTo(0.5, 10);
415
+ });
416
+ });
417
+
418
+ describe("event loop lag gauge", () => {
419
+ const LAG_GAUGE: string = "process.runtime.nodejs.eventloop.lag";
420
+
421
+ test("observes mean, p99 and max converted from ns to ms, then resets", () => {
422
+ mockHistogram.mean = 12_500_000; // 12.5ms
423
+ mockHistogram.max = 80_000_000; // 80ms
424
+ mockHistogram.percentile.mockReturnValue(40_000_000); // 40ms
425
+
426
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
427
+ RuntimeMetrics.init();
428
+
429
+ expect(observe(LAG_GAUGE)).toEqual([
430
+ { value: 12.5, attributes: { quantile: "mean" } },
431
+ { value: 40, attributes: { quantile: "p99" } },
432
+ { value: 80, attributes: { quantile: "max" } },
433
+ ]);
434
+ expect(mockHistogram.percentile).toHaveBeenCalledWith(99);
435
+ expect(mockHistogram.reset).toHaveBeenCalledTimes(1);
436
+ });
437
+
438
+ test("skips non-finite values (empty histogram) but still resets", () => {
439
+ mockHistogram.mean = NaN;
440
+ mockHistogram.max = 5_000_000;
441
+ mockHistogram.percentile.mockReturnValue(Infinity);
442
+
443
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
444
+ RuntimeMetrics.init();
445
+
446
+ expect(observe(LAG_GAUGE)).toEqual([
447
+ { value: 5, attributes: { quantile: "max" } },
448
+ ]);
449
+ expect(mockHistogram.reset).toHaveBeenCalledTimes(1);
450
+ });
451
+
452
+ test("each collection resets the histogram so intervals do not accumulate", () => {
453
+ mockHistogram.mean = 1_000_000;
454
+ mockHistogram.max = 1_000_000;
455
+ mockHistogram.percentile.mockReturnValue(1_000_000);
456
+
457
+ const RuntimeMetrics: typeof RuntimeMetricsType = loadRuntimeMetrics();
458
+ RuntimeMetrics.init();
459
+
460
+ observe(LAG_GAUGE);
461
+ observe(LAG_GAUGE);
462
+ expect(mockHistogram.reset).toHaveBeenCalledTimes(2);
463
+ });
464
+ });
465
+ });
@@ -0,0 +1,202 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
2
+ import DatabaseConfig from "../../../../../../Server/DatabaseConfig";
3
+ import AlertService from "../../../../../../Server/Services/AlertService";
4
+ import { MicrosoftTeamsAlertActionType } from "../../../../../../Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes";
5
+ import MicrosoftTeamsAlertMessages from "../../../../../../Server/Utils/Workspace/MicrosoftTeams/Messages/Alert";
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
+ /*
17
+ * NOTE: unlike the incident builder (and the Slack alert builder), the
18
+ * "Execute On Call", "Change Alert State" and "Add Note" buttons here use
19
+ * ExecuteAlertOnCallPolicy / AlertStateChanged / AddAlertNote rather than the
20
+ * View* action ids that MicrosoftTeamsAlertActions actually dispatches on.
21
+ * These tests pin the current output.
22
+ */
23
+
24
+ const getButtons: (
25
+ blocks: Array<WorkspaceMessageBlock>,
26
+ ) => Array<WorkspaceMessagePayloadButton> = (
27
+ blocks: Array<WorkspaceMessageBlock>,
28
+ ): Array<WorkspaceMessagePayloadButton> => {
29
+ return (blocks[1] as WorkspacePayloadButtons).buttons;
30
+ };
31
+
32
+ describe("MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks", () => {
33
+ const projectId: ObjectID = ObjectID.generate();
34
+ const alertId: ObjectID = ObjectID.generate();
35
+
36
+ beforeEach(() => {
37
+ jest
38
+ .spyOn(DatabaseConfig, "getHost")
39
+ .mockResolvedValue(new Hostname("oneuptime.test"));
40
+ jest
41
+ .spyOn(DatabaseConfig, "getHttpProtocol")
42
+ .mockResolvedValue(Protocol.HTTPS);
43
+ });
44
+
45
+ afterEach(() => {
46
+ jest.restoreAllMocks();
47
+ });
48
+
49
+ test("returns a divider followed by a single buttons block", async () => {
50
+ const blocks: Array<WorkspaceMessageBlock> =
51
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
52
+ alertId,
53
+ projectId,
54
+ });
55
+
56
+ expect(blocks).toHaveLength(2);
57
+ expect(blocks[0]).toEqual({ _type: "WorkspacePayloadDivider" });
58
+ expect(blocks[1]!._type).toBe("WorkspacePayloadButtons");
59
+ });
60
+
61
+ test("emits the 6 buttons in order with the expected action ids and titles", async () => {
62
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
63
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
64
+ alertId,
65
+ projectId,
66
+ }),
67
+ );
68
+
69
+ expect(
70
+ buttons.map((button: WorkspaceMessagePayloadButton) => {
71
+ return button.actionId;
72
+ }),
73
+ ).toEqual([
74
+ MicrosoftTeamsAlertActionType.ViewAlert,
75
+ MicrosoftTeamsAlertActionType.ExecuteAlertOnCallPolicy,
76
+ MicrosoftTeamsAlertActionType.AckAlert,
77
+ MicrosoftTeamsAlertActionType.ResolveAlert,
78
+ MicrosoftTeamsAlertActionType.AlertStateChanged,
79
+ MicrosoftTeamsAlertActionType.AddAlertNote,
80
+ ]);
81
+
82
+ expect(
83
+ buttons.map((button: WorkspaceMessagePayloadButton) => {
84
+ return button.title;
85
+ }),
86
+ ).toEqual([
87
+ "🔗 View Alert",
88
+ "📞 Execute On Call",
89
+ "👀 Acknowledge Alert",
90
+ "✅ Resolve Alert",
91
+ "➡️ Change Alert State",
92
+ "📄 Add Note",
93
+ ]);
94
+ });
95
+
96
+ test("every button carries the alert id as its value", async () => {
97
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
98
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
99
+ alertId,
100
+ projectId,
101
+ }),
102
+ );
103
+
104
+ expect(buttons).toHaveLength(6);
105
+
106
+ for (const button of buttons) {
107
+ expect(button._type).toBe("WorkspaceMessagePayloadButton");
108
+ expect(button.value).toBe(alertId.toString());
109
+ expect(button.value).not.toBe(projectId.toString());
110
+ }
111
+ });
112
+
113
+ test("only the view button links to the alert page in the dashboard", async () => {
114
+ const buttons: Array<WorkspaceMessagePayloadButton> = getButtons(
115
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
116
+ alertId,
117
+ projectId,
118
+ }),
119
+ );
120
+
121
+ expect(buttons[0]!.url?.toString()).toBe(
122
+ `https://oneuptime.test/dashboard/${projectId.toString()}/alerts/${alertId.toString()}`,
123
+ );
124
+
125
+ for (const button of buttons.slice(1)) {
126
+ expect(button.url).toBeUndefined();
127
+ }
128
+ });
129
+
130
+ test("asks AlertService for the link with the project and alert ids", async () => {
131
+ const linkSpy: jest.SpiedFunction<
132
+ typeof AlertService.getAlertLinkInDashboard
133
+ > = jest.spyOn(AlertService, "getAlertLinkInDashboard");
134
+
135
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
136
+ alertId,
137
+ projectId,
138
+ });
139
+
140
+ expect(linkSpy).toHaveBeenCalledTimes(1);
141
+ expect(linkSpy).toHaveBeenCalledWith(projectId, alertId);
142
+ });
143
+
144
+ test("throws BadDataException when the alert id is missing", async () => {
145
+ const linkSpy: jest.SpiedFunction<
146
+ typeof AlertService.getAlertLinkInDashboard
147
+ > = jest.spyOn(AlertService, "getAlertLinkInDashboard");
148
+
149
+ await expect(
150
+ MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
151
+ alertId: undefined as unknown as ObjectID,
152
+ projectId,
153
+ }),
154
+ ).rejects.toThrow(new BadDataException("Alert ID is required"));
155
+
156
+ expect(linkSpy).not.toHaveBeenCalled();
157
+ });
158
+
159
+ test("throws when the project id is missing (no dashboard link can be built)", async () => {
160
+ await expect(
161
+ MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
162
+ alertId,
163
+ projectId: undefined as unknown as ObjectID,
164
+ }),
165
+ ).rejects.toThrow();
166
+ });
167
+
168
+ test("propagates a failure while building the dashboard link", async () => {
169
+ jest
170
+ .spyOn(AlertService, "getAlertLinkInDashboard")
171
+ .mockRejectedValue(new Error("dashboard url unavailable"));
172
+
173
+ await expect(
174
+ MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
175
+ alertId,
176
+ projectId,
177
+ }),
178
+ ).rejects.toThrow("dashboard url unavailable");
179
+ });
180
+
181
+ test("builds a fresh block list for each alert", async () => {
182
+ const otherId: ObjectID = ObjectID.generate();
183
+
184
+ const first: Array<WorkspaceMessageBlock> =
185
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
186
+ alertId,
187
+ projectId,
188
+ });
189
+ const second: Array<WorkspaceMessageBlock> =
190
+ await MicrosoftTeamsAlertMessages.getAlertCreateMessageBlocks({
191
+ alertId: otherId,
192
+ projectId,
193
+ });
194
+
195
+ expect(first).not.toBe(second);
196
+ expect(getButtons(first)[0]!.value).toBe(alertId.toString());
197
+ expect(getButtons(second)[0]!.value).toBe(otherId.toString());
198
+ expect(getButtons(second)[0]!.url?.toString()).toContain(
199
+ `/alerts/${otherId.toString()}`,
200
+ );
201
+ });
202
+ });