fix(connections): persist SSL settings and honor a URL's sslmode (#36)

Connecting to a managed provider (Neon in the report) failed with
"connection is insecure (try using `sslmode=require`)" because the TLS mode
never reached the backend:

- ConnectionFormData carried no ssl_* fields and both submit handlers
  (NewConnectionScreen.buildPayload, EditConnectionModal save + test) omitted
  them, so the SSH/SSL tab's mode was silently dropped before IPC.
- SslFields wrote ssl_ca_cert / ssl_client_cert / ssl_client_key — names the
  Rust ConnectionInput ignores (it expects ssl_ca_path / ssl_cert_path /
  ssl_key_path).
- parseConnectionString ignored query params, so a pasted Neon/Supabase URL's
  ?sslmode=require was discarded.

Pasting a URI now fills every setting it can (sslmode / ssl-mode, including
MySQL's REQUIRED and VERIFY_IDENTITY spellings) and offers a derived label
(database name, else host/file stem) as a placeholder that Test/Save uses when
the field is left blank. Managed presets pre-select their TLS mode (Supabase /
Neon → Require, PlanetScale → Verify Full).

Backend safety net: db::tls::resolve_ssl_mode defaults *.neon.tech /
*.supabase.co / *.psdb.cloud to `require` when a connection has no ssl_mode, so
connections saved before this fix keep working; an explicit mode (including
disable) always wins.

Tests: +15 frontend (parser, form payload, SSL field names, edit modal),
+4 Rust (resolve_ssl_mode / tls_decision_for).
This commit is contained in:
2026-09-24 03:25:13 +08:00
committed by GitHub
parent f807c22a36
commit 3454ce67fe
16 changed files with 549 additions and 65 deletions
@@ -1,5 +1,6 @@
import type { DbType } from "../../lib/types";
import type { Environment } from "./EnvironmentSelect";
import type { SslMode } from "../../lib/connectionString";
export interface ConnectionFormData {
name: string;
@@ -24,4 +25,13 @@ export interface ConnectionFormData {
ssh_private_key?: string | null;
ssh_password: string | null;
ssh_passphrase?: string | null;
// SSL/TLS fields. These must live on the form data (and survive into the
// submit payload) or the SSH/SSL tab's selections are silently dropped — the
// backend then connects with TLS disabled, which managed providers (Neon,
// Supabase, PlanetScale) reject with "connection is insecure".
// `null` = unset, which the backend treats as TLS disabled.
ssl_mode?: SslMode | null;
ssl_ca_path?: string | null;
ssl_cert_path?: string | null;
ssl_key_path?: string | null;
}