API de autenticação e sessão
O login usa um desafio de curta duração, confirmação por Telegram e prova de controle do navegador original. Um ID do Telegram fornecido pelo cliente não é prova de identidade.
Nesta página
Iniciando login#
POST /api/auth/telegram/start aceita um objeto JSON vazio {}. Exige a Origin exata do aplicativo e um bot disponível. O servidor cria um desafio com duração de 300 segundos e um cookie protegido de prova do navegador.
A resposta 201 contém challengeId, code, expiresAt e telegramUrl. O cookie de prova é excluído do link profundo e é inacessível ao JavaScript. O limite é de seis inícios por minuto por endereço com hash.
const response = await fetch('/api/auth/telegram/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: '{}'
});
const challenge = await response.json();
// Show code and telegramUrl to the user.Aguardando confirmação#
POST /api/auth/telegram/complete aceita {challengeId}. Exige Origin e o cookie original de prova do navegador. Até a confirmação, a resposta é 202 {status: "pending"}.
Após a confirmação, 200 retorna status=authenticated, user, csrfToken e expiresAt. Uma sessão é emitida uma única vez. Desafios expirados retornam 410; desafios usados ou cancelados retornam 409.
const response = await fetch('/api/auth/telegram/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ challengeId: challenge.challengeId })
});
if (response.status === 202) {
// Poll again after a delay; do not create a new challenge.
}Lendo a sessão#
GET /api/auth/me retorna 200 {authenticated:false} quando não existe sessão válida. Uma resposta com login inclui o usuário, token CSRF e expiração.
O cookie __Host-kevmi-session dura até 24 horas com Secure, HttpOnly, SameSite=Lax e Path=/. O banco de dados armazena um hash SHA-256 do token. Um formulário de perfil não pode ler nem substituir o cookie.
Alterações de conta#
Mutações exigem a sessão, Origin exata e o X-CSRF-Token atual. Sec-Fetch-Site: cross-site é rejeitado. O servidor não oferece acesso CORS arbitrário.
O ID da conta vem da sessão, não da entrada da solicitação. Registros ausentes ou de outro usuário não revelam detalhes de propriedade identificáveis.
Encerrando a sessão#
POST /api/auth/logout encerra a sessão atual e limpa o cookie. Origin e CSRF são obrigatórios; o corpo não é lido. Telegram /logout também encerra todas as sessões da conta.
Cookies não se movem automaticamente para outro domínio. Ao mudar o domínio do serviço, atualize APP_ORIGIN e o webhook do bot, depois faça login novamente.