diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index de561725ed..971aeb23f0 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -231,19 +231,28 @@ class App { }); // Support application/json type post data - this.app.use(bodyParser.json({ limit: "16mb", verify: (req, res, buf) => { - // @ts-ignore - req.rawBody = buf; - }})); + this.app.use(bodyParser.json({ + limit: '16mb', verify: (req, res, buf) => { + // @ts-ignore + req.rawBody = buf; + } + })); // Support application/xml type post data // @ts-ignore - this.app.use(bodyParser.xml({ limit: "16mb", xmlParseOptions: { + this.app.use(bodyParser.xml({ limit: '16mb', xmlParseOptions: { normalize: true, // Trim whitespace inside text nodes normalizeTags: true, // Transform tags to lowercase - explicitArray: false // Only put properties in array if length > 1 + explicitArray: false, // Only put properties in array if length > 1 } })); + this.app.use(bodyParser.text({ + limit: '16mb', verify: (req, res, buf) => { + // @ts-ignore + req.rawBody = buf; + } + })); + // Make sure that Vue history mode works properly this.app.use(history({ rewrites: [ diff --git a/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts b/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts index da501d7fb0..3d4b63b30b 100644 --- a/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts +++ b/packages/nodes-base/nodes/Aws/AwsSnsTrigger.node.ts @@ -21,13 +21,13 @@ export class AwsSnsTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'AWS SNS Trigger', subtitle: `={{$parameter["topic"].split(':')[5]}}`, - name: 'AwsSnsTrigger', + name: 'awsSnsTrigger', icon: 'file:sns.png', group: ['trigger'], version: 1, description: 'Handle AWS SNS events via webhooks', defaults: { - name: 'AWS SNS Trigger', + name: 'AWS-SNS-Trigger', color: '#FF9900', }, inputs: [], @@ -108,7 +108,7 @@ export class AwsSnsTrigger implements INodeType { 'Version=2010-03-31', ]; const data = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ListSubscriptionsByTopic&' + params.join('&')); - const subscriptions = get(data, 'ListSubscriptionsByTopicResponse.ListSubscriptionsByTopicResult.Subscriptions.member') + const subscriptions = get(data, 'ListSubscriptionsByTopicResponse.ListSubscriptionsByTopicResult.Subscriptions.member'); for (const subscription of subscriptions) { if (webhookData.webhookId === subscription.SubscriptionArn) { return true; @@ -118,8 +118,13 @@ export class AwsSnsTrigger implements INodeType { }, async create(this: IHookFunctions): Promise { const webhookData = this.getWorkflowStaticData('node'); - const webhookUrl = this.getNodeWebhookUrl('default'); + const webhookUrl = this.getNodeWebhookUrl('default') as string; const topic = this.getNodeParameter('topic') as string; + + if (webhookUrl.includes('%20')) { + throw new Error('The name of the SNS Trigger Node is not allowed to contain any spaces!'); + } + const params = [ `TopicArn=${topic}`, `Endpoint=${webhookUrl}`, @@ -127,12 +132,10 @@ export class AwsSnsTrigger implements INodeType { 'ReturnSubscriptionArn=true', 'Version=2010-03-31', ]; - try { - const { SubscribeResponse } = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Subscribe&' + params.join('&')); - webhookData.webhookId = SubscribeResponse.SubscribeResult.SubscriptionArn; - } catch (err) { - throw new Error(err); - } + + const { SubscribeResponse } = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Subscribe&' + params.join('&')); + webhookData.webhookId = SubscribeResponse.SubscribeResult.SubscriptionArn; + return true; }, async delete(this: IHookFunctions): Promise { @@ -155,24 +158,33 @@ export class AwsSnsTrigger implements INodeType { async webhook(this: IWebhookFunctions): Promise { const req = this.getRequestObject(); const topic = this.getNodeParameter('topic') as string; - if (req.body.Type === 'SubscriptionConfirmation' && - req.body.TopicArn === topic) { - const { Token } = req.body; + + // @ts-ignore + const body = JSON.parse((req.rawBody).toString()); + + if (body.Type === 'SubscriptionConfirmation' && + body.TopicArn === topic) { + const { Token } = body; const params = [ `TopicArn=${topic}`, `Token=${Token}`, 'Version=2010-03-31', ]; await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ConfirmSubscription&' + params.join('&')); + + return { + noWebhookResponse: true, + }; + } + + if (body.Type === 'UnsubscribeConfirmation') { return {}; } - if (req.body.Type === 'UnsubscribeConfirmation') { - return {}; - } + //TODO verify message signature return { workflowData: [ - this.helpers.returnJsonArray(req.body), + this.helpers.returnJsonArray(body), ], }; } diff --git a/packages/nodes-base/nodes/Aws/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/GenericFunctions.ts index 31e25dce39..ff1a6a5fd2 100644 --- a/packages/nodes-base/nodes/Aws/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Aws/GenericFunctions.ts @@ -42,10 +42,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I } } - if (errorMessage !== undefined) { - throw errorMessage; - } - throw error.response.body; + throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`); } }