@@ -509,6 +509,172 @@ dsn = "postgres://user:pass@localhost:5432/testdb"
509509 expect ( result ) . toBeTruthy ( ) ;
510510 expect ( result ?. sources [ 0 ] . sslmode ) . toBeUndefined ( ) ;
511511 } ) ;
512+
513+ it ( 'should accept sslmode = "verify-ca" for PostgreSQL' , ( ) => {
514+ const tomlContent = `
515+ [[sources]]
516+ id = "test_db"
517+ type = "postgres"
518+ host = "localhost"
519+ database = "testdb"
520+ user = "user"
521+ password = "pass"
522+ sslmode = "verify-ca"
523+ ` ;
524+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
525+
526+ const result = loadTomlConfig ( ) ;
527+
528+ expect ( result ) . toBeTruthy ( ) ;
529+ expect ( result ?. sources [ 0 ] . sslmode ) . toBe ( 'verify-ca' ) ;
530+ } ) ;
531+
532+ it ( 'should accept sslmode = "verify-full" for PostgreSQL' , ( ) => {
533+ const tomlContent = `
534+ [[sources]]
535+ id = "test_db"
536+ type = "postgres"
537+ host = "localhost"
538+ database = "testdb"
539+ user = "user"
540+ password = "pass"
541+ sslmode = "verify-full"
542+ ` ;
543+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
544+
545+ const result = loadTomlConfig ( ) ;
546+
547+ expect ( result ) . toBeTruthy ( ) ;
548+ expect ( result ?. sources [ 0 ] . sslmode ) . toBe ( 'verify-full' ) ;
549+ } ) ;
550+
551+ it ( 'should reject sslmode = "verify-ca" for MySQL' , ( ) => {
552+ const tomlContent = `
553+ [[sources]]
554+ id = "test_db"
555+ type = "mysql"
556+ host = "localhost"
557+ database = "testdb"
558+ user = "user"
559+ password = "pass"
560+ sslmode = "verify-ca"
561+ ` ;
562+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
563+
564+ expect ( ( ) => loadTomlConfig ( ) ) . toThrow ( "sslmode 'verify-ca' which is only supported for PostgreSQL" ) ;
565+ } ) ;
566+
567+ it ( 'should reject sslmode = "verify-full" for MariaDB' , ( ) => {
568+ const tomlContent = `
569+ [[sources]]
570+ id = "test_db"
571+ type = "mariadb"
572+ host = "localhost"
573+ database = "testdb"
574+ user = "user"
575+ password = "pass"
576+ sslmode = "verify-full"
577+ ` ;
578+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
579+
580+ expect ( ( ) => loadTomlConfig ( ) ) . toThrow ( "sslmode 'verify-full' which is only supported for PostgreSQL" ) ;
581+ } ) ;
582+
583+ it ( 'should reject sslmode = "verify-ca" for SQL Server' , ( ) => {
584+ const tomlContent = `
585+ [[sources]]
586+ id = "test_db"
587+ type = "sqlserver"
588+ host = "localhost"
589+ database = "testdb"
590+ user = "user"
591+ password = "pass"
592+ sslmode = "verify-ca"
593+ ` ;
594+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
595+
596+ expect ( ( ) => loadTomlConfig ( ) ) . toThrow ( "sslmode 'verify-ca' which is only supported for PostgreSQL" ) ;
597+ } ) ;
598+
599+ it ( 'should reject sslrootcert when sslmode is "require"' , ( ) => {
600+ const certPath = path . join ( tempDir , 'ca.pem' ) ;
601+ fs . writeFileSync ( certPath , 'cert-content' ) ;
602+
603+ const tomlContent = `
604+ [[sources]]
605+ id = "test_db"
606+ type = "postgres"
607+ host = "localhost"
608+ database = "testdb"
609+ user = "user"
610+ password = "pass"
611+ sslmode = "require"
612+ sslrootcert = '${ certPath } '
613+ ` ;
614+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
615+
616+ expect ( ( ) => loadTomlConfig ( ) ) . toThrow ( "sslrootcert requires sslmode 'verify-ca' or 'verify-full'" ) ;
617+ } ) ;
618+
619+ it ( 'should reject sslrootcert when sslmode is not set' , ( ) => {
620+ const certPath = path . join ( tempDir , 'ca.pem' ) ;
621+ fs . writeFileSync ( certPath , 'cert-content' ) ;
622+
623+ const tomlContent = `
624+ [[sources]]
625+ id = "test_db"
626+ type = "postgres"
627+ host = "localhost"
628+ database = "testdb"
629+ user = "user"
630+ password = "pass"
631+ sslrootcert = '${ certPath } '
632+ ` ;
633+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
634+
635+ expect ( ( ) => loadTomlConfig ( ) ) . toThrow ( "sslrootcert requires sslmode 'verify-ca' or 'verify-full'" ) ;
636+ } ) ;
637+
638+ it ( 'should accept sslrootcert with sslmode = "verify-ca" when file exists' , ( ) => {
639+ const certPath = path . join ( tempDir , 'ca.pem' ) ;
640+ fs . writeFileSync ( certPath , 'cert-content' ) ;
641+
642+ const tomlContent = `
643+ [[sources]]
644+ id = "test_db"
645+ type = "postgres"
646+ host = "localhost"
647+ database = "testdb"
648+ user = "user"
649+ password = "pass"
650+ sslmode = "verify-ca"
651+ sslrootcert = '${ certPath } '
652+ ` ;
653+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
654+
655+ const result = loadTomlConfig ( ) ;
656+
657+ expect ( result ) . toBeTruthy ( ) ;
658+ expect ( result ?. sources [ 0 ] . sslmode ) . toBe ( 'verify-ca' ) ;
659+ expect ( result ?. sources [ 0 ] . sslrootcert ) . toBe ( certPath ) ;
660+ } ) ;
661+
662+ it ( 'should reject sslrootcert when file does not exist' , ( ) => {
663+ const tomlContent = `
664+ [[sources]]
665+ id = "test_db"
666+ type = "postgres"
667+ host = "localhost"
668+ database = "testdb"
669+ user = "user"
670+ password = "pass"
671+ sslmode = "verify-ca"
672+ sslrootcert = "/nonexistent/ca.pem"
673+ ` ;
674+ fs . writeFileSync ( path . join ( tempDir , 'dbhub.toml' ) , tomlContent ) ;
675+
676+ expect ( ( ) => loadTomlConfig ( ) ) . toThrow ( "sslrootcert file not found or not accessible: '/nonexistent/ca.pem'" ) ;
677+ } ) ;
512678 } ) ;
513679
514680 describe ( 'SQL Server authentication validation' , ( ) => {
@@ -978,6 +1144,41 @@ dsn = "postgres://user:pass@localhost:5432/testdb"
9781144 expect ( dsn ) . toBe ( 'postgres://user:pass@localhost:5432/testdb?sslmode=require' ) ;
9791145 } ) ;
9801146
1147+ it ( 'should build PostgreSQL DSN with verify-ca and sslrootcert' , ( ) => {
1148+ const source : SourceConfig = {
1149+ id : 'pg_verify' ,
1150+ type : 'postgres' ,
1151+ host : 'rds.amazonaws.com' ,
1152+ port : 5432 ,
1153+ database : 'testdb' ,
1154+ user : 'user' ,
1155+ password : 'pass' ,
1156+ sslmode : 'verify-ca' ,
1157+ sslrootcert : '/path/to/ca-bundle.pem'
1158+ } ;
1159+
1160+ const dsn = buildDSNFromSource ( source ) ;
1161+
1162+ expect ( dsn ) . toBe ( 'postgres://user:pass@rds.amazonaws.com:5432/testdb?sslmode=verify-ca&sslrootcert=%2Fpath%2Fto%2Fca-bundle.pem' ) ;
1163+ } ) ;
1164+
1165+ it ( 'should build PostgreSQL DSN with verify-full without sslrootcert' , ( ) => {
1166+ const source : SourceConfig = {
1167+ id : 'pg_verify_full' ,
1168+ type : 'postgres' ,
1169+ host : 'localhost' ,
1170+ port : 5432 ,
1171+ database : 'testdb' ,
1172+ user : 'user' ,
1173+ password : 'pass' ,
1174+ sslmode : 'verify-full'
1175+ } ;
1176+
1177+ const dsn = buildDSNFromSource ( source ) ;
1178+
1179+ expect ( dsn ) . toBe ( 'postgres://user:pass@localhost:5432/testdb?sslmode=verify-full' ) ;
1180+ } ) ;
1181+
9811182 it ( 'should build MySQL DSN with sslmode' , ( ) => {
9821183 const source : SourceConfig = {
9831184 id : 'mysql_ssl' ,
0 commit comments