Skip to content

Commit

Permalink
feature: add database and non http credentials test
Browse files Browse the repository at this point in the history
Add credential testing to Postgres, MySQL, MicrosoftSQL, Redis, FTP, SFTP, IMAP, RabbitMQ and MQTT

Co-authored-by: Omar Ajoue <krynble@gmail.com>
  • Loading branch information
agobrech and krynble authored Sep 1, 2022
1 parent b5511e5 commit d82e879
Show file tree
Hide file tree
Showing 8 changed files with 438 additions and 3 deletions.
50 changes: 50 additions & 0 deletions packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import {
createDeferredPromise,
IBinaryData,
IBinaryKeyData,
ICredentialDataDecryptedObject,
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
IDeferredPromise,
INodeCredentialTestResult,
INodeExecutionData,
INodeType,
INodeTypeDescription,
Expand Down Expand Up @@ -43,6 +47,7 @@ export class EmailReadImap implements INodeType {
{
name: 'imap',
required: true,
testedBy: 'imapConnectionTest',
},
],
properties: [
Expand Down Expand Up @@ -171,6 +176,51 @@ export class EmailReadImap implements INodeType {
],
};

methods = {
credentialTest: {
async imapConnectionTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
const credentials = credential.data as ICredentialDataDecryptedObject;
try {
const config: ImapSimpleOptions = {
imap: {
user: credentials.user as string,
password: credentials.password as string,
host: credentials.host as string,
port: credentials.port as number,
tls: credentials.secure as boolean,
authTimeout: 20000,
},
};
const tlsOptions: IDataObject = {};

if (credentials.secure) {
tlsOptions.servername = credentials.host as string;
}
if (!_.isEmpty(tlsOptions)) {
config.imap.tlsOptions = tlsOptions;
}
const conn = imapConnect(config).then(async (conn) => {
return conn;
});
(await conn).getBoxes((err, boxes) => {});
} catch (error) {
console.log(error);
return {
status: 'Error',
message: error.message,
};
}
return {
status: 'OK',
message: 'Connection successful!',
};
},
},
};

async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {
const credentials = await this.getCredentials('imap');

Expand Down
62 changes: 62 additions & 0 deletions packages/nodes-base/nodes/Ftp/Ftp.node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { IExecuteFunctions } from 'n8n-core';
import {
ICredentialDataDecryptedObject,
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
INodeCredentialTestResult,
INodeExecutionData,
INodeType,
INodeTypeDescription,
Expand Down Expand Up @@ -56,6 +59,7 @@ export class Ftp implements INodeType {
protocol: ['ftp'],
},
},
testedBy: 'ftpConnectionTest',
},
{
// nodelinter-ignore-next-line
Expand All @@ -66,6 +70,7 @@ export class Ftp implements INodeType {
protocol: ['sftp'],
},
},
testedBy: 'sftpConnectionTest',
},
],
properties: [
Expand Down Expand Up @@ -348,6 +353,63 @@ export class Ftp implements INodeType {
],
};

methods = {
credentialTest: {
async ftpConnectionTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
const credentials = credential.data as ICredentialDataDecryptedObject;
try {
let ftp: ftpClient;
ftp = new ftpClient();
await ftp.connect({
host: credentials.host as string,
port: credentials.port as number,
user: credentials.username as string,
password: credentials.password as string,
});
} catch (error) {
return {
status: 'Error',
message: error.message,
};
}
return {
status: 'OK',
message: 'Connection successful!',
};
},
async sftpConnectionTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
const credentials = credential.data as ICredentialDataDecryptedObject;
try {
let sftp: sftpClient;
sftp = new sftpClient();
await sftp.connect({
host: credentials.host as string,
port: credentials.port as number,
username: credentials.username as string,
password: credentials.password as string,
privateKey: credentials.privateKey as string | undefined,
passphrase: credentials.passphrase as string | undefined,
});
} catch (error) {
return {
status: 'Error',
message: error.message,
};
}
return {
status: 'OK',
message: 'Connection successful!',
};
},
},
};

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
// const returnData: IDataObject[] = [];
Expand Down
89 changes: 88 additions & 1 deletion packages/nodes-base/nodes/MQTT/Mqtt.node.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { IExecuteFunctions } from 'n8n-core';

import { IDataObject, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
import {
ICredentialDataDecryptedObject,
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
INodeCredentialTestResult,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';

import mqtt from 'mqtt';

Expand All @@ -23,6 +32,7 @@ export class Mqtt implements INodeType {
{
name: 'mqtt',
required: true,
testedBy: 'mqttConnectionTest',
},
],
properties: [
Expand Down Expand Up @@ -96,6 +106,83 @@ export class Mqtt implements INodeType {
],
};

methods = {
credentialTest: {
async mqttConnectionTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
const credentials = credential.data as ICredentialDataDecryptedObject;
try {
const protocol = (credentials.protocol as string) || 'mqtt';
const host = credentials.host as string;
const brokerUrl = `${protocol}://${host}`;
const port = (credentials.port as number) || 1883;
const clientId =
(credentials.clientId as string) || `mqttjs_${Math.random().toString(16).substr(2, 8)}`;
const clean = credentials.clean as boolean;
const ssl = credentials.ssl as boolean;
const ca = credentials.ca as string;
const cert = credentials.cert as string;
const key = credentials.key as string;
const rejectUnauthorized = credentials.rejectUnauthorized as boolean;

let client: mqtt.MqttClient;

if (ssl === false) {
const clientOptions: IClientOptions = {
port,
clean,
clientId,
};

if (credentials.username && credentials.password) {
clientOptions.username = credentials.username as string;
clientOptions.password = credentials.password as string;
}
client = mqtt.connect(brokerUrl, clientOptions);
} else {
const clientOptions: IClientOptions = {
port,
clean,
clientId,
ca,
cert,
key,
rejectUnauthorized,
};
if (credentials.username && credentials.password) {
clientOptions.username = credentials.username as string;
clientOptions.password = credentials.password as string;
}

client = mqtt.connect(brokerUrl, clientOptions);
}
// tslint:disable-next-line: no-any
await new Promise((resolve, reject): any => {
client.on('connect', (test) => {
resolve(test);
client.end();
});
client.on('error', (error) => {
client.end();
reject(error);
});
});
} catch (error) {
return {
status: 'Error',
message: error.message,
};
}
return {
status: 'OK',
message: 'Connection successful!',
};
},
},
};

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const length = items.length;
Expand Down
43 changes: 43 additions & 0 deletions packages/nodes-base/nodes/Microsoft/Sql/MicrosoftSql.node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { IExecuteFunctions } from 'n8n-core';

import {
ICredentialDataDecryptedObject,
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
INodeCredentialTestResult,
INodeExecutionData,
INodeType,
INodeTypeDescription,
Expand Down Expand Up @@ -42,6 +46,7 @@ export class MicrosoftSql implements INodeType {
{
name: 'microsoftSql',
required: true,
testedBy: 'microsoftSqlConnectionTest',
},
],
properties: [
Expand Down Expand Up @@ -213,6 +218,44 @@ export class MicrosoftSql implements INodeType {
],
};

methods = {
credentialTest: {
async microsoftSqlConnectionTest(
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> {
const credentials = credential.data as ICredentialDataDecryptedObject;
try {
const config = {
server: credentials.server as string,
port: credentials.port as number,
database: credentials.database as string,
user: credentials.user as string,
password: credentials.password as string,
domain: credentials.domain ? (credentials.domain as string) : undefined,
connectionTimeout: credentials.connectTimeout as number,
requestTimeout: credentials.requestTimeout as number,
options: {
encrypt: credentials.tls as boolean,
enableArithAbort: false,
},
};
const pool = new mssql.ConnectionPool(config);
await pool.connect();
} catch (error) {
return {
status: 'Error',
message: error.message,
};
}
return {
status: 'OK',
message: 'Connection successful!',
};
},
},
};

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const credentials = await this.getCredentials('microsoftSql');

Expand Down
Loading

0 comments on commit d82e879

Please sign in to comment.