@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
|
@@ -18,12 +18,16 @@ import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/Database
|
|
|
18
18
|
import Dictionary from "../../../Types/Dictionary";
|
|
19
19
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
20
20
|
import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
|
|
21
|
+
import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
|
|
22
|
+
import Exception from "../../../Types/Exception/Exception";
|
|
23
|
+
import ExceptionCode from "../../../Types/Exception/ExceptionCode";
|
|
21
24
|
import { JSONObject } from "../../../Types/JSON";
|
|
22
25
|
import ObjectID from "../../../Types/ObjectID";
|
|
23
26
|
import Permission, {
|
|
24
27
|
UserPermission,
|
|
25
28
|
UserTenantAccessPermission,
|
|
26
29
|
} from "../../../Types/Permission";
|
|
30
|
+
import UserType from "../../../Types/UserType";
|
|
27
31
|
import { beforeEach, describe, expect, test } from "@jest/globals";
|
|
28
32
|
|
|
29
33
|
/*
|
|
@@ -38,7 +42,12 @@ import { beforeEach, describe, expect, test } from "@jest/globals";
|
|
|
38
42
|
* admits anonymous callers as UserType.Public and takes the project from a
|
|
39
43
|
* caller-supplied `tenantid` header. So the handler is the only gate, and it
|
|
40
44
|
* has to refuse BEFORE any mail-sending work starts - a route that refuses
|
|
41
|
-
* after the send has not refused anything.
|
|
45
|
+
* after the send has not refused anything. An anonymous caller is refused
|
|
46
|
+
* with a 401, not the 422 below: this is the route from the customer report,
|
|
47
|
+
* where an admin's tab sat open past the access-token lifetime, the cookie
|
|
48
|
+
* stopped being sent, and "Send setup reminder" answered "You are not
|
|
49
|
+
* authorized to access this project's data." The dashboard refreshes the
|
|
50
|
+
* session and resends only on a 401.
|
|
42
51
|
*
|
|
43
52
|
* WITH WHAT STANDING. Membership is the bar for the READS on this router and
|
|
44
53
|
* was, wrongly, the bar for this write too. Every read-only Viewer holds an
|
|
@@ -97,11 +106,28 @@ const REMINDER_ROUTE: string = "/on-call-readiness/send-setup-reminder";
|
|
|
97
106
|
|
|
98
107
|
/*
|
|
99
108
|
* The message every authorisation refusal on this router carries. Asserted on
|
|
100
|
-
* the literal so "you are in the wrong project" cannot drift apart from "you
|
|
101
|
-
* not
|
|
109
|
+
* the literal so "you are in the wrong project" cannot drift apart from "you may
|
|
110
|
+
* not do this here" - an authenticated caller must not be able to tell them
|
|
111
|
+
* apart.
|
|
112
|
+
*
|
|
113
|
+
* "You are not logged in" is deliberately a different answer (401, below). It
|
|
114
|
+
* is decided before the tenant, the body or anything else project-specific is
|
|
115
|
+
* looked at, so it is the same for every project and discloses nothing.
|
|
102
116
|
*/
|
|
103
117
|
const REFUSAL: string = "You are not authorized to access this project's data.";
|
|
104
118
|
|
|
119
|
+
function expectAuthenticationRequired(thrown: unknown): void {
|
|
120
|
+
expect(thrown).toBeInstanceOf(NotAuthenticatedException);
|
|
121
|
+
expect(thrown).not.toBeInstanceOf(NotAuthorizedException);
|
|
122
|
+
expect((thrown as Exception).code).toBe(
|
|
123
|
+
ExceptionCode.NotAuthenticatedException,
|
|
124
|
+
);
|
|
125
|
+
expect((thrown as Exception).code).toBe(401);
|
|
126
|
+
expect((thrown as Exception).message).toBe(
|
|
127
|
+
CommonAPI.AUTHENTICATION_REQUIRED_MESSAGE,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
105
131
|
interface RegisteredRoute {
|
|
106
132
|
method: string;
|
|
107
133
|
uri: string;
|
|
@@ -365,7 +391,12 @@ describe("OnCallReadinessAPI POST /send-setup-reminder - registration", () => {
|
|
|
365
391
|
});
|
|
366
392
|
|
|
367
393
|
describe("OnCallReadinessAPI POST /send-setup-reminder - who may call it", () => {
|
|
368
|
-
|
|
394
|
+
/*
|
|
395
|
+
* Was the 422 REFUSAL. An anonymous caller with a tenant header is, in
|
|
396
|
+
* practice, an admin whose session expired while the page sat open; the 401
|
|
397
|
+
* is what makes the dashboard refresh and resend the same POST.
|
|
398
|
+
*/
|
|
399
|
+
test("an anonymous caller is refused with 401 and nothing is sent", async () => {
|
|
369
400
|
propsSpy.mockResolvedValue({
|
|
370
401
|
tenantId: projectId,
|
|
371
402
|
userTenantAccessPermission: {},
|
|
@@ -375,10 +406,52 @@ describe("OnCallReadinessAPI POST /send-setup-reminder - who may call it", () =>
|
|
|
375
406
|
userIds: [userA.toString()],
|
|
376
407
|
});
|
|
377
408
|
|
|
409
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
410
|
+
expect(result.nextCallCount).toBe(1);
|
|
411
|
+
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
412
|
+
expect(Response.sendJsonObjectResponse).not.toHaveBeenCalled();
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test("an explicitly Public caller is refused with 401 and nothing is sent", async () => {
|
|
416
|
+
propsSpy.mockResolvedValue({
|
|
417
|
+
tenantId: projectId,
|
|
418
|
+
userType: UserType.Public,
|
|
419
|
+
} as never);
|
|
420
|
+
|
|
421
|
+
const result: RouteCallResult = await callRoute({
|
|
422
|
+
userIds: [userA.toString()],
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
426
|
+
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test("a project API key is authenticated, so it gets the member refusal (422), not a 401", async () => {
|
|
430
|
+
/*
|
|
431
|
+
* The route sends mail as a person acting for the project and only admits
|
|
432
|
+
* logged-in members. A key that even holds ProjectOwner is refused - but
|
|
433
|
+
* as an authorisation failure, because a 401 would send an API client off
|
|
434
|
+
* to refresh a session it never had.
|
|
435
|
+
*/
|
|
436
|
+
propsSpy.mockResolvedValue({
|
|
437
|
+
...buildProps({
|
|
438
|
+
projectId: projectId,
|
|
439
|
+
userId: callerUserId,
|
|
440
|
+
permissions: [Permission.ProjectOwner],
|
|
441
|
+
}),
|
|
442
|
+
userId: undefined,
|
|
443
|
+
userType: UserType.API,
|
|
444
|
+
} as never);
|
|
445
|
+
|
|
446
|
+
const result: RouteCallResult = await callRoute({
|
|
447
|
+
userIds: [userA.toString()],
|
|
448
|
+
});
|
|
449
|
+
|
|
378
450
|
expect(result.thrownToNext).toBeInstanceOf(NotAuthorizedException);
|
|
379
|
-
expect((result.thrownToNext as
|
|
380
|
-
|
|
451
|
+
expect((result.thrownToNext as Exception).code).toBe(
|
|
452
|
+
ExceptionCode.NotAuthorizedException,
|
|
381
453
|
);
|
|
454
|
+
expect((result.thrownToNext as Exception).message).toBe(REFUSAL);
|
|
382
455
|
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
383
456
|
});
|
|
384
457
|
|
|
@@ -401,7 +474,11 @@ describe("OnCallReadinessAPI POST /send-setup-reminder - who may call it", () =>
|
|
|
401
474
|
});
|
|
402
475
|
|
|
403
476
|
test("a request with no tenant header is refused before the body is even parsed", async () => {
|
|
404
|
-
|
|
477
|
+
/*
|
|
478
|
+
* A logged-in caller who sent no tenant header. (With no session as well,
|
|
479
|
+
* the refusal is the 401 - next test.)
|
|
480
|
+
*/
|
|
481
|
+
propsSpy.mockResolvedValue({ userId: callerUserId } as never);
|
|
405
482
|
|
|
406
483
|
const result: RouteCallResult = await callRoute({
|
|
407
484
|
userIds: ["obviously-not-a-uuid"],
|
|
@@ -418,6 +495,33 @@ describe("OnCallReadinessAPI POST /send-setup-reminder - who may call it", () =>
|
|
|
418
495
|
);
|
|
419
496
|
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
420
497
|
});
|
|
498
|
+
|
|
499
|
+
test("a request with no session and no tenant header is a 401, decided before the tenant or the body", async () => {
|
|
500
|
+
/*
|
|
501
|
+
* This used to be the 400 above. "Who are you?" now comes first, so a
|
|
502
|
+
* signed-out caller cannot learn anything about the tenant rules or the
|
|
503
|
+
* body format, and the dashboard gets the 401 it refreshes on.
|
|
504
|
+
*/
|
|
505
|
+
propsSpy.mockResolvedValue({} as never);
|
|
506
|
+
|
|
507
|
+
const result: RouteCallResult = await callRoute({
|
|
508
|
+
userIds: ["obviously-not-a-uuid"],
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
512
|
+
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
test("an anonymous caller with a malformed body is still the 401, not the body's 400", async () => {
|
|
516
|
+
propsSpy.mockResolvedValue({ tenantId: projectId } as never);
|
|
517
|
+
|
|
518
|
+
const result: RouteCallResult = await callRoute({
|
|
519
|
+
userIds: "not-even-an-array",
|
|
520
|
+
} as unknown as JSONObject);
|
|
521
|
+
|
|
522
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
523
|
+
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
524
|
+
});
|
|
421
525
|
});
|
|
422
526
|
|
|
423
527
|
/*
|
|
@@ -448,6 +552,14 @@ describe("OnCallReadinessAPI POST /send-setup-reminder - membership is not enoug
|
|
|
448
552
|
expect((result.thrownToNext as NotAuthorizedException).message).toBe(
|
|
449
553
|
REFUSAL,
|
|
450
554
|
);
|
|
555
|
+
/*
|
|
556
|
+
* 422, not 401: this member IS logged in. Answering with a 401 would make
|
|
557
|
+
* the dashboard refresh a perfectly good session and replay the POST, only
|
|
558
|
+
* to be refused again.
|
|
559
|
+
*/
|
|
560
|
+
expect((result.thrownToNext as Exception).code).toBe(
|
|
561
|
+
ExceptionCode.NotAuthorizedException,
|
|
562
|
+
);
|
|
451
563
|
expect(sendRemindersSpy).not.toHaveBeenCalled();
|
|
452
564
|
});
|
|
453
565
|
|
|
@@ -16,11 +16,15 @@ import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/Database
|
|
|
16
16
|
import Dictionary from "../../../Types/Dictionary";
|
|
17
17
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
18
18
|
import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
|
|
19
|
+
import NotAuthenticatedException from "../../../Types/Exception/NotAuthenticatedException";
|
|
20
|
+
import Exception from "../../../Types/Exception/Exception";
|
|
21
|
+
import ExceptionCode from "../../../Types/Exception/ExceptionCode";
|
|
19
22
|
import ObjectID from "../../../Types/ObjectID";
|
|
20
23
|
import Permission, {
|
|
21
24
|
UserPermission,
|
|
22
25
|
UserTenantAccessPermission,
|
|
23
26
|
} from "../../../Types/Permission";
|
|
27
|
+
import UserType from "../../../Types/UserType";
|
|
24
28
|
import {
|
|
25
29
|
afterEach,
|
|
26
30
|
beforeAll,
|
|
@@ -46,6 +50,13 @@ import {
|
|
|
46
50
|
* path belongs to that same project. Checking only the first would let a
|
|
47
51
|
* member of project A send their own tenant header while targeting project
|
|
48
52
|
* B's resource id.
|
|
53
|
+
*
|
|
54
|
+
* A caller with no credentials at all is refused with NotAuthenticatedException
|
|
55
|
+
* (401) before either check, and before the tenant header is even looked at.
|
|
56
|
+
* That is almost always a signed-in user whose access-token cookie expired, and
|
|
57
|
+
* the dashboard only refreshes the session and resends on a 401. Authenticated
|
|
58
|
+
* callers keep the refusals they always had (400 no tenant, 422 not a member /
|
|
59
|
+
* wrong project).
|
|
49
60
|
*/
|
|
50
61
|
|
|
51
62
|
jest.mock("../../../Server/Utils/Express", () => {
|
|
@@ -109,6 +120,17 @@ type RouteCallResult = {
|
|
|
109
120
|
nextCallCount: number;
|
|
110
121
|
};
|
|
111
122
|
|
|
123
|
+
function expectAuthenticationRequired(thrown: unknown): void {
|
|
124
|
+
expect(thrown).toBeInstanceOf(NotAuthenticatedException);
|
|
125
|
+
expect((thrown as Exception).code).toBe(
|
|
126
|
+
ExceptionCode.NotAuthenticatedException,
|
|
127
|
+
);
|
|
128
|
+
expect((thrown as Exception).code).toBe(401);
|
|
129
|
+
expect((thrown as Exception).message).toBe(
|
|
130
|
+
CommonAPI.AUTHENTICATION_REQUIRED_MESSAGE,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
112
134
|
async function callGetRoute(data: {
|
|
113
135
|
uri: string;
|
|
114
136
|
params: Dictionary<string>;
|
|
@@ -246,7 +268,8 @@ describe("Project-scoped custom routes require an authenticated member of the re
|
|
|
246
268
|
expect(readArgs.props["isRoot"]).toBe(true);
|
|
247
269
|
});
|
|
248
270
|
|
|
249
|
-
|
|
271
|
+
// Was BadDataException (400) before the credential check.
|
|
272
|
+
test("rejects an unauthenticated caller with NotAuthenticatedException (401) and never reads the monitor", async () => {
|
|
250
273
|
mockProps({});
|
|
251
274
|
|
|
252
275
|
const result: RouteCallResult = await callGetRoute({
|
|
@@ -254,12 +277,29 @@ describe("Project-scoped custom routes require an authenticated member of the re
|
|
|
254
277
|
params: { monitorId: monitorId.toString() },
|
|
255
278
|
});
|
|
256
279
|
|
|
280
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
281
|
+
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
282
|
+
expect(refreshSpy).not.toHaveBeenCalled();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test("rejects a logged-in caller with no tenant header with BadDataException (400) and never reads the monitor", async () => {
|
|
286
|
+
mockProps({ userId: callerUserId, userType: UserType.User });
|
|
287
|
+
|
|
288
|
+
const result: RouteCallResult = await callGetRoute({
|
|
289
|
+
uri: MONITOR_REFRESH_ROUTE,
|
|
290
|
+
params: { monitorId: monitorId.toString() },
|
|
291
|
+
});
|
|
292
|
+
|
|
257
293
|
expect(result.thrownToNext).toBeInstanceOf(BadDataException);
|
|
294
|
+
expect((result.thrownToNext as Exception).code).toBe(
|
|
295
|
+
ExceptionCode.BadDataException,
|
|
296
|
+
);
|
|
258
297
|
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
259
298
|
expect(refreshSpy).not.toHaveBeenCalled();
|
|
260
299
|
});
|
|
261
300
|
|
|
262
|
-
|
|
301
|
+
// Was NotAuthorizedException (422) before the credential check.
|
|
302
|
+
test("rejects a public caller that supplies a tenant header it is not a member of with 401", async () => {
|
|
263
303
|
mockProps({
|
|
264
304
|
tenantId: callerProjectId,
|
|
265
305
|
userId: undefined,
|
|
@@ -271,7 +311,28 @@ describe("Project-scoped custom routes require an authenticated member of the re
|
|
|
271
311
|
params: { monitorId: monitorId.toString() },
|
|
272
312
|
});
|
|
273
313
|
|
|
314
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
315
|
+
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
316
|
+
expect(refreshSpy).not.toHaveBeenCalled();
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test("rejects a logged-in caller whose tenant header names a project they are not in with 422", async () => {
|
|
320
|
+
mockProps({
|
|
321
|
+
tenantId: callerProjectId,
|
|
322
|
+
userId: callerUserId,
|
|
323
|
+
userType: UserType.User,
|
|
324
|
+
userTenantAccessPermission: {},
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
const result: RouteCallResult = await callGetRoute({
|
|
328
|
+
uri: MONITOR_REFRESH_ROUTE,
|
|
329
|
+
params: { monitorId: monitorId.toString() },
|
|
330
|
+
});
|
|
331
|
+
|
|
274
332
|
expect(result.thrownToNext).toBeInstanceOf(NotAuthorizedException);
|
|
333
|
+
expect((result.thrownToNext as Exception).code).toBe(
|
|
334
|
+
ExceptionCode.NotAuthorizedException,
|
|
335
|
+
);
|
|
275
336
|
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
276
337
|
expect(refreshSpy).not.toHaveBeenCalled();
|
|
277
338
|
});
|
|
@@ -383,7 +444,8 @@ describe("Project-scoped custom routes require an authenticated member of the re
|
|
|
383
444
|
expect(Response.sendEmptySuccessResponse).toHaveBeenCalledTimes(1);
|
|
384
445
|
});
|
|
385
446
|
|
|
386
|
-
|
|
447
|
+
// Was BadDataException (400) before the credential check.
|
|
448
|
+
test("rejects an unauthenticated caller with NotAuthenticatedException (401) and never reads the rule", async () => {
|
|
387
449
|
mockProps({});
|
|
388
450
|
|
|
389
451
|
const result: RouteCallResult = await callGetRoute({
|
|
@@ -391,12 +453,29 @@ describe("Project-scoped custom routes require an authenticated member of the re
|
|
|
391
453
|
params: { workspaceNotifcationRuleId: ruleId.toString() },
|
|
392
454
|
});
|
|
393
455
|
|
|
456
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
457
|
+
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
458
|
+
expect(testRuleSpy).not.toHaveBeenCalled();
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
test("rejects a logged-in caller with no tenant header with BadDataException (400) and never reads the rule", async () => {
|
|
462
|
+
mockProps({ userId: callerUserId, userType: UserType.User });
|
|
463
|
+
|
|
464
|
+
const result: RouteCallResult = await callGetRoute({
|
|
465
|
+
uri: TEST_RULE_ROUTE,
|
|
466
|
+
params: { workspaceNotifcationRuleId: ruleId.toString() },
|
|
467
|
+
});
|
|
468
|
+
|
|
394
469
|
expect(result.thrownToNext).toBeInstanceOf(BadDataException);
|
|
470
|
+
expect((result.thrownToNext as Exception).code).toBe(
|
|
471
|
+
ExceptionCode.BadDataException,
|
|
472
|
+
);
|
|
395
473
|
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
396
474
|
expect(testRuleSpy).not.toHaveBeenCalled();
|
|
397
475
|
});
|
|
398
476
|
|
|
399
|
-
|
|
477
|
+
// Was NotAuthorizedException (422) before the credential check.
|
|
478
|
+
test("rejects a public caller that supplies a tenant header it is not a member of with 401", async () => {
|
|
400
479
|
mockProps({
|
|
401
480
|
tenantId: callerProjectId,
|
|
402
481
|
userId: undefined,
|
|
@@ -408,7 +487,35 @@ describe("Project-scoped custom routes require an authenticated member of the re
|
|
|
408
487
|
params: { workspaceNotifcationRuleId: ruleId.toString() },
|
|
409
488
|
});
|
|
410
489
|
|
|
490
|
+
expectAuthenticationRequired(result.thrownToNext);
|
|
491
|
+
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
492
|
+
expect(testRuleSpy).not.toHaveBeenCalled();
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
/*
|
|
496
|
+
* The rule test posts a message as a person (testByUserId), so a project
|
|
497
|
+
* API key - authenticated, but nobody - is refused. With the 422, not a
|
|
498
|
+
* 401: the key's client has no session to refresh.
|
|
499
|
+
*/
|
|
500
|
+
test("rejects a project API key with 422 and never reads the rule", async () => {
|
|
501
|
+
mockProps({
|
|
502
|
+
...buildMemberProps({
|
|
503
|
+
projectId: callerProjectId,
|
|
504
|
+
userId: callerUserId,
|
|
505
|
+
}),
|
|
506
|
+
userId: undefined,
|
|
507
|
+
userType: UserType.API,
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
const result: RouteCallResult = await callGetRoute({
|
|
511
|
+
uri: TEST_RULE_ROUTE,
|
|
512
|
+
params: { workspaceNotifcationRuleId: ruleId.toString() },
|
|
513
|
+
});
|
|
514
|
+
|
|
411
515
|
expect(result.thrownToNext).toBeInstanceOf(NotAuthorizedException);
|
|
516
|
+
expect((result.thrownToNext as Exception).code).toBe(
|
|
517
|
+
ExceptionCode.NotAuthorizedException,
|
|
518
|
+
);
|
|
412
519
|
expect(findOneByIdSpy).not.toHaveBeenCalled();
|
|
413
520
|
expect(testRuleSpy).not.toHaveBeenCalled();
|
|
414
521
|
});
|