# token-verifier _(no submodules)_ ## Purpose Verifies signed JWTs against local keys or remote JWKS endpoints. The `TokenVerifier` class resolves verification keys from either an in-memory key cache or a remote JWKS URI (with retry and AbortSignal support), then delegates cryptographic verification to `jose`. After successful signature verification, per-verification constraint checks enforce tenant isolation, role requirements, and permission scopes. ## Features - `TokenVerifier` class with configurable issuer, audience, clock tolerance, and injectable clock - Remote JWKS URI support with configurable TTL caching and retry (default 3 attempts) - `AbortSignal` cancellation for JWKS fetch operations - `addKey(jwk)` — register a local JWK for key-only verification (no remote fetch) - `clearCache()` — invalidate the JWKS cache for immediate rotation - `verifyToken(token, options?)` — returns `VerifyTokenResult` (never throws) - Per-verification constraints: `requiredTenantId`, `requiredRole`, `requiredPermissions`, `requiredClaims`, `requiredDomains` - `verifyTokenWithKey(token, key, options?)` — standalone function for pre-imported keys - `createTokenVerifier(config?)` — factory function ## Usage: Basic Example ```ts import { generateKeyPair, keyPairToJWK } from "@suaveplan/jwt-tenant/keys/key-generator"; import { TokenIssuer } from "@suaveplan/jwt-tenant/token/token-issuer"; import { TokenVerifier } from "@suaveplan/jwt-tenant/token/token-verifier"; const kp = await generateKeyPair("EdDSA"); const issuer = new TokenIssuer({ issuer: "https://auth.example.com" }); const token = await issuer.createToken(kp, { subject: "u1", tenantId: "acme" }); const verifier = new TokenVerifier({ issuer: "https://auth.example.com" }); const jwk = await keyPairToJWK(kp); verifier.addKey(jwk); const result = await verifier.verifyToken(token); // result.valid === true // result.payload.tenant_id === "acme" ``` ## Usage: Advanced Example ```ts const verifier = new TokenVerifier({ jwksUri: "https://auth.example.com/.well-known/jwks.json", issuer: "https://auth.example.com", cacheMaxAge: 5 * 60 * 1000, clockTolerance: 30, maxRetries: 3, signal: AbortSignal.timeout(5000), }); const result = await verifier.verifyToken(token, { requiredTenantId: "acme", requiredRole: "admin", requiredPermissions: ["write:data"], requiredDomains: ["acme.example.com"], }); ``` ## API Reference ### `TokenVerifier` Constructor: `new TokenVerifier(config?: TokenVerifierConfig)`. #### Methods - **`verifyToken(token, options?): Promise`** — Verifies the token. Returns `{ valid: true, payload }` or `{ valid: false, error, errorCode }`. Never throws. - **`addKey(jwk): void`** — Adds a local JWK to the key cache. - **`clearCache(): void`** — Clears the key cache. ### `createTokenVerifier(config?): TokenVerifier` Factory function. ### `verifyTokenWithKey(token, key, options?): Promise` Standalone verification with a pre-imported key reference. ## Implementation Notes JWKS cache uses timestamp comparison (`clock() >= cacheExpiresAt`) for expiry. Multi-key verification tries each JWK in order and returns on the first success — the last error is preserved and wrapped if all keys fail. The `checkConstraints` method is `protected` to allow subclass extension without exposing it in the public API. All jose errors are classified by message substring matching into one of the JWT error codes.