first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
# token-verifier
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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<VerifyTokenResult>`** — 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<VerifyTokenResult>`
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.