2.9 KiB
04 — Autenticação e cadastro do cliente
Contexto do projeto (leia sempre)
Sistema web "Briefing de Site" da SeConectai: o cliente se cadastra e depois preenche o briefing de criação do site, com um botão Ajuda em cada pergunta que abre um popup com o texto do guia auxiliar. O dono (Tiago) acompanha tudo por um painel admin.
Stack fixa: Next.js 14+ (App Router) + TypeScript, PostgreSQL 16, Prisma, Tailwind + shadcn/ui, React Hook Form + Zod, Auth.js v5 (Credentials, estratégia JWT), Docker Compose. Idioma da interface: pt-BR.
Regras gerais: leia 00-arquitetura-briefing-site.md e 99-progresso.md antes de começar; não avance se a etapa anterior estiver incompleta; ao terminar, devolva o 99-progresso.md atualizado. Não invente dependências fora da stack. Nada de senhas de clientes em lugar nenhum.
Pré-requisito
Etapas 01–03 concluídas.
Tarefa
Cadastro (/cadastro)
Campos: Nome completo, CPF, WhatsApp, E-mail, Senha (mín. 8) e confirmação. Seletor "Este site é para uma empresa?" — se sim, exibir Razão Social, CNPJ e Endereço (CEP com busca opcional no ViaCEP no navegador, logradouro, número, complemento, bairro, cidade, UF). Checkbox obrigatório de aceite da Política de Privacidade/LGPD (guardar lgpdAceiteEm).
Validações Zod (cliente + servidor) em lib/validators.ts: CPF e CNPJ com dígito verificador; WhatsApp brasileiro (DDD + 9 dígitos, normalizar para +55DDDNÚMERO); e-mail normalizado em minúsculas; máscara de entrada para CPF/CNPJ/WhatsApp/CEP.
Servidor: criar User + Cliente em transação; CPF → lib/crypto.ts (encrypt/decrypt AES-256-GCM com CPF_ENC_KEY, hashCpf HMAC-SHA256 com CPF_HASH_KEY); rejeitar e-mail ou CPF já cadastrados com mensagem genérica que não revele qual existe; senha com argon2.
Login e sessão
Auth.js v5 com provider Credentials, JWT, cookie httpOnly/secure/sameSite=lax; sessão contém userId e papel. middleware.ts protege /briefings* (CLIENTE) e /admin* (ADMIN) e redireciona para /login. Limitar tentativas de login (rate limit simples em memória por IP+e-mail).
Recuperar senha
/recuperar-senha (pede e-mail; resposta sempre igual exista ou não a conta) → e-mail com link de token aleatório (guardar só o hash, expira em 1 h, uso único) → /redefinir-senha. Enviar por SMTP via lib/mail.ts (nodemailer).
Após o login
Cliente cai em /briefings (lista vazia com botão "Iniciar meu briefing"). Admin cai em /admin.
Critérios de aceite
- Cadastro PF e PJ funcionam; campos de empresa só aparecem/são exigidos no modo PJ.
- CPF/CNPJ inválidos são recusados; CPF não aparece em texto puro no banco nem em logs.
- E-mail/CPF duplicado é recusado sem revelar qual.
- Rotas protegidas redirecionam; cliente não acessa
/admin. - Recuperação de senha funciona de ponta a ponta (token expira e é de uso único).
Atualize 99-progresso.md (04).