# Feature Specification: Desk Account Management & Registration (004) **Criado:** 2026-06-10 **Concluído:** 2026-06-10 **Status:** ✅ **FECHADA — entregue e validada** (+ extensão 2FA recovery 2026-06-16) **API:** `0.9.4-desk-2fa-recovery` **Depende de:** Spec 003 (desk-auth-rbac) **Validado por:** Roger — cadastro, ativação, e-mail VM108, QR TOTP, login MFA, **Minha conta** --- ## Resumo Fluxo completo para equipe técnica e ops do **Ligbox Ops Desk**: **cadastro → aprovação root → ativação 2-de-3 → login → Minha conta (troca de senha)** E-mail operacional via **VM108** (`@ligbox.com.br`). UI em **pt-BR**. --- ## Decisões confirmadas (Roger) | Ponto | Decisão | |-------|---------| | **2FA ativação** | Três fatores — candidato completa **qualquer 2 de 3** | | Perfil | Root escolhe na aprovação (`ops_lead`, `technician`, `noc`) | | Login | **E-mail** é o username | | Usuários seed | `root`, `admin`, `mini`, `noc` — sem cadastro | | Idioma | **Português do Brasil (pt-BR)** | | E-mail | **Ligbox** — `@ligbox.com.br` via **VM108** (Carbonio) | | Telefone OTP | Por e-mail (SMS futuro) | | ntfy | Opcional — `ntfy.sh` (sem instalar na VM122) | | Troca de senha | Self-service em **Minha conta**; **TOTP obrigatório** se 2FA ativo | | **Recuperação 2FA** | Link **Perdi acesso ao autenticador** no login — OTP e-mail + novo QR | | **Códigos backup** | 10 códigos de uso único na ativação (e após recuperação) | ### Regra 2-de-3 (ativação) | # | Fator | Método | |---|-------|--------| | 1 | E-mail | OTP 6 dígitos | | 2 | Telefone | OTP 6 dígitos (por e-mail) | | 3 | App autenticador | QR TOTP + ntfy opcional | --- ## Fluxo completo (entregue) ```mermaid flowchart TD A[register.html] --> B[Pedido + ticket + e-mail root] B --> C[Root aprova — Mensagens] C --> D[E-mail + link activate.html] D --> E[2 de 3 fatores — 3 colunas] E --> F[Conta ativa] F --> G{totp_enabled?} G -->|Sim| H[Login senha + TOTP] G -->|Não| I[Login senha] H --> J[Minha conta] I --> J J --> K[Trocar senha — TOTP se ativo] ``` --- ## Componentes entregues | Componente | Estado | |------------|--------| | `register.html` | ✅ PRG → login | | `activate.html` | ✅ 3 colunas, QR local, progresso, ntfy | | `login.html` | ✅ MFA step | | `index.html` — Mensagens / Admin / **Minha conta** | ✅ | | Postfix VM122 → LMTP VM108 | ✅ | | `ligbox-ops@ligbox.com.br` | ✅ | | `pyotp` + `/login/mfa` | ✅ | | ntfy push OTP | ✅ | | Tickets cadastro | ✅ | | pt-BR (UI + API + e-mails) | ✅ | | `POST /change-password` | ✅ | | Formulário Minha conta estável | ✅ sem refresh apagando campos | --- ## API (v0.8) | Método | Endpoint | Descrição | |--------|----------|-----------| | POST | `/api/v1/auth/register` | Novo pedido | | GET | `/api/v1/auth/registration-requests` | Lista (root) | | POST | `/api/v1/auth/registration-requests/{id}/approve` | Aprovar | | POST | `/api/v1/auth/registration-requests/{id}/reject` | Rejeitar | | GET | `/api/v1/auth/activate?token=` | QR + fatores | | POST | `/api/v1/auth/activate/send-email-otp` | OTP e-mail | | POST | `/api/v1/auth/activate/send-phone-otp` | OTP telefone | | POST | `/api/v1/auth/activate` | 2 de {email, phone, totp} | | POST | `/api/v1/auth/login` | Pode retornar `mfa_required` | | POST | `/api/v1/auth/login/mfa` | Conclui login TOTP | | GET | `/api/v1/auth/me` | Perfil + `totp_enabled` | | POST | `/api/v1/auth/change-password` | Troca senha (TOTP se ativo) | | POST | `/api/v1/auth/login/mfa` | TOTP **ou** `backup_code` | | POST | `/api/v1/auth/mfa-recovery/send-email` | OTP e-mail (sessão 2FA ativa) | | POST | `/api/v1/auth/mfa-recovery/verify-email` | Valida OTP → `recovery_token` + QR | | GET | `/api/v1/auth/mfa-recovery/setup` | QR pendente (recovery) | | POST | `/api/v1/auth/mfa-recovery/complete` | Novo TOTP + JWT + backup codes | ### `POST /change-password` ```json { "current_password": "senha-atual", "new_password": "nova-senha-min-8", "totp_code": "123456" } ``` - `totp_code` **obrigatório** quando `totp_enabled = true` (protege sessão abandonada) - Nova senha ≠ senha atual; mínimo 8 caracteres --- ## UI — telas principais ### `activate.html` - 3 colunas responsivas · QR em `/assets/qrcode.min.js` - Barra `X/2 fatores` · link ntfy ### `Minha conta` (todos os perfis) - Dados do perfil (e-mail, role, último login, 2FA) - Formulário: senha atual · nova · confirmar · TOTP (se ativo) - Refresh automático **não** re-renderiza esta tela (preserva digitação) --- ## E-mail (arquitetura) | VM | Função | |----|--------| | **108** | Mail Ligbox — `mail.ligbox.com.br` → LMTP `:7025` | | **112** | Legado Ibytera — `@ibytera.com`, `@dratcoin.com` | | **122** | Postfix local — roteamento por domínio | **Env Desk:** `ligbox-ops@ligbox.com.br` · notificações root: `admin@ligbox.com.br` Redirect temporário Postfix: `@itecnologys.com` → `@ligbox.com.br` Docs: `docs/email-ligbox-vm108.md` · `docs/postfix-vm122.md` --- ## Critérios de aceite — todos ✅ - [x] Cadastro com aprovação root - [x] Ativação 2-de-3 (e-mail, telefone, TOTP) - [x] QR code funcional (biblioteca local) - [x] OTP e-mail via VM108 - [x] Login MFA quando TOTP configurado - [x] Tickets e notificações - [x] UI pt-BR - [x] Minha conta — troca de senha self-service - [x] TOTP obrigatório na troca de senha (se 2FA ativo) - [x] **Recuperação 2FA** — perdi autenticador (e-mail OTP + novo QR) - [x] **Códigos backup** — 10× uso único na ativação e após recuperação - [x] Login MFA aceita código de backup - [x] Formulário Minha conta persistente ao digitar - [x] Validação E2E Roger — **aprovado** --- ## Fora de escopo (futuro) | Item | Notas | |------|-------| | SMS telefone | OTP continua por e-mail | | ntfy self-hosted | Usar `ntfy.sh` por ora | | Log auditoria senhas | Backlog ops | | Remover redirect `@itecnologys.com` | Após migrar caixas VM108 | | `must_change_password` no 1º login | Opcional v2.1 | | Regenerar backup codes em Minha conta | Requer TOTP — backlog | --- ## Referências - Spec 003 — auth/RBAC - `specs/004-desk-account-management/tasks.md` - `specs/004-desk-account-management/quickstart.md` - `.cursor/rules/portugues-brasil.mdc`