diff --git a/packages/cli/src/workflows/workflow.service.ts b/packages/cli/src/workflows/workflow.service.ts index fc0e7894fb8..3e9ae97b5cd 100644 --- a/packages/cli/src/workflows/workflow.service.ts +++ b/packages/cli/src/workflows/workflow.service.ts @@ -265,6 +265,10 @@ export class WorkflowService { ); } + if (workflow.isArchived) { + throw new BadRequestError('Cannot update an archived workflow.'); + } + if (!forceSave && expectedChecksum) { await this._detectConflicts(workflow, expectedChecksum); } @@ -533,6 +537,10 @@ export class WorkflowService { ); } + if (workflow.isArchived) { + throw new BadRequestError('Cannot activate an archived workflow.'); + } + const versionIdToActivate = options?.versionId ?? workflow.versionId; const wasActive = workflow.activeVersionId !== null; diff --git a/packages/cli/test/integration/workflows/workflows.controller.test.ts b/packages/cli/test/integration/workflows/workflows.controller.test.ts index 56c07643293..281003dcc8f 100644 --- a/packages/cli/test/integration/workflows/workflows.controller.test.ts +++ b/packages/cli/test/integration/workflows/workflows.controller.test.ts @@ -3300,6 +3300,24 @@ describe('PATCH /workflows/:workflowId', () => { expect(activeWorkflowManagerLike.add).not.toHaveBeenCalled(); }); + test('should not update an archived workflow', async () => { + const workflow = await createWorkflowWithHistory({ isArchived: true }, owner); + + const response = await authOwnerAgent + .patch(`/workflows/${workflow.id}`) + .send({ + name: 'Updated Name', + }) + .expect(400); + + expect(response.body.message).toBe('Cannot update an archived workflow.'); + + const updatedWorkflow = await workflowRepository.findById(workflow.id); + expect(updatedWorkflow).not.toBeNull(); + expect(updatedWorkflow!.name).toBe(workflow.name); + expect(updatedWorkflow!.isArchived).toBe(true); + }); + describe('Security: Mass Assignment Protection on Update', () => { test.each([ { @@ -3805,6 +3823,23 @@ describe('POST /workflows/:workflowId/activate', () => { workflowId: workflow.id, }); }); + + test('should not activate an archived workflow', async () => { + const workflow = await createWorkflowWithHistory({ isArchived: true }, owner); + + const response = await authOwnerAgent + .post(`/workflows/${workflow.id}/activate`) + .send({ versionId: workflow.versionId }) + .expect(400); + + expect(response.body.message).toBe('Cannot activate an archived workflow.'); + expect(activeWorkflowManagerLike.add).not.toHaveBeenCalled(); + + const updatedWorkflow = await workflowRepository.findById(workflow.id); + expect(updatedWorkflow).not.toBeNull(); + expect(updatedWorkflow!.active).toBe(false); + expect(updatedWorkflow!.activeVersionId).toBeNull(); + }); }); describe('POST /workflows/:workflowId/deactivate', () => {