@@ -2,6 +2,9 @@ const fs = require('fs');
22const ssh = require ( 'tunnel-ssh' ) ;
33const pg = require ( 'pg' ) ;
44
5+ const SSL_NOT_SUPPORTED_MESSAGE = 'The server does not support SSL connections' ;
6+ const POSTGRES_SSL_REQUIRED_ERROR_CODE = '28000' ;
7+
58const getSshConfig = info => {
69 const config = {
710 username : info . ssh_user ,
@@ -43,14 +46,16 @@ const connectViaSsh = info =>
4346 } ) ;
4447
4548const getSslOptions = ( connectionInfo , logger ) => {
46- const sslType = mapSslType ( connectionInfo . sslType ) ;
49+ const sslType = connectionInfo . sslType ;
4750
48- if ( ! sslType || sslType === 'disable' ) {
51+ if ( ! sslType || sslType === 'disable' || sslType === 'allow' ) {
4952 return false ;
5053 }
5154
52- if ( sslType === 'allow' ) {
53- return true ;
55+ if ( [ 'require' , 'prefer' ] . includes ( sslType ) && ! connectionInfo . certAuthority ) {
56+ return {
57+ rejectUnauthorized : false ,
58+ } ;
5459 }
5560
5661 let sslOptions = {
@@ -102,6 +107,8 @@ const createClient = async (connectionInfo, logger) => {
102107 connectionInfo = info ;
103108 }
104109
110+ connectionInfo = Object . assign ( { } , connectionInfo , { sslType : mapSslType ( connectionInfo . sslType ) } ) ;
111+
105112 const config = {
106113 host : connectionInfo . host ,
107114 user : connectionInfo . userName ,
@@ -116,10 +123,40 @@ const createClient = async (connectionInfo, logger) => {
116123 application_name : 'Hackolade' ,
117124 } ;
118125
126+ const client = await connectClient ( config ) . catch ( retryOnSslError ( connectionInfo , config , logger ) ) ;
127+
128+ return { client, sshTunnel } ;
129+ } ;
130+
131+ const retryOnSslError = ( connectionInfo , config , logger ) => async error => {
132+ if ( error . message === SSL_NOT_SUPPORTED_MESSAGE && connectionInfo . sslType === 'prefer' ) {
133+ logger . info ( "Retry connection without SSL (SSL mode 'prefer')" ) ;
134+ logger . error ( error ) ;
135+
136+ return await connectClient ( {
137+ ...config ,
138+ ssl : false ,
139+ } ) ;
140+ }
141+
142+ if ( error . code ?. toString ( ) === POSTGRES_SSL_REQUIRED_ERROR_CODE && connectionInfo . sslType === 'allow' ) {
143+ logger . info ( "Retry connection with SSL (SSL mode 'allow')" ) ;
144+ logger . error ( error ) ;
145+
146+ return await connectClient ( {
147+ ...config ,
148+ ssl : { rejectUnauthorized : false } ,
149+ } ) ;
150+ }
151+
152+ throw error ;
153+ } ;
154+
155+ const connectClient = async config => {
119156 const client = new pg . Client ( config ) ;
120157 await client . connect ( ) ;
121158
122- return { client, sshTunnel } ;
159+ return client ;
123160} ;
124161
125162module . exports = {
0 commit comments