From e6ec134cf37ac21b26d10162b3d49da7dad85a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Fri, 28 Oct 2022 11:24:11 +0200 Subject: [PATCH] fix(AWS SNS Trigger Node): add missing jsonParse import (#4463) * fix(AwsSnsTrigger): add missing jsonParse import * add clear typings for req.rawBody and getHeaderData() --- packages/cli/src/Server.ts | 5 ----- packages/cli/src/WebhookServer.ts | 4 ---- packages/core/src/NodeExecuteFunctions.ts | 9 +++++---- packages/core/src/index.ts | 6 ++++++ packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts | 7 ++++--- .../nodes/Cisco/Webex/CiscoWebexTrigger.node.ts | 1 - .../nodes-base/nodes/Facebook/FacebookTrigger.node.ts | 1 - .../nodes-base/nodes/HelpScout/HelpScoutTrigger.node.ts | 1 - packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts | 1 - packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts | 1 - packages/nodes-base/nodes/Shopify/ShopifyTrigger.node.ts | 1 - packages/nodes-base/nodes/Wait/Wait.node.ts | 1 - packages/nodes-base/nodes/Webhook/Webhook.node.ts | 1 - packages/nodes-base/nodes/Wise/WiseTrigger.node.ts | 1 - .../nodes/WooCommerce/WooCommerceTrigger.node.ts | 4 ---- packages/workflow/src/Interfaces.ts | 3 ++- 16 files changed, 17 insertions(+), 30 deletions(-) diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 514eddde859ac..2f6ea5e972d2c 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -622,7 +622,6 @@ class App { // Make sure that each request has the "parsedUrl" parameter this.app.use((req: express.Request, res: express.Response, next: express.NextFunction) => { (req as ICustomRequest).parsedUrl = parseUrl(req); - // @ts-ignore req.rawBody = Buffer.from('', 'base64'); next(); }); @@ -632,7 +631,6 @@ class App { bodyParser.json({ limit: `${this.payloadSizeMax}mb`, verify: (req, res, buf) => { - // @ts-ignore req.rawBody = buf; }, }), @@ -649,7 +647,6 @@ class App { explicitArray: false, // Only put properties in array if length > 1 }, verify: (req: express.Request, res: any, buf: any) => { - // @ts-ignore req.rawBody = buf; }, }), @@ -659,7 +656,6 @@ class App { bodyParser.text({ limit: `${this.payloadSizeMax}mb`, verify: (req, res, buf) => { - // @ts-ignore req.rawBody = buf; }, }), @@ -685,7 +681,6 @@ class App { limit: `${this.payloadSizeMax}mb`, extended: false, verify: (req, res, buf) => { - // @ts-ignore req.rawBody = buf; }, }), diff --git a/packages/cli/src/WebhookServer.ts b/packages/cli/src/WebhookServer.ts index d73e62bcad1d4..362ac7089bebd 100644 --- a/packages/cli/src/WebhookServer.ts +++ b/packages/cli/src/WebhookServer.ts @@ -236,7 +236,6 @@ class App { // Make sure that each request has the "parsedUrl" parameter this.app.use((req: express.Request, res: express.Response, next: express.NextFunction) => { (req as ICustomRequest).parsedUrl = parseUrl(req); - // @ts-ignore req.rawBody = Buffer.from('', 'base64'); next(); }); @@ -246,7 +245,6 @@ class App { bodyParser.json({ limit: '16mb', verify: (req, res, buf) => { - // @ts-ignore req.rawBody = buf; }, }), @@ -269,7 +267,6 @@ class App { bodyParser.text({ limit: '16mb', verify: (req, res, buf) => { - // @ts-ignore req.rawBody = buf; }, }), @@ -280,7 +277,6 @@ class App { bodyParser.urlencoded({ extended: false, verify: (req, res, buf) => { - // @ts-ignore req.rawBody = buf; }, }), diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index 9961f9e9536b2..3ba44c3dcca88 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -74,7 +74,7 @@ import crypto, { createHmac } from 'crypto'; // eslint-disable-next-line import/no-extraneous-dependencies import { get } from 'lodash'; // eslint-disable-next-line import/no-extraneous-dependencies -import express from 'express'; +import type { Request, Response } from 'express'; import FormData from 'form-data'; import path from 'path'; import { OptionsWithUri, OptionsWithUrl } from 'request'; @@ -103,6 +103,7 @@ import { } from '.'; import { extractValue } from './ExtractValue'; import { getClientCredentialsToken } from './OAuth2Helper'; +import { IncomingHttpHeaders } from 'http'; axios.defaults.timeout = 300000; // Prevent axios from adding x-form-www-urlencoded headers by default @@ -2937,7 +2938,7 @@ export function getExecuteWebhookFunctions( async getCredentials(type: string): Promise { return getCredentials(workflow, node, type, additionalData, mode); }, - getHeaderData(): object { + getHeaderData(): IncomingHttpHeaders { if (additionalData.httpRequest === undefined) { throw new Error('Request is missing!'); } @@ -2987,13 +2988,13 @@ export function getExecuteWebhookFunctions( } return additionalData.httpRequest.query; }, - getRequestObject(): express.Request { + getRequestObject(): Request { if (additionalData.httpRequest === undefined) { throw new Error('Request is missing!'); } return additionalData.httpRequest; }, - getResponseObject(): express.Response { + getResponseObject(): Response { if (additionalData.httpResponse === undefined) { throw new Error('Response is missing!'); } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6a327177ccc5c..e5fda891e87de 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -19,3 +19,9 @@ export * from './LoadNodeListSearch'; export * from './NodeExecuteFunctions'; export * from './WorkflowExecute'; export { NodeExecuteFunctions, UserSettings }; + +declare module 'http' { + export interface IncomingMessage { + rawBody: Buffer; + } +} diff --git a/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts b/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts index 629e85340f307..290eb09284472 100644 --- a/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts +++ b/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts @@ -6,7 +6,7 @@ import { INodeType, INodeTypeDescription, IWebhookResponseData, - NodeApiError, + jsonParse, NodeOperationError, } from 'n8n-workflow'; @@ -177,8 +177,9 @@ export class AwsSnsTrigger implements INodeType { const req = this.getRequestObject(); const topic = this.getNodeParameter('topic') as string; - // @ts-ignore - const body = jsonParse(req.rawBody.toString()); + const body = jsonParse<{ Type: string; TopicArn: string; Token: string }>( + req.rawBody.toString(), + ); if (body.Type === 'SubscriptionConfirmation' && body.TopicArn === topic) { const { Token } = body; diff --git a/packages/nodes-base/nodes/Cisco/Webex/CiscoWebexTrigger.node.ts b/packages/nodes-base/nodes/Cisco/Webex/CiscoWebexTrigger.node.ts index f1e6a015c93b5..f07f8f185559b 100644 --- a/packages/nodes-base/nodes/Cisco/Webex/CiscoWebexTrigger.node.ts +++ b/packages/nodes-base/nodes/Cisco/Webex/CiscoWebexTrigger.node.ts @@ -587,7 +587,6 @@ export class CiscoWebexTrigger implements INodeType { //@ts-ignore const computedSignature = createHmac('sha1', webhookData.secret) - //@ts-ignore .update(req.rawBody) .digest('hex'); if (headers['x-spark-signature'] !== computedSignature) { diff --git a/packages/nodes-base/nodes/Facebook/FacebookTrigger.node.ts b/packages/nodes-base/nodes/Facebook/FacebookTrigger.node.ts index 881d178757b57..607c31a3403cf 100644 --- a/packages/nodes-base/nodes/Facebook/FacebookTrigger.node.ts +++ b/packages/nodes-base/nodes/Facebook/FacebookTrigger.node.ts @@ -268,7 +268,6 @@ export class FacebookTrigger implements INodeType { // validate signature if app secret is set if (credentials.appSecret !== '') { const computedSignature = createHmac('sha1', credentials.appSecret as string) - //@ts-ignore .update(req.rawBody) .digest('hex'); if (headerData['x-hub-signature'] !== `sha1=${computedSignature}`) { diff --git a/packages/nodes-base/nodes/HelpScout/HelpScoutTrigger.node.ts b/packages/nodes-base/nodes/HelpScout/HelpScoutTrigger.node.ts index 4417634f14787..1e1ca92912a04 100644 --- a/packages/nodes-base/nodes/HelpScout/HelpScoutTrigger.node.ts +++ b/packages/nodes-base/nodes/HelpScout/HelpScoutTrigger.node.ts @@ -189,7 +189,6 @@ export class HelpScoutTrigger implements INodeType { } const computedSignature = createHmac('sha1', webhookData.secret as string) - //@ts-ignore .update(req.rawBody) .digest('base64'); if (headerData['x-helpscout-signature'] !== computedSignature) { diff --git a/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts b/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts index 068c465792cec..45e451f4db87a 100644 --- a/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts +++ b/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts @@ -157,7 +157,6 @@ export class JotFormTrigger implements INodeType { }, }; - //@ts-ignore async webhook(this: IWebhookFunctions): Promise { const req = this.getRequestObject(); const formId = this.getNodeParameter('form') as string; diff --git a/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts b/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts index 4277c71eed27e..44716f34e096f 100644 --- a/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts +++ b/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts @@ -119,7 +119,6 @@ export class MailjetTrigger implements INodeType { }, }; - //@ts-ignore async webhook(this: IWebhookFunctions): Promise { const req = this.getRequestObject(); return { diff --git a/packages/nodes-base/nodes/Shopify/ShopifyTrigger.node.ts b/packages/nodes-base/nodes/Shopify/ShopifyTrigger.node.ts index aac21fa113546..1168f658a72a3 100644 --- a/packages/nodes-base/nodes/Shopify/ShopifyTrigger.node.ts +++ b/packages/nodes-base/nodes/Shopify/ShopifyTrigger.node.ts @@ -412,7 +412,6 @@ export class ShopifyTrigger implements INodeType { headerData['x-shopify-shop-domain'] !== undefined && headerData['x-shopify-api-version'] !== undefined ) { - // @ts-ignore const computedSignature = createHmac('sha256', secret).update(req.rawBody).digest('base64'); if (headerData['x-shopify-hmac-sha256'] !== computedSignature) { diff --git a/packages/nodes-base/nodes/Wait/Wait.node.ts b/packages/nodes-base/nodes/Wait/Wait.node.ts index e4b31a5a80d2a..b5192bb3ec14c 100644 --- a/packages/nodes-base/nodes/Wait/Wait.node.ts +++ b/packages/nodes-base/nodes/Wait/Wait.node.ts @@ -781,7 +781,6 @@ export class Wait implements INodeType { if (options.rawBody) { response.binary = { data: { - // @ts-ignore data: req.rawBody.toString(BINARY_ENCODING), mimeType, }, diff --git a/packages/nodes-base/nodes/Webhook/Webhook.node.ts b/packages/nodes-base/nodes/Webhook/Webhook.node.ts index d1769449fce17..6ea1fddc5982c 100644 --- a/packages/nodes-base/nodes/Webhook/Webhook.node.ts +++ b/packages/nodes-base/nodes/Webhook/Webhook.node.ts @@ -593,7 +593,6 @@ export class Webhook implements INodeType { if (options.rawBody) { response.binary = { data: { - // @ts-ignore data: req.rawBody.toString(BINARY_ENCODING), mimeType, }, diff --git a/packages/nodes-base/nodes/Wise/WiseTrigger.node.ts b/packages/nodes-base/nodes/Wise/WiseTrigger.node.ts index 27ea6c30ca311..24bf362732aa7 100644 --- a/packages/nodes-base/nodes/Wise/WiseTrigger.node.ts +++ b/packages/nodes-base/nodes/Wise/WiseTrigger.node.ts @@ -182,7 +182,6 @@ export class WiseTrigger implements INodeType { const publicKey = credentials.environment === 'test' ? testPublicKey : (livePublicKey as string); - //@ts-ignore const sig = createVerify('RSA-SHA1').update(req.rawBody); const verified = sig.verify(publicKey, signature, 'base64'); diff --git a/packages/nodes-base/nodes/WooCommerce/WooCommerceTrigger.node.ts b/packages/nodes-base/nodes/WooCommerce/WooCommerceTrigger.node.ts index 0a749946786e4..086b107f6c55e 100644 --- a/packages/nodes-base/nodes/WooCommerce/WooCommerceTrigger.node.ts +++ b/packages/nodes-base/nodes/WooCommerce/WooCommerceTrigger.node.ts @@ -156,21 +156,17 @@ export class WooCommerceTrigger implements INodeType { }, }; - //@ts-ignore async webhook(this: IWebhookFunctions): Promise { const req = this.getRequestObject(); const headerData = this.getHeaderData(); const webhookData = this.getWorkflowStaticData('node'); - //@ts-ignore if (headerData['x-wc-webhook-id'] === undefined) { return {}; } const computedSignature = createHmac('sha256', webhookData.secret as string) - //@ts-ignore .update(req.rawBody) .digest('base64'); - //@ts-ignore if (headerData['x-wc-webhook-signature'] !== computedSignature) { // Signature is not valid so ignore call return {}; diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 5a3357f13e74a..c51b200344ac8 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -4,6 +4,7 @@ // eslint-disable-next-line max-classes-per-file import * as express from 'express'; import * as FormData from 'form-data'; +import type { IncomingHttpHeaders } from 'http'; import type { URLSearchParams } from 'url'; import type { IDeferredPromise } from './DeferredPromise'; import type { Workflow } from './Workflow'; @@ -784,7 +785,7 @@ export interface ITriggerFunctions { export interface IWebhookFunctions { getBodyData(): IDataObject; getCredentials(type: string): Promise; - getHeaderData(): object; + getHeaderData(): IncomingHttpHeaders; getMode(): WorkflowExecuteMode; getNode(): INode; getNodeParameter(