Vimine (navigateur)
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.
Connexion
Section intitulée « Connexion »signIn(options?)
Section intitulée « signIn(options?) »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é |
createSignInUrl(options?)
Section intitulée « createSignInUrl(options?) »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.
hasRedirectParams(url?)
Section intitulée « hasRedirectParams(url?) »true quand l’URL (par défaut : la page courante) porte les paramètres d’un retour (code+state ou error).
handleRedirect({ url?, cleanUrl? })
Section intitulée « handleRedirect({ url?, cleanUrl? }) »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é.
getSession() · isSignedIn()
Section intitulée « getSession() · isSignedIn() »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}getAccessToken()
Section intitulée « getAccessToken() »Un jeton d’accès valable, rafraîchi quand il expire dans les 30 secondes. Lève not_signed_in sans session.
refresh()
Section intitulée « refresh() »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).
onChange(listener)
Section intitulée « onChange(listener) »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.
API membre
Section intitulée « API membre »request(path, init?)
Section intitulée « request(path, init?) »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) |
membership
Section intitulée « membership »| 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, …) |
registrations
Section intitulée « registrations »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
Section intitulée « connections »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.
Stockage
Section intitulée « Stockage »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é.
Utilitaires
Section intitulée « Utilitaires »createPkce()→{ verifier, challenge, method: 'S256' },createVerifier(),createChallenge(verifier),createState(),base64url(bytes)— PKCE etstatesur WebCrypto, si vous construisez le flux à la main.DEFAULT_API_URL,DEFAULT_APP_URL.publicApi(options?)— voir API publique.VimineError— voir Erreurs.