跳到內容

Vimine(瀏覽器)

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

Vimine 負責使用 Vimine 登入(OAuth 2.1 + PKCE)、會員的工作階段以及對會員 API 的呼叫。每個用戶端一個實例;建立一次,反覆使用。

選項 型別 預設值
clientId string — 您的 vmc_…(必填)
redirectUri string — 呼叫 handleRedirect() 的頁面,已為該用戶端登記(必填)
scopes Scope[] ['profile:read', 'membership:read'] signIn() 申請的權限
storage 'session' | 'local' | 'memory' | TokenStorage 'session' 工作階段和進行中的登入儲存在哪裡
storageKey string vimine:<clientId>: 儲存中的鍵字首
locale Locale 'it' 登入和授權同意頁面的語言
apiUrl string https://api.vimine.network API 的來源
appUrl string https://app.vimine.network 登入頁面的來源
fetch typeof fetch globalThis.fetch 用於測試和 polyfill
navigate (url) => void top.location.assign 如何離開目前頁面

缺少 clientId 或 redirectUri 時,建構函式拋出 VimineError(invalid_options)。

把頂層視窗送到登入和授權同意頁面。請在使用者操作(一次點選)中呼叫。在跨網域 iframe 內部,導覽會被拒絕(framed):登入頁面從不顯示在框架中。

選項
scopes 本次登入的權限
prompt 'login'(始終要求輸入登入資訊)或 'consent'(始終要求同意)
returnTo 您自己的狀態,儲存在本機,由 handleRedirect() 傳回——不會被發送

createSignInUrl(options?)

章節「createSignInUrl(options?)」

建構授權 URL 並記住進行中的登入(PKCE verifier 和 state),但不進行重新導向。適合您自己呈現連結的場景。

當 URL(預設:目前頁面)帶有返回參數(code+state 或 error)時為 true。

handleRedirect({ url?, cleanUrl? })

章節「handleRedirect({ url?, cleanUrl? })」

在回呼頁面上:檢查 state,用授權碼交換權杖並儲存工作階段。傳回 { session, returnTo };URL 中沒有登入參數時傳回 null。啟用 cleanUrl(預設 true)時,會從位址列中移除 code、state 和 error。

錯誤(VimineError.code):會員未授權時為 access_denied 及其他 OAuth 錯誤;本瀏覽器沒有發起過登入時(儲存為空或已過期)為 no_flow;返回不符時為 state_mismatch;授權碼已過期或已被使用時為 invalid_grant。

getSession() · isSignedIn()

章節「getSession() · isSignedIn()」

已儲存的工作階段,或 null。

interface Session {
accessToken: string;
refreshToken: string | null;
expiresAt: number; // 毫秒,絕對時間
scope: Scope[];
sub: string | null; // 會員在您的協會中的識別碼(vms_…)
mode?: 'live' | 'test'; // 測試用戶端的工作階段為 'test'
}

一個有效的存取權杖;若在 30 秒內到期則先重新整理。沒有工作階段時拋出 not_signed_in。

用重新整理權杖輪換工作階段(即使被並行呼叫,也只發出一次請求)。如果重新整理權杖已無法使用,工作階段會被清除,錯誤會被重新拋出。

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

章節「signOut({ everywhere?, postLogoutRedirectUri?, state? })」

撤銷重新整理權杖(RFC 7009,盡力而為)並清除工作階段。使用 everywhere: true 時,隨後會把瀏覽器送到 Vimine 應用的 /oauth/logout,結束會員的工作階段,再返回 postLogoutRedirectUri(預設為 redirectUri;必須位於已登記的來源上)。

每次登入、重新整理和登出時呼叫 listener(session | null);使用 storage: 'local' 時,其他分頁中發生的這些事件也會觸發。傳回取消訂閱的函式。

一次經過驗證的呼叫:Authorization: Bearer,輸入輸出均為 JSON,錯誤以 VimineError 拋出,回應為 401 時在重新整理後重試一次。init.idempotencyKey 會成為 Idempotency-Key 請求標頭。

const events = await vimine.request('/v1/me/membership/events?limit=5');
Scope
me.get() profile:read 個人資料(Me),帶有 codicefiscale_check:當事人的身份識別方式(null = 尚未識別)
me.update(patch) profile:write 電話、性別,以及身份識別資訊:出生日期、出生地和出生國(birth_country)、稅號——可選,可以之後再補充。不一致的稅號傳回 422,帶有一條 codicefiscale_mismatch 記錄;當它為 confirmable 時,當事人可以用 codicefiscale_confirmed: true 確認(指南)
Scope
membership.get() membership:read 會員卡:status、verdict、expires_at、statuto、card
membership.request(body, { idempotencyKey? }) membership:request 入會申請;未提供冪等鍵時會自動產生。個人資料尚未識別身份時傳回 422 identification_required:err.errors 列出缺少的內容,用 me.update() 補全
membership.events({ limit?, cursor? }) membership:read 狀態歷史,分頁
membership.statuto() membership:read 現行章程及會員的接受情況
membership.acceptStatuto({ version, sha256? }) statuto:accept 記錄接受
membership.card() membership:read 會員卡權杖(QR Code)及其有效時段;會員資格未生效時傳回 409 not_active
membership.renew({ version, sha256? }) POST /v1/me/membership/renew 自助續期:免費且無需審核時立即完成,否則向秘書處提交申請
membership.setNetworkOptIn(bool) PATCH /v1/me/membership/network-opt-in 加入網路的同意(network:manage)
membership.googleWalletUrl() GET /v1/me/membership/wallet/google “新增到 Google Wallet”連結;會員資格未生效時傳回 409 not_active
membership.cardSvg() GET /v1/me/membership/card.svg SVG 格式的會員卡(帶 QR Code);會員資格未生效時傳回 409 not_active
membership.emailCard() POST /v1/me/membership/card/email 透過電子郵件把會員卡發給會員

協會已發布的活動,包括僅限會員的活動(events:read)。公開活動無需登入:vimine.public.events。

events.list({ filter?, from?, to?, limit? }) filter:upcoming(預設)、past、cancelled、all
events.get(slug) 文案、圖片、各報名類型及剩餘名額
events.eligibility(slug) 會員能否報名?按類型給出,並附原因(membership_required、sold_out 等)

會員的報名(registrations:read / registrations:write)。參見活動與報名指南。

registrations.create(slug, { registration_type, note?, quantity? }, opts?) 免費類型 → confirmed,帶 QR Code token;需付參與費 → reserved,帶 payment_instructions;422 not_eligible 附原因;自動產生 Idempotency-Key
registrations.list({ filter? }) · registrations.get(id) 會員的報名(filter: 'upcoming')
registrations.cancel(id) 在活動的取消期限內取消(超過期限傳回 409 window_closed)
registrations.tokenPayload(id) 已確認報名的 QR Code 內容,或 null
connections.list() 會員在本協會中授權過的應用
connections.revoke(clientId) 撤回對某個應用的同意(其工作階段隨即結束)

無需憑證的公開端點:參見 publicApi。

storage 位置 適用場景
'session'(預設) sessionStorage:每個分頁獨立,關閉即清除 對公開用戶端而言最安全的預設值
'local' localStorage:多個分頁共享,重啟後仍保留;登出會同步到其他分頁 會員期望保持登入狀態的應用
'memory' 僅在記憶體中 SSR、測試、自助終端
TokenStorage 您自己的物件 { get, set, remove } Node、加密儲存、原生應用

在無法使用瀏覽器儲存的情況下(隱私模式、about:blank),SDK 會退回到記憶體儲存。MemoryStorage 已匯出。

  • createPkce() → { verifier, challenge, method: 'S256' }、createVerifier()、createChallenge(verifier)、createState()、base64url(bytes)——基於 WebCrypto 的 PKCE 和 state,供您手動建構流程時使用。
  • DEFAULT_API_URL、DEFAULT_APP_URL。
  • publicApi(options?)——參見公開 API。
  • VimineError——參見錯誤。