# Correção: login falha ("Credenciais inválidas") para alguns usuários com senha correta ## Contexto Usuários relatam, de forma intermitente entre pessoas (não para todos), que digitam a senha correta e recebem "Credenciais inválidas". A hipótese inicial ("será que está logando mas mostra erro?") foi **descartada**: em `src/app/lib/userLoginAction.js` o `signIn` em caso de sucesso lança `NEXT_REDIRECT`, que é corretamente relançado (linhas 32-39), redirecionando para `/dispatcher`. Não existe caminho de sucesso que ainda exiba o erro. Trata-se de uma **falha real de autenticação** (nenhuma sessão é criada). ### Causa raiz O `username` é **gravado normalizado** mas **consultado cru**: - Schema `src/app/models/User.js:9-10` define `trim: true` + `lowercase: true`. O Mongoose aplica isso em todo `save`/`create`, então no banco todo username está minúsculo e sem espaços. - Login `src/app/lib/utils/auth.js:31-32` busca com o valor cru: `User.findOne({ username: credentials.username })`. O MongoDB faz match **case-sensitive**. Resultado: quem cadastrou `Joao` (salvo como `joao`) e faz login digitando `Joao` gera busca por `"Joao"` → nenhum match → `null` → "Credenciais inválidas", **sem nem comparar a senha**. ### Por que "alguns sim, outros não" Quem digita o usuário todo em minúsculo entra; quem digita com maiúscula/espaço falha **sempre** (consistente por usuário, não aleatório). Gatilho principal: teclado de **celular** auto-capitaliza a primeira letra, e o input de login (`src/app/auth/login/LoginForm.jsx:31-37`) não tem `autoCapitalize`/`autoCorrect`/`autoComplete`. Autofill com espaço final tem o mesmo efeito. Daí o padrão "mobile reclama, desktop não". **Observação sobre dados:** não é necessária migração de banco. Como o Mongoose já força lowercase em toda gravação, não há usernames mixed-case armazenados — apenas a consulta precisa ser corrigida. ## Abordagem (escopo robusto) ### 1. Normalizar a consulta no provider de auth (correção central) `src/app/lib/utils/auth.js` - Derivar um username normalizado uma vez e usá-lo na consulta: ```js const username = (credentials.username || "").trim().toLowerCase(); const password = credentials.password; ... const user = await User.findOne({ username }).lean(); ``` - Remover o uso duplicado de `credentials.username` na linha 32 (usar a variável já tratada). ### 2. Normalizar também no server action de login `src/app/lib/userLoginAction.js` - Após `formData.get("username")`, normalizar antes de validar/enviar e antes de preencher `rawData` (para que o `defaultValue` re-exibido no form já volte normalizado): ```js const username = (formData.get("username") || "").trim().toLowerCase(); ``` - Mantém o tratamento de `NEXT_REDIRECT`/`CredentialsSignin` como está. ### 3. Endurecer o input de login contra auto-capitalização (mobile) `src/app/auth/login/LoginForm.jsx` — no `UIInput` de `name="username"` adicionar: `autoCapitalize="none"`, `autoCorrect="off"`, `spellCheck={false}`, `autoComplete="username"`. - Confirmar que `src/components/ui/input.jsx` repassa `...props` (já repassa), então os atributos fluem para o `` nativo. ### 4. Alinhar a checagem de duplicado no cadastro `src/app/lib/users/createUserAction.js:131` — a verificação `findOne({ username })` usa o valor cru e é case-sensitive, enquanto o `User.create` grava lowercased. Normalizar o `username` logo na leitura (linha 24) para `(formData.get("username") || "").trim().toLowerCase()`, de modo que a checagem de duplicado, a mensagem de erro re-exibida e o valor gravado fiquem consistentes. A validação de "sem espaços" (linha 55) continua válida. - Aplicar a mesma normalização de leitura em `createWardUserAction.js` (criação de ward) para manter consistência, caso ele leia username de formData da mesma forma. ## Arquivos críticos - `src/app/lib/utils/auth.js` — fix central da consulta (CRÍTICO) - `src/app/lib/userLoginAction.js` — normalização do input do login - `src/app/auth/login/LoginForm.jsx` — atributos anti auto-capitalize - `src/app/lib/users/createUserAction.js` — consistência na checagem/gravação - `src/app/lib/users/createWardUserAction.js` — mesma consistência - (referência, sem alteração) `src/app/models/User.js`, `src/components/ui/input.jsx` ## Verificação 1. **Repro do bug (antes do fix):** com um usuário existente (ex.: `joao`), tentar login digitando `Joao` ou `joao ` (com espaço) → deve dar "Credenciais inválidas". 2. **Depois do fix:** - Login com `Joao`, `JOAO`, ` joao `, `joao` → todos devem autenticar e redirecionar para `/dispatcher`. - Senha errada → continua "Credenciais inválidas" (regressão de segurança garantida). - Usuário inexistente → "Credenciais inválidas". 3. **Mobile:** abrir `/auth/login` em viewport mobile / dispositivo e confirmar que o campo Usuário não auto-capitaliza a primeira letra. 4. **Cadastro:** registrar `Maria`; conferir no banco que foi salvo como `maria`; tentar cadastrar `maria` de novo → "Nome de usuario ja cadastrado". 5. Rodar a app localmente (`npm run dev`) e exercitar os fluxos acima; rodar a suíte de testes se existir.