auth.sessions
Listar e revogar sessões, e elevar uma para o sudo mode.
Uma sessão é um período autenticado de um usuário num dispositivo. Ela não é o token — os tokens rotacionam por baixo dela — e sobrevive a uma renovação, e é por isso que revogar uma sessão significa alguma coisa, enquanto "expirar um token" não.
Tudo aqui precisa de uma sessão própria, e a maior parte precisa de sudo por cima.
list
list() → Session[]
Toda sessão ativa que a pessoa tem, em qualquer dispositivo.
const { data: sessions } = await nulvless.auth.sessions.list();Cada uma carrega:
idstringRequiredO que o revoke recebe.
is_current_sessionbooleanRequiredMarca a que está fazendo a requisição. Renderize de forma diferente e não ofereça revogá-la por acidente — isso é um logout, não uma revogação.
finger_printSessionFingerPrintOptionalDispositivo, navegador, sistema e localização aproximada. Preenchido só quando
o client foi criado com trackUser, e no servidor só quando você repassa os
headers do usuário — caso contrário toda sessão parece ter vindo da sua
infraestrutura.
amr{ method, timestamp }[]RequiredComo esta sessão foi autenticada, em ordem. Uma sessão que usou senha e depois um código TOTP carrega os dois.
scopesstring[]RequiredO que a sessão carrega independente de qualquer recurso.
invalidatedbooleanRequiredRevogada, mas ainda não removida da lista.
sudo_expires_atstring | nullOptionalQuando o sudo vence. Ausente ou nulo quando a sessão não está elevada.
created_atstringRequiredupdated_atstringRequiredexpires_atstringRequiredÉ exatamente isso que uma tela de "onde você está conectado" renderiza — a
impressão digital dá a linha de dispositivo, o amr dá o "entrou com senha e
autenticador", e o is_current_session dá o "este dispositivo".
revoke
revoke({ id, nonce }) → null
Encerra uma sessão imediatamente. Os tokens dela param de funcionar; uma renovação em andamento falha.
await nulvless.auth.sessions.revoke({ id, nonce: code });idstringRequiredVindo do list(), ou do auth.getSession() para a atual.
noncestringOptionalConfirmação de sudo para esta chamada. Veja abaixo.
Exige sudo
Revogar é protegido sob manage_sessions. Uma sessão roubada não pode conseguir
despejar o dono de verdade em silêncio.
Para encerrar todas as sessões menos a atual, o
auth.signOut('others') é uma chamada só, em vez de
um laço sobre o list().
sudo
sudo(method?) → { challenge }
Inicia uma elevação de sudo enviando um código de confirmação.
const { data } = await nulvless.auth.sessions.sudo();
const { data: viaEmail } = await nulvless.auth.sessions.sudo('email_otp');methodSudoMethodOptionalCom qual fator confirmar. Omita e a plataforma escolhe, do mesmo jeito que faz num desafio de MFA.
totpO app autenticador. Nada é enviado.email_otpUm código por e-mail.sms_otpUm código por SMS.Devolve um Challenge. O que você faz com o código decide em qual dos dois
caminhos abaixo você está.
sudoVerify
sudoVerify({ code }) → Authenticated
Completa a elevação, para a sessão inteira.
const { data } = await nulvless.auth.sessions.sudoVerify({ code });
// data.sudo.expires_in → segundos que a janela duracodestringRequiredO que a pessoa digitou.
Nenhum token de desafio é necessário. O desafio de sudo pendente é resolvido pela própria sessão, e é por isso que esta chamada recebe só o código.
Em caso de sucesso, a sessão é reemitida com sudo ativo e guardada
automaticamente. O data.sudo.expires_in são os segundos restantes — use para
mostrar a janela fechando, em vez de adivinhar.
checkSudo
checkSudo(params?) → null
Pergunta se o sudo está ativo agora. Responde 204 quando está, e um erro
quando não está.
const { error } = await nulvless.auth.sessions.checkSudo();
if (error) startSudoFlow();Útil ao entrar numa tela de configurações, para o pedido aparecer uma vez na porta em vez de no primeiro clique destrutivo.
Sudo mode
Uma sessão válida diz quem entrou. Ela não diz quem está no teclado agora. O sudo mode é uma janela curta em que isso acabou de ser reprovado.
Duas formas de satisfazer
As duas começam com sudo(), que envia o código. Elas diferem no que você gasta
com ele.
await nulvless.auth.sessions.sudo();
const { data } = await nulvless.auth.sessions.sudoVerify({ code });
// tudo que é protegido por sudo passa até data.sudo.expires_in acabarCerto quando a pessoa está prestes a fazer várias coisas sensíveis em sequência.
O nonce vai dentro dos params, não nas options. Ele trafega como
nlv-sudo-nonce e é de uso único.
Saber quando é necessário
Não crave no código quais das suas chamadas são protegidas — isso é configuração por ambiente e pode mudar sem você. Reaja ao evento:
nulvless.auth.on('sudo-required', async () => {
await nulvless.auth.sessions.sudo();
openSudoPrompt();
});Ele dispara em 403 protected_action_denied. Veja
Eventos.
O que é protegido
Um ambiente nomeia os grupos que quer cobertos: manage_mfa,
manage_credentials, manage_grants, manage_identities, manage_sessions e
manage_passwords. Uma chave mestra desliga tudo, e uma configuração controla
quanto tempo uma elevação dura.
Sudo mode cobre o fluxo inteiro, inclusive fazer o mesmo nas suas próprias rotas.