Usuários e Acessos

A gestão de usuários e convites que todo App member-central já traz — permissões nativas, quem convida, convites pela Central, página própria e endpoints.

Todo App member-central ou root-central nasce com a gestão de usuários do OonCore. Não há código a escrever para o caso padrão.

O que vem por padrão

  • Página /usuarios-acessos (componente CoreUsersAccess) com o item Usuários e Acessos na seção Configurações do menu.
  • Para mudar onde o item aparece (outra seção, ordem ou o menu do usuário), declare na navegação do App um item com href: "/usuarios-acessos" e permissions: ["users.read"] — ele substitui o item padrão, e a página continua a do Core (0.7.39). Exemplo: { label: "Usuários e Acessos", href: "/usuarios-acessos", section: "Configurações", order: 60, permissions: ["users.read"], action: "user-menu" }.
  • O perfil admin vê a página, convida, copia e regenera links, revoga convites e altera perfis.
  • Os demais perfis não veem a página até receberem as permissões abaixo.

Permissões nativas

Permissão O que libera
users.read Ver a página e a lista de usuários e convites
users.invite Convidar, copiar o link, regenerar e revogar convites
users.update Alterar o perfil de um usuário (fluxo local)
users.disable Desativar ou reativar um usuário (fluxo local)
roles.read Listar os perfis do App

Já existem no Core: basta atribuí-las aos perfis — não declare em rbac.permissions.

Quem pode convidar

{
  "rbac": {
    "roles": [
      { "code": "admin", "name": "Administrador", "admin": true, "permissions": ["*"] },
      { "code": "gestor", "name": "Gestor", "description": "Convida pessoas e acompanha os acessos da equipe.",
        "permissions": ["users.read", "users.invite", "pedidos.read"] },
      { "code": "operator", "name": "Operador", "permissions": ["pedidos.read", "pedidos.write"] }
    ]
  }
}
  • Sem escalada de privilégio: quem convida só atribui perfis cujas permissões já possui (RBAC_PRIVILEGE_ESCALATION_DENIED). "*" só é atribuído por quem também tem "*".
  • Último administrador: no fluxo local, o último admin ativo não pode ser rebaixado nem desativado.
  • Clientes de App licenciado: a autoridade comercial é decidida pela Central para aquela licença.

Convites pela Central

Por padrão os convites são locais: o App gera o link e quem convida o envia. Para a Central de Ativações gerir:

{ "auth": { "invitations": "central" } }
  • E-mail enviado pela Central com a identidade Oon e link para /accept-invite do App; delivery informa se saiu (sent) ou falhou (failed + reasonCode).
  • Cadastro: conta nova informa nome, CPF, telefone, senha e aceite dos termos; conta existente usa a senha ou a sessão aberta.
  • Concessão: vínculo com a organização e acesso ao App ficam na Central, com limite de usuários do plano e auditoria.

Requer App publicado pela Plataforma (credencial de deployment e PUBLIC_APP_URL em HTTPS). No runtime local o fluxo permanece local.

OON_CENTRAL_INVITATIONS_ENABLED (true/false) no runtime continua aceita apenas como chave de emergência.

Página própria

export const app = defineOonApp({
  // ...
  systemPages: {
    usersAccess: MinhaGestaoDeAcessos, // mesma rota e item de menu
    // ou usersAccess: false — remove a página e o item padrão
  },
});
import { Can, useOonApi } from "@oondemand/oon-core-front";

export function MinhaGestaoDeAcessos() {
  const { http } = useOonApi();
  async function convidar(email: string, roleCode: string) {
    const { data } = await http.post("/core/users/invitations", { email, roleCode }, {
      headers: { "idempotency-key": crypto.randomUUID() }, // reutilize a mesma chave ao repetir a tentativa
    });
    return data; // { invitation, access, inviteUrl?, delivery? }
  }
  return <Can permission="users.invite">{/* formulário de convite */}</Can>;
}

A página não deve guardar tokens nem montar links: o link vem sempre do backend.

Endpoints

Método e rota Permissão Uso
GET /core/role-catalog pública Catálogo de perfis
GET /core/rbac pública Política resumida
GET /core/roles roles.read Perfis completos
GET /core/users users.read Usuários e convites pendentes
POST /core/users/invitations users.invite { email, roleCode, name? } + idempotency-key
GET /core/users/invitations/:id/link users.invite Recupera o link
POST /core/users/invitations/:id/regenerate users.invite { version } — invalida o anterior
DELETE /core/users/invitations/:id users.invite { version } — revoga
PATCH /core/users/:id users.update / users.disable { roleCode } ou { status } (fluxo local)
POST /core/invitations/inspect pública { token }
POST /core/invitations/accept pública { token, intent, password?, registration?, version? }

inviteUrl aponta para PUBLIC_APP_URL/accept-invite#token=… — o token vai no fragmento, que não chega a logs nem a servidores intermediários.

Aceite

/accept-invite é uma página pública do Core que trata conta nova, conta existente e sessão já aberta, com mensagens legíveis e "Código · Protocolo · Central" em caso de erro. Uma página própria de aceite não é necessária nem recomendada.