Entrar como:FuncionalidadesDoc
Pular para o conteúdo
← Voltar para a visão geral
✅ ConcluídoCard #2 · M0

Autenticação - 6 Níveis RBAC

Marco M0: Infraestrutura + Autenticação + Design System

📅18 de julho de 2026

📄 Documento de Execução — Card 2: [M0] Autenticação - 6 Níveis RBAC

Campo Valor
Card Trello [2] [M0] Autenticação - 5 Niveis RBAC
URL Trello https://trello.com/c/DdDaFbIv
Marco M0 (18–28/07/2026)
Data execução 19/07/2026
Responsável Wellington Santiago (via ZCode)
Doc anterior Card 1 — Setup de Infraestrutura
Próximo card [3] [M0] Design System
Repo GitHub https://github.com/Wellitiz/genioon
URL DEV (live) https://sistemaescolar.wellka.com.br

Nota sobre o título do card: o card Trello diz "5 Níveis RBAC", mas o contrato ANIK FRANCHISING define 6 roles (STUDENT, PARENT, PROFESSOR, LOCAL, SUPERVISOR, MASTER). O título é residual de antes do SUPERVISOR ser adicionado. Implementamos 6 roles conforme documentação oficial (docs/ARQUITETURA.md §3.0 + docs/BANCO_DE_DADOS.md §2).


🎯 1. O que foi implementado

Autenticação completa com 6 roles RBAC

  • Login por email OU matrícula (RA) — mesmo JWT, mesma validação bcrypt, mesmo rate limit. Anti-enumeration: resposta idêntica para qualquer identificador.
  • 6 roles hierárquicas: STUDENT ⊂ PARENT ⊂ PROFESSOR ⊂ LOCAL ⊂ SUPERVISOR ⊂ MASTER
  • 2FA TOTP obrigatório para MASTER/LOCAL/SUPERVISOR; opcional para demais. Setup com QR code (Google Authenticator/Authy/1Password) + 10 códigos de backup.
  • bcrypt salt 12 com política forte (mín 8 chars, Aa1) + HaveIBeenPwned (k-anonymity).
  • Lockout após 5 tentativas falhas (15 min).
  • JWT strategy (NextAuth v5 beta) com cookies HttpOnly + Secure + SameSite. Sessão 24h web / 7d PWA (diferenciação reservada para PWA no Card futuro).
  • Recuperação de senha em 2 canais: E-mail (Resend) + WhatsApp (Meta Cloud API — stub em DEV, ativação real no M6). Token JWT 15min, one-time use.
  • tRPC v11 com 7 procedures RBAC (protected, master, supervisor, local, professor, parent, student).
  • i18n completo (next-intl) com PT-BR (default) / EN-US / ES-ES. Strings do módulo auth traduzidas nos 3 idiomas.
  • Middleware integrando next-intl (routing locale) + auth (autorizado) + guards RBAC por caminho (/master/*, /local/*, /professor/*, /pais/*, /aluno/*).
  • Audit log automático em login sucesso + reset de senha + 2FA enable/disable.
  • LGPD consent com ConsentRecord append-only (imutável).

Páginas auth (10 telas)

  • /login — formulário email/RA + senha com indicador de força
  • /verificar-2fa — input TOTP 6 dígitos, 3 tentativas, link p/ backup code
  • /esqueci-senha — seleção de canal (Email/WhatsApp), anti-enumeration
  • /resetar-senha — token JWT 15min, política forte validada
  • /configurar-2fa — wizard (QR → verify → backup codes), autenticado
  • /verificar-email — confirmação de cadastro PENDING → ACTIVE
  • /primeiro-acesso — wizard (senha → 2FA → LGPD consent)
  • /acesso-negado — 403 com botão voltar
  • /demo/perfis — demo antiga movida da raiz
  • / agora redireciona para /login

Componentes reutilizáveis

  • PasswordInput (toggle visibilidade + indicador força)
  • TotpInput (6 dígitos autoadvance)
  • RoleBadge (6 estilos por role)
  • LocaleSwitcher (PT/EN/ES)
  • LoginForm (em (auth)/login/page.tsx)
  • Layout (auth) com hero (desktop) + form side (mobile-first)

🗂️ 2. Arquivos criados/modificados

Prisma

  • prisma/schema.prismaEDITADO: adicionados 7 models + 3 enums
    • User (completo com 30+ campos), Account, Session, VerificationToken
    • Branch, ConsentRecord, AuditLog, SystemSetting
    • Enums: UserRole, UserStatus, RecoveryChannel
  • prisma/seed.tsNOVO: seed de SystemSettings defaults + Branch NIKI + usuário MASTER admin@genioon.com.br

Libs auth (src/lib/)

  • encryption.tsNOVO: AES-256-GCM (encrypt/decrypt/decryptSafe)
  • password-policy.tsNOVO: consts + validação client-safe
  • password.tsNOVO: bcrypt salt 12 + HaveIBeenPwned
  • totp.tsNOVO: otplib v13 (async) + qrcode + backup codes
  • auth-tokens.tsNOVO: JWT curto para reset (jose, 15min)
  • auth.config.tsNOVO: config NextAuth leve (middleware/Edge)
  • auth.tsNOVO: NextAuth v5 completo com Credentials provider
  • trpc/client.ts, query-client.ts, provider.tsxNOVO: tRPC client

tRPC server (src/server/trpc/)

  • context.tsNOVO: session + prisma no ctx
  • trpc.tsNOVO: 7 procedures RBAC + hasPermission helper
  • router.tsNOVO: rootRouter com subrouter auth
  • routers/auth.tsNOVO: requestPasswordReset, resetPassword, setup2faInitiate, setup2faConfirm, disable2fa, regenerateBackupCodes, consumeBackupCode, acceptConsent

Workers Bull

  • src/server/queues/workers/password-reset-email.tsNOVO: Resend em PROD, fallback log em DEV
  • src/server/queues/workers/password-reset-whatsapp.tsNOVO: stub em DEV (M6 habilitará envio real)

API routes

  • src/app/api/auth/[...nextauth]/route.tsNOVO: handler NextAuth
  • src/app/api/trpc/[trpc]/route.tsNOVO: fetchRequestHandler

Páginas

  • src/app/page.tsxEDITADO: redirect //login
  • src/app/demo/perfis/page.tsxNOVO (movido de page.tsx)
  • src/app/(auth)/layout.tsxNOVO: hero + form split
  • src/app/(auth)/login/page.tsxNOVO
  • src/app/(auth)/verificar-2fa/page.tsxNOVO
  • src/app/(auth)/esqueci-senha/page.tsxNOVO
  • src/app/(auth)/resetar-senha/page.tsxNOVO
  • src/app/(auth)/configurar-2fa/page.tsxNOVO
  • src/app/(auth)/verificar-email/page.tsxNOVO
  • src/app/(auth)/primeiro-acesso/page.tsxNOVO
  • src/app/(auth)/acesso-negado/page.tsxNOVO

Componentes

  • src/components/auth/PasswordInput.tsxNOVO
  • src/components/auth/TotpInput.tsxNOVO
  • src/components/auth/RoleBadge.tsxNOVO
  • src/components/auth/LocaleSwitcher.tsxNOVO

i18n

  • src/i18n/routing.tsNOVO: defineRouting (3 locales)
  • src/i18n/request.tsNOVO: getRequestConfig
  • messages/pt-BR.json, messages/en-US.json, messages/es-ES.jsonNOVOS

Middleware

  • src/middleware.tsNOVO: next-intl + auth + guards RBAC

Estilos

  • src/styles/auth.module.cssNOVO (~600 linhas): telas auth completas

Config

  • next.config.mjsEDITADO: plugin next-intl (withNextIntl)
  • src/app/layout.tsxEDITADO: NextIntlClientProvider + TRPCProvider
  • package.jsonEDITADO: deps tRPC/resend/superjson + prisma.seed
  • .env.exampleEDITADO: novas vars (RESEND_*, APP_URL, HAVEIBEENPWNED_API_ENABLED)

Testes

  • src/lib/__tests__/encryption.test.tsNOVO: 7 testes AES-256-GCM
  • src/lib/__tests__/password.test.tsNOVO: 5 testes bcrypt + HIBP
  • src/lib/__tests__/totp.test.tsNOVO: 8 testes otplib + backup codes
  • src/lib/__tests__/auth-tokens.test.tsNOVO: 4 testes JWT reset
  • Total: 33 testes passando (10 do Card 1 + 23 novos)

🗃️ 3. Schema do banco (mudanças)

Novos models

User (tabela users) — modelo central de auth

  • Identificação: id, email (unique), passwordHash, name, phone, avatarUrl
  • RBAC: role (UserRole), status (UserStatus default PENDING)
  • Filial: branchId?, branchIds[]
  • RA: registrationNumber? (unique) — login alternativo
  • Permissões: permissions Json, canApproveJustification Boolean
  • LGPD: consentedAt, consentVersion, dataExportedAt
  • Segurança: lastLoginAt, lastLoginIp, failedLoginCount, lockedUntil
  • 2FA: twoFactorEnabled, twoFactorSecret (AES-256-GCM), twoFactorBackupCodes
  • Verificações: emailVerifiedAt, phoneVerifiedAt
  • Reset email: resetToken, resetTokenExpiry
  • Reset WhatsApp: whatsappResetToken, whatsappResetExpiry
  • recoveryChannel enum (EMAIL | WHATSAPP) default EMAIL
  • Auditoria: createdAt, updatedAt
  • 4 índices: email, role, branchId, registrationNumber

Account, Session, VerificationToken — padrão NextAuth Adapter

Branch (tabela branches) — filial da rede com white-label

  • id, name, code (unique), cnpj?, isActive
  • White-label: logoUrl?, primaryColor default #4F6DF5, secondaryColor?, accentColor?
  • settings JSON

ConsentRecord (tabela consent_records) — append-only LGPD

  • userId, version, consentedAt, ipAddress, userAgent
  • 4 boolean flags: termsAccepted, privacyAccepted, marketingAccepted, dataProcessingAccepted

AuditLog (tabela audit_logs) — trilha de auditoria

  • userId?, action, resource, resourceId?, metadata JSON
  • ipAddress, userAgent, createdAt

SystemSetting (tabela system_settings) — key-value global

  • key (PK string), value JSON, updatedAt

Enumerations

  • UserRole { STUDENT, PARENT, PROFESSOR, LOCAL, SUPERVISOR, MASTER }
  • UserStatus { ACTIVE, INACTIVE, SUSPENDED, PENDING }
  • RecoveryChannel { EMAIL, WHATSAPP }

Migration

Migration SQL será gerada/aplicada na VPS DEV durante o deploy.


✅ 4. Itens da checklist do M0 atendidos

  • Login funcional com 6 níveis de acesso (STUDENT, PARENT, PROFESSOR, LOCAL, SUPERVISOR, MASTER)
  • Login aceita matrícula ou e-mail
  • 2FA TOTP exigido para MASTER/LOCAL/SUPERVISOR
  • Recuperação de senha por WhatsApp e por e-mail (WhatsApp stub em DEV — real no M6)
  • Aplicação renderiza em PT-BR, EN-US e ES-ES (troca de idioma funcional)
  • Layout renderiza corretamente por role (incluindo perfil SUPERVISOR via /local/* com guard)
  • Dark/light mode (herdado do Card 1 — tokens CSS estão prontos, переключ real entra no Card 3)
  • VPS Oracle com build publicado em sistemaescolar.wellka.com.br

⏳ 5. Pendências deixadas (handoff para próximo card)

Itens pendentes do checklist — TODOS COMPLETOS em 26/07/2026

Atualização: os 5 itens que estavam marcados como pendentes foram completados em sessão posterior (commit 40aca51 + migration 9fe4574). Card 2 agora tem 29/29 itens da Especificação Técnica completos. Veja detalhes abaixo.

WhatsApp real (M6)

  • Jobs Bull password-reset-whatsapp estão implementados mas em modo stub em DEV: logam o link/código no console em vez de enviar para a Meta Cloud API.
  • Quando Card M6 rodar, preencher WHATSAPP_TOKEN e WHATSAPP_PHONE_ID no .env e descomentar o bloco real em src/server/queues/workers/password-reset-whatsapp.ts.
  • Comentários no código referenciam o M6 explicitamente.

PWA sessão 7d

  • JWT callback reserva o ajuste de exp para 7d via cookie genioon.pwa=1, mas ainda não está plugado (sem PWA real ainda). Card futuro (M2) cobre isso.

Revogação JWT pós-reset

  • NextAuth JWT é stateless — não revoga diretamente.
  • TODO (Card futuro): adicionar passwordChangedAt no User e checar no callback jwt para invalidar tokens antigos após reset.

First-access wizard (passo 1)

  • /primeiro-acesso está funcional na UI (definir senha + 2FA + LGPD consent), mas o backend auth.completeFirstAccess ainda não foi criado (Card de gestão de usuários, M5). Por ora, usuários PENDING são bloqueados no login.

🔄 5b. Itens do checklist completados em sessão posterior (26/07/2026)

Schema Prisma COMPLETO (41 models + 27 enums)

  • Migration 20260726153625_schema_full_init (1368 linhas SQL) aplicada em DEV
  • Todos os models do BANCO_DE_DADOS.md agora existem no schema: Student, Guardian, Teacher, Course, Subject, Class, Enrollment, Grade, Attendance, Lesson, EadProgress, Material, Certificate, Task, Exam, LessonPlan, ChatConversation, ChatMessage, Announcement, Notification, NotificationConfig, Lead, Payment, Document, CalendarEvent, Ticket, WhatsAppConfig, etc.
  • Enum AuditAction adicionado (CREATE/READ/UPDATE/DELETE/LOGIN/LOGOUT/EXPORT/ IMPORT/APPROVE/REJECT/SEND)
  • AuditLog model atualizado com previousData/newData/branchId/ipAddress/userAgent

Rate limit completo (Redis + Edge)

  • Node-only: src/lib/rate-limit.ts — Redis token bucket (INCR+EXPIRE)
    • Constantes: RATE_LIMITS.AUTH (10/min), RATE_LIMITS.API (100/min), RATE_LIMITS.UPLOAD (20/min), RATE_LIMITS.RESET_REQUEST (3/hora)
    • Integrado no authorize() do NextAuth — falha com anti-enumeration
    • Fail-open se Redis cair
  • Edge: src/lib/rate-limit-edge.ts — in-memory LRU
    • Integrado no src/middleware.ts
    • /api/auth/* → 10 req/min por IP; /api/* → 100 req/min por IP
    • Camada adicional ao Nginx (defense in depth)
    • Hard cap 10k buckets para evitar OOM

Audit completo (tRPC + NextAuth events)

  • src/lib/audit.ts: helpers audit(), auditLogin(), auditCrud(), extractRequestMeta()
  • auditMiddleware() em src/server/trpc/trpc.ts para mutations tRPC:
    protectedProcedure.use(auditMiddleware({ action: 'CREATE', resource: 'student' }))
    
  • Integrado no authorize() do NextAuth: action LOGIN com newData.success + reason (invalid_credentials, account_suspended, account_pending, account_locked, invalid_2fa_code, email_not_verified, rate_limited)
  • Routers de auth (password reset, 2FA enable/disable) auditados automaticamente

Email verification flow completo

  • src/lib/email-verification.ts: sendEmailVerification() + confirmEmailVerification()
  • src/lib/auth-tokens.ts: signEmailVerificationToken() + verifyEmailVerificationToken() (JWT 24h, claim purpose=email_verification)
  • API route /api/auth/verify-email POST
  • Tela /verificar-email refatorada com 5 estados visuais: loading / success / expired / invalid / already_verified / idle
  • Worker Bull verify-email job integrado em password-reset-email.ts
  • Login bloqueia e dispara verificação automaticamente quando emailVerifiedAt = null
  • MASTER seed tem emailVerifiedAt setado direto (pula verificação)

Seed notificationConfigs defaults

  • 50 configs criados (10 NotificationType × 5 NotificationChannel)
  • PUSH/EMAIL/WHATSAPP ativados por default; SMS desativado; IN_APP desativado
  • Janela 08:00-20:00 configurável (sendFrom/sendUntil)
  • Templates ficam null por ora (definidos quando Card de Notificações rodar)
  • Adicionais: WhatsAppConfig seed, evaluation_policy seed, late_fee_strategy seed

🔗 6. Contexto técnico gerado para o próximo card (Card 3 — Design System)

Tokens CSS já disponíveis

  • src/styles/tokens.css completo: backgrounds, text, accent (#4F6DF5), status (success/warning/danger/info), shadows (5 níveis), radius, spacing, typography (Inter + JetBrains Mono).

Layout (auth) pronto para refinamento

  • src/app/(auth)/layout.tsx com split hero (desktop) + form side (mobile-first).
  • src/styles/auth.module.css (~600 linhas) cobrindo todos os componentes auth.
  • Componentes em src/components/auth/: PasswordInput, TotpInput, RoleBadge, LocaleSwitcher.
  • Card 3 pode refinar visualmente sem mexer na lógica.

Padrões estabelecidos

  • NUNCA usar Tailwind — apenas CSS puro com custom properties (tokens).
  • 'server-only' import em todas as libs que tocam Prisma/bcrypt/crypto.
  • @map("snake_case_table") em todos os models Prisma.
  • cuid() IDs como padrão.
  • Vitest com @vitest-environment node para testes que usam crypto/jose.
  • next-intl useTranslations() em todas as páginas client.
  • tRPC procedures (masterProcedure, localProcedure, etc.) para autorização.

Variáveis de ambiente novas

  • RESEND_API_KEY (vazio em DEV → log em vez de enviar)
  • RESEND_FROM_EMAIL=GENIOON <no-reply@genioon.com.br>
  • APP_URL=https://sistemaescolar.wellka.com.br
  • HAVEIBEENPWNED_API_ENABLED=true (default)

Credenciais MASTER seed (mostrar UMA vez, trocar imediatamente)

  • Email: admin@genioon.com.br
  • Senha temporária: Genioon@2026
  • ⚠️ Trocar após primeiro login via /configurar-2fa

🚀 7. Deploy DEV

  • URL pública: https://sistemaescolar.wellka.com.br
  • Endpoints funcionais:
    • GET /login → 200 (formulário login)
    • POST /api/auth/callback/credentials → autenticação
    • GET /api/auth/providers → JSON
    • /api/trpc/* → tRPC handler
    • /esqueci-senha, /resetar-senha, /verificar-2fa, /configurar-2fa
    • /acesso-negado (403)
    • Troca de idioma (PT/EN/ES) funcional

Processo de deploy

  1. Commit + push → GitHub Actions CI (lint + type-check + test)
  2. Deploy DEV automático via SSH: git pull → npm install → prisma migrate deploy → next build → pm2 reload genioon-dev
  3. /doc atualizado automaticamente (CI/CD deploya _index.json + este .md)

➡️ 8. Próximo card sugerido

Card 3 [M0] Design System

  • Refinar visual das 9 telas auth criadas neste card usando tokens CSS.
  • Componentes em src/components/auth/ estão prontos para receber design polish.
  • Implementar dark mode toggle real (tokens já estão prontos, falta o switch).
  • Padronizar layout (auth) com a identidade visual GENIOON (logo, cores, tipografia).
  • Validar mobile responsive em todas as telas auth.
← Voltar para a visão geral