Pular para o conteúdo principal

Feature: Autenticação e Acesso

Introdução ao documento

Este documento descreve a feature de autenticação observada no hub: entrada pública, login por CPF, criação de sessão via NextAuth e redirecionamento inicial do usuário autenticado. Evidências: src/app/page.tsx:8-27, src/components/Login/Login.component.tsx:100-122, src/utils/authOptions.ts:20-117.

Versionamento

  • Documento criado em 2026-03-20.
  • Revisar quando mudarem src/app/page.tsx, src/components/Login/Login.component.tsx, src/utils/authOptions.ts ou a rota api/auth/[...nextauth]. Evidências: src/app/page.tsx:8-27, src/components/Login/Login.component.tsx:100-122, src/app/api/auth/[...nextauth]/route.ts:1-6.

Referencial teórico

O fluxo foi derivado da página /, do componente Login, da configuração nextAuthOptions e do redirect do layout protegido. Evidências: src/app/page.tsx:8-27, src/components/Login/Login.component.tsx:77-237, src/utils/authOptions.ts:7-117, src/app/(protected-routes)/layout.tsx:21-25.

Visão geral

  • A rota / exibe a tela de login quando não há sessão e redireciona para /home quando a sessão já existe. Evidências: src/app/page.tsx:8-27.
  • O formulário autentica via signIn('credentials'), usando CPF digitado como username e password. Evidências: src/components/Login/Login.component.tsx:100-122.
  • O CredentialsProvider envia as credenciais para ${baseUrl}/api/jwt-auth/v1/token e persiste o objeto retornado na sessão JWT. Evidências: src/utils/authOptions.ts:59-109.

Atores

  • Participante, que entra por CPF e pode ter course_id persistido no navegador. Evidências: src/components/Login/Login.component.tsx:100-107.
  • Facilitador e supervisor, que podem entrar por rotas públicas contextualizadas e limpam isParticipantMode no login. Evidências: src/components/Login/Login.component.tsx:104-106, src/app/(public-routes)/[slug]/page.tsx:11-30.
  • Backend WordPress/JWT, que valida credenciais em /api/jwt-auth/v1/token. Evidências: src/utils/authOptions.ts:59-69.

Pré-condições

  • O usuário precisa acessar a rota pública / ou /(public-routes)/[slug] sem sessão válida. Evidências: src/app/page.tsx:9-15, src/app/(public-routes)/[slug]/page.tsx:33-52.
  • NEXTAUTH_URL e NEXTAUTH_SECRET precisam estar configurados para a sessão funcionar. Evidências: .env.example:3-4, helm/templates/secret.yaml:13-18.
  • API_URL precisa apontar para o backend que expõe /api/jwt-auth/v1/token. Evidências: src/utils/consts.ts:1, src/utils/authOptions.ts:59-69.

Fluxo principal

  1. O usuário acessa /; se já existe sessão, a página redireciona para /home. Evidências: src/app/page.tsx:9-15.
  2. O usuário digita CPF; o componente mascara o valor e usa o mesmo CPF como usuário e senha. Evidências: src/components/Login/Login.component.tsx:124-127, src/components/Login/Login.component.tsx:184-197.
  3. O componente chama signIn('credentials', { redirect: false, username, password }). Evidências: src/components/Login/Login.component.tsx:108-113.
  4. O CredentialsProvider chama ${baseUrl}/api/jwt-auth/v1/token e retorna o payload do usuário quando recebe token. Evidências: src/utils/authOptions.ts:59-87.
  5. Em sucesso, a UI faz router.push('/home'). Evidências: src/components/Login/Login.component.tsx:119-121.

Fluxos alternativos

  • Se o login falhar, a UI marca erro e exibe Usuário ou senha incorretos. Evidências: src/components/Login/Login.component.tsx:115-117, src/components/Login/Login.component.tsx:199-203.
  • Em modo E2E, o provider aceita mocks por CPF e gera fallback supervisor para usuários não mapeados. Evidências: src/utils/authOptions.ts:25-43.
  • Se o usuário já estiver autenticado e acessar /, ele não vê a tela de login. Evidências: src/app/page.tsx:9-15.

Regras de negócio

  • A autenticação credencial usa CPF sem máscara tanto para username quanto para password. Evidências: src/components/Login/Login.component.tsx:109-113.
  • Quando course_id vem da página pública, ele é salvo em localStorage antes do login. Evidências: src/components/Login/Login.component.tsx:100-103.
  • Logins de supervisor/facilitador removem isParticipantMode do navegador. Evidências: src/components/Login/Login.component.tsx:104-106.
  • Usuários administrator são remapeados para supervisor na sessão. Evidências: src/utils/authOptions.ts:85.
  • Para subscriber com enroll_ids, o login dispara logs de negócio Logou no HUB. Evidências: src/utils/authOptions.ts:71-83, src/app/services/external/LogsService.ts:3-15.

Estados possíveis

  • sem_sessao: tela de login renderizada. Evidências: src/app/page.tsx:17-27.
  • autenticando: submissão do formulário com signIn. Evidências: src/components/Login/Login.component.tsx:108-113.
  • erro: result?.error verdadeiro. Evidências: src/components/Login/Login.component.tsx:115-117.
  • autenticado: sessão criada e navegação para /home. Evidências: src/components/Login/Login.component.tsx:119-121, src/app/(protected-routes)/layout.tsx:21-25.

Endpoints envolvidos

  • Ver OpenAPI: POST /api/auth/[...nextauth] e o backend externo ${API_URL}/api/jwt-auth/v1/token.
  • Ver também OpenAPI: POST /api/logs para o registro de ações em fluxos autenticados.

Evidências: src/app/api/auth/[...nextauth]/route.ts:1-6, src/utils/authOptions.ts:59-83, src/app/api/logs/route.ts:6-40.

Dados impactados

  • Ver model.md: identidade do usuário em sessão, turma corrente e vínculo de matrícula (enroll_id) usado para logging.
  • O repositório também persiste course_id e isParticipantMode no navegador. Evidências: src/components/Login/Login.component.tsx:100-107.

Pendências

  • O contrato exato do payload JWT do WordPress não está formalizado no repositório.
  • Não há rate limiting, MFA ou política de bloqueio documentados no código versionado.