Files
GTI_GERENCIADOR_FISCAL/app/templates/base.html
T
GustavoandClaude Sonnet 5 aa1c528197 fix: botao Sair quebrado em /clientes, /log e /gerador-chave (csrf_token vazio)
base.html usava {{ csrf_token }}, variavel que so algumas rotas passam
explicitamente no contexto do template. Em /clientes (GET), /log e
/gerador-chave a variavel nunca era passada, entao o campo oculto do
formulario de logout renderizava com value="" e exigir_csrf (app/csrf.py)
rejeitava o POST /logout com 403 - o usuario nao conseguia clicar em
'Sair' logo apos logar, ja que /clientes e para onde todo login cai.

Corrige na raiz: usa {{ csrf_token or request.state.csrf_token }}, caindo
para o valor que csrf_cookie_middleware (app/main.py) ja popula em toda
requisicao quando a rota nao passar csrf_token explicitamente. Protege
tambem qualquer rota futura que esqueca de passar a variavel.

Testes de regressao em tests/test_main.py: confirma que GET /clientes
renderiza um csrf_token nao vazio no formulario de logout, e que
POST /logout funciona (303) apos visitar /clientes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 21:18:39 -03:00

49 lines
2.4 KiB
HTML

<!-- app/templates/base.html -->
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>{% block titulo %}Painel de Clientes{% endblock %}</title>
<style>
body { font-family: system-ui, sans-serif; margin: 0; background: #17171a; color: #f4f4f5; }
nav { background: #232326; padding: 12px 20px; display: flex; gap: 16px; }
nav a { color: #f4f4f5; text-decoration: none; }
nav a:hover { color: #F5821F; }
main { padding: 20px; max-width: 960px; margin: 0 auto; }
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
th, td { text-align: left; padding: 8px; border-bottom: 1px solid #3a3a3e; }
th a { color: inherit; text-decoration: none; white-space: nowrap; }
th a:hover { color: #F5821F; }
input, select { padding: 8px; border-radius: 6px; border: 1px solid #3a3a3e; background: #17171a; color: #f4f4f5; width: 100%; box-sizing: border-box; }
label { display: block; margin-top: 10px; font-size: 0.85rem; color: #a1a1aa; }
button { margin-top: 14px; padding: 10px 16px; border: none; border-radius: 6px; background: #F5821F; color: #17171a; font-weight: 700; cursor: pointer; }
.mensagem { padding: 10px; border-radius: 6px; margin-bottom: 12px; }
.mensagem.success { background: #14532d; }
.mensagem.danger { background: #7f1d1d; }
.mensagem.warning { background: #78350f; }
a.botao { display: inline-block; padding: 6px 10px; border: 1px solid #3a3a3e; border-radius: 6px; color: #f4f4f5; text-decoration: none; margin-right: 6px; }
</style>
</head>
<body>
<nav>
<a href="/clientes">Clientes</a>
<a href="/gerador-chave">Gerador de chave</a>
{% if request.state.usuario and request.state.usuario.eh_admin %}
<a href="/funcionarios">Funcionários</a>
{% endif %}
<a href="/log">Log</a>
{% if request.state.usuario %}
<a href="/minha-conta">Minha conta</a>
<form method="post" action="/logout" style="display:inline;margin:0">
<input type="hidden" name="csrf_token" value="{{ csrf_token or request.state.csrf_token }}">
<button type="submit" style="margin:0;padding:4px 10px;background:transparent;border:1px solid #3a3a3e;color:#f4f4f5;font-weight:400">Sair</button>
</form>
{% endif %}
</nav>
<main>
{% if mensagem %}<div class="mensagem {{ mensagem_tipo or 'success' }}">{{ mensagem }}</div>{% endif %}
{% block conteudo %}{% endblock %}
</main>
</body>
</html>