fix(frontend): tela de "Trocar senha" no primeiro acesso

Achado real reportado pelo usuário testando: todo usuário criado (tenant novo em
Clientes > Tenants, ou convite em Administração > Usuários) nasce com
mustChangePassword: true (agente.md secao 199), mas POST /api/login simplesmente
bloqueava com "use a API /auth/change-password por enquanto" — sem nenhuma tela pra
fazer isso. Todo primeiro login de qualquer conta nova batia nessa parede.

POST /api/login agora grava o cookie de sessão mesmo com mustChangePassword: true
(única forma de chamar /auth/change-password autenticado depois) e devolve o flag pro
client, que manda pra /trocar-senha em vez de mostrar erro. Tela nova pede a senha
temporária + nova senha (2x), chama POST /auth/change-password, e reaproveita a mesma
decisão platform/tenant do login normal (/api/post-login).

Testado ponta a ponta com um usuário de teste de verdade (convidado, nunca logado
antes): login → /trocar-senha → senha trocada → /app direto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
2026-08-30 10:41:20 -03:00
parent 798aa7b579
commit 4b927e9d9e
8 changed files with 195 additions and 8 deletions

22
TODO.md
View File

@@ -1735,6 +1735,28 @@ secao 96-103, 124, 169) + achado real de autorização em `/ai/models`
Regressão: tenant_admin e platform_super_admin continuam vendo
TODO item do próprio menu (sem perder nada)
## PHASE 49 — Tela de "Trocar senha" no primeiro acesso (agente.md secao
199) — achado real reportado pelo usuário testando
- [x] achado real: todo usuário criado (tenant novo em Clientes > Tenants,
ou convite em Administração > Usuários) nasce com
`mustChangePassword: true` (secao 199) — mas `POST /api/login`
simplesmente bloqueava com "use a API /auth/change-password por
enquanto", sem nenhuma tela pra fazer isso. Todo primeiro login de
qualquer conta nova batia nessa parede. Descoberto pelo usuário
tentando logar num tenant que ele mesmo criou
- [x] Corrigido: `POST /api/login` agora grava o cookie de sessão mesmo
com `mustChangePassword: true` (única forma de chamar
`/auth/change-password` autenticado depois) e devolve o flag pro
client, que manda pra `/trocar-senha` em vez de mostrar erro. Tela
nova: senha temporária + nova senha (2x, valida no client que
batem e que tem 12+ caracteres) → `POST /auth/change-password` →
mesma decisão platform/tenant do login normal (`/api/post-login`,
reaproveitado)
- [x] Testado ponta a ponta com um usuário de teste de verdade (convidado,
nunca logado antes): login → `/trocar-senha` → senha trocada →
`/app` direto, sem passar pela tela de login de novo. Usuário de
teste removido no final
---
## Riscos conhecidos