Files
scoreodonto.com/documentação/RX_BACKLOG_robustez-seguranca-cleanup.md
T
VPS 4 Builder 37cc818f4c docs: centraliza e reescreve a documentação em documentação/
- reúne todos os .md de ScoreOdonto numa pasta única (fonte única, dentro do repo versionado pelo Gitea)
- arquitetura.md: reescrito p/ o estado REAL (3 VPS, banco compartilhado dev/prod, sem staging/listener/registry fantasmas)
- deploy.md: reescrito p/ o estado-ALVO (Gitea CI/CD: push->build->registry->deploy por tag)
- DEPLOY-PRODUCAO.md: runbook operacional executável (fluxo manual real de hoje)
- VERDADE-HOJE.md: auditoria (codigo/banco/containers/deploy/versao/rollback)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 06:45:51 +02:00

94 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RX — Backlog de robustez, segurança e limpeza
> Tarefas derivadas da revisão de 2026-06-12 (multi-tenant + client.exe + storage).
> Prioridade: **P1** (faria primeiro) · **P2** · **P3**. Marcar `[x]` ao concluir.
> Regra do projeto: nada vai pra prod sem autorização; dev.rx e prod.rx **compartilham
> DB+Wasabi** (ver T3.1 — separar é o que mais reduz risco).
---
## 3. Robustez do RX / resync
- [ ] **T3.1 (P1) — Separar DEV de PROD (DB + Wasabi).** Hoje compartilham o mesmo
Postgres (`dental_images`) e o mesmo bucket → testes mexem em dado real. Opções:
banco `dental_images_dev` e/ou prefixo/bucket Wasabi por ambiente (`RX_ENV`).
- [x] **T3.2 (P1) — Healthcheck de reconciliação Wasabi↔banco** por `clinica_id`/`tenant_id`.
FEITO (dev): `GET /api/admin/rx-health` (RX) — contagens por (tenant,clínica) + cron +
`?clinica_id=&checkLimit=N` (HEAD-check de ausentes). Proxy `GET /api/rx/health`
(scoreodonto, superadmin). Validado: Consultt 2723 imgs/513 pac, 0 ausentes em 15. Commit 016305e.
- [ ] **T3.3 (P2) — Índice único parcial** `images(original_filename) WHERE enabled=1`
como trava de duplicata no banco. ⚠️ Criar CONCURRENTLY e fora do boot (se houver
duplicata, a criação no boot derrubaria o servidor).
- [ ] **T3.4 (P2) — Remover `send-image` legado** após confirmar que todo `.exe` em campo
é ≥ Direct Upload (1.3.x). Elimina um caminho de upload + base64 pela VPS.
- [ ] **T3.5 (P2) — Throttle/progresso no resync.** `trigger-sync` reescaneia todos os PNGs;
em clínica grande é pesado → lote + reporte de progresso.
- [ ] **T3.6 (P3) — `check-image-exists`**: garantir que checa linha no banco **E** objeto no
Wasabi (senão objeto sumido nunca é reenviado).
## 4. Client.exe
- [ ] **T4.1 (P1) — Code signing do instalador NSIS** (evita SmartScreen nas clínicas).
- [ ] **T4.2 (P1) — `machine_token` em repouso**: proteger no config local (DPAPI/cripto).
- [ ] **T4.3 (P2) — Retry/backoff + fila persistente** nos PUT do Wasabi e na `uploadQueue`
(sobreviver a restart / internet ruim).
- [ ] **T4.4 (P2) — Telemetria pro `/clients`**: client envia `last_sync`, profundidade da
fila e últimos erros → página mostra saúde real.
- [ ] **T4.5 (P2) — `lookupPatientInfo` tolerante a versão** do banco do sensor RF.
- [ ] **T4.6 (P3) — Pipeline de auto-update**: automatizar envio de `Setup x.y.z.exe` +
`latest.yml` pro `updates/` do prod ao rebuildar.
## 5. Segurança / hardening
- [ ] **T5.1 (P1) — `api_token` global criptografado em repouso** (hoje texto puro em
`settings.rx_config_global`) + rotação + idealmente token de escopo reduzido (não-god).
- [x] **T5.2 (P1) — Auditar escopo GLOBAL do `tenantGuard`** — FEITO (dev). 🔴 Achado crítico:
a família `/api/sync/*` (sync GLOBAL legado) usava `tenantGuard`**burlável sem clinicaId**;
`DELETE /api/sync/truncate-all` fazia `TRUNCATE pacientes,agendamentos,financeiro,leads,guias`
de **todas as clínicas** → qualquer usuário logado (até funcionário) apagava o banco inteiro.
**Corrigido**: os 13 endpoints `/api/sync/*``superadminGuard`. Provado: não-superadmin
agora recebe **403** (antes truncava). 2º achado: **`/api/settings/google-credentials`** GET+POST
(credenciais OAuth GLOBAIS da plataforma) também era `tenantGuard` → qualquer logado sobrescrevia →
**`superadminGuard`** (403 p/ não-super; front só chama p/ superadmin). **Auditoria completa**:
todos os demais `tenantGuard` (clinica-sync, dashboard, agendamentos, avaliacoes, financeiro,
guias, leads/:id/converter, DELETE :id, rx/devices) exigem `req.clinicaId` + `WHERE clinica_id` → seguros.
- [ ] **T5.3 (P1) — Auth do `remote-crud-patient`** (socket escreve no banco local do client):
validar papel/escopo forte no servidor.
- [ ] **T5.4 (P2) — Defesa em profundidade no RX server**: validar tenant nos endpoints admin
(não confiar só no proxy do scoreodonto).
- [ ] **T5.5 (P2) — Revisar os 9 dias de WIP** (`auth.js`, `database.js`, `storage.js`, páginas)
antes do prod.
- [!] **T5.6 (P3→P0) — Auditar histórico do git por segredos** — FEITO. 🔴🔴🔴 ACHADOS CRÍTICOS:
- `dental-server/bkp/docs/ENV-CONFIG.txt` tem o **`JWT_SECRET` REAL** (confirmado == o do
servidor) commitado → **qualquer um com acesso ao repo forja JWT de admin do RX**.
- `INSTRUCOES-SERVIDOR-VPS.txt` tem o **`DB_PASSWORD`/`REDIS_PASSWORD` reais** em texto puro.
AÇÃO OBRIGATÓRIA (decisão do usuário, não automatizei):
1. **Rotacionar JWT_SECRET** (invalida tokens, força re-login) — fecha a forja.
2. **Rotacionar senha do Postgres/Redis** (10.99.0.3).
3. Remover os segredos dos arquivos versionados + **scrub do histórico** (git filter-repo/BFG).
`.secrets` já está no .gitignore (feito antes); isso NÃO resolve os já commitados → rotação é mandatória.
## 6. Limpeza / tech-debt
- [ ] **T6.1 (P1) — Consolidar os 4 caminhos de upload** (`image-upload-direct`, `send-image`,
`/api/images/upload`, `/upload-file`) → manter 12, remover o resto.
- [ ] **T6.2 (P2) — Simplificar `storage.js` pós-resync** (remover fallback legado quando todos
os objetos estiverem na key nova).
- [ ] **T6.3 (P2) — Remover diretórios mortos** (`bkp/`, `public_legacy/`, `old-root-files/`).
- [ ] **T6.4 (P3) — Upgrade Node 20 → 22** (AWS SDK exigirá ≥22 em 2027).
- [ ] **T6.5 (P3) — Log levels** (info/debug/error) no servidor RX.
- [ ] **T6.6 (P3) — Passada final de comentários/padronização** no fluxo RX.
---
### Log
- **2026-06-12** — T3.2 concluída (healthcheck de reconciliação, read-only).
- **2026-06-12** — T5.2 concluída. 🔴 Fechado RCE-like: `/api/sync/truncate-all` (e família) +
`/api/settings/google-credentials` deixavam qualquer logado truncar o banco / trocar OAuth global →
agora `superadminGuard` (403 p/ não-super). Mudanças no **scoreodonto (dev), não commitadas**.
- **2026-06-12** — T3.6 auditada: `check-image-exists` já está correto (checa banco+Wasabi, apaga órfão). Sem fix.
- **2026-06-12** — T5.6 🔴🔴🔴: JWT_SECRET REAL + senha de DB/Redis commitados (ENV-CONFIG.txt,
EXEMPLO-ENV.txt, INSTRUCOES-SERVIDOR-VPS.txt, test-db2.js). **Passo 3 FEITO** (redigidos do working
tree, commits 4616f20+2b679a5). **PENDENTE/MANDATÓRIO (usuário): rotacionar JWT_SECRET + senha
Postgres/Redis + scrub do histórico** — até lá, a exposição persiste no histórico do Gitea.