diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.test.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.test.ts new file mode 100644 index 0000000000..fc67b6bb17 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.test.ts @@ -0,0 +1,156 @@ +import { mock } from 'jest-mock-extended'; +import type { PostgresNodeCredentials } from 'n8n-nodes-base/nodes/Postgres/v2/helpers/interfaces'; +import type { IExecuteFunctions } from 'n8n-workflow'; + +import { getPostgresDataSource } from './postgres'; + +describe('Postgres SSL settings', () => { + const credentials = mock({ + host: 'localhost', + port: 5432, + user: 'user', + password: 'password', + database: 'database', + }); + + test('ssl is disabled + allowUnauthorizedCerts is false', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'disable', + allowUnauthorizedCerts: false, + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: false, + }); + }); + + test('ssl is disabled + allowUnauthorizedCerts is true', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'disable', + allowUnauthorizedCerts: true, + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: false, + }); + }); + + test('ssl is disabled + allowUnauthorizedCerts is undefined', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'disable', + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: false, + }); + }); + + test('ssl is allow + allowUnauthorizedCerts is false', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'allow', + allowUnauthorizedCerts: false, + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: true, + }); + }); + + test('ssl is allow + allowUnauthorizedCerts is true', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'allow', + allowUnauthorizedCerts: true, + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: { rejectUnauthorized: false }, + }); + }); + + test('ssl is allow + allowUnauthorizedCerts is undefined', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'allow', + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: true, + }); + }); + + test('ssl is require + allowUnauthorizedCerts is false', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'require', + allowUnauthorizedCerts: false, + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: true, + }); + }); + + test('ssl is require + allowUnauthorizedCerts is true', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'require', + allowUnauthorizedCerts: true, + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: { rejectUnauthorized: false }, + }); + }); + + test('ssl is require + allowUnauthorizedCerts is undefined', async () => { + const context = mock({ + getCredentials: jest.fn().mockReturnValue({ + ...credentials, + ssl: 'require', + }), + }); + + const dataSource = await getPostgresDataSource.call(context); + + expect(dataSource.options).toMatchObject({ + ssl: true, + }); + }); +}); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.ts index 31dda9ed72..8654dcafbb 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/SqlAgent/other/handlers/postgres.ts @@ -1,29 +1,23 @@ import { DataSource } from '@n8n/typeorm'; +import type { PostgresNodeCredentials } from 'n8n-nodes-base/dist/nodes/Postgres/v2/helpers/interfaces'; import { type IExecuteFunctions } from 'n8n-workflow'; +import type { TlsOptions } from 'tls'; export async function getPostgresDataSource(this: IExecuteFunctions): Promise { - const credentials = await this.getCredentials('postgres'); + const credentials = await this.getCredentials('postgres'); - const dataSource = new DataSource({ - type: 'postgres', - host: credentials.host as string, - port: credentials.port as number, - username: credentials.user as string, - password: credentials.password as string, - database: credentials.database as string, - }); - - if (credentials.allowUnauthorizedCerts === true) { - dataSource.setOptions({ - ssl: { - rejectUnauthorized: true, - }, - }); - } else { - dataSource.setOptions({ - ssl: !['disable', undefined].includes(credentials.ssl as string | undefined), - }); + let ssl: TlsOptions | boolean = !['disable', undefined].includes(credentials.ssl); + if (credentials.allowUnauthorizedCerts && ssl) { + ssl = { rejectUnauthorized: false }; } - return dataSource; + return new DataSource({ + type: 'postgres', + host: credentials.host, + port: credentials.port, + username: credentials.user, + password: credentials.password, + database: credentials.database, + ssl, + }); }