mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-15 09:04:07 -08:00
ee7147c6b3
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Benchmark Docker Image CI / build (push) Waiting to run
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { connect, type IClientOptions, type MqttClient } from 'mqtt';
|
|
import { ApplicationError, randomString } from 'n8n-workflow';
|
|
|
|
import { formatPrivateKey } from '@utils/utilities';
|
|
|
|
interface BaseMqttCredential {
|
|
protocol: 'mqtt' | 'mqtts' | 'ws';
|
|
host: string;
|
|
port: number;
|
|
username: string;
|
|
password: string;
|
|
clean: boolean;
|
|
clientId: string;
|
|
passwordless?: boolean;
|
|
}
|
|
|
|
type NonSslMqttCredential = BaseMqttCredential & {
|
|
ssl: false;
|
|
};
|
|
|
|
type SslMqttCredential = BaseMqttCredential & {
|
|
ssl: true;
|
|
ca: string;
|
|
cert: string;
|
|
key: string;
|
|
rejectUnauthorized?: boolean;
|
|
};
|
|
export type MqttCredential = NonSslMqttCredential | SslMqttCredential;
|
|
|
|
export const createClient = async (credentials: MqttCredential): Promise<MqttClient> => {
|
|
const { protocol, host, port, clean, clientId, username, password } = credentials;
|
|
|
|
const clientOptions: IClientOptions = {
|
|
protocol,
|
|
host,
|
|
port,
|
|
clean,
|
|
clientId: clientId || `mqttjs_${randomString(8).toLowerCase()}`,
|
|
};
|
|
|
|
if (username && password) {
|
|
clientOptions.username = username;
|
|
clientOptions.password = password;
|
|
}
|
|
|
|
if (credentials.ssl) {
|
|
clientOptions.ca = formatPrivateKey(credentials.ca);
|
|
clientOptions.cert = formatPrivateKey(credentials.cert);
|
|
clientOptions.key = formatPrivateKey(credentials.key);
|
|
clientOptions.rejectUnauthorized = credentials.rejectUnauthorized;
|
|
}
|
|
|
|
return await new Promise((resolve, reject) => {
|
|
const client = connect(clientOptions);
|
|
|
|
const onConnect = () => {
|
|
client.removeListener('connect', onConnect);
|
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
client.removeListener('error', onError);
|
|
resolve(client);
|
|
};
|
|
|
|
const onError = (error: Error) => {
|
|
client.removeListener('connect', onConnect);
|
|
client.removeListener('error', onError);
|
|
// mqtt client has an automatic reconnect mechanism that will
|
|
// keep trying to reconnect until it succeeds unless we
|
|
// explicitly close the client
|
|
client.end();
|
|
reject(new ApplicationError(error.message));
|
|
};
|
|
|
|
client.once('connect', onConnect);
|
|
client.once('error', onError);
|
|
});
|
|
};
|