fix: harden security, reduce duplication, and improve robustness

- Fix SQL injection in data.rs by wrapping get_table_data in READ ONLY transaction
- Fix SQL injection in docker.rs CREATE DATABASE via escape_ident
- Fix command injection in docker.rs by validating pg_version/container_name
  and escaping shell-interpolated values
- Fix UTF-8 panic on stderr truncation with char_indices
- Wrap delete_rows in a transaction for atomicity
- Replace .expect() with proper error propagation in lib.rs
- Cache AI settings in AppState to avoid repeated disk reads
- Cap JSONB column discovery at 50 to prevent unbounded queries
- Fix ERD colorMode to respect system theme via useTheme()
- Extract AppState::get_pool() replacing ~19 inline pool patterns
- Extract shared AiSettingsFields component (DRY popover + sheet)
- Make get_connections_path pub(crate) and reuse from docker.rs
- Deduplicate check_docker by delegating to check_docker_internal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 11:41:14 +03:00
parent baa794b66a
commit d507162377
15 changed files with 1196 additions and 667 deletions

View File

@@ -13,24 +13,20 @@ use tauri::Manager;
pub fn run() {
let shared_state = Arc::new(AppState::new());
tauri::Builder::default()
let _ = tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_dialog::init())
.manage(shared_state)
.setup(|app| {
let state = app.state::<Arc<AppState>>().inner().clone();
let connections_path = app
let data_dir = app
.path()
.app_data_dir()
.expect("failed to resolve app data dir")
.join("connections.json");
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
let connections_path = data_dir.join("connections.json");
// Read app settings
let settings_path = app
.path()
.app_data_dir()
.expect("failed to resolve app data dir")
.join("app_settings.json");
let settings_path = data_dir.join("app_settings.json");
let settings = if settings_path.exists() {
std::fs::read_to_string(&settings_path)
@@ -154,5 +150,7 @@ pub fn run() {
commands::settings::get_mcp_status,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
.inspect_err(|e| {
log::error!("Tauri application error: {}", e);
});
}