From 48b373729dc50d073f059a502191b291c80834c8 Mon Sep 17 00:00:00 2001 From: Freedom <48708512+xddcode@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:36:23 +0800 Subject: [PATCH] fix(postgres): default absent sslmode to prefer --- .../connection/ConnectionDialog.vue | 2 +- .../__tests__/postgresTlsMode.spec.ts | 5 ++-- .../src/lib/connection/postgresTlsMode.ts | 5 ++-- crates/dbx-core/src/connection.rs | 16 +++++----- crates/dbx-core/src/models/connection.rs | 29 ++++++++++--------- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index 4b81ecb33..d0a2865be 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -5621,7 +5621,7 @@ function openExternalUrl(url: string) { ? 'catalog=paimon_catalog' : form.db_type === 'cassandra' ? 'localdatacenter=dc1' - : 'sslmode=disable' + : 'sslmode=prefer' " /> diff --git a/apps/desktop/src/lib/connection/__tests__/postgresTlsMode.spec.ts b/apps/desktop/src/lib/connection/__tests__/postgresTlsMode.spec.ts index ca47a3982..e50ca27e3 100644 --- a/apps/desktop/src/lib/connection/__tests__/postgresTlsMode.spec.ts +++ b/apps/desktop/src/lib/connection/__tests__/postgresTlsMode.spec.ts @@ -2,8 +2,8 @@ import { describe, expect, it } from "vitest"; import { postgresTlsModeForForm } from "@/lib/connection/postgresTlsMode"; describe("postgresTlsModeForForm", () => { - it("uses disable when legacy connections have no explicit mode", () => { - expect(postgresTlsModeForForm(undefined, false)).toBe("disable"); + it("uses prefer when legacy connections have no explicit mode", () => { + expect(postgresTlsModeForForm(undefined, false)).toBe("prefer"); }); it("keeps the legacy TLS toggle mapped to require", () => { @@ -12,6 +12,7 @@ describe("postgresTlsModeForForm", () => { it("honors explicit modes and aliases", () => { expect(postgresTlsModeForForm("disable", false)).toBe("disable"); + expect(postgresTlsModeForForm("prefer", false)).toBe("prefer"); expect(postgresTlsModeForForm("verify_identity", false)).toBe("verify-full"); }); }); diff --git a/apps/desktop/src/lib/connection/postgresTlsMode.ts b/apps/desktop/src/lib/connection/postgresTlsMode.ts index b4f7a10c9..69a2f70ff 100644 --- a/apps/desktop/src/lib/connection/postgresTlsMode.ts +++ b/apps/desktop/src/lib/connection/postgresTlsMode.ts @@ -12,7 +12,8 @@ export function postgresTlsModeForForm(value: string | undefined, ssl: boolean | case "verify-identity": return "verify-full"; default: - // DBX and DBeaver expose TLS as opt-in; an absent mode must remain plaintext. - return ssl ? "require" : "disable"; + // Align with libpq/JDBC: absent mode prefers TLS and can fall back to plaintext. + // Legacy ssl=true still maps to require. + return ssl ? "require" : "prefer"; } } diff --git a/crates/dbx-core/src/connection.rs b/crates/dbx-core/src/connection.rs index 64a7340b6..1726cca2a 100644 --- a/crates/dbx-core/src/connection.rs +++ b/crates/dbx-core/src/connection.rs @@ -3638,10 +3638,10 @@ fn native_postgres_url_config(config: &ConnectionConfig) -> Option String { if connection_options.is_empty() { if !parts.iter().any(|part| url_param_key_is(part, "sslmode")) { - // TLS is opt-in in the connection form; avoid tokio-postgres' implicit prefer mode. - parts.insert(0, if force_tls { "sslmode=require" } else { "sslmode=disable" }.to_string()); + // Match libpq/JDBC: absent mode prefers TLS and falls back to plaintext. + // Explicit ssl toggle still forces require; users can opt into disable. + parts.insert(0, if force_tls { "sslmode=require" } else { "sslmode=prefer" }.to_string()); } return parts.join("&"); } @@ -1729,7 +1730,7 @@ fn normalize_postgres_url_params(value: &str, force_tls: bool) -> String { } if !parts.iter().any(|part| url_param_key_is(part, "sslmode")) { - parts.insert(0, if force_tls { "sslmode=require" } else { "sslmode=disable" }.to_string()); + parts.insert(0, if force_tls { "sslmode=require" } else { "sslmode=prefer" }.to_string()); } parts.join("&") @@ -2120,7 +2121,7 @@ mod tests { config.db_type = DatabaseType::Postgres; assert_eq!(config.effective_database(), Some(" analytics ")); - assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/%20analytics%20?sslmode=disable"); + assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/%20analytics%20?sslmode=prefer"); } #[test] @@ -2681,11 +2682,11 @@ mod tests { } #[test] - fn postgres_url_disables_tls_by_default() { + fn postgres_url_prefers_tls_by_default() { let mut config = mysql_config("postgres", "secret", Some("test")); config.db_type = DatabaseType::Postgres; - assert_eq!(config.connection_url(), "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=disable"); + assert_eq!(config.connection_url(), "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=prefer"); } #[test] @@ -2719,7 +2720,7 @@ mod tests { assert_eq!( config.connection_url(), - "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=disable&options=%2Dc%20search%5Fpath%3Dpublic" + "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=prefer&options=%2Dc%20search%5Fpath%3Dpublic" ); let pg_config = tokio_postgres::Config::from_str(&config.connection_url()).unwrap(); assert_eq!(pg_config.get_options(), Some("-c search_path=public")); @@ -2733,7 +2734,7 @@ mod tests { assert_eq!( config.connection_url(), - "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=disable&options=%2Dc%20search%5Fpath%3Dapp" + "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=prefer&options=%2Dc%20search%5Fpath%3Dapp" ); let pg_config = tokio_postgres::Config::from_str(&config.connection_url()).unwrap(); assert_eq!(pg_config.get_options(), Some("-c search_path=app")); @@ -2767,7 +2768,7 @@ mod tests { assert_eq!( config.connection_url(), - "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=disable&options=%2Dc%20statement%5Ftimeout%3D5000%20%2Dc%20TimeZone%3DUTC" + "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=prefer&options=%2Dc%20statement%5Ftimeout%3D5000%20%2Dc%20TimeZone%3DUTC" ); } @@ -2779,7 +2780,7 @@ mod tests { assert_eq!( config.connection_url(), - "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=disable&options=-c%20TimeZone%3DUTC" + "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=prefer&options=-c%20TimeZone%3DUTC" ); } @@ -2788,7 +2789,7 @@ mod tests { let mut config = mysql_config("root", "secret", None); config.db_type = DatabaseType::Postgres; - assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/postgres?sslmode=disable"); + assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/postgres?sslmode=prefer"); } #[test] @@ -2796,7 +2797,7 @@ mod tests { let mut config = mysql_config("root", "secret", Some("")); config.db_type = DatabaseType::Postgres; - assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/postgres?sslmode=disable"); + assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/postgres?sslmode=prefer"); } #[test] @@ -2804,7 +2805,7 @@ mod tests { let mut config = mysql_config("awsuser", "secret", Some("")); config.db_type = DatabaseType::Redshift; - assert_eq!(config.connection_url(), "postgres://awsuser:secret@10.1.2.3:2883/dev?sslmode=disable"); + assert_eq!(config.connection_url(), "postgres://awsuser:secret@10.1.2.3:2883/dev?sslmode=prefer"); } #[test] @@ -2813,7 +2814,7 @@ mod tests { config.db_type = DatabaseType::Postgres; config.driver_profile = Some("cockroachdb".to_string()); - assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/defaultdb?sslmode=disable"); + assert_eq!(config.connection_url(), "postgres://root:secret@10.1.2.3:2883/defaultdb?sslmode=prefer"); } #[test]