@oneuptime/common 13.0.7 → 14.0.0

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 (759) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +23 -15
  2. package/Models/DatabaseModels/GlobalConfig.ts +24 -0
  3. package/Models/DatabaseModels/Monitor.ts +3 -2
  4. package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
  5. package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +1 -1
  6. package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +1 -1
  7. package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +1 -1
  8. package/Scripts/generate-service-worker.js +65 -4
  9. package/Server/API/AIBillingAPI.ts +1 -0
  10. package/Server/API/AIInsightAPI.ts +1 -4
  11. package/Server/API/AIInvestigationAPI.ts +1 -4
  12. package/Server/API/AIReadinessAPI.ts +4 -5
  13. package/Server/API/AlertAPI.ts +1 -0
  14. package/Server/API/AutoRemediationAPI.ts +1 -4
  15. package/Server/API/BaseAPI.ts +34 -0
  16. package/Server/API/BaseAnalyticsAPI.ts +80 -9
  17. package/Server/API/BillingAPI.ts +2 -0
  18. package/Server/API/BillingInvoiceAPI.ts +1 -0
  19. package/Server/API/BillingPaymentMethodAPI.ts +2 -0
  20. package/Server/API/CodeFixRunAPI.ts +1 -3
  21. package/Server/API/CommonAPI.ts +68 -4
  22. package/Server/API/DashboardAPI.ts +12 -12
  23. package/Server/API/GlobalConfigAPI.ts +243 -460
  24. package/Server/API/IncidentAPI.ts +2 -0
  25. package/Server/API/IncidentEpisodeAPI.ts +1 -0
  26. package/Server/API/NotificationAPI.ts +1 -0
  27. package/Server/API/OnCallCalendarAPI.ts +4 -5
  28. package/Server/API/OnCallDutyPolicyAPI.ts +7 -0
  29. package/Server/API/OnCallReadinessAPI.ts +4 -1
  30. package/Server/API/OnCallScheduleTimelineAPI.ts +731 -0
  31. package/Server/API/ProjectAPI.ts +1 -0
  32. package/Server/API/ProjectOIDC.ts +25 -16
  33. package/Server/API/ProjectSSO.ts +24 -16
  34. package/Server/API/ScheduledMaintenanceAPI.ts +1 -0
  35. package/Server/API/StatusPageAPI.ts +261 -74
  36. package/Server/API/TeamMemberAPI.ts +13 -1
  37. package/Server/API/UserCallAPI.ts +2 -0
  38. package/Server/API/UserEmailAPI.ts +2 -0
  39. package/Server/API/UserIncomingCallNumberAPI.ts +2 -0
  40. package/Server/API/UserMicrosoftTeamsAPI.ts +1 -0
  41. package/Server/API/UserSlackAPI.ts +1 -0
  42. package/Server/API/UserSmsAPI.ts +2 -0
  43. package/Server/API/UserTotpAuthAPI.ts +1 -0
  44. package/Server/API/UserWebAuthnAPI.ts +2 -0
  45. package/Server/API/UserWebhookAPI.ts +1 -0
  46. package/Server/API/UserWhatsAppAPI.ts +2 -0
  47. package/Server/Enterprise/EnterpriseEdition.ts +649 -0
  48. package/Server/Enterprise/EnterpriseFeature.ts +48 -0
  49. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
  50. package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
  51. package/Server/EnvironmentConfig.ts +147 -2
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
  53. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  54. package/Server/Middleware/MasterAdminAuthorization.ts +13 -2
  55. package/Server/Middleware/UserAuthorization.ts +117 -21
  56. package/Server/Services/ApiKeyPermissionService.ts +101 -4
  57. package/Server/Services/AuditLogService.ts +84 -1079
  58. package/Server/Services/DatabaseService.ts +245 -0
  59. package/Server/Services/DetectionRuleService.ts +5 -4
  60. package/Server/Services/EnterpriseLicenseService.ts +38 -0
  61. package/Server/Services/GlobalConfigService.ts +80 -1
  62. package/Server/Services/MonitorProbeService.ts +116 -20
  63. package/Server/Services/MonitorService.ts +56 -4
  64. package/Server/Services/MonitorStatusTimelineService.ts +284 -0
  65. package/Server/Services/MonitorTemplateService.ts +26 -0
  66. package/Server/Services/OnCallDutyPolicyChildService.ts +261 -0
  67. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -2
  68. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -2
  69. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -2
  70. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -2
  71. package/Server/Services/PayAsYouGoBillingService.ts +23 -28
  72. package/Server/Services/ProjectService.ts +302 -0
  73. package/Server/Services/RumSessionPinService.ts +293 -22
  74. package/Server/Services/StatusPagePrivateUserService.ts +7 -3
  75. package/Server/Services/StatusPageService.ts +78 -1
  76. package/Server/Services/TeamMemberService.ts +11 -0
  77. package/Server/Services/TeamPermissionService.ts +120 -26
  78. package/Server/Services/TeamService.ts +10 -0
  79. package/Server/Services/ThreatIntelFeedService.ts +6 -3
  80. package/Server/Services/UserService.ts +10 -17
  81. package/Server/Types/Database/Permissions/BasePermission.ts +9 -7
  82. package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
  83. package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
  84. package/Server/Types/Database/Permissions/Index.ts +75 -11
  85. package/Server/Types/Database/Permissions/TablePermission.ts +34 -31
  86. package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
  87. package/Server/Types/Markdown.ts +41 -0
  88. package/Server/Utils/AI/AIChatPrivacyFilter.ts +8 -0
  89. package/Server/Utils/AI/AIRunPrivacyFilter.ts +8 -0
  90. package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
  91. package/Server/Utils/EditionEnforcement.ts +233 -0
  92. package/Server/Utils/FrontendEnvironment.ts +41 -2
  93. package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
  94. package/Server/Utils/MasterAdminPageAccess.ts +61 -0
  95. package/Server/Utils/Monitor/AffectedResourceList.ts +190 -0
  96. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
  97. package/Server/Utils/Monitor/MonitorAlert.ts +3 -1
  98. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
  99. package/Server/Utils/Monitor/MonitorIncident.ts +3 -1
  100. package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
  101. package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1 -1
  102. package/Server/Utils/Realtime.ts +163 -45
  103. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +11 -28
  104. package/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.ts +170 -0
  105. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +1 -1
  106. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +6 -2
  107. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.ts +10 -9
  108. package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
  109. package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
  110. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
  111. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
  112. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
  113. package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
  114. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
  115. package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
  116. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +1059 -0
  117. package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +376 -0
  118. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +757 -0
  119. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +307 -0
  120. package/Tests/App/Dashboard/ArgumentsFormGroupByUnlistedAttributes.test.tsx +131 -0
  121. package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
  122. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +1 -1
  123. package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +9 -1
  124. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +24 -0
  125. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +162 -8
  126. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
  127. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
  128. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +105 -6
  129. package/Tests/App/Dashboard/EntityFilterDropdownUnlistedSelection.test.tsx +434 -0
  130. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +276 -1
  131. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
  132. package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +9 -1
  133. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
  134. package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +58 -42
  135. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +42 -5
  136. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +34 -23
  137. package/Tests/App/Dashboard/ScheduleTimeline.test.tsx +1580 -0
  138. package/Tests/App/Dashboard/ScheduleTimelineAPI.test.ts +280 -0
  139. package/Tests/App/Dashboard/ScheduleTimelineModel.test.ts +673 -0
  140. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +133 -70
  141. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
  142. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
  143. package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +86 -3
  144. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -58
  145. package/Tests/App/Dashboard/SecurityEventsGuideContent.test.ts +1313 -0
  146. package/Tests/App/Dashboard/SecurityEventsHowItWorksCard.test.tsx +536 -0
  147. package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
  148. package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +222 -0
  149. package/Tests/App/Dashboard/SecurityEventsThreatIntelPage.test.tsx +199 -0
  150. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
  151. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +171 -36
  152. package/Tests/App/Dashboard/SloViewSideMenu.test.tsx +215 -0
  153. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +40 -3
  154. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
  155. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +12 -4
  156. package/Tests/App/PublicDashboard/PublicDashboardWidgetListAuth.test.tsx +623 -0
  157. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
  158. package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
  159. package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
  160. package/Tests/Models/OnCallCalendarFeedModels.test.ts +23 -1
  161. package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
  162. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +138 -5
  163. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +187 -0
  164. package/Tests/Server/API/AIInvestigationAvailabilityAuthorization.test.ts +51 -3
  165. package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +55 -2
  166. package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
  167. package/Tests/Server/API/BaseAnalyticsAPIAggregateCache.test.ts +729 -0
  168. package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +93 -7
  169. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +36 -3
  170. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +1003 -24
  171. package/Tests/Server/API/DashboardPublicRateLimit.test.ts +6 -3
  172. package/Tests/Server/API/ExpiredSessionAIRoutes.test.ts +708 -0
  173. package/Tests/Server/API/ExpiredSessionCustomRoutes.test.ts +928 -0
  174. package/Tests/Server/API/ExpiredSessionMonitorTemplate.test.ts +319 -0
  175. package/Tests/Server/API/ExpiredSessionOnCallDutyPolicy.test.ts +336 -0
  176. package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +820 -0
  177. package/Tests/Server/API/GlobalConfigLicense.test.ts +766 -381
  178. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +115 -12
  179. package/Tests/Server/API/OnCallCalendarAPI.test.ts +375 -8
  180. package/Tests/Server/API/OnCallReadinessAPI.test.ts +196 -912
  181. package/Tests/Server/API/OnCallScheduleTimelineAPI.test.ts +1513 -0
  182. package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +119 -7
  183. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +111 -4
  184. package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +615 -0
  185. package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +89 -2
  186. package/Tests/Server/API/SessionReplayAPI.test.ts +121 -0
  187. package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
  188. package/Tests/Server/API/StatusPageMasterPasswordRateLimit.test.ts +4 -2
  189. package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +441 -0
  190. package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +664 -0
  191. package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
  192. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +7 -0
  193. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +6 -0
  194. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +65 -4
  195. package/Tests/Server/API/UserProjectsAPI.test.ts +63 -3
  196. package/Tests/Server/API/UserTotpAuthAPI.test.ts +48 -2
  197. package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +11 -2
  198. package/Tests/Server/API/UserWebAuthnBackupCodeMinting.test.ts +46 -3
  199. package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +18 -2
  200. package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +24 -7
  201. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
  202. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
  203. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
  204. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
  205. package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
  206. package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
  207. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
  208. package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
  209. package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
  210. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
  211. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
  212. package/Tests/Server/Middleware/ExpiredSessionUserMiddleware.test.ts +563 -0
  213. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +299 -19
  214. package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +453 -0
  215. package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
  216. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
  217. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +24 -0
  218. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +2 -0
  219. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +3 -3
  220. package/Tests/Server/Services/AuditLogService.test.ts +460 -990
  221. package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
  222. package/Tests/Server/Services/DatabaseServiceCreateSuppliedId.test.ts +147 -0
  223. package/Tests/Server/Services/DatabaseServiceLoginBeforeHooks.test.ts +1078 -0
  224. package/Tests/Server/Services/DatabaseServiceTenantRelationGuard.test.ts +259 -0
  225. package/Tests/Server/Services/DatabaseServiceWriteOperatorValues.test.ts +147 -0
  226. package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
  227. package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
  228. package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
  229. package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +115 -1
  230. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
  231. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
  232. package/Tests/Server/Services/OnCallChildCreateAuthorizationPostgres.test.ts +711 -0
  233. package/Tests/Server/Services/OnCallDutyPolicyChildService.test.ts +733 -0
  234. package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +190 -140
  235. package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +4 -9
  236. package/Tests/Server/Services/PermissionBlockDeletion.test.ts +780 -0
  237. package/Tests/Server/Services/PermissionBlockDeletionPostgres.test.ts +628 -0
  238. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
  239. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
  240. package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +77 -1
  241. package/Tests/Server/Services/RumSessionPinCreatePermission.test.ts +715 -0
  242. package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
  243. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
  244. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
  245. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
  246. package/Tests/Server/Services/TeamMemberMultiTenantReadPostgres.test.ts +394 -0
  247. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +6 -0
  248. package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +131 -0
  249. package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
  250. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +13 -2
  251. package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
  252. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
  253. package/Tests/Server/Types/Database/Permissions/ModelPermissionAnonymousRefusal.test.ts +518 -0
  254. package/Tests/Server/Types/Database/Permissions/MultiTenantPermissions.test.ts +350 -0
  255. package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +282 -25
  256. package/Tests/Server/Types/Database/Permissions/TableLevelBlockPermission.test.ts +459 -0
  257. package/Tests/Server/Types/Markdown.test.ts +181 -0
  258. package/Tests/Server/Utils/AI/AIRunPrivacyFilter.test.ts +101 -9
  259. package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +88 -4
  260. package/Tests/Server/Utils/AI/Toolbox/ExceptionTools.test.ts +459 -0
  261. package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +794 -0
  262. package/Tests/Server/Utils/AI/Toolbox/RecentChangesTools.test.ts +574 -0
  263. package/Tests/Server/Utils/AI/Toolbox/SecurityEventTools.test.ts +596 -0
  264. package/Tests/Server/Utils/CaptchaRequestAndLogging.test.ts +395 -0
  265. package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
  266. package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
  267. package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
  268. package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
  269. package/Tests/Server/Utils/MasterAdminPageAccess.test.ts +251 -0
  270. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
  271. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
  272. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +616 -0
  273. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +934 -96
  274. package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
  275. package/Tests/Server/Utils/Realtime.test.ts +502 -0
  276. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorSeverity.test.ts +216 -0
  277. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +142 -0
  278. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.test.ts +140 -0
  279. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepairClickhouseIntegration.test.ts +542 -0
  280. package/Tests/Server/Utils/Telemetry/ChangeEventRow.test.ts +743 -0
  281. package/Tests/Server/Utils/Telemetry/RuntimeMetrics.test.ts +465 -0
  282. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.test.ts +202 -0
  283. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.test.ts +194 -0
  284. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.test.ts +231 -0
  285. package/Tests/Server/Utils/Workspace/Slack/Messages/Alert.test.ts +194 -0
  286. package/Tests/Server/Utils/Workspace/Slack/Messages/AlertEpisode.test.ts +194 -0
  287. package/Tests/Server/Utils/Workspace/Slack/Messages/Incident.test.ts +194 -0
  288. package/Tests/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.test.ts +194 -0
  289. package/Tests/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.test.ts +247 -0
  290. package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
  291. package/Tests/Types/AI/AIInsightEvidence.test.ts +206 -0
  292. package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
  293. package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
  294. package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtilAnonymous.test.ts +144 -0
  295. package/Tests/Types/Call/CallProvider.test.ts +528 -0
  296. package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
  297. package/Tests/Types/Kubernetes/KubernetesCostIngest.test.ts +236 -0
  298. package/Tests/Types/OnCallDutyPolicy/ScheduleTimeline.test.ts +736 -0
  299. package/Tests/Types/OnCallDutyPolicy/ScheduleTimelineLayout.test.ts +996 -0
  300. package/Tests/Types/SecurityEvent/SigmaRule.test.ts +142 -0
  301. package/Tests/Types/Workflow/Components/JSON.test.ts +182 -0
  302. package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +116 -1
  303. package/Tests/UI/Components/Dropdown/DropdownAsyncOptions.test.tsx +81 -0
  304. package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
  305. package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
  306. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +165 -171
  307. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
  308. package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
  309. package/Tests/UI/Components/EventAttachmentList.test.tsx +174 -0
  310. package/Tests/UI/Components/Forms/BasicFormBurnRateTemplateDefaults.test.tsx +395 -0
  311. package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +286 -0
  312. package/Tests/UI/Components/Forms/FormSummary.test.tsx +128 -0
  313. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
  314. package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
  315. package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
  316. package/Tests/UI/Components/ModelTable/BaseModelTableQueryChange.test.tsx +365 -0
  317. package/Tests/UI/Components/OpenAuthenticatedUrl.test.ts +358 -0
  318. package/Tests/UI/Components/SessionAwareImage.test.tsx +496 -0
  319. package/Tests/UI/Components/TelemetryHistogramZeroBuckets.test.tsx +190 -0
  320. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
  321. package/Tests/UI/Components/TooltipInteractive.test.tsx +97 -0
  322. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
  323. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardInstallGuidance.test.tsx +1 -1
  324. package/Tests/UI/Monitor/EvaluationLogListTimestamps.test.tsx +367 -0
  325. package/Tests/UI/Utils/API/BaseAPIRefreshSession.test.ts +1087 -0
  326. package/Tests/UI/Utils/API/DashboardHost.ts +12 -0
  327. package/Tests/UI/Utils/API/FakeAxiosServer.ts +183 -0
  328. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  329. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  330. package/Tests/UI/Utils/Cookie.test.ts +440 -0
  331. package/Tests/UI/Utils/ModelAPIRequestClient.test.ts +278 -0
  332. package/Tests/UI/Utils/Navigation.test.ts +33 -0
  333. package/Tests/UI/Utils/PricingPlan.test.ts +295 -0
  334. package/Tests/UI/Utils/Realtime.test.ts +759 -0
  335. package/Tests/UI/Utils/Telemetry/Telemetry.test.ts +500 -0
  336. package/Tests/Utils/APIInstanceDispatch.test.ts +311 -0
  337. package/Tests/Utils/HostAddressUtil.test.ts +138 -0
  338. package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
  339. package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
  340. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizerSeverity.test.ts +565 -0
  341. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
  342. package/Types/API/Hostname.ts +63 -16
  343. package/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.ts +40 -0
  344. package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
  345. package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
  346. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
  347. package/Types/Database/CanonicalModelInstance.ts +102 -0
  348. package/Types/Database/TableColumn.ts +20 -6
  349. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
  350. package/Types/IP/IPv6.ts +6 -1
  351. package/Types/Monitor/MonitorEvaluationSummary.ts +3 -0
  352. package/Types/Monitor/MonitorStep.ts +6 -1
  353. package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
  354. package/Types/OnCallDutyPolicy/ScheduleTimeline.ts +507 -0
  355. package/Types/OnCallDutyPolicy/ScheduleTimelineLayout.ts +589 -0
  356. package/Types/Realtime/EventName.ts +11 -0
  357. package/Types/SecurityEvent/DetectionFindingConstants.ts +14 -0
  358. package/Types/SecurityEvent/OcsfSeverity.ts +31 -26
  359. package/Types/SecurityEvent/SigmaRule.ts +51 -0
  360. package/Types/SecurityEvent/ThreatIntelConstants.ts +18 -0
  361. package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
  362. package/UI/Components/AttachmentList/EventAttachmentList.tsx +30 -2
  363. package/UI/Components/Dashboard/DashboardVariableControl.tsx +12 -2
  364. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  365. package/UI/Components/EditionLabel/EditionLabel.tsx +808 -1195
  366. package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
  367. package/UI/Components/EventItem/EventItem.tsx +12 -1
  368. package/UI/Components/Forms/BasicForm.tsx +151 -126
  369. package/UI/Components/Forms/CollapsibleFormSection.tsx +63 -0
  370. package/UI/Components/Forms/Fields/FormField.tsx +10 -4
  371. package/UI/Components/Forms/FormSummary.tsx +7 -0
  372. package/UI/Components/Forms/Types/Field.ts +10 -0
  373. package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
  374. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  375. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +2 -1
  376. package/UI/Components/Markdown.tsx/SessionAwareImage.tsx +122 -0
  377. package/UI/Components/ModelList/ModelList.tsx +11 -1
  378. package/UI/Components/ModelTable/BaseModelTable.tsx +34 -5
  379. package/UI/Components/ModelTable/TableView.tsx +1 -1
  380. package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
  381. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
  382. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +8 -1
  383. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  384. package/UI/Utils/API/API.ts +173 -12
  385. package/UI/Utils/API/RequestOptions.ts +11 -0
  386. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +31 -7
  387. package/UI/Utils/ModelAPI/ModelAPI.ts +30 -9
  388. package/UI/Utils/Navigation.ts +9 -0
  389. package/UI/Utils/OpenAuthenticatedUrl.ts +154 -0
  390. package/UI/Utils/Realtime.ts +176 -30
  391. package/UI/esbuild-enterprise.js +263 -0
  392. package/Utils/API.ts +14 -5
  393. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
  394. package/Utils/HostAddressUtil.ts +94 -0
  395. package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
  396. package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
  397. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +157 -7
  398. package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +9 -17
  399. package/Utils/Slo/SloBurnRateTemplate.ts +2 -2
  400. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
  401. package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
  402. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  403. package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
  404. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  405. package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
  406. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  407. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
  408. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  409. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +1 -1
  410. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -1
  411. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +1 -1
  412. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -1
  413. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +1 -1
  414. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -1
  415. package/build/dist/Server/API/AIBillingAPI.js +1 -1
  416. package/build/dist/Server/API/AIBillingAPI.js.map +1 -1
  417. package/build/dist/Server/API/AIInsightAPI.js +1 -4
  418. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  419. package/build/dist/Server/API/AIInvestigationAPI.js +1 -4
  420. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  421. package/build/dist/Server/API/AIReadinessAPI.js +1 -3
  422. package/build/dist/Server/API/AIReadinessAPI.js.map +1 -1
  423. package/build/dist/Server/API/AlertAPI.js +1 -1
  424. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  425. package/build/dist/Server/API/AutoRemediationAPI.js +1 -4
  426. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  427. package/build/dist/Server/API/BaseAPI.js +33 -0
  428. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  429. package/build/dist/Server/API/BaseAnalyticsAPI.js +55 -10
  430. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  431. package/build/dist/Server/API/BillingAPI.js +2 -2
  432. package/build/dist/Server/API/BillingAPI.js.map +1 -1
  433. package/build/dist/Server/API/BillingInvoiceAPI.js +1 -1
  434. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  435. package/build/dist/Server/API/BillingPaymentMethodAPI.js +2 -2
  436. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  437. package/build/dist/Server/API/CodeFixRunAPI.js +1 -3
  438. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
  439. package/build/dist/Server/API/CommonAPI.js +50 -5
  440. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  441. package/build/dist/Server/API/DashboardAPI.js +12 -12
  442. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  443. package/build/dist/Server/API/GlobalConfigAPI.js +158 -342
  444. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  445. package/build/dist/Server/API/IncidentAPI.js +2 -2
  446. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  447. package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
  448. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  449. package/build/dist/Server/API/NotificationAPI.js +1 -1
  450. package/build/dist/Server/API/NotificationAPI.js.map +1 -1
  451. package/build/dist/Server/API/OnCallCalendarAPI.js +1 -4
  452. package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -1
  453. package/build/dist/Server/API/OnCallDutyPolicyAPI.js +6 -0
  454. package/build/dist/Server/API/OnCallDutyPolicyAPI.js.map +1 -1
  455. package/build/dist/Server/API/OnCallReadinessAPI.js +4 -1
  456. package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -1
  457. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +494 -0
  458. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -0
  459. package/build/dist/Server/API/ProjectAPI.js +1 -1
  460. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  461. package/build/dist/Server/API/ProjectOIDC.js +24 -16
  462. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  463. package/build/dist/Server/API/ProjectSSO.js +24 -16
  464. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  465. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
  466. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  467. package/build/dist/Server/API/StatusPageAPI.js +218 -76
  468. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  469. package/build/dist/Server/API/TeamMemberAPI.js +11 -4
  470. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  471. package/build/dist/Server/API/UserCallAPI.js +2 -2
  472. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  473. package/build/dist/Server/API/UserEmailAPI.js +2 -2
  474. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  475. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +2 -2
  476. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  477. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +1 -1
  478. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -1
  479. package/build/dist/Server/API/UserSlackAPI.js +1 -1
  480. package/build/dist/Server/API/UserSlackAPI.js.map +1 -1
  481. package/build/dist/Server/API/UserSmsAPI.js +2 -2
  482. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  483. package/build/dist/Server/API/UserTotpAuthAPI.js +1 -1
  484. package/build/dist/Server/API/UserTotpAuthAPI.js.map +1 -1
  485. package/build/dist/Server/API/UserWebAuthnAPI.js +2 -2
  486. package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
  487. package/build/dist/Server/API/UserWebhookAPI.js +1 -1
  488. package/build/dist/Server/API/UserWebhookAPI.js.map +1 -1
  489. package/build/dist/Server/API/UserWhatsAppAPI.js +2 -2
  490. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  491. package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
  492. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
  493. package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
  494. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
  495. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
  496. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
  497. package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
  498. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
  499. package/build/dist/Server/EnvironmentConfig.js +84 -2
  500. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  501. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
  502. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
  503. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  504. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  505. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -2
  506. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  507. package/build/dist/Server/Middleware/UserAuthorization.js +94 -15
  508. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  509. package/build/dist/Server/Services/ApiKeyPermissionService.js +80 -4
  510. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  511. package/build/dist/Server/Services/AuditLogService.js +71 -740
  512. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  513. package/build/dist/Server/Services/DatabaseService.js +171 -0
  514. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  515. package/build/dist/Server/Services/DetectionRuleService.js +4 -4
  516. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
  517. package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
  518. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  519. package/build/dist/Server/Services/GlobalConfigService.js +63 -0
  520. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  521. package/build/dist/Server/Services/MonitorProbeService.js +90 -17
  522. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  523. package/build/dist/Server/Services/MonitorService.js +45 -4
  524. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  525. package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
  526. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  527. package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
  528. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  529. package/build/dist/Server/Services/OnCallDutyPolicyChildService.js +170 -0
  530. package/build/dist/Server/Services/OnCallDutyPolicyChildService.js.map +1 -0
  531. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -2
  532. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  533. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +2 -2
  534. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  535. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -2
  536. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  537. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -2
  538. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  539. package/build/dist/Server/Services/PayAsYouGoBillingService.js +20 -27
  540. package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -1
  541. package/build/dist/Server/Services/ProjectService.js +231 -0
  542. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  543. package/build/dist/Server/Services/RumSessionPinService.js +198 -16
  544. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  545. package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
  546. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  547. package/build/dist/Server/Services/StatusPageService.js +71 -0
  548. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  549. package/build/dist/Server/Services/TeamMemberService.js +10 -0
  550. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  551. package/build/dist/Server/Services/TeamPermissionService.js +89 -27
  552. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  553. package/build/dist/Server/Services/TeamService.js +9 -0
  554. package/build/dist/Server/Services/TeamService.js.map +1 -1
  555. package/build/dist/Server/Services/ThreatIntelFeedService.js +5 -4
  556. package/build/dist/Server/Services/ThreatIntelFeedService.js.map +1 -1
  557. package/build/dist/Server/Services/UserService.js +10 -16
  558. package/build/dist/Server/Services/UserService.js.map +1 -1
  559. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +9 -6
  560. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  561. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
  562. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  563. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
  564. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  565. package/build/dist/Server/Types/Database/Permissions/Index.js +60 -6
  566. package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
  567. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +24 -16
  568. package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
  569. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
  570. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  571. package/build/dist/Server/Types/Markdown.js +31 -0
  572. package/build/dist/Server/Types/Markdown.js.map +1 -1
  573. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +7 -0
  574. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -1
  575. package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js +7 -0
  576. package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js.map +1 -1
  577. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
  578. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
  579. package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
  580. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
  581. package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
  582. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
  583. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
  584. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
  585. package/build/dist/Server/Utils/MasterAdminPageAccess.js +39 -0
  586. package/build/dist/Server/Utils/MasterAdminPageAccess.js.map +1 -0
  587. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +96 -0
  588. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
  589. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  590. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  591. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +3 -1
  592. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  593. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +449 -261
  594. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  595. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +3 -1
  596. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  597. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
  598. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
  599. package/build/dist/Server/Utils/Realtime.js +126 -37
  600. package/build/dist/Server/Utils/Realtime.js.map +1 -1
  601. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +7 -25
  602. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
  603. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js +127 -0
  604. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js.map +1 -0
  605. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +1 -1
  606. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
  607. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +3 -2
  608. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js.map +1 -1
  609. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js +4 -8
  610. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js.map +1 -1
  611. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
  612. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  613. package/build/dist/Types/API/Hostname.js +59 -11
  614. package/build/dist/Types/API/Hostname.js.map +1 -1
  615. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js +31 -1
  616. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js.map +1 -1
  617. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
  618. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
  619. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
  620. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
  621. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
  622. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
  623. package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
  624. package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
  625. package/build/dist/Types/Database/TableColumn.js +19 -6
  626. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  627. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
  628. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
  629. package/build/dist/Types/IP/IPv6.js +6 -1
  630. package/build/dist/Types/IP/IPv6.js.map +1 -1
  631. package/build/dist/Types/Monitor/MonitorStep.js +5 -0
  632. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  633. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
  634. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js +321 -0
  635. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js.map +1 -0
  636. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js +372 -0
  637. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js.map +1 -0
  638. package/build/dist/Types/Realtime/EventName.js +10 -0
  639. package/build/dist/Types/Realtime/EventName.js.map +1 -1
  640. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +11 -0
  641. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
  642. package/build/dist/Types/SecurityEvent/OcsfSeverity.js +30 -25
  643. package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -1
  644. package/build/dist/Types/SecurityEvent/SigmaRule.js +47 -0
  645. package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -1
  646. package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js +14 -0
  647. package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js.map +1 -1
  648. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
  649. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
  650. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +9 -4
  651. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -1
  652. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +10 -2
  653. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -1
  654. package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -1
  655. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  656. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +425 -585
  657. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  658. package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
  659. package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
  660. package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
  661. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  662. package/build/dist/UI/Components/Forms/BasicForm.js +70 -64
  663. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  664. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +27 -0
  665. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -0
  666. package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -7
  667. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  668. package/build/dist/UI/Components/Forms/FormSummary.js +7 -0
  669. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  670. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
  671. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  672. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  673. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  674. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +2 -1
  675. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  676. package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js +84 -0
  677. package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js.map +1 -0
  678. package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
  679. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  680. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +14 -1
  681. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  682. package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
  683. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  684. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
  685. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  686. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
  687. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  688. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -1
  689. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  690. package/build/dist/UI/Components/Tooltip/Tooltip.js +2 -1
  691. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  692. package/build/dist/UI/Utils/API/API.js +143 -19
  693. package/build/dist/UI/Utils/API/API.js.map +1 -1
  694. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +21 -7
  695. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  696. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +26 -9
  697. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  698. package/build/dist/UI/Utils/Navigation.js +8 -0
  699. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  700. package/build/dist/UI/Utils/OpenAuthenticatedUrl.js +92 -0
  701. package/build/dist/UI/Utils/OpenAuthenticatedUrl.js.map +1 -0
  702. package/build/dist/UI/Utils/Realtime.js +120 -15
  703. package/build/dist/UI/Utils/Realtime.js.map +1 -1
  704. package/build/dist/Utils/API.js +13 -5
  705. package/build/dist/Utils/API.js.map +1 -1
  706. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
  707. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  708. package/build/dist/Utils/HostAddressUtil.js +80 -0
  709. package/build/dist/Utils/HostAddressUtil.js.map +1 -0
  710. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
  711. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
  712. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
  713. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
  714. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +123 -6
  715. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
  716. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +4 -18
  717. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -1
  718. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +2 -2
  719. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  720. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
  721. package/jest.config.json +3 -1
  722. package/package.json +1 -1
  723. package/test-setup.sh +103 -34
  724. package/tsconfig.json +13 -0
  725. package/Server/API/EnterpriseLicenseAPI.ts +0 -925
  726. package/Server/API/TeamComplianceAPI.ts +0 -158
  727. package/Server/Middleware/SCIMAuthorization.ts +0 -141
  728. package/Server/Services/TeamComplianceService.ts +0 -733
  729. package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
  730. package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
  731. package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
  732. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
  733. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
  734. package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
  735. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
  736. package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
  737. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
  738. package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
  739. package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
  740. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
  741. package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
  742. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
  743. package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
  744. package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
  745. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
  746. package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
  747. package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
  748. package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
  749. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
  750. package/build/dist/Server/Services/TeamComplianceService.js +0 -537
  751. package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
  752. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
  753. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
  754. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
  755. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
  756. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
  757. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
  758. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
  759. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
@@ -0,0 +1,820 @@
1
+ import { mockRouter } from "./Helpers";
2
+ import AIBillingRouter from "../../../Server/API/AIBillingAPI";
3
+ import AlertAPI from "../../../Server/API/AlertAPI";
4
+ import BillingAPI from "../../../Server/API/BillingAPI";
5
+ import BillingInvoiceAPI from "../../../Server/API/BillingInvoiceAPI";
6
+ import BillingPaymentMethodAPI from "../../../Server/API/BillingPaymentMethodAPI";
7
+ import IncidentAPI from "../../../Server/API/IncidentAPI";
8
+ import IncidentEpisodeAPI from "../../../Server/API/IncidentEpisodeAPI";
9
+ import NotificationRouter from "../../../Server/API/NotificationAPI";
10
+ import ProjectAPI from "../../../Server/API/ProjectAPI";
11
+ import ScheduledMaintenanceAPI from "../../../Server/API/ScheduledMaintenanceAPI";
12
+ import TeamMemberAPI from "../../../Server/API/TeamMemberAPI";
13
+ import UserCallAPI from "../../../Server/API/UserCallAPI";
14
+ import UserEmailAPI from "../../../Server/API/UserEmailAPI";
15
+ import UserIncomingCallNumberAPI from "../../../Server/API/UserIncomingCallNumberAPI";
16
+ import UserMicrosoftTeamsAPI from "../../../Server/API/UserMicrosoftTeamsAPI";
17
+ import UserSlackAPI from "../../../Server/API/UserSlackAPI";
18
+ import UserSmsAPI from "../../../Server/API/UserSmsAPI";
19
+ import UserTotpAuthAPI from "../../../Server/API/UserTotpAuthAPI";
20
+ import UserWebAuthnAPI from "../../../Server/API/UserWebAuthnAPI";
21
+ import UserWebhookAPI from "../../../Server/API/UserWebhookAPI";
22
+ import UserWhatsAppAPI from "../../../Server/API/UserWhatsAppAPI";
23
+ import UserMiddleware from "../../../Server/Middleware/UserAuthorization";
24
+ import VerificationCodeRateLimit, {
25
+ VerificationCodeRateLimitBucket,
26
+ } from "../../../Server/Middleware/VerificationCodeRateLimit";
27
+ import ProjectService from "../../../Server/Services/ProjectService";
28
+ import TeamMemberService from "../../../Server/Services/TeamMemberService";
29
+ import {
30
+ ExpressRequest,
31
+ ExpressResponse,
32
+ NextFunction,
33
+ OneUptimeRequest,
34
+ } from "../../../Server/Utils/Express";
35
+ import Response from "../../../Server/Utils/Response";
36
+ import Dictionary from "../../../Types/Dictionary";
37
+ import Exception from "../../../Types/Exception/Exception";
38
+ import ExceptionCode from "../../../Types/Exception/ExceptionCode";
39
+ import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
40
+ import JSONWebTokenData from "../../../Types/JsonWebTokenData";
41
+ import ObjectID from "../../../Types/ObjectID";
42
+ import UserType from "../../../Types/UserType";
43
+ import {
44
+ afterEach,
45
+ beforeAll,
46
+ beforeEach,
47
+ describe,
48
+ expect,
49
+ test,
50
+ } from "@jest/globals";
51
+
52
+ /*
53
+ * Every custom route that gained UserMiddleware.requireUserAuthentication in
54
+ * the expired-session fix, in one table.
55
+ *
56
+ * THE BUG
57
+ *
58
+ * A customer left the Dashboard open for more than 15 minutes, clicked a
59
+ * button, and was told "You are not authorized to access this project's
60
+ * data." The access-token cookie's maxAge is the JWT's own lifetime, so the
61
+ * browser had dropped it and the request arrived with no token at all.
62
+ * getUserMiddleware does not refuse that request - it marks it UserType.Public
63
+ * and calls next(), because some routes are meant to be anonymous - and each
64
+ * of these handlers then refused it in its own words: a 422, a 400, or worse,
65
+ * a root read that answered with nothing. The browser client only refreshes
66
+ * the session and replays the request on a 401, so every one of those
67
+ * surfaced as a hard error instead of a silent refresh.
68
+ *
69
+ * THE FIX, AS IT APPEARS ON THE ROUTER
70
+ *
71
+ * requireUserAuthentication sits IMMEDIATELY after getUserMiddleware on each
72
+ * of these routes. Immediately, because:
73
+ *
74
+ * - before getUserMiddleware there is no userType to look at, so it would
75
+ * refuse everybody;
76
+ * - on the verification-code routes the VerificationCodeRateLimit limiter
77
+ * must come AFTER it. The limiter spends item and IP budgets as soon as
78
+ * it runs, so running it first would let a stale tab burn a user's
79
+ * attempts on requests that were going to be refused anyway, and a
80
+ * limited request would be answered with a 429 - also not a cue to
81
+ * refresh.
82
+ *
83
+ * WHY A TABLE
84
+ *
85
+ * Twenty-odd routes across nineteen files, each an independent one-line
86
+ * registration. Dropping the guard from one of them breaks nothing that the
87
+ * route's own tests would notice - they call the handler directly - and the
88
+ * symptom only appears for a user whose tab has been idle for a quarter of an
89
+ * hour. So each route is named here, located on the router the API class (or
90
+ * module) actually registered it on, and its middleware list is asserted by
91
+ * identity.
92
+ *
93
+ * Then the chain is RUN for every route with the request an idle tab really
94
+ * sends: no cookie, no API key, but the tenantid header the Dashboard always
95
+ * attaches. getUserMiddleware is the real one, so the test also proves the
96
+ * premise - that such a request reaches the guard as Public rather than
97
+ * being refused earlier - and the guard must answer it with a 401 before the
98
+ * limiter or the handler is reached.
99
+ */
100
+
101
+ jest.mock("../../../Server/Utils/Express", () => {
102
+ return {
103
+ getRouter: () => {
104
+ return mockRouter;
105
+ },
106
+ };
107
+ });
108
+
109
+ jest.mock("../../../Server/Utils/Response", () => {
110
+ return {
111
+ sendEntityArrayResponse: jest.fn(),
112
+ sendJsonArrayResponse: jest.fn(),
113
+ sendJsonObjectResponse: jest.fn(),
114
+ sendEmptySuccessResponse: jest.fn(),
115
+ sendEntityResponse: jest.fn(),
116
+ sendErrorResponse: jest.fn(),
117
+ sendFileResponse: jest.fn(),
118
+ setNoCacheHeaders: jest.fn(),
119
+ };
120
+ });
121
+
122
+ const AUTHENTICATION_REQUIRED_MESSAGE: string =
123
+ "Authentication required. Please log in to access this resource.";
124
+
125
+ const PROJECT_ID: string = "11111111-1111-4111-8111-111111111111";
126
+ const USER_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
127
+ const ROW_ID: string = "33333333-3333-4333-8333-333333333333";
128
+
129
+ type HttpMethod = "GET" | "POST" | "PUT";
130
+
131
+ type GuardedRoute = {
132
+ method: HttpMethod;
133
+
134
+ // Relative to /api, exactly as the router registers it.
135
+ uri: string;
136
+
137
+ // Where the route is registered, for the test names.
138
+ registeredBy: string;
139
+
140
+ // Set only for the routes that also carry a verification-code limiter.
141
+ limiter?: VerificationCodeRateLimitBucket | undefined;
142
+ };
143
+
144
+ const GUARDED_ROUTES: Array<GuardedRoute> = [
145
+ // Credit top-ups.
146
+ {
147
+ method: "POST",
148
+ uri: "/notification/recharge",
149
+ registeredBy: "NotificationAPI",
150
+ },
151
+ { method: "POST", uri: "/ai/recharge", registeredBy: "AIBillingAPI" },
152
+
153
+ // "Send a test message" buttons on the user's notification settings.
154
+ { method: "POST", uri: "/user-slack/test", registeredBy: "UserSlackAPI" },
155
+ {
156
+ method: "POST",
157
+ uri: "/user-microsoft-teams/test",
158
+ registeredBy: "UserMicrosoftTeamsAPI",
159
+ },
160
+ { method: "POST", uri: "/user-webhook/test", registeredBy: "UserWebhookAPI" },
161
+
162
+ // Security key enrolment.
163
+ {
164
+ method: "POST",
165
+ uri: "/user-webauthn/generate-registration-options",
166
+ registeredBy: "UserWebAuthnAPI",
167
+ },
168
+ {
169
+ method: "POST",
170
+ uri: "/user-webauthn/verify-registration",
171
+ registeredBy: "UserWebAuthnAPI",
172
+ },
173
+
174
+ // Contact-method verification, each behind a verification-code limiter.
175
+ {
176
+ method: "POST",
177
+ uri: "/user-incoming-call-number/verify",
178
+ registeredBy: "UserIncomingCallNumberAPI",
179
+ limiter: VerificationCodeRateLimitBucket.Verify,
180
+ },
181
+ {
182
+ method: "POST",
183
+ uri: "/user-incoming-call-number/resend-verification-code",
184
+ registeredBy: "UserIncomingCallNumberAPI",
185
+ limiter: VerificationCodeRateLimitBucket.Resend,
186
+ },
187
+ {
188
+ method: "POST",
189
+ uri: "/user-sms/verify",
190
+ registeredBy: "UserSmsAPI",
191
+ limiter: VerificationCodeRateLimitBucket.Verify,
192
+ },
193
+ {
194
+ method: "POST",
195
+ uri: "/user-sms/resend-verification-code",
196
+ registeredBy: "UserSmsAPI",
197
+ limiter: VerificationCodeRateLimitBucket.Resend,
198
+ },
199
+ {
200
+ method: "POST",
201
+ uri: "/user-call/verify",
202
+ registeredBy: "UserCallAPI",
203
+ limiter: VerificationCodeRateLimitBucket.Verify,
204
+ },
205
+ {
206
+ method: "POST",
207
+ uri: "/user-call/resend-verification-code",
208
+ registeredBy: "UserCallAPI",
209
+ limiter: VerificationCodeRateLimitBucket.Resend,
210
+ },
211
+ {
212
+ method: "POST",
213
+ uri: "/user-email/verify",
214
+ registeredBy: "UserEmailAPI",
215
+ limiter: VerificationCodeRateLimitBucket.Verify,
216
+ },
217
+ {
218
+ method: "POST",
219
+ uri: "/user-email/resend-verification-code",
220
+ registeredBy: "UserEmailAPI",
221
+ limiter: VerificationCodeRateLimitBucket.Resend,
222
+ },
223
+ {
224
+ method: "POST",
225
+ uri: "/user-whatsapp/verify",
226
+ registeredBy: "UserWhatsAppAPI",
227
+ limiter: VerificationCodeRateLimitBucket.Verify,
228
+ },
229
+ {
230
+ method: "POST",
231
+ uri: "/user-whatsapp/resend-verification-code",
232
+ registeredBy: "UserWhatsAppAPI",
233
+ limiter: VerificationCodeRateLimitBucket.Resend,
234
+ },
235
+
236
+ // Authenticator app enrolment.
237
+ {
238
+ method: "POST",
239
+ uri: "/user-totp-auth/validate",
240
+ registeredBy: "UserTotpAuthAPI",
241
+ },
242
+
243
+ // Team membership.
244
+ {
245
+ method: "POST",
246
+ uri: "/team-member/is-user-registered",
247
+ registeredBy: "TeamMemberAPI",
248
+ },
249
+ {
250
+ method: "POST",
251
+ uri: "/team-member/remove-user-from-project",
252
+ registeredBy: "TeamMemberAPI",
253
+ },
254
+ {
255
+ method: "POST",
256
+ uri: "/team-member/:id/leave",
257
+ registeredBy: "TeamMemberAPI",
258
+ },
259
+
260
+ // Billing.
261
+ {
262
+ method: "POST",
263
+ uri: "/billing-payment-methods/setup",
264
+ registeredBy: "BillingPaymentMethodAPI",
265
+ },
266
+ {
267
+ method: "POST",
268
+ uri: "/billing-payment-methods/set-default",
269
+ registeredBy: "BillingPaymentMethodAPI",
270
+ },
271
+ {
272
+ method: "GET",
273
+ uri: "/billing/pay-as-you-go-status",
274
+ registeredBy: "BillingAPI",
275
+ },
276
+ {
277
+ method: "GET",
278
+ uri: "/billing/customer-balance",
279
+ registeredBy: "BillingAPI",
280
+ },
281
+ {
282
+ method: "POST",
283
+ uri: "/billing-invoices/pay",
284
+ registeredBy: "BillingInvoiceAPI",
285
+ },
286
+ {
287
+ method: "PUT",
288
+ uri: "/project/:id/change-plan",
289
+ registeredBy: "ProjectAPI",
290
+ },
291
+
292
+ // "Generate with AI" buttons.
293
+ {
294
+ method: "POST",
295
+ uri: "/incident/generate-postmortem-from-ai/:incidentId",
296
+ registeredBy: "IncidentAPI",
297
+ },
298
+ {
299
+ method: "POST",
300
+ uri: "/incident/generate-note-from-ai/:incidentId",
301
+ registeredBy: "IncidentAPI",
302
+ },
303
+ {
304
+ method: "POST",
305
+ uri: "/alert/generate-note-from-ai/:alertId",
306
+ registeredBy: "AlertAPI",
307
+ },
308
+ {
309
+ method: "POST",
310
+ uri: "/incident-episode/generate-postmortem-from-ai/:episodeId",
311
+ registeredBy: "IncidentEpisodeAPI",
312
+ },
313
+ {
314
+ method: "POST",
315
+ uri: "/scheduled-maintenance/generate-note-from-ai/:scheduledMaintenanceId",
316
+ registeredBy: "ScheduledMaintenanceAPI",
317
+ },
318
+ ];
319
+
320
+ type RecordedRoute = ReturnType<typeof mockRouter.match>;
321
+
322
+ type RouterFunction = RecordedRoute["handlerFunction"];
323
+
324
+ type FindRouteFunction = (route: GuardedRoute) => RecordedRoute;
325
+
326
+ const findRoute: FindRouteFunction = (route: GuardedRoute): RecordedRoute => {
327
+ return mockRouter.match(route.method, route.uri);
328
+ };
329
+
330
+ /*
331
+ * Every limiter the API classes were built with, mapped to its bucket.
332
+ * getMiddleware returns a fresh closure per route, so this is the only way to
333
+ * tell "the limiter" apart from any other function by identity.
334
+ */
335
+ const limiterBuckets: Map<unknown, VerificationCodeRateLimitBucket> = new Map<
336
+ unknown,
337
+ VerificationCodeRateLimitBucket
338
+ >();
339
+
340
+ beforeAll(() => {
341
+ const realGetMiddleware: typeof VerificationCodeRateLimit.getMiddleware =
342
+ VerificationCodeRateLimit.getMiddleware.bind(VerificationCodeRateLimit);
343
+
344
+ const capture: jest.SpyInstance = jest
345
+ .spyOn(VerificationCodeRateLimit, "getMiddleware")
346
+ .mockImplementation(((bucket: VerificationCodeRateLimitBucket) => {
347
+ const limiter: ReturnType<
348
+ typeof VerificationCodeRateLimit.getMiddleware
349
+ > = realGetMiddleware(bucket);
350
+ limiterBuckets.set(limiter, bucket);
351
+ return limiter;
352
+ }) as never);
353
+
354
+ /*
355
+ * NotificationAPI and AIBillingAPI register at import time on a module-level
356
+ * router, so their routes are already on the recorder. mockRouter.routes is
357
+ * therefore NOT cleared here.
358
+ */
359
+ new UserSlackAPI();
360
+ new UserMicrosoftTeamsAPI();
361
+ new UserWebhookAPI();
362
+ new UserWebAuthnAPI();
363
+ new UserIncomingCallNumberAPI();
364
+ new UserSmsAPI();
365
+ new UserCallAPI();
366
+ new UserEmailAPI();
367
+ new UserWhatsAppAPI();
368
+ new UserTotpAuthAPI();
369
+ new TeamMemberAPI();
370
+ new BillingPaymentMethodAPI();
371
+ new BillingAPI();
372
+ new BillingInvoiceAPI();
373
+ new ProjectAPI();
374
+ new IncidentAPI();
375
+ new IncidentEpisodeAPI();
376
+ new AlertAPI();
377
+ new ScheduledMaintenanceAPI();
378
+
379
+ capture.mockRestore();
380
+ });
381
+
382
+ afterEach(() => {
383
+ jest.restoreAllMocks();
384
+ });
385
+
386
+ describe("the harness", () => {
387
+ /*
388
+ * The two module-level routers are the ones most likely to be recorded
389
+ * somewhere other than here, so prove they are the recorder before
390
+ * trusting anything the table says about them.
391
+ */
392
+ test("the module-level routers are the recorder this file reads", () => {
393
+ expect(NotificationRouter).toBe(mockRouter);
394
+ expect(AIBillingRouter).toBe(mockRouter);
395
+ });
396
+
397
+ test("captured a limiter for each verification-code route", () => {
398
+ const limiterRoutes: Array<GuardedRoute> = GUARDED_ROUTES.filter(
399
+ (route: GuardedRoute): boolean => {
400
+ return Boolean(route.limiter);
401
+ },
402
+ );
403
+
404
+ expect(limiterRoutes).toHaveLength(10);
405
+ expect(limiterBuckets.size).toBeGreaterThanOrEqual(limiterRoutes.length);
406
+ });
407
+
408
+ /*
409
+ * mockRouter.match returns the FIRST registration of a method and path, so
410
+ * a second registration of the same route - one with the guard, one
411
+ * without - would hide behind it. Each must be registered exactly once.
412
+ */
413
+ test.each(GUARDED_ROUTES)(
414
+ "$method $uri ($registeredBy) is registered exactly once",
415
+ (route: GuardedRoute) => {
416
+ const registrations: Array<RecordedRoute> = mockRouter.routes.filter(
417
+ (recorded: RecordedRoute): boolean => {
418
+ return recorded.method === route.method && recorded.uri === route.uri;
419
+ },
420
+ );
421
+
422
+ expect(registrations).toHaveLength(1);
423
+ },
424
+ );
425
+ });
426
+
427
+ describe("middleware order on every guarded route", () => {
428
+ test.each(GUARDED_ROUTES)(
429
+ "$method $uri ($registeredBy) resolves the session, then requires it",
430
+ (route: GuardedRoute) => {
431
+ const middlewares: Array<RouterFunction> = findRoute(route).middlewares;
432
+
433
+ expect(middlewares[0]).toBe(UserMiddleware.getUserMiddleware);
434
+ expect(middlewares[1]).toBe(UserMiddleware.requireUserAuthentication);
435
+
436
+ // Exactly once: a second copy further down would mean a mis-edit.
437
+ expect(
438
+ middlewares.filter((middleware: RouterFunction): boolean => {
439
+ return (
440
+ (middleware as unknown) ===
441
+ (UserMiddleware.requireUserAuthentication as unknown)
442
+ );
443
+ }),
444
+ ).toHaveLength(1);
445
+
446
+ // The guard is middleware, never the handler itself.
447
+ expect(findRoute(route).handlerFunction).not.toBe(
448
+ UserMiddleware.requireUserAuthentication,
449
+ );
450
+ },
451
+ );
452
+
453
+ const limiterRoutes: Array<GuardedRoute> = GUARDED_ROUTES.filter(
454
+ (route: GuardedRoute): boolean => {
455
+ return Boolean(route.limiter);
456
+ },
457
+ );
458
+
459
+ test.each(limiterRoutes)(
460
+ "$method $uri ($registeredBy) runs its $limiter limiter only after the guard",
461
+ (route: GuardedRoute) => {
462
+ const middlewares: Array<RouterFunction> = findRoute(route).middlewares;
463
+
464
+ const guardIndex: number = middlewares.indexOf(
465
+ UserMiddleware.requireUserAuthentication as unknown as RouterFunction,
466
+ );
467
+
468
+ const limiterIndexes: Array<number> = middlewares
469
+ .map((middleware: RouterFunction, index: number): number => {
470
+ return limiterBuckets.has(middleware) ? index : -1;
471
+ })
472
+ .filter((index: number): boolean => {
473
+ return index >= 0;
474
+ });
475
+
476
+ expect(guardIndex).toBe(1);
477
+ expect(limiterIndexes).toEqual([2]);
478
+ expect(limiterBuckets.get(middlewares[2])).toBe(route.limiter);
479
+ },
480
+ );
481
+
482
+ test.each(
483
+ GUARDED_ROUTES.filter((route: GuardedRoute): boolean => {
484
+ return !route.limiter;
485
+ }),
486
+ )(
487
+ "$method $uri ($registeredBy) carries no verification-code limiter",
488
+ (route: GuardedRoute) => {
489
+ const middlewares: Array<RouterFunction> = findRoute(route).middlewares;
490
+
491
+ expect(
492
+ middlewares.some((middleware: RouterFunction): boolean => {
493
+ return limiterBuckets.has(middleware);
494
+ }),
495
+ ).toBe(false);
496
+ },
497
+ );
498
+ });
499
+
500
+ type ChainResult = {
501
+ // Index of the middleware that answered instead of calling next(), or -1.
502
+ stoppedAt: number;
503
+ reachedHandler: boolean;
504
+ sentError: Exception | undefined;
505
+ sendErrorCallCount: number;
506
+ request: OneUptimeRequest;
507
+ };
508
+
509
+ type RunChainFunction = (data: {
510
+ route: GuardedRoute;
511
+ request: Dictionary<unknown>;
512
+ runHandler?: boolean | undefined;
513
+ }) => Promise<ChainResult>;
514
+
515
+ /*
516
+ * Runs the recorded middlewares in order, from getUserMiddleware, the way
517
+ * Express would, and stops at the first one that answers instead of calling
518
+ * next(). The handler is only invoked when asked for and only if every
519
+ * middleware let the request through.
520
+ */
521
+ const runChain: RunChainFunction = async (data: {
522
+ route: GuardedRoute;
523
+ request: Dictionary<unknown>;
524
+ runHandler?: boolean | undefined;
525
+ }): Promise<ChainResult> => {
526
+ const recorded: RecordedRoute = findRoute(data.route);
527
+
528
+ const req: OneUptimeRequest = {
529
+ params: {},
530
+ query: {},
531
+ body: {},
532
+ cookies: {},
533
+ ...data.request,
534
+ } as unknown as OneUptimeRequest;
535
+
536
+ const res: ExpressResponse = {
537
+ status: jest.fn().mockReturnThis(),
538
+ json: jest.fn().mockReturnThis(),
539
+ send: jest.fn().mockReturnThis(),
540
+ set: jest.fn().mockReturnThis(),
541
+ setHeader: jest.fn().mockReturnThis(),
542
+ } as unknown as ExpressResponse;
543
+
544
+ let stoppedAt: number = -1;
545
+
546
+ for (let index: number = 0; index < recorded.middlewares.length; index++) {
547
+ const next: jest.Mock = jest.fn();
548
+
549
+ await recorded.middlewares[index]!(
550
+ req as ExpressRequest,
551
+ res,
552
+ next as unknown as NextFunction,
553
+ );
554
+
555
+ if (next.mock.calls.length === 0) {
556
+ stoppedAt = index;
557
+ break;
558
+ }
559
+ }
560
+
561
+ const reachedHandler: boolean = stoppedAt === -1;
562
+
563
+ if (reachedHandler && data.runHandler) {
564
+ await recorded.handlerFunction(
565
+ req as ExpressRequest,
566
+ res,
567
+ jest.fn() as unknown as NextFunction,
568
+ );
569
+ }
570
+
571
+ const errorCalls: Array<Array<unknown>> = (
572
+ Response.sendErrorResponse as unknown as jest.Mock
573
+ ).mock.calls as Array<Array<unknown>>;
574
+
575
+ return {
576
+ stoppedAt: stoppedAt,
577
+ reachedHandler: reachedHandler,
578
+ sentError: errorCalls[0]?.[2] as Exception | undefined,
579
+ sendErrorCallCount: errorCalls.length,
580
+ request: req,
581
+ };
582
+ };
583
+
584
+ /*
585
+ * What a Dashboard tab sends once its access-token cookie has expired: the
586
+ * tenantid header it always attaches, no cookie, no Authorization header, no
587
+ * apikey. The params fill every route parameter in the table with a
588
+ * well-formed id so nothing fails on the path before it fails on the session.
589
+ */
590
+ const EXPIRED_SESSION_REQUEST: Dictionary<unknown> = {
591
+ headers: { tenantid: PROJECT_ID, "user-agent": "jest" },
592
+ params: {
593
+ id: PROJECT_ID,
594
+ incidentId: ROW_ID,
595
+ alertId: ROW_ID,
596
+ episodeId: ROW_ID,
597
+ scheduledMaintenanceId: ROW_ID,
598
+ },
599
+ body: { itemId: ROW_ID, code: "123456", userId: USER_ID.toString() },
600
+ };
601
+
602
+ describe("an expired session on every guarded route", () => {
603
+ let consumeSpy: jest.SpyInstance;
604
+
605
+ beforeEach(() => {
606
+ jest.clearAllMocks();
607
+
608
+ /*
609
+ * getUserMiddleware records the tenant's last-active time fire-and-forget
610
+ * whenever a tenantid header is present. Stubbed so the anonymous request
611
+ * never reaches Postgres.
612
+ */
613
+ jest
614
+ .spyOn(ProjectService, "updateLastActive")
615
+ .mockResolvedValue(undefined as never);
616
+
617
+ /*
618
+ * If the guard ever slips behind a limiter, the limiter would run here.
619
+ * Stubbed so that shows up as a spent-budget assertion failure rather
620
+ * than as a Redis connection error.
621
+ */
622
+ consumeSpy = jest
623
+ .spyOn(VerificationCodeRateLimit, "consume")
624
+ .mockResolvedValue({ outcome: "allowed" } as never);
625
+ });
626
+
627
+ test.each(GUARDED_ROUTES)(
628
+ "$method $uri ($registeredBy) answers 401 at the guard, before anything else runs",
629
+ async (route: GuardedRoute) => {
630
+ const result: ChainResult = await runChain({
631
+ route: route,
632
+ request: EXPIRED_SESSION_REQUEST,
633
+ });
634
+
635
+ // The premise: getUserMiddleware let the request through as Public.
636
+ expect(result.request.userType).toBe(UserType.Public);
637
+
638
+ // The fix: the guard, at index 1, answered it.
639
+ expect(result.stoppedAt).toBe(1);
640
+ expect(result.reachedHandler).toBe(false);
641
+ expect(result.sendErrorCallCount).toBe(1);
642
+ expect(result.sentError).toBeInstanceOf(NotAuthenticatedException);
643
+ expect(result.sentError?.code).toBe(
644
+ ExceptionCode.NotAuthenticatedException,
645
+ );
646
+ expect(result.sentError?.message).toBe(AUTHENTICATION_REQUIRED_MESSAGE);
647
+
648
+ // Nothing downstream spent anything.
649
+ expect(consumeSpy).not.toHaveBeenCalled();
650
+ },
651
+ );
652
+
653
+ /*
654
+ * The same request without the tenantid header - a call the page makes
655
+ * before a project is selected - must get the same 401, not a
656
+ * "project required" answer.
657
+ */
658
+ test.each(GUARDED_ROUTES)(
659
+ "$method $uri ($registeredBy) answers 401 even without a tenant",
660
+ async (route: GuardedRoute) => {
661
+ const result: ChainResult = await runChain({
662
+ route: route,
663
+ request: { ...EXPIRED_SESSION_REQUEST, headers: {} },
664
+ });
665
+
666
+ expect(result.stoppedAt).toBe(1);
667
+ expect(result.sentError).toBeInstanceOf(NotAuthenticatedException);
668
+ },
669
+ );
670
+ });
671
+
672
+ describe("credentialed callers get past the guard on every route", () => {
673
+ beforeEach(() => {
674
+ jest.clearAllMocks();
675
+ });
676
+
677
+ /*
678
+ * requireUserAuthentication is presence-only. Signed-in users obviously,
679
+ * but also project API keys and master admins: automation that already
680
+ * calls these routes with a key must keep working, and whatever the handler
681
+ * then decides about a key is the handler's business, unchanged by this
682
+ * fix.
683
+ */
684
+ const callers: Array<[string, Dictionary<unknown>]> = [
685
+ [
686
+ "a signed-in user",
687
+ {
688
+ userType: UserType.User,
689
+ userAuthorization: { userId: USER_ID } as JSONWebTokenData,
690
+ },
691
+ ],
692
+ ["a project API key", { userType: UserType.API }],
693
+ [
694
+ "a master admin",
695
+ {
696
+ userType: UserType.MasterAdmin,
697
+ userAuthorization: {
698
+ userId: USER_ID,
699
+ isMasterAdmin: true,
700
+ } as JSONWebTokenData,
701
+ },
702
+ ],
703
+ ];
704
+
705
+ test.each(GUARDED_ROUTES)(
706
+ "$method $uri ($registeredBy) admits a user, an API key and a master admin",
707
+ async (route: GuardedRoute) => {
708
+ const guard: RouterFunction = findRoute(route).middlewares[1]!;
709
+
710
+ for (const [label, caller] of callers) {
711
+ const next: jest.Mock = jest.fn();
712
+
713
+ await guard(
714
+ { headers: {}, ...caller } as unknown as ExpressRequest,
715
+ {} as ExpressResponse,
716
+ next as unknown as NextFunction,
717
+ );
718
+
719
+ expect({ caller: label, nextCalls: next.mock.calls }).toEqual({
720
+ caller: label,
721
+ nextCalls: [[]],
722
+ });
723
+ }
724
+
725
+ expect(Response.sendErrorResponse).not.toHaveBeenCalled();
726
+ },
727
+ );
728
+ });
729
+
730
+ /*
731
+ * One route driven end to end, handler included: POST
732
+ * /team-member/remove-user-from-project, because it is destructive and
733
+ * because its handler has its own "Not authenticated" check that answers with
734
+ * a 422. If the guard were missing, the chain would fall through to that
735
+ * handler and the answer would be the 422 - exactly the kind of refusal the
736
+ * browser client does not recover from.
737
+ */
738
+ describe("POST /team-member/remove-user-from-project with an expired session", () => {
739
+ const ROUTE: GuardedRoute = {
740
+ method: "POST",
741
+ uri: "/team-member/remove-user-from-project",
742
+ registeredBy: "TeamMemberAPI",
743
+ };
744
+
745
+ let deleteBySpy: jest.SpyInstance;
746
+
747
+ beforeEach(() => {
748
+ jest.clearAllMocks();
749
+
750
+ jest
751
+ .spyOn(ProjectService, "updateLastActive")
752
+ .mockResolvedValue(undefined as never);
753
+
754
+ deleteBySpy = jest
755
+ .spyOn(TeamMemberService, "deleteBy")
756
+ .mockResolvedValue(1 as never);
757
+ });
758
+
759
+ test("is refused with a 401 and deletes nothing", async () => {
760
+ const result: ChainResult = await runChain({
761
+ route: ROUTE,
762
+ request: {
763
+ headers: { tenantid: PROJECT_ID },
764
+ body: { userId: USER_ID.toString() },
765
+ },
766
+ runHandler: true,
767
+ });
768
+
769
+ expect(result.reachedHandler).toBe(false);
770
+ expect(deleteBySpy).not.toHaveBeenCalled();
771
+ expect(Response.sendErrorResponse).toHaveBeenCalledTimes(1);
772
+ expect(Response.sendErrorResponse).toHaveBeenCalledWith(
773
+ result.request,
774
+ expect.anything(),
775
+ expect.any(NotAuthenticatedException),
776
+ );
777
+ expect(result.sentError?.code).toBe(401);
778
+ expect(Response.sendJsonObjectResponse).not.toHaveBeenCalled();
779
+ });
780
+
781
+ /*
782
+ * The contrast that makes the assertion above meaningful: the same request
783
+ * with the guard skipped reaches the handler, which refuses it with its
784
+ * own 422. That is the answer an expired session used to get.
785
+ */
786
+ test("would have been a 422 from the handler without the guard", async () => {
787
+ const recorded: RecordedRoute = findRoute(ROUTE);
788
+
789
+ const req: OneUptimeRequest = {
790
+ params: {},
791
+ query: {},
792
+ cookies: {},
793
+ headers: { tenantid: PROJECT_ID },
794
+ body: { userId: USER_ID.toString() },
795
+ } as unknown as OneUptimeRequest;
796
+
797
+ const res: ExpressResponse = {
798
+ status: jest.fn().mockReturnThis(),
799
+ } as unknown as ExpressResponse;
800
+
801
+ // getUserMiddleware only, then straight to the handler.
802
+ await recorded.middlewares[0]!(
803
+ req as ExpressRequest,
804
+ res,
805
+ jest.fn() as unknown as NextFunction,
806
+ );
807
+
808
+ await recorded.handlerFunction(
809
+ req as ExpressRequest,
810
+ res,
811
+ jest.fn() as unknown as NextFunction,
812
+ );
813
+
814
+ const sent: Exception = (Response.sendErrorResponse as unknown as jest.Mock)
815
+ .mock.calls[0]![2] as Exception;
816
+
817
+ expect(sent.code).toBe(ExceptionCode.NotAuthorizedException);
818
+ expect(deleteBySpy).not.toHaveBeenCalled();
819
+ });
820
+ });