From bf878545b3b0527adfda7c8fdd3bf67da7fcf4a8 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Jul 2026 14:17:38 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20denylist=E7=A7=BB=E9=99=A4arrays/objetos?= =?UTF-8?q?=20=E2=80=94=20=E8=A7=A3=E5=86=B3PATCH=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E4=BD=86=E5=AD=97=E6=AE=B5=E4=B8=8D=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/plugins/supabase.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src-tauri/src/plugins/supabase.rs b/src-tauri/src/plugins/supabase.rs index 4441fdc..e08679a 100644 --- a/src-tauri/src/plugins/supabase.rs +++ b/src-tauri/src/plugins/supabase.rs @@ -250,12 +250,27 @@ 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 { - // Sem whitelist — o frontend envia só o que o usuário editou. - // O Supabase/Postgres valida as colunas existentes. - // edited_at é atualizado pelo frontend no objeto updates. + // Campos que o frontend envia mas NÃO existem como colunas na tabela. + // Arrays e objetos são guardados no JSONB `dados` — não em colunas escalar. + static BLOCKED: &[&str] = &[ + "id", "uuid", "criado_em", "atualizado_em", "enviado_por", + "ip_origem", "user_agent", "id_fechamento", + // arrays e objetos que existem dentro do JSONB `dados` + "vales", "despesas", "sangrias", "cancelamentos", + "pixcnpj", "receber", + "cartoes_credito", "cartoes_debito", + "cartoes_alimentacao", "cartoes_pix", + ]; + let map = updates.as_object().cloned().unwrap_or_default(); - if map.is_empty() { + // Remove campos bloqueados + let filtered: serde_json::Map = map + .into_iter() + .filter(|(k, _)| !BLOCKED.contains(&k.as_str())) + .collect(); + + if filtered.is_empty() { return Err(SupabaseError::Api("Nenhum campo para atualizar".into())); } @@ -265,14 +280,14 @@ impl SupabaseClient { urlencoding::encode(id_fechamento) ); - log::info!("[PATCH] url={} body={:#?}", url, map); + log::info!("[PATCH] url={} body={:#?}", url, filtered); let resp = self .http .patch(&url) .headers(self.headers(true)) .header("Prefer", "return=representation") - .json(&map) + .json(&filtered) .send()?; let status = resp.status();