Aparência
Autenticação e autorização
O que é este documento — como o ionCLASS autentica os clientes (tokens Sanctum) e autoriza o que cada um pode fazer, nos dois eixos: o Tipo de usuário (persona/tenancy) e o Papel (permissões finas). Cobre os dois fluxos de onboarding — responsável (mobile) e operador (monitor) — e como o escopo de escola difere entre eles.
1. Autenticação — tokens Sanctum
Todos os clientes REST (mobile do responsável e PWA do operador) autenticam com tokens bearer do Sanctum sob o guard auth:sanctum, enviados em Authorization: Bearer …. O token é emitido ao fim de cada fluxo de login/cadastro. Um 401 em qualquer chamada limpa o token guardado no cliente (MMKV no mobile, localStorage monitor.authToken no monitor).
O logout revoga apenas o token da requisição atual, para que sair em um aparelho não deslogue os outros. O handshake de broadcasting (POST /api/broadcasting/auth) usa o mesmo guard — ver tempo real.
2. Os dois eixos de autorização
A autorização opera em dois eixos ortogonais:
| Eixo | O que é | Onde vive | O que governa |
|---|---|---|---|
| Tipo de usuário | Persona + escopo de tenancy; conjunto fixo de 6 valores, hierárquico | atributo da conta | Recursos estruturais/administrativos (redes, escolas, usuários, papéis), decididos por políticas de acesso |
| Papel | Pacote de permissões finas no formato domínio.ação | pacote de permissões (spatie) | Capacidade operacional fina (ex.: live_monitor.view, arrival_signals.update_status) |
Os 6 tipos: dono da plataforma, admin de rede, admin de escola, operador, responsável e terceiro autorizado. Agrupamentos úteis: staff (dono + admin de rede + admin de escola + operador — os que aparecem na tela de usuários), gestores (staff que administra recursos estruturais; o operador é staff mas NÃO é gestor), elevados (dono + admin de rede — cross-tenant, dirigem o enforce de MFA e os gates de criar/inativar escola).
Regra prática: o Tipo diz onde você senta na hierarquia e o que enxerga; o Papel diz quais ações operacionais você pode disparar. Ver a portaria: um operador só transmite/move o quadro se tiver o Papel com live_monitor.view/arrival_signals.update_status — ser operador, por si, não basta.
3. Fluxo do responsável (mobile)
Primeiro acesso do responsável, sem convites e sem aprovação manual. Onboarding = casar CPF + email contra um responsável pré-cadastrado (via importação CSV ou sync do hardware) → código de 6 dígitos por email → confirmar. O responsável pode não ter conta — a conta só é materializada na confirmação do código, não na importação.
POST v1/auth/register POST v1/auth/verify-code
│ │
casa CPF+email ──▶ envia código valida código ──▶ materializa a conta
(código hasheado + vincula ao responsável
em cache; texto + emite token Sanctum
puro por email)3.1 Passo 1 — POST v1/auth/register
- Casa o CPF normalizado + email contra um responsável pré-cadastrado (a busca inclui registros excluídos, para reativar quem apagou a conta).
- Email é opcional no registro. A importação (CSV/hardware) pode não ter email; nesse caso o CPF sozinho prova a identidade e o email informado vira o email da conta. Só se valida o email informado contra o registro quando o registro já tem um.
- Anti-enumeração: qualquer divergência — CPF desconhecido ou email que não bate — retorna o mesmo 422 genérico (
"CPF e email não conferem com nossos registros."). Não há fila de admin para CPF desconhecido. - Guarda em cache um código de 6 dígitos hasheado + senha hasheada, com validade configurável (padrão 15 min), e envia o código em texto por email. A chave de cache é derivada de
(cpf, email)— a identidade global do responsável — para o passo 2 achar a entrada sem token na URL. - Repetir o
registerregenera um código novo ("reenviar código"). A escola não é enviada pelo app: é derivada dos vínculos do responsável. - Um responsável com conta viva já vinculada é bloqueado (
"Este responsável já completou o cadastro. Faça login.").
3.2 Passo 2 — POST v1/auth/verify-code
- Valida o código. Código errado incrementa um contador de tentativas; ao atingir o limite (padrão 5) a entrada é purgada (auditoria de bloqueio por tentativas) e o responsável pede outro. Código certo é one-shot — consumido imediatamente (replays viram "código inválido ou expirado").
- Numa transação: materializa a conta (papel responsável, ativa, email verificado), vincula ao responsável, grava o consentimento LGPD e emite o token. Se o responsável adotar o email confirmado (não tinha um), ele passa a ser o email do registro. Uma conta excluída é restaurada (mantém id + trilha de auditoria).
3.3 Rotas auxiliares
POST v1/auth/login (email + senha), recuperação de senha por código (auth/password/forgot → 202 sempre, anti-enumeração; auth/password/reset), e auth/password (troca autenticada). Todas com limites de taxa dedicados (cadastro, recuperação de senha e login).
4. Fluxo do operador (monitor)
POST v1/auth/operator-login:
- Verifica credenciais; em credencial ruim, 422 genérico — não revela se o email é de operador.
- Exige que o usuário seja operador; um não-operador recebe a mensagem explícita
"Apenas operadores podem acessar o monitor."(aqui a mensagem é explícita de propósito, para o legítimo não-operador entender a recusa). - Exige que a conta esteja ativa; conta desativada →
"Sua conta foi desativada. Entre em contato com o administrador.". - Sucesso retorna o token + os dados do operador.
As rotas do operador exigem token Sanctum válido + perfil de operador (operador com escola vinculada, que resolve o contexto da escola). As rotas me/logout não exigem permissão — um operador sem Papel ainda precisa bootar o PWA, ver quem é e sair. O resto do quadro é gated pela permissão live_monitor.view e as transições por arrival_signals.update_status — o Papel, nunca o mero fato de ser operador, decide a autoridade (ver §2).
5. Escopo de escola
O escopo de escola difere por cliente e é a razão de um enviar header e o outro não:
| Cliente | Vínculo com escola | Como envia | Resolução no backend |
|---|---|---|---|
| Responsável (mobile) | N:N | Header X-School-Id (escola ativa) | O backend valida o vínculo com a escola informada |
| Operador (monitor) | 1 escola | Sem header | O backend resolve a escola pelo token |
O mobile também usa X-Pin-Confirmation (PIN de segurança) para ações sensíveis — um gate protege rotas de alta responsabilidade (excluir conta, revogar consentimento biométrico, criar/editar autorizações e passes, editar responsáveis). O PIN é provado por me/pin/verify (→ token de confirmação de curta duração). Detalhes na superfície: app do responsável.
Ver também
- personas e superfícies — quem é cada persona
- modelo de domínio — a conta, o responsável, a escola e os vínculos
- tempo real — autorização de canais (handshake Sanctum + Papel)
- app do responsável — PIN e
X-School-Idno app - monitor de portaria — o PWA do operador