From b38001ad4395fd673cbb49cea588d5ef3114db44 Mon Sep 17 00:00:00 2001 From: Gajus Date: Fri, 3 Jan 2025 11:55:32 -0600 Subject: [PATCH 1/4] fix: add missing ssl models --- packages/utilities/src/utilities/parseDsn.ts | 111 +++++++++++++------ 1 file changed, 77 insertions(+), 34 deletions(-) diff --git a/packages/utilities/src/utilities/parseDsn.ts b/packages/utilities/src/utilities/parseDsn.ts index 0d186049..4e6f6ec5 100644 --- a/packages/utilities/src/utilities/parseDsn.ts +++ b/packages/utilities/src/utilities/parseDsn.ts @@ -5,6 +5,7 @@ import { type ConnectionOptions } from '@slonik/types'; import { readFileSync } from 'node:fs'; import { z } from 'zod'; +// eslint-disable-next-line complexity export const parseDsn = (dsn: string): ConnectionOptions => { if (dsn.trim() === '') { return {}; @@ -56,7 +57,17 @@ export const parseDsn = (dsn: string): ConnectionOptions => { .describe( 'Specifies the location for the secret key used for the client certificate.', ), - sslmode: z.enum(['disable', 'no-verify', 'require']).optional(), + sslmode: z + .enum([ + 'allow', + 'disable', + 'no-verify', + 'prefer', + 'require', + 'verify-ca', + 'verify-full', + ]) + .optional(), sslrootcert: z .string() .optional() @@ -78,49 +89,81 @@ export const parseDsn = (dsn: string): ConnectionOptions => { connectionOptions.sslMode = searchParameters.sslmode; } - let sslCert: string | undefined; - let sslKey: string | undefined; - let sslRootCert: string | undefined; + /** + * Refer to https://github.com/brianc/node-postgres/pull/2709 + */ + if ( + searchParameters.sslcert || + searchParameters.sslkey || + searchParameters.sslrootcert || + searchParameters.sslmode + ) { + let sslCert: string | undefined; + let sslKey: string | undefined; + let sslRootCert: string | undefined; + + if (searchParameters.sslcert) { + try { + sslCert = readFileSync(searchParameters.sslcert, 'utf8'); + } catch { + throw new UnexpectedStateError('Failed to read SSL certificate file.'); + } + } - if (searchParameters.sslcert) { - try { - sslCert = readFileSync(searchParameters.sslcert, 'utf8'); - } catch { - throw new UnexpectedStateError('Failed to read SSL certificate file.'); + if (searchParameters.sslkey) { + try { + sslKey = readFileSync(searchParameters.sslkey, 'utf8'); + } catch { + throw new UnexpectedStateError('Failed to read SSL key file.'); + } } - } - if (searchParameters.sslkey) { - try { - sslKey = readFileSync(searchParameters.sslkey, 'utf8'); - } catch { - throw new UnexpectedStateError('Failed to read SSL key file.'); + if (searchParameters.sslrootcert) { + try { + sslRootCert = readFileSync(searchParameters.sslrootcert, 'utf8'); + } catch { + throw new UnexpectedStateError( + 'Failed to read SSL root certificate file.', + ); + } } - } - if (searchParameters.sslrootcert) { - try { - sslRootCert = readFileSync(searchParameters.sslrootcert, 'utf8'); - } catch { - throw new UnexpectedStateError( - 'Failed to read SSL root certificate file.', - ); + if (sslCert || sslKey || sslRootCert) { + if ((sslCert && !sslKey) || (!sslCert && sslKey)) { + throw new UnexpectedStateError( + 'Both sslcert and sslkey must be provided together.', + ); + } + + connectionOptions.ssl = { + ca: sslRootCert, + cert: sslCert, + key: sslKey, + rejectUnauthorized: searchParameters.sslmode !== 'no-verify', + }; } } - if (sslCert || sslKey || sslRootCert) { - if ((sslCert && !sslKey) || (!sslCert && sslKey)) { - throw new UnexpectedStateError( - 'Both sslcert and sslkey must be provided together.', - ); + switch (connectionOptions.sslMode) { + case 'disable': { + connectionOptions.ssl = false; + break; } - connectionOptions.ssl = { - ca: sslRootCert, - cert: sslCert, - key: sslKey, - rejectUnauthorized: searchParameters.sslmode !== 'no-verify', - }; + case 'no-verify': { + connectionOptions.ssl = { + ...connectionOptions.ssl, + rejectUnauthorized: false, + }; + break; + } + + case 'prefer': + case 'require': + case 'verify-ca': + case 'verify-full': { + break; + } } return connectionOptions; From 4ee47b04925bda3fbf4722fbd289f23a0f8d5fce Mon Sep 17 00:00:00 2001 From: Gajus Date: Fri, 3 Jan 2025 11:57:29 -0600 Subject: [PATCH 2/4] fix: add missing ssl models --- packages/types/src/types.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index 049916a6..b37a0a6f 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -14,7 +14,14 @@ export type ConnectionOptions = { key?: string; rejectUnauthorized: boolean; }; - sslMode?: 'disable' | 'no-verify' | 'require'; + sslMode?: + | 'allow' + | 'disable' + | 'no-verify' + | 'prefer' + | 'require' + | 'verify-ca' + | 'verify-full'; username?: string; }; From a3f70edc6b40c70c842db8cbda229d7c602871d5 Mon Sep 17 00:00:00 2001 From: Gajus Date: Fri, 3 Jan 2025 12:00:13 -0600 Subject: [PATCH 3/4] fix: add missing ssl models --- packages/types/src/types.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index b37a0a6f..98c905ed 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -8,12 +8,14 @@ export type ConnectionOptions = { options?: string; password?: string; port?: number; - ssl?: { - ca?: string; - cert?: string; - key?: string; - rejectUnauthorized: boolean; - }; + ssl?: + | boolean + | { + ca?: string; + cert?: string; + key?: string; + rejectUnauthorized: boolean; + }; sslMode?: | 'allow' | 'disable' From 4bb0263e9e056c9ac2773e7648f7807c3723bfa5 Mon Sep 17 00:00:00 2001 From: Gajus Date: Fri, 3 Jan 2025 12:26:57 -0600 Subject: [PATCH 4/4] fix: add missing ssl models --- packages/utilities/src/utilities/parseDsn.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/utilities/src/utilities/parseDsn.ts b/packages/utilities/src/utilities/parseDsn.ts index 4e6f6ec5..74052343 100644 --- a/packages/utilities/src/utilities/parseDsn.ts +++ b/packages/utilities/src/utilities/parseDsn.ts @@ -151,8 +151,10 @@ export const parseDsn = (dsn: string): ConnectionOptions => { } case 'no-verify': { + const ssl = connectionOptions.ssl ?? {}; + connectionOptions.ssl = { - ...connectionOptions.ssl, + ...ssl, rejectUnauthorized: false, }; break;