From ea36ec0bcfd37b57d17915623e5b4765e87c5933 Mon Sep 17 00:00:00 2001 From: Csaba Tuncsik Date: Fri, 24 Nov 2023 17:24:57 +0100 Subject: [PATCH 1/2] fix: Suppress dev server websocket messages in workflow view --- .../src/components/WorkflowPreview.vue | 26 ++++++++++--------- .../__tests__/WorkflowPreview.test.ts | 20 ++++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/packages/editor-ui/src/components/WorkflowPreview.vue b/packages/editor-ui/src/components/WorkflowPreview.vue index 1fd3948b6e1a4..ee8a29d817d9f 100644 --- a/packages/editor-ui/src/components/WorkflowPreview.vue +++ b/packages/editor-ui/src/components/WorkflowPreview.vue @@ -135,19 +135,21 @@ const onMouseLeave = () => { }; const receiveMessage = ({ data }: MessageEvent) => { - try { - const json = JSON.parse(data); - if (json.command === 'n8nReady') { - ready.value = true; - } else if (json.command === 'openNDV') { - nodeViewDetailsOpened.value = true; - } else if (json.command === 'closeNDV') { - nodeViewDetailsOpened.value = false; - } else if (json.command === 'error') { - emit('close'); + if (data?.includes('"command"')) { + try { + const json = JSON.parse(data); + if (json.command === 'n8nReady') { + ready.value = true; + } else if (json.command === 'openNDV') { + nodeViewDetailsOpened.value = true; + } else if (json.command === 'closeNDV') { + nodeViewDetailsOpened.value = false; + } else if (json.command === 'error') { + emit('close'); + } + } catch (e) { + console.error(e); } - } catch (e) { - console.error(e); } }; const onDocumentScroll = () => { diff --git a/packages/editor-ui/src/components/__tests__/WorkflowPreview.test.ts b/packages/editor-ui/src/components/__tests__/WorkflowPreview.test.ts index 7297544a81fcc..78ab1a6a41a19 100644 --- a/packages/editor-ui/src/components/__tests__/WorkflowPreview.test.ts +++ b/packages/editor-ui/src/components/__tests__/WorkflowPreview.test.ts @@ -12,6 +12,7 @@ const renderComponent = createComponentRenderer(WorkflowPreview); let pinia: ReturnType; let workflowsStore: ReturnType; let postMessageSpy: vi.SpyInstance; +let consoleErrorSpy: vi.SpyInstance; const sendPostMessageCommand = (command: string) => { window.postMessage(`{"command":"${command}"}`, '*'); @@ -23,6 +24,7 @@ describe('WorkflowPreview', () => { setActivePinia(pinia); workflowsStore = useWorkflowsStore(); + consoleErrorSpy = vi.spyOn(console, 'error'); postMessageSpy = vi.fn(); Object.defineProperty(HTMLIFrameElement.prototype, 'contentWindow', { writable: true, @@ -32,6 +34,10 @@ describe('WorkflowPreview', () => { }); }); + afterEach(() => { + consoleErrorSpy.mockRestore(); + }); + it('should not call iframe postMessage when it is ready and no workflow or executionId props', async () => { renderComponent({ pinia, @@ -227,4 +233,18 @@ describe('WorkflowPreview', () => { expect(emitted().close).toBeDefined(); }); }); + + it('should not do anything if no "command" is sent in the message', async () => { + const { emitted } = renderComponent({ + pinia, + props: {}, + }); + + window.postMessage('commando', '*'); + + await waitFor(() => { + expect(console.error).not.toHaveBeenCalled(); + expect(emitted()).toEqual({}); + }); + }); }); From ba17b7765fca94e3f33922fc8c490477956820c4 Mon Sep 17 00:00:00 2001 From: Csaba Tuncsik Date: Fri, 24 Nov 2023 17:28:36 +0100 Subject: [PATCH 2/2] fix: Suppress message process in NodeView if there is no command --- packages/editor-ui/src/views/NodeView.vue | 96 ++++++++++++----------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue index 705780fac7550..935f168418561 100644 --- a/packages/editor-ui/src/views/NodeView.vue +++ b/packages/editor-ui/src/views/NodeView.vue @@ -4211,56 +4211,58 @@ export default defineComponent({ } }, async onPostMessageReceived(message: MessageEvent) { - try { - const json = JSON.parse(message.data); - if (json && json.command === 'openWorkflow') { - try { - await this.importWorkflowExact(json); - this.isExecutionPreview = false; - } catch (e) { - if (window.top) { - window.top.postMessage( - JSON.stringify({ - command: 'error', - message: this.$locale.baseText('openWorkflow.workflowImportError'), - }), - '*', - ); + if (message?.data?.includes('"command"')) { + try { + const json = JSON.parse(message.data); + if (json && json.command === 'openWorkflow') { + try { + await this.importWorkflowExact(json); + this.isExecutionPreview = false; + } catch (e) { + if (window.top) { + window.top.postMessage( + JSON.stringify({ + command: 'error', + message: this.$locale.baseText('openWorkflow.workflowImportError'), + }), + '*', + ); + } + this.showMessage({ + title: this.$locale.baseText('openWorkflow.workflowImportError'), + message: (e as Error).message, + type: 'error', + }); } - this.showMessage({ - title: this.$locale.baseText('openWorkflow.workflowImportError'), - message: (e as Error).message, - type: 'error', - }); - } - } else if (json && json.command === 'openExecution') { - try { - // If this NodeView is used in preview mode (in iframe) it will not have access to the main app store - // so everything it needs has to be sent using post messages and passed down to child components - this.isProductionExecutionPreview = json.executionMode !== 'manual'; - - await this.openExecution(json.executionId); - this.isExecutionPreview = true; - } catch (e) { - if (window.top) { - window.top.postMessage( - JSON.stringify({ - command: 'error', - message: this.$locale.baseText('nodeView.showError.openExecution.title'), - }), - '*', - ); + } else if (json && json.command === 'openExecution') { + try { + // If this NodeView is used in preview mode (in iframe) it will not have access to the main app store + // so everything it needs has to be sent using post messages and passed down to child components + this.isProductionExecutionPreview = json.executionMode !== 'manual'; + + await this.openExecution(json.executionId); + this.isExecutionPreview = true; + } catch (e) { + if (window.top) { + window.top.postMessage( + JSON.stringify({ + command: 'error', + message: this.$locale.baseText('nodeView.showError.openExecution.title'), + }), + '*', + ); + } + this.showMessage({ + title: this.$locale.baseText('nodeView.showError.openExecution.title'), + message: (e as Error).message, + type: 'error', + }); } - this.showMessage({ - title: this.$locale.baseText('nodeView.showError.openExecution.title'), - message: (e as Error).message, - type: 'error', - }); + } else if (json?.command === 'setActiveExecution') { + this.workflowsStore.activeWorkflowExecution = json.execution; } - } else if (json?.command === 'setActiveExecution') { - this.workflowsStore.activeWorkflowExecution = json.execution; - } - } catch (e) {} + } catch (e) {} + } }, async onImportWorkflowDataEvent(data: IDataObject) { await this.importWorkflowData(data.data as IWorkflowDataUpdate, 'file');