first commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user