@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
@@ -1,10 +1,17 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import Model from "../../Models/DatabaseModels/RumSessionPin";
3
+ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
3
4
  import BadDataException from "../../Types/Exception/BadDataException";
5
+ import Exception from "../../Types/Exception/Exception";
6
+ import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
4
7
  import ObjectID from "../../Types/ObjectID";
5
8
  import OneUptimeDate from "../../Types/Date";
9
+ import DatabaseRequestType from "../Types/BaseDatabase/DatabaseRequestType";
6
10
  import CreateBy from "../Types/Database/CreateBy";
7
11
  import { OnCreate } from "../Types/Database/Hooks";
12
+ import CreatePermission from "../Types/Database/Permissions/CreatePermission";
13
+ import ReadPermission from "../Types/Database/Permissions/ReadPermission";
14
+ import TablePermission from "../Types/Database/Permissions/TablePermission";
8
15
  import QueryHelper from "../Types/Database/QueryHelper";
9
16
  import PostgresErrorTranslator from "../Utils/Database/PostgresErrorTranslator";
10
17
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
@@ -24,6 +31,62 @@ const isUniqueViolation: IsUniqueViolationFunction = (
24
31
  return PostgresErrorTranslator.isUniqueViolation(error);
25
32
  };
26
33
 
34
+ /* What the unique index keys a pin on. */
35
+ interface PinKey {
36
+ projectId: ObjectID;
37
+ rumApplicationId: ObjectID;
38
+ sessionId: string;
39
+ }
40
+
41
+ type IsSameIdFunction = (a: ObjectID, b: ObjectID) => boolean;
42
+
43
+ /*
44
+ * ObjectID.equals compares the strings as given, but a UUID is the same
45
+ * project in any case - and the tenant an API key resolves to comes back
46
+ * from Postgres in lower case whatever the client typed.
47
+ */
48
+ const isSameId: IsSameIdFunction = (a: ObjectID, b: ObjectID): boolean => {
49
+ return a.toString().toLowerCase() === b.toString().toLowerCase();
50
+ };
51
+
52
+ type ToPlainIdFunction = (
53
+ value: unknown,
54
+ field: string,
55
+ ) => ObjectID | undefined;
56
+
57
+ /*
58
+ * An id from the request body as a plain ObjectID. The body is deserialized
59
+ * generically, so a field typed as an id can arrive as some other object.
60
+ */
61
+ const toPlainId: ToPlainIdFunction = (
62
+ value: unknown,
63
+ field: string,
64
+ ): ObjectID | undefined => {
65
+ if (value === undefined || value === null) {
66
+ return undefined;
67
+ }
68
+
69
+ if (value instanceof ObjectID || typeof value === "string") {
70
+ const id: string = value.toString();
71
+
72
+ if (ObjectID.isValidUUID(id)) {
73
+ return new ObjectID(id);
74
+ }
75
+ }
76
+
77
+ throw new BadDataException(`${field} must be an ID.`);
78
+ };
79
+
80
+ type IsInternalCallerFunction = (
81
+ props: DatabaseCommonInteractionProps,
82
+ ) => boolean;
83
+
84
+ const isInternalCaller: IsInternalCallerFunction = (
85
+ props: DatabaseCommonInteractionProps,
86
+ ): boolean => {
87
+ return Boolean(props.isRoot || props.isMasterAdmin);
88
+ };
89
+
27
90
  /*
28
91
  * Pins that keep a session recording past its retention window.
29
92
  *
@@ -88,27 +151,36 @@ export class Service extends DatabaseService<Model> {
88
151
  *
89
152
  * The pre-check handles the common case and the catch closes the race
90
153
  * between two concurrent pins of the same session.
154
+ *
155
+ * Both lookups read as root, so neither may run until the caller has
156
+ * passed the create check that super.create would otherwise have been the
157
+ * first to apply, and what they find is handed back only as far as the
158
+ * caller could have read it.
91
159
  */
92
160
  @CaptureSpan()
93
161
  public override async create(createBy: CreateBy<Model>): Promise<Model> {
94
- const projectId: ObjectID | undefined = createBy.data.projectId;
95
- const rumApplicationId: ObjectID | undefined =
96
- createBy.data.rumApplicationId;
97
- const sessionId: string | undefined = createBy.data.sessionId;
162
+ this.assertCallerMayCreatePins(createBy.props);
98
163
 
99
- if (!projectId || !rumApplicationId || !sessionId) {
164
+ if (!isInternalCaller(createBy.props)) {
165
+ /* The database keeps these for itself; a request does not set them. */
166
+ delete createBy.data._id;
167
+ delete createBy.data.createdAt;
168
+ delete createBy.data.updatedAt;
169
+ delete createBy.data.deletedAt;
170
+ delete createBy.data.version;
171
+ }
172
+
173
+ const pinKey: PinKey | null = this.resolvePinKey(createBy);
174
+
175
+ if (!pinKey) {
100
176
  /* Let onBeforeCreate produce the specific validation message. */
101
177
  return await super.create(createBy);
102
178
  }
103
179
 
104
- const existingPin: Model | null = await this.getPinForSession({
105
- projectId: projectId,
106
- rumApplicationId: rumApplicationId,
107
- sessionId: sessionId,
108
- });
180
+ const existingPin: Model | null = await this.getPinForSession(pinKey);
109
181
 
110
182
  if (existingPin) {
111
- return existingPin;
183
+ return await this.presentExistingPin(existingPin, pinKey, createBy.props);
112
184
  }
113
185
 
114
186
  try {
@@ -118,27 +190,204 @@ export class Service extends DatabaseService<Model> {
118
190
  throw err;
119
191
  }
120
192
 
121
- const racedPin: Model | null = await this.getPinForSession({
122
- projectId: projectId,
123
- rumApplicationId: rumApplicationId,
124
- sessionId: sessionId,
125
- });
193
+ const racedPin: Model | null = await this.getPinForSession(pinKey);
126
194
 
127
195
  if (racedPin) {
128
- return racedPin;
196
+ return await this.presentExistingPin(racedPin, pinKey, createBy.props);
197
+ }
198
+
199
+ throw err;
200
+ }
201
+ }
202
+
203
+ /*
204
+ * The table half of ModelPermission.checkCreatePermissions: signed in or
205
+ * holding an API key, and granted something on the model's create list in
206
+ * the tenant. The column half stays with super.create, which runs it after
207
+ * onBeforeCreate has stripped the fields it rewrites; the idempotent path
208
+ * writes no columns for it to judge.
209
+ */
210
+ private assertCallerMayCreatePins(
211
+ props: DatabaseCommonInteractionProps,
212
+ ): void {
213
+ if (isInternalCaller(props)) {
214
+ return;
215
+ }
216
+
217
+ CreatePermission.checkCreateBlockPermissions(Model, props);
218
+
219
+ TablePermission.checkTableLevelPermissions(
220
+ Model,
221
+ props,
222
+ DatabaseRequestType.Create,
223
+ );
224
+ }
225
+
226
+ /*
227
+ * The (projectId, rumApplicationId, sessionId) this request would insert,
228
+ * which is therefore what both lookups must search - or null when a part
229
+ * is missing, so that onBeforeCreate can say which. The lookups are
230
+ * queries, so every part has to be a plain id or string.
231
+ *
232
+ * projectId is the one super.create will write: the caller's tenant when
233
+ * there is one, otherwise the projectId an internal caller passed. A
234
+ * request naming any other project is refused, because the caller's
235
+ * grants were checked in the tenant and nowhere else; internal callers
236
+ * keep DatabaseService's rule that the tenant replaces it.
237
+ *
238
+ * The project and the application can also be named through the `project`
239
+ * and `rumApplication` relations. Each shares its scalar's column and wins
240
+ * over it when TypeORM saves, so a relation that disagrees is refused and
241
+ * both are dropped, leaving the scalars as the only thing saved.
242
+ */
243
+ private resolvePinKey(createBy: CreateBy<Model>): PinKey | null {
244
+ const props: DatabaseCommonInteractionProps = createBy.props;
245
+ const isInternal: boolean = isInternalCaller(props);
246
+
247
+ const claimedProjectId: ObjectID | undefined = toPlainId(
248
+ createBy.data.projectId,
249
+ "projectId",
250
+ );
251
+ const rumApplicationId: ObjectID | undefined = toPlainId(
252
+ createBy.data.rumApplicationId,
253
+ "rumApplicationId",
254
+ );
255
+
256
+ const rawSessionId: unknown = createBy.data.sessionId;
257
+
258
+ if (
259
+ rawSessionId !== undefined &&
260
+ rawSessionId !== null &&
261
+ typeof rawSessionId !== "string"
262
+ ) {
263
+ throw new BadDataException("sessionId must be a string.");
264
+ }
265
+
266
+ const sessionId: string | undefined =
267
+ typeof rawSessionId === "string" ? rawSessionId : undefined;
268
+
269
+ const projectRelationId: ObjectID | undefined = toPlainId(
270
+ createBy.data.project?._id,
271
+ "project",
272
+ );
273
+ const applicationRelationId: ObjectID | undefined = toPlainId(
274
+ createBy.data.rumApplication?._id,
275
+ "rumApplication",
276
+ );
277
+
278
+ delete createBy.data.project;
279
+ delete createBy.data.rumApplication;
280
+
281
+ const projectId: ObjectID | undefined = isInternal
282
+ ? props.tenantId || claimedProjectId
283
+ : props.tenantId;
284
+
285
+ const projectClaims: Array<ObjectID> = [];
286
+
287
+ if (projectRelationId) {
288
+ projectClaims.push(projectRelationId);
289
+ }
290
+
291
+ if (claimedProjectId && !isInternal) {
292
+ projectClaims.push(claimedProjectId);
293
+ }
294
+
295
+ for (const projectClaim of projectClaims) {
296
+ if (!projectId || !isSameId(projectClaim, projectId)) {
297
+ throw isInternal
298
+ ? new BadDataException("project does not match projectId.")
299
+ : new NotAuthorizedException(
300
+ "You are not authorized to pin recordings in this project.",
301
+ );
302
+ }
303
+ }
304
+
305
+ if (
306
+ applicationRelationId &&
307
+ !(rumApplicationId && isSameId(applicationRelationId, rumApplicationId))
308
+ ) {
309
+ throw new BadDataException(
310
+ "rumApplication does not match rumApplicationId.",
311
+ );
312
+ }
313
+
314
+ if (!claimedProjectId || !projectId || !rumApplicationId || !sessionId) {
315
+ return null;
316
+ }
317
+
318
+ createBy.data.projectId = projectId;
319
+ createBy.data.rumApplicationId = rumApplicationId;
320
+
321
+ return {
322
+ projectId: projectId,
323
+ rumApplicationId: rumApplicationId,
324
+ sessionId: sessionId,
325
+ };
326
+ }
327
+
328
+ /*
329
+ * An existing pin was read as root, and passing the create check says
330
+ * nothing about reading it: CreateRumSessionReplay, the ingest grant, is
331
+ * on the create list but not the read list, and a team can block reads
332
+ * alone. Such a caller learns that the recording is pinned, which is all
333
+ * pinning it again needs, and nothing that somebody else wrote on the pin.
334
+ */
335
+ private async presentExistingPin(
336
+ pin: Model,
337
+ pinKey: PinKey,
338
+ props: DatabaseCommonInteractionProps,
339
+ ): Promise<Model> {
340
+ if (await this.callerMayReadPins(props)) {
341
+ return pin;
342
+ }
343
+
344
+ /*
345
+ * Not even the pin's id: it is what the update and delete endpoints
346
+ * take, and this caller could not have listed it.
347
+ */
348
+ const acknowledgement: Model = new Model();
349
+ acknowledgement.projectId = pinKey.projectId;
350
+ acknowledgement.rumApplicationId = pinKey.rumApplicationId;
351
+ acknowledgement.sessionId = pinKey.sessionId;
352
+
353
+ return acknowledgement;
354
+ }
355
+
356
+ /*
357
+ * The gates a read of this table applies, answered instead of thrown: the
358
+ * read block list (label-scoped blocks included, which this model cannot
359
+ * narrow to rows and so refuses outright) and the read list itself. Any
360
+ * refusal, whatever its type, means the caller does not get the pin.
361
+ */
362
+ private async callerMayReadPins(
363
+ props: DatabaseCommonInteractionProps,
364
+ ): Promise<boolean> {
365
+ if (isInternalCaller(props)) {
366
+ return true;
367
+ }
368
+
369
+ try {
370
+ await ReadPermission.checkReadBlockPermission(Model, {}, props);
371
+
372
+ TablePermission.checkTableLevelPermissions(
373
+ Model,
374
+ props,
375
+ DatabaseRequestType.Read,
376
+ );
377
+ } catch (err) {
378
+ if (err instanceof Exception) {
379
+ return false;
129
380
  }
130
381
 
131
382
  throw err;
132
383
  }
384
+
385
+ return true;
133
386
  }
134
387
 
135
388
  /* Null when the recording is not pinned. */
136
389
  @CaptureSpan()
137
- public async getPinForSession(data: {
138
- projectId: ObjectID;
139
- rumApplicationId: ObjectID;
140
- sessionId: string;
141
- }): Promise<Model | null> {
390
+ public async getPinForSession(data: PinKey): Promise<Model | null> {
142
391
  return await this.findOneBy({
143
392
  query: {
144
393
  projectId: data.projectId,
@@ -147,6 +396,9 @@ export class Service extends DatabaseService<Model> {
147
396
  },
148
397
  select: {
149
398
  _id: true,
399
+ projectId: true,
400
+ rumApplicationId: true,
401
+ sessionId: true,
150
402
  reason: true,
151
403
  incidentId: true,
152
404
  alertId: true,
@@ -2,6 +2,8 @@ import CreateBy from "../Types/Database/CreateBy";
2
2
  import DeleteBy from "../Types/Database/DeleteBy";
3
3
  import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
4
4
  import UpdateBy from "../Types/Database/UpdateBy";
5
+ import ModelPermission from "../Types/Database/Permissions/Index";
6
+ import QueryHelper from "../Types/Database/QueryHelper";
5
7
  import AccessTokenService from "./AccessTokenService";
6
8
  import DatabaseService from "./DatabaseService";
7
9
  import TeamMemberService from "./TeamMemberService";
@@ -11,7 +13,7 @@ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCom
11
13
  import DatabaseCommonInteractionPropsUtil, {
12
14
  PermissionType,
13
15
  } from "../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
14
- import LIMIT_MAX, { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
16
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
15
17
  import BadDataException from "../../Types/Exception/BadDataException";
16
18
  import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
17
19
  import PermissionScope from "../../Types/Database/AccessControl/PermissionScope";
@@ -112,6 +114,11 @@ export class Service extends DatabaseService<Model> {
112
114
  data.props,
113
115
  PermissionType.Allow,
114
116
  );
117
+ const callerBlocks: Array<UserPermission> =
118
+ DatabaseCommonInteractionPropsUtil.getUserPermissions(
119
+ data.props,
120
+ PermissionType.Block,
121
+ );
115
122
 
116
123
  /*
117
124
  * ProjectOwner is the sole tenant-level delegation override. In
@@ -123,6 +130,12 @@ export class Service extends DatabaseService<Model> {
123
130
  */
124
131
  if (
125
132
  callerPermissions.some((permission: UserPermission) => {
133
+ return (
134
+ permission.permission === Permission.ProjectOwner &&
135
+ this.permissionCoversGrant(permission, PermissionScope.All, [])
136
+ );
137
+ }) &&
138
+ !callerBlocks.some((permission: UserPermission) => {
126
139
  return permission.permission === Permission.ProjectOwner;
127
140
  })
128
141
  ) {
@@ -142,7 +155,38 @@ export class Service extends DatabaseService<Model> {
142
155
  );
143
156
  });
144
157
 
145
- if (!canDelegate) {
158
+ const matchingBlocks: Array<UserPermission> = callerBlocks.filter(
159
+ (permission: UserPermission) => {
160
+ return permission.permission === data.permission;
161
+ },
162
+ );
163
+ const targetHasLabelScope: boolean =
164
+ targetLabelIds.length > 0 &&
165
+ data.scope !== PermissionScope.All &&
166
+ data.scope !== PermissionScope.Owned;
167
+ const isBlocked: boolean = matchingBlocks.some(
168
+ (permission: UserPermission) => {
169
+ /*
170
+ * An unrestricted/Owned grant may include resources blocked from the
171
+ * caller. Ownership also cannot be transferred between principals.
172
+ */
173
+ if (
174
+ !targetHasLabelScope ||
175
+ permission.scope === PermissionScope.All ||
176
+ permission.scope === PermissionScope.Owned ||
177
+ permission.labelIds.length === 0
178
+ ) {
179
+ return true;
180
+ }
181
+ return permission.labelIds.some((blockedLabelId: ObjectID) => {
182
+ return targetLabelIds.some((labelId: ObjectID) => {
183
+ return labelId.toString() === blockedLabelId.toString();
184
+ });
185
+ });
186
+ },
187
+ );
188
+
189
+ if (!canDelegate || isBlocked) {
146
190
  throw new NotAuthorizedException(
147
191
  `You cannot grant ${data.permission} because your own access does not include that permission at an equal or broader scope.`,
148
192
  );
@@ -349,13 +393,33 @@ export class Service extends DatabaseService<Model> {
349
393
  protected override async onBeforeUpdate(
350
394
  updateBy: UpdateBy<Model>,
351
395
  ): Promise<OnUpdate<Model>> {
352
- const teamPermissions: Array<Model> = await this.findBy({
396
+ updateBy.query = await ModelPermission.checkUpdateQueryPermissions(
397
+ Model,
398
+ updateBy.query,
399
+ updateBy.data,
400
+ updateBy.props,
401
+ );
402
+ const selectedPermissions: Array<Model> = await this.findAllBy({
353
403
  query: updateBy.query,
404
+ select: { _id: true },
405
+ skip: updateBy.skip,
406
+ limit: updateBy.limit,
407
+ props: { isRoot: true },
408
+ });
409
+ const selectedIds: Array<ObjectID> = selectedPermissions.map(
410
+ (row: Model) => {
411
+ return row.id!;
412
+ },
413
+ );
414
+ // Read complete labels independently of any relation filters in the query.
415
+ const teamPermissions: Array<Model> = await this.findAllBy({
416
+ query: { _id: QueryHelper.any(selectedIds) },
354
417
  select: {
355
418
  _id: true,
356
419
  teamId: true,
357
420
  projectId: true,
358
421
  permission: true,
422
+ isBlockPermission: true,
359
423
  labels: {
360
424
  _id: true,
361
425
  },
@@ -364,8 +428,6 @@ export class Service extends DatabaseService<Model> {
364
428
  isPermissionsEditable: true,
365
429
  },
366
430
  },
367
- skip: 0,
368
- limit: LIMIT_MAX,
369
431
  props: {
370
432
  isRoot: true,
371
433
  },
@@ -404,6 +466,16 @@ export class Service extends DatabaseService<Model> {
404
466
  ? (rawUpdateData.scope as PermissionScope)
405
467
  : permission.scope;
406
468
 
469
+ // Retargeting or narrowing a deny also removes its original restriction.
470
+ if (permission.isBlockPermission) {
471
+ this.assertCanGrantPermission({
472
+ permission: permission.permission!,
473
+ labelIds: this.getLabelIds(permission.labels),
474
+ scope: permission.scope,
475
+ props: updateBy.props,
476
+ });
477
+ }
478
+
407
479
  this.assertCanGrantPermission({
408
480
  permission: requestedPermission,
409
481
  labelIds: this.getLabelIds(requestedLabels),
@@ -413,24 +485,7 @@ export class Service extends DatabaseService<Model> {
413
485
  }
414
486
 
415
487
  if (updateBy.data.labels && updateBy.data.labels.length > 0) {
416
- const existingPermissions: Array<Model> = await this.findBy({
417
- query: updateBy.query,
418
- select: {
419
- _id: true,
420
- labels: true,
421
- isBlockPermission: true,
422
- projectId: true,
423
- teamId: true,
424
- permission: true,
425
- },
426
- limit: LIMIT_PER_PROJECT,
427
- skip: 0,
428
- props: {
429
- isRoot: true,
430
- },
431
- });
432
-
433
- for (const alreadySavedPermission of existingPermissions) {
488
+ for (const alreadySavedPermission of teamPermissions) {
434
489
  // check if the
435
490
 
436
491
  const isBlockPermission: boolean =
@@ -471,6 +526,8 @@ export class Service extends DatabaseService<Model> {
471
526
  }
472
527
  }
473
528
 
529
+ updateBy.query = { ...updateBy.query, _id: QueryHelper.any(selectedIds) };
530
+ updateBy.skip = 0;
474
531
  return { updateBy, carryForward: teamPermissions };
475
532
  }
476
533
 
@@ -523,31 +580,68 @@ export class Service extends DatabaseService<Model> {
523
580
  protected override async onBeforeDelete(
524
581
  deleteBy: DeleteBy<Model>,
525
582
  ): Promise<OnDelete<Model>> {
526
- const teamPermissions: Array<Model> = await this.findBy({
583
+ // Scope the root lookup using the same delete authorization as the write.
584
+ deleteBy.query = await ModelPermission.checkDeleteQueryPermission(
585
+ Model,
586
+ deleteBy.query,
587
+ deleteBy.props,
588
+ );
589
+ const selectedPermissions: Array<Model> = await this.findAllBy({
527
590
  query: deleteBy.query,
591
+ select: { _id: true },
592
+ skip: deleteBy.skip,
593
+ limit: deleteBy.limit,
594
+ props: { isRoot: true },
595
+ });
596
+ const selectedIds: Array<ObjectID> = selectedPermissions.map(
597
+ (row: Model) => {
598
+ return row.id!;
599
+ },
600
+ );
601
+ const teamPermissions: Array<Model> = await this.findAllBy({
602
+ query: { _id: QueryHelper.any(selectedIds) },
528
603
  select: {
529
604
  _id: true,
530
605
  teamId: true,
531
606
  projectId: true,
607
+ permission: true,
608
+ isBlockPermission: true,
609
+ labels: { _id: true },
610
+ scope: true,
532
611
  team: {
533
612
  isPermissionsEditable: true,
534
613
  },
535
614
  },
536
- skip: 0,
537
- limit: LIMIT_MAX,
538
615
  props: {
539
616
  isRoot: true,
540
617
  },
541
618
  });
542
619
 
543
620
  for (const permission of teamPermissions) {
621
+ this.assertProjectMatchesTenant(permission.projectId!, deleteBy.props);
544
622
  if (!permission.team?.isPermissionsEditable) {
545
623
  throw new BadDataException(
546
624
  "Permissions for this team is not deleteable. You can create a new team and add permissions to that team instead.",
547
625
  );
548
626
  }
627
+
628
+ if (permission.isBlockPermission) {
629
+ this.assertCanGrantPermission({
630
+ permission: permission.permission!,
631
+ labelIds: this.getLabelIds(permission.labels),
632
+ scope: permission.scope,
633
+ props: deleteBy.props,
634
+ });
635
+ }
549
636
  }
550
637
 
638
+ // Keep the write restricted to the page whose authority was checked.
639
+ deleteBy.query = {
640
+ ...deleteBy.query,
641
+ _id: QueryHelper.any(selectedIds),
642
+ };
643
+ deleteBy.skip = 0;
644
+
551
645
  let teamMembers: Array<TeamMember> = [];
552
646
 
553
647
  for (const permission of teamPermissions) {
@@ -9,6 +9,8 @@ import ObjectID from "../../Types/ObjectID";
9
9
  import {
10
10
  THREAT_INTEL_MINIMUM_CONFIDENCE_MAX,
11
11
  THREAT_INTEL_MINIMUM_CONFIDENCE_MIN,
12
+ THREAT_INTEL_POLL_INTERVAL_MAX_IN_MINUTES,
13
+ THREAT_INTEL_POLL_INTERVAL_MIN_IN_MINUTES,
12
14
  } from "../../Types/SecurityEvent/ThreatIntelConstants";
13
15
  import TaxiiClient from "../Utils/SecurityEvent/ThreatIntel/TaxiiClient";
14
16
 
@@ -40,11 +42,12 @@ export class Service extends DatabaseService<Model> {
40
42
  if (data.pollIntervalInMinutes !== undefined) {
41
43
  if (
42
44
  !Number.isInteger(data.pollIntervalInMinutes) ||
43
- data.pollIntervalInMinutes < 1 ||
44
- data.pollIntervalInMinutes > 1440
45
+ data.pollIntervalInMinutes <
46
+ THREAT_INTEL_POLL_INTERVAL_MIN_IN_MINUTES ||
47
+ data.pollIntervalInMinutes > THREAT_INTEL_POLL_INTERVAL_MAX_IN_MINUTES
45
48
  ) {
46
49
  throw new BadDataException(
47
- "Poll interval must be a whole number of minutes between 1 and 1440.",
50
+ `Poll interval must be a whole number of minutes between ${THREAT_INTEL_POLL_INTERVAL_MIN_IN_MINUTES} and ${THREAT_INTEL_POLL_INTERVAL_MAX_IN_MINUTES}.`,
48
51
  );
49
52
  }
50
53
  }
@@ -70,16 +70,18 @@ export default class BasePermission {
70
70
  props,
71
71
  );
72
72
 
73
- if (!props.isMultiTenantRequest) {
74
- // We will check for this permission in recursive function.
75
-
73
+ /*
74
+ * Only TenantPermission's per-project recursion returns an array of
75
+ * queries whose permissions have already been checked. The incoming
76
+ * query is copied into an ordinary object above, so a caller cannot
77
+ * supply this array. A multi-tenant request scoped to the current user
78
+ * (such as pending team invitations) still needs every check below.
79
+ */
80
+ if (!Array.isArray(query)) {
76
81
  // check model level permissions.
77
82
  TablePermission.checkTableLevelPermissions(modelType, props, type);
78
83
 
79
- /*
80
- * We will check for this permission in recursive function.
81
- * check query permissions.
82
- */
84
+ // check query permissions.
83
85
  QueryPermission.checkQueryPermission(modelType, query, props);
84
86
 
85
87
  query = await AccessControlPermission.addAccessControlIdsToQuery(