UNPKG

accounts

Version:

Tempo Accounts SDK

47 lines 2.22 kB
import { createRemoteJWKSet, jwtVerify } from 'jose'; /** Cache of remote JWKS sets keyed by issuer, so verification reuses fetched keys. */ const jwksCache = new Map(); /** * Verifies an OIDC identity token (JWT) against an issuer's JWKS and returns its * claims. Asserts the signature, `iss`, `aud`, and `exp` (via `jose`), plus * `email_verified === true`. Optionally cross-checks `sub` (the account address) * and `nonce` when provided. Throws on any failure. * * Standalone counterpart to `Handler.auth({ identity })` — use it when minting * your own session inside `onAuthenticate` with `session: false`. */ export async function verify(idToken, options) { const { audience, issuer, nonce, subject } = options; let jwks = jwksCache.get(issuer); if (!jwks) { // Discover the JWKS endpoint (standard OIDC), falling back to the // conventional path when the issuer omits the discovery document. const discovery = await fetch(`${trimTrailingSlash(issuer)}/.well-known/openid-configuration`) .then((res) => (res.ok ? res.json() : null)) .catch(() => null); const jwksUri = discovery?.jwks_uri ?? `${trimTrailingSlash(issuer)}/.well-known/jwks.json`; jwks = createRemoteJWKSet(new URL(jwksUri)); jwksCache.set(issuer, jwks); } const { payload } = await jwtVerify(idToken, jwks, { algorithms: ['EdDSA'], audience, issuer, }); if (payload.email_verified !== true) throw new Error('email not verified'); if (subject && String(payload.sub).toLowerCase() !== subject.toLowerCase()) throw new Error('identity token subject mismatch'); if (nonce !== undefined && payload.nonce !== nonce) throw new Error('identity token nonce mismatch'); return { email: typeof payload.email === 'string' ? payload.email : undefined, nonce: typeof payload.nonce === 'string' ? payload.nonce : undefined, subject: String(payload.sub), }; } /** Strips a single trailing slash so issuer-relative URLs join cleanly. */ function trimTrailingSlash(value) { return value.endsWith('/') ? value.slice(0, -1) : value; } //# sourceMappingURL=Identity.js.map