UNPKG

vouchsafe

Version:

Self-verifying identity and offline trust verification for JWTs, including attestations, vouches, revocations, and multi-hop trust chains.

104 lines (89 loc) 2.9 kB
// src/identity.mjs // Minimal OO wrapper around the existing functional API import { createVouchsafeIdentity, createVouchsafeIdentityFromKeypair, verifyUrnMatchesKey } from './urn.mjs'; import { createJwt, verifyJwt } from './jwt.mjs'; import { createAttestation, createVouchToken, validateVouchToken, revokeVouchToken } from './vouch.mjs'; function normalizePurpose(purpose) { if (!purpose) return undefined; return Array.isArray(purpose) ? purpose.join(' ') : purpose; } /** * Usage: * // rehydrate from existing material * const id = new Identity({ urn, keypair }); * * // or generate: * const id = await Identity.create('alice'); * * // or derive a URN from an existing keypair + label: * const id = await Identity.fromKeypair('alice', keypair); */ export class Identity { constructor(init) { if (!init || typeof init !== 'object') { throw new TypeError('Identity ctor expects { urn, keypair }'); } const { urn, keypair } = init; if (!urn || !keypair || !keypair.publicKey || !keypair.privateKey) { throw new Error('Identity requires a valid { urn, keypair:{ publicKey, privateKey } }'); } this.urn = urn; this.keypair = keypair; } // --- factories (async) --- static async create(label, ...rest) { // passthrough any extra args (e.g., hashAlg) as your createVouchsafeIdentity supports const { urn, keypair } = await createVouchsafeIdentity(label, ...rest); return new Identity({ urn, keypair }); } static async from(init, { verify = true } = {}) { // Rehydrate from { urn, keypair } and (optionally) verify the binding if (!init || !init.urn || !init.keypair) { throw new Error('Identity.from requires { urn, keypair }'); } if (verify) { await verifyUrnMatchesKey(init.urn, init.keypair.publicKey); } return new Identity(init); } static async fromKeypair(label, keypair) { const { urn, keypair: kp } = await createVouchsafeIdentityFromKeypair(label, keypair); return new Identity({ urn, keypair: kp }); } // --- token creation --- async attest(claims = {}) { // Default vch_iss to this identity when omitted const c = { ...claims, purpose: normalizePurpose(claims.purpose) }; return createAttestation(this.urn, this.keypair, c); } async vouch(subjectToken, opts = {}) { const c = { ...opts, purpose: normalizePurpose(opts.purpose) }; return createVouchToken(subjectToken, this.urn, this.keypair, c); } async revoke(vouchToken, opts = {}) { // Revoke a specific vouch, or pass { revokes: 'all' } to revoke all for that subject return revokeVouchToken(vouchToken, this.keypair, opts); } async verify(token) { return validateVouchToken(token); } // --- utilities --- toJSON() { return { urn: this.urn, keypair: this.keypair }; } }