Vimine (Browser)
import { Vimine } from '@vimine/sdk';const vimine = new Vimine(options);Vimine übernimmt Mit Vimine anmelden (OAuth 2.1 + PKCE), die Sitzung des Mitglieds und die Aufrufe der
Mitglieder-API. Eine Instanz pro Client; legen Sie sie einmal an und verwenden Sie sie wieder.
Optionen
Abschnitt betitelt „Optionen“| Option | Typ | Standard | |
|---|---|---|---|
clientId |
string |
— | Ihre vmc_… (Pflicht) |
redirectUri |
string |
— | die Seite, die handleRedirect() aufruft, für den Client registriert (Pflicht) |
scopes |
Scope[] |
['profile:read', 'membership:read'] |
von signIn() angeforderte Berechtigungen |
storage |
'session' | 'local' | 'memory' | TokenStorage |
'session' |
wo die Sitzung und die laufende Anmeldung liegen |
storageKey |
string |
vimine:<clientId>: |
Schlüsselpräfix im Speicher |
locale |
Locale |
'it' |
Sprache der Anmelde- und Einwilligungsseiten |
apiUrl |
string |
https://api.vimine.network |
Origin der API |
appUrl |
string |
https://app.vimine.network |
Origin der Anmeldeseiten |
fetch |
typeof fetch |
globalThis.fetch |
für Tests und Polyfills |
navigate |
(url) => void |
top.location.assign |
wie die Seite verlassen wird |
Der Konstruktor wirft einen VimineError (invalid_options) ohne clientId oder redirectUri.
Anmeldung
Abschnitt betitelt „Anmeldung“signIn(options?)
Abschnitt betitelt „signIn(options?)“Schickt das oberste Fenster zur Anmelde- und Einwilligungsseite. Rufen Sie es aus einer Nutzergeste (einem Klick) auf. Aus einem
Cross-Origin-iframe heraus wird die Navigation abgelehnt (framed): Die Anmeldeseite wird nie in einem Frame gezeigt.
| Option | |
|---|---|
scopes |
Berechtigungen dieser Anmeldung |
prompt |
'login' (immer Zugangsdaten) oder 'consent' (immer Einwilligung) |
returnTo |
Ihr eigener Zustand, lokal gespeichert und von handleRedirect() zurückgegeben — er wird nicht gesendet |
createSignInUrl(options?)
Abschnitt betitelt „createSignInUrl(options?)“Baut die Autorisierungs-URL und merkt sich die laufende Anmeldung (PKCE-Verifier und state), ohne zu
navigieren. Nützlich, wenn Sie den Link selbst darstellen.
hasRedirectParams(url?)
Abschnitt betitelt „hasRedirectParams(url?)“true, wenn die URL (Standard: die aktuelle Seite) die Parameter einer Rückkehr trägt (code+state oder error).
handleRedirect({ url?, cleanUrl? })
Abschnitt betitelt „handleRedirect({ url?, cleanUrl? })“Auf der Callback-Seite: prüft den state, tauscht den Code gegen Tokens ein und speichert die Sitzung. Liefert
{ session, returnTo } oder null, wenn die URL keine Anmeldeparameter trägt. Mit cleanUrl (Standard
true) entfernt es code, state und error aus der Adressleiste.
Fehler (VimineError.code): access_denied und die anderen OAuth-Fehler, wenn das Mitglied nicht autorisiert hat;
no_flow, wenn in diesem Browser keine Anmeldung gestartet wurde (Speicher leer oder abgelaufen); state_mismatch, wenn die
Rückkehr nicht passt; invalid_grant, wenn der Code abgelaufen ist oder schon verwendet wurde.
Sitzung
Abschnitt betitelt „Sitzung“getSession() · isSignedIn()
Abschnitt betitelt „getSession() · isSignedIn()“Die gespeicherte Sitzung oder null.
interface Session { accessToken: string; refreshToken: string | null; expiresAt: number; // ms, absolut scope: Scope[]; sub: string | null; // die Kennung des Mitglieds für Ihren Verein (vms_…) mode?: 'live' | 'test'; // 'test' für Sitzungen eines Test-Clients}getAccessToken()
Abschnitt betitelt „getAccessToken()“Ein gültiges Access-Token, erneuert, wenn es innerhalb von 30 Sekunden abläuft. Wirft not_signed_in ohne Sitzung.
refresh()
Abschnitt betitelt „refresh()“Rotiert die Sitzung mit dem Refresh-Token (eine einzige Anfrage, auch bei gleichzeitigen Aufrufen). Ist das Refresh-Token nicht mehr verwendbar, wird die Sitzung gelöscht und der Fehler weitergeworfen.
signOut({ everywhere?, postLogoutRedirectUri?, state? })
Abschnitt betitelt „signOut({ everywhere?, postLogoutRedirectUri?, state? })“Widerruft das Refresh-Token (RFC 7009, nach bestem Bemühen) und vergisst die Sitzung. Mit everywhere: true schickt es den
Browser anschließend zu /oauth/logout der Vimine-App, das die Sitzung des Mitglieds beendet und zu
postLogoutRedirectUri zurückkehrt (Standard redirectUri; es muss auf einem registrierten Origin liegen).
onChange(listener)
Abschnitt betitelt „onChange(listener)“listener(session | null) bei jeder Anmeldung, Erneuerung und Abmeldung; mit storage: 'local' auch bei denen, die
in anderen Tabs geschehen. Liefert die Funktion zum Abmelden des Listeners.
Mitglieder-API
Abschnitt betitelt „Mitglieder-API“request(path, init?)
Abschnitt betitelt „request(path, init?)“Ein authentifizierter Aufruf: Authorization: Bearer, JSON hin und zurück, Fehler als VimineError, eine Wiederholung nach einer
Erneuerung, wenn die Antwort 401 ist. init.idempotencyKey wird zum Header Idempotency-Key.
const events = await vimine.request('/v1/me/membership/events?limit=5');| Scope | ||
|---|---|---|
me.get() |
profile:read |
das Profil (Me), mit codicefiscale_check: wie die Person identifiziert ist (null = noch nicht) |
me.update(patch) |
profile:write |
Telefon, Geschlecht und die Identifizierung: Geburtsdatum, Geburtsort und Geburtsland (birth_country), Steuernummer — optional, kann später ergänzt werden. Eine abweichende Steuernummer ergibt 422 mit einem Eintrag codicefiscale_mismatch; ist er confirmable, bestätigt die Person sie mit codicefiscale_confirmed: true (Anleitung) |
membership
Abschnitt betitelt „membership“| Scope | ||
|---|---|---|
membership.get() |
membership:read |
der Ausweis: status, verdict, expires_at, statuto, card |
membership.request(body, { idempotencyKey? }) |
membership:request |
Beitrittsantrag; fehlt ein Idempotenzschlüssel, wird einer erzeugt. 422 identification_required, wenn das Profil nicht identifiziert ist: err.errors nennt, was fehlt, zu ergänzen mit me.update() |
membership.events({ limit?, cursor? }) |
membership:read |
Statusverlauf, seitenweise |
membership.statuto() |
membership:read |
das geltende Statuto und die Annahme durch das Mitglied |
membership.acceptStatuto({ version, sha256? }) |
statuto:accept |
erfasst die Annahme |
membership.card() |
membership:read |
das Ausweis-Token (QR) und sein Fenster; 409 not_active, solange die Mitgliedschaft nicht aktiv ist |
membership.renew({ version, sha256? }) |
POST /v1/me/membership/renew |
Verlängerung durch das Mitglied: sofort, wenn kostenlos und ohne Genehmigung, sonst ein Antrag an das Sekretariat |
membership.setNetworkOptIn(bool) |
PATCH /v1/me/membership/network-opt-in |
Einwilligung zum Netzwerk (network:manage) |
membership.googleWalletUrl() |
GET /v1/me/membership/wallet/google |
ein Link „In Google Wallet speichern“; 409 not_active, solange die Mitgliedschaft nicht aktiv ist |
membership.cardSvg() |
GET /v1/me/membership/card.svg |
der Ausweis als SVG (mit dem QR-Code); 409 not_active, solange die Mitgliedschaft nicht aktiv ist |
membership.emailCard() |
POST /v1/me/membership/card/email |
schickt dem Mitglied seinen Ausweis per E-Mail |
Die veröffentlichten Veranstaltungen des Vereins, einschließlich derer nur für Mitglieder (events:read). Die öffentlichen brauchen keine
Anmeldung: vimine.public.events.
events.list({ filter?, from?, to?, limit? }) |
filter: upcoming (Standard), past, cancelled, all |
events.get(slug) |
Inhalte, Bilder, Anmeldearten mit freien Plätzen |
events.eligibility(slug) |
darf sich das Mitglied anmelden? pro Art, mit Gründen (membership_required, sold_out, …) |
registrations
Abschnitt betitelt „registrations“Die Anmeldungen des Mitglieds (registrations:read / registrations:write). Siehe die Anleitung Veranstaltungen und Anmeldungen.
registrations.create(slug, { registration_type, note?, quantity? }, opts?) |
kostenlose Art → confirmed mit dem QR-token; mit Beitrag → reserved mit payment_instructions; 422 not_eligible mit den Gründen; Idempotency-Key wird erzeugt |
registrations.list({ filter? }) · registrations.get(id) |
die Anmeldungen des Mitglieds (filter: 'upcoming') |
registrations.cancel(id) |
storniert innerhalb des Fensters der Veranstaltung (danach 409 window_closed) |
registrations.tokenPayload(id) |
der QR-Inhalt einer bestätigten Anmeldung oder null |
connections
Abschnitt betitelt „connections“connections.list() |
die Apps, die das Mitglied in diesem Verein autorisiert hat |
connections.revoke(clientId) |
widerruft die Einwilligung für eine App (ihre Sitzungen enden) |
Die öffentlichen Endpunkte ohne Zugangsdaten: siehe publicApi.
Speicher
Abschnitt betitelt „Speicher“storage |
Wo | Wann |
|---|---|---|
'session' (Standard) |
sessionStorage: pro Tab, weg, wenn er sich schließt |
die sicherste Voreinstellung für einen öffentlichen Client |
'local' |
localStorage: zwischen Tabs geteilt, überlebt Neustarts; die Abmeldung erreicht die anderen Tabs |
Apps, in denen das Mitglied erwartet, angemeldet zu bleiben |
'memory' |
nur im Speicher | SSR, Tests, Kiosk-Geräte |
TokenStorage |
ein eigenes Objekt { get, set, remove } |
Node, verschlüsselte Speicher, native Apps |
Wo der Browser-Speicher nicht verfügbar ist (privater Modus, about:blank), weicht das SDK auf den Arbeitsspeicher aus.
MemoryStorage wird exportiert.
Hilfsfunktionen
Abschnitt betitelt „Hilfsfunktionen“createPkce()→{ verifier, challenge, method: 'S256' },createVerifier(),createChallenge(verifier),createState(),base64url(bytes)— PKCE undstateauf WebCrypto, falls Sie den Ablauf von Hand bauen.DEFAULT_API_URL,DEFAULT_APP_URL.publicApi(options?)— siehe Öffentliche API.VimineError— siehe Fehler.