From 224e008fb64dabef99998508eb4385e1b872c5ad Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Mon, 4 Jul 2022 11:44:26 +0300 Subject: [PATCH] feat(Webflow Trigger Node): Reduce chance of webhook duplication and add credential test (#3594) * upstream merge * :zap: additional check for webhook, credentials update * :fire: Remove unnecessary condition * :zap: Change credential injection to generic type * :shirt: Fix linting issue Co-authored-by: ricardo --- package-lock.json | 15 ++++++++++++ .../credentials/WebflowApi.credentials.ts | 16 +++++++++++++ .../nodes/Webflow/GenericFunctions.ts | 23 ++++++++++--------- .../nodes/Webflow/WebflowTrigger.node.ts | 22 ++++++++++-------- 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc42d8b3f1..1a01aae011 100644 --- a/package-lock.json +++ b/package-lock.json @@ -104518,6 +104518,21 @@ "safe-buffer": "~5.2.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", diff --git a/packages/nodes-base/credentials/WebflowApi.credentials.ts b/packages/nodes-base/credentials/WebflowApi.credentials.ts index f569814d6a..03b03808d7 100644 --- a/packages/nodes-base/credentials/WebflowApi.credentials.ts +++ b/packages/nodes-base/credentials/WebflowApi.credentials.ts @@ -1,4 +1,6 @@ import { + IAuthenticateGeneric, + ICredentialTestRequest, ICredentialType, INodeProperties, } from 'n8n-workflow'; @@ -15,4 +17,18 @@ export class WebflowApi implements ICredentialType { default: '', }, ]; + authenticate: IAuthenticateGeneric = { + type: 'generic', + properties: { + headers: { + 'Authorization': '=Bearer {{$credentials.accessToken}}', + }, + }, + }; + test: ICredentialTestRequest = { + request: { + baseURL: 'https://api.webflow.com', + url: '/sites', + }, + }; } diff --git a/packages/nodes-base/nodes/Webflow/GenericFunctions.ts b/packages/nodes-base/nodes/Webflow/GenericFunctions.ts index ec0b338683..a4cb4e4795 100644 --- a/packages/nodes-base/nodes/Webflow/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Webflow/GenericFunctions.ts @@ -12,7 +12,6 @@ import { import { IDataObject, NodeApiError, - NodeOperationError, } from 'n8n-workflow'; export async function webflowApiRequest( @@ -24,7 +23,17 @@ export async function webflowApiRequest( uri?: string, option: IDataObject = {}, ) { - const authenticationMethod = this.getNodeParameter('authentication', 0); + const authenticationMethod = this.getNodeParameter('authentication', 0, 'accessToken'); + let credentialsType = ''; + + if (authenticationMethod === 'accessToken') { + credentialsType = 'webflowApi'; + } + + if (authenticationMethod === 'oAuth2') { + credentialsType = 'webflowOAuth2Api'; + } + let options: OptionsWithUri = { headers: { @@ -46,15 +55,7 @@ export async function webflowApiRequest( delete options.body; } try { - if (authenticationMethod === 'accessToken') { - const credentials = await this.getCredentials('webflowApi'); - - options.headers!['authorization'] = `Bearer ${credentials.accessToken}`; - - return await this.helpers.request!(options); - } else { - return await this.helpers.requestOAuth2!.call(this, 'webflowOAuth2Api', options); - } + return await this.helpers.requestWithAuthentication.call(this, credentialsType, options); } catch (error) { throw new NodeApiError(this.getNode(), error); } diff --git a/packages/nodes-base/nodes/Webflow/WebflowTrigger.node.ts b/packages/nodes-base/nodes/Webflow/WebflowTrigger.node.ts index 2c66f787fd..d7b7b34e5d 100644 --- a/packages/nodes-base/nodes/Webflow/WebflowTrigger.node.ts +++ b/packages/nodes-base/nodes/Webflow/WebflowTrigger.node.ts @@ -208,18 +208,22 @@ export class WebflowTrigger implements INodeType { default: { async checkExists(this: IHookFunctions): Promise { const webhookData = this.getWorkflowStaticData('node'); + const webhookUrl = this.getNodeWebhookUrl('default'); const siteId = this.getNodeParameter('site') as string; - if (webhookData.webhookId === undefined) { - return false; + + const event = this.getNodeParameter('event') as string; + const registeredWebhooks = await webflowApiRequest.call(this, 'GET', `/sites/${siteId}/webhooks`) as IDataObject[]; + + for (const webhook of registeredWebhooks) { + if (webhook.url === webhookUrl && webhook.triggerType === event) { + webhookData.webhookId = webhook._id; + return true; + } } - const endpoint = `/sites/${siteId}/webhooks/${webhookData.webhookId}`; - try { - await webflowApiRequest.call(this, 'GET', endpoint); - } catch (error) { - return false; - } - return true; + + return false; }, + async create(this: IHookFunctions): Promise { const webhookUrl = this.getNodeWebhookUrl('default'); const webhookData = this.getWorkflowStaticData('node');