@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
@@ -138,6 +138,80 @@ describe("PayAsYouGoBillingService", () => {
138
138
  expect(hasPaymentMethods).toHaveBeenCalledWith("cus_project");
139
139
  });
140
140
 
141
+ describe.each([PlanType.Growth, PlanType.Scale, PlanType.Enterprise])(
142
+ "%s plan payment-method exemption",
143
+ (planType: PlanType) => {
144
+ beforeEach(() => {
145
+ getPlan.mockRestore();
146
+ getJestSpyOn(SubscriptionPlan, "getSubscriptionPlans").mockReturnValue([
147
+ new SubscriptionPlan(
148
+ "paid_monthly",
149
+ "paid_yearly",
150
+ planType,
151
+ 20,
152
+ 200,
153
+ 1,
154
+ 14,
155
+ ),
156
+ ]);
157
+ hasPaymentMethods.mockRejectedValue(
158
+ new Error("Payment provider unavailable"),
159
+ );
160
+ getSubscription.mockRejectedValue(
161
+ new Error("Payment provider unavailable"),
162
+ );
163
+ });
164
+
165
+ it.each(["paid_monthly", "paid_yearly"])(
166
+ "allows %s without consulting the payment provider",
167
+ async (planId: string) => {
168
+ project.paymentProviderPlanId = planId;
169
+ await expect(
170
+ service.canUsePayAsYouGo(PROJECT_ID, { useCache: false }),
171
+ ).resolves.toBe(true);
172
+ await expect(
173
+ service.requirePayAsYouGo(PROJECT_ID),
174
+ ).resolves.toBeUndefined();
175
+ expect(hasPaymentMethods).not.toHaveBeenCalled();
176
+ expect(getSubscription).not.toHaveBeenCalled();
177
+ },
178
+ );
179
+
180
+ it("does not require a Stripe customer or subscription for admission", async () => {
181
+ project.paymentProviderPlanId = "paid_monthly";
182
+ delete project.paymentProviderCustomerId;
183
+ delete project.paymentProviderSubscriptionId;
184
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
185
+ expect(hasPaymentMethods).not.toHaveBeenCalled();
186
+ expect(getSubscription).not.toHaveBeenCalled();
187
+ });
188
+
189
+ it("authorizes direct metered usage for the subscription's paid project", async () => {
190
+ project.paymentProviderPlanId = "paid_yearly";
191
+ const owner: Project = new Project();
192
+ owner.id = PROJECT_ID;
193
+ getJestSpyOn(ProjectService, "findOneBy").mockResolvedValue(owner);
194
+ const subscription: Stripe.Subscription = {
195
+ customer: "cus_project",
196
+ } as Stripe.Subscription;
197
+ await expect(
198
+ service.requireMeteredSubscriptionPayment(subscription),
199
+ ).resolves.toBeUndefined();
200
+ const authorization: LiveUsageAuthorization | null =
201
+ await service.authorizeUsageNow(PROJECT_ID);
202
+ expect(authorization).not.toBeNull();
203
+ expect(
204
+ service.isLiveAuthorizationFor(
205
+ authorization || undefined,
206
+ PROJECT_ID,
207
+ ),
208
+ ).toBe(true);
209
+ expect(hasPaymentMethods).not.toHaveBeenCalled();
210
+ expect(getSubscription).not.toHaveBeenCalled();
211
+ });
212
+ },
213
+ );
214
+
141
215
  it("does not cache a rejection, so adding a payment method takes effect immediately", async () => {
142
216
  await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
143
217
  hasPaymentMethods.mockResolvedValue(true);
@@ -318,34 +392,11 @@ describe("PayAsYouGoBillingService", () => {
318
392
 
319
393
  describe("paid subscriptions without a stored payment method", () => {
320
394
  beforeEach(() => {
321
- getPlan.mockReturnValue(
322
- new SubscriptionPlan(
323
- "growth",
324
- "growth_yearly",
325
- PlanType.Growth,
326
- 20,
327
- 200,
328
- 1,
329
- 14,
330
- ),
331
- );
332
- });
333
-
334
- it("permits a verified active invoice agreement", async () => {
335
- getSubscription.mockResolvedValue({
336
- customer: { id: "cus_project" },
337
- status: "active",
338
- collection_method: "send_invoice",
339
- });
340
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
395
+ getPlan.mockReturnValue(GROWTH_PLAN);
341
396
  });
342
397
 
343
398
  it("preserves already authorized invoice history without a new cutoff", async () => {
344
- getSubscription.mockResolvedValue({
345
- customer: "cus_project",
346
- status: "active",
347
- collection_method: "send_invoice",
348
- });
399
+ getSubscription.mockResolvedValue(ACTIVE_INVOICE_AGREEMENT);
349
400
  const start: jest.SpyInstance = getJestSpyOn(
350
401
  BillingService,
351
402
  "getMeteredBillingStartDate",
@@ -354,30 +405,73 @@ describe("PayAsYouGoBillingService", () => {
354
405
  service.getTelemetryBillingStartDate(PROJECT_ID),
355
406
  ).resolves.toBeUndefined();
356
407
  expect(start).not.toHaveBeenCalled();
408
+ expect(hasPaymentMethods).not.toHaveBeenCalled();
357
409
  });
358
410
 
359
- it.each(["trialing", "unpaid", "canceled", "past_due", "incomplete"])(
360
- "does not interpret a %s subscription as a paid invoice contract",
411
+ it.each([
412
+ "active",
413
+ "trialing",
414
+ "unpaid",
415
+ "canceled",
416
+ "past_due",
417
+ "incomplete",
418
+ ])(
419
+ "leaves %s subscription enforcement to the existing subscription checks",
361
420
  async (status: string) => {
362
421
  getSubscription.mockResolvedValue({
363
422
  customer: "cus_project",
364
423
  status,
365
424
  collection_method: "send_invoice",
366
425
  });
367
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
426
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
427
+ expect(hasPaymentMethods).not.toHaveBeenCalled();
428
+ expect(getSubscription).not.toHaveBeenCalled();
368
429
  },
369
430
  );
431
+ });
432
+
433
+ describe("plan changes", () => {
434
+ it("allows an upgrade immediately on a fresh check after a cached Free denial", async () => {
435
+ await expect(
436
+ service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
437
+ ).resolves.toBe(false);
438
+ getPlan.mockReturnValue(GROWTH_PLAN);
439
+ project.paymentProviderPlanId = "growth";
440
+ await expect(
441
+ service.canUsePayAsYouGo(PROJECT_ID, { useCache: false }),
442
+ ).resolves.toBe(true);
443
+ await expect(
444
+ service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
445
+ ).resolves.toBe(true);
446
+ expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
447
+ });
448
+
449
+ it("requires a card after a downgrade on the next fresh check", async () => {
450
+ getPlan.mockReturnValueOnce(GROWTH_PLAN);
451
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
452
+ await expect(
453
+ service.canUsePayAsYouGo(PROJECT_ID, { useCache: false }),
454
+ ).resolves.toBe(false);
455
+ await expect(
456
+ service.requirePayAsYouGo(PROJECT_ID),
457
+ ).rejects.toBeInstanceOf(PaymentRequiredException);
458
+ });
370
459
 
371
- it("denies automatic collection without a card", async () => {
460
+ it("does not keep a paid exemption past the admission cache lifetime", async () => {
461
+ const now: jest.SpyInstance = getJestSpyOn(Date, "now").mockReturnValue(
462
+ 100_000,
463
+ );
464
+ getPlan.mockReturnValueOnce(GROWTH_PLAN);
465
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
466
+ now.mockReturnValue(160_001);
372
467
  await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
468
+ expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
373
469
  });
374
470
 
375
- it("does not accept another customer's invoice contract", async () => {
376
- getSubscription.mockResolvedValue({
377
- customer: "cus_other",
378
- status: "active",
379
- collection_method: "send_invoice",
380
- });
471
+ it("rechecks the plan after invalidation", async () => {
472
+ getPlan.mockReturnValueOnce(GROWTH_PLAN);
473
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
474
+ service.invalidate(PROJECT_ID);
381
475
  await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
382
476
  });
383
477
  });
@@ -467,116 +561,30 @@ describe("PayAsYouGoBillingService", () => {
467
561
  expect(hasPaymentMethods).not.toHaveBeenCalled();
468
562
  });
469
563
 
470
- /*
471
- * Stripe rate-limits GET /v1/subscriptions/:id per endpoint. Reading the
472
- * subscription before the card put that endpoint in front of every card
473
- * holder's answer - three or four reads per monitor create - and CI's Stripe
474
- * test account, shared with every other environment running this code, was
475
- * held at the limit until requests failed. The card is read first now, and
476
- * the subscription only when there is no card.
477
- */
478
- describe("reading the card before the subscription", () => {
479
- beforeEach(() => {
480
- getPlan.mockReturnValue(GROWTH_PLAN);
481
- });
482
-
483
- it("authorizes a card holder on a paid plan without reading its subscription", async () => {
484
- hasPaymentMethods.mockResolvedValue(true);
485
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
486
- expect(hasPaymentMethods).toHaveBeenCalledWith("cus_project");
487
- expect(getSubscription).not.toHaveBeenCalled();
488
- });
489
-
490
- it("reads the card first, then accepts this customer's active invoice agreement", async () => {
491
- getSubscription.mockResolvedValue(ACTIVE_INVOICE_AGREEMENT);
492
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
493
- expect(getSubscription).toHaveBeenCalledWith("sub_project");
494
- expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
495
- expect(hasPaymentMethods.mock.invocationCallOrder[0]).toBeLessThan(
496
- getSubscription.mock.invocationCallOrder[0]!,
497
- );
498
- });
499
-
500
- it("still refuses a no-card project an invoice agreement that belongs to another customer", async () => {
501
- getSubscription.mockResolvedValue({
502
- ...ACTIVE_INVOICE_AGREEMENT,
503
- customer: { id: "cus_other" },
504
- });
505
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
506
- expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
507
- expect(getSubscription).toHaveBeenCalledTimes(1);
508
- });
564
+ it("refuses a no-card Free project even with an invoice-looking subscription", async () => {
565
+ getSubscription.mockResolvedValue(ACTIVE_INVOICE_AGREEMENT);
566
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
567
+ expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
568
+ expect(getSubscription).not.toHaveBeenCalled();
569
+ });
509
570
 
510
- it.each(["trialing", "past_due", "canceled"])(
511
- "still refuses a no-card project whose invoice subscription is %s",
512
- async (status: string) => {
513
- getSubscription.mockResolvedValue({
514
- ...ACTIVE_INVOICE_AGREEMENT,
515
- status,
516
- });
517
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
518
- expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
519
- },
571
+ it("does not cache a failed Free-plan payment-method read", async () => {
572
+ hasPaymentMethods.mockRejectedValueOnce(
573
+ new Error("Payment provider unavailable"),
520
574
  );
521
-
522
- it("refuses a no-card Free project without reading even an invoice-looking subscription", async () => {
523
- getPlan.mockReturnValue(
524
- new SubscriptionPlan("free", "free_yearly", PlanType.Free, 0, 0, 0, 0),
525
- );
526
- getSubscription.mockResolvedValue(ACTIVE_INVOICE_AGREEMENT);
527
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(false);
528
- expect(hasPaymentMethods).toHaveBeenCalledTimes(1);
529
- expect(getSubscription).not.toHaveBeenCalled();
530
- });
531
-
532
- it("authorizes a redeemed reseller license without any payment-provider call", async () => {
533
- project.resellerId = ObjectID.generate();
534
- project.resellerPlanId = ObjectID.generate();
535
- getJestSpyOn(PromoCodeService, "findOneBy").mockResolvedValue(
536
- new PromoCode(),
537
- );
538
- await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
539
- expect(hasPaymentMethods).not.toHaveBeenCalled();
540
- expect(getSubscription).not.toHaveBeenCalled();
541
- });
542
-
543
- it("propagates a failed card read without falling through to the invoice read or caching an answer", async () => {
544
- hasPaymentMethods.mockRejectedValueOnce(
545
- new Error("Payment provider unavailable"),
546
- );
547
- await expect(
548
- service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
549
- ).rejects.toThrow("Payment provider unavailable");
550
- expect(getSubscription).not.toHaveBeenCalled();
551
-
552
- /*
553
- * Neither a denial nor an allow was recorded: even the admission path,
554
- * which may answer from a cached denial, has to read again.
555
- */
556
- hasPaymentMethods.mockResolvedValue(true);
557
- await expect(
558
- service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
559
- ).resolves.toBe(true);
560
- expect(hasPaymentMethods).toHaveBeenCalledTimes(2);
561
- });
562
-
563
- it("propagates a failed invoice read on the no-card path without caching an answer", async () => {
564
- getSubscription.mockRejectedValueOnce(new Error("Stripe rate limited"));
565
- await expect(
566
- service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
567
- ).rejects.toThrow("Stripe rate limited");
568
-
569
- getSubscription.mockResolvedValue(ACTIVE_INVOICE_AGREEMENT);
570
- await expect(
571
- service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
572
- ).resolves.toBe(true);
573
- expect(getSubscription).toHaveBeenCalledTimes(2);
574
- });
575
+ await expect(
576
+ service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
577
+ ).rejects.toThrow("Payment provider unavailable");
578
+ expect(getSubscription).not.toHaveBeenCalled();
579
+ hasPaymentMethods.mockResolvedValue(true);
580
+ await expect(
581
+ service.canUsePayAsYouGo(PROJECT_ID, { allowStaleDenial: true }),
582
+ ).resolves.toBe(true);
583
+ expect(hasPaymentMethods).toHaveBeenCalledTimes(2);
575
584
  });
576
585
 
577
586
  /*
578
- * With the card read first, an invoice customer who also keeps a card on
579
- * file is authorized as "payment-method". That answer must not earn them a
587
+ * Paid-plan authorization must not change an invoice customer's existing
580
588
  * metered billing cutoff: a cutoff waives every unreported telemetry cost
581
589
  * before it, which their invoice agreement already bills.
582
590
  */
@@ -607,6 +615,48 @@ describe("PayAsYouGoBillingService", () => {
607
615
  expect(meteredBillingStart).toHaveBeenCalledWith("cus_project");
608
616
  });
609
617
 
618
+ it.each([PlanType.Growth, PlanType.Scale, PlanType.Enterprise])(
619
+ "preserves the durable billing cutoff for a %s project without a card",
620
+ async (planType: PlanType) => {
621
+ getPlan.mockReturnValue(
622
+ new SubscriptionPlan("paid", "paid_yearly", planType, 20, 200, 1, 14),
623
+ );
624
+ hasPaymentMethods.mockResolvedValue(false);
625
+ await expect(
626
+ service.getTelemetryBillingStartDate(PROJECT_ID),
627
+ ).resolves.toEqual(new Date("2026-09-09T00:00:00Z"));
628
+ expect(meteredBillingStart).toHaveBeenCalledWith("cus_project");
629
+ expect(hasPaymentMethods).not.toHaveBeenCalled();
630
+ },
631
+ );
632
+
633
+ it.each(["trialing", "unpaid", "canceled", "past_due", "incomplete"])(
634
+ "does not waive billing history for a %s invoice subscription",
635
+ async (status: string) => {
636
+ getSubscription.mockResolvedValue({
637
+ ...ACTIVE_INVOICE_AGREEMENT,
638
+ status,
639
+ });
640
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
641
+ await expect(
642
+ service.getTelemetryBillingStartDate(PROJECT_ID),
643
+ ).resolves.toEqual(new Date("2026-09-09T00:00:00Z"));
644
+ expect(meteredBillingStart).toHaveBeenCalledWith("cus_project");
645
+ },
646
+ );
647
+
648
+ it("does not waive billing history using another customer's invoice subscription", async () => {
649
+ getSubscription.mockResolvedValue({
650
+ ...ACTIVE_INVOICE_AGREEMENT,
651
+ customer: { id: "cus_other" },
652
+ });
653
+ await expect(service.canUsePayAsYouGo(PROJECT_ID)).resolves.toBe(true);
654
+ await expect(
655
+ service.getTelemetryBillingStartDate(PROJECT_ID),
656
+ ).resolves.toEqual(new Date("2026-09-09T00:00:00Z"));
657
+ expect(meteredBillingStart).toHaveBeenCalledWith("cus_project");
658
+ });
659
+
610
660
  it("asks a Free card holder for no subscription before its cutoff", async () => {
611
661
  getPlan.mockReturnValue(
612
662
  new SubscriptionPlan("free", "free_yearly", PlanType.Free, 0, 0, 0, 0),
@@ -248,7 +248,7 @@ describe("Stripe rate-limit budget for pay-as-you-go billing", () => {
248
248
  jest.restoreAllMocks();
249
249
  });
250
250
 
251
- it("answers a card holder's pay-as-you-go allow check with zero subscription reads", async () => {
251
+ it("answers a paid plan's pay-as-you-go allow check without payment-provider reads", async () => {
252
252
  await expect(
253
253
  PayAsYouGoBillingService.canUsePayAsYouGo(projectId),
254
254
  ).resolves.toBe(true);
@@ -259,10 +259,7 @@ describe("Stripe rate-limit budget for pay-as-you-go billing", () => {
259
259
  ).resolves.toBe(true);
260
260
 
261
261
  expect(stripe.retrieveSubscription).not.toHaveBeenCalled();
262
- expect(stripe.calls).toEqual([
263
- "paymentMethods.list",
264
- "paymentMethods.list",
265
- ]);
262
+ expect(stripe.calls).toEqual([]);
266
263
  });
267
264
 
268
265
  it("creates a non-manual monitor on a card-holding Growth project with at most one subscription read", async () => {
@@ -306,8 +303,6 @@ describe("Stripe rate-limit budget for pay-as-you-go billing", () => {
306
303
  { quantity: 1 },
307
304
  );
308
305
  expect(stripe.calls).toEqual([
309
- "paymentMethods.list", // admission, in onBeforeCreate
310
- "paymentMethods.list", // the report's one live authorization
311
306
  "subscriptions.retrieve", // the metered subscription's items
312
307
  "subscriptionItems.createUsageRecord",
313
308
  ]);
@@ -367,8 +362,8 @@ describe("Stripe rate-limit budget for pay-as-you-go billing", () => {
367
362
  // Only the telemetry cutoff asks about an invoice agreement, and only once.
368
363
  expect(subscriptionReadsOf(stripe, SUBSCRIPTION_ID)).toBe(1);
369
364
 
370
- // One live authorization per product report, shared by everything after it.
371
- expect(callsTo(stripe, "paymentMethods.list")).toBe(billingPass.length);
365
+ // Paid plans authorize usage without reading payment methods.
366
+ expect(callsTo(stripe, "paymentMethods.list")).toBe(0);
372
367
 
373
368
  // Every usage write still reads the metered items it writes against.
374
369
  expect(subscriptionReadsOf(stripe, METERED_SUBSCRIPTION_ID)).toBe(