🐛 Fix SNS-Trigger-Node

This commit is contained in:
Jan Oberhauser 2020-02-09 18:27:06 -08:00
parent ca047b9c78
commit 3fe236b9e6
3 changed files with 45 additions and 27 deletions

View file

@ -231,19 +231,28 @@ class App {
}); });
// Support application/json type post data // Support application/json type post data
this.app.use(bodyParser.json({ limit: "16mb", verify: (req, res, buf) => { this.app.use(bodyParser.json({
// @ts-ignore limit: '16mb', verify: (req, res, buf) => {
req.rawBody = buf; // @ts-ignore
}})); req.rawBody = buf;
}
}));
// Support application/xml type post data // Support application/xml type post data
// @ts-ignore // @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 normalize: true, // Trim whitespace inside text nodes
normalizeTags: true, // Transform tags to lowercase 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 // Make sure that Vue history mode works properly
this.app.use(history({ this.app.use(history({
rewrites: [ rewrites: [

View file

@ -21,13 +21,13 @@ export class AwsSnsTrigger implements INodeType {
description: INodeTypeDescription = { description: INodeTypeDescription = {
displayName: 'AWS SNS Trigger', displayName: 'AWS SNS Trigger',
subtitle: `={{$parameter["topic"].split(':')[5]}}`, subtitle: `={{$parameter["topic"].split(':')[5]}}`,
name: 'AwsSnsTrigger', name: 'awsSnsTrigger',
icon: 'file:sns.png', icon: 'file:sns.png',
group: ['trigger'], group: ['trigger'],
version: 1, version: 1,
description: 'Handle AWS SNS events via webhooks', description: 'Handle AWS SNS events via webhooks',
defaults: { defaults: {
name: 'AWS SNS Trigger', name: 'AWS-SNS-Trigger',
color: '#FF9900', color: '#FF9900',
}, },
inputs: [], inputs: [],
@ -108,7 +108,7 @@ export class AwsSnsTrigger implements INodeType {
'Version=2010-03-31', 'Version=2010-03-31',
]; ];
const data = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ListSubscriptionsByTopic&' + params.join('&')); 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) { for (const subscription of subscriptions) {
if (webhookData.webhookId === subscription.SubscriptionArn) { if (webhookData.webhookId === subscription.SubscriptionArn) {
return true; return true;
@ -118,8 +118,13 @@ export class AwsSnsTrigger implements INodeType {
}, },
async create(this: IHookFunctions): Promise<boolean> { async create(this: IHookFunctions): Promise<boolean> {
const webhookData = this.getWorkflowStaticData('node'); const webhookData = this.getWorkflowStaticData('node');
const webhookUrl = this.getNodeWebhookUrl('default'); const webhookUrl = this.getNodeWebhookUrl('default') as string;
const topic = this.getNodeParameter('topic') 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 = [ const params = [
`TopicArn=${topic}`, `TopicArn=${topic}`,
`Endpoint=${webhookUrl}`, `Endpoint=${webhookUrl}`,
@ -127,12 +132,10 @@ export class AwsSnsTrigger implements INodeType {
'ReturnSubscriptionArn=true', 'ReturnSubscriptionArn=true',
'Version=2010-03-31', 'Version=2010-03-31',
]; ];
try {
const { SubscribeResponse } = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Subscribe&' + params.join('&')); const { SubscribeResponse } = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Subscribe&' + params.join('&'));
webhookData.webhookId = SubscribeResponse.SubscribeResult.SubscriptionArn; webhookData.webhookId = SubscribeResponse.SubscribeResult.SubscriptionArn;
} catch (err) {
throw new Error(err);
}
return true; return true;
}, },
async delete(this: IHookFunctions): Promise<boolean> { async delete(this: IHookFunctions): Promise<boolean> {
@ -155,24 +158,33 @@ export class AwsSnsTrigger implements INodeType {
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> { async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
const req = this.getRequestObject(); const req = this.getRequestObject();
const topic = this.getNodeParameter('topic') as string; const topic = this.getNodeParameter('topic') as string;
if (req.body.Type === 'SubscriptionConfirmation' &&
req.body.TopicArn === topic) { // @ts-ignore
const { Token } = req.body; const body = JSON.parse((req.rawBody).toString());
if (body.Type === 'SubscriptionConfirmation' &&
body.TopicArn === topic) {
const { Token } = body;
const params = [ const params = [
`TopicArn=${topic}`, `TopicArn=${topic}`,
`Token=${Token}`, `Token=${Token}`,
'Version=2010-03-31', 'Version=2010-03-31',
]; ];
await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ConfirmSubscription&' + params.join('&')); await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=ConfirmSubscription&' + params.join('&'));
return {
noWebhookResponse: true,
};
}
if (body.Type === 'UnsubscribeConfirmation') {
return {}; return {};
} }
if (req.body.Type === 'UnsubscribeConfirmation') {
return {};
}
//TODO verify message signature //TODO verify message signature
return { return {
workflowData: [ workflowData: [
this.helpers.returnJsonArray(req.body), this.helpers.returnJsonArray(body),
], ],
}; };
} }

View file

@ -42,10 +42,7 @@ export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | I
} }
} }
if (errorMessage !== undefined) { throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
throw errorMessage;
}
throw error.response.body;
} }
} }