@oneuptime/common 12.0.6 → 12.0.7
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/AIInsight.ts +1 -1
- package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
- package/Models/DatabaseModels/DeletedProject.ts +595 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Monitor.ts +111 -0
- package/Models/DatabaseModels/Project.ts +3 -3
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
- package/Server/API/FileAPI.ts +15 -2
- package/Server/API/MicrosoftTeamsAPI.ts +6 -1
- package/Server/API/ProjectAPI.ts +214 -0
- package/Server/API/StatusPageAPI.ts +39 -6
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Services/AIAgentService.ts +20 -0
- package/Server/Services/DashboardDomainService.ts +73 -28
- package/Server/Services/DatabaseService.ts +1 -0
- package/Server/Services/DeletedProjectService.ts +138 -0
- package/Server/Services/FileService.ts +61 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
- package/Server/Services/IncidentPublicNoteService.ts +18 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +311 -0
- package/Server/Services/ProbeService.ts +20 -0
- package/Server/Services/ProjectService.ts +297 -1
- package/Server/Services/PushNotificationService.ts +71 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
- package/Server/Services/StatusPageAnnouncementService.ts +53 -0
- package/Server/Services/StatusPageDomainService.ts +73 -28
- package/Server/Services/TeamMemberService.ts +117 -12
- package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
- package/Server/Services/UserWebhookService.ts +34 -109
- package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
- package/Server/Types/Database/DeleteById.ts +2 -0
- package/Server/Types/Database/DeleteOneBy.ts +6 -0
- package/Server/Types/Domain.ts +41 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
- package/Server/Types/Workflow/Components/API/Get.ts +2 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
- package/Server/Types/Workflow/Components/API/Post.ts +2 -1
- package/Server/Types/Workflow/Components/API/Put.ts +2 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +41 -2
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
- package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
- package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
- package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
- package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
- package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
- package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
- package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
- package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
- package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
- package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
- package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
- package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
- package/Server/Utils/DataSource/EgressGuard.ts +176 -16
- package/Server/Utils/DataSource/HttpFetch.ts +6 -45
- package/Server/Utils/Execute.ts +8 -0
- package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
- package/Server/Utils/LLM/LLMService.ts +57 -12
- package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
- package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
- package/Server/Utils/Monitor/MonitorResource.ts +36 -0
- package/Server/Utils/Response.ts +142 -6
- package/Server/Utils/SSRFProtection.ts +273 -60
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/VM/VMRunner.ts +88 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
- package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
- package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
- package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
- package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
- package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
- package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
- package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
- package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
- package/Tests/Server/API/ProjectAPI.test.ts +299 -1
- package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
- package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
- package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
- package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
- package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
- package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
- package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
- package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
- package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
- package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
- package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
- package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
- package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
- package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
- package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
- package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
- package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
- package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
- package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
- package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
- package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
- package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
- package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
- package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
- package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
- package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
- package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
- package/Tests/Types/JSONFunctions.test.ts +252 -1
- package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
- package/Tests/UI/Components/404.test.tsx +1 -1
- package/Tests/UI/Components/Alert.test.tsx +1 -1
- package/Tests/UI/Components/Badge.test.tsx +1 -1
- package/Tests/UI/Components/BasicForm.test.tsx +39 -10
- package/Tests/UI/Components/Button.test.tsx +1 -1
- package/Tests/UI/Components/Card.test.tsx +1 -1
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
- package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
- package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
- package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
- package/Tests/UI/Components/Dropdown.test.tsx +1 -1
- package/Tests/UI/Components/FilePicker.test.tsx +1 -1
- package/Tests/UI/Components/HiddenText.test.tsx +1 -1
- package/Tests/UI/Components/Input.test.tsx +1 -1
- package/Tests/UI/Components/Loader.test.tsx +1 -1
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +1 -1
- package/Tests/UI/Components/MasterPage.test.tsx +1 -1
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +489 -0
- package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
- package/Tests/UI/Components/NavBar.test.tsx +1 -1
- package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
- package/Tests/UI/Components/Pagination.test.tsx +1 -1
- package/Tests/UI/Components/Pill.test.tsx +1 -1
- package/Tests/UI/Components/Probe.test.tsx +1 -1
- package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
- package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
- package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
- package/Tests/UI/Components/SideOver.test.tsx +500 -6
- package/Tests/UI/Components/Tabs.test.tsx +1 -1
- package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +1 -1
- package/Tests/UI/Components/TextArea.test.tsx +1 -1
- package/Tests/UI/Components/Toast.test.tsx +1 -1
- package/Tests/UI/Components/Toggle.test.tsx +1 -1
- package/Tests/UI/Components/TopSection.test.tsx +1 -1
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
- package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
- package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
- package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
- package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
- package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
- package/Tests/Utils/Realtime.test.ts +78 -0
- package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
- package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
- package/Types/AI/FixPullRequestCiStatus.ts +1 -1
- package/Types/AI/FixVerificationStatus.ts +2 -2
- package/Types/API/Hostname.ts +92 -4
- package/Types/API/URL.ts +43 -25
- package/Types/Billing/BalanceAdjustmentType.ts +14 -0
- package/Types/Billing/ProjectBalanceType.ts +13 -0
- package/Types/Domain.ts +26 -0
- package/Types/File/MimeType.ts +11 -0
- package/Types/JSONFunctions.ts +15 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
- package/Types/Workflow/Components/BaseModel.ts +92 -28
- package/Typings/Index.d.ts +12 -0
- package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
- package/UI/Components/Modal/ConfirmModal.tsx +10 -5
- package/UI/Components/Modal/Modal.tsx +27 -47
- package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
- package/UI/Components/SideOver/SideOver.tsx +195 -68
- package/UI/Utils/PageScrollLock.ts +66 -0
- package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
- package/Utils/Dashboard/VariableInterpolation.ts +19 -1
- package/Utils/LegacySerializedArray.ts +60 -0
- package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
- package/Utils/Telemetry/SavedViewFilters.ts +88 -0
- package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
- package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
- package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +3 -3
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/FileAPI.js +14 -2
- package/build/dist/Server/API/FileAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +157 -4
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +27 -3
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +17 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +55 -18
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +1 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DeletedProjectService.js +124 -0
- package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
- package/build/dist/Server/Services/FileService.js +52 -0
- package/build/dist/Server/Services/FileService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.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/MonitorService.js +232 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +17 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +228 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +56 -0
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
- package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
- package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +97 -6
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +31 -87
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Domain.js +37 -0
- package/build/dist/Server/Types/Domain.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +35 -2
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/Execute.js +2 -2
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +112 -5
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +219 -53
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
- package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
- package/build/dist/Types/API/Hostname.js +73 -4
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/API/URL.js +42 -24
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
- package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
- package/build/dist/Types/Domain.js +22 -0
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +11 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +14 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +83 -28
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +24 -34
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +52 -0
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
- package/build/dist/Utils/LegacySerializedArray.js +51 -0
- package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
- package/jest.config.json +3 -0
- package/package.json +1 -1
- package/tsconfig.json +3 -1
|
@@ -33,12 +33,24 @@ import CaptureSpan from "../../Telemetry/CaptureSpan";
|
|
|
33
33
|
import BadDataException from "../../../../Types/Exception/BadDataException";
|
|
34
34
|
import ObjectID from "../../../../Types/ObjectID";
|
|
35
35
|
import WorkspaceProjectAuthTokenService from "../../../Services/WorkspaceProjectAuthTokenService";
|
|
36
|
+
import SSRFProtection from "../../SSRFProtection";
|
|
36
37
|
|
|
37
38
|
export default class SlackUtil extends WorkspaceBase {
|
|
38
39
|
public static isValidSlackIncomingWebhookUrl(
|
|
39
|
-
incomingWebhookUrl: URL,
|
|
40
|
+
incomingWebhookUrl: URL | string,
|
|
40
41
|
): boolean {
|
|
41
|
-
|
|
42
|
+
/*
|
|
43
|
+
* Host AND path prefix. The host check is what stops SSRF; the "/services/"
|
|
44
|
+
* prefix is what makes this tighter than a bare domain pin. Both are read
|
|
45
|
+
* off the WHATWG parser via getBareHostname, so a "#"/"?" in the string
|
|
46
|
+
* cannot make an attacker host look like a Slack one.
|
|
47
|
+
*/
|
|
48
|
+
if (
|
|
49
|
+
SSRFProtection.getBareHostname(incomingWebhookUrl) !== "hooks.slack.com"
|
|
50
|
+
) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
return incomingWebhookUrl
|
|
43
55
|
.toString()
|
|
44
56
|
.startsWith("https://hooks.slack.com/services/");
|
|
@@ -2265,6 +2277,17 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
2265
2277
|
);
|
|
2266
2278
|
logger.debug(data, {} as LogAttributes);
|
|
2267
2279
|
|
|
2280
|
+
/*
|
|
2281
|
+
* Enforced at the sink, not only at the callers: this URL reaches here from
|
|
2282
|
+
* workflow arguments and from status page subscribers, and a caller that
|
|
2283
|
+
* forgets the pin is an SSRF from the API server.
|
|
2284
|
+
*/
|
|
2285
|
+
if (!SlackUtil.isValidSlackIncomingWebhookUrl(data.url)) {
|
|
2286
|
+
throw new BadDataException(
|
|
2287
|
+
"Slack Webhook URL must start with https://hooks.slack.com/services/",
|
|
2288
|
+
);
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2268
2291
|
const apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null =
|
|
2269
2292
|
await API.post({
|
|
2270
2293
|
url: data.url,
|
|
@@ -43,6 +43,12 @@ export interface WorkspaceChannel {
|
|
|
43
43
|
name: string;
|
|
44
44
|
workspaceType: WorkspaceType;
|
|
45
45
|
teamId?: string; // Required for Microsoft Teams
|
|
46
|
+
/*
|
|
47
|
+
* Microsoft Teams only: "standard" | "private" | "shared". Bots cannot post
|
|
48
|
+
* to shared channels at all, and a private channel needs the app installed
|
|
49
|
+
* into that channel specifically rather than into the parent team.
|
|
50
|
+
*/
|
|
51
|
+
membershipType?: string | undefined;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
export default class WorkspaceBase {
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import {
|
|
3
|
+
act,
|
|
4
|
+
fireEvent,
|
|
5
|
+
render,
|
|
6
|
+
screen,
|
|
7
|
+
waitFor,
|
|
8
|
+
} from "@testing-library/react";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { beforeEach, describe, expect, it } from "@jest/globals";
|
|
11
|
+
import API from "../../../UI/Utils/API/API";
|
|
12
|
+
import ProjectUtil from "../../../UI/Utils/Project";
|
|
13
|
+
import PermissionUtil from "../../../UI/Utils/Permission";
|
|
14
|
+
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
15
|
+
import HTTPResponse from "../../../Types/API/HTTPResponse";
|
|
16
|
+
import Route from "../../../Types/API/Route";
|
|
17
|
+
import Dictionary from "../../../Types/Dictionary";
|
|
18
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
19
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
20
|
+
import { getJestSpyOn } from "../../Spy";
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Settings > Danger Zone is where a customer deletes their project - the one
|
|
24
|
+
* moment OneUptime can ask why they are leaving, because a second later the
|
|
25
|
+
* project and every trace of the account are gone for good.
|
|
26
|
+
*
|
|
27
|
+
* The page is rendered for real down to the confirmation dialog. Page chrome
|
|
28
|
+
* (the layout shell and the side menu) is stubbed: both want a router this
|
|
29
|
+
* test has no use for, and neither has anything to do with deleting a project.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
33
|
+
"11111111-1111-4111-8111-111111111111",
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
interface MutableConfig {
|
|
37
|
+
billingEnabled: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const config: MutableConfig = { billingEnabled: true };
|
|
41
|
+
|
|
42
|
+
(
|
|
43
|
+
globalThis as unknown as { __dangerZoneConfig: MutableConfig }
|
|
44
|
+
).__dangerZoneConfig = config;
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* BILLING_ENABLED is a module-scope const, so the two deployments have to be
|
|
48
|
+
* switchable per test rather than per file. defineProperty rather than a
|
|
49
|
+
* getter in the object literal: a literal getter is read once while the
|
|
50
|
+
* object is built, which would freeze the value at mock time.
|
|
51
|
+
*/
|
|
52
|
+
jest.mock("../../../UI/Config", () => {
|
|
53
|
+
const mocked: Record<string, unknown> = {
|
|
54
|
+
...jest.requireActual("../../../UI/Config"),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
Object.defineProperty(mocked, "BILLING_ENABLED", {
|
|
58
|
+
get: (): boolean => {
|
|
59
|
+
return Boolean(
|
|
60
|
+
(
|
|
61
|
+
globalThis as unknown as {
|
|
62
|
+
__dangerZoneConfig: MutableConfig | undefined;
|
|
63
|
+
}
|
|
64
|
+
).__dangerZoneConfig?.billingEnabled,
|
|
65
|
+
);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return mocked;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
jest.mock("../../../UI/Components/Page/Page", () => {
|
|
73
|
+
const react: typeof React = jest.requireActual("react");
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
__esModule: true,
|
|
77
|
+
default: (props: { children?: React.ReactNode }) => {
|
|
78
|
+
return react.createElement("div", null, props.children);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
jest.mock(
|
|
84
|
+
"../../../../App/FeatureSet/Dashboard/src/Pages/Settings/SideMenu",
|
|
85
|
+
() => {
|
|
86
|
+
return {
|
|
87
|
+
__esModule: true,
|
|
88
|
+
default: () => {
|
|
89
|
+
return null;
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
* Imported after the mocks above so the page picks them up - the module reads
|
|
97
|
+
* BILLING_ENABLED as soon as it renders.
|
|
98
|
+
*/
|
|
99
|
+
import DangerZone from "../../../../App/FeatureSet/Dashboard/src/Pages/Settings/DangerZone";
|
|
100
|
+
|
|
101
|
+
interface PageCalls {
|
|
102
|
+
projectDeleted: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type RenderPageFunction = () => PageCalls;
|
|
106
|
+
|
|
107
|
+
const renderPage: RenderPageFunction = (): PageCalls => {
|
|
108
|
+
const calls: PageCalls = { projectDeleted: 0 };
|
|
109
|
+
|
|
110
|
+
render(
|
|
111
|
+
<DangerZone
|
|
112
|
+
pageRoute={new Route("/settings/danger-zone")}
|
|
113
|
+
currentProject={null}
|
|
114
|
+
hasPaymentMethod={true}
|
|
115
|
+
onProjectDeleted={() => {
|
|
116
|
+
calls.projectDeleted = calls.projectDeleted + 1;
|
|
117
|
+
}}
|
|
118
|
+
/>,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return calls;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
type OpenConfirmationFunction = () => void;
|
|
125
|
+
|
|
126
|
+
const openConfirmation: OpenConfirmationFunction = (): void => {
|
|
127
|
+
fireEvent.click(
|
|
128
|
+
screen.getByRole("button", { name: "Delete Project" }) as HTMLElement,
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
type ConfirmFunction = () => Promise<void>;
|
|
133
|
+
|
|
134
|
+
/*
|
|
135
|
+
* The confirm button kicks off the delete request, so the state updates it
|
|
136
|
+
* causes land outside this tick - hence act rather than a bare click.
|
|
137
|
+
*/
|
|
138
|
+
const confirm: ConfirmFunction = async (): Promise<void> => {
|
|
139
|
+
await act(async () => {
|
|
140
|
+
fireEvent.click(screen.getByTestId("modal-footer-submit-button"));
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
type TypeReasonFunction = (reason: string) => void;
|
|
145
|
+
|
|
146
|
+
const typeReason: TypeReasonFunction = (reason: string): void => {
|
|
147
|
+
fireEvent.change(screen.getByTestId("project-deletion-reason"), {
|
|
148
|
+
target: { value: reason },
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
describe("Settings > Danger Zone", () => {
|
|
153
|
+
let postCalls: Array<{
|
|
154
|
+
url: string;
|
|
155
|
+
data: JSONObject;
|
|
156
|
+
headers: Dictionary<string> | undefined;
|
|
157
|
+
}> = [];
|
|
158
|
+
|
|
159
|
+
beforeEach(() => {
|
|
160
|
+
jest.restoreAllMocks();
|
|
161
|
+
|
|
162
|
+
config.billingEnabled = true;
|
|
163
|
+
postCalls = [];
|
|
164
|
+
|
|
165
|
+
getJestSpyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(
|
|
166
|
+
PROJECT_ID,
|
|
167
|
+
);
|
|
168
|
+
getJestSpyOn(ProjectUtil, "clearCurrentProject").mockImplementation(
|
|
169
|
+
() => {},
|
|
170
|
+
);
|
|
171
|
+
getJestSpyOn(PermissionUtil, "clearProjectPermissions").mockImplementation(
|
|
172
|
+
() => {},
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
getJestSpyOn(API, "post").mockImplementation((data: any) => {
|
|
176
|
+
postCalls.push({
|
|
177
|
+
url: data.url.toString(),
|
|
178
|
+
data: data.data as JSONObject,
|
|
179
|
+
headers: data.headers as Dictionary<string> | undefined,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
return Promise.resolve(new HTTPResponse<JSONObject>(200, {}, {}));
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
/*
|
|
187
|
+
* The server resolves which project's permissions this request carries from
|
|
188
|
+
* the tenantid header. API.post does not add it (ModelAPI does), so without
|
|
189
|
+
* it every delete from this page is refused - and the customer is told they
|
|
190
|
+
* are not allowed to delete their own project.
|
|
191
|
+
*/
|
|
192
|
+
it("sends the project the request is authenticated for", async () => {
|
|
193
|
+
renderPage();
|
|
194
|
+
openConfirmation();
|
|
195
|
+
await confirm();
|
|
196
|
+
|
|
197
|
+
await waitFor(() => {
|
|
198
|
+
expect(postCalls).toHaveLength(1);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
expect(postCalls[0]?.headers?.["tenantid"]).toBe(PROJECT_ID.toString());
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("warns that the deletion cannot be undone", () => {
|
|
205
|
+
renderPage();
|
|
206
|
+
|
|
207
|
+
expect(screen.getByText(/no way to recover/i)).toBeInTheDocument();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("does not ask anything until the customer confirms they want to delete", () => {
|
|
211
|
+
renderPage();
|
|
212
|
+
|
|
213
|
+
expect(screen.queryByTestId("project-deletion-reason")).toBeNull();
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("asks why the customer is deleting the project", () => {
|
|
217
|
+
renderPage();
|
|
218
|
+
openConfirmation();
|
|
219
|
+
|
|
220
|
+
expect(
|
|
221
|
+
screen.getByText("Why are you deleting this project?"),
|
|
222
|
+
).toBeInTheDocument();
|
|
223
|
+
expect(screen.getByTestId("project-deletion-reason")).toBeInTheDocument();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("sends the reason with the delete", async () => {
|
|
227
|
+
renderPage();
|
|
228
|
+
openConfirmation();
|
|
229
|
+
typeReason("Too expensive for our team");
|
|
230
|
+
await confirm();
|
|
231
|
+
|
|
232
|
+
await waitFor(() => {
|
|
233
|
+
expect(postCalls).toHaveLength(1);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
expect(postCalls[0]?.url).toContain(
|
|
237
|
+
`/project/${PROJECT_ID.toString()}/delete-project`,
|
|
238
|
+
);
|
|
239
|
+
expect(postCalls[0]?.data).toEqual({
|
|
240
|
+
data: { deletionReason: "Too expensive for our team" },
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* Answering is optional. A customer who does not want to say why must still
|
|
246
|
+
* be able to delete their project.
|
|
247
|
+
*/
|
|
248
|
+
it("still deletes the project when no reason is given", async () => {
|
|
249
|
+
const calls: PageCalls = renderPage();
|
|
250
|
+
|
|
251
|
+
openConfirmation();
|
|
252
|
+
await confirm();
|
|
253
|
+
|
|
254
|
+
await waitFor(() => {
|
|
255
|
+
expect(postCalls).toHaveLength(1);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(postCalls[0]?.data).toEqual({ data: { deletionReason: "" } });
|
|
259
|
+
expect(calls.projectDeleted).toBe(1);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it("clears the deleted project out of the session on success", async () => {
|
|
263
|
+
const calls: PageCalls = renderPage();
|
|
264
|
+
|
|
265
|
+
openConfirmation();
|
|
266
|
+
typeReason("Consolidating projects");
|
|
267
|
+
await confirm();
|
|
268
|
+
|
|
269
|
+
await waitFor(() => {
|
|
270
|
+
expect(calls.projectDeleted).toBe(1);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
expect(ProjectUtil.clearCurrentProject).toHaveBeenCalled();
|
|
274
|
+
expect(PermissionUtil.clearProjectPermissions).toHaveBeenCalled();
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
/*
|
|
278
|
+
* The success handler navigates away from the project. Running it after a
|
|
279
|
+
* failed delete would leave the customer looking at a project they still
|
|
280
|
+
* have and cannot get back to.
|
|
281
|
+
*/
|
|
282
|
+
it("does not clear the session when the delete is refused", async () => {
|
|
283
|
+
getJestSpyOn(API, "post").mockResolvedValue(
|
|
284
|
+
new HTTPErrorResponse(400, { message: "Delete not allowed" }, {}),
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
const calls: PageCalls = renderPage();
|
|
288
|
+
|
|
289
|
+
openConfirmation();
|
|
290
|
+
await confirm();
|
|
291
|
+
|
|
292
|
+
await waitFor(() => {
|
|
293
|
+
expect(screen.getByText("Delete Error")).toBeInTheDocument();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
expect(calls.projectDeleted).toBe(0);
|
|
297
|
+
expect(ProjectUtil.clearCurrentProject).not.toHaveBeenCalled();
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
/*
|
|
301
|
+
* Self-hosted installs have nobody to follow up with and nowhere to record
|
|
302
|
+
* an answer, so the question is not asked at all there.
|
|
303
|
+
*/
|
|
304
|
+
describe("on a self-hosted install", () => {
|
|
305
|
+
beforeEach(() => {
|
|
306
|
+
config.billingEnabled = false;
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it("does not ask why the project is being deleted", () => {
|
|
310
|
+
renderPage();
|
|
311
|
+
openConfirmation();
|
|
312
|
+
|
|
313
|
+
expect(screen.queryByTestId("project-deletion-reason")).toBeNull();
|
|
314
|
+
expect(
|
|
315
|
+
screen.queryByText("Why are you deleting this project?"),
|
|
316
|
+
).toBeNull();
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("still deletes the project", async () => {
|
|
320
|
+
const calls: PageCalls = renderPage();
|
|
321
|
+
|
|
322
|
+
openConfirmation();
|
|
323
|
+
await confirm();
|
|
324
|
+
|
|
325
|
+
await waitFor(() => {
|
|
326
|
+
expect(calls.projectDeleted).toBe(1);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
expect(postCalls[0]?.url).toContain(
|
|
330
|
+
`/project/${PROJECT_ID.toString()}/delete-project`,
|
|
331
|
+
);
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
});
|