## MG-4 — Autenticação no Firebase Auth, com recuperação de senha

**PRD:** `docs/prd/migracao-firebase.md`

**Como** participante, **quero** entrar com e-mail e senha e **conseguir
recuperar o acesso**, **para** esquecer a senha não custar minha conta e meu
histórico de bolões.

**Prioridade:** Must — hoje esquecer a senha é definitivo, e isso é a pior
consequência do produto.

**Critérios de aceite:**

- Dado que tenho conta, quando entro com e-mail e senha corretos, então acesso os
  meus bolões.
- Dado que erro a senha, então a recusa **não** revela se o e-mail existe.
- Dado que erro a senha várias vezes, então novas tentativas são limitadas.
- Dado que esqueci a senha, quando peço recuperação, então recebo e-mail e
  consigo definir uma nova.
- Dado que estou logado em outro aparelho, quando entro aqui, então a outra sessão
  continua válida.
- Dado que estou sem conexão na abertura do app, então a sessão guardada continua
  valendo — não sou deslogado por falta de rede.
- Dado que meu e-mail tem maiúsculas, então entro na mesma conta.

**Tasks:**

_Backend_
- [x] `BE-1` Firebase Auth com e-mail/senha e política de senha equivalente à atual (mínimo 8)
- [x] `BE-2` Documento de perfil (`usuarios/{uid}`) criado no primeiro login, com nome de exibição (depende de BE-1)
- [ ] `BE-3` Recuperação de senha por e-mail habilitada, com o texto em português (depende de BE-1)
- [x] `BE-4` Confirmar que a resposta de credencial inválida não distingue e-mail inexistente de senha errada (depende de BE-1)
- [x] `BE-5` Confirmar o limite de tentativas do Auth e registrar o número real (depende de BE-1)

_Mobile_
- [ ] `FE-1` Login e cadastro pelo SDK do Firebase, mantendo as telas atuais (depende de BE-1)
- [ ] `FE-2` Fluxo de "esqueci minha senha" — **a tela hoje diz que não existe recuperação**, e esse texto sai (depende de BE-3)
- [ ] `FE-3` Sessão offline: cache do Auth sobrevive à abertura sem rede (depende de BE-1)

_QA_
- [ ] `QA-1` Escrever o plano de casos de teste a partir desta story
- [ ] `QA-2` Executar reaproveitando `AC-1`, `AC-2` e `AC-3`, **mais** os casos novos de recuperação de senha

**Riscos/Dependências:**

- Depende de `MG-1`. Não depende de Blaze: o Auth funciona no plano gratuito.
- **`AC-4` volta do cancelamento.** Ela foi cancelada em 03/08 por não haver
  serviço de e-mail; o Auth resolve isso sem custo. A consequência registrada em
  `AC-1`/`AC-2` ("não há recuperação, esquecer a senha custa a conta") **deixa de
  valer** e os textos de tela que a anunciam precisam sair — inclusive o caso
  `AC-2-09`, que hoje **exige** a ausência do link.
- O rate limit deixa de ser nosso: `AC-2-03`/`AC-2-04` passam a verificar o
  comportamento do Auth, e o número de tentativas pode não ser o mesmo. Registrar o
  real em vez de assumir.

- **07/08 — servidor feito e verificado; app segue aberto.** 4 casos de integração
  (suíte de 70). Execução em `docs/testes/MG-4-execucao.md`. `FE-1` a `FE-3` e `BE-3`
  ficam abertas: trocar o login para o SDK do Firebase mexe na camada de dados do
  app, que é o assunto de `MG-7`, e habilitar o e-mail de recuperação exige o projeto
  real.
- **Seguindo a premissa de que `AC-4` volta do cancelamento** (o Auth dá recuperação
  de senha de graça). Se a decisão for o contrário, é reversível: texto de tela e
  estado de story.
- **🔴 Regressão de segurança encontrada, e ela não é código:** o Auth distingue
  `auth/wrong-password` de `auth/user-not-found`, o que **quebra `AC-2-02`** — o
  login volta a ser oráculo de enumeração, e dá para descobrir quem tem conta
  testando e-mails. A correção é configuração (*email enumeration protection*), e
  **não é verificável em emulador**: o emulador não implementa. Primeira coisa da
  lista de `MG-8`.
- **`BE-1` marcada com ressalva registrada:** o Auth puro aceita senha de **6**, e a
  política do produto é 8. O app valida antes de chamar, mas quem falar direto com a
  API cria com 6. Fechar exige política do Identity Platform ou *blocking function* —
  upgrade de plano, decisão do dono.
- **`BE-5` marcada como "medido, não suposto":** o emulador **não** aplica rate limit,
  então `AC-2-03`/`AC-2-04` passam a depender do comportamento em produção, com o
  número a ser medido no projeto real.
