@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.
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +1 -1
- package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +1 -1
- package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +1 -1
- package/Server/API/AIBillingAPI.ts +1 -0
- package/Server/API/AIInsightAPI.ts +1 -4
- package/Server/API/AIInvestigationAPI.ts +1 -4
- package/Server/API/AIReadinessAPI.ts +4 -5
- package/Server/API/AlertAPI.ts +1 -0
- package/Server/API/AutoRemediationAPI.ts +1 -4
- package/Server/API/BaseAPI.ts +13 -0
- package/Server/API/BaseAnalyticsAPI.ts +80 -9
- package/Server/API/BillingAPI.ts +2 -0
- package/Server/API/BillingInvoiceAPI.ts +1 -0
- package/Server/API/BillingPaymentMethodAPI.ts +2 -0
- package/Server/API/CodeFixRunAPI.ts +1 -3
- package/Server/API/CommonAPI.ts +68 -4
- package/Server/API/DashboardAPI.ts +12 -12
- package/Server/API/GlobalConfigAPI.ts +17 -0
- package/Server/API/IncidentAPI.ts +2 -0
- package/Server/API/IncidentEpisodeAPI.ts +1 -0
- package/Server/API/NotificationAPI.ts +1 -0
- package/Server/API/OnCallCalendarAPI.ts +4 -5
- package/Server/API/OnCallDutyPolicyAPI.ts +7 -0
- package/Server/API/OnCallReadinessAPI.ts +4 -1
- package/Server/API/OnCallScheduleTimelineAPI.ts +731 -0
- package/Server/API/ProjectAPI.ts +1 -0
- package/Server/API/ScheduledMaintenanceAPI.ts +1 -0
- package/Server/API/StatusPageAPI.ts +161 -32
- package/Server/API/TeamMemberAPI.ts +3 -0
- package/Server/API/UserCallAPI.ts +2 -0
- package/Server/API/UserEmailAPI.ts +2 -0
- package/Server/API/UserIncomingCallNumberAPI.ts +2 -0
- package/Server/API/UserMicrosoftTeamsAPI.ts +1 -0
- package/Server/API/UserSlackAPI.ts +1 -0
- package/Server/API/UserSmsAPI.ts +2 -0
- package/Server/API/UserTotpAuthAPI.ts +1 -0
- package/Server/API/UserWebAuthnAPI.ts +2 -0
- package/Server/API/UserWebhookAPI.ts +1 -0
- package/Server/API/UserWhatsAppAPI.ts +2 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +13 -2
- package/Server/Middleware/UserAuthorization.ts +79 -5
- package/Server/Services/ApiKeyPermissionService.ts +101 -4
- package/Server/Services/DatabaseService.ts +245 -0
- package/Server/Services/DetectionRuleService.ts +5 -4
- package/Server/Services/OnCallDutyPolicyChildService.ts +261 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -2
- package/Server/Services/PayAsYouGoBillingService.ts +23 -28
- package/Server/Services/ProjectService.ts +18 -0
- package/Server/Services/RumSessionPinService.ts +274 -22
- package/Server/Services/TeamPermissionService.ts +120 -26
- package/Server/Services/ThreatIntelFeedService.ts +6 -3
- package/Server/Types/Database/Permissions/BasePermission.ts +9 -7
- package/Server/Types/Database/Permissions/Index.ts +75 -11
- package/Server/Types/Database/Permissions/TablePermission.ts +24 -28
- package/Server/Utils/AI/AIChatPrivacyFilter.ts +8 -0
- package/Server/Utils/AI/AIRunPrivacyFilter.ts +8 -0
- package/Server/Utils/MasterAdminPageAccess.ts +61 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +3 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +3 -1
- package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1 -1
- package/Server/Utils/Realtime.ts +163 -45
- package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +11 -28
- package/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.ts +170 -0
- package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +1 -1
- package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +6 -2
- package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.ts +10 -9
- package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +1059 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +376 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +757 -0
- package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +307 -0
- package/Tests/App/Dashboard/ArgumentsFormGroupByUnlistedAttributes.test.tsx +131 -0
- package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +1 -1
- package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +9 -1
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +24 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +162 -8
- package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +105 -6
- package/Tests/App/Dashboard/EntityFilterDropdownUnlistedSelection.test.tsx +434 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +276 -1
- package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +9 -1
- package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +58 -42
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +42 -5
- package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +34 -23
- package/Tests/App/Dashboard/ScheduleTimeline.test.tsx +1580 -0
- package/Tests/App/Dashboard/ScheduleTimelineAPI.test.ts +280 -0
- package/Tests/App/Dashboard/ScheduleTimelineModel.test.ts +673 -0
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +95 -68
- package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +86 -3
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +28 -3
- package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +761 -0
- package/Tests/App/Dashboard/SecurityEventsGuideContent.test.ts +1313 -0
- package/Tests/App/Dashboard/SecurityEventsHowItWorksCard.test.tsx +536 -0
- package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +222 -0
- package/Tests/App/Dashboard/SecurityEventsThreatIntelPage.test.tsx +199 -0
- package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +321 -0
- package/Tests/App/Dashboard/SloOverviewHero.test.tsx +171 -36
- package/Tests/App/Dashboard/SloViewSideMenu.test.tsx +215 -0
- package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +40 -3
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +12 -4
- package/Tests/App/PublicDashboard/PublicDashboardWidgetListAuth.test.tsx +623 -0
- package/Tests/Models/OnCallCalendarFeedModels.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +138 -5
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +187 -0
- package/Tests/Server/API/AIInvestigationAvailabilityAuthorization.test.ts +51 -3
- package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +55 -2
- package/Tests/Server/API/BaseAnalyticsAPIAggregateCache.test.ts +729 -0
- package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +93 -7
- package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +36 -3
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +1003 -24
- package/Tests/Server/API/DashboardPublicRateLimit.test.ts +6 -3
- package/Tests/Server/API/ExpiredSessionAIRoutes.test.ts +708 -0
- package/Tests/Server/API/ExpiredSessionCustomRoutes.test.ts +928 -0
- package/Tests/Server/API/ExpiredSessionMonitorTemplate.test.ts +319 -0
- package/Tests/Server/API/ExpiredSessionOnCallDutyPolicy.test.ts +336 -0
- package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +820 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +140 -0
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +115 -12
- package/Tests/Server/API/OnCallCalendarAPI.test.ts +375 -8
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +175 -17
- package/Tests/Server/API/OnCallScheduleTimelineAPI.test.ts +1513 -0
- package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +119 -7
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +111 -4
- package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +615 -0
- package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +89 -2
- package/Tests/Server/API/SessionReplayAPI.test.ts +121 -0
- package/Tests/Server/API/StatusPageMasterPasswordRateLimit.test.ts +4 -2
- package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +441 -0
- package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +664 -0
- package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +7 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +6 -0
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +65 -4
- package/Tests/Server/API/UserProjectsAPI.test.ts +63 -3
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +48 -2
- package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +11 -2
- package/Tests/Server/API/UserWebAuthnBackupCodeMinting.test.ts +46 -3
- package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +18 -2
- package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +24 -7
- package/Tests/Server/Middleware/ExpiredSessionUserMiddleware.test.ts +563 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +299 -19
- package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +453 -0
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +24 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +2 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +3 -3
- package/Tests/Server/Services/DatabaseServiceCreateSuppliedId.test.ts +147 -0
- package/Tests/Server/Services/DatabaseServiceLoginBeforeHooks.test.ts +1078 -0
- package/Tests/Server/Services/DatabaseServiceTenantRelationGuard.test.ts +259 -0
- package/Tests/Server/Services/DatabaseServiceWriteOperatorValues.test.ts +147 -0
- package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +115 -1
- package/Tests/Server/Services/OnCallChildCreateAuthorizationPostgres.test.ts +711 -0
- package/Tests/Server/Services/OnCallDutyPolicyChildService.test.ts +733 -0
- package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +190 -140
- package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +4 -9
- package/Tests/Server/Services/PermissionBlockDeletion.test.ts +780 -0
- package/Tests/Server/Services/PermissionBlockDeletionPostgres.test.ts +628 -0
- package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +77 -1
- package/Tests/Server/Services/RumSessionPinCreatePermission.test.ts +715 -0
- package/Tests/Server/Services/TeamMemberMultiTenantReadPostgres.test.ts +394 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +6 -0
- package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +131 -0
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +13 -2
- package/Tests/Server/Types/Database/Permissions/ModelPermissionAnonymousRefusal.test.ts +518 -0
- package/Tests/Server/Types/Database/Permissions/MultiTenantPermissions.test.ts +350 -0
- package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +282 -25
- package/Tests/Server/Types/Database/Permissions/TableLevelBlockPermission.test.ts +459 -0
- package/Tests/Server/Utils/AI/AIRunPrivacyFilter.test.ts +101 -9
- package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +88 -4
- package/Tests/Server/Utils/AI/Toolbox/ExceptionTools.test.ts +459 -0
- package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +794 -0
- package/Tests/Server/Utils/AI/Toolbox/RecentChangesTools.test.ts +574 -0
- package/Tests/Server/Utils/AI/Toolbox/SecurityEventTools.test.ts +596 -0
- package/Tests/Server/Utils/CaptchaRequestAndLogging.test.ts +395 -0
- package/Tests/Server/Utils/MasterAdminPageAccess.test.ts +251 -0
- package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +616 -0
- package/Tests/Server/Utils/Realtime.test.ts +502 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorSeverity.test.ts +216 -0
- package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +142 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.test.ts +140 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepairClickhouseIntegration.test.ts +542 -0
- package/Tests/Server/Utils/Telemetry/ChangeEventRow.test.ts +743 -0
- package/Tests/Server/Utils/Telemetry/RuntimeMetrics.test.ts +465 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.test.ts +202 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.test.ts +231 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/Alert.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/AlertEpisode.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/Incident.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.test.ts +247 -0
- package/Tests/Types/AI/AIInsightEvidence.test.ts +206 -0
- package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtilAnonymous.test.ts +144 -0
- package/Tests/Types/Call/CallProvider.test.ts +528 -0
- package/Tests/Types/Kubernetes/KubernetesCostIngest.test.ts +236 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleTimeline.test.ts +736 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleTimelineLayout.test.ts +996 -0
- package/Tests/Types/SecurityEvent/SigmaRule.test.ts +142 -0
- package/Tests/Types/Workflow/Components/JSON.test.ts +182 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +116 -1
- package/Tests/UI/Components/Dropdown/DropdownAsyncOptions.test.tsx +81 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +89 -1
- package/Tests/UI/Components/EventAttachmentList.test.tsx +174 -0
- package/Tests/UI/Components/Forms/BasicFormBurnRateTemplateDefaults.test.tsx +395 -0
- package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +286 -0
- package/Tests/UI/Components/Forms/FormSummary.test.tsx +128 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableQueryChange.test.tsx +365 -0
- package/Tests/UI/Components/OpenAuthenticatedUrl.test.ts +358 -0
- package/Tests/UI/Components/SessionAwareImage.test.tsx +496 -0
- package/Tests/UI/Components/TelemetryHistogramZeroBuckets.test.tsx +190 -0
- package/Tests/UI/Components/TooltipInteractive.test.tsx +97 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardInstallGuidance.test.tsx +1 -1
- package/Tests/UI/Monitor/EvaluationLogListTimestamps.test.tsx +367 -0
- package/Tests/UI/Utils/API/BaseAPIRefreshSession.test.ts +1087 -0
- package/Tests/UI/Utils/API/DashboardHost.ts +12 -0
- package/Tests/UI/Utils/API/FakeAxiosServer.ts +183 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/Cookie.test.ts +440 -0
- package/Tests/UI/Utils/ModelAPIRequestClient.test.ts +278 -0
- package/Tests/UI/Utils/Navigation.test.ts +33 -0
- package/Tests/UI/Utils/PricingPlan.test.ts +295 -0
- package/Tests/UI/Utils/Realtime.test.ts +759 -0
- package/Tests/UI/Utils/Telemetry/Telemetry.test.ts +500 -0
- package/Tests/Utils/APIInstanceDispatch.test.ts +311 -0
- package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizerSeverity.test.ts +565 -0
- package/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.ts +40 -0
- package/Types/Monitor/MonitorEvaluationSummary.ts +3 -0
- package/Types/OnCallDutyPolicy/ScheduleTimeline.ts +507 -0
- package/Types/OnCallDutyPolicy/ScheduleTimelineLayout.ts +589 -0
- package/Types/Realtime/EventName.ts +11 -0
- package/Types/SecurityEvent/DetectionFindingConstants.ts +14 -0
- package/Types/SecurityEvent/OcsfSeverity.ts +31 -26
- package/Types/SecurityEvent/SigmaRule.ts +51 -0
- package/Types/SecurityEvent/ThreatIntelConstants.ts +18 -0
- package/UI/Components/AttachmentList/EventAttachmentList.tsx +30 -2
- package/UI/Components/Dashboard/DashboardVariableControl.tsx +12 -2
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +12 -0
- package/UI/Components/EventItem/EventItem.tsx +12 -1
- package/UI/Components/Forms/BasicForm.tsx +151 -126
- package/UI/Components/Forms/CollapsibleFormSection.tsx +63 -0
- package/UI/Components/Forms/Fields/FormField.tsx +10 -4
- package/UI/Components/Forms/FormSummary.tsx +7 -0
- package/UI/Components/Forms/Types/Field.ts +10 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +2 -1
- package/UI/Components/Markdown.tsx/SessionAwareImage.tsx +122 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +34 -5
- package/UI/Components/ModelTable/TableView.tsx +1 -1
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +8 -1
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Utils/API/API.ts +173 -12
- package/UI/Utils/API/RequestOptions.ts +11 -0
- package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +31 -7
- package/UI/Utils/ModelAPI/ModelAPI.ts +30 -9
- package/UI/Utils/Navigation.ts +9 -0
- package/UI/Utils/OpenAuthenticatedUrl.ts +154 -0
- package/UI/Utils/Realtime.ts +176 -30
- package/Utils/API.ts +14 -5
- package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +157 -7
- package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +9 -17
- package/Utils/Slo/SloBurnRateTemplate.ts +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -1
- package/build/dist/Server/API/AIBillingAPI.js +1 -1
- package/build/dist/Server/API/AIBillingAPI.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +1 -4
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +1 -4
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AIReadinessAPI.js +1 -3
- package/build/dist/Server/API/AIReadinessAPI.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +1 -1
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +1 -4
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +12 -0
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +55 -10
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/BillingAPI.js +2 -2
- package/build/dist/Server/API/BillingAPI.js.map +1 -1
- package/build/dist/Server/API/BillingInvoiceAPI.js +1 -1
- package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
- package/build/dist/Server/API/BillingPaymentMethodAPI.js +2 -2
- package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
- package/build/dist/Server/API/CodeFixRunAPI.js +1 -3
- package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +50 -5
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +12 -12
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +12 -0
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +2 -2
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/NotificationAPI.js +1 -1
- package/build/dist/Server/API/NotificationAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallCalendarAPI.js +1 -4
- package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallDutyPolicyAPI.js +6 -0
- package/build/dist/Server/API/OnCallDutyPolicyAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js +4 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +494 -0
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -0
- package/build/dist/Server/API/ProjectAPI.js +1 -1
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +125 -33
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +3 -3
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +2 -2
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +2 -2
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +2 -2
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/UserSlackAPI.js +1 -1
- package/build/dist/Server/API/UserSlackAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +2 -2
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserTotpAuthAPI.js +1 -1
- package/build/dist/Server/API/UserTotpAuthAPI.js.map +1 -1
- package/build/dist/Server/API/UserWebAuthnAPI.js +2 -2
- package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
- package/build/dist/Server/API/UserWebhookAPI.js +1 -1
- package/build/dist/Server/API/UserWebhookAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +2 -2
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -2
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +64 -4
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +80 -4
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +171 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DetectionRuleService.js +4 -4
- package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyChildService.js +170 -0
- package/build/dist/Server/Services/OnCallDutyPolicyChildService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/PayAsYouGoBillingService.js +20 -27
- package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +17 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +180 -16
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +89 -27
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/ThreatIntelFeedService.js +5 -4
- package/build/dist/Server/Services/ThreatIntelFeedService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +9 -6
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/Index.js +60 -6
- package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +14 -13
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +7 -0
- package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js +7 -0
- package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/MasterAdminPageAccess.js +39 -0
- package/build/dist/Server/Utils/MasterAdminPageAccess.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +3 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +3 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Realtime.js +126 -37
- package/build/dist/Server/Utils/Realtime.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +7 -25
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js +127 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +3 -2
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js +4 -8
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js.map +1 -1
- package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js +31 -1
- package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js +321 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js +372 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js.map +1 -0
- package/build/dist/Types/Realtime/EventName.js +10 -0
- package/build/dist/Types/Realtime/EventName.js.map +1 -1
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +11 -0
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
- package/build/dist/Types/SecurityEvent/OcsfSeverity.js +30 -25
- package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -1
- package/build/dist/Types/SecurityEvent/SigmaRule.js +47 -0
- package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -1
- package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js +14 -0
- package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js.map +1 -1
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +9 -4
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -1
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +10 -2
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +11 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
- package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +70 -64
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +27 -0
- package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -0
- package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -7
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/FormSummary.js +7 -0
- package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +2 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js +84 -0
- package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +14 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +2 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Utils/API/API.js +143 -19
- package/build/dist/UI/Utils/API/API.js.map +1 -1
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +21 -7
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +26 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +8 -0
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/OpenAuthenticatedUrl.js +92 -0
- package/build/dist/UI/Utils/OpenAuthenticatedUrl.js.map +1 -0
- package/build/dist/UI/Utils/Realtime.js +120 -15
- package/build/dist/UI/Utils/Realtime.js.map +1 -1
- package/build/dist/Utils/API.js +13 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +123 -6
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
- package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +4 -18
- package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -1
- package/build/dist/Utils/Slo/SloBurnRateTemplate.js +2 -2
- package/package.json +1 -1
|
@@ -20,6 +20,7 @@ const router: ExpressRouter = Express.getRouter();
|
|
|
20
20
|
router.post(
|
|
21
21
|
"/ai/recharge",
|
|
22
22
|
UserMiddleware.getUserMiddleware,
|
|
23
|
+
UserMiddleware.requireUserAuthentication,
|
|
23
24
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
24
25
|
try {
|
|
25
26
|
if (!IsBillingEnabled) {
|
|
@@ -10,7 +10,6 @@ import Response from "../Utils/Response";
|
|
|
10
10
|
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
11
11
|
import ObjectID from "../../Types/ObjectID";
|
|
12
12
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
13
|
-
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
14
13
|
import { JSONArray, JSONObject } from "../../Types/JSON";
|
|
15
14
|
import AIInsightStatus from "../../Types/AI/AIInsightStatus";
|
|
16
15
|
import AIInsightHumanVerdict from "../../Types/AI/AIInsightHumanVerdict";
|
|
@@ -42,9 +41,7 @@ async function getLoggedInProps(
|
|
|
42
41
|
const props: DatabaseCommonInteractionProps =
|
|
43
42
|
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
throw new NotAuthorizedException("A logged-in user session is required.");
|
|
47
|
-
}
|
|
44
|
+
CommonAPI.assertAuthenticatedUser(props);
|
|
48
45
|
|
|
49
46
|
return props;
|
|
50
47
|
}
|
|
@@ -11,7 +11,6 @@ import Response from "../Utils/Response";
|
|
|
11
11
|
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
12
12
|
import ObjectID from "../../Types/ObjectID";
|
|
13
13
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
14
|
-
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
15
14
|
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
16
15
|
import Query from "../../Types/BaseDatabase/Query";
|
|
17
16
|
import { JSONArray, JSONObject } from "../../Types/JSON";
|
|
@@ -184,9 +183,7 @@ async function getLoggedInProps(
|
|
|
184
183
|
const props: DatabaseCommonInteractionProps =
|
|
185
184
|
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
186
185
|
|
|
187
|
-
|
|
188
|
-
throw new NotAuthorizedException("A logged-in user session is required.");
|
|
189
|
-
}
|
|
186
|
+
CommonAPI.assertAuthenticatedUser(props);
|
|
190
187
|
|
|
191
188
|
return props;
|
|
192
189
|
}
|
|
@@ -49,11 +49,10 @@ router.post(
|
|
|
49
49
|
* because it loads the exception with the caller's props first, and
|
|
50
50
|
* derives the project from that authorized row.
|
|
51
51
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
52
|
+
CommonAPI.assertAuthenticatedUser(
|
|
53
|
+
props,
|
|
54
|
+
"AI readiness requires a logged-in user session.",
|
|
55
|
+
);
|
|
57
56
|
|
|
58
57
|
if (!props.tenantId) {
|
|
59
58
|
throw new BadDataException("Project ID is required (tenantid header).");
|
package/Server/API/AlertAPI.ts
CHANGED
|
@@ -38,6 +38,7 @@ export default class AlertAPI extends BaseAPI<Alert, AlertServiceType> {
|
|
|
38
38
|
this.router.post(
|
|
39
39
|
`${new this.entityType().getCrudApiPath()?.toString()}/generate-note-from-ai/:alertId`,
|
|
40
40
|
UserMiddleware.getUserMiddleware,
|
|
41
|
+
UserMiddleware.requireUserAuthentication,
|
|
41
42
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
42
43
|
try {
|
|
43
44
|
await this.generateNoteFromAI(req, res);
|
|
@@ -11,7 +11,6 @@ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCom
|
|
|
11
11
|
import ObjectID from "../../Types/ObjectID";
|
|
12
12
|
import OneUptimeDate from "../../Types/Date";
|
|
13
13
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
14
|
-
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
15
14
|
import AutoRemediationSuggestionStatus from "../../Types/AutoRemediation/AutoRemediationSuggestionStatus";
|
|
16
15
|
import AutoRemediationSuggestionType from "../../Types/AutoRemediation/AutoRemediationSuggestionType";
|
|
17
16
|
import AutoRemediationVerificationStatus from "../../Types/AutoRemediation/AutoRemediationVerificationStatus";
|
|
@@ -65,9 +64,7 @@ async function getLoggedInProps(
|
|
|
65
64
|
const props: DatabaseCommonInteractionProps =
|
|
66
65
|
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
throw new NotAuthorizedException("A logged-in user session is required.");
|
|
70
|
-
}
|
|
67
|
+
CommonAPI.assertAuthenticatedUser(props);
|
|
71
68
|
|
|
72
69
|
return props;
|
|
73
70
|
}
|
package/Server/API/BaseAPI.ts
CHANGED
|
@@ -553,6 +553,19 @@ export default class BaseAPI<
|
|
|
553
553
|
this.entityType,
|
|
554
554
|
) as TBaseModel;
|
|
555
555
|
|
|
556
|
+
/*
|
|
557
|
+
* A create builds a brand-new row, so it must not carry the row's own
|
|
558
|
+
* primary key. getRepository().save() treats an entity that already has an
|
|
559
|
+
* id as an update of the existing row rather than an insert, so a stray
|
|
560
|
+
* `_id` (or the `id` spelling, which BaseModel.fromJSON has already folded
|
|
561
|
+
* into `_id`) would make a "create" modify an existing record instead.
|
|
562
|
+
* updateItem strips `_id` for a related reason; do it here too. Only the
|
|
563
|
+
* top-level primary key is removed - nested `_id`s inside relation
|
|
564
|
+
* objects/arrays reference existing related rows and are left untouched.
|
|
565
|
+
*/
|
|
566
|
+
delete (item as any)["_id"];
|
|
567
|
+
delete (item as any)["id"];
|
|
568
|
+
|
|
556
569
|
const miscDataProps: JSONObject = JSONFunctions.deserialize(
|
|
557
570
|
body["miscDataProps"] as JSONObject,
|
|
558
571
|
);
|
|
@@ -3,6 +3,9 @@ import UserMiddleware from "../Middleware/UserAuthorization";
|
|
|
3
3
|
import AnalyticsDatabaseService from "../Services/AnalyticsDatabaseService";
|
|
4
4
|
import CreateBy from "../Types/AnalyticsDatabase/CreateBy";
|
|
5
5
|
import GroupBy from "../Types/AnalyticsDatabase/GroupBy";
|
|
6
|
+
import ModelPermission, {
|
|
7
|
+
CheckReadPermissionType,
|
|
8
|
+
} from "../Types/AnalyticsDatabase/ModelPermission";
|
|
6
9
|
import Query from "../Types/AnalyticsDatabase/Query";
|
|
7
10
|
import Select from "../Types/AnalyticsDatabase/Select";
|
|
8
11
|
import Sort from "../Types/AnalyticsDatabase/Sort";
|
|
@@ -39,11 +42,9 @@ import logger from "../Utils/Logger";
|
|
|
39
42
|
* widgets loading on the same page) onto a single ClickHouse query
|
|
40
43
|
* while still looking real-time to humans.
|
|
41
44
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* with row-level access scoping should override `getAggregate` to
|
|
46
|
-
* skip the cache (or shape the key to include the access scope).
|
|
45
|
+
* A cache hit never reaches the service, which is where the read
|
|
46
|
+
* check lives, so getAggregateCacheKey runs that check itself and
|
|
47
|
+
* keys the slot on the permission-scoped query — see there.
|
|
47
48
|
*/
|
|
48
49
|
const ANALYTICS_AGGREGATE_CACHE_TTL_SECONDS: number = 8;
|
|
49
50
|
|
|
@@ -396,11 +397,11 @@ export default class BaseAnalyticsAPI<
|
|
|
396
397
|
* burst. On cache outage (Redis down, parse error, …) we fall
|
|
397
398
|
* through to a live query so behavior degrades to today's.
|
|
398
399
|
*/
|
|
399
|
-
const projectId: string | undefined = databaseProps.tenantId?.toString();
|
|
400
400
|
const cacheNamespace: string = `${this.getEntityName()}-aggregate`;
|
|
401
|
-
const cacheKey: string | null =
|
|
402
|
-
|
|
403
|
-
|
|
401
|
+
const cacheKey: string | null = await this.getAggregateCacheKey(
|
|
402
|
+
aggregateBy,
|
|
403
|
+
databaseProps,
|
|
404
|
+
);
|
|
404
405
|
|
|
405
406
|
if (cacheKey) {
|
|
406
407
|
try {
|
|
@@ -438,6 +439,76 @@ export default class BaseAnalyticsAPI<
|
|
|
438
439
|
return Response.sendJsonObjectResponse(req, res, responseBody);
|
|
439
440
|
}
|
|
440
441
|
|
|
442
|
+
/*
|
|
443
|
+
* A cached aggregate is answered BEFORE service.aggregateBy runs, and
|
|
444
|
+
* service.aggregateBy is where the read check lives. So a hit has to
|
|
445
|
+
* clear that same check first — otherwise anyone who can name a project
|
|
446
|
+
* in the `tenantid` header (getUserMiddleware accepts it even from an
|
|
447
|
+
* anonymous caller) reads whatever someone else aggregated there in the
|
|
448
|
+
* last few seconds.
|
|
449
|
+
*
|
|
450
|
+
* checkReadPermission runs here on a copy of the query, with the same
|
|
451
|
+
* select the service passes. It throws for an anonymous caller (401) and
|
|
452
|
+
* for one without read permission on the model or the queried columns
|
|
453
|
+
* (422), and it returns the query the live path would send to
|
|
454
|
+
* ClickHouse. That scoped query goes into the key because it carries
|
|
455
|
+
* everything that makes one caller's result differ from another's: the
|
|
456
|
+
* tenant, the Owned / label-restricted `IN (...)` filter on the owning
|
|
457
|
+
* resource, and for a multi-tenant request the caller's own list of
|
|
458
|
+
* projects.
|
|
459
|
+
*
|
|
460
|
+
* The caller's raw query stays in the key next to it. Scoping overwrites
|
|
461
|
+
* projectId, but a service can still plan from the raw query —
|
|
462
|
+
* MetricService picks point-type and rollup routing from the projectId
|
|
463
|
+
* the caller sent, before its own check rewrites it — so two requests
|
|
464
|
+
* that scope to the same query can still compute different results.
|
|
465
|
+
* Callers share a slot only when both their request and their access
|
|
466
|
+
* scope are identical.
|
|
467
|
+
*
|
|
468
|
+
* Returns null (skip the cache) without a tenant, and for a request the
|
|
469
|
+
* service's own validation is about to reject, so that request gets the
|
|
470
|
+
* service's error message rather than one from the check here.
|
|
471
|
+
*/
|
|
472
|
+
protected async getAggregateCacheKey(
|
|
473
|
+
aggregateBy: AggregateBy<AnalyticsDataModel>,
|
|
474
|
+
props: DatabaseCommonInteractionProps,
|
|
475
|
+
): Promise<string | null> {
|
|
476
|
+
if (!props.tenantId) {
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const aggregateColumnName: string | undefined =
|
|
481
|
+
aggregateBy.aggregateColumnName?.toString();
|
|
482
|
+
const timestampColumnName: string | undefined =
|
|
483
|
+
aggregateBy.aggregationTimestampColumnName?.toString();
|
|
484
|
+
const model: TAnalyticsDataModel = new this.entityType();
|
|
485
|
+
|
|
486
|
+
if (
|
|
487
|
+
!aggregateColumnName ||
|
|
488
|
+
!timestampColumnName ||
|
|
489
|
+
!model.getTableColumn(aggregateColumnName) ||
|
|
490
|
+
!model.getTableColumn(timestampColumnName)
|
|
491
|
+
) {
|
|
492
|
+
return null;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const scoped: CheckReadPermissionType<TAnalyticsDataModel> =
|
|
496
|
+
await ModelPermission.checkReadPermission(
|
|
497
|
+
this.entityType,
|
|
498
|
+
{ ...(aggregateBy.query || {}) } as Query<TAnalyticsDataModel>,
|
|
499
|
+
{
|
|
500
|
+
[aggregateColumnName]: true,
|
|
501
|
+
[timestampColumnName]: true,
|
|
502
|
+
} as Select<TAnalyticsDataModel>,
|
|
503
|
+
props,
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
return `${props.tenantId.toString()}:${this.buildAggregateCacheKey({
|
|
507
|
+
...aggregateBy,
|
|
508
|
+
scopedQuery: scoped.query,
|
|
509
|
+
} as AggregateBy<AnalyticsDataModel>)}`;
|
|
510
|
+
}
|
|
511
|
+
|
|
441
512
|
/*
|
|
442
513
|
* Stable serialization for the aggregate cache key. Date instances
|
|
443
514
|
* are normalized to ISO so two logically-equal time windows hit
|
package/Server/API/BillingAPI.ts
CHANGED
|
@@ -126,6 +126,7 @@ export default class BillingAPI {
|
|
|
126
126
|
this.router.get(
|
|
127
127
|
`/billing/pay-as-you-go-status`,
|
|
128
128
|
UserMiddleware.getUserMiddleware,
|
|
129
|
+
UserMiddleware.requireUserAuthentication,
|
|
129
130
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
130
131
|
try {
|
|
131
132
|
const projectId: ObjectID | null = this.getTenantId(req);
|
|
@@ -158,6 +159,7 @@ export default class BillingAPI {
|
|
|
158
159
|
this.router.get(
|
|
159
160
|
`/billing/customer-balance`,
|
|
160
161
|
UserMiddleware.getUserMiddleware,
|
|
162
|
+
UserMiddleware.requireUserAuthentication,
|
|
161
163
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
162
164
|
try {
|
|
163
165
|
if (!IsBillingEnabled) {
|
|
@@ -137,6 +137,7 @@ export default class UserAPI extends BaseAPI<
|
|
|
137
137
|
this.router.post(
|
|
138
138
|
`${new this.entityType().getCrudApiPath()?.toString()}/pay`,
|
|
139
139
|
UserMiddleware.getUserMiddleware,
|
|
140
|
+
UserMiddleware.requireUserAuthentication,
|
|
140
141
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
141
142
|
try {
|
|
142
143
|
if (!IsBillingEnabled) {
|
|
@@ -44,6 +44,7 @@ export default class UserAPI extends BaseAPI<
|
|
|
44
44
|
this.router.post(
|
|
45
45
|
`${new this.entityType().getCrudApiPath()?.toString()}/setup`,
|
|
46
46
|
UserMiddleware.getUserMiddleware,
|
|
47
|
+
UserMiddleware.requireUserAuthentication,
|
|
47
48
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
48
49
|
try {
|
|
49
50
|
if (!IsBillingEnabled) {
|
|
@@ -121,6 +122,7 @@ export default class UserAPI extends BaseAPI<
|
|
|
121
122
|
this.router.post(
|
|
122
123
|
`${new this.entityType().getCrudApiPath()?.toString()}/set-default`,
|
|
123
124
|
UserMiddleware.getUserMiddleware,
|
|
125
|
+
UserMiddleware.requireUserAuthentication,
|
|
124
126
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
125
127
|
try {
|
|
126
128
|
if (!IsBillingEnabled) {
|
|
@@ -358,9 +358,7 @@ export default class CodeFixRunAPI {
|
|
|
358
358
|
const props: DatabaseCommonInteractionProps =
|
|
359
359
|
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
360
360
|
|
|
361
|
-
|
|
362
|
-
throw new NotAuthorizedException("A logged-in user session is required.");
|
|
363
|
-
}
|
|
361
|
+
CommonAPI.assertAuthenticatedUser(props);
|
|
364
362
|
|
|
365
363
|
if (!props.tenantId) {
|
|
366
364
|
throw new BadDataException("Project ID is required (tenantid header).");
|
package/Server/API/CommonAPI.ts
CHANGED
|
@@ -31,14 +31,19 @@ export default class CommonAPI {
|
|
|
31
31
|
* missing header. Assert the scope up front so the caller gets the real
|
|
32
32
|
* cause.
|
|
33
33
|
*
|
|
34
|
-
* This deliberately checks the tenant
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* This deliberately checks the tenant, not the user: API-key callers are
|
|
35
|
+
* authenticated by ProjectMiddleware and carry tenant permissions without
|
|
36
|
+
* ever setting `userId`. It does refuse a caller with no credentials at all
|
|
37
|
+
* (401, see assertCredentialsPresent), because a tenant header on its own
|
|
38
|
+
* proves nothing and usually means an expired session. Use
|
|
39
|
+
* assertAuthenticatedProjectMember when an endpoint must additionally be a
|
|
40
|
+
* logged-in human member.
|
|
38
41
|
*/
|
|
39
42
|
public static assertTenantScoped(
|
|
40
43
|
databaseProps: DatabaseCommonInteractionProps,
|
|
41
44
|
): ObjectID {
|
|
45
|
+
CommonAPI.assertCredentialsPresent(databaseProps);
|
|
46
|
+
|
|
42
47
|
const projectId: ObjectID | undefined = databaseProps.tenantId;
|
|
43
48
|
|
|
44
49
|
if (!projectId) {
|
|
@@ -64,6 +69,8 @@ export default class CommonAPI {
|
|
|
64
69
|
public static assertAuthenticatedProjectPrincipal(
|
|
65
70
|
databaseProps: DatabaseCommonInteractionProps,
|
|
66
71
|
): ObjectID {
|
|
72
|
+
CommonAPI.assertCredentialsPresent(databaseProps);
|
|
73
|
+
|
|
67
74
|
const projectId: ObjectID | undefined = databaseProps.tenantId;
|
|
68
75
|
|
|
69
76
|
if (!projectId) {
|
|
@@ -85,6 +92,59 @@ export default class CommonAPI {
|
|
|
85
92
|
return projectId;
|
|
86
93
|
}
|
|
87
94
|
|
|
95
|
+
public static readonly AUTHENTICATION_REQUIRED_MESSAGE: string =
|
|
96
|
+
DatabaseCommonInteractionPropsUtil.AUTHENTICATION_REQUIRED_MESSAGE;
|
|
97
|
+
|
|
98
|
+
// See DatabaseCommonInteractionPropsUtil.isAnonymous.
|
|
99
|
+
public static isAnonymous(
|
|
100
|
+
databaseProps: DatabaseCommonInteractionProps,
|
|
101
|
+
): boolean {
|
|
102
|
+
return DatabaseCommonInteractionPropsUtil.isAnonymous(databaseProps);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
* "Who are you?" comes before "may you?".
|
|
107
|
+
*
|
|
108
|
+
* An anonymous caller has to get 401, never 422 or 400. The browser client
|
|
109
|
+
* (Common/UI/Utils/API/API.ts) refreshes the session and replays the request
|
|
110
|
+
* on a 401 and on nothing else, so answering an expired session with "you
|
|
111
|
+
* are not authorized to access this project's data" leaves a signed-in user
|
|
112
|
+
* looking at an authorization error until something else happens to trigger
|
|
113
|
+
* a 401. Every guard below calls this first, and so should any custom route
|
|
114
|
+
* that checks its caller by hand.
|
|
115
|
+
*
|
|
116
|
+
* Callers that ARE authenticated but lack access keep whatever refusal the
|
|
117
|
+
* route already gives them.
|
|
118
|
+
*/
|
|
119
|
+
public static assertCredentialsPresent(
|
|
120
|
+
databaseProps: DatabaseCommonInteractionProps,
|
|
121
|
+
): void {
|
|
122
|
+
DatabaseCommonInteractionPropsUtil.assertCredentialsPresent(databaseProps);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* For routes that act as a person (they record who approved, who asked,
|
|
127
|
+
* whose settings changed) and so cannot run on an API key.
|
|
128
|
+
*
|
|
129
|
+
* No credentials is 401, as above. A project API key IS authenticated, so it
|
|
130
|
+
* gets the route's own refusal (422) rather than a 401 its client would
|
|
131
|
+
* answer by trying to refresh a session it never had.
|
|
132
|
+
*/
|
|
133
|
+
public static assertAuthenticatedUser(
|
|
134
|
+
databaseProps: DatabaseCommonInteractionProps,
|
|
135
|
+
notAUserMessage?: string,
|
|
136
|
+
): ObjectID {
|
|
137
|
+
CommonAPI.assertCredentialsPresent(databaseProps);
|
|
138
|
+
|
|
139
|
+
if (!databaseProps.userId) {
|
|
140
|
+
throw new NotAuthorizedException(
|
|
141
|
+
notAUserMessage || "A logged-in user session is required.",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return databaseProps.userId;
|
|
146
|
+
}
|
|
147
|
+
|
|
88
148
|
/*
|
|
89
149
|
* getUserMiddleware lets unauthenticated requests through as "public" and
|
|
90
150
|
* takes the tenant id from a caller-supplied header — custom endpoints
|
|
@@ -95,6 +155,8 @@ export default class CommonAPI {
|
|
|
95
155
|
public static assertAuthenticatedProjectMember(
|
|
96
156
|
databaseProps: DatabaseCommonInteractionProps,
|
|
97
157
|
): ObjectID {
|
|
158
|
+
CommonAPI.assertCredentialsPresent(databaseProps);
|
|
159
|
+
|
|
98
160
|
const projectId: ObjectID | undefined = databaseProps.tenantId;
|
|
99
161
|
|
|
100
162
|
if (!projectId) {
|
|
@@ -179,6 +241,8 @@ export default class CommonAPI {
|
|
|
179
241
|
allowedPermissions: Array<Permission>;
|
|
180
242
|
errorMessage?: string | undefined;
|
|
181
243
|
}): void {
|
|
244
|
+
CommonAPI.assertCredentialsPresent(data.databaseProps);
|
|
245
|
+
|
|
182
246
|
if (data.databaseProps.isMasterAdmin) {
|
|
183
247
|
return;
|
|
184
248
|
}
|
|
@@ -415,7 +415,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
415
415
|
.getCrudApiPath()
|
|
416
416
|
?.toString()}/seo/:dashboardIdOrDomain`,
|
|
417
417
|
publicDashboardRateLimit,
|
|
418
|
-
UserMiddleware.
|
|
418
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
419
419
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
420
420
|
try {
|
|
421
421
|
const dashboardIdOrDomain: string = req.params[
|
|
@@ -596,7 +596,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
596
596
|
this.router.post(
|
|
597
597
|
overviewApiPath,
|
|
598
598
|
publicDashboardRateLimit,
|
|
599
|
-
UserMiddleware.
|
|
599
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
600
600
|
overviewHandler,
|
|
601
601
|
);
|
|
602
602
|
|
|
@@ -608,7 +608,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
608
608
|
this.router.get(
|
|
609
609
|
overviewApiPath,
|
|
610
610
|
publicDashboardRateLimit,
|
|
611
|
-
UserMiddleware.
|
|
611
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
612
612
|
overviewHandler,
|
|
613
613
|
);
|
|
614
614
|
|
|
@@ -616,7 +616,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
616
616
|
this.router.post(
|
|
617
617
|
`${new this.entityType().getCrudApiPath()?.toString()}/domain`,
|
|
618
618
|
publicDashboardRateLimit,
|
|
619
|
-
UserMiddleware.
|
|
619
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
620
620
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
621
621
|
try {
|
|
622
622
|
if (!req.body["domain"]) {
|
|
@@ -662,7 +662,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
662
662
|
.getCrudApiPath()
|
|
663
663
|
?.toString()}/metadata/:dashboardId`,
|
|
664
664
|
publicDashboardRateLimit,
|
|
665
|
-
UserMiddleware.
|
|
665
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
666
666
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
667
667
|
try {
|
|
668
668
|
const dashboardId: ObjectID = new ObjectID(
|
|
@@ -725,7 +725,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
725
725
|
.getCrudApiPath()
|
|
726
726
|
?.toString()}/view-config/:dashboardId`,
|
|
727
727
|
publicDashboardRateLimit,
|
|
728
|
-
UserMiddleware.
|
|
728
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
729
729
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
730
730
|
try {
|
|
731
731
|
const dashboardId: ObjectID = new ObjectID(
|
|
@@ -827,7 +827,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
827
827
|
.getCrudApiPath()
|
|
828
828
|
?.toString()}/attribute-values/:dashboardId`,
|
|
829
829
|
publicDashboardRateLimit,
|
|
830
|
-
UserMiddleware.
|
|
830
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
831
831
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
832
832
|
try {
|
|
833
833
|
const dashboardId: ObjectID = new ObjectID(
|
|
@@ -941,7 +941,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
941
941
|
.getCrudApiPath()
|
|
942
942
|
?.toString()}/metric-types/:dashboardId`,
|
|
943
943
|
publicDashboardRateLimit,
|
|
944
|
-
UserMiddleware.
|
|
944
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
945
945
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
946
946
|
try {
|
|
947
947
|
const dashboardId: ObjectID = new ObjectID(
|
|
@@ -1051,7 +1051,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
1051
1051
|
.getCrudApiPath()
|
|
1052
1052
|
?.toString()}/metrics-aggregate/:dashboardId`,
|
|
1053
1053
|
publicDashboardRateLimit,
|
|
1054
|
-
UserMiddleware.
|
|
1054
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
1055
1055
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
1056
1056
|
try {
|
|
1057
1057
|
const dashboardId: ObjectID = new ObjectID(
|
|
@@ -1328,7 +1328,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
1328
1328
|
.getCrudApiPath()
|
|
1329
1329
|
?.toString()}/resource-list/:dashboardId/:resourceType`,
|
|
1330
1330
|
publicDashboardRateLimit,
|
|
1331
|
-
UserMiddleware.
|
|
1331
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
1332
1332
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
1333
1333
|
try {
|
|
1334
1334
|
const resourceType: string = req.params["resourceType"] as string;
|
|
@@ -1368,7 +1368,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
1368
1368
|
.getCrudApiPath()
|
|
1369
1369
|
?.toString()}/slo-history-aggregate/:dashboardId`,
|
|
1370
1370
|
publicDashboardRateLimit,
|
|
1371
|
-
UserMiddleware.
|
|
1371
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
1372
1372
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
1373
1373
|
try {
|
|
1374
1374
|
const dashboardId: ObjectID = new ObjectID(
|
|
@@ -1506,7 +1506,7 @@ export default class DashboardAPI extends BaseAPI<
|
|
|
1506
1506
|
.getCrudApiPath()
|
|
1507
1507
|
?.toString()}/master-password/:dashboardId`,
|
|
1508
1508
|
masterPasswordRateLimit,
|
|
1509
|
-
UserMiddleware.
|
|
1509
|
+
UserMiddleware.getPublicRouteUserMiddleware,
|
|
1510
1510
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
1511
1511
|
try {
|
|
1512
1512
|
if (!req.params["dashboardId"]) {
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import EnterpriseLicenseInstanceSummary from "../../Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary";
|
|
27
27
|
import VersionUtil from "../../Utils/VersionUtil";
|
|
28
28
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
29
|
+
import NotAuthenticatedException from "../../Types/Exception/NotAuthenticatedException";
|
|
29
30
|
import MasterAdminAuthorization from "../Middleware/MasterAdminAuthorization";
|
|
30
31
|
import EnterpriseLicenseSeatUtil from "../Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil";
|
|
31
32
|
import { SeatUsage } from "../../Utils/EnterpriseLicense/EnterpriseLicenseSeats";
|
|
@@ -70,6 +71,22 @@ export default class GlobalConfigAPI extends BaseAPI<
|
|
|
70
71
|
UserMiddleware.getUserMiddleware,
|
|
71
72
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
72
73
|
try {
|
|
74
|
+
/*
|
|
75
|
+
* This route also serves the login page, so a caller with no session
|
|
76
|
+
* normally gets the reduced anonymous payload below. Unless it says
|
|
77
|
+
* it is signed in (the dashboards do): then no session means an
|
|
78
|
+
* expired one, and the anonymous payload would read as "unlicensed".
|
|
79
|
+
* Answer 401 so the client refreshes and asks again.
|
|
80
|
+
*/
|
|
81
|
+
if (
|
|
82
|
+
req.query["signedIn"] === "true" &&
|
|
83
|
+
UserMiddleware.isAnonymousRequest(req as OneUptimeRequest)
|
|
84
|
+
) {
|
|
85
|
+
throw new NotAuthenticatedException(
|
|
86
|
+
UserMiddleware.AUTHENTICATION_REQUIRED_MESSAGE,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
73
90
|
const config: GlobalConfig | null =
|
|
74
91
|
await GlobalConfigService.findOneById({
|
|
75
92
|
id: ObjectID.getZeroObjectID(),
|
|
@@ -58,6 +58,7 @@ export default class IncidentAPI extends BaseAPI<
|
|
|
58
58
|
.getCrudApiPath()
|
|
59
59
|
?.toString()}/generate-postmortem-from-ai/:incidentId`,
|
|
60
60
|
UserMiddleware.getUserMiddleware,
|
|
61
|
+
UserMiddleware.requireUserAuthentication,
|
|
61
62
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
62
63
|
try {
|
|
63
64
|
await this.generatePostmortemFromAI(req, res);
|
|
@@ -73,6 +74,7 @@ export default class IncidentAPI extends BaseAPI<
|
|
|
73
74
|
.getCrudApiPath()
|
|
74
75
|
?.toString()}/generate-note-from-ai/:incidentId`,
|
|
75
76
|
UserMiddleware.getUserMiddleware,
|
|
77
|
+
UserMiddleware.requireUserAuthentication,
|
|
76
78
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
77
79
|
try {
|
|
78
80
|
await this.generateNoteFromAI(req, res);
|
|
@@ -43,6 +43,7 @@ export default class IncidentEpisodeAPI extends BaseAPI<
|
|
|
43
43
|
.getCrudApiPath()
|
|
44
44
|
?.toString()}/generate-postmortem-from-ai/:episodeId`,
|
|
45
45
|
UserMiddleware.getUserMiddleware,
|
|
46
|
+
UserMiddleware.requireUserAuthentication,
|
|
46
47
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
47
48
|
try {
|
|
48
49
|
await this.generatePostmortemFromAI(req, res);
|
|
@@ -19,6 +19,7 @@ const router: ExpressRouter = Express.getRouter();
|
|
|
19
19
|
router.post(
|
|
20
20
|
"/notification/recharge",
|
|
21
21
|
UserMiddleware.getUserMiddleware,
|
|
22
|
+
UserMiddleware.requireUserAuthentication,
|
|
22
23
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
23
24
|
try {
|
|
24
25
|
let amount: number | PositiveNumber = JSONFunctions.deserializeValue(
|
|
@@ -1500,11 +1500,10 @@ async function findPersonalFeed(data: {
|
|
|
1500
1500
|
}
|
|
1501
1501
|
|
|
1502
1502
|
function requireUserId(props: DatabaseCommonInteractionProps): ObjectID {
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
return props.userId;
|
|
1503
|
+
return CommonAPI.assertAuthenticatedUser(
|
|
1504
|
+
props,
|
|
1505
|
+
"A logged-in user is required.",
|
|
1506
|
+
);
|
|
1508
1507
|
}
|
|
1509
1508
|
|
|
1510
1509
|
router.get(
|
|
@@ -35,6 +35,13 @@ export default class OnCallDutyPolicyAPI extends BaseAPI<
|
|
|
35
35
|
const databaseProps: DatabaseCommonInteractionProps =
|
|
36
36
|
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
37
37
|
|
|
38
|
+
/*
|
|
39
|
+
* The header polls this on every dashboard page, so it is usually
|
|
40
|
+
* the first request to notice an expired session. It must answer
|
|
41
|
+
* 401 so the client refreshes, not "Invalid userId.".
|
|
42
|
+
*/
|
|
43
|
+
CommonAPI.assertCredentialsPresent(databaseProps);
|
|
44
|
+
|
|
38
45
|
const projectId: ObjectID = databaseProps.tenantId as ObjectID;
|
|
39
46
|
|
|
40
47
|
const userId: ObjectID = databaseProps.userId as ObjectID;
|
|
@@ -68,7 +68,10 @@ import TeamMember from "../../Models/DatabaseModels/TeamMember";
|
|
|
68
68
|
* header before any authorisation runs. So each route asserts, itself:
|
|
69
69
|
*
|
|
70
70
|
* 1. the caller is a logged-in member of the project it named
|
|
71
|
-
* (CommonAPI.assertAuthenticatedProjectMember)
|
|
71
|
+
* (CommonAPI.assertAuthenticatedProjectMember). A caller with no session
|
|
72
|
+
* at all gets 401, not the 422 a non-member gets: in practice that caller
|
|
73
|
+
* is an admin whose access-token cookie expired while the page sat open,
|
|
74
|
+
* and only a 401 makes the dashboard refresh the session and resend, and
|
|
72
75
|
* 2. the resource in the path - the policy, or the user - actually belongs to
|
|
73
76
|
* that same project, because otherwise a member of project A reads project
|
|
74
77
|
* B's data simply by sending their own `tenantid` header alongside a
|