auth.grants
Convidar pessoas para um recurso, e gerenciar o que elas têm lá.
Um grant é um usuário com um papel sobre um recurso. É a única coisa que existe em tempo de execução — não há um registro de "membro" por trás, e é por isso que listar os grants de alguém é listar as organizações dessa pessoa.
Só no client de servidor, e estes métodos agem como o usuário que chamou — a
permissão dele é verificada e ele fica registrado como autor. Repasse os headers
dele com forwardUserHeaders. Para agir como a
plataforma, use auth.admin.grants.
list
list(context?) → Grant[]
Todo grant que o usuário que chamou possui.
contextstringOptionalEstreita para grants cujo papel vive neste contexto — 'org', 'project'.
Omita para tudo.
Isso substitui uma tabela de memberships. Para renderizar "suas organizações",
liste os grants naquele contexto e busque os recursos por resource:
const { data: grants } = await nulvless.auth.grants.list('org');
const orgs = await db.organizations.findBySlugs(grants.map((g) => g.resource));getMembers
getMembers(resource) → GrantMembers
Todo mundo em um recurso, já agrupado por status.
const { data } = await nulvless.auth.grants.getMembers('acme');resourcestringRequiredQualquer identificador contra o qual você concedeu — um slug de org, um id de projeto.
Devolve quatro listas em vez de uma:
grantedGrant[]OptionalinvitationsGrant[]OptionalrequestedsGrant[]OptionalblockedsGrant[]OptionalUma tela de membros renderiza isso direto. Sem separar em baldes no cliente, e sem filtrar uma lista achatada por uma string de status que você teve que aprender.
get
get(id) → Grant
Um grant por id.
const { data: grant } = await nulvless.auth.grants.get(id);idstringRequiredinvite
invite(params, options) → Grant[]
Convida pessoas para um recurso. Em lote — uma chamada, vários convites.
invitesInvite[]RequiredUma entrada por pessoa. Cada uma recebe email mais um role_id, e
opcionalmente scopes extras por cima do papel.
resourcestringRequiredA coisa sendo compartilhada. Não é um contexto — o contexto veio junto com o papel quando ele foi definido.
messagestringOptionalMostrado a quem foi convidado. Na prática, o nome legível do recurso, já que o
resource em si costuma ser um slug.
noncestringOptionalConfirmação de sudo.
const { data } = await nulvless.auth.grants.invite(
{
invites: [{ email: '[email protected]', role_id: adminRoleId }],
resource: 'acme',
message: 'Acme Inc',
},
{
headers: forwardUserHeaders(req),
redirect_uri: 'https://app.example.com/join',
},
);Três coisas que pegam as pessoas
role_id é um id, não um nome. 'admin' é rejeitado — leia os ids uma vez
com auth.admin.roles.list(context).
redirect_uri é uma option, não um param. Ela vai no segundo argumento.
Você convida um e-mail, não um usuário. A pessoa não precisa ter conta. O
grant volta com status: 'invited' e sem granted_to; esse campo é preenchido
quando ela se cadastra.
Devolve um Grant por convite. Um convite não concede nada até ser aceito —
apenas granted passa numa verificação de permissão.
accept
accept(id) → Grant
Leva um convite pendente para granted. O acesso começa aqui.
await nulvless.auth.grants.accept(grantId, {
headers: forwardUserHeaders(req),
});Não precisa de nenhuma permissão sobre o recurso — a pessoa ainda não tem uma, e o id do grant é a autorização. Proteja essa rota apenas com autenticação. Exigir um papel aqui é a forma mais comum de um time acidentalmente tornar os convites impossíveis de aceitar.
cancel
cancel(id) → Grant
Retira um convite, ou recusa um.
await nulvless.auth.grants.cancel(grantId, {
headers: forwardUserHeaders(req),
});A mesma chamada para os dois lados.
update
update(id, params) → Grant
Muda o que um grant carrega.
await nulvless.auth.grants.update(grantId, {
scopes: ['projects:read'],
nonce: code,
});scopesstring[]OptionalSubstitui os escopos do grant.
noncestringOptionalPara mudar o que todo mundo com um papel pode fazer, edite o papel — todos os
portadores se movem de uma vez e nenhum grant é tocado. Recorrer ao update
quando você queria o admin.roles.update é como
um modelo de permissões vira um punhado de exceções por pessoa que ninguém
consegue auditar.
revoke
revoke({ id, nonce }) → Grant
Remove o grant. Tokens que o carregam param de passar.
await nulvless.auth.grants.revoke({ id, nonce: code });idstringRequirednoncestringOptionalblock
block({ id, nonce }) → Grant
Mantém o registro e nega o acesso.
await nulvless.auth.grants.block({ id, nonce: code });idstringRequirednoncestringOptionalA diferença para o revoke importa quando o histórico importa: um grant
bloqueado ainda explica quem tomou as ações ligadas a ele, enquanto um revogado
sumiu.
leave
leave({ id, nonce }) → Grant
A própria pessoa se removendo.
await nulvless.auth.grants.leave({ id, nonce: code });idstringRequiredO id do grant — não o recurso.
noncestringOptionalÉ autoatendimento, então, como o accept, não precisa de papel sobre o recurso.
Quem precisa de permissão
A assimetria é fácil de inverter:
invite, revoke, block, updateprecisa de papelAgindo sobre o acesso de outra pessoa. Tipicamente owner ou admin, e protegido
por sudo sob manage_grants.
accept, cancel, leavesó autenticaçãoAgindo sobre o seu próprio. O id do grant é a autorização.
O objeto Grant
idstringRequiredstatusGrantStatusRequiredgrantedAtivo. O único status que passa numa verificação.invitedEnviado, não respondido.requestedPedido, não aprovado.blockedNegado, registro mantido.resourcestringRequiredgranted_toUserOptionalAusente até quem foi convidado ter uma conta.
roleRoleOptionalCarrega a key que o verify({ roles }) casa, e o context ao qual o papel
pertence.
scopesstring[]RequiredemailstringOptionalO endereço convidado, antes de existir um usuário.
created_atstringOptionalupdated_atstringOptionalVerificar contra um grant que ainda está invited ou requested responde 403
com forbidden_access_waiting_accept, não o genérico
forbidden_resource_access. Essa é a diferença entre "você não tem acesso" e "o
seu convite está na sua caixa de entrada".