@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
|
@@ -7,9 +7,40 @@ import ReadPermission, { CheckReadPermissionType } from "./ReadPermission";
|
|
|
7
7
|
import UpdatePermission from "./UpdatePermission";
|
|
8
8
|
import BaseModel from "../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
9
9
|
import DatabaseCommonInteractionProps from "../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
10
|
+
import DatabaseCommonInteractionPropsUtil from "../../../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
|
|
11
|
+
import NotAuthenticatedException from "../../../../Types/Exception/NotAuthenticatedException";
|
|
12
|
+
import NotAuthorizedException from "../../../../Types/Exception/NotAuthorizedException";
|
|
10
13
|
import CaptureSpan from "../../../Utils/Telemetry/CaptureSpan";
|
|
11
14
|
|
|
12
15
|
export default class ModelPermission {
|
|
16
|
+
/*
|
|
17
|
+
* A refusal of a caller with no credentials at all is a 401.
|
|
18
|
+
*
|
|
19
|
+
* The login check near the top of every permission check passes an
|
|
20
|
+
* anonymous caller straight through on models that are readable (or
|
|
21
|
+
* creatable) by Public - Probe, AIAgent, LlmProvider and friends - and the
|
|
22
|
+
* column, select and query checks that follow then refuse it with 422
|
|
23
|
+
* NotAuthorizedException. For the dashboard that caller is a signed-in user
|
|
24
|
+
* whose access-token cookie expired, and only a 401 makes the browser client
|
|
25
|
+
* refresh the session and replay the request. Callers with credentials keep
|
|
26
|
+
* the 422 they always got; the message is kept either way.
|
|
27
|
+
*/
|
|
28
|
+
private static toAnonymousRefusal(
|
|
29
|
+
error: unknown,
|
|
30
|
+
props: DatabaseCommonInteractionProps,
|
|
31
|
+
): unknown {
|
|
32
|
+
if (
|
|
33
|
+
error instanceof NotAuthorizedException &&
|
|
34
|
+
!props.isRoot &&
|
|
35
|
+
!props.isMasterAdmin &&
|
|
36
|
+
DatabaseCommonInteractionPropsUtil.isAnonymous(props)
|
|
37
|
+
) {
|
|
38
|
+
return new NotAuthenticatedException(error.message);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return error;
|
|
42
|
+
}
|
|
43
|
+
|
|
13
44
|
@CaptureSpan()
|
|
14
45
|
public static async checkDeletePermissionByModel<
|
|
15
46
|
TBaseModel extends BaseModel,
|
|
@@ -18,7 +49,11 @@ export default class ModelPermission {
|
|
|
18
49
|
fetchModelWithAccessControlIds: () => Promise<TBaseModel | null>;
|
|
19
50
|
props: DatabaseCommonInteractionProps;
|
|
20
51
|
}): Promise<void> {
|
|
21
|
-
|
|
52
|
+
try {
|
|
53
|
+
return await DeletePermission.checkDeletePermissionByModel(data);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw ModelPermission.toAnonymousRefusal(error, data.props);
|
|
56
|
+
}
|
|
22
57
|
}
|
|
23
58
|
|
|
24
59
|
@CaptureSpan()
|
|
@@ -29,7 +64,11 @@ export default class ModelPermission {
|
|
|
29
64
|
fetchModelWithAccessControlIds: () => Promise<TBaseModel | null>;
|
|
30
65
|
props: DatabaseCommonInteractionProps;
|
|
31
66
|
}): Promise<void> {
|
|
32
|
-
|
|
67
|
+
try {
|
|
68
|
+
return await UpdatePermission.checkUpdatePermissionByModel(data);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw ModelPermission.toAnonymousRefusal(error, data.props);
|
|
71
|
+
}
|
|
33
72
|
}
|
|
34
73
|
|
|
35
74
|
@CaptureSpan()
|
|
@@ -38,7 +77,15 @@ export default class ModelPermission {
|
|
|
38
77
|
query: Query<TBaseModel>,
|
|
39
78
|
props: DatabaseCommonInteractionProps,
|
|
40
79
|
): Promise<Query<TBaseModel>> {
|
|
41
|
-
|
|
80
|
+
try {
|
|
81
|
+
return await DeletePermission.checkDeletePermission(
|
|
82
|
+
modelType,
|
|
83
|
+
query,
|
|
84
|
+
props,
|
|
85
|
+
);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
throw ModelPermission.toAnonymousRefusal(error, props);
|
|
88
|
+
}
|
|
42
89
|
}
|
|
43
90
|
|
|
44
91
|
@CaptureSpan()
|
|
@@ -48,12 +95,16 @@ export default class ModelPermission {
|
|
|
48
95
|
data: QueryDeepPartialEntity<TBaseModel>,
|
|
49
96
|
props: DatabaseCommonInteractionProps,
|
|
50
97
|
): Promise<Query<TBaseModel>> {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
98
|
+
try {
|
|
99
|
+
return await UpdatePermission.checkUpdatePermissions(
|
|
100
|
+
modelType,
|
|
101
|
+
query,
|
|
102
|
+
data,
|
|
103
|
+
props,
|
|
104
|
+
);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw ModelPermission.toAnonymousRefusal(error, props);
|
|
107
|
+
}
|
|
57
108
|
}
|
|
58
109
|
|
|
59
110
|
@CaptureSpan()
|
|
@@ -62,7 +113,11 @@ export default class ModelPermission {
|
|
|
62
113
|
data: TBaseModel,
|
|
63
114
|
props: DatabaseCommonInteractionProps,
|
|
64
115
|
): void {
|
|
65
|
-
|
|
116
|
+
try {
|
|
117
|
+
return CreatePermission.checkCreatePermissions(modelType, data, props);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
throw ModelPermission.toAnonymousRefusal(error, props);
|
|
120
|
+
}
|
|
66
121
|
}
|
|
67
122
|
|
|
68
123
|
@CaptureSpan()
|
|
@@ -72,6 +127,15 @@ export default class ModelPermission {
|
|
|
72
127
|
select: Select<TBaseModel> | null,
|
|
73
128
|
props: DatabaseCommonInteractionProps,
|
|
74
129
|
): Promise<CheckReadPermissionType<TBaseModel>> {
|
|
75
|
-
|
|
130
|
+
try {
|
|
131
|
+
return await ReadPermission.checkReadPermission(
|
|
132
|
+
modelType,
|
|
133
|
+
query,
|
|
134
|
+
select,
|
|
135
|
+
props,
|
|
136
|
+
);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
throw ModelPermission.toAnonymousRefusal(error, props);
|
|
139
|
+
}
|
|
76
140
|
}
|
|
77
141
|
}
|
|
@@ -168,35 +168,31 @@ export default class TablePermission {
|
|
|
168
168
|
const modelPermissions: Array<Permission> =
|
|
169
169
|
TablePermission.getTablePermission(modelType, type);
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
(userPermission
|
|
183
|
-
return userPermission.permission === permission;
|
|
184
|
-
},
|
|
185
|
-
) as UserPermission;
|
|
186
|
-
|
|
187
|
-
if (
|
|
188
|
-
userPermission &&
|
|
171
|
+
/*
|
|
172
|
+
* The user gets one block row per TeamPermission across all of their
|
|
173
|
+
* teams, unmerged and unordered, so the same permission can be blocked
|
|
174
|
+
* both for some labels and for the whole table. A row without labels
|
|
175
|
+
* blocks the whole table and must win whichever row comes first:
|
|
176
|
+
* ReadPermission and AccessControlPermission only enforce the labelled
|
|
177
|
+
* rows, so an unlabelled row missed here is enforced nowhere.
|
|
178
|
+
*/
|
|
179
|
+
const tableWideBlock: UserPermission | undefined = userPermissions.find(
|
|
180
|
+
(userPermission: UserPermission) => {
|
|
181
|
+
return (
|
|
182
|
+
modelPermissions.includes(userPermission.permission) &&
|
|
189
183
|
(!userPermission.labelIds || userPermission.labelIds.length === 0)
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
)
|
|
198
|
-
}
|
|
199
|
-
|
|
184
|
+
);
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
if (tableWideBlock) {
|
|
189
|
+
throw new NotAuthorizedException(
|
|
190
|
+
`You are not authorized to ${type} ${
|
|
191
|
+
new modelType().singularName
|
|
192
|
+
} because ${
|
|
193
|
+
tableWideBlock.permission
|
|
194
|
+
} is in your team's permission block list.`,
|
|
195
|
+
);
|
|
200
196
|
}
|
|
201
197
|
}
|
|
202
198
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
2
|
+
import DatabaseCommonInteractionPropsUtil from "../../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
|
|
2
3
|
import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
|
|
3
4
|
|
|
4
5
|
/*
|
|
@@ -16,6 +17,13 @@ export function pinQueryToRequestingUser<TQuery>(
|
|
|
16
17
|
return query;
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
/*
|
|
21
|
+
* No credentials at all is an expired session, not someone else's data:
|
|
22
|
+
* 401 so the client refreshes. The countBy overrides reach this before the
|
|
23
|
+
* permission layer's own login check does.
|
|
24
|
+
*/
|
|
25
|
+
DatabaseCommonInteractionPropsUtil.assertCredentialsPresent(props);
|
|
26
|
+
|
|
19
27
|
if (!props.userId) {
|
|
20
28
|
throw new NotAuthorizedException(
|
|
21
29
|
"AI conversations are personal and can only be accessed by the user who created them.",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
2
|
+
import DatabaseCommonInteractionPropsUtil from "../../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
|
|
2
3
|
import { FindWhereProperty } from "../../../Types/BaseDatabase/Query";
|
|
3
4
|
import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
|
|
4
5
|
import AIRunType from "../../../Types/AI/AIRunType";
|
|
@@ -57,6 +58,13 @@ export function getAIRunPrivacyRaw(
|
|
|
57
58
|
* /ai-run nor /code-fix-run grants today. That is a separate product
|
|
58
59
|
* decision and must not ride in as a side effect of this filter.
|
|
59
60
|
*/
|
|
61
|
+
/*
|
|
62
|
+
* No credentials at all is an expired session, not someone else's data:
|
|
63
|
+
* 401 so the client refreshes. The countBy overrides reach this before the
|
|
64
|
+
* permission layer's own login check does.
|
|
65
|
+
*/
|
|
66
|
+
DatabaseCommonInteractionPropsUtil.assertCredentialsPresent(props);
|
|
67
|
+
|
|
60
68
|
if (!props.userId) {
|
|
61
69
|
throw new NotAuthorizedException(
|
|
62
70
|
"AI runs are personal and can only be accessed by the user who created them.",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import { ExpressRequest, ExpressResponse } from "./Express";
|
|
3
|
+
import JSONWebToken from "./JsonWebToken";
|
|
4
|
+
import logger from "./Logger";
|
|
5
|
+
import Response from "./Response";
|
|
6
|
+
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
7
|
+
import { JSONObject } from "../../Types/JSON";
|
|
8
|
+
import JSONWebTokenData from "../../Types/JsonWebTokenData";
|
|
9
|
+
|
|
10
|
+
export const NOT_A_MASTER_ADMIN_MESSAGE: string =
|
|
11
|
+
"Unauthorized: Only master admins can access the admin dashboard.";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* Gate for the Admin Dashboard's index page (the HTML shell, not its APIs).
|
|
15
|
+
*
|
|
16
|
+
* It refuses only a caller it can positively identify as NOT a master admin.
|
|
17
|
+
* A missing access token, or one that no longer decodes, is served the shell:
|
|
18
|
+
* the access-token cookie expires with the JWT inside it, so an admin who
|
|
19
|
+
* reloads a tab left open past the token lifetime arrives here with no token
|
|
20
|
+
* at all, and answering that with a 422 JSON page meant the app never loaded
|
|
21
|
+
* and so never got to refresh the session. The shell holds nothing the public
|
|
22
|
+
* static bundle does not; once it loads, the SPA sends a signed-out visitor to
|
|
23
|
+
* the login page, and every admin API it calls refreshes an expired session
|
|
24
|
+
* (or answers 401) on its own.
|
|
25
|
+
*/
|
|
26
|
+
export const ensureMasterAdminPageAccess: (data: {
|
|
27
|
+
req: ExpressRequest;
|
|
28
|
+
res: ExpressResponse;
|
|
29
|
+
service: string;
|
|
30
|
+
}) => Promise<JSONObject> = async (data: {
|
|
31
|
+
req: ExpressRequest;
|
|
32
|
+
res: ExpressResponse;
|
|
33
|
+
service: string;
|
|
34
|
+
}): Promise<JSONObject> => {
|
|
35
|
+
const accessToken: string | undefined =
|
|
36
|
+
UserMiddleware.getAccessTokenFromExpressRequest(data.req);
|
|
37
|
+
|
|
38
|
+
if (!accessToken) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let authData: JSONWebTokenData;
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
authData = JSONWebToken.decode(accessToken);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Expired or unreadable: let the app load and refresh it.
|
|
48
|
+
logger.debug(error, { service: data.service });
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!authData.isMasterAdmin) {
|
|
53
|
+
Response.sendErrorResponse(
|
|
54
|
+
data.req,
|
|
55
|
+
data.res,
|
|
56
|
+
new NotAuthorizedException(NOT_A_MASTER_ADMIN_MESSAGE),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {};
|
|
61
|
+
};
|
|
@@ -86,6 +86,7 @@ export default class MonitorAlert {
|
|
|
86
86
|
select: {
|
|
87
87
|
_id: true,
|
|
88
88
|
title: true,
|
|
89
|
+
createdAt: true,
|
|
89
90
|
createdCriteriaId: true,
|
|
90
91
|
projectId: true,
|
|
91
92
|
alertNumber: true,
|
|
@@ -514,6 +515,7 @@ export default class MonitorAlert {
|
|
|
514
515
|
relatedAlertNumber: alreadyOpenAlert?.alertNumber,
|
|
515
516
|
relatedAlertNumberWithPrefix:
|
|
516
517
|
alreadyOpenAlert?.alertNumberWithPrefix,
|
|
518
|
+
relatedAlertCreatedAt: alreadyOpenAlert?.createdAt,
|
|
517
519
|
at: OneUptimeDate.getCurrentDate(),
|
|
518
520
|
});
|
|
519
521
|
continue;
|
|
@@ -794,7 +796,7 @@ export default class MonitorAlert {
|
|
|
794
796
|
relatedAlertId: createdAlert.id?.toString(),
|
|
795
797
|
relatedAlertNumber: createdAlert.alertNumber,
|
|
796
798
|
relatedAlertNumberWithPrefix: createdAlert.alertNumberWithPrefix,
|
|
797
|
-
at: OneUptimeDate.getCurrentDate(),
|
|
799
|
+
at: createdAlert.createdAt || OneUptimeDate.getCurrentDate(),
|
|
798
800
|
});
|
|
799
801
|
} catch (err) {
|
|
800
802
|
/*
|
|
@@ -99,6 +99,7 @@ export default class MonitorIncident {
|
|
|
99
99
|
select: {
|
|
100
100
|
_id: true,
|
|
101
101
|
title: true,
|
|
102
|
+
createdAt: true,
|
|
102
103
|
createdCriteriaId: true,
|
|
103
104
|
createdIncidentTemplateId: true,
|
|
104
105
|
projectId: true,
|
|
@@ -579,6 +580,7 @@ export default class MonitorIncident {
|
|
|
579
580
|
relatedIncidentNumber: alreadyOpenIncident?.incidentNumber,
|
|
580
581
|
relatedIncidentNumberWithPrefix:
|
|
581
582
|
alreadyOpenIncident?.incidentNumberWithPrefix,
|
|
583
|
+
relatedIncidentCreatedAt: alreadyOpenIncident?.createdAt,
|
|
582
584
|
at: OneUptimeDate.getCurrentDate(),
|
|
583
585
|
});
|
|
584
586
|
continue;
|
|
@@ -913,7 +915,7 @@ export default class MonitorIncident {
|
|
|
913
915
|
relatedIncidentNumber: createdIncident.incidentNumber,
|
|
914
916
|
relatedIncidentNumberWithPrefix:
|
|
915
917
|
createdIncident.incidentNumberWithPrefix,
|
|
916
|
-
at: OneUptimeDate.getCurrentDate(),
|
|
918
|
+
at: createdIncident.createdAt || OneUptimeDate.getCurrentDate(),
|
|
917
919
|
});
|
|
918
920
|
} catch (err) {
|
|
919
921
|
/*
|
|
@@ -176,7 +176,7 @@ export interface EmptyOutcomeOptions {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/* The schedule facts every render needs, read once per request. */
|
|
179
|
-
interface ScheduleInfo {
|
|
179
|
+
export interface ScheduleInfo {
|
|
180
180
|
id: ObjectID;
|
|
181
181
|
name: string;
|
|
182
182
|
timezone?: string | undefined;
|
package/Server/Utils/Realtime.ts
CHANGED
|
@@ -24,6 +24,19 @@ import Dictionary from "../../Types/Dictionary";
|
|
|
24
24
|
import UserPermissionUtil from "./UserPermission/UserPermission";
|
|
25
25
|
import CaptureSpan from "./Telemetry/CaptureSpan";
|
|
26
26
|
|
|
27
|
+
// What became of one ListenToModelEvent request.
|
|
28
|
+
export enum ListenToModelEventOutcome {
|
|
29
|
+
Joined = "Joined",
|
|
30
|
+
// No access token, or one that no longer decodes. The client was told.
|
|
31
|
+
AuthenticationRequired = "AuthenticationRequired",
|
|
32
|
+
// A valid session without access to this tenant or model.
|
|
33
|
+
NotAuthorized = "NotAuthorized",
|
|
34
|
+
// The request itself was malformed.
|
|
35
|
+
InvalidRequest = "InvalidRequest",
|
|
36
|
+
// Something failed while authorizing (for example the permission cache).
|
|
37
|
+
Failed = "Failed",
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
export default abstract class Realtime {
|
|
28
41
|
private static socketServer: SocketServer | null = null;
|
|
29
42
|
|
|
@@ -45,37 +58,19 @@ export default abstract class Realtime {
|
|
|
45
58
|
this.socketServer!.on("connection", (socket: Socket) => {
|
|
46
59
|
logger.debug("New socket connection established");
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
logger.error("modelType is not a string", socketLogAttributes);
|
|
62
|
-
throw new BadDataException("modelType is not a string");
|
|
63
|
-
}
|
|
64
|
-
if (typeof data["modelName"] !== "string") {
|
|
65
|
-
logger.error("modelName is not a string", socketLogAttributes);
|
|
66
|
-
throw new BadDataException("modelName is not a string");
|
|
67
|
-
}
|
|
68
|
-
if (typeof data["tenantId"] !== "string") {
|
|
69
|
-
logger.error("tenantId is not a string", socketLogAttributes);
|
|
70
|
-
throw new BadDataException("tenantId is not a string");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
await Realtime.listenToModelEvent(socket, {
|
|
74
|
-
eventType: data["eventType"] as ModelEventType,
|
|
75
|
-
modelType: data["modelType"] as DatabaseType,
|
|
76
|
-
modelName: data["modelName"] as string,
|
|
77
|
-
tenantId: data["tenantId"] as string,
|
|
78
|
-
});
|
|
61
|
+
/*
|
|
62
|
+
* socket.io calls a listener and throws away what it returns. An async
|
|
63
|
+
* listener that throws is therefore an unhandled rejection: nothing
|
|
64
|
+
* goes back to the client, and the subscription it asked for simply
|
|
65
|
+
* never happens. handleListenToModelEventRequest settles every outcome
|
|
66
|
+
* itself; the catch is a backstop, not the error handling.
|
|
67
|
+
*/
|
|
68
|
+
socket.on(EventName.ListenToModalEvent, (data: JSONObject): void => {
|
|
69
|
+
Realtime.handleListenToModelEventRequest(socket, data).catch(
|
|
70
|
+
(err: unknown) => {
|
|
71
|
+
logger.error(err);
|
|
72
|
+
},
|
|
73
|
+
);
|
|
79
74
|
});
|
|
80
75
|
});
|
|
81
76
|
}
|
|
@@ -83,11 +78,108 @@ export default abstract class Realtime {
|
|
|
83
78
|
return this.socketServer;
|
|
84
79
|
}
|
|
85
80
|
|
|
81
|
+
/*
|
|
82
|
+
* One ListenToModelEvent from a client, start to finish. Never throws: a
|
|
83
|
+
* malformed request, a missing or expired access token, a refused
|
|
84
|
+
* subscription and a failing permission lookup each end here as an outcome,
|
|
85
|
+
* so none of them can become an unhandled rejection in the socket listener.
|
|
86
|
+
*/
|
|
87
|
+
@CaptureSpan()
|
|
88
|
+
public static async handleListenToModelEventRequest(
|
|
89
|
+
socket: Socket,
|
|
90
|
+
data: JSONObject,
|
|
91
|
+
): Promise<ListenToModelEventOutcome> {
|
|
92
|
+
logger.debug("Received ListenToModalEvent with data:");
|
|
93
|
+
logger.debug(data);
|
|
94
|
+
|
|
95
|
+
let request: ListenToModelEventJSON;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
request = Realtime.parseListenToModelEventRequest(data);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
logger.error(err);
|
|
101
|
+
return ListenToModelEventOutcome.InvalidRequest;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
return await Realtime.listenToModelEvent(socket, request);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
// A permission-cache (Redis) failure, say. The room is not joined.
|
|
108
|
+
const failureLogAttributes: LogAttributes = {
|
|
109
|
+
projectId: request.tenantId,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
logger.error(err, failureLogAttributes);
|
|
113
|
+
return ListenToModelEventOutcome.Failed;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private static parseListenToModelEventRequest(
|
|
118
|
+
data: JSONObject,
|
|
119
|
+
): ListenToModelEventJSON {
|
|
120
|
+
if (!data || typeof data !== "object") {
|
|
121
|
+
logger.error("ListenToModelEvent data is not an object");
|
|
122
|
+
throw new BadDataException("ListenToModelEvent data is not an object");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const socketLogAttributes: LogAttributes = {
|
|
126
|
+
projectId: data["tenantId"]?.toString(),
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (typeof data["eventType"] !== "string") {
|
|
130
|
+
logger.error("eventType is not a string", socketLogAttributes);
|
|
131
|
+
throw new BadDataException("eventType is not a string");
|
|
132
|
+
}
|
|
133
|
+
if (typeof data["modelType"] !== "string") {
|
|
134
|
+
logger.error("modelType is not a string", socketLogAttributes);
|
|
135
|
+
throw new BadDataException("modelType is not a string");
|
|
136
|
+
}
|
|
137
|
+
if (typeof data["modelName"] !== "string") {
|
|
138
|
+
logger.error("modelName is not a string", socketLogAttributes);
|
|
139
|
+
throw new BadDataException("modelName is not a string");
|
|
140
|
+
}
|
|
141
|
+
if (typeof data["tenantId"] !== "string") {
|
|
142
|
+
logger.error("tenantId is not a string", socketLogAttributes);
|
|
143
|
+
throw new BadDataException("tenantId is not a string");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
eventType: data["eventType"] as ModelEventType,
|
|
148
|
+
modelType: data["modelType"] as DatabaseType,
|
|
149
|
+
modelName: data["modelName"] as string,
|
|
150
|
+
tenantId: data["tenantId"] as string,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* The socket has no usable user session: tell the client, which refreshes
|
|
156
|
+
* its session and reconnects so the new handshake carries the new cookie.
|
|
157
|
+
* Dropping the request silently is what used to happen, and it left every
|
|
158
|
+
* subscription made after the access token expired dead (no live counters
|
|
159
|
+
* after switching project, no live logs) with nothing in the browser to
|
|
160
|
+
* show why.
|
|
161
|
+
*/
|
|
162
|
+
private static rejectForMissingAuthentication(
|
|
163
|
+
socket: Socket,
|
|
164
|
+
data: ListenToModelEventJSON,
|
|
165
|
+
reason: string,
|
|
166
|
+
listenLogAttributes: LogAttributes,
|
|
167
|
+
): ListenToModelEventOutcome {
|
|
168
|
+
logger.debug(
|
|
169
|
+
`${reason}, aborting joining room and asking the client to re-authenticate`,
|
|
170
|
+
listenLogAttributes,
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
socket.emit(EventName.AuthenticationRequired, data);
|
|
174
|
+
|
|
175
|
+
return ListenToModelEventOutcome.AuthenticationRequired;
|
|
176
|
+
}
|
|
177
|
+
|
|
86
178
|
@CaptureSpan()
|
|
87
179
|
public static async listenToModelEvent(
|
|
88
180
|
socket: Socket,
|
|
89
181
|
data: ListenToModelEventJSON,
|
|
90
|
-
): Promise<
|
|
182
|
+
): Promise<ListenToModelEventOutcome> {
|
|
91
183
|
const listenLogAttributes: LogAttributes = {
|
|
92
184
|
projectId: data.tenantId?.toString(),
|
|
93
185
|
};
|
|
@@ -116,31 +208,51 @@ export default abstract class Realtime {
|
|
|
116
208
|
this.getAccessTokenFromSocket(socket);
|
|
117
209
|
|
|
118
210
|
if (!userAccessToken) {
|
|
119
|
-
|
|
120
|
-
|
|
211
|
+
return this.rejectForMissingAuthentication(
|
|
212
|
+
socket,
|
|
213
|
+
data,
|
|
214
|
+
"User access token not found in socket",
|
|
121
215
|
listenLogAttributes,
|
|
122
216
|
);
|
|
123
|
-
return;
|
|
124
217
|
}
|
|
125
218
|
|
|
126
219
|
logger.debug("Decoding user access token", listenLogAttributes);
|
|
127
|
-
|
|
128
|
-
|
|
220
|
+
|
|
221
|
+
/*
|
|
222
|
+
* The token is the one the browser sent with the handshake, and it is not
|
|
223
|
+
* re-read for the life of the connection. Once it expires every decode
|
|
224
|
+
* throws, which is the normal state of a dashboard tab left open past the
|
|
225
|
+
* access token's lifetime, not an error in the request.
|
|
226
|
+
*/
|
|
227
|
+
let userAuthorizationData: JSONWebTokenData;
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
userAuthorizationData = JSONWebToken.decode(userAccessToken);
|
|
231
|
+
} catch {
|
|
232
|
+
return this.rejectForMissingAuthentication(
|
|
233
|
+
socket,
|
|
234
|
+
data,
|
|
235
|
+
"User access token in socket is invalid or expired",
|
|
236
|
+
listenLogAttributes,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
129
239
|
|
|
130
240
|
if (!userAuthorizationData) {
|
|
131
|
-
|
|
132
|
-
|
|
241
|
+
return this.rejectForMissingAuthentication(
|
|
242
|
+
socket,
|
|
243
|
+
data,
|
|
244
|
+
"User authorization data not found in socket",
|
|
133
245
|
listenLogAttributes,
|
|
134
246
|
);
|
|
135
|
-
return;
|
|
136
247
|
}
|
|
137
248
|
|
|
138
249
|
if (!userAuthorizationData.userId) {
|
|
139
|
-
|
|
140
|
-
|
|
250
|
+
return this.rejectForMissingAuthentication(
|
|
251
|
+
socket,
|
|
252
|
+
data,
|
|
253
|
+
"User ID not found in socket",
|
|
141
254
|
listenLogAttributes,
|
|
142
255
|
);
|
|
143
|
-
return;
|
|
144
256
|
}
|
|
145
257
|
|
|
146
258
|
logger.debug("Checking user access permissions", listenLogAttributes);
|
|
@@ -179,7 +291,7 @@ export default abstract class Realtime {
|
|
|
179
291
|
"User does not have access to this tenant, aborting joining room",
|
|
180
292
|
listenLogAttributes,
|
|
181
293
|
);
|
|
182
|
-
return;
|
|
294
|
+
return ListenToModelEventOutcome.NotAuthorized;
|
|
183
295
|
}
|
|
184
296
|
|
|
185
297
|
logger.debug(
|
|
@@ -214,12 +326,16 @@ export default abstract class Realtime {
|
|
|
214
326
|
}
|
|
215
327
|
}
|
|
216
328
|
|
|
329
|
+
/*
|
|
330
|
+
* Authenticated but not allowed. The room is not joined and, as before,
|
|
331
|
+
* nothing is sent back: a fresh session would not change the answer.
|
|
332
|
+
*/
|
|
217
333
|
if (!hasAccess) {
|
|
218
334
|
logger.debug(
|
|
219
335
|
"User does not have access to this tenant, aborting joining room",
|
|
220
336
|
listenLogAttributes,
|
|
221
337
|
);
|
|
222
|
-
return;
|
|
338
|
+
return ListenToModelEventOutcome.NotAuthorized;
|
|
223
339
|
}
|
|
224
340
|
|
|
225
341
|
if (data.modelId) {
|
|
@@ -244,6 +360,8 @@ export default abstract class Realtime {
|
|
|
244
360
|
// join the room.
|
|
245
361
|
await socket.join(roomId);
|
|
246
362
|
}
|
|
363
|
+
|
|
364
|
+
return ListenToModelEventOutcome.Joined;
|
|
247
365
|
}
|
|
248
366
|
|
|
249
367
|
@CaptureSpan()
|