Vimine (navegador)
import { Vimine } from '@vimine/sdk';const vimine = new Vimine(options);Vimine gestiona Iniciar sesión con Vimine (OAuth 2.1 + PKCE), la sesión del socio y las llamadas a la API de
socios. Una instancia por cliente; créala una vez y reutilízala.
Opciones
Sección titulada «Opciones»| Opción | Tipo | Por defecto | |
|---|---|---|---|
clientId |
string |
— | tu vmc_… (obligatorio) |
redirectUri |
string |
— | la página que llama a handleRedirect(), registrada para el cliente (obligatorio) |
scopes |
Scope[] |
['profile:read', 'membership:read'] |
permisos que solicita signIn() |
storage |
'session' | 'local' | 'memory' | TokenStorage |
'session' |
dónde viven la sesión y el inicio de sesión en curso |
storageKey |
string |
vimine:<clientId>: |
prefijo de las claves en el almacenamiento |
locale |
Locale |
'it' |
idioma de las páginas de inicio de sesión y de consentimiento |
apiUrl |
string |
https://api.vimine.network |
origen de la API |
appUrl |
string |
https://app.vimine.network |
origen de las páginas de inicio de sesión |
fetch |
typeof fetch |
globalThis.fetch |
para tests y polyfills |
navigate |
(url) => void |
top.location.assign |
cómo salir de la página |
El constructor lanza un VimineError (invalid_options) sin clientId o redirectUri.
Inicio de sesión
Sección titulada «Inicio de sesión»signIn(options?)
Sección titulada «signIn(options?)»Envía la ventana principal a la página de inicio de sesión y de consentimiento. Llámalo desde un gesto del
usuario (un clic). Desde dentro de un iframe de otro origen la navegación se rechaza (framed): la página de inicio
de sesión nunca se muestra en un marco.
| Opción | |
|---|---|
scopes |
permisos de este inicio de sesión |
prompt |
'login' (credenciales siempre) o 'consent' (consentimiento siempre) |
returnTo |
tu propio estado, guardado localmente y devuelto por handleRedirect() — no se envía |
createSignInUrl(options?)
Sección titulada «createSignInUrl(options?)»Construye la URL de autorización y recuerda el inicio de sesión en curso (verificador PKCE y state) sin navegar.
Útil cuando dibujas tú el enlace.
hasRedirectParams(url?)
Sección titulada «hasRedirectParams(url?)»true cuando la URL (por defecto: la página actual) lleva los parámetros de una vuelta (code+state o error).
handleRedirect({ url?, cleanUrl? })
Sección titulada «handleRedirect({ url?, cleanUrl? })»En la página de callback: comprueba el state, intercambia el código por los tokens y guarda la sesión. Devuelve
{ session, returnTo }, o null cuando la URL no lleva parámetros de inicio de sesión. Con cleanUrl (por defecto
true) quita code, state y error de la barra de direcciones.
Errores (VimineError.code): access_denied y los demás errores OAuth cuando el socio no ha autorizado; no_flow
cuando no se ha iniciado ningún inicio de sesión desde este navegador (almacenamiento vacío o caducado);
state_mismatch cuando la vuelta no corresponde; invalid_grant cuando el código ha caducado o ya se ha usado.
getSession() · isSignedIn()
Sección titulada «getSession() · isSignedIn()»La sesión guardada, o null.
interface Session { accessToken: string; refreshToken: string | null; expiresAt: number; // ms, absoluto scope: Scope[]; sub: string | null; // el identificador del socio para tu asociación (vms_…) mode?: 'live' | 'test'; // 'test' para las sesiones de un cliente de prueba}getAccessToken()
Sección titulada «getAccessToken()»Un token de acceso válido, renovado cuando caduca en menos de 30 segundos. Lanza not_signed_in si no hay sesión.
refresh()
Sección titulada «refresh()»Rota la sesión con el refresh token (una sola petición aunque se llame de forma concurrente). Cuando el refresh token ya no se puede usar, la sesión se borra y el error se vuelve a lanzar.
signOut({ everywhere?, postLogoutRedirectUri?, state? })
Sección titulada «signOut({ everywhere?, postLogoutRedirectUri?, state? })»Revoca el refresh token (RFC 7009, en la medida de lo posible) y olvida la sesión. Con everywhere: true, después
envía el navegador al /oauth/logout de la app de Vimine, que cierra la sesión del socio y vuelve a
postLogoutRedirectUri (por defecto redirectUri; debe estar en un origen registrado).
onChange(listener)
Sección titulada «onChange(listener)»listener(session | null) en cada inicio de sesión, renovación y cierre de sesión; con storage: 'local', también
para los que ocurren en otras pestañas. Devuelve la función para cancelar la suscripción.
API de socios
Sección titulada «API de socios»request(path, init?)
Sección titulada «request(path, init?)»Una llamada autenticada: Authorization: Bearer, JSON de entrada y de salida, errores como VimineError, un
reintento después de una renovación cuando la respuesta es 401. init.idempotencyKey se convierte en la cabecera
Idempotency-Key.
const events = await vimine.request('/v1/me/membership/events?limit=5');| Scope | ||
|---|---|---|
me.get() |
profile:read |
el perfil (Me), con codicefiscale_check: cómo está identificada la persona (null = todavía no) |
me.update(patch) |
profile:write |
teléfono, sexo, y la identificación: fecha, lugar y país de nacimiento (birth_country), código fiscal — opcional, se puede añadir más tarde. Un código que no coincide responde 422 con una entrada codicefiscale_mismatch; cuando es confirmable, la persona lo confirma con codicefiscale_confirmed: true (guía) |
membership
Sección titulada «membership»| Scope | ||
|---|---|---|
membership.get() |
membership:read |
el carné: status, verdict, expires_at, statuto, card |
membership.request(body, { idempotencyKey? }) |
membership:request |
solicitud de inscripción; se genera una clave de idempotencia si falta. 422 identification_required cuando el perfil no está identificado: err.errors indica lo que falta, que se completa con me.update() |
membership.events({ limit?, cursor? }) |
membership:read |
historial de estados, paginado |
membership.statuto() |
membership:read |
el estatuto en vigor y la aceptación del socio |
membership.acceptStatuto({ version, sha256? }) |
statuto:accept |
registra la aceptación |
membership.card() |
membership:read |
el token del carné (QR) y su ventana; 409 not_active salvo que la inscripción esté activa |
membership.renew({ version, sha256? }) |
POST /v1/me/membership/renew |
renovación por cuenta propia: inmediata si es gratuita y sin aprobación; si no, una solicitud a la secretaría |
membership.setNetworkOptIn(bool) |
PATCH /v1/me/membership/network-opt-in |
consentimiento al Network (network:manage) |
membership.googleWalletUrl() |
GET /v1/me/membership/wallet/google |
un enlace «Guardar en Google Wallet»; 409 not_active salvo que la inscripción esté activa |
membership.cardSvg() |
GET /v1/me/membership/card.svg |
el carné en SVG (con el QR); 409 not_active salvo que la inscripción esté activa |
membership.emailCard() |
POST /v1/me/membership/card/email |
envía al socio su carné por correo |
Los eventos publicados de la asociación, incluidos los que son solo para socios (events:read). Los públicos no
necesitan iniciar sesión: vimine.public.events.
events.list({ filter?, from?, to?, limit? }) |
filter: upcoming (por defecto), past, cancelled, all |
events.get(slug) |
contenido, imágenes, tipos de inscripción con las plazas que quedan |
events.eligibility(slug) |
¿puede inscribirse el socio? por tipo, con los motivos (membership_required, sold_out, …) |
registrations
Sección titulada «registrations»Las inscripciones del socio (registrations:read / registrations:write). Consulta la guía Eventos e inscripciones.
registrations.create(slug, { registration_type, note?, quantity? }, opts?) |
tipo gratuito → confirmed con el token del QR; con contribución → reserved con payment_instructions; 422 not_eligible con los motivos; Idempotency-Key generada |
registrations.list({ filter? }) · registrations.get(id) |
las inscripciones del socio (filter: 'upcoming') |
registrations.cancel(id) |
anula dentro de la ventana del evento (después, 409 window_closed) |
registrations.tokenPayload(id) |
el contenido del QR de una inscripción confirmada, o null |
connections
Sección titulada «connections»connections.list() |
las apps que el socio ha autorizado en esta asociación |
connections.revoke(clientId) |
retira el consentimiento a una app (sus sesiones terminan) |
Los endpoints públicos, sin credenciales: consulta publicApi.
Almacenamiento
Sección titulada «Almacenamiento»storage |
Dónde | Cuándo |
|---|---|---|
'session' (por defecto) |
sessionStorage: por pestaña, desaparece al cerrarla |
la opción por defecto más segura para un cliente público |
'local' |
localStorage: compartido entre pestañas, sobrevive a los reinicios; el cierre de sesión se propaga a las demás pestañas |
apps en las que el socio espera seguir con la sesión iniciada |
'memory' |
solo en memoria | SSR, tests, quioscos |
TokenStorage |
un objeto tuyo { get, set, remove } |
Node, almacenamientos cifrados, apps nativas |
Cuando el almacenamiento del navegador no está disponible (modo privado, about:blank), el SDK recurre a la memoria.
Se exporta MemoryStorage.
Utilidades
Sección titulada «Utilidades»createPkce()→{ verifier, challenge, method: 'S256' },createVerifier(),createChallenge(verifier),createState(),base64url(bytes)— PKCE ystatesobre WebCrypto, si construyes el flujo a mano.DEFAULT_API_URL,DEFAULT_APP_URL.publicApi(options?)— consulta API pública.VimineError— consulta Errores.