Aller au contenu

Vimine (navigateur)

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

Vimine gère Se connecter avec Vimine (OAuth 2.1 + PKCE), la session du membre et les appels à l’API membre. Une instance par client ; créez-la une fois et réutilisez-la.

Option Type Par défaut
clientId string — votre vmc_… (obligatoire)
redirectUri string — la page qui appelle handleRedirect(), enregistrée pour le client (obligatoire)
scopes Scope[] ['profile:read', 'membership:read'] autorisations demandées par signIn()
storage 'session' | 'local' | 'memory' | TokenStorage 'session' où vivent la session et la connexion en cours
storageKey string vimine:<clientId>: préfixe des clés dans le stockage
locale Locale 'it' langue des pages de connexion et de consentement
apiUrl string https://api.vimine.network origine de l’API
appUrl string https://app.vimine.network origine des pages de connexion
fetch typeof fetch globalThis.fetch pour les tests et les polyfills
navigate (url) => void top.location.assign comment quitter la page

Le constructeur lève une VimineError (invalid_options) sans clientId ou sans redirectUri.

Envoie la fenêtre principale vers la page de connexion et de consentement. Appelez-la depuis un geste de l’utilisateur (un clic). Depuis une iframe d’une autre origine, la navigation est refusée (framed) : la page de connexion n’est jamais affichée dans un cadre.

Option
scopes autorisations de cette connexion
prompt 'login' (identifiants toujours) ou 'consent' (consentement toujours)
returnTo votre propre état, conservé localement et renvoyé par handleRedirect() — il n’est pas envoyé

Construit l’URL d’autorisation et mémorise la connexion en cours (vérificateur PKCE et state) sans naviguer. Utile quand vous affichez le lien vous-même.

true quand l’URL (par défaut : la page courante) porte les paramètres d’un retour (code+state ou error).

Sur la page de callback : vérifie le state, échange le code contre des jetons et enregistre la session. Renvoie { session, returnTo }, ou null quand l’URL ne porte aucun paramètre de connexion. Avec cleanUrl (par défaut true), elle retire code, state et error de la barre d’adresse.

Erreurs (VimineError.code) : access_denied et les autres erreurs OAuth quand le membre n’a pas donné son autorisation ; no_flow quand aucune connexion n’a été lancée depuis ce navigateur (stockage vide ou expiré) ; state_mismatch quand le retour ne correspond pas ; invalid_grant quand le code a expiré ou a déjà été utilisé.

La session enregistrée, ou null.

interface Session {
accessToken: string;
refreshToken: string | null;
expiresAt: number; // ms, absolu
scope: Scope[];
sub: string | null; // l’identifiant du membre pour votre association (vms_…)
mode?: 'live' | 'test'; // 'test' pour les sessions d’un client de test
}

Un jeton d’accès valable, rafraîchi quand il expire dans les 30 secondes. Lève not_signed_in sans session.

Fait tourner la session avec le jeton de rafraîchissement (une seule requête même en cas d’appels concurrents). Quand le jeton de rafraîchissement n’est plus utilisable, la session est effacée et l’erreur relancée.

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

Section intitulée « signOut({ everywhere?, postLogoutRedirectUri?, state? }) »

Révoque le jeton de rafraîchissement (RFC 7009, au mieux) et oublie la session. Avec everywhere: true, elle envoie ensuite le navigateur vers le /oauth/logout de l’application Vimine, qui met fin à la session du membre et revient sur postLogoutRedirectUri (par défaut redirectUri ; elle doit se trouver sur une origine enregistrée).

listener(session | null) à chaque connexion, rafraîchissement et déconnexion ; avec storage: 'local', aussi pour ceux survenus dans d’autres onglets. Renvoie la fonction de désabonnement.

Un appel authentifié : Authorization: Bearer, JSON en entrée et en sortie, erreurs sous forme de VimineError, un nouvel essai après un rafraîchissement quand la réponse est 401. init.idempotencyKey devient l’en-tête Idempotency-Key.

const events = await vimine.request('/v1/me/membership/events?limit=5');
Scope
me.get() profile:read le profil (Me), avec codicefiscale_check : comment la personne est identifiée (null = pas encore)
me.update(patch) profile:write téléphone, genre, et l’identification : date, lieu et pays de naissance (birth_country), code fiscal — facultatif, peut être ajouté plus tard. Un code en désaccord répond 422 avec une entrée codicefiscale_mismatch ; quand elle est confirmable, la personne le confirme avec codicefiscale_confirmed: true (guide)
Scope
membership.get() membership:read la carte : status, verdict, expires_at, statuto, card
membership.request(body, { idempotencyKey? }) membership:request demande d’adhésion ; une clé d’idempotence est générée si elle est absente. 422 identification_required quand le profil n’est pas identifié : err.errors nomme ce qui manque, à compléter avec me.update()
membership.events({ limit?, cursor? }) membership:read historique des états, paginé
membership.statuto() membership:read le statuto en vigueur et l’acceptation du membre
membership.acceptStatuto({ version, sha256? }) statuto:accept enregistre l’acceptation
membership.card() membership:read le jeton de la carte (QR) et sa fenêtre ; 409 not_active si l’adhésion n’est pas active
membership.renew({ version, sha256? }) POST /v1/me/membership/renew renouvellement par le membre : immédiat quand il est gratuit et sans approbation, sinon une demande au secrétariat
membership.setNetworkOptIn(bool) PATCH /v1/me/membership/network-opt-in consentement au Network (network:manage)
membership.googleWalletUrl() GET /v1/me/membership/wallet/google un lien « Enregistrer dans Google Wallet » ; 409 not_active si l’adhésion n’est pas active
membership.cardSvg() GET /v1/me/membership/card.svg la carte en SVG (avec le QR) ; 409 not_active si l’adhésion n’est pas active
membership.emailCard() POST /v1/me/membership/card/email envoie sa carte au membre par e-mail

Les événements publiés de l’association, y compris ceux réservés aux membres (events:read). Les événements publics n’exigent pas de connexion : vimine.public.events.

events.list({ filter?, from?, to?, limit? }) filter : upcoming (par défaut), past, cancelled, all
events.get(slug) contenu, images, types d’inscription avec les places restantes
events.eligibility(slug) le membre peut-il s’inscrire ? par type, avec les raisons (membership_required, sold_out, …)

Les inscriptions du membre (registrations:read / registrations:write). Voir le guide Événements et inscriptions.

registrations.create(slug, { registration_type, note?, quantity? }, opts?) type gratuit → confirmed avec le token du QR ; avec contribution → reserved avec payment_instructions ; 422 not_eligible avec les raisons ; Idempotency-Key générée
registrations.list({ filter? }) · registrations.get(id) les inscriptions du membre (filter: 'upcoming')
registrations.cancel(id) annule dans la fenêtre de l’événement (409 window_closed ensuite)
registrations.tokenPayload(id) le contenu du QR d’une inscription confirmée, ou null
connections.list() les applications que le membre a autorisées dans cette association
connections.revoke(clientId) retire le consentement à une application (ses sessions prennent fin)

Les endpoints publics, sans identifiants : voir publicApi.

storage Où Quand
'session' (par défaut) sessionStorage : par onglet, effacé à sa fermeture le choix par défaut le plus sûr pour un client public
'local' localStorage : partagé entre les onglets, survit aux redémarrages ; la déconnexion se propage aux autres onglets applications où le membre s’attend à rester connecté
'memory' en mémoire seulement SSR, tests, bornes
TokenStorage un objet à vous { get, set, remove } Node, stockages chiffrés, applications natives

Là où le stockage du navigateur n’est pas disponible (navigation privée, about:blank), le SDK se replie sur la mémoire. MemoryStorage est exporté.

  • createPkce() → { verifier, challenge, method: 'S256' }, createVerifier(), createChallenge(verifier), createState(), base64url(bytes) — PKCE et state sur WebCrypto, si vous construisez le flux à la main.
  • DEFAULT_API_URL, DEFAULT_APP_URL.
  • publicApi(options?) — voir API publique.
  • VimineError — voir Erreurs.