-
Status do intake: ready-for-intake
-
Data: 2026-08-24
-
Origem: relato de falha no envio de formulário padrão (texto de erro "Corpo HTML padrão" no e-mail) e erro 403 Forbidden ("Token CSRF inválido ou ausente") ao pesquisar componentes ou gerar preview no painel de edição
-
Classificação: bugfix, resiliência, forms, comunicacao, formulario, csrf
-
Batch candidato: BATCH-132
Esta especificação define os requisitos para garantir que o envio de formulários sem componente de mensagem personalizado utilize automaticamente o template padrão forms-prepared-email com substituição completa dos campos preenchidos, além de blindar as ações (form_action), assuntos, e corrigir as chamadas AJAX do painel administrativo (forms.js) que geram URLs com barra dupla (forms/editar//) e erro de CSRF.
1. Problemas Identificados e Causas-Raiz
-
Bug do
issetemmessage_component:-
Em
gestor/bibliotecas/formulario.php(linha 909):$mensagem = !empty($emailData) && isset($emailData['message_component']) ? gestor_componente(Array('id' => $emailData['message_component'])) : gestor_componente(Array('id' => 'forms-prepared-email')); -
Ao salvar um formulário no módulo
formssem escolher um componente específico no autocomplete (sig-search-input), o JSONfields_schema.email.message_componenté persistido como string vazia"". -
isset($emailData['message_component'])retornatrue, resultando emgestor_componente(['id' => ''])(retorno vazio). -
O fallback para
forms-prepared-emailnunca é executado.$mensagemvazia cai no fallback genérico decomunicacao.php, enviando<p>Corpo HTML Padrão</p>.
-
-
Inconsistência de
form_actionesubject:-
Em
formulario.php(linha 276),isset($schema['form_action'])com valor""apontava o formulário para a raiz/em vez deforms-submissions-process/. -
Em
formulario.php(linha 904),isset($emailData['subject'])com valor""impedia o fallback para a variável padrãoforms-subject-emails.
-
-
Erro 403 (Token CSRF inválido/ausente) e URL Malformada em
forms.js:-
No arquivo
gestor/modulos/forms/forms.js(linhas 274, 323, 374): As requisições AJAX (widget-preview,buscar-componentes,salvar-template) utilizam:url: gestor.raiz + gestor.moduloCaminho + '/', -
Como
gestor.moduloCaminhojá contém a barra final (ex.:forms/editar/), a concatenação produzforms/editar//(com barra dupla). -
A barra dupla quebra o roteamento de parâmetros do
gestor.php, impedindo a correspondência da rota autenticada e gerando a resposta403 Forbidden({"status":"error","message":"Token CSRF inválido ou ausente."}). -
Além disso, os payloads dessas chamadas não passavam o
_csrf_tokenexplicitamente no objeto de dados.
-
2. Requisitos Técnicos de Implementação
2.1. Fallback Robusto de Template de E-mail (formulario.php)
-
Substituir a checagem com
issetpor validação de string não vazia (!empty($emailData['message_component']) && trim((string)$emailData['message_component']) !== ''). -
Se o componente informado não existir ou retornar vazio via
gestor_componente(), aplicar fallback obrigatório para o componente canônicoforms-prepared-email. -
Garantir que as tags
#code#,#formName#e a célula repetível<!-- cel < --> ... <!-- cel > -->sejam populadas com os campos submetidos (#label#,#valor#,#valor_full#).
2.2. Blindagem de Assunto (subject) e Remetentes
-
Em
formulario.php(linha 904), se$emailData['subject']for vazio ou contiver apenas espaços, aplicar o fallback paragestor_variaveis(['id' => 'forms-subject-emails']). -
Garantir sanitização e fallbacks para
reply_toereply_to_name.
2.3. Blindagem de Endpoint de Ação (form_action)
-
Em
formulario.php(linhas 276–278 e 323), garantir que seform_actionfor nulo ou"",$formActionreceba$_GESTOR['url-raiz'] . 'forms-submissions-process/'. -
Em
forms.widget.phpeformulario.js, manter a coerência garantindo que o fallbackforms-submissions-process/seja sempre acionado quando não houver rota customizada explícita.
2.4. Normalização de URL e CSRF em forms.js
-
Criar função auxiliar
moduloUrl()emforms.jspara higienizar a URL (removendo barras duplicadas, similar ahtml-editor-interface.js):function moduloUrl() { var url = String(gestor.raiz || '') + String(gestor.moduloCaminho || '').replace(/^\/+/, ''); url = url.replace(/([^:])\/{2,}/g, '$1/'); if (url.charAt(url.length - 1) !== '/') url += '/'; return url; } -
Atualizar todas as chamadas AJAX (
widget-preview,buscar-componentes,salvar-template) para usarurl: moduloUrl(). -
Incluir
_csrf_token: (window.gestor && gestor.csrfToken) ? gestor.csrfToken : ''no payload das chamadas AJAX.
2.5. Tratamento no Autocomplete (sig-autocomplete / sig-search-input)
-
Ao apagar o texto no input de busca
sig-search-inputou clicar em.sig-clear, garantir que o campo oculto#email_message_componentseja limpo (val('')).
3. Critérios de Aceitação
-
Sintaxe e Linting:
php -lenode --check100% limpos. -
Busca de Componentes no Painel:
-
Digitar na caixa
sig-search-inputna aba E-mail não emite erro 403 Forbidden nem reclama de CSRF; a busca de componentes retorna os resultados filtrados via AJAX. -
O preview do formulário (
widget-preview) carrega normalmente sem erro 403.
-
-
Envio Padrão Funcional:
-
Formulário sem componente de e-mail selecionado deve enviar o e-mail formatado utilizando o template
forms-prepared-email(tabela de campos com labels e valores preenchidos). -
O e-mail recebido NÃO deve conter o texto "Corpo HTML padrão".
-
-
Persistência e Roteamento:
-
Formulário sem ação explícita direciona para
forms-submissions-process/e grava a submissão emforms_submissions.
-
-
Suíte de Testes Automatizados:
-
Cobrir os cenários de fallback de template de e-mail e sanitização de endpoints na suíte PHPUnit.
-