diff --git a/packages/cli/src/webhooks/__tests__/waiting-forms.test.ts b/packages/cli/src/webhooks/__tests__/waiting-forms.test.ts index 6d599b65c95..3aab8c52846 100644 --- a/packages/cli/src/webhooks/__tests__/waiting-forms.test.ts +++ b/packages/cli/src/webhooks/__tests__/waiting-forms.test.ts @@ -228,6 +228,98 @@ describe('WaitingForms', () => { expect(res.send).toHaveBeenCalledWith(execution.status); }); + it('should set CORS headers when origin header is present for status endpoint', async () => { + const execution = mock({ + status: 'success', + }); + executionRepository.findSingleExecution.mockResolvedValue(execution); + + const req = mock({ + headers: { origin: 'null' }, + params: { + path: '123', + suffix: WAITING_FORMS_EXECUTION_STATUS, + }, + }); + + const res = mock(); + + await waitingForms.executeWebhook(req, res); + + expect(res.header).toHaveBeenCalledWith('Access-Control-Allow-Origin', 'null'); + }); + + it('should not set CORS headers when origin header is missing for status endpoint', async () => { + const execution = mock({ + status: 'success', + }); + executionRepository.findSingleExecution.mockResolvedValue(execution); + + const req = mock({ + headers: { origin: undefined }, + params: { + path: '123', + suffix: WAITING_FORMS_EXECUTION_STATUS, + }, + }); + + const res = mock(); + + await waitingForms.executeWebhook(req, res); + + expect(res.header).not.toHaveBeenCalledWith('Access-Control-Allow-Origin', expect.anything()); + }); + + it('should not set CORS headers for non-status endpoints', async () => { + const execution = mock({ + finished: true, + status: 'success', + data: { + resultData: { + lastNodeExecuted: 'LastNode', + runData: {}, + error: undefined, + }, + }, + workflowData: { + id: 'workflow1', + name: 'Test Workflow', + nodes: [ + { + name: 'LastNode', + type: 'other-node-type', + typeVersion: 1, + position: [0, 0], + parameters: {}, + }, + ], + connections: {}, + active: false, + activeVersionId: undefined, + settings: {}, + staticData: {}, + isArchived: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + }); + executionRepository.findSingleExecution.mockResolvedValue(execution); + + const req = mock({ + headers: { origin: 'null' }, + params: { + path: '123', + suffix: undefined, + }, + }); + + const res = mock(); + + await waitingForms.executeWebhook(req, res); + + expect(res.header).not.toHaveBeenCalledWith('Access-Control-Allow-Origin', expect.anything()); + }); + it('should handle old executions with missing activeVersionId field when active=true', () => { const execution = mock({ workflowData: { diff --git a/packages/cli/src/webhooks/waiting-forms.ts b/packages/cli/src/webhooks/waiting-forms.ts index d4c115a3117..324bc1da1b3 100644 --- a/packages/cli/src/webhooks/waiting-forms.ts +++ b/packages/cli/src/webhooks/waiting-forms.ts @@ -96,6 +96,11 @@ export class WaitingForms extends WaitingWebhooks { status = 'form-waiting'; } } + + if (req.headers.origin) { + res.header('Access-Control-Allow-Origin', req.headers.origin); + } + res.send(status); return { noWebhookResponse: true }; }