@oneuptime/common 14.0.1 → 14.0.3
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/AlertEpisodeMember.ts +8 -1
- package/Models/DatabaseModels/AlertFeed.ts +2 -0
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +63 -0
- package/Models/DatabaseModels/IncidentAlert.ts +540 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +8 -1
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +9 -2
- package/Models/DatabaseModels/IncidentFeed.ts +2 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +9 -2
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +429 -0
- package/Models/DatabaseModels/Monitor.ts +48 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Models/DatabaseModels/RumApplication.ts +52 -1
- package/Models/DatabaseModels/Runner.ts +5 -4
- package/Models/DatabaseModels/RunnerJob.ts +66 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +10 -2
- package/Models/DatabaseModels/WorkflowVariable.ts +479 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +79 -25
- package/Server/API/AIInvestigationAPI.ts +341 -0
- package/Server/API/AutoRemediationAPI.ts +184 -2
- package/Server/API/CommonAPI.ts +70 -0
- package/Server/API/KubernetesClusterAiAccessAPI.ts +793 -0
- package/Server/API/MicrosoftTeamsAPI.ts +770 -315
- package/Server/API/MonitorAPI.ts +140 -0
- package/Server/API/OnCallScheduleTimelineAPI.ts +5 -21
- package/Server/API/SlackAPI.ts +447 -99
- package/Server/API/StatusPageAPI.ts +146 -26
- package/Server/API/TelemetryAPI.ts +216 -5
- package/Server/API/UserTwoFactorBackupCodeAPI.ts +1 -0
- package/Server/API/WorkflowVariableAPI.ts +156 -0
- package/Server/Infrastructure/GlobalCache.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.ts +97 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.ts +20 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +28 -0
- package/Server/Middleware/TelemetryIngest.ts +47 -2
- package/Server/Middleware/UserAuthorization.ts +56 -2
- package/Server/Services/AIAgentService.ts +1 -0
- package/Server/Services/AccessTokenService.ts +121 -48
- package/Server/Services/AlertEpisodeMemberService.ts +9 -0
- package/Server/Services/AlertEpisodeService.ts +14 -1
- package/Server/Services/AlertService.ts +134 -22
- package/Server/Services/AutoRemediationRuleEngineService.ts +968 -39
- package/Server/Services/AutoRemediationRuleService.ts +118 -0
- package/Server/Services/BillingService.ts +1 -0
- package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +16 -22
- package/Server/Services/IncidentAlertService.ts +1811 -0
- package/Server/Services/IncidentEpisodeMemberService.ts +9 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +66 -0
- package/Server/Services/IncidentEpisodeRoleMemberService.ts +27 -0
- package/Server/Services/IncidentEpisodeService.ts +14 -1
- package/Server/Services/IncidentGroupingEngineService.ts +11 -0
- package/Server/Services/IncidentMemberService.ts +21 -0
- package/Server/Services/IncidentPublicNoteService.ts +63 -0
- package/Server/Services/IncidentService.ts +330 -30
- package/Server/Services/IncidentStateTimelineService.ts +39 -0
- package/Server/Services/IncidentTemplateService.ts +83 -3
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1943 -0
- package/Server/Services/KubernetesClusterService.ts +1570 -1
- package/Server/Services/LogAggregationService.ts +14 -6
- package/Server/Services/MonitorService.ts +651 -52
- package/Server/Services/MonitorStatusTimelineService.ts +639 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +3 -0
- package/Server/Services/OnCallNotificationAlertingService.ts +36 -12
- package/Server/Services/OnCallSetupReminderService.ts +1 -0
- package/Server/Services/ProbeService.ts +7 -1
- package/Server/Services/ProjectService.ts +11 -1
- package/Server/Services/RunbookCredentialService.ts +26 -1
- package/Server/Services/RunbookSecretService.ts +36 -0
- package/Server/Services/RunnerJobService.ts +941 -23
- package/Server/Services/RunnerService.ts +439 -6
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +66 -0
- package/Server/Services/ScheduledMaintenanceService.ts +124 -19
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +82 -3
- package/Server/Services/ServiceLevelObjectiveService.ts +14 -1
- package/Server/Services/StatusPagePrivateUserService.ts +1 -0
- package/Server/Services/StatusPageService.ts +301 -74
- package/Server/Services/StatusPageSubscriberService.ts +4 -0
- package/Server/Services/TeamMemberService.ts +309 -7
- package/Server/Services/TraceAggregationService.ts +10 -6
- package/Server/Services/UserEmailService.ts +1 -0
- package/Server/Services/UserNotificationMethodAdminService.ts +1 -0
- package/Server/Services/UserNotificationRuleAdminService.ts +1 -0
- package/Server/Services/UserNotificationRuleService.ts +4 -0
- package/Server/Services/UserService.ts +122 -1
- package/Server/Services/WorkflowVariableService.ts +593 -8
- package/Server/Services/WorkspaceNotificationRuleService.ts +588 -8
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +170 -1
- package/Server/Types/Database/QueryHelper.ts +22 -0
- package/Server/Types/Markdown.ts +502 -27
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +182 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +525 -0
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +854 -0
- package/Server/Utils/AI/CodeFix/CodeFixAgentAuth.ts +22 -2
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1916 -307
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1601 -74
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +139 -7
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +58 -1
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +54 -1
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +14 -6
- package/Server/Utils/AI/Toolbox/ResourceTools.ts +4 -2
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +1341 -150
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +375 -4
- package/Server/Utils/Database/AffectedResourceRelations.ts +127 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +240 -1
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +1 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +83 -9
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +5 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +104 -9
- package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +124 -7
- package/Server/Utils/Monitor/ProbeMonitorsNotification.ts +407 -0
- package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +1 -0
- package/Server/Utils/PushNotificationUtil.ts +45 -0
- package/Server/Utils/Rules/OwnerRuleAssignment.ts +40 -3
- package/Server/Utils/Runbook/RunbookExecutePermission.ts +56 -6
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +223 -33
- package/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.ts +559 -0
- package/Server/Utils/StartServer.ts +4 -3
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +528 -0
- package/Server/Utils/TwoFactorBackupCodeNotification.ts +1 -0
- package/Server/Utils/UserPermission/UserPermission.ts +16 -0
- package/Server/Utils/Workflow/OAuth2TokenClient.ts +704 -0
- package/Server/Utils/Workflow/WorkflowVariableOAuthToken.ts +318 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +47 -7
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +57 -16
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +193 -214
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +57 -13
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.ts +54 -17
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +179 -161
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +281 -167
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.ts +114 -0
- package/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.ts +895 -0
- package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +7 -9
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +96 -227
- package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +93 -214
- package/Server/Utils/Workspace/Slack/Actions/Auth.ts +30 -3
- package/Server/Utils/Workspace/Slack/Actions/Authorization.ts +99 -0
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +117 -283
- package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +101 -196
- package/Server/Utils/Workspace/Slack/Actions/ReactionNote.ts +329 -0
- package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +111 -287
- package/Server/Utils/Workspace/Slack/Slack.ts +86 -17
- package/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
- package/Server/Utils/Workspace/Workspace.ts +171 -54
- package/Server/Utils/Workspace/WorkspaceActionAuthorization.ts +252 -0
- package/Server/Utils/Workspace/WorkspaceBase.ts +39 -0
- package/Server/Utils/Workspace/WorkspaceOAuthState.ts +280 -0
- package/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.ts +96 -0
- package/Server/Utils/Workspace/WorkspaceReactionNote.ts +620 -0
- package/Tests/App/Dashboard/AttributesJSONDashboardSurfaces.test.tsx +496 -0
- package/Tests/App/Dashboard/AutoRemediationRulesTableCommandRunners.test.tsx +152 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +32 -0
- package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
- package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
- package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +794 -0
- package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
- package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +840 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +653 -0
- package/Tests/App/Dashboard/DatabaseMonitorStepForm.test.tsx +197 -0
- package/Tests/App/Dashboard/DatabaseMonitorView.test.tsx +376 -0
- package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +262 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
- package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
- package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
- package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2080 -0
- package/Tests/App/Dashboard/EventNotesPages.test.tsx +486 -0
- package/Tests/App/Dashboard/EventNotesUtil.test.ts +933 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +238 -0
- package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
- package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
- package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
- package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
- package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
- package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
- package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
- package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
- package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
- package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
- package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +665 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
- package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +494 -0
- package/Tests/App/Dashboard/IncidentEpisodeOverviewNotifyDefault.test.tsx +706 -0
- package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +472 -0
- package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +858 -0
- package/Tests/App/Dashboard/IncomingEmailAddressSettings.test.tsx +567 -0
- package/Tests/App/Dashboard/InvestigationClusterToolFormat.test.ts +241 -0
- package/Tests/App/Dashboard/InvestigationEvidenceKubectl.test.tsx +322 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +12 -0
- package/Tests/App/Dashboard/InvestigationPanelClusterAccess.test.tsx +476 -0
- package/Tests/App/Dashboard/InvestigationRunDetailsKubectl.test.tsx +383 -0
- package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
- package/Tests/App/Dashboard/KubectlActivitySummary.test.tsx +366 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +2886 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +2688 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +915 -0
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
- package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
- package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
- package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
- package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
- package/Tests/App/Dashboard/LayerDateTimeFieldTimezoneName.test.tsx +66 -0
- package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
- package/Tests/App/Dashboard/LogMonitorPreview.test.tsx +174 -0
- package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
- package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
- package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
- package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +279 -0
- package/Tests/App/Dashboard/MonitorMetricQueryConfig.test.ts +244 -0
- package/Tests/App/Dashboard/MonitorOpenWorkCard.test.tsx +381 -0
- package/Tests/App/Dashboard/MonitorOpenWorkHook.test.tsx +784 -0
- package/Tests/App/Dashboard/MonitorOverviewData.test.tsx +2199 -0
- package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +1169 -0
- package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +1127 -0
- package/Tests/App/Dashboard/MonitorOverviewPage.test.tsx +2136 -0
- package/Tests/App/Dashboard/MonitorOverviewSelectReadable.test.ts +368 -0
- package/Tests/App/Dashboard/MonitorOverviewStatBar.test.tsx +526 -0
- package/Tests/App/Dashboard/MonitorOverviewSupportingCards.test.tsx +542 -0
- package/Tests/App/Dashboard/MonitorOwnersCombine.test.ts +299 -0
- package/Tests/App/Dashboard/MonitorProbesCard.test.tsx +602 -0
- package/Tests/App/Dashboard/MonitorResponseTimeCard.test.tsx +386 -0
- package/Tests/App/Dashboard/MonitorSetupAndConnectionCards.test.tsx +612 -0
- package/Tests/App/Dashboard/MonitorStatusChangesCard.test.tsx +257 -0
- package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +360 -1
- package/Tests/App/Dashboard/MonitorUptimeHistoryCard.test.tsx +835 -0
- package/Tests/App/Dashboard/MonitorUptimeSummaryHook.test.tsx +971 -0
- package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +580 -0
- package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
- package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
- package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
- package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
- package/Tests/App/Dashboard/OnCallLayerRestrictionTimesPreserved.test.tsx +441 -0
- package/Tests/App/Dashboard/OnCallNavbar.test.tsx +214 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewCalendarDisplay.test.tsx +1389 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +205 -1
- package/Tests/App/Dashboard/OnCallScheduleTimeInputsSettingsZone.test.tsx +198 -0
- package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
- package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
- package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
- package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +524 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardApproval.test.tsx +702 -0
- package/Tests/App/Dashboard/RemoveUserFromProject.test.tsx +427 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +4 -0
- package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
- package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +3 -1
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +166 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +622 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +1491 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +489 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewNotifyDefault.test.tsx +909 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +14 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceWindowStatsTranslation.test.tsx +307 -0
- package/Tests/App/Dashboard/SecurityEventAttributeColumnPicker.test.tsx +542 -0
- package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +174 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +973 -212
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +491 -52
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +301 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +158 -1
- package/Tests/App/Dashboard/SecurityEventProviderTile.test.tsx +869 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +959 -94
- package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +2 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +274 -1
- package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
- package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
- package/Tests/App/Dashboard/TeamMembershipRemoval.test.ts +900 -0
- package/Tests/App/Dashboard/TeamMembershipRemovalPages.test.tsx +460 -0
- package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
- package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
- package/Tests/App/Dashboard/TimezoneElements.test.tsx +321 -0
- package/Tests/App/Dashboard/TimezoneSelectButton.test.tsx +634 -0
- package/Tests/App/Dashboard/TraceExplorer.test.tsx +260 -0
- package/Tests/App/Dashboard/TraceMonitorPreview.test.tsx +182 -0
- package/Tests/App/Dashboard/UserTimezoneInit.test.tsx +544 -0
- package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
- package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
- package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
- package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
- package/Tests/App/Dashboard/WorkflowVariableModals.test.tsx +1630 -0
- package/Tests/App/Dashboard/WorkflowVariableRoutes.test.tsx +603 -0
- package/Tests/App/Dashboard/WorkflowVariableTokenStatus.test.tsx +589 -0
- package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +1543 -0
- package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +3227 -0
- package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +1277 -395
- package/Tests/App/StatusPage/StatusPageOverviewMonitorGroupUptime.test.tsx +714 -0
- package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.NewYork.test.tsx +1009 -0
- package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.test.tsx +1092 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -0
- package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
- package/Tests/Models/DatabaseModels/KubernetesClusterAiAccessColumns.test.ts +520 -0
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +66 -2
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
- package/Tests/Models/DatabaseModels/WorkspaceProjectAuthTokenAccessControl.test.ts +236 -0
- package/Tests/Models/IncidentEpisodePublicNoteNotifyColumnContract.test.ts +103 -0
- package/Tests/Models/IncidentPublicNoteNotifyColumnContract.test.ts +96 -0
- package/Tests/Models/ScheduledMaintenancePublicNoteNotifyColumnContract.test.ts +111 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +976 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +836 -0
- package/Tests/Server/API/CommonAPIAssertCanCreateTable.test.ts +565 -0
- package/Tests/Server/API/CommonAPIAssertCanReadTable.test.ts +282 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +1744 -0
- package/Tests/Server/API/LogHistogramAPI.test.ts +371 -0
- package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +125 -30
- package/Tests/Server/API/MicrosoftTeamsOAuthState.test.ts +1121 -0
- package/Tests/Server/API/MonitorUptimeSummaryAPI.test.ts +685 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +602 -1
- package/Tests/Server/API/SlackChannelCacheAPI.test.ts +358 -0
- package/Tests/Server/API/SlackOAuthState.test.ts +688 -0
- package/Tests/Server/API/StatusPageOverviewMonitorGroupUptime.test.ts +527 -0
- package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +2 -0
- package/Tests/Server/API/StatusPageUptimeAPI.test.ts +427 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +4 -0
- package/Tests/Server/API/WorkflowVariableAPI.test.ts +404 -0
- package/Tests/Server/API/WorkspaceOAuthTestHelpers.ts +289 -0
- package/Tests/Server/API/WorkspaceSendTestNotificationRoutes.test.ts +2064 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +86 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +589 -0
- package/Tests/Server/Infrastructure/Postgres/AddOAuth2WorkflowVariablesMigration.test.ts +254 -0
- package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
- package/Tests/Server/Middleware/BlockedUserMiddleware.test.ts +403 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +13 -0
- package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +2 -0
- package/Tests/Server/Middleware/RemovedProjectMemberAuthorization.test.ts +469 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +77 -1
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +211 -0
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +358 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +97 -0
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +2 -0
- package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +14 -2
- package/Tests/Server/Services/AccessTokenRemovedMemberAccess.test.ts +1044 -0
- package/Tests/Server/Services/AddOwnersIdempotency.test.ts +5 -0
- package/Tests/Server/Services/AlertEpisodeMemberCreatePermission.test.ts +139 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +1361 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +375 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +2384 -0
- package/Tests/Server/Services/FindOwnersProjectMembership.test.ts +267 -0
- package/Tests/Server/Services/InboundEmail/SendGridInboundProviderAddress.test.ts +90 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
- package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
- package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
- package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
- package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
- package/Tests/Server/Services/IncidentEpisodeMemberCreatePermission.test.ts +143 -0
- package/Tests/Server/Services/IncidentEpisodePublicNoteNotifyDefault.test.ts +805 -0
- package/Tests/Server/Services/IncidentPublicNoteNotifyDefault.test.ts +724 -0
- package/Tests/Server/Services/IncidentRoleProjectMembership.test.ts +233 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +372 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessBindingGuard.test.ts +1876 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +620 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +421 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +3662 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessSubjectClusters.test.ts +405 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +975 -0
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +497 -0
- package/Tests/Server/Services/KubernetesClusterServiceDeleteSettlesRemediation.test.ts +328 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +99 -0
- package/Tests/Server/Services/MonitorServiceIncomingEmailCustomAddress.test.ts +447 -0
- package/Tests/Server/Services/MonitorServiceProbeFlagSync.test.ts +1334 -0
- package/Tests/Server/Services/MonitorServiceProbeStatusGrouping.test.ts +1640 -0
- package/Tests/Server/Services/MonitorServiceRefreshCurrentStatus.test.ts +225 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +8 -8
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +264 -1
- package/Tests/Server/Services/MonitorStatusTimelineMergedDowntime.test.ts +284 -0
- package/Tests/Server/Services/MonitorUptimeSummaryService.test.ts +1043 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +5 -0
- package/Tests/Server/Services/OnCallUndeliverablePageOwnerMembership.test.ts +359 -0
- package/Tests/Server/Services/ProbeServiceDashboardLink.test.ts +191 -0
- package/Tests/Server/Services/ProjectOwnersProjectMembership.test.ts +221 -0
- package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +5 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +28 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +9 -1
- package/Tests/Server/Services/RunnerJobEnqueueAiCommandAgentRunner.test.ts +230 -0
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +978 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +866 -0
- package/Tests/Server/Services/RunnerJobSubmitResultRedaction.test.ts +322 -0
- package/Tests/Server/Services/RunnerJobSubmitResultUnstorableText.test.ts +357 -0
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +227 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +581 -0
- package/Tests/Server/Services/ScheduledMaintenancePublicNoteNotifyDefault.test.ts +802 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +53 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +5 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +12 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +1176 -1
- package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +18 -0
- package/Tests/Server/Services/TeamMemberProjectMembership.test.ts +255 -0
- package/Tests/Server/Services/TeamMemberRemovalRevokesProjectAccess.test.ts +600 -0
- package/Tests/Server/Services/TeamMemberResourceCleanup.test.ts +731 -0
- package/Tests/Server/Services/TeamMemberWorkspaceAccountCleanup.test.ts +164 -0
- package/Tests/Server/Services/TraceAggregationService.test.ts +64 -0
- package/Tests/Server/Services/UserServiceBlockedUser.test.ts +293 -0
- package/Tests/Server/Services/WorkflowVariableOAuthHooks.test.ts +1016 -0
- package/Tests/Server/Services/WorkflowVariableOAuthPostgres.test.ts +543 -0
- package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +16 -5
- package/Tests/Server/Services/WorkspaceNotificationRuleNoteDelivery.test.ts +473 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleSendTestNotification.test.ts +3690 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenMiscDataSecrets.test.ts +374 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenSlackChannelCache.test.ts +143 -0
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableOAuthColumnPermission.test.ts +250 -0
- package/Tests/Server/Types/Database/QueryHelperJsonContains.test.ts +96 -0
- package/Tests/Server/Types/Markdown.test.ts +1033 -0
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +285 -0
- package/Tests/Server/Utils/AI/CodeFix/CodeFixAgentAuth.test.ts +159 -1
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +752 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +1840 -0
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +1067 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +355 -0
- package/Tests/Server/Utils/AI/PostIncidentStatusUpdateTool.test.ts +496 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +305 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +1365 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +639 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +1585 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +1065 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +2138 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +1035 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +517 -0
- package/Tests/Server/Utils/AI/ResourceTools.test.ts +27 -1
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +1371 -24
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorRollbackRace.test.ts +962 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +518 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +939 -2
- package/Tests/Server/Utils/Database/ProjectScopedRelationReferences.test.ts +371 -0
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +64 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricObservationRemediation.test.ts +102 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +362 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +55 -0
- package/Tests/Server/Utils/Monitor/MonitorEmailAddressRedaction.test.ts +255 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +347 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +203 -0
- package/Tests/Server/Utils/Monitor/ProbeMonitorsNotification.test.ts +1147 -0
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +79 -0
- package/Tests/Server/Utils/ResourceFeed/ResourceFeedUtil.test.ts +21 -1
- package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +155 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +288 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.test.ts +304 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +40 -3
- package/Tests/Server/Utils/Workflow/OAuth2TokenClient.test.ts +702 -0
- package/Tests/Server/Utils/Workflow/OAuth2TokenClientHttpIntegration.test.ts +507 -0
- package/Tests/Server/Utils/Workflow/WorkflowVariableOAuthToken.test.ts +831 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +63 -1
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsAppAccessToken.test.ts +256 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +60 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChatActionAuthorization.test.ts +442 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +44 -2
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +55 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsReactionNoteSync.test.ts +1522 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsServiceUrl.test.ts +130 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +4 -4
- package/Tests/Server/Utils/Workspace/Slack/SlackActionAuthorization.test.ts +691 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMessageByTimestamp.test.ts +253 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackReactionNote.test.ts +574 -0
- package/Tests/Server/Utils/Workspace/WorkspaceActionAuthorization.test.ts +488 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +861 -0
- package/Tests/Server/Utils/Workspace/WorkspaceMessageAuthor.test.ts +635 -0
- package/Tests/Server/Utils/Workspace/WorkspaceOAuthState.test.ts +548 -0
- package/Tests/Server/Utils/Workspace/WorkspaceReactionNote.test.ts +839 -0
- package/Tests/Server/Utils/Workspace/WorkspaceSendErrorMessage.test.ts +725 -0
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +283 -9
- package/Tests/Types/DateBrowserLocalWallClock.test.ts +280 -0
- package/Tests/Types/DateLocalShortMonthNameFallback.test.ts +389 -0
- package/Tests/Types/DateUserTimezone.test.ts +177 -4
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +306 -0
- package/Tests/Types/Kubernetes/KubernetesClusterAiAccess.test.ts +283 -0
- package/Tests/Types/Kubernetes/KubernetesRunnerPostureWriteScope.test.ts +68 -0
- package/Tests/Types/Monitor/DatabaseMonitor/SqlServerPlatform.test.ts +144 -0
- package/Tests/Types/Monitor/MonitorStepExceptionMonitor.test.ts +160 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +53 -0
- package/Tests/Types/Rum/WebVitals.test.ts +173 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +91 -16
- package/Tests/Types/Runner/RunnerLiveStatus.test.ts +14 -3
- package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +15 -0
- package/Tests/Types/StatusPage/PublicNoteSubscriberNotificationDefault.test.ts +1868 -0
- package/Tests/Types/Timezone.test.ts +5 -0
- package/Tests/Types/TimezoneAlias.test.ts +1034 -0
- package/Tests/Types/Workflow/JiraTemplateFixtures.ts +833 -0
- package/Tests/Types/Workflow/JiraTemplateScripts.test.ts +5414 -0
- package/Tests/Types/Workflow/JiraTemplateSimulation.test.ts +4803 -0
- package/Tests/Types/Workflow/JiraTemplates.test.ts +5429 -0
- package/Tests/Types/Workflow/Templates.test.ts +79 -4
- package/Tests/Types/Workflow/WorkflowVariableOAuth.test.ts +520 -0
- package/Tests/Types/Workspace/WorkspaceNoteReaction.test.ts +177 -0
- package/Tests/UI/Components/AttributesJSON/AttributesJSONView.test.tsx +390 -0
- package/Tests/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.test.tsx +566 -0
- package/Tests/UI/Components/AttributesJSON/JSONHighlight.test.ts +131 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +276 -1
- package/Tests/UI/Components/Calendar/Calendar.test.tsx +1611 -0
- package/Tests/UI/Components/Calendar/CalendarDayLayout.test.ts +1486 -0
- package/Tests/UI/Components/Calendar/CalendarDayLayoutDst.test.ts +632 -0
- package/Tests/UI/Components/Calendar/CalendarDst.test.tsx +388 -0
- package/Tests/UI/Components/Charts/ChartGroupPlotFloor.test.tsx +170 -0
- package/Tests/UI/Components/Charts/HistogramSelection.test.ts +282 -0
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +6 -0
- package/Tests/UI/Components/CustomTimeRangeModalTimezoneTranslation.test.tsx +285 -0
- package/Tests/UI/Components/Dropdown.test.tsx +999 -2
- package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
- package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +216 -0
- package/Tests/UI/Components/Forms/FormFieldTimezoneDescriptionTranslation.test.tsx +461 -0
- package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +641 -0
- package/Tests/UI/Components/Forms/IncidentPublicNoteNotifyPayload.test.tsx +346 -0
- package/Tests/UI/Components/Forms/ScheduledMaintenancePublicNoteNotifyPayload.test.tsx +493 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +911 -2
- package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.NewYork.test.tsx +730 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.Tokyo.test.tsx +506 -0
- package/Tests/UI/Components/HistogramClickToZoom.test.tsx +619 -0
- package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
- package/Tests/UI/Components/LogDetailsPanelAttributesJSON.test.tsx +248 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +47 -1
- package/Tests/UI/Components/LogsViewerSmallScreens.test.tsx +620 -0
- package/Tests/UI/Components/ModelPageModelChange.test.tsx +242 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +521 -0
- package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +406 -2
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +169 -2
- package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +266 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerSmallScreens.test.tsx +439 -0
- package/Tests/UI/Components/TimezoneDropdownLegacyValues.test.tsx +704 -0
- package/Tests/UI/Components/UseHistogramZoom.test.tsx +89 -1
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +175 -0
- package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +5 -5
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
- package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
- package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
- package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
- package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
- package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
- package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +28 -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/PermissionGate.test.ts +76 -0
- package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +51 -0
- package/Tests/UI/Utils/Timezone.test.ts +747 -33
- package/Tests/UI/Workspace/SendTestNotificationButton.test.tsx +1854 -0
- package/Tests/UI/Workspace/WorkspaceCardsSendTestNotification.test.tsx +1864 -0
- package/Tests/Utils/AI/InvestigationReport.test.ts +435 -7
- package/Tests/Utils/AiRemediation/KubectlAllowlistValidatorParity.test.ts +1084 -0
- package/Tests/Utils/AiRemediation/KubectlOutputRedactor.test.ts +2531 -0
- package/Tests/Utils/AiRemediation/KubectlPolicy.test.ts +1895 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyAllowlist.test.ts +428 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +828 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyCustomResourceScope.test.ts +573 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyDenials.test.ts +1525 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyExposeOverrides.test.ts +275 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyNodePatch.test.ts +428 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyObjectWords.test.ts +195 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyPatchParents.test.ts +637 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyPodSecurityBaseline.test.ts +322 -0
- package/Tests/Utils/AiRemediation/KubectlPolicySafeWriteScope.test.ts +1026 -0
- package/Tests/Utils/AiRemediation/KubectlWaitBudget.test.ts +267 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScope.test.ts +390 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +777 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeClusterScoped.test.ts +613 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeEntryPoint.test.ts +576 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeKubectlSpellings.test.ts +752 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeObjectWords.test.ts +358 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeOverrides.test.ts +293 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +598 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopePolicyParity.test.ts +403 -0
- package/Tests/Utils/Dashboard/DashboardClockComponent.test.ts +154 -5
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
- package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +478 -0
- package/Tests/Utils/Monitor/MonitorCheckScheduleUtil.test.ts +646 -0
- package/Tests/Utils/Monitor/MonitorOverviewCriteriaUtil.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorOverviewFamily.test.ts +274 -0
- package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +3100 -0
- package/Tests/Utils/Monitor/MonitorOverviewProbeUtil.test.ts +1412 -0
- package/Tests/Utils/Monitor/MonitorOverviewTargetUtil.test.ts +374 -0
- package/Tests/Utils/Monitor/MonitorStatusHistoryUtil.test.ts +332 -0
- package/Tests/Utils/Monitor/MonitorUptimeSummaryUtil.test.ts +946 -0
- package/Tests/Utils/Rum/SessionIdentity.test.ts +94 -0
- package/Tests/Utils/Rum/SessionReplayWafCompatibility.test.ts +840 -0
- package/Tests/Utils/Rum/SessionReplayWireEncoding.test.ts +208 -0
- package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
- package/Tests/Utils/Rum/UserFlow.test.ts +1010 -0
- package/Tests/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.test.ts +217 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +1272 -1
- package/Tests/Utils/StatusPage/UptimeDailyAggregateTotals.test.ts +298 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +649 -1
- package/Tests/Utils/StatusPage/UptimeDailyAggregateWindow.test.ts +314 -0
- package/Tests/Utils/Telemetry/AttributesJSON.test.ts +454 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +418 -2
- package/Tests/Utils/Uptime/DayUptimeGraphUtilMidnightDst.test.ts +160 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Auckland.test.ts +45 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Kolkata.test.ts +40 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.London.test.ts +147 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.NewYork.test.ts +48 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Tokyo.test.ts +39 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezoneCases.ts +1015 -0
- package/Tests/Utils/Uptime/UptimeUtil.test.ts +75 -0
- package/Tests/Utils/Uptime/UptimeUtilChronologicalOrder.test.ts +1279 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +203 -5
- package/Types/Date.ts +121 -7
- package/Types/Email/EmailMessage.ts +8 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Exception/ExceptionMessages.ts +1 -0
- package/Types/Incident/IncidentAlertLink.ts +38 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +488 -0
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +54 -0
- package/Types/Kubernetes/KubernetesClusterAiAccessToolNames.ts +17 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +9 -0
- package/Types/Monitor/DatabaseMonitor/SqlServerPlatform.ts +117 -0
- package/Types/Monitor/KubernetesAlertTemplates.ts +6 -5
- package/Types/Monitor/MonitorStepExceptionMonitor.ts +56 -0
- package/Types/Monitor/MonitorUptimeSummary.ts +113 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +11 -0
- package/Types/Permission.ts +48 -0
- package/Types/Rum/SessionReplay.ts +80 -8
- package/Types/Rum/SessionReplayApi.ts +44 -1
- package/Types/Rum/UserFlow.ts +187 -0
- package/Types/Rum/WebVitals.ts +52 -0
- package/Types/Runbook/RunbookStepType.ts +10 -0
- package/Types/Runbook/RunnerJobOrigin.ts +15 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +6 -2
- package/Types/StatusPage/MergedDowntimeTotals.ts +17 -0
- package/Types/StatusPage/PublicNoteSubscriberNotificationDefault.ts +148 -0
- package/Types/StatusPage/UptimeDailyAggregate.ts +15 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +9 -0
- package/Types/Timezone.ts +5 -0
- package/Types/TimezoneAlias.ts +385 -0
- package/Types/Workflow/Templates.ts +3041 -2
- package/Types/Workflow/WorkflowVariableOAuth.ts +476 -0
- package/Types/Workspace/WorkspaceNoteReaction.ts +132 -0
- package/Typings/Index.d.ts +24 -0
- package/UI/Components/AttributesJSON/AttributesJSONPreferences.ts +175 -0
- package/UI/Components/AttributesJSON/AttributesJSONView.tsx +138 -0
- package/UI/Components/AttributesJSON/AttributesViewToggle.tsx +79 -0
- package/UI/Components/AttributesJSON/BracesGlyph.tsx +30 -0
- package/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.tsx +491 -0
- package/UI/Components/AttributesJSON/JSONHighlight.ts +77 -0
- package/UI/Components/Calendar/Calendar.css +83 -0
- package/UI/Components/Calendar/Calendar.tsx +136 -7
- package/UI/Components/Calendar/CalendarDayLayout.ts +236 -0
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -1
- package/UI/Components/Charts/Utils/HistogramSelection.ts +117 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +269 -0
- package/UI/Components/Charts/Utils/useHistogramZoom.ts +26 -2
- package/UI/Components/Date/CustomTimeRangeModal.tsx +26 -3
- package/UI/Components/Detail/FieldLabel.tsx +8 -0
- package/UI/Components/Dropdown/Dropdown.tsx +58 -9
- package/UI/Components/Forms/Fields/FormField.tsx +49 -14
- package/UI/Components/Graphs/DayUptimeGraph.tsx +166 -25
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +10 -2
- package/UI/Components/Graphs/UptimeDaySummary.tsx +8 -0
- package/UI/Components/InfoCard/InfoCard.tsx +47 -1
- package/UI/Components/LogsViewer/LogsViewer.tsx +52 -5
- package/UI/Components/LogsViewer/components/ColumnSelector.tsx +13 -2
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +13 -1
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +91 -76
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +15 -1
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +28 -106
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +54 -6
- package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +8 -2
- package/UI/Components/LogsViewer/useLogsHistogram.ts +39 -6
- package/UI/Components/ModelTable/BaseModelTable.tsx +161 -31
- package/UI/Components/ModelTable/Column.ts +5 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +12 -0
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +10 -2
- package/UI/Components/Page/ModelPage.tsx +59 -3
- package/UI/Components/Table/TableHeader.tsx +47 -2
- package/UI/Components/Table/Types/Column.ts +7 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +69 -5
- package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +12 -1
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +15 -1
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +36 -104
- package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +9 -1
- package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
- package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +19 -1
- package/UI/Utils/PermissionGate.ts +11 -2
- package/UI/Utils/Timezone.ts +69 -28
- package/Utils/AI/InvestigationReport.ts +195 -25
- package/Utils/AiRemediation/KubectlOutputRedactor.ts +1724 -0
- package/Utils/AiRemediation/KubectlPolicy.ts +4136 -0
- package/Utils/AiRemediation/KubectlWaitBudget.ts +156 -0
- package/Utils/AiRemediation/KubectlWriteScope.ts +1964 -0
- package/Utils/Dashboard/Components/DashboardClockComponent.ts +7 -6
- package/Utils/Incident/IncidentFromAlerts.ts +516 -0
- package/Utils/Monitor/IncomingEmailMonitorAddress.ts +292 -0
- package/Utils/Monitor/MonitorCheckScheduleUtil.ts +654 -0
- package/Utils/Monitor/MonitorOverviewCriteriaUtil.ts +188 -0
- package/Utils/Monitor/MonitorOverviewFamily.ts +263 -0
- package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +1958 -0
- package/Utils/Monitor/MonitorOverviewProbeUtil.ts +979 -0
- package/Utils/Monitor/MonitorOverviewTargetUtil.ts +299 -0
- package/Utils/Monitor/MonitorStatusHistoryUtil.ts +201 -0
- package/Utils/Monitor/MonitorUptimeSummaryUtil.ts +638 -0
- package/Utils/Rum/SessionIdentity.ts +44 -0
- package/Utils/Rum/SessionReplayWireEncoding.ts +137 -0
- package/Utils/Rum/SessionTraceState.ts +212 -0
- package/Utils/Rum/UserFlow.ts +1527 -0
- package/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.ts +107 -0
- package/Utils/StatusPage/ResourceUptime.ts +99 -0
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +197 -0
- package/Utils/Telemetry/AttributesJSON.ts +367 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +165 -0
- package/Utils/Uptime/UptimeUtil.ts +122 -38
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +8 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
- package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +8 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +10 -3
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +10 -3
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +434 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +49 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Runner.js +4 -4
- package/build/dist/Models/DatabaseModels/Runner.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +66 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +11 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +487 -3
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +64 -16
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +205 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +115 -2
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +49 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +564 -0
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -0
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +465 -176
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +107 -1
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +5 -16
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +322 -78
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +123 -17
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +144 -5
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js +1 -0
- package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js.map +1 -1
- package/build/dist/Server/API/WorkflowVariableAPI.js +109 -0
- package/build/dist/Server/API/WorkflowVariableAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js +54 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +21 -0
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +32 -2
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +39 -6
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +1 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +87 -42
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeMemberService.js +4 -0
- package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +12 -1
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +110 -23
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +716 -30
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +100 -0
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +1 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +11 -16
- package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +4 -0
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +48 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js +21 -0
- package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +12 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentMemberService.js +14 -0
- package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +48 -0
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +263 -33
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +33 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +68 -4
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +1470 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterService.js +1097 -0
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +14 -6
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +487 -48
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +540 -3
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +3 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +29 -7
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
- package/build/dist/Server/Services/OnCallSetupReminderService.js +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +7 -1
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +11 -1
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RunbookCredentialService.js +24 -0
- package/build/dist/Server/Services/RunbookCredentialService.js.map +1 -1
- package/build/dist/Server/Services/RunbookSecretService.js +44 -0
- package/build/dist/Server/Services/RunbookSecretService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +641 -21
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +344 -5
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +48 -0
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +102 -20
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +67 -4
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +12 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -0
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +230 -32
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +270 -11
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +10 -6
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +1 -0
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +1 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +4 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +107 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowVariableService.js +396 -7
- package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +463 -7
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +144 -2
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +20 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +394 -27
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +123 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +344 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +587 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js +18 -2
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1380 -239
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +1099 -68
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +88 -6
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +45 -11
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +41 -11
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +11 -4
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +4 -2
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +997 -141
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +299 -4
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +120 -0
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +160 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +59 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +5 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +84 -22
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +70 -5
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js +249 -0
- package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -1
- package/build/dist/Server/Utils/PushNotificationUtil.js +27 -0
- package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +26 -3
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
- package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js +38 -3
- package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +143 -23
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js +406 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +4 -3
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +382 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -0
- package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js +1 -0
- package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js.map +1 -1
- package/build/dist/Server/Utils/UserPermission/UserPermission.js +10 -0
- package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +447 -0
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -0
- package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js +202 -0
- package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +39 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +44 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +150 -191
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +44 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js +39 -17
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +151 -145
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +221 -127
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js +91 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js +673 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +3 -9
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +65 -166
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +63 -157
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +23 -3
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js +92 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +81 -210
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +68 -138
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js +240 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +85 -212
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +60 -17
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
- package/build/dist/Server/Utils/Workspace/Workspace.js +134 -41
- package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js +197 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +32 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js +199 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js +91 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js +450 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +103 -5
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/Date.js +97 -7
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
- package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
- package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +245 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +49 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js +16 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js +104 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js.map +1 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +6 -5
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +32 -0
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorUptimeSummary.js +52 -0
- package/build/dist/Types/Monitor/MonitorUptimeSummary.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +9 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +52 -2
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +11 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/Types/Rum/UserFlow.js +115 -0
- package/build/dist/Types/Rum/UserFlow.js.map +1 -0
- package/build/dist/Types/Rum/WebVitals.js +25 -0
- package/build/dist/Types/Rum/WebVitals.js.map +1 -1
- package/build/dist/Types/Runbook/RunbookStepType.js +10 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Runbook/RunnerJobOrigin.js +14 -0
- package/build/dist/Types/Runbook/RunnerJobOrigin.js.map +1 -1
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +2 -2
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
- package/build/dist/Types/StatusPage/MergedDowntimeTotals.js +2 -0
- package/build/dist/Types/StatusPage/MergedDowntimeTotals.js.map +1 -0
- package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js +65 -0
- package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +8 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/Types/Timezone.js +5 -0
- package/build/dist/Types/Timezone.js.map +1 -1
- package/build/dist/Types/TimezoneAlias.js +340 -0
- package/build/dist/Types/TimezoneAlias.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +2694 -2
- package/build/dist/Types/Workflow/Templates.js.map +1 -1
- package/build/dist/Types/Workflow/WorkflowVariableOAuth.js +314 -0
- package/build/dist/Types/Workflow/WorkflowVariableOAuth.js.map +1 -0
- package/build/dist/Types/Workspace/WorkspaceNoteReaction.js +98 -0
- package/build/dist/Types/Workspace/WorkspaceNoteReaction.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js +95 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js +44 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js +27 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js +9 -0
- package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js +260 -0
- package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js +56 -0
- package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +94 -7
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Calendar/CalendarDayLayout.js +136 -0
- package/build/dist/UI/Components/Calendar/CalendarDayLayout.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js +72 -0
- package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +178 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +13 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -1
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +20 -4
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -1
- package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
- package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -9
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +36 -13
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +117 -11
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +36 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js +10 -2
- package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +9 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +16 -15
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +14 -74
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +22 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +9 -2
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +16 -5
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +89 -22
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +7 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +5 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +37 -3
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +18 -2
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +27 -6
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +7 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +17 -77
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +10 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +15 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +4 -2
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/Timezone.js +52 -17
- package/build/dist/UI/Utils/Timezone.js.map +1 -1
- package/build/dist/Utils/AI/InvestigationReport.js +116 -21
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js +1209 -0
- package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +2973 -0
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js +99 -0
- package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlWriteScope.js +1429 -0
- package/build/dist/Utils/AiRemediation/KubectlWriteScope.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js +7 -6
- package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +214 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js +471 -0
- package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js +107 -0
- package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewFamily.js +191 -0
- package/build/dist/Utils/Monitor/MonitorOverviewFamily.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +1259 -0
- package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js +593 -0
- package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js +195 -0
- package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js +464 -0
- package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js.map +1 -0
- package/build/dist/Utils/Rum/SessionIdentity.js +31 -1
- package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayWireEncoding.js +128 -0
- package/build/dist/Utils/Rum/SessionReplayWireEncoding.js.map +1 -0
- package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
- package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
- package/build/dist/Utils/Rum/UserFlow.js +941 -0
- package/build/dist/Utils/Rum/UserFlow.js.map +1 -0
- package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js +82 -0
- package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +46 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/AttributesJSON.js +245 -0
- package/build/dist/Utils/Telemetry/AttributesJSON.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +103 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -1
- package/build/dist/Utils/Uptime/UptimeUtil.js +91 -27
- package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
- package/jest.config.json +2 -1
- package/package.json +2 -1
- package/tsconfig.tests.json +36 -0
- package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +0 -337
- package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +0 -124
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +0 -47
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "@testing-library/jest-dom";
|
|
2
|
-
import { act, cleanup, render, screen } from "@testing-library/react";
|
|
2
|
+
import { act, cleanup, render, screen, waitFor } from "@testing-library/react";
|
|
3
3
|
import React, { ReactElement } from "react";
|
|
4
4
|
import {
|
|
5
5
|
afterEach,
|
|
@@ -9,34 +9,30 @@ import {
|
|
|
9
9
|
jest,
|
|
10
10
|
test,
|
|
11
11
|
} from "@jest/globals";
|
|
12
|
+
import type { SpyInstance } from "jest-mock";
|
|
12
13
|
|
|
13
14
|
/*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* The workflow variables list - Workflows > Global Variables and Workflow >
|
|
16
|
+
* View > Workflow Variables - after it was simplified.
|
|
16
17
|
*
|
|
17
|
-
*
|
|
18
|
-
* Variables (local) - passed isEditable={false}, so a variable was immutable
|
|
19
|
-
* from the moment it was saved. There was a reason for that, and it is why
|
|
20
|
-
* turning the flag on is not the whole fix:
|
|
18
|
+
* What was asked for, and what every describe block below pins down:
|
|
21
19
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
20
|
+
* 1. The list shows Name, Type and Description. The Secret, Token and
|
|
21
|
+
* Created At columns are gone.
|
|
22
|
+
* 2. A row has one action, View, which opens the variable's own page. Show
|
|
23
|
+
* ID, Update Content, Edit Details and Delete are no longer row actions.
|
|
24
|
+
* 3. Create makes a static variable and never asks which kind. An OAuth 2.0
|
|
25
|
+
* variable is created from the More (⋯) menu beside it.
|
|
26
|
+
* 4. Both of the above on the global page and on a workflow's own page.
|
|
28
27
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* one column through ModelAPI.
|
|
34
|
-
*
|
|
35
|
-
* ModelTable is replaced by a prop recorder: what is under test is the
|
|
36
|
-
* configuration the page hands it, and the real table fetches on mount.
|
|
28
|
+
* ModelTable, the OAuth create form and the token refresh modal are replaced
|
|
29
|
+
* by prop recorders: what is under test is the configuration the page hands
|
|
30
|
+
* them and what the page does when their callbacks fire. The real table
|
|
31
|
+
* fetches on mount.
|
|
37
32
|
*/
|
|
38
33
|
|
|
39
34
|
let permissionsForTest: Array<unknown> = [];
|
|
35
|
+
let isMasterAdminForTest: boolean = false;
|
|
40
36
|
|
|
41
37
|
jest.mock("../../../UI/Utils/Permission", () => {
|
|
42
38
|
return {
|
|
@@ -60,7 +56,7 @@ jest.mock("../../../UI/Utils/User", () => {
|
|
|
60
56
|
__esModule: true,
|
|
61
57
|
default: {
|
|
62
58
|
isMasterAdmin: (): boolean => {
|
|
63
|
-
return
|
|
59
|
+
return isMasterAdminForTest;
|
|
64
60
|
},
|
|
65
61
|
getUserId: (): null => {
|
|
66
62
|
return null;
|
|
@@ -80,37 +76,48 @@ jest.mock("../../../UI/Utils/Project", () => {
|
|
|
80
76
|
};
|
|
81
77
|
});
|
|
82
78
|
|
|
79
|
+
const getLastParamAsObjectID: ReturnType<
|
|
80
|
+
typeof jest.fn<(position: number) => unknown>
|
|
81
|
+
> = jest.fn<(position: number) => unknown>();
|
|
82
|
+
|
|
83
83
|
jest.mock("../../../UI/Utils/Navigation", () => {
|
|
84
84
|
return {
|
|
85
85
|
__esModule: true,
|
|
86
86
|
default: {
|
|
87
|
-
getLastParamAsObjectID: (): unknown => {
|
|
88
|
-
return
|
|
87
|
+
getLastParamAsObjectID: (position: number): unknown => {
|
|
88
|
+
return getLastParamAsObjectID(position);
|
|
89
89
|
},
|
|
90
90
|
},
|
|
91
91
|
};
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
const updateById: ReturnType<
|
|
95
|
-
typeof jest.fn<(data: unknown) => Promise<unknown>>
|
|
96
|
-
> = jest.fn<(data: unknown) => Promise<unknown>>();
|
|
97
|
-
|
|
98
94
|
jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
|
|
99
95
|
return {
|
|
100
96
|
__esModule: true,
|
|
101
97
|
default: {
|
|
102
|
-
|
|
103
|
-
return
|
|
98
|
+
getCommonHeaders: (): Record<string, string> => {
|
|
99
|
+
return { tenantid: "project-header" };
|
|
104
100
|
},
|
|
105
101
|
},
|
|
106
102
|
};
|
|
107
103
|
});
|
|
108
104
|
|
|
105
|
+
const apiPost: ReturnType<typeof jest.fn<(data: unknown) => Promise<unknown>>> =
|
|
106
|
+
jest.fn<(data: unknown) => Promise<unknown>>();
|
|
107
|
+
|
|
109
108
|
jest.mock("../../../UI/Utils/API/API", () => {
|
|
110
109
|
return {
|
|
111
110
|
__esModule: true,
|
|
112
111
|
default: {
|
|
112
|
+
post: (data: unknown): Promise<unknown> => {
|
|
113
|
+
return apiPost(data);
|
|
114
|
+
},
|
|
115
|
+
// The same precedence as the real one, for the two shapes used here.
|
|
113
116
|
getFriendlyMessage: (error: unknown): string => {
|
|
117
|
+
if (error instanceof HTTPErrorResponse) {
|
|
118
|
+
return error.message || "Server Error. Please try again";
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
return error instanceof Error ? error.message : "Request failed.";
|
|
115
122
|
},
|
|
116
123
|
},
|
|
@@ -120,38 +127,77 @@ jest.mock("../../../UI/Utils/API/API", () => {
|
|
|
120
127
|
type FormFieldEntry = {
|
|
121
128
|
field?: Record<string, unknown> | undefined;
|
|
122
129
|
title?: string | undefined;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
required?:
|
|
130
|
+
stepId?: string | undefined;
|
|
131
|
+
fieldType?: string | undefined;
|
|
132
|
+
required?:
|
|
133
|
+
| boolean
|
|
134
|
+
| ((values: Record<string, unknown>) => boolean)
|
|
135
|
+
| undefined;
|
|
126
136
|
description?: string | undefined;
|
|
137
|
+
placeholder?: string | undefined;
|
|
138
|
+
validation?: Record<string, unknown> | undefined;
|
|
139
|
+
showIf?: ((values: Record<string, unknown>) => boolean) | undefined;
|
|
140
|
+
doNotShowWhenCreating?: boolean | undefined;
|
|
141
|
+
cardSelectOptions?: Array<unknown> | undefined;
|
|
142
|
+
dropdownOptions?: Array<unknown> | undefined;
|
|
127
143
|
};
|
|
128
144
|
|
|
129
|
-
type
|
|
145
|
+
type ColumnEntry = {
|
|
146
|
+
field?: Record<string, unknown> | undefined;
|
|
147
|
+
title?: string | undefined;
|
|
148
|
+
type?: string | undefined;
|
|
149
|
+
getElement?: ((item: unknown) => ReactElement) | undefined;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
type CardButtonEntry = {
|
|
130
153
|
title: string;
|
|
154
|
+
icon?: IconProp | undefined;
|
|
155
|
+
buttonStyle?: ButtonStyleType | undefined;
|
|
131
156
|
disabled?: boolean | undefined;
|
|
132
157
|
tooltip?: string | undefined;
|
|
133
|
-
|
|
134
|
-
onClick: (
|
|
135
|
-
item: unknown,
|
|
136
|
-
onCompleteAction: () => void,
|
|
137
|
-
onError: (error: Error) => void,
|
|
138
|
-
) => void;
|
|
158
|
+
onClick: () => void;
|
|
139
159
|
};
|
|
140
160
|
|
|
141
161
|
type CapturedTableProps = {
|
|
162
|
+
id?: string | undefined;
|
|
163
|
+
name?: string | undefined;
|
|
164
|
+
userPreferencesKey?: string | undefined;
|
|
165
|
+
saveFilterProps?: { tableId?: string | undefined } | undefined;
|
|
142
166
|
isEditable?: boolean | undefined;
|
|
143
|
-
editButtonText?: string | undefined;
|
|
144
|
-
filters?: Array<{ field?: Record<string, unknown> | undefined }> | undefined;
|
|
145
|
-
selectMoreFields?: Record<string, unknown> | undefined;
|
|
146
|
-
isCreateable?: boolean | undefined;
|
|
147
167
|
isDeleteable?: boolean | undefined;
|
|
168
|
+
isCreateable?: boolean | undefined;
|
|
169
|
+
isViewable?: boolean | undefined;
|
|
170
|
+
viewButtonText?: string | undefined;
|
|
171
|
+
showViewIdButton?: boolean | undefined;
|
|
172
|
+
editButtonText?: string | undefined;
|
|
173
|
+
onViewPage?: ((item: unknown) => Promise<unknown>) | undefined;
|
|
174
|
+
actionButtons?: Array<{ title: string }> | undefined;
|
|
175
|
+
cardProps?:
|
|
176
|
+
| {
|
|
177
|
+
title?: string | undefined;
|
|
178
|
+
description?: string | undefined;
|
|
179
|
+
buttons?: Array<CardButtonEntry> | undefined;
|
|
180
|
+
}
|
|
181
|
+
| undefined;
|
|
148
182
|
query?: Record<string, unknown> | undefined;
|
|
183
|
+
selectMoreFields?: Record<string, unknown> | undefined;
|
|
149
184
|
formFields?: Array<FormFieldEntry> | undefined;
|
|
150
|
-
|
|
185
|
+
formSteps?: Array<unknown> | undefined;
|
|
151
186
|
onBeforeCreate?: ((item: unknown) => Promise<unknown>) | undefined;
|
|
152
|
-
|
|
153
|
-
|
|
187
|
+
onFetchSuccess?:
|
|
188
|
+
| ((data: Array<unknown>, totalCount: number) => void)
|
|
189
|
+
| undefined;
|
|
190
|
+
refreshToggle?: string | undefined;
|
|
191
|
+
noItemsMessage?: string | undefined;
|
|
192
|
+
showRefreshButton?: boolean | undefined;
|
|
154
193
|
searchableFields?: Array<string> | undefined;
|
|
194
|
+
filters?:
|
|
195
|
+
| Array<{
|
|
196
|
+
field?: Record<string, unknown> | undefined;
|
|
197
|
+
title?: string | undefined;
|
|
198
|
+
}>
|
|
199
|
+
| undefined;
|
|
200
|
+
columns?: Array<ColumnEntry> | undefined;
|
|
155
201
|
};
|
|
156
202
|
|
|
157
203
|
let capturedTableProps: CapturedTableProps | null = null;
|
|
@@ -166,37 +212,67 @@ jest.mock("../../../UI/Components/ModelTable/ModelTable", () => {
|
|
|
166
212
|
};
|
|
167
213
|
});
|
|
168
214
|
|
|
169
|
-
type
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
description?: string | undefined;
|
|
174
|
-
onClose?: (() => void) | undefined;
|
|
175
|
-
onSubmit?: ((data: Record<string, unknown>) => void) | undefined;
|
|
176
|
-
formProps: {
|
|
177
|
-
initialValues: Record<string, unknown>;
|
|
178
|
-
fields: Array<FormFieldEntry>;
|
|
179
|
-
};
|
|
215
|
+
type CapturedOAuthModalProps = {
|
|
216
|
+
workflowId?: ObjectID | undefined;
|
|
217
|
+
onClose: () => void;
|
|
218
|
+
onSuccess: (variable: WorkflowVariable) => void;
|
|
180
219
|
};
|
|
181
220
|
|
|
182
|
-
let
|
|
221
|
+
let capturedOAuthModalProps: CapturedOAuthModalProps | null = null;
|
|
183
222
|
|
|
184
|
-
jest.mock(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
223
|
+
jest.mock(
|
|
224
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/Workflow/CreateOAuthWorkflowVariableModal",
|
|
225
|
+
() => {
|
|
226
|
+
return {
|
|
227
|
+
__esModule: true,
|
|
228
|
+
default: (props: CapturedOAuthModalProps): ReactElement => {
|
|
229
|
+
capturedOAuthModalProps = props;
|
|
230
|
+
return <div data-testid="create-oauth-variable-modal" />;
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
},
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
type CapturedRefreshModalProps = {
|
|
237
|
+
variableName: string;
|
|
238
|
+
outcome: TokenRefreshOutcome | null;
|
|
239
|
+
onClose: () => void;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
let capturedRefreshModalProps: CapturedRefreshModalProps | null = null;
|
|
243
|
+
|
|
244
|
+
// Every outcome the modal was rendered with, in order - null is "pending".
|
|
245
|
+
let refreshModalOutcomes: Array<TokenRefreshOutcome | null> = [];
|
|
246
|
+
|
|
247
|
+
jest.mock(
|
|
248
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/Workflow/WorkflowVariableTokenRefreshModal",
|
|
249
|
+
() => {
|
|
250
|
+
return {
|
|
251
|
+
__esModule: true,
|
|
252
|
+
default: (props: CapturedRefreshModalProps): ReactElement => {
|
|
253
|
+
capturedRefreshModalProps = props;
|
|
254
|
+
refreshModalOutcomes.push(props.outcome);
|
|
255
|
+
return <div data-testid="token-refresh-modal" />;
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
);
|
|
193
260
|
|
|
194
261
|
import GlobalVariablesPage from "../../../../App/FeatureSet/Dashboard/src/Pages/Workflow/Variable";
|
|
195
262
|
import WorkflowVariablesPage from "../../../../App/FeatureSet/Dashboard/src/Pages/Workflow/View/Variable";
|
|
263
|
+
import { TokenRefreshOutcome } from "../../../../App/FeatureSet/Dashboard/src/Utils/Workflow/WorkflowVariableUtil";
|
|
196
264
|
import WorkflowVariable from "../../../Models/DatabaseModels/WorkflowVariable";
|
|
265
|
+
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
197
266
|
import IsNull from "../../../Types/BaseDatabase/IsNull";
|
|
267
|
+
import OneUptimeDate from "../../../Types/Date";
|
|
268
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
198
269
|
import ObjectID from "../../../Types/ObjectID";
|
|
199
270
|
import Permission from "../../../Types/Permission";
|
|
271
|
+
import {
|
|
272
|
+
OAuth2GrantType,
|
|
273
|
+
WorkflowVariableType,
|
|
274
|
+
} from "../../../Types/Workflow/WorkflowVariableOAuth";
|
|
275
|
+
import { ButtonStyleType } from "../../../UI/Components/Button/Button";
|
|
200
276
|
import PermissionGate from "../../../UI/Utils/PermissionGate";
|
|
201
277
|
|
|
202
278
|
const PROJECT_ID: ObjectID = new ObjectID(
|
|
@@ -212,8 +288,75 @@ const OTHER_VARIABLE_ID: ObjectID = new ObjectID(
|
|
|
212
288
|
"44444444-4444-4444-8444-444444444444",
|
|
213
289
|
);
|
|
214
290
|
|
|
291
|
+
const EXPIRES_AT_ISO: string = "2030-01-01T10:00:00.000Z";
|
|
292
|
+
|
|
293
|
+
const OAUTH_MENU_TITLE: string = "Create OAuth 2.0 Variable";
|
|
294
|
+
|
|
295
|
+
// The columns, and their fields, the list no longer shows.
|
|
296
|
+
const REMOVED_COLUMN_TITLES: Array<string> = ["Secret", "Token", "Created At"];
|
|
297
|
+
const REMOVED_COLUMN_FIELDS: Array<string> = [
|
|
298
|
+
"isSecret",
|
|
299
|
+
"oauthAccessTokenExpiresAt",
|
|
300
|
+
"oauthLastRefreshedAt",
|
|
301
|
+
"oauthLastRefreshError",
|
|
302
|
+
"oauthLastRefreshErrorAt",
|
|
303
|
+
"createdAt",
|
|
304
|
+
];
|
|
305
|
+
|
|
306
|
+
// The row actions the list used to offer, and no longer does.
|
|
307
|
+
const REMOVED_ROW_ACTIONS: Array<string> = [
|
|
308
|
+
"Show ID",
|
|
309
|
+
"Update Content",
|
|
310
|
+
"Update Credentials",
|
|
311
|
+
"Edit Details",
|
|
312
|
+
"Edit",
|
|
313
|
+
"Delete",
|
|
314
|
+
];
|
|
315
|
+
|
|
316
|
+
// Write-only or secret columns: no list request may ever select them.
|
|
317
|
+
const NEVER_SELECTED_FIELDS: Array<string> = [
|
|
318
|
+
"content",
|
|
319
|
+
"oauthClientSecret",
|
|
320
|
+
"oauthRefreshToken",
|
|
321
|
+
"oauthAccessToken",
|
|
322
|
+
];
|
|
323
|
+
|
|
215
324
|
type Page = "global" | "local";
|
|
216
325
|
|
|
326
|
+
type PageCase = {
|
|
327
|
+
page: Page;
|
|
328
|
+
workflowId: ObjectID | undefined;
|
|
329
|
+
cardTitle: string;
|
|
330
|
+
noItemsMessage: string;
|
|
331
|
+
reference: string;
|
|
332
|
+
otherReference: string;
|
|
333
|
+
viewRoute: string;
|
|
334
|
+
otherViewRoute: string;
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const PAGE_CASES: Array<PageCase> = [
|
|
338
|
+
{
|
|
339
|
+
page: "global",
|
|
340
|
+
workflowId: undefined,
|
|
341
|
+
cardTitle: "Global Variables",
|
|
342
|
+
noItemsMessage: "No global variables found.",
|
|
343
|
+
reference: "{{global.variables.THIS_NAME}}",
|
|
344
|
+
otherReference: "{{local.variables.THIS_NAME}}",
|
|
345
|
+
viewRoute: `/dashboard/${PROJECT_ID.toString()}/workflows/variables/${VARIABLE_ID.toString()}`,
|
|
346
|
+
otherViewRoute: `/dashboard/${PROJECT_ID.toString()}/workflows/variables/${OTHER_VARIABLE_ID.toString()}`,
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
page: "local",
|
|
350
|
+
workflowId: WORKFLOW_ID,
|
|
351
|
+
cardTitle: "Workflow Variables",
|
|
352
|
+
noItemsMessage: "No workflow variables found.",
|
|
353
|
+
reference: "{{local.variables.THIS_NAME}}",
|
|
354
|
+
otherReference: "{{global.variables.THIS_NAME}}",
|
|
355
|
+
viewRoute: `/dashboard/${PROJECT_ID.toString()}/workflows/${WORKFLOW_ID.toString()}/variables/${VARIABLE_ID.toString()}`,
|
|
356
|
+
otherViewRoute: `/dashboard/${PROJECT_ID.toString()}/workflows/${WORKFLOW_ID.toString()}/variables/${OTHER_VARIABLE_ID.toString()}`,
|
|
357
|
+
},
|
|
358
|
+
];
|
|
359
|
+
|
|
217
360
|
function renderPage(page: Page): void {
|
|
218
361
|
const props: Record<string, unknown> = {};
|
|
219
362
|
|
|
@@ -245,10 +388,22 @@ function table(): CapturedTableProps {
|
|
|
245
388
|
return capturedTableProps;
|
|
246
389
|
}
|
|
247
390
|
|
|
391
|
+
function fieldName(entry: {
|
|
392
|
+
field?: Record<string, unknown> | undefined;
|
|
393
|
+
}): string {
|
|
394
|
+
return Object.keys(entry.field || {})[0] || "";
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function formFieldNames(): Array<string> {
|
|
398
|
+
return (table().formFields || []).map((entry: FormFieldEntry) => {
|
|
399
|
+
return fieldName(entry);
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
248
403
|
function formField(name: string): FormFieldEntry {
|
|
249
404
|
const entry: FormFieldEntry | undefined = (table().formFields || []).find(
|
|
250
405
|
(field: FormFieldEntry) => {
|
|
251
|
-
return
|
|
406
|
+
return fieldName(field) === name;
|
|
252
407
|
},
|
|
253
408
|
);
|
|
254
409
|
|
|
@@ -259,510 +414,1237 @@ function formField(name: string): FormFieldEntry {
|
|
|
259
414
|
return entry;
|
|
260
415
|
}
|
|
261
416
|
|
|
262
|
-
function
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
417
|
+
function column(title: string): ColumnEntry {
|
|
418
|
+
const entry: ColumnEntry | undefined = (table().columns || []).find(
|
|
419
|
+
(candidate: ColumnEntry) => {
|
|
420
|
+
return candidate.title === title;
|
|
421
|
+
},
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
if (!entry) {
|
|
425
|
+
throw new Error(`The table has no ${title} column`);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return entry;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function moreMenuButtons(): Array<CardButtonEntry> {
|
|
432
|
+
return table().cardProps?.buttons || [];
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function oauthMenuButton(): CardButtonEntry {
|
|
436
|
+
const button: CardButtonEntry | undefined = moreMenuButtons().find(
|
|
437
|
+
(entry: CardButtonEntry) => {
|
|
438
|
+
return entry.title === OAUTH_MENU_TITLE;
|
|
439
|
+
},
|
|
440
|
+
);
|
|
268
441
|
|
|
269
442
|
if (!button) {
|
|
270
|
-
throw new Error(
|
|
443
|
+
throw new Error(`The More menu offers no "${OAUTH_MENU_TITLE}"`);
|
|
271
444
|
}
|
|
272
445
|
|
|
273
446
|
return button;
|
|
274
447
|
}
|
|
275
448
|
|
|
276
|
-
function
|
|
277
|
-
|
|
278
|
-
|
|
449
|
+
function isOAuthFormOpen(): boolean {
|
|
450
|
+
return screen.queryByTestId("create-oauth-variable-modal") !== null;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function oauthForm(): CapturedOAuthModalProps {
|
|
454
|
+
if (!isOAuthFormOpen() || !capturedOAuthModalProps) {
|
|
455
|
+
throw new Error("The OAuth 2.0 create form is not open");
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return capturedOAuthModalProps;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function isRefreshModalOpen(): boolean {
|
|
462
|
+
return screen.queryByTestId("token-refresh-modal") !== null;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function refreshModal(): CapturedRefreshModalProps {
|
|
466
|
+
if (!isRefreshModalOpen() || !capturedRefreshModalProps) {
|
|
467
|
+
throw new Error("The token refresh modal is not open");
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return capturedRefreshModalProps;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function openOAuthForm(): void {
|
|
474
|
+
act(() => {
|
|
475
|
+
oauthMenuButton().onClick();
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function staticVariable(): WorkflowVariable {
|
|
480
|
+
const variable: WorkflowVariable = new WorkflowVariable();
|
|
481
|
+
variable._id = VARIABLE_ID.toString();
|
|
482
|
+
variable.name = "PLAIN";
|
|
483
|
+
variable.variableType = WorkflowVariableType.Static;
|
|
484
|
+
return variable;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function oauthVariable(
|
|
488
|
+
overrides?: Partial<Record<string, unknown>> | undefined,
|
|
279
489
|
): WorkflowVariable {
|
|
280
490
|
const variable: WorkflowVariable = new WorkflowVariable();
|
|
491
|
+
variable._id = VARIABLE_ID.toString();
|
|
492
|
+
variable.name = "API_TOKEN";
|
|
493
|
+
variable.variableType = WorkflowVariableType.OAuth2;
|
|
494
|
+
variable.oauthGrantType = OAuth2GrantType.ClientCredentials;
|
|
281
495
|
|
|
282
|
-
|
|
283
|
-
variable
|
|
496
|
+
for (const [key, value] of Object.entries(overrides || {})) {
|
|
497
|
+
(variable as unknown as Record<string, unknown>)[key] = value;
|
|
284
498
|
}
|
|
285
499
|
|
|
286
|
-
variable.name = name || "AirflowToken";
|
|
287
500
|
return variable;
|
|
288
501
|
}
|
|
289
502
|
|
|
290
|
-
function
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
503
|
+
function refreshCall(callIndex: number = 0): {
|
|
504
|
+
url: string;
|
|
505
|
+
headers: unknown;
|
|
506
|
+
data: unknown;
|
|
507
|
+
} {
|
|
508
|
+
const call: { url: unknown; headers: unknown; data: unknown } = apiPost.mock
|
|
509
|
+
.calls[callIndex]![0] as { url: unknown; headers: unknown; data: unknown };
|
|
510
|
+
|
|
511
|
+
return { url: String(call.url), headers: call.headers, data: call.data };
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
type Deferred<T> = {
|
|
515
|
+
promise: Promise<T>;
|
|
516
|
+
resolve: (value: T) => void;
|
|
517
|
+
reject: (error: unknown) => void;
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
function createDeferred<T>(): Deferred<T> {
|
|
521
|
+
let resolve: (value: T) => void = (): void => {
|
|
522
|
+
// Replaced below, synchronously, by the promise executor.
|
|
523
|
+
};
|
|
524
|
+
let reject: (error: unknown) => void = (): void => {
|
|
525
|
+
// Replaced below, synchronously, by the promise executor.
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
const promise: Promise<T> = new Promise<T>(
|
|
529
|
+
(res: (value: T) => void, rej: (error: unknown) => void) => {
|
|
530
|
+
resolve = res;
|
|
531
|
+
reject = rej;
|
|
532
|
+
},
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
return { promise, resolve, reject };
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/*
|
|
539
|
+
* Fires the open OAuth form's onSuccess with the saved variable and lets
|
|
540
|
+
* whatever it starts settle. Waits for nothing in particular, so it also
|
|
541
|
+
* serves the cases where no token is asked for at all.
|
|
542
|
+
*/
|
|
543
|
+
async function saveOAuthVariable(variable: WorkflowVariable): Promise<void> {
|
|
544
|
+
await act(async () => {
|
|
545
|
+
oauthForm().onSuccess(variable);
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// A few more turns, so a request sent late would still be seen.
|
|
549
|
+
await act(async () => {
|
|
550
|
+
await Promise.resolve();
|
|
551
|
+
await Promise.resolve();
|
|
301
552
|
});
|
|
302
553
|
}
|
|
303
554
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
555
|
+
/*
|
|
556
|
+
* Opens the OAuth form from the More menu and fires its onSuccess with the
|
|
557
|
+
* saved variable, then waits for the token outcome to land in the modal.
|
|
558
|
+
*/
|
|
559
|
+
async function createOAuthVariable(variable: WorkflowVariable): Promise<void> {
|
|
560
|
+
openOAuthForm();
|
|
561
|
+
|
|
562
|
+
await saveOAuthVariable(variable);
|
|
308
563
|
|
|
309
|
-
|
|
564
|
+
await waitFor(() => {
|
|
565
|
+
expect(capturedRefreshModalProps?.outcome).toBeTruthy();
|
|
566
|
+
});
|
|
310
567
|
}
|
|
311
568
|
|
|
312
|
-
|
|
569
|
+
type RoleCase = {
|
|
570
|
+
label: string;
|
|
571
|
+
permissions: Array<Permission>;
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
/*
|
|
575
|
+
* Roles on WorkflowVariable's create list but not its update list. The
|
|
576
|
+
* refresh route writes the token to the variable, so it checks for update and
|
|
577
|
+
* would refuse every one of these.
|
|
578
|
+
*/
|
|
579
|
+
const CREATE_ONLY_ROLES: Array<RoleCase> = [
|
|
580
|
+
{
|
|
581
|
+
label: "Create and Read Workflow Variables",
|
|
582
|
+
permissions: [
|
|
583
|
+
Permission.CreateWorkflowVariable,
|
|
584
|
+
Permission.ReadWorkflowVariable,
|
|
585
|
+
],
|
|
586
|
+
},
|
|
587
|
+
{ label: "Project Member", permissions: [Permission.ProjectMember] },
|
|
588
|
+
{ label: "Workflow Admin", permissions: [Permission.WorkflowAdmin] },
|
|
589
|
+
{ label: "Workflow Member", permissions: [Permission.WorkflowMember] },
|
|
590
|
+
/*
|
|
591
|
+
* A workflow variable is not an operational resource, so the Edit All
|
|
592
|
+
* wildcard does not widen its update list - here or on the server.
|
|
593
|
+
*/
|
|
594
|
+
{
|
|
595
|
+
label: "Create Workflow Variables with Edit All Operational Resources",
|
|
596
|
+
permissions: [
|
|
597
|
+
Permission.CreateWorkflowVariable,
|
|
598
|
+
Permission.EditAllOperationalResources,
|
|
599
|
+
],
|
|
600
|
+
},
|
|
601
|
+
];
|
|
602
|
+
|
|
603
|
+
// Roles on both lists: these may create the variable and fetch its token.
|
|
604
|
+
const CREATE_AND_UPDATE_ROLES: Array<RoleCase> = [
|
|
605
|
+
{ label: "Project Admin", permissions: [Permission.ProjectAdmin] },
|
|
606
|
+
{ label: "Project Owner", permissions: [Permission.ProjectOwner] },
|
|
607
|
+
{
|
|
608
|
+
label: "Create and Edit Workflow Variables",
|
|
609
|
+
permissions: [
|
|
610
|
+
Permission.CreateWorkflowVariable,
|
|
611
|
+
Permission.EditWorkflowVariable,
|
|
612
|
+
],
|
|
613
|
+
},
|
|
614
|
+
];
|
|
615
|
+
|
|
616
|
+
let clockTick: number = 0;
|
|
617
|
+
let currentDateSpy: SpyInstance<() => Date> | null = null;
|
|
313
618
|
|
|
314
619
|
beforeEach(() => {
|
|
315
620
|
capturedTableProps = null;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
621
|
+
capturedOAuthModalProps = null;
|
|
622
|
+
capturedRefreshModalProps = null;
|
|
623
|
+
refreshModalOutcomes = [];
|
|
624
|
+
apiPost.mockReset();
|
|
625
|
+
apiPost.mockResolvedValue({
|
|
626
|
+
data: { oauthAccessTokenExpiresAt: EXPIRES_AT_ISO },
|
|
627
|
+
});
|
|
628
|
+
getLastParamAsObjectID.mockReset();
|
|
629
|
+
getLastParamAsObjectID.mockReturnValue(WORKFLOW_ID);
|
|
319
630
|
permissionsForTest = [Permission.ProjectAdmin];
|
|
631
|
+
isMasterAdminForTest = false;
|
|
320
632
|
PermissionGate.clearPermissionPropsCache();
|
|
633
|
+
|
|
634
|
+
/*
|
|
635
|
+
* refreshToggle is an ISO timestamp. Two bumps inside the same millisecond
|
|
636
|
+
* would be the same string and read as "not refreshed", so every read of
|
|
637
|
+
* the clock moves it on by a second.
|
|
638
|
+
*/
|
|
639
|
+
clockTick = 0;
|
|
640
|
+
currentDateSpy = jest
|
|
641
|
+
.spyOn(OneUptimeDate, "getCurrentDate")
|
|
642
|
+
.mockImplementation((): Date => {
|
|
643
|
+
clockTick++;
|
|
644
|
+
return new Date(Date.UTC(2026, 8, 23, 12, 0, 0) + clockTick * 1000);
|
|
645
|
+
});
|
|
321
646
|
});
|
|
322
647
|
|
|
323
648
|
afterEach(() => {
|
|
324
649
|
cleanup();
|
|
650
|
+
currentDateSpy?.mockRestore();
|
|
651
|
+
currentDateSpy = null;
|
|
325
652
|
});
|
|
326
653
|
|
|
327
|
-
describe
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
* about making this safe rather than about making it true.
|
|
331
|
-
*/
|
|
332
|
-
test("offers Edit", () => {
|
|
333
|
-
renderPage(page);
|
|
654
|
+
describe("the pages", () => {
|
|
655
|
+
test("the global page lists the project's variables, with no workflow", () => {
|
|
656
|
+
renderPage("global");
|
|
334
657
|
|
|
335
|
-
expect(table().
|
|
336
|
-
expect(
|
|
337
|
-
expect(table().isDeleteable).toBe(true);
|
|
658
|
+
expect(table().query?.["workflowId"]).toBeInstanceOf(IsNull);
|
|
659
|
+
expect(getLastParamAsObjectID).not.toHaveBeenCalled();
|
|
338
660
|
});
|
|
339
661
|
|
|
340
|
-
|
|
341
|
-
|
|
662
|
+
// /dashboard/:projectId/workflows/:id/variables - the id is one from the end.
|
|
663
|
+
test("the workflow page reads the workflow id from the URL", () => {
|
|
664
|
+
renderPage("local");
|
|
342
665
|
|
|
343
|
-
expect(
|
|
344
|
-
|
|
345
|
-
expect(formField("content").required).toBe(true);
|
|
346
|
-
expect(formField("content").doNotShowWhenCreating).toBeFalsy();
|
|
666
|
+
expect(getLastParamAsObjectID).toHaveBeenCalledWith(1);
|
|
667
|
+
expect(table().query?.["workflowId"]).toBe(WORKFLOW_ID);
|
|
347
668
|
});
|
|
669
|
+
});
|
|
348
670
|
|
|
349
|
-
|
|
350
|
-
|
|
671
|
+
describe.each(PAGE_CASES)("the $page variables list", (pageCase: PageCase) => {
|
|
672
|
+
describe("columns", () => {
|
|
673
|
+
test("are exactly Name, Type and Description", () => {
|
|
674
|
+
renderPage(pageCase.page);
|
|
675
|
+
|
|
676
|
+
expect(
|
|
677
|
+
(table().columns || []).map((entry: ColumnEntry) => {
|
|
678
|
+
return entry.title;
|
|
679
|
+
}),
|
|
680
|
+
).toEqual(["Name", "Type", "Description"]);
|
|
681
|
+
|
|
682
|
+
expect(
|
|
683
|
+
(table().columns || []).map((entry: ColumnEntry) => {
|
|
684
|
+
return fieldName(entry);
|
|
685
|
+
}),
|
|
686
|
+
).toEqual(["name", "variableType", "description"]);
|
|
687
|
+
});
|
|
351
688
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
});
|
|
689
|
+
// Ask 1, stated as a test.
|
|
690
|
+
test("no longer include Secret, Token or Created At", () => {
|
|
691
|
+
renderPage(pageCase.page);
|
|
356
692
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
*/
|
|
363
|
-
test("the secret toggle is actually updatable at the model level", () => {
|
|
364
|
-
const variable: WorkflowVariable = new WorkflowVariable();
|
|
365
|
-
|
|
366
|
-
expect(
|
|
367
|
-
variable.getColumnAccessControlForAllColumns()["isSecret"]?.update,
|
|
368
|
-
).toEqual(
|
|
369
|
-
expect.arrayContaining([
|
|
370
|
-
Permission.ProjectOwner,
|
|
371
|
-
Permission.ProjectAdmin,
|
|
372
|
-
Permission.EditWorkflowVariable,
|
|
373
|
-
]),
|
|
374
|
-
);
|
|
693
|
+
for (const entry of table().columns || []) {
|
|
694
|
+
expect(REMOVED_COLUMN_TITLES).not.toContain(entry.title);
|
|
695
|
+
expect(REMOVED_COLUMN_FIELDS).not.toContain(fieldName(entry));
|
|
696
|
+
}
|
|
697
|
+
});
|
|
375
698
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
variable.getColumnAccessControlForAllColumns()["content"]?.read,
|
|
379
|
-
).toEqual([]);
|
|
380
|
-
});
|
|
699
|
+
test("a static variable's Type reads Static", () => {
|
|
700
|
+
renderPage(pageCase.page);
|
|
381
701
|
|
|
382
|
-
|
|
383
|
-
* "Edit" is the verb a user reaches for when they want to change a variable's
|
|
384
|
-
* value, and it is the one button that cannot. Naming it for what it edits is
|
|
385
|
-
* what makes the neighbouring Update Content action findable.
|
|
386
|
-
*/
|
|
387
|
-
test("names the Edit button for what it actually edits", () => {
|
|
388
|
-
renderPage(page);
|
|
702
|
+
render(column("Type").getElement!(staticVariable()));
|
|
389
703
|
|
|
390
|
-
|
|
391
|
-
|
|
704
|
+
expect(screen.getByText("Static")).toBeInTheDocument();
|
|
705
|
+
expect(screen.queryByText("OAuth 2.0")).not.toBeInTheDocument();
|
|
706
|
+
});
|
|
392
707
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
708
|
+
// Rows saved before OAuth 2.0 variables existed have no type at all.
|
|
709
|
+
test("a variable with no type reads Static", () => {
|
|
710
|
+
renderPage(pageCase.page);
|
|
711
|
+
|
|
712
|
+
const variable: WorkflowVariable = new WorkflowVariable();
|
|
713
|
+
variable._id = VARIABLE_ID.toString();
|
|
714
|
+
variable.name = "LEGACY";
|
|
715
|
+
|
|
716
|
+
render(column("Type").getElement!(variable));
|
|
717
|
+
|
|
718
|
+
expect(screen.getByText("Static")).toBeInTheDocument();
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
test("an OAuth 2.0 variable's Type reads OAuth 2.0, with its grant type underneath", () => {
|
|
722
|
+
renderPage(pageCase.page);
|
|
723
|
+
|
|
724
|
+
render(column("Type").getElement!(oauthVariable()));
|
|
725
|
+
|
|
726
|
+
expect(screen.getByText("OAuth 2.0")).toBeInTheDocument();
|
|
727
|
+
expect(screen.getByText("Client Credentials")).toBeInTheDocument();
|
|
728
|
+
expect(screen.queryByText("Static")).not.toBeInTheDocument();
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
test("names the Refresh Token grant too", () => {
|
|
732
|
+
renderPage(pageCase.page);
|
|
401
733
|
|
|
402
|
-
|
|
734
|
+
render(
|
|
735
|
+
column("Type").getElement!(
|
|
736
|
+
oauthVariable({ oauthGrantType: OAuth2GrantType.RefreshToken }),
|
|
737
|
+
),
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
expect(screen.getByText("OAuth 2.0")).toBeInTheDocument();
|
|
741
|
+
expect(screen.getByText("Refresh Token")).toBeInTheDocument();
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
test("an OAuth 2.0 variable with no grant type reads OAuth 2.0 alone", () => {
|
|
745
|
+
renderPage(pageCase.page);
|
|
403
746
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
747
|
+
const cell: ReturnType<typeof render> = render(
|
|
748
|
+
column("Type").getElement!(
|
|
749
|
+
oauthVariable({ oauthGrantType: undefined }),
|
|
750
|
+
),
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
expect(cell.container.textContent).toBe("OAuth 2.0");
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
test("filters and searches only on what the list shows", () => {
|
|
757
|
+
renderPage(pageCase.page);
|
|
758
|
+
|
|
759
|
+
expect(
|
|
760
|
+
(table().filters || []).map(
|
|
761
|
+
(entry: { field?: Record<string, unknown> | undefined }) => {
|
|
762
|
+
return fieldName(entry);
|
|
763
|
+
},
|
|
764
|
+
),
|
|
765
|
+
).toEqual(["name", "description"]);
|
|
766
|
+
expect(table().searchableFields).toEqual(["name", "description"]);
|
|
767
|
+
});
|
|
407
768
|
});
|
|
408
769
|
|
|
409
|
-
|
|
410
|
-
|
|
770
|
+
describe("row actions", () => {
|
|
771
|
+
// Ask 2, stated as a test.
|
|
772
|
+
test("are a single View button", () => {
|
|
773
|
+
renderPage(pageCase.page);
|
|
774
|
+
|
|
775
|
+
expect(table().isViewable).toBe(true);
|
|
776
|
+
expect(table().viewButtonText).toBe("View");
|
|
777
|
+
expect(table().showViewIdButton).toBeFalsy();
|
|
778
|
+
expect(table().isEditable).toBe(false);
|
|
779
|
+
expect(table().isDeleteable).toBe(false);
|
|
780
|
+
expect(table().actionButtons || []).toEqual([]);
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
test("no longer offer Show ID, Update Content, Update Credentials, Edit Details or Delete", () => {
|
|
784
|
+
renderPage(pageCase.page);
|
|
411
785
|
|
|
412
|
-
|
|
786
|
+
const titles: Array<string> = (table().actionButtons || []).map(
|
|
787
|
+
(entry: { title: string }) => {
|
|
788
|
+
return entry.title;
|
|
789
|
+
},
|
|
790
|
+
);
|
|
413
791
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
792
|
+
for (const removed of REMOVED_ROW_ACTIONS) {
|
|
793
|
+
expect(titles).not.toContain(removed);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// No Edit button left over under a new name, either.
|
|
797
|
+
expect(table().editButtonText).toBeUndefined();
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
test("View opens the variable's own page", async () => {
|
|
801
|
+
renderPage(pageCase.page);
|
|
802
|
+
|
|
803
|
+
const route: unknown = await table().onViewPage!(staticVariable());
|
|
804
|
+
|
|
805
|
+
expect(String(route)).toBe(pageCase.viewRoute);
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
test("View opens an OAuth 2.0 variable's page the same way", async () => {
|
|
809
|
+
renderPage(pageCase.page);
|
|
810
|
+
|
|
811
|
+
const route: unknown = await table().onViewPage!(oauthVariable());
|
|
812
|
+
|
|
813
|
+
expect(String(route)).toBe(pageCase.viewRoute);
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
test("View opens the page of the row it was pressed on", async () => {
|
|
817
|
+
renderPage(pageCase.page);
|
|
818
|
+
|
|
819
|
+
const variable: WorkflowVariable = staticVariable();
|
|
820
|
+
variable._id = OTHER_VARIABLE_ID.toString();
|
|
821
|
+
|
|
822
|
+
const route: unknown = await table().onViewPage!(variable);
|
|
823
|
+
|
|
824
|
+
expect(String(route)).toBe(pageCase.otherViewRoute);
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
// A route with ":id" still in it would open a page that cannot load.
|
|
828
|
+
test("View refuses a row without an id rather than opening a broken page", async () => {
|
|
829
|
+
renderPage(pageCase.page);
|
|
830
|
+
|
|
831
|
+
const variable: WorkflowVariable = new WorkflowVariable();
|
|
832
|
+
variable.name = "NO_ID";
|
|
833
|
+
|
|
834
|
+
await expect(table().onViewPage!(variable)).rejects.toThrow(
|
|
835
|
+
"This variable has no id",
|
|
836
|
+
);
|
|
837
|
+
});
|
|
419
838
|
});
|
|
420
839
|
|
|
421
|
-
describe("the
|
|
422
|
-
test("is offered,
|
|
423
|
-
renderPage(page);
|
|
840
|
+
describe("the Create form", () => {
|
|
841
|
+
test("is still offered, on a card named for the page", () => {
|
|
842
|
+
renderPage(pageCase.page);
|
|
424
843
|
|
|
425
|
-
expect(
|
|
844
|
+
expect(table().isCreateable).toBe(true);
|
|
845
|
+
expect(table().cardProps?.title).toBe(pageCase.cardTitle);
|
|
846
|
+
expect(table().noItemsMessage).toBe(pageCase.noItemsMessage);
|
|
847
|
+
expect(table().name).toBe("Workflows");
|
|
848
|
+
expect(table().showRefreshButton).toBe(true);
|
|
849
|
+
});
|
|
426
850
|
|
|
427
|
-
|
|
851
|
+
test("asks only for a static variable's name, description, content and secret toggle", () => {
|
|
852
|
+
renderPage(pageCase.page);
|
|
428
853
|
|
|
429
|
-
expect(
|
|
430
|
-
|
|
431
|
-
|
|
854
|
+
expect(formFieldNames()).toEqual([
|
|
855
|
+
"name",
|
|
856
|
+
"description",
|
|
432
857
|
"content",
|
|
858
|
+
"isSecret",
|
|
433
859
|
]);
|
|
434
|
-
expect(modal().description).toContain("AirflowToken");
|
|
435
860
|
});
|
|
436
861
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
862
|
+
// Ask 3, stated as a test.
|
|
863
|
+
test("never asks which kind of variable to create", () => {
|
|
864
|
+
renderPage(pageCase.page);
|
|
440
865
|
|
|
441
|
-
|
|
442
|
-
|
|
866
|
+
expect(formFieldNames()).not.toContain("variableType");
|
|
867
|
+
expect(table().formSteps || []).toEqual([]);
|
|
868
|
+
|
|
869
|
+
for (const entry of table().formFields || []) {
|
|
870
|
+
expect(entry.fieldType).not.toBe("CardSelect");
|
|
871
|
+
expect(entry.cardSelectOptions).toBeUndefined();
|
|
872
|
+
// Nothing on the form hides or shows by a type the form never sets.
|
|
873
|
+
expect(entry.showIf).toBeUndefined();
|
|
874
|
+
expect(entry.stepId).toBeUndefined();
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
test("carries none of the OAuth 2.0 settings", () => {
|
|
879
|
+
renderPage(pageCase.page);
|
|
880
|
+
|
|
881
|
+
for (const name of formFieldNames()) {
|
|
882
|
+
expect(name.startsWith("oauth")).toBe(false);
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
test("requires the content, and says it cannot be viewed again", () => {
|
|
887
|
+
renderPage(pageCase.page);
|
|
888
|
+
|
|
889
|
+
expect(formField("content").required).toBe(true);
|
|
890
|
+
expect(formField("content").fieldType).toBe("LongText");
|
|
891
|
+
expect(formField("content").doNotShowWhenCreating).toBeFalsy();
|
|
892
|
+
expect(formField("content").description).toContain(
|
|
893
|
+
"cannot be viewed once saved",
|
|
894
|
+
);
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
test("offers the Secret toggle, optional, and describes redaction rather than encryption", () => {
|
|
898
|
+
renderPage(pageCase.page);
|
|
899
|
+
|
|
900
|
+
const secret: FormFieldEntry = formField("isSecret");
|
|
901
|
+
|
|
902
|
+
expect(secret.fieldType).toBe("Boolean");
|
|
903
|
+
expect(secret.required).toBe(false);
|
|
904
|
+
expect(secret.description).toContain("[REDACTED]");
|
|
905
|
+
expect(secret.description).toContain("cannot be turned off again");
|
|
906
|
+
expect(secret.description).not.toMatch(/encrypt/i);
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
test("leaves the description optional", () => {
|
|
910
|
+
renderPage(pageCase.page);
|
|
911
|
+
|
|
912
|
+
expect(formField("description").required).toBe(false);
|
|
913
|
+
expect(formField("description").fieldType).toBe("LongText");
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
test("validates the name", () => {
|
|
917
|
+
renderPage(pageCase.page);
|
|
918
|
+
|
|
919
|
+
const name: FormFieldEntry = formField("name");
|
|
920
|
+
|
|
921
|
+
expect(name.required).toBe(true);
|
|
922
|
+
expect(name.fieldType).toBe("Text");
|
|
923
|
+
expect(name.validation).toEqual({
|
|
924
|
+
minLength: 2,
|
|
925
|
+
noSpaces: true,
|
|
926
|
+
noSpecialCharacters: true,
|
|
443
927
|
});
|
|
928
|
+
});
|
|
444
929
|
|
|
445
|
-
|
|
930
|
+
/*
|
|
931
|
+
* Nothing links a workflow to the variable row it names, so renaming a
|
|
932
|
+
* variable silently breaks every workflow using the old name. The form is
|
|
933
|
+
* the one place that can say so, in the page's own reference syntax.
|
|
934
|
+
*/
|
|
935
|
+
test("shows the page's reference syntax, and warns that renaming breaks it", () => {
|
|
936
|
+
renderPage(pageCase.page);
|
|
446
937
|
|
|
447
|
-
const
|
|
448
|
-
.calls[0]?.[0] as Record<string, unknown>;
|
|
938
|
+
const description: string = formField("name").description || "";
|
|
449
939
|
|
|
450
|
-
expect(
|
|
451
|
-
expect(
|
|
452
|
-
expect(
|
|
940
|
+
expect(description).toContain(pageCase.reference);
|
|
941
|
+
expect(description).not.toContain(pageCase.otherReference);
|
|
942
|
+
expect(description).toContain(
|
|
943
|
+
"Renaming it does not update workflows that already refer to the old name",
|
|
944
|
+
);
|
|
453
945
|
});
|
|
454
946
|
|
|
455
|
-
test("
|
|
456
|
-
renderPage(page);
|
|
457
|
-
openUpdateContentModal();
|
|
947
|
+
test("stamps Static on what it creates", async () => {
|
|
948
|
+
renderPage(pageCase.page);
|
|
458
949
|
|
|
459
|
-
|
|
950
|
+
const created: WorkflowVariable = (await table().onBeforeCreate!(
|
|
951
|
+
new WorkflowVariable(),
|
|
952
|
+
)) as WorkflowVariable;
|
|
460
953
|
|
|
461
|
-
|
|
462
|
-
|
|
954
|
+
expect(created.variableType).toBe(WorkflowVariableType.Static);
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
// The form cannot make anything else, whatever arrives in its values.
|
|
958
|
+
test("stamps Static even over a type the values claim to be OAuth 2.0", async () => {
|
|
959
|
+
renderPage(pageCase.page);
|
|
960
|
+
|
|
961
|
+
const item: WorkflowVariable = new WorkflowVariable();
|
|
962
|
+
item.variableType = WorkflowVariableType.OAuth2;
|
|
963
|
+
|
|
964
|
+
const created: WorkflowVariable = (await table().onBeforeCreate!(
|
|
965
|
+
item,
|
|
966
|
+
)) as WorkflowVariable;
|
|
967
|
+
|
|
968
|
+
expect(created.variableType).toBe(WorkflowVariableType.Static);
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
test(
|
|
972
|
+
pageCase.page === "global"
|
|
973
|
+
? "leaves the workflow unset, so the variable is global"
|
|
974
|
+
: "stamps the workflow, so the variable is local to it",
|
|
975
|
+
async () => {
|
|
976
|
+
renderPage(pageCase.page);
|
|
977
|
+
|
|
978
|
+
const created: WorkflowVariable = (await table().onBeforeCreate!(
|
|
979
|
+
new WorkflowVariable(),
|
|
980
|
+
)) as WorkflowVariable;
|
|
981
|
+
|
|
982
|
+
if (pageCase.workflowId) {
|
|
983
|
+
expect(created.workflowId?.toString()).toBe(
|
|
984
|
+
pageCase.workflowId.toString(),
|
|
985
|
+
);
|
|
986
|
+
} else {
|
|
987
|
+
expect(created.workflowId).toBeUndefined();
|
|
988
|
+
}
|
|
989
|
+
},
|
|
990
|
+
);
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
describe("what the list reads", () => {
|
|
994
|
+
test("is scoped to the page's variables in the current project", () => {
|
|
995
|
+
renderPage(pageCase.page);
|
|
996
|
+
|
|
997
|
+
if (pageCase.workflowId) {
|
|
998
|
+
expect(table().query?.["workflowId"]).toBe(pageCase.workflowId);
|
|
999
|
+
} else {
|
|
1000
|
+
expect(table().query?.["workflowId"]).toBeInstanceOf(IsNull);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
expect(table().query?.["projectId"]).toBe(PROJECT_ID);
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
// The Type column needs the type and grant type; nothing else rides along.
|
|
1007
|
+
test("selects the type and the grant type, and nothing more", () => {
|
|
1008
|
+
renderPage(pageCase.page);
|
|
1009
|
+
|
|
1010
|
+
expect(table().selectMoreFields).toEqual({
|
|
1011
|
+
variableType: true,
|
|
1012
|
+
oauthGrantType: true,
|
|
463
1013
|
});
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
test("never selects content, a credential or a token", () => {
|
|
1017
|
+
renderPage(pageCase.page);
|
|
1018
|
+
|
|
1019
|
+
const select: Array<string> = Object.keys(table().selectMoreFields || {});
|
|
1020
|
+
|
|
1021
|
+
for (const name of NEVER_SELECTED_FIELDS) {
|
|
1022
|
+
expect(select).not.toContain(name);
|
|
464
1023
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
1024
|
+
for (const entry of table().columns || []) {
|
|
1025
|
+
expect(fieldName(entry)).not.toBe(name);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
for (const filter of table().filters || []) {
|
|
1029
|
+
expect(fieldName(filter)).not.toBe(name);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
expect(table().searchableFields || []).not.toContain(name);
|
|
1033
|
+
}
|
|
471
1034
|
});
|
|
472
1035
|
|
|
473
1036
|
/*
|
|
474
|
-
* The
|
|
475
|
-
*
|
|
476
|
-
* credential that is the difference between a rotation and a silent
|
|
477
|
-
* non-rotation.
|
|
1037
|
+
* The two lists keep their own saved filters and column preferences, so
|
|
1038
|
+
* the ids must differ.
|
|
478
1039
|
*/
|
|
479
|
-
test("
|
|
480
|
-
renderPage(page);
|
|
481
|
-
|
|
1040
|
+
test("keeps its table and filter ids apart from the other page's", () => {
|
|
1041
|
+
renderPage(pageCase.page);
|
|
1042
|
+
|
|
1043
|
+
if (pageCase.workflowId) {
|
|
1044
|
+
expect(table().id).toBe("workflow-variables-table");
|
|
1045
|
+
expect(table().saveFilterProps?.tableId).toBe(
|
|
1046
|
+
"workflow-view-variables-table",
|
|
1047
|
+
);
|
|
1048
|
+
} else {
|
|
1049
|
+
expect(table().id).toBe("global-workflow-variables-table");
|
|
1050
|
+
expect(table().saveFilterProps?.tableId).toBe(
|
|
1051
|
+
"workflow-variables-table",
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
482
1056
|
|
|
483
|
-
|
|
1057
|
+
describe("the More menu", () => {
|
|
1058
|
+
test("holds exactly one entry: Create OAuth 2.0 Variable", () => {
|
|
1059
|
+
renderPage(pageCase.page);
|
|
484
1060
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
1061
|
+
expect(
|
|
1062
|
+
moreMenuButtons().map((entry: CardButtonEntry) => {
|
|
1063
|
+
return entry.title;
|
|
1064
|
+
}),
|
|
1065
|
+
).toEqual([OAUTH_MENU_TITLE]);
|
|
1066
|
+
});
|
|
488
1067
|
|
|
489
|
-
|
|
490
|
-
|
|
1068
|
+
/*
|
|
1069
|
+
* BaseModelTable puts one button beside the search - the NORMAL button
|
|
1070
|
+
* with the Add icon, or failing that the first NORMAL or PRIMARY one - and
|
|
1071
|
+
* everything else in the More (⋯) menu. An OUTLINE button with its own
|
|
1072
|
+
* icon can never be picked, so this entry stays in the menu even for
|
|
1073
|
+
* somebody the Create button is hidden from.
|
|
1074
|
+
*/
|
|
1075
|
+
test("is an outline button, so the table never promotes it beside the search", () => {
|
|
1076
|
+
renderPage(pageCase.page);
|
|
1077
|
+
|
|
1078
|
+
const button: CardButtonEntry = oauthMenuButton();
|
|
1079
|
+
|
|
1080
|
+
expect(button.buttonStyle).toBe(ButtonStyleType.OUTLINE);
|
|
1081
|
+
expect(button.buttonStyle).not.toBe(ButtonStyleType.NORMAL);
|
|
1082
|
+
expect(button.buttonStyle).not.toBe(ButtonStyleType.PRIMARY);
|
|
1083
|
+
expect(button.icon).toBe(IconProp.Key);
|
|
1084
|
+
expect(button.icon).not.toBe(IconProp.Add);
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
test("the card tells people where to find it", () => {
|
|
1088
|
+
renderPage(pageCase.page);
|
|
1089
|
+
|
|
1090
|
+
expect(table().cardProps?.description).toContain("More menu");
|
|
1091
|
+
expect(table().cardProps?.description).toContain("OAuth 2.0");
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1094
|
+
test("is enabled for a project admin, and says what an OAuth variable is", () => {
|
|
1095
|
+
permissionsForTest = [Permission.ProjectAdmin];
|
|
1096
|
+
|
|
1097
|
+
renderPage(pageCase.page);
|
|
1098
|
+
|
|
1099
|
+
expect(oauthMenuButton().disabled).toBe(false);
|
|
1100
|
+
expect(oauthMenuButton().tooltip).toContain("access token");
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
// The gate follows the model's create list, not just the admin roles.
|
|
1104
|
+
test("is enabled for somebody who may only create workflow variables", () => {
|
|
1105
|
+
permissionsForTest = [Permission.CreateWorkflowVariable];
|
|
1106
|
+
|
|
1107
|
+
renderPage(pageCase.page);
|
|
1108
|
+
|
|
1109
|
+
expect(oauthMenuButton().disabled).toBe(false);
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
test("is enabled for a master admin, even before the permission snapshot arrives", () => {
|
|
1113
|
+
permissionsForTest = [];
|
|
1114
|
+
isMasterAdminForTest = true;
|
|
1115
|
+
|
|
1116
|
+
renderPage(pageCase.page);
|
|
1117
|
+
|
|
1118
|
+
expect(oauthMenuButton().disabled).toBe(false);
|
|
491
1119
|
});
|
|
492
1120
|
|
|
493
1121
|
/*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
* empty - and the person who has just pasted a long token has to go and find
|
|
497
|
-
* it again, which is exactly the friction this whole change is about.
|
|
1122
|
+
* Locked, with the reason, rather than a form that 403s after somebody
|
|
1123
|
+
* has pasted a client secret into it.
|
|
498
1124
|
*/
|
|
499
|
-
test("
|
|
500
|
-
|
|
501
|
-
openUpdateContentModal();
|
|
1125
|
+
test("is locked for a viewer, with a tooltip naming the missing permission", () => {
|
|
1126
|
+
permissionsForTest = [Permission.Viewer];
|
|
502
1127
|
|
|
503
|
-
|
|
1128
|
+
renderPage(pageCase.page);
|
|
504
1129
|
|
|
505
|
-
|
|
1130
|
+
const button: CardButtonEntry = oauthMenuButton();
|
|
506
1131
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
1132
|
+
expect(button.disabled).toBe(true);
|
|
1133
|
+
expect(button.tooltip).toContain(
|
|
1134
|
+
"You do not have permission to create this Workflow Variable",
|
|
1135
|
+
);
|
|
1136
|
+
expect(button.tooltip).toContain("Create Workflow Variables");
|
|
1137
|
+
});
|
|
510
1138
|
|
|
511
|
-
|
|
512
|
-
|
|
1139
|
+
test("does nothing when pressed while locked", () => {
|
|
1140
|
+
permissionsForTest = [Permission.Viewer];
|
|
1141
|
+
|
|
1142
|
+
renderPage(pageCase.page);
|
|
1143
|
+
|
|
1144
|
+
act(() => {
|
|
1145
|
+
oauthMenuButton().onClick();
|
|
513
1146
|
});
|
|
1147
|
+
|
|
1148
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1149
|
+
expect(capturedOAuthModalProps).toBeNull();
|
|
514
1150
|
});
|
|
515
1151
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
1152
|
+
/*
|
|
1153
|
+
* An empty snapshot is "not loaded yet", not "not allowed": a disabled
|
|
1154
|
+
* button there would blame somebody who may well hold the permission.
|
|
1155
|
+
*/
|
|
1156
|
+
test("is hidden, not locked, while the permission snapshot is still empty", () => {
|
|
1157
|
+
permissionsForTest = [];
|
|
519
1158
|
|
|
520
|
-
|
|
1159
|
+
renderPage(pageCase.page);
|
|
521
1160
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
});
|
|
1161
|
+
expect(moreMenuButtons()).toEqual([]);
|
|
1162
|
+
});
|
|
525
1163
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
1164
|
+
/*
|
|
1165
|
+
* The snapshot rides in on an API response header. Without a re-render
|
|
1166
|
+
* after the first fetch, the entry would stay hidden for the life of the
|
|
1167
|
+
* page after a fresh sign-in.
|
|
1168
|
+
*/
|
|
1169
|
+
test("appears once the list's first fetch brings the permission snapshot in", () => {
|
|
1170
|
+
permissionsForTest = [];
|
|
1171
|
+
|
|
1172
|
+
renderPage(pageCase.page);
|
|
1173
|
+
|
|
1174
|
+
expect(moreMenuButtons()).toEqual([]);
|
|
1175
|
+
|
|
1176
|
+
permissionsForTest = [Permission.ProjectAdmin];
|
|
529
1177
|
|
|
530
1178
|
act(() => {
|
|
531
|
-
|
|
1179
|
+
table().onFetchSuccess!([], 0);
|
|
532
1180
|
});
|
|
533
1181
|
|
|
534
|
-
|
|
1182
|
+
expect(oauthMenuButton().disabled).toBe(false);
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
test("opens the OAuth 2.0 create form for this page's variables", () => {
|
|
1186
|
+
renderPage(pageCase.page);
|
|
535
1187
|
|
|
536
|
-
expect(
|
|
1188
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1189
|
+
|
|
1190
|
+
openOAuthForm();
|
|
1191
|
+
|
|
1192
|
+
expect(isOAuthFormOpen()).toBe(true);
|
|
1193
|
+
|
|
1194
|
+
if (pageCase.workflowId) {
|
|
1195
|
+
expect(oauthForm().workflowId).toBe(pageCase.workflowId);
|
|
1196
|
+
} else {
|
|
1197
|
+
expect(oauthForm().workflowId).toBeUndefined();
|
|
1198
|
+
}
|
|
537
1199
|
});
|
|
538
1200
|
|
|
539
|
-
test("
|
|
540
|
-
renderPage(page);
|
|
541
|
-
openUpdateContentModal();
|
|
1201
|
+
test("closing the form without creating hides it and fetches no token", () => {
|
|
1202
|
+
renderPage(pageCase.page);
|
|
542
1203
|
|
|
543
|
-
|
|
544
|
-
|
|
1204
|
+
openOAuthForm();
|
|
1205
|
+
|
|
1206
|
+
act(() => {
|
|
1207
|
+
oauthForm().onClose();
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1211
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
1212
|
+
expect(apiPost).not.toHaveBeenCalled();
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1215
|
+
test("can be opened again after it was closed", () => {
|
|
1216
|
+
renderPage(pageCase.page);
|
|
1217
|
+
|
|
1218
|
+
openOAuthForm();
|
|
1219
|
+
|
|
1220
|
+
act(() => {
|
|
1221
|
+
oauthForm().onClose();
|
|
545
1222
|
});
|
|
546
1223
|
|
|
547
|
-
|
|
1224
|
+
openOAuthForm();
|
|
548
1225
|
|
|
549
|
-
expect(
|
|
1226
|
+
expect(isOAuthFormOpen()).toBe(true);
|
|
550
1227
|
});
|
|
1228
|
+
});
|
|
551
1229
|
|
|
1230
|
+
describe("after an OAuth 2.0 variable is created", () => {
|
|
552
1231
|
/*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
* class of stale-selection bug this change fixes in BaseModelTable. Rotating
|
|
556
|
-
* a credential onto the wrong variable would be invisible: content is never
|
|
557
|
-
* read back, so it would surface only as a workflow authenticating with the
|
|
558
|
-
* wrong token.
|
|
1232
|
+
* A token request can take up to 20 seconds. The modal opens as soon as
|
|
1233
|
+
* it goes out, so something on screen says it is happening.
|
|
559
1234
|
*/
|
|
560
|
-
test("
|
|
561
|
-
|
|
1235
|
+
test("closes the form and shows a pending token modal while the provider is asked", async () => {
|
|
1236
|
+
const response: Deferred<unknown> = createDeferred<unknown>();
|
|
1237
|
+
apiPost.mockReturnValue(response.promise);
|
|
562
1238
|
|
|
563
|
-
|
|
1239
|
+
renderPage(pageCase.page);
|
|
1240
|
+
openOAuthForm();
|
|
564
1241
|
|
|
565
1242
|
act(() => {
|
|
566
|
-
|
|
1243
|
+
oauthForm().onSuccess(oauthVariable());
|
|
567
1244
|
});
|
|
568
1245
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
expect(
|
|
1246
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1247
|
+
expect(refreshModal().outcome).toBeNull();
|
|
1248
|
+
expect(refreshModal().variableName).toBe("API_TOKEN");
|
|
1249
|
+
expect(apiPost).toHaveBeenCalledTimes(1);
|
|
572
1250
|
|
|
573
1251
|
await act(async () => {
|
|
574
|
-
|
|
1252
|
+
response.resolve({
|
|
1253
|
+
data: { oauthAccessTokenExpiresAt: EXPIRES_AT_ISO },
|
|
1254
|
+
});
|
|
1255
|
+
await response.promise;
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
await waitFor(() => {
|
|
1259
|
+
expect(refreshModal().outcome).not.toBeNull();
|
|
575
1260
|
});
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
test("asks for the new variable's first token through the refresh route, with the tenant header", async () => {
|
|
1264
|
+
renderPage(pageCase.page);
|
|
1265
|
+
|
|
1266
|
+
await createOAuthVariable(oauthVariable());
|
|
1267
|
+
|
|
1268
|
+
expect(apiPost).toHaveBeenCalledTimes(1);
|
|
1269
|
+
expect(refreshCall().url).toContain(
|
|
1270
|
+
`/workflow-variable/${VARIABLE_ID.toString()}/refresh-oauth-token`,
|
|
1271
|
+
);
|
|
1272
|
+
expect(refreshCall().headers).toEqual({ tenantid: "project-header" });
|
|
1273
|
+
expect(refreshCall().data).toEqual({});
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
test("shows when the new token expires once the provider answers", async () => {
|
|
1277
|
+
renderPage(pageCase.page);
|
|
1278
|
+
|
|
1279
|
+
await createOAuthVariable(oauthVariable());
|
|
1280
|
+
|
|
1281
|
+
const outcome: TokenRefreshOutcome = refreshModal().outcome!;
|
|
576
1282
|
|
|
577
|
-
|
|
578
|
-
|
|
1283
|
+
expect(outcome.variableName).toBe("API_TOKEN");
|
|
1284
|
+
expect(outcome.error).toBeUndefined();
|
|
1285
|
+
expect(outcome.savedWhat).toBeUndefined();
|
|
1286
|
+
expect(outcome.expiresAt).toEqual(new Date(EXPIRES_AT_ISO));
|
|
579
1287
|
|
|
580
|
-
|
|
1288
|
+
// Pending first, then the answer - never the answer out of nowhere.
|
|
1289
|
+
expect(refreshModalOutcomes[0]).toBeNull();
|
|
1290
|
+
expect(refreshModalOutcomes[refreshModalOutcomes.length - 1]).toBe(
|
|
1291
|
+
outcome,
|
|
1292
|
+
);
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
test("says so when the provider does not say when the token expires", async () => {
|
|
1296
|
+
apiPost.mockResolvedValue({ data: {} });
|
|
1297
|
+
|
|
1298
|
+
renderPage(pageCase.page);
|
|
1299
|
+
|
|
1300
|
+
await createOAuthVariable(oauthVariable());
|
|
1301
|
+
|
|
1302
|
+
expect(refreshModal().outcome!.error).toBeUndefined();
|
|
1303
|
+
expect(refreshModal().outcome!.expiresAt).toBeNull();
|
|
581
1304
|
});
|
|
582
1305
|
|
|
583
1306
|
/*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
* retry in, and nothing the user typed - reachable only by reloading.
|
|
1307
|
+
* A mistyped secret or token URL shows up while the person who typed it
|
|
1308
|
+
* is still looking, in the provider's own words.
|
|
587
1309
|
*/
|
|
588
|
-
test("
|
|
589
|
-
|
|
590
|
-
|
|
1310
|
+
test("shows the provider's refusal", async () => {
|
|
1311
|
+
apiPost.mockResolvedValue(
|
|
1312
|
+
new HTTPErrorResponse(
|
|
1313
|
+
400,
|
|
1314
|
+
{
|
|
1315
|
+
message:
|
|
1316
|
+
"invalid_client: AADSTS7000215: Invalid client secret provided.",
|
|
1317
|
+
},
|
|
1318
|
+
{},
|
|
1319
|
+
),
|
|
1320
|
+
);
|
|
591
1321
|
|
|
592
|
-
|
|
1322
|
+
renderPage(pageCase.page);
|
|
593
1323
|
|
|
594
|
-
await
|
|
595
|
-
modal().onSubmit?.({ content: "rotated-token" });
|
|
596
|
-
});
|
|
1324
|
+
await createOAuthVariable(oauthVariable());
|
|
597
1325
|
|
|
598
|
-
|
|
1326
|
+
const outcome: TokenRefreshOutcome = refreshModal().outcome!;
|
|
599
1327
|
|
|
600
|
-
|
|
1328
|
+
expect(outcome.variableName).toBe("API_TOKEN");
|
|
1329
|
+
expect(outcome.error).toBe(
|
|
1330
|
+
"invalid_client: AADSTS7000215: Invalid client secret provided.",
|
|
1331
|
+
);
|
|
1332
|
+
expect(outcome.expiresAt).toBeUndefined();
|
|
1333
|
+
});
|
|
601
1334
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
});
|
|
1335
|
+
test("shows a request that never reached the provider", async () => {
|
|
1336
|
+
apiPost.mockRejectedValue(new Error("Network Error"));
|
|
605
1337
|
|
|
606
|
-
|
|
1338
|
+
renderPage(pageCase.page);
|
|
1339
|
+
|
|
1340
|
+
await createOAuthVariable(oauthVariable());
|
|
1341
|
+
|
|
1342
|
+
expect(refreshModal().outcome!.error).toBe("Network Error");
|
|
1343
|
+
});
|
|
1344
|
+
|
|
1345
|
+
test("does not call the refresh route for a variable that came back without an id", async () => {
|
|
1346
|
+
renderPage(pageCase.page);
|
|
1347
|
+
|
|
1348
|
+
const variable: WorkflowVariable = oauthVariable({ _id: undefined });
|
|
1349
|
+
|
|
1350
|
+
await createOAuthVariable(variable);
|
|
1351
|
+
|
|
1352
|
+
expect(apiPost).not.toHaveBeenCalled();
|
|
1353
|
+
expect(refreshModal().outcome!.error).toContain(
|
|
1354
|
+
"This variable has no id",
|
|
1355
|
+
);
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1358
|
+
test("calls a variable without a name 'this variable'", async () => {
|
|
1359
|
+
renderPage(pageCase.page);
|
|
1360
|
+
|
|
1361
|
+
const variable: WorkflowVariable = oauthVariable({ name: undefined });
|
|
1362
|
+
|
|
1363
|
+
await createOAuthVariable(variable);
|
|
1364
|
+
|
|
1365
|
+
expect(refreshModal().variableName).toBe("this variable");
|
|
1366
|
+
expect(refreshModal().outcome!.variableName).toBe("this variable");
|
|
607
1367
|
});
|
|
608
1368
|
|
|
609
1369
|
/*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
* undefined id.
|
|
1370
|
+
* Once when the row is added, so it shows at once, and again once the
|
|
1371
|
+
* refresh has written the expiry or the failure to it.
|
|
613
1372
|
*/
|
|
614
|
-
test("
|
|
615
|
-
|
|
616
|
-
|
|
1373
|
+
test("refreshes the list when the variable is created, and again once the outcome is in", async () => {
|
|
1374
|
+
const response: Deferred<unknown> = createDeferred<unknown>();
|
|
1375
|
+
apiPost.mockReturnValue(response.promise);
|
|
1376
|
+
|
|
1377
|
+
renderPage(pageCase.page);
|
|
1378
|
+
|
|
1379
|
+
const initialToggle: string | undefined = table().refreshToggle;
|
|
1380
|
+
expect(initialToggle).toBeTruthy();
|
|
1381
|
+
|
|
1382
|
+
openOAuthForm();
|
|
1383
|
+
|
|
1384
|
+
act(() => {
|
|
1385
|
+
oauthForm().onSuccess(oauthVariable());
|
|
1386
|
+
});
|
|
1387
|
+
|
|
1388
|
+
const afterCreateToggle: string | undefined = table().refreshToggle;
|
|
1389
|
+
expect(afterCreateToggle).not.toBe(initialToggle);
|
|
617
1390
|
|
|
618
1391
|
await act(async () => {
|
|
619
|
-
|
|
1392
|
+
response.resolve({
|
|
1393
|
+
data: { oauthAccessTokenExpiresAt: EXPIRES_AT_ISO },
|
|
1394
|
+
});
|
|
1395
|
+
await response.promise;
|
|
620
1396
|
});
|
|
621
1397
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
1398
|
+
await waitFor(() => {
|
|
1399
|
+
expect(table().refreshToggle).not.toBe(afterCreateToggle);
|
|
1400
|
+
});
|
|
1401
|
+
|
|
1402
|
+
expect(table().refreshToggle).not.toBe(initialToggle);
|
|
626
1403
|
});
|
|
627
1404
|
|
|
628
|
-
test("
|
|
629
|
-
renderPage(page);
|
|
630
|
-
openUpdateContentModal();
|
|
1405
|
+
test("closing the outcome modal removes it", async () => {
|
|
1406
|
+
renderPage(pageCase.page);
|
|
631
1407
|
|
|
632
|
-
|
|
1408
|
+
await createOAuthVariable(oauthVariable());
|
|
633
1409
|
|
|
634
|
-
|
|
635
|
-
|
|
1410
|
+
expect(isRefreshModalOpen()).toBe(true);
|
|
1411
|
+
|
|
1412
|
+
act(() => {
|
|
1413
|
+
refreshModal().onClose();
|
|
636
1414
|
});
|
|
637
1415
|
|
|
638
|
-
expect(
|
|
1416
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
1417
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1418
|
+
});
|
|
1419
|
+
|
|
1420
|
+
test("closing the outcome modal after a failure removes it too", async () => {
|
|
1421
|
+
apiPost.mockRejectedValue(new Error("Network Error"));
|
|
1422
|
+
|
|
1423
|
+
renderPage(pageCase.page);
|
|
1424
|
+
|
|
1425
|
+
await createOAuthVariable(oauthVariable());
|
|
639
1426
|
|
|
640
1427
|
act(() => {
|
|
641
|
-
|
|
1428
|
+
refreshModal().onClose();
|
|
642
1429
|
});
|
|
643
1430
|
|
|
644
|
-
|
|
1431
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1434
|
+
// Only the OAuth form's success fetches a token; the Create form never does.
|
|
1435
|
+
test("a static variable created from the Create form fetches no token", async () => {
|
|
1436
|
+
renderPage(pageCase.page);
|
|
1437
|
+
|
|
1438
|
+
await act(async () => {
|
|
1439
|
+
await table().onBeforeCreate!(new WorkflowVariable());
|
|
1440
|
+
});
|
|
645
1441
|
|
|
646
|
-
expect(
|
|
1442
|
+
expect(apiPost).not.toHaveBeenCalled();
|
|
1443
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
647
1444
|
});
|
|
648
1445
|
});
|
|
649
1446
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
test(
|
|
658
|
-
|
|
1447
|
+
/*
|
|
1448
|
+
* Creating a variable and refreshing its token are different permissions.
|
|
1449
|
+
* Somebody who may create but not update would only get OneUptime's own
|
|
1450
|
+
* refusal back from the refresh route - shown as if their provider had said
|
|
1451
|
+
* no - so the page does not ask for them.
|
|
1452
|
+
*/
|
|
1453
|
+
describe("whose new OAuth 2.0 variable gets its first token fetched", () => {
|
|
1454
|
+
test.each(CREATE_ONLY_ROLES)(
|
|
1455
|
+
"not somebody who may only create variables ($label): the form closes and the list refreshes, with no token request and no token modal",
|
|
1456
|
+
async (role: RoleCase) => {
|
|
1457
|
+
permissionsForTest = role.permissions;
|
|
659
1458
|
|
|
660
|
-
|
|
1459
|
+
renderPage(pageCase.page);
|
|
661
1460
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
1461
|
+
const initialToggle: string | undefined = table().refreshToggle;
|
|
1462
|
+
|
|
1463
|
+
// They may create, so the menu entry does open the form.
|
|
1464
|
+
expect(oauthMenuButton().disabled).toBe(false);
|
|
1465
|
+
|
|
1466
|
+
openOAuthForm();
|
|
1467
|
+
|
|
1468
|
+
expect(isOAuthFormOpen()).toBe(true);
|
|
1469
|
+
|
|
1470
|
+
await saveOAuthVariable(oauthVariable());
|
|
1471
|
+
|
|
1472
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1473
|
+
|
|
1474
|
+
// The new row still shows up at once.
|
|
1475
|
+
expect(table().refreshToggle).not.toBe(initialToggle);
|
|
1476
|
+
|
|
1477
|
+
expect(apiPost).not.toHaveBeenCalled();
|
|
1478
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
1479
|
+
expect(capturedRefreshModalProps).toBeNull();
|
|
1480
|
+
expect(refreshModalOutcomes).toEqual([]);
|
|
1481
|
+
},
|
|
1482
|
+
);
|
|
1483
|
+
|
|
1484
|
+
// With no token request there is nothing to wait for, so no second bump.
|
|
1485
|
+
test("refreshes the list once, and only once, for somebody who may only create", async () => {
|
|
1486
|
+
permissionsForTest = [
|
|
1487
|
+
Permission.CreateWorkflowVariable,
|
|
1488
|
+
Permission.ReadWorkflowVariable,
|
|
1489
|
+
];
|
|
1490
|
+
|
|
1491
|
+
renderPage(pageCase.page);
|
|
1492
|
+
|
|
1493
|
+
const initialToggle: string | undefined = table().refreshToggle;
|
|
1494
|
+
|
|
1495
|
+
openOAuthForm();
|
|
1496
|
+
|
|
1497
|
+
await saveOAuthVariable(oauthVariable());
|
|
1498
|
+
|
|
1499
|
+
const afterCreateToggle: string | undefined = table().refreshToggle;
|
|
1500
|
+
|
|
1501
|
+
expect(afterCreateToggle).not.toBe(initialToggle);
|
|
1502
|
+
|
|
1503
|
+
await act(async () => {
|
|
1504
|
+
await Promise.resolve();
|
|
1505
|
+
});
|
|
1506
|
+
|
|
1507
|
+
expect(table().refreshToggle).toBe(afterCreateToggle);
|
|
667
1508
|
});
|
|
668
1509
|
|
|
669
|
-
test("
|
|
670
|
-
permissionsForTest = [
|
|
1510
|
+
test("can open the form again afterwards, still without a token modal in the way", async () => {
|
|
1511
|
+
permissionsForTest = [
|
|
1512
|
+
Permission.CreateWorkflowVariable,
|
|
1513
|
+
Permission.ReadWorkflowVariable,
|
|
1514
|
+
];
|
|
671
1515
|
|
|
672
|
-
renderPage(page);
|
|
1516
|
+
renderPage(pageCase.page);
|
|
673
1517
|
|
|
674
|
-
|
|
1518
|
+
openOAuthForm();
|
|
1519
|
+
|
|
1520
|
+
await saveOAuthVariable(oauthVariable());
|
|
1521
|
+
|
|
1522
|
+
openOAuthForm();
|
|
1523
|
+
|
|
1524
|
+
expect(isOAuthFormOpen()).toBe(true);
|
|
1525
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
675
1526
|
});
|
|
676
1527
|
|
|
1528
|
+
test.each(CREATE_AND_UPDATE_ROLES)(
|
|
1529
|
+
"somebody who may also update variables ($label): asks for the token and shows the outcome",
|
|
1530
|
+
async (role: RoleCase) => {
|
|
1531
|
+
permissionsForTest = role.permissions;
|
|
1532
|
+
|
|
1533
|
+
renderPage(pageCase.page);
|
|
1534
|
+
|
|
1535
|
+
await createOAuthVariable(oauthVariable());
|
|
1536
|
+
|
|
1537
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1538
|
+
expect(apiPost).toHaveBeenCalledTimes(1);
|
|
1539
|
+
expect(refreshCall().url).toContain(
|
|
1540
|
+
`/workflow-variable/${VARIABLE_ID.toString()}/refresh-oauth-token`,
|
|
1541
|
+
);
|
|
1542
|
+
|
|
1543
|
+
expect(refreshModal().variableName).toBe("API_TOKEN");
|
|
1544
|
+
expect(refreshModal().outcome!.error).toBeUndefined();
|
|
1545
|
+
expect(refreshModal().outcome!.expiresAt).toEqual(
|
|
1546
|
+
new Date(EXPIRES_AT_ISO),
|
|
1547
|
+
);
|
|
1548
|
+
expect(refreshModalOutcomes[0]).toBeNull();
|
|
1549
|
+
},
|
|
1550
|
+
);
|
|
1551
|
+
|
|
677
1552
|
/*
|
|
678
|
-
*
|
|
679
|
-
* the
|
|
680
|
-
* that as "not allowed, no reason" precisely so callers hide the affordance
|
|
681
|
-
* rather than accuse somebody who may well hold the permission.
|
|
1553
|
+
* PermissionGate lets a master admin do everything before it even looks
|
|
1554
|
+
* at the snapshot, so an empty one does not stop the fetch.
|
|
682
1555
|
*/
|
|
683
|
-
test("
|
|
1556
|
+
test("a master admin, even before the permission snapshot arrives", async () => {
|
|
684
1557
|
permissionsForTest = [];
|
|
1558
|
+
isMasterAdminForTest = true;
|
|
685
1559
|
|
|
686
|
-
renderPage(page);
|
|
1560
|
+
renderPage(pageCase.page);
|
|
687
1561
|
|
|
688
|
-
|
|
1562
|
+
await createOAuthVariable(oauthVariable());
|
|
1563
|
+
|
|
1564
|
+
expect(apiPost).toHaveBeenCalledTimes(1);
|
|
1565
|
+
expect(refreshCall().url).toContain(
|
|
1566
|
+
`/workflow-variable/${VARIABLE_ID.toString()}/refresh-oauth-token`,
|
|
1567
|
+
);
|
|
1568
|
+
expect(refreshModal().outcome!.expiresAt).toEqual(
|
|
1569
|
+
new Date(EXPIRES_AT_ISO),
|
|
1570
|
+
);
|
|
689
1571
|
});
|
|
690
|
-
});
|
|
691
|
-
});
|
|
692
1572
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
1573
|
+
test("a master admin whose project role may only create", async () => {
|
|
1574
|
+
permissionsForTest = [Permission.CreateWorkflowVariable];
|
|
1575
|
+
isMasterAdminForTest = true;
|
|
696
1576
|
|
|
697
|
-
|
|
698
|
-
expect(String(table().query?.["projectId"])).toBe(PROJECT_ID.toString());
|
|
699
|
-
expect(table().cardProps?.title).toBe("Global Variables");
|
|
700
|
-
});
|
|
1577
|
+
renderPage(pageCase.page);
|
|
701
1578
|
|
|
702
|
-
|
|
703
|
-
renderPage("local");
|
|
1579
|
+
await createOAuthVariable(oauthVariable());
|
|
704
1580
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
});
|
|
1581
|
+
expect(apiPost).toHaveBeenCalledTimes(1);
|
|
1582
|
+
expect(isRefreshModalOpen()).toBe(true);
|
|
1583
|
+
});
|
|
709
1584
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
* workflowId disappears from the page that created it.
|
|
714
|
-
*/
|
|
715
|
-
test("a variable created on the workflow page is stamped with the workflow", async () => {
|
|
716
|
-
renderPage("local");
|
|
1585
|
+
// The gate is read when the variable is saved, not when the form opened.
|
|
1586
|
+
test("not somebody whose role lost update while the form was open", async () => {
|
|
1587
|
+
permissionsForTest = [Permission.ProjectAdmin];
|
|
717
1588
|
|
|
718
|
-
|
|
719
|
-
new WorkflowVariable(),
|
|
720
|
-
)) as WorkflowVariable;
|
|
1589
|
+
renderPage(pageCase.page);
|
|
721
1590
|
|
|
722
|
-
|
|
723
|
-
});
|
|
1591
|
+
openOAuthForm();
|
|
724
1592
|
|
|
725
|
-
|
|
726
|
-
|
|
1593
|
+
permissionsForTest = [
|
|
1594
|
+
Permission.CreateWorkflowVariable,
|
|
1595
|
+
Permission.ReadWorkflowVariable,
|
|
1596
|
+
];
|
|
727
1597
|
|
|
728
|
-
|
|
729
|
-
new WorkflowVariable(),
|
|
730
|
-
)) as WorkflowVariable;
|
|
1598
|
+
await saveOAuthVariable(oauthVariable());
|
|
731
1599
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1600
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1601
|
+
expect(apiPost).not.toHaveBeenCalled();
|
|
1602
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
1603
|
+
});
|
|
735
1604
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
*/
|
|
744
|
-
test.each(PAGES)("%s", (page: Page) => {
|
|
745
|
-
renderPage(page);
|
|
1605
|
+
test("somebody whose role gained update while the form was open", async () => {
|
|
1606
|
+
permissionsForTest = [
|
|
1607
|
+
Permission.CreateWorkflowVariable,
|
|
1608
|
+
Permission.ReadWorkflowVariable,
|
|
1609
|
+
];
|
|
1610
|
+
|
|
1611
|
+
renderPage(pageCase.page);
|
|
746
1612
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
1613
|
+
openOAuthForm();
|
|
1614
|
+
|
|
1615
|
+
permissionsForTest = [
|
|
1616
|
+
Permission.CreateWorkflowVariable,
|
|
1617
|
+
Permission.EditWorkflowVariable,
|
|
1618
|
+
];
|
|
1619
|
+
|
|
1620
|
+
await saveOAuthVariable(oauthVariable());
|
|
1621
|
+
|
|
1622
|
+
await waitFor(() => {
|
|
1623
|
+
expect(refreshModal().outcome).toBeTruthy();
|
|
1624
|
+
});
|
|
1625
|
+
|
|
1626
|
+
expect(apiPost).toHaveBeenCalledTimes(1);
|
|
1627
|
+
});
|
|
750
1628
|
|
|
751
1629
|
/*
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
*
|
|
1630
|
+
* An empty snapshot (not a master admin) is PermissionGate's "not loaded
|
|
1631
|
+
* yet": it does not allow, so the page does not ask. The variable still
|
|
1632
|
+
* gets its first token the first time a workflow uses it.
|
|
755
1633
|
*/
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
}
|
|
1634
|
+
test("not while the permission snapshot is empty at the moment of saving", async () => {
|
|
1635
|
+
permissionsForTest = [Permission.ProjectAdmin];
|
|
759
1636
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
1637
|
+
renderPage(pageCase.page);
|
|
1638
|
+
|
|
1639
|
+
openOAuthForm();
|
|
1640
|
+
|
|
1641
|
+
permissionsForTest = [];
|
|
1642
|
+
|
|
1643
|
+
await saveOAuthVariable(oauthVariable());
|
|
764
1644
|
|
|
765
|
-
|
|
766
|
-
|
|
1645
|
+
expect(isOAuthFormOpen()).toBe(false);
|
|
1646
|
+
expect(apiPost).not.toHaveBeenCalled();
|
|
1647
|
+
expect(isRefreshModalOpen()).toBe(false);
|
|
1648
|
+
});
|
|
767
1649
|
});
|
|
768
1650
|
});
|