Pular para o conteúdo

Vimine (navegador)

Ver como Markdown
import { Vimine } from '@vimine/sdk';
const vimine = new Vimine(options);

Vimine cuida do Entrar com Vimine (OAuth 2.1 + PKCE), da sessão do associado e das chamadas à API do associado. Uma instância por cliente; crie-a uma vez e reutilize-a.

Opção Tipo Padrão
clientId string — o seu vmc_… (obrigatório)
redirectUri string — a página que chama handleRedirect(), registrada para o cliente (obrigatório)
scopes Scope[] ['profile:read', 'membership:read'] permissões pedidas por signIn()
storage 'session' | 'local' | 'memory' | TokenStorage 'session' onde ficam a sessão e o login pendente
storageKey string vimine:<clientId>: prefixo das chaves no storage
locale Locale 'it' idioma das páginas de login e de consentimento
apiUrl string https://api.vimine.network origem da API
appUrl string https://app.vimine.network origem das páginas de login
fetch typeof fetch globalThis.fetch para testes e polyfills
navigate (url) => void top.location.assign como sair da página

O construtor lança um VimineError (invalid_options) sem clientId ou redirectUri.

Manda a janela principal para a página de login e de consentimento. Chame-o a partir de um gesto do usuário (um clique). De dentro de um iframe de outra origem a navegação é recusada (framed): a página de login nunca é mostrada num frame.

Opção
scopes permissões deste login
prompt 'login' (credenciais sempre) ou 'consent' (consentimento sempre)
returnTo um estado seu, guardado localmente e devolvido por handleRedirect() — ele não é enviado

Monta a URL de autorização e guarda o login pendente (verificador PKCE e state) sem navegar. Útil quando você mesmo renderiza o link.

true quando a URL (padrão: a página atual) traz os parâmetros de um retorno (code+state ou error).

Na página de callback: confere o state, troca o código por tokens e guarda a sessão. Devolve { session, returnTo }, ou null quando a URL não traz parâmetros de login. Com cleanUrl (padrão true) ele remove code, state e error da barra de endereços.

Erros (VimineError.code): access_denied e os outros erros OAuth quando o associado não autorizou; no_flow quando nenhum login foi iniciado neste navegador (storage vazio ou expirado); state_mismatch quando o retorno não corresponde; invalid_grant quando o código expirou ou já foi usado.

A sessão guardada, ou null.

interface Session {
accessToken: string;
refreshToken: string | null;
expiresAt: number; // ms, absoluto
scope: Scope[];
sub: string | null; // o identificador do associado para a sua associação (vms_…)
mode?: 'live' | 'test'; // 'test' para as sessões de um cliente de teste
}

Um access token válido, renovado quando vence em menos de 30 segundos. Lança not_signed_in sem uma sessão.

Renova a sessão com o refresh token (uma única requisição mesmo quando chamado de forma concorrente). Quando o refresh token não pode mais ser usado, a sessão é apagada e o erro é relançado.

signOut({ everywhere?, postLogoutRedirectUri?, state? })

Seção intitulada “signOut({ everywhere?, postLogoutRedirectUri?, state? })”

Revoga o refresh token (RFC 7009, na medida do possível) e esquece a sessão. Com everywhere: true, depois manda o navegador para o /oauth/logout do app Vimine, que encerra a sessão do associado e volta para postLogoutRedirectUri (padrão redirectUri; precisa estar numa origem registrada).

listener(session | null) a cada login, renovação e logout; com storage: 'local', também para os que aconteceram em outras abas. Devolve a função que remove o listener.

Uma chamada autenticada: Authorization: Bearer, JSON na ida e na volta, erros como VimineError, uma nova tentativa depois de uma renovação quando a resposta é 401. init.idempotencyKey vira o cabeçalho Idempotency-Key.

const events = await vimine.request('/v1/me/membership/events?limit=5');
Escopo
me.get() profile:read o perfil (Me), com codicefiscale_check: como a pessoa está identificada (null = ainda não)
me.update(patch) profile:write telefone, sexo, e a identificação: data, local e país de nascimento (birth_country), código fiscal — opcional, pode ser adicionado depois. Um código que não confere responde 422 com uma entrada codicefiscale_mismatch; quando ela é confirmable, a pessoa o confirma com codicefiscale_confirmed: true (guia)
Escopo
membership.get() membership:read a carteirinha: status, verdict, expires_at, statuto, card
membership.request(body, { idempotencyKey? }) membership:request pedido de adesão; uma chave de idempotência é gerada quando ausente. 422 identification_required quando o perfil não está identificado: err.errors indica o que falta, a completar com me.update()
membership.events({ limit?, cursor? }) membership:read histórico de status, paginado
membership.statuto() membership:read o statuto em vigor e a aceitação do associado
membership.acceptStatuto({ version, sha256? }) statuto:accept registra a aceitação
membership.card() membership:read o token da carteirinha (QR) e a sua janela; 409 not_active se a carteirinha não estiver ativa
membership.renew({ version, sha256? }) POST /v1/me/membership/renew renovação pelo próprio associado: na hora quando é gratuita e sem aprovação, senão um pedido à secretaria
membership.setNetworkOptIn(bool) PATCH /v1/me/membership/network-opt-in consentimento ao Network (network:manage)
membership.googleWalletUrl() GET /v1/me/membership/wallet/google um link “Salvar no Google Wallet”; 409 not_active se a carteirinha não estiver ativa
membership.cardSvg() GET /v1/me/membership/card.svg a carteirinha em SVG (com o QR); 409 not_active se a carteirinha não estiver ativa
membership.emailCard() POST /v1/me/membership/card/email envia a carteirinha por e-mail ao associado

Os eventos publicados da associação, incluindo os só para associados (events:read). Os públicos não precisam de login: vimine.public.events.

events.list({ filter?, from?, to?, limit? }) filter: upcoming (padrão), past, cancelled, all
events.get(slug) conteúdo, imagens, tipos de inscrição com as vagas restantes
events.eligibility(slug) o associado pode se inscrever? por tipo, com os motivos (membership_required, sold_out, …)

As inscrições do associado (registrations:read / registrations:write). Veja o guia Eventos e inscrições.

registrations.create(slug, { registration_type, note?, quantity? }, opts?) tipo gratuito → confirmed com o token do QR; com contribuição → reserved com payment_instructions; 422 not_eligible com os motivos; Idempotency-Key gerada
registrations.list({ filter? }) · registrations.get(id) as inscrições do associado (filter: 'upcoming')
registrations.cancel(id) cancela dentro da janela do evento (409 window_closed depois)
registrations.tokenPayload(id) o conteúdo do QR de uma inscrição confirmada, ou null
connections.list() os apps que o associado autorizou nesta associação
connections.revoke(clientId) retira o consentimento de um app (as sessões dele terminam)

Os endpoints públicos, sem credenciais: veja publicApi.

storage Onde Quando
'session' (padrão) sessionStorage: por aba, some quando ela é fechada o padrão mais seguro para um cliente público
'local' localStorage: compartilhado entre as abas, sobrevive às reinicializações; o logout se propaga às outras abas apps em que o associado espera continuar conectado
'memory' só na memória SSR, testes, quiosques
TokenStorage um objeto seu { get, set, remove } Node, storages criptografados, apps nativos

Onde o storage do navegador não está disponível (modo privado, about:blank), o SDK recorre à memória. MemoryStorage é exportado.

  • createPkce() → { verifier, challenge, method: 'S256' }, createVerifier(), createChallenge(verifier), createState(), base64url(bytes) — PKCE e state sobre WebCrypto, se você montar o fluxo à mão.
  • DEFAULT_API_URL, DEFAULT_APP_URL.
  • publicApi(options?) — veja API pública.
  • VimineError — veja Erros.