diff --git a/packages/nodes-base/credentials/HttpCustomAuth.credentials.ts b/packages/nodes-base/credentials/HttpCustomAuth.credentials.ts new file mode 100644 index 0000000000000..405d7b7cdf3ee --- /dev/null +++ b/packages/nodes-base/credentials/HttpCustomAuth.credentials.ts @@ -0,0 +1,28 @@ +/* eslint-disable n8n-nodes-base/cred-class-field-name-unsuffixed */ +/* eslint-disable n8n-nodes-base/cred-class-name-unsuffixed */ +import type { ICredentialType, INodeProperties } from 'n8n-workflow'; + +export class HttpCustomAuth implements ICredentialType { + name = 'httpCustomAuth'; + + displayName = 'Custom Auth'; + + documentationUrl = 'httpRequest'; + + genericAuth = true; + + icon = 'node:n8n-nodes-base.httpRequest'; + + properties: INodeProperties[] = [ + { + displayName: 'JSON', + name: 'json', + type: 'json', + required: true, + description: 'Use json to specify authentication values for headers, body and qs.', + placeholder: + '{ "headers": { "key" : "value" }, "body": { "key": "value" }, "qs": { "key": "value" } }', + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts index 13129d9d3aea2..4e5598d11bcb5 100644 --- a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts +++ b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts @@ -6,8 +6,9 @@ import type { INodeType, INodeTypeDescription, JsonObject, + IRequestOptionsSimplified, } from 'n8n-workflow'; -import { NodeApiError, NodeOperationError } from 'n8n-workflow'; +import { NodeApiError, NodeOperationError, jsonParse } from 'n8n-workflow'; import type { OptionsWithUri } from 'request'; import type { RequestPromiseOptions } from 'request-promise-native'; @@ -36,6 +37,15 @@ export class GraphQL implements INodeType { }, }, }, + { + name: 'httpCustomAuth', + required: true, + displayOptions: { + show: { + authentication: ['customAuth'], + }, + }, + }, { name: 'httpDigestAuth', required: true, @@ -92,6 +102,10 @@ export class GraphQL implements INodeType { name: 'Basic Auth', value: 'basicAuth', }, + { + name: 'Custom Auth', + value: 'customAuth', + }, { name: 'Digest Auth', value: 'digestAuth', @@ -284,6 +298,7 @@ export class GraphQL implements INodeType { const items = this.getInputData(); let httpBasicAuth; let httpDigestAuth; + let httpCustomAuth; let httpHeaderAuth; let httpQueryAuth; let oAuth1Api; @@ -294,6 +309,11 @@ export class GraphQL implements INodeType { } catch (error) { // Do nothing } + try { + httpCustomAuth = await this.getCredentials('httpCustomAuth'); + } catch (error) { + // Do nothing + } try { httpDigestAuth = await this.getCredentials('httpDigestAuth'); } catch (error) { @@ -361,6 +381,21 @@ export class GraphQL implements INodeType { pass: httpBasicAuth.password as string, }; } + if (httpCustomAuth !== undefined) { + const customAuth = jsonParse( + (httpCustomAuth.json as string) || '{}', + { errorMessage: 'Invalid Custom Auth JSON' }, + ); + if (customAuth.headers) { + requestOptions.headers = { ...requestOptions.headers, ...customAuth.headers }; + } + if (customAuth.body) { + requestOptions.body = { ...requestOptions.body, ...customAuth.body }; + } + if (customAuth.qs) { + requestOptions.qs = { ...requestOptions.qs, ...customAuth.qs }; + } + } if (httpHeaderAuth !== undefined) { requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value; } @@ -387,6 +422,7 @@ export class GraphQL implements INodeType { } else { if (requestFormat === 'json') { requestOptions.body = { + ...requestOptions.body, query: gqlQuery, variables: this.getNodeParameter('variables', itemIndex, {}) as object, operationName: this.getNodeParameter('operationName', itemIndex) as string, diff --git a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts index 78288365639bb..915edb166d645 100644 --- a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts +++ b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts @@ -8,6 +8,7 @@ import type { INodeType, INodeTypeBaseDescription, INodeTypeDescription, + IRequestOptionsSimplified, JsonObject, } from 'n8n-workflow'; @@ -969,6 +970,7 @@ export class HttpRequestV3 implements INodeType { let httpDigestAuth; let httpHeaderAuth; let httpQueryAuth; + let httpCustomAuth; let oAuth1Api; let oAuth2Api; let nodeCredentialType; @@ -992,6 +994,10 @@ export class HttpRequestV3 implements INodeType { try { httpQueryAuth = await this.getCredentials('httpQueryAuth'); } catch {} + } else if (genericAuthType === 'httpCustomAuth') { + try { + httpCustomAuth = await this.getCredentials('httpCustomAuth'); + } catch {} } else if (genericAuthType === 'oAuth1Api') { try { oAuth1Api = await this.getCredentials('oAuth1Api'); @@ -1345,6 +1351,24 @@ export class HttpRequestV3 implements INodeType { }; authDataKeys.auth = ['pass']; } + if (httpCustomAuth !== undefined) { + const customAuth = jsonParse( + (httpCustomAuth.json as string) || '{}', + { errorMessage: 'Invalid Custom Auth JSON' }, + ); + if (customAuth.headers) { + requestOptions.headers = { ...requestOptions.headers, ...customAuth.headers }; + authDataKeys.headers = Object.keys(customAuth.headers); + } + if (customAuth.body) { + requestOptions.body = { ...requestOptions.body, ...customAuth.body }; + authDataKeys.body = Object.keys(customAuth.body); + } + if (customAuth.qs) { + requestOptions.qs = { ...requestOptions.qs, ...customAuth.qs }; + authDataKeys.qs = Object.keys(customAuth.qs); + } + } if (requestOptions.headers!.accept === undefined) { if (responseFormat === 'json') { diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index cf100c387f960..c9cab8c02c2f7 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -152,6 +152,7 @@ "dist/credentials/HttpBasicAuth.credentials.js", "dist/credentials/HttpDigestAuth.credentials.js", "dist/credentials/HttpHeaderAuth.credentials.js", + "dist/credentials/HttpCustomAuth.credentials.js", "dist/credentials/HttpQueryAuth.credentials.js", "dist/credentials/HubspotApi.credentials.js", "dist/credentials/HubspotAppToken.credentials.js",