Atualização Automatica dos numeros e correção de erro e falha de segurança
This commit is contained in:
94
README.md
94
README.md
@@ -1208,3 +1208,97 @@ app/views/layouts/_navbar.html.erb # botão flutuante + alç
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><strong>🔒 Segurança + auto-atualização do painel + cron (06/07/2026)</strong></summary>
|
||||
|
||||
Revisão de segurança do site em produção (via browser + inspeção de headers) e
|
||||
melhorias no **Dashboard de Operações**. **Sem migration.**
|
||||
|
||||
### 🩸 Causa-raiz descoberta — produção em modo `development`
|
||||
A página de erro 404 do site expunha o backtrace do Rails e havia o cookie
|
||||
`__profilin` (rack-mini-profiler) — sinais de que o container roda em
|
||||
**`RAILS_ENV=development`**. Isso é a origem de várias falhas abaixo (cookie de
|
||||
sessão sem `Secure`, sem redirect HTTPS, sem CSP, páginas de exceção vazando
|
||||
código).
|
||||
|
||||
> ⚠️ **Ação necessária no servidor** (o `.env` não está no repositório): definir
|
||||
> `RAILS_ENV=production` e `FORCE_SSL=true` no `.env` e rebuildar. Ao migrar para
|
||||
> `production`, validar o carregamento dos assets (Tailwind via CDN + importmap).
|
||||
|
||||
### 🔴 Correções de segurança
|
||||
- **HTTPS obrigatório + cookie `Secure` (itens 1 e 2)** — `config.force_ssl` +
|
||||
`assume_ssl` (este último para o TLS terminado no Cloudflare, evitando loop de
|
||||
redirect). Em `application.rb` fica atrás de `ENV["FORCE_SSL"]=="true"`, então
|
||||
**funciona mesmo enquanto o deploy roda fora do modo production**;
|
||||
`production.rb` também já vem com `force_ssl = true`.
|
||||
- **rack-mini-profiler desligado (item 3)** — no `Gemfile` passou a `require:
|
||||
false`: a gem não monta mais o middleware (fim do cookie `__profilin` e da rota
|
||||
`/mini-profiler-resources`), em qualquer ambiente.
|
||||
- **Content Security Policy (item 5)** — nova política em
|
||||
`config/initializers/content_security_policy.rb` com allowlist dos CDNs reais
|
||||
(Tailwind, Chart.js, Flatpickr, Leaflet, Google Fonts, tiles ArcGIS/OSM).
|
||||
Começa em **Report-Only** (só reporta violações, não bloqueia) para não quebrar
|
||||
mapa/gráficos; instruções no topo do arquivo para ativar o bloqueio
|
||||
(`report_only = false`) depois de validar no console.
|
||||
- Erro de login genérico ("Invalid email or password.") e recuperação de senha
|
||||
**não** revelam se o e-mail existe (sem enumeração de usuários) — **OK**, sem
|
||||
mudança. Pendência conhecida: login por **PIN de 4 dígitos sem identificador** —
|
||||
avaliar rate-limiting/rack-attack.
|
||||
|
||||
### 🔄 Painel de Operações atualiza sozinho (sem F5)
|
||||
- Novo `app/javascript/controllers/auto_refresh_controller.js` — a cada **5 min**
|
||||
(`data-auto-refresh-interval-value`, em ms) faz `Turbo.visit` na própria URL:
|
||||
re-renderiza KPIs/gráficos/mapa **sem o flash do F5**, **preserva os filtros**
|
||||
(que vivem na query string) e a **posição de rolagem**; pausa em aba oculta ou
|
||||
quando há um campo em foco.
|
||||
|
||||
### 🕑 Horário da "última atualização" corrigido
|
||||
- Antes mostrava `Time.now` — o **fuso do container (UTC)** e a **hora de
|
||||
renderização** (por isso aparecia adiantado e sempre "agora"). Agora um helper
|
||||
(`ultima_atualizacao_dados` / `ultima_atualizacao_label`) calcula o **último
|
||||
slot real de sincronização** (a cada 30 min, das 08h às 18h) no fuso de
|
||||
Brasília (`Time.current`).
|
||||
|
||||
### ⏰ Agendamento (whenever/cron) no Docker
|
||||
- `config/schedule.rb` — job de histórico passou de `every 1.hour` para
|
||||
**`*/30 8-18`** (a cada 30 min, 08h-18h), batendo com a cadência real.
|
||||
- `Dockerfile` — instala o pacote **`cron`**.
|
||||
- `docker-compose.yml` — o boot agora roda, em ordem: `db:prepare` →
|
||||
**`whenever --update-crontab`** (grava os jobs) → **`cron`** (sobe o daemon) →
|
||||
`rails s`. As variáveis do banco chegam ao job via **dotenv** quando o rake
|
||||
carrega o Rails.
|
||||
|
||||
### 📂 Arquivos
|
||||
```
|
||||
config/application.rb # gate FORCE_SSL → force_ssl + assume_ssl
|
||||
config/environments/production.rb # force_ssl = true (+ assume_ssl)
|
||||
config/initializers/content_security_policy.rb # CSP (report-only) — NOVO
|
||||
config/initializers/rack_mini_profiler.rb # comentário atualizado
|
||||
Gemfile # rack-mini-profiler, require: false
|
||||
.env.example # RAILS_ENV=production + FORCE_SSL=true
|
||||
app/helpers/application_helper.rb # ultima_atualizacao_dados / _label
|
||||
app/javascript/controllers/auto_refresh_controller.js # auto-refresh do painel — NOVO
|
||||
app/views/operacoes_dashboard/index.html.erb # data-controller auto-refresh + horário
|
||||
config/schedule.rb # cron */30 8-18
|
||||
lib/tasks/historico.rake # desc atualizada
|
||||
Dockerfile # instala cron
|
||||
docker-compose.yml # whenever --update-crontab + cron no boot
|
||||
```
|
||||
|
||||
### ▶️ Deploy
|
||||
```bash
|
||||
# 1. No servidor, ajustar o .env:
|
||||
# RAILS_ENV=production
|
||||
# FORCE_SSL=true
|
||||
# 2. Rebuildar e subir (já roda whenever --update-crontab + cron no boot):
|
||||
docker compose up -d --build
|
||||
# 3. Validar a CSP no navegador (F12 → console, sem violações) e então trocar
|
||||
# config/initializers/content_security_policy.rb para report_only = false.
|
||||
```
|
||||
|
||||
> **Sem migration.** ⚠️ Em produção, **reiniciar o Puma** após o deploy.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user