Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

N8N-4126 credentials injection and testing on specific nodes #3816

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
034e0d2
Add cred injection and cred testing
agobrech Jul 19, 2022
94bba72
Add cred injection, cred testing
agobrech Jul 19, 2022
a261fb0
add cred injection, cred testing to supabase
agobrech Jul 19, 2022
d645116
✨ Add cred injection and moved cred testing for dropcontact
agobrech Jul 19, 2022
1ec38b6
🔥 Removed old cred testing method
agobrech Jul 19, 2022
049b1fa
Add cred injection, cred testing to lemlist
agobrech Jul 19, 2022
39d7bb6
🔥 remove log message
agobrech Jul 19, 2022
3c9ce5b
✨ Add cred injection to segment
agobrech Jul 19, 2022
f686f04
Add cred injection for uproc
agobrech Jul 19, 2022
eae4342
Merge branch 'master' into n8n-4126-credentials-injection-and-testing…
agobrech Aug 2, 2022
9436987
🎨 Fix format issue
agobrech Aug 2, 2022
1e2403a
Merge branch 'master' into n8n-4126-credentials-injection-and-testing…
agobrech Aug 4, 2022
8e40e99
Merge branch 'master' into n8n-4126-credentials-injection-and-testing…
agobrech Aug 10, 2022
9cd5010
✨ Add credential injection to AWS Lambda
agobrech Aug 10, 2022
0ac510e
✨ Add credentials injection to S3 AWS
agobrech Aug 10, 2022
1318711
✨ Add S3 SES Textract credentials injection
agobrech Aug 10, 2022
5be7c8a
⏪ Revert "✨ Add credential injection to AWS Lambda"
agobrech Aug 17, 2022
58fab55
🐛 Fix a bug where wrong endpoint was being use for testing
agobrech Aug 17, 2022
de9fa4b
🐛 Improved testing for uproc
agobrech Aug 17, 2022
e1f0ea7
Merge branch 'master' into n8n-4126-credentials-injection-and-testing…
agobrech Aug 23, 2022
aa6b66b
Revert "✨ Add credentials injection to S3 AWS"
agobrech Aug 23, 2022
2174fb6
Revert "✨ Add S3 SES Textract credentials injection"
agobrech Aug 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion packages/nodes-base/credentials/DropcontactApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ICredentialType, NodePropertyTypes } from 'n8n-workflow';
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
NodePropertyTypes,
} from 'n8n-workflow';

export class DropcontactApi implements ICredentialType {
name = 'dropcontactApi';
Expand All @@ -12,4 +17,23 @@ export class DropcontactApi implements ICredentialType {
default: '',
},
];
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
headers: {
'user-agent': 'n8n',
'X-Access-Token': '={{$credentials.apiKey}}',
},
},
};
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.dropcontact.io',
url: '/batch',
method: 'POST',
body: {
data: [{ email: '' }],
},
},
};
}
23 changes: 22 additions & 1 deletion packages/nodes-base/credentials/LemlistApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import {
ICredentialDataDecryptedObject,
ICredentialTestRequest,
ICredentialType,
IHttpRequestOptions,
INodeProperties,
} from 'n8n-workflow';

export class LemlistApi implements ICredentialType {
name = 'lemlistApi';
Expand All @@ -12,4 +18,19 @@ export class LemlistApi implements ICredentialType {
default: '',
},
];
async authenticate(
credentials: ICredentialDataDecryptedObject,
requestOptions: IHttpRequestOptions,
): Promise<IHttpRequestOptions> {
const encodedApiKey = Buffer.from(':' + credentials.apiKey).toString('base64');
requestOptions.headers!['Authorization'] = `Basic ${encodedApiKey}`;
requestOptions.headers!['user-agent'] = 'n8n';
krynble marked this conversation as resolved.
Show resolved Hide resolved
return requestOptions;
}
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.lemlist.com/api',
url: '/campaigns',
},
};
}
22 changes: 21 additions & 1 deletion packages/nodes-base/credentials/MailgunApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

export class MailgunApi implements ICredentialType {
name = 'mailgunApi';
Expand Down Expand Up @@ -35,4 +40,19 @@ export class MailgunApi implements ICredentialType {
default: '',
},
];
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
auth: {
username: 'api',
password: '={{$credentials.apiKey}}',
},
},
};
test: ICredentialTestRequest = {
request: {
baseURL: '=https://{{$credentials.apiDomain}}/v3',
url: '/domains',
},
};
}
21 changes: 20 additions & 1 deletion packages/nodes-base/credentials/PhantombusterApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

export class PhantombusterApi implements ICredentialType {
name = 'phantombusterApi';
Expand All @@ -12,4 +17,18 @@ export class PhantombusterApi implements ICredentialType {
default: '',
},
];
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
headers: {
'X-Phantombuster-Key': '={{$credentials.apiKey}}',
},
},
};
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.phantombuster.com/api/v2',
url: '/agents/fetch-all',
},
};
}
15 changes: 14 additions & 1 deletion packages/nodes-base/credentials/SegmentApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import {
ICredentialDataDecryptedObject,
ICredentialType,
IHttpRequestOptions,
INodeProperties,
} from 'n8n-workflow';

export class SegmentApi implements ICredentialType {
name = 'segmentApi';
Expand All @@ -12,4 +17,12 @@ export class SegmentApi implements ICredentialType {
default: '',
},
];
async authenticate(
credentials: ICredentialDataDecryptedObject,
requestOptions: IHttpRequestOptions,
): Promise<IHttpRequestOptions> {
const base64Key = Buffer.from(`${credentials.writekey}:`).toString('base64');
requestOptions.headers!['Authorization'] = `Basic ${base64Key}`;
return requestOptions;
}
}
25 changes: 24 additions & 1 deletion packages/nodes-base/credentials/SupabaseApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

export class SupabaseApi implements ICredentialType {
name = 'supabaseApi';
Expand All @@ -19,4 +24,22 @@ export class SupabaseApi implements ICredentialType {
default: '',
},
];
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
headers: {
apikey: '={{$credentials.serviceRole}}',
Authorization: '=Bearer {{$credentials.serviceRole}}',
},
},
};
test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials.host}}/rest/v1',
headers: {
Prefer: 'return=representation',
},
url: '/',
},
};
}
26 changes: 25 additions & 1 deletion packages/nodes-base/credentials/UProcApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import {
ICredentialDataDecryptedObject,
ICredentialTestRequest,
ICredentialType,
IHttpRequestOptions,
INodeProperties,
} from 'n8n-workflow';

export class UProcApi implements ICredentialType {
name = 'uprocApi';
Expand All @@ -19,4 +25,22 @@ export class UProcApi implements ICredentialType {
default: '',
},
];
async authenticate(
credentials: ICredentialDataDecryptedObject,
requestOptions: IHttpRequestOptions,
): Promise<IHttpRequestOptions> {
const token = Buffer.from(`${credentials.email}:${credentials.apiKey}`).toString('base64');
requestOptions.headers = {
...requestOptions.headers,
Authorization: `Basic ${token}`,
};
return requestOptions;
}
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.uproc.io/api/v2',
url: '/profile',
method: 'GET',
},
};
}
27 changes: 1 addition & 26 deletions packages/nodes-base/nodes/Dropcontact/Dropcontact.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
NodeApiError,
} from 'n8n-workflow';

import { dropcontactApiRequest, validateCredentials } from './GenericFunction';
import { dropcontactApiRequest } from './GenericFunction';

export class Dropcontact implements INodeType {
description: INodeTypeDescription = {
Expand All @@ -32,7 +32,6 @@ export class Dropcontact implements INodeType {
{
name: 'dropcontactApi',
required: true,
testedBy: 'dropcontactApiCredentialTest',
},
],
properties: [
Expand Down Expand Up @@ -244,30 +243,6 @@ export class Dropcontact implements INodeType {
},
],
};

methods = {
credentialTest: {
async dropcontactApiCredentialTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
try {
await validateCredentials.call(this, credential.data as ICredentialDataDecryptedObject);
} catch (error) {
return {
status: 'Error',
message: 'The API Key included in the request is invalid',
};
}

return {
status: 'OK',
message: 'Connection successful!',
};
},
},
};

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const entryData = this.getInputData();
const resource = this.getNodeParameter('resource', 0) as string;
Expand Down
45 changes: 2 additions & 43 deletions packages/nodes-base/nodes/Dropcontact/GenericFunction.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { IExecuteFunctions, IHookFunctions } from 'n8n-core';

import {
ICredentialDataDecryptedObject,
ICredentialTestFunctions,
IDataObject,
ILoadOptionsFunctions,
NodeApiError,
} from 'n8n-workflow';
import { IDataObject, ILoadOptionsFunctions, NodeApiError } from 'n8n-workflow';

import { OptionsWithUri } from 'request';

Expand All @@ -20,15 +14,7 @@ export async function dropcontactApiRequest(
body: IDataObject,
qs: IDataObject,
) {
const { apiKey } = (await this.getCredentials('dropcontactApi')) as {
apiKey: string;
};

const options: OptionsWithUri = {
headers: {
'user-agent': 'n8n',
'X-Access-Token': apiKey,
},
method,
uri: `https://api.dropcontact.io${endpoint}`,
qs,
Expand All @@ -45,35 +31,8 @@ export async function dropcontactApiRequest(
}

try {
return await this.helpers.request!(options);
return await this.helpers.requestWithAuthentication.call(this, 'dropcontactApi', options);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
}

export async function validateCredentials(
this: ICredentialTestFunctions,
decryptedCredentials: ICredentialDataDecryptedObject,
// tslint:disable-next-line:no-any
): Promise<any> {
const credentials = decryptedCredentials;

const { apiKey } = credentials as {
apiKey: string;
};

const options: OptionsWithUri = {
headers: {
'user-agent': 'n8n',
'X-Access-Token': apiKey,
},
method: 'POST',
body: {
data: [{ email: '' }],
},
uri: `https://api.dropcontact.io/batch`,
json: true,
};

return this.helpers.request!(options);
}
9 changes: 1 addition & 8 deletions packages/nodes-base/nodes/Lemlist/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,9 @@ export async function lemlistApiRequest(
qs: IDataObject = {},
option: IDataObject = {},
) {
const { apiKey } = (await this.getCredentials('lemlistApi')) as {
apiKey: string;
};

const encodedApiKey = Buffer.from(':' + apiKey).toString('base64');

const options: OptionsWithUri = {
headers: {
'user-agent': 'n8n',
Authorization: `Basic ${encodedApiKey}`,
},
method,
uri: `https://api.lemlist.com/api${endpoint}`,
Expand All @@ -48,7 +41,7 @@ export async function lemlistApiRequest(
}

try {
return await this.helpers.request!(options);
return await this.helpers.requestWithAuthentication.call(this,'lemlistApi',options);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
Expand Down
6 changes: 1 addition & 5 deletions packages/nodes-base/nodes/Mailgun/Mailgun.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,13 @@ export class Mailgun implements INodeType {
method: 'POST',
formData,
uri: `https://${credentials.apiDomain}/v3/${credentials.emailDomain}/messages`,
auth: {
user: 'api',
pass: credentials.apiKey as string,
},
json: true,
};

let responseData;

try {
responseData = await this.helpers.request(options);
responseData = await this.helpers.requestWithAuthentication.call(this, 'mailgunApi', options);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
Expand Down
3 changes: 1 addition & 2 deletions packages/nodes-base/nodes/Phantombuster/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export async function phantombusterApiRequest(

const options: OptionsWithUri = {
headers: {
'X-Phantombuster-Key': credentials.apiKey,
},
method,
body,
Expand All @@ -31,7 +30,7 @@ export async function phantombusterApiRequest(
delete options.body;
}
//@ts-ignore
return await this.helpers.request.call(this, options);
return await this.helpers.requestWithAuthentication.call(this, 'phantombusterApi',options);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
Expand Down
Loading