From d112ad061e60dc4599569b2680330b52e2ab1df0 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Jul 2026 13:24:19 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20whitelist=20de=20colunas=20no=20PATCH=20?= =?UTF-8?q?=E2=80=94=20ignora=20campos=20inexistentes=20na=20tabela;=20cor?= =?UTF-8?q?rige=20JSON.stringify=20removido?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/plugins/supabase.rs | 33 ++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/plugins/supabase.rs b/src-tauri/src/plugins/supabase.rs index ef95cab..22e0471 100644 --- a/src-tauri/src/plugins/supabase.rs +++ b/src-tauri/src/plugins/supabase.rs @@ -250,21 +250,48 @@ impl SupabaseClient { /// Atualiza campos específicos de um fechamento pelo id_fechamento. pub fn atualizar_fechamento(&self, id_fechamento: &str, updates: &serde_json::Value) -> Result { + // Whitelist: só colunas que existem na tabela fechamentos_web. + // Campos de lista (vales, despesas, sangrias, etc.) vivem no JSONB `dados` + // e são tratados separadamente via salvar_listas / carregar_listas. + static ALLOWED: &[&str] = &[ + "data", "loja", "turno", "operador", + "saldo_troco", "saldo_credito", "saldo_debito", "saldo_alimentacao", + "saldo_vales", "saldo_areceber", + "total_cartao_credito", "total_cartao_debito", "total_cartao_alimentacao", + "total_cartao_pix", "total_pixcnpj", + "total_sangrias", "total_despesas", "total_vales", + "total_areceber", "total_cancelamentos", + "fechamento_dinheiro", "fechamento_cartoes", "fechamento_areceber", + "clientes", "frango", "vendas", "saldo_esperado", + "observacoes", "edited_at", "edited_by", + ]; + + let filtered: serde_json::Map = updates + .as_object() + .cloned() + .unwrap_or_default() + .into_iter() + .filter(|(k, _)| ALLOWED.contains(&k.as_str())) + .collect(); + + if filtered.is_empty() { + return Err(SupabaseError::Api("Nenhum campo válido para atualizar".into())); + } + let url = format!( "{}/rest/v1/fechamentos_web?id_fechamento=eq.{}", self.base_url, urlencoding::encode(id_fechamento) ); - // Log do que está sendo enviado (debug) - log::info!("[PATCH] url={} body={}", url, updates); + log::info!("[PATCH] url={} body={:#?}", url, filtered); let resp = self .http .patch(&url) .headers(self.headers(true)) .header("Prefer", "return=representation") - .json(updates) + .json(&filtered) .send()?; let status = resp.status();