toolcraft 0.0.125 → 0.0.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/composition.json CHANGED
@@ -76,6 +76,11 @@
76
76
  "version": "0.0.1",
77
77
  "license": "MIT"
78
78
  },
79
+ {
80
+ "name": "mcp-oauth-server",
81
+ "version": "0.1.0",
82
+ "license": "MIT"
83
+ },
79
84
  {
80
85
  "name": "sisteransi",
81
86
  "version": "1.0.5",
@@ -103,7 +108,7 @@
103
108
  },
104
109
  {
105
110
  "name": "toolcraft",
106
- "version": "0.0.125",
111
+ "version": "0.0.127",
107
112
  "license": "MIT"
108
113
  },
109
114
  {
@@ -113,7 +118,7 @@
113
118
  },
114
119
  {
115
120
  "name": "toolcraft-schema",
116
- "version": "0.0.125",
121
+ "version": "0.0.127",
117
122
  "license": "MIT"
118
123
  },
119
124
  {
@@ -76,6 +76,11 @@
76
76
  "version": "0.0.1",
77
77
  "license": "MIT"
78
78
  },
79
+ {
80
+ "name": "mcp-oauth-server",
81
+ "version": "0.1.0",
82
+ "license": "MIT"
83
+ },
79
84
  {
80
85
  "name": "sisteransi",
81
86
  "version": "1.0.5",
@@ -103,7 +108,7 @@
103
108
  },
104
109
  {
105
110
  "name": "toolcraft",
106
- "version": "0.0.125",
111
+ "version": "0.0.127",
107
112
  "license": "MIT"
108
113
  },
109
114
  {
@@ -113,7 +118,7 @@
113
118
  },
114
119
  {
115
120
  "name": "toolcraft-schema",
116
- "version": "0.0.125",
121
+ "version": "0.0.127",
117
122
  "license": "MIT"
118
123
  },
119
124
  {
package/dist/http.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import "./node-require-shim.js";
2
2
  import { type HttpListenOptions, type HttpServer, type HttpServerHandle, type HttpToolContext, type HttpTransportOptions } from "tiny-http-mcp-server/server";
3
3
  import type { Group } from "./index.js";
4
+ import type { OAuthAuthorizationServer } from "mcp-oauth-server";
4
5
  import { type RunMCPOptions } from "./mcp.js";
5
6
  export type ToolcraftHTTPContext = HttpToolContext;
6
7
  export type ToolcraftHTTPServer = HttpServer;
@@ -13,7 +14,16 @@ export interface RunHTTPMCPOptions<TServices extends object = Record<string, unk
13
14
  path?: string;
14
15
  requestServices?(context: ToolcraftHTTPContext): Partial<TServices> | Promise<Partial<TServices>>;
15
16
  }
17
+ export interface HTTPMCPAuthorizationOptions {
18
+ authorizationServer: Pick<OAuthAuthorizationServer, "issuer" | "verifyAccessToken">;
19
+ resource: string;
20
+ requiredScopes?: readonly string[];
21
+ scopesSupported?: readonly string[];
22
+ }
23
+ export declare function createHTTPMCPAuthorization(options: HTTPMCPAuthorizationOptions): import("tiny-http-mcp-server/server").TinyHttpMcpServerOAuthOptions;
16
24
  export declare function createHTTPMCPServer<TServices extends object = Record<string, unknown>>(roots: Group<TServices> | Group<TServices>[], options: RunHTTPMCPOptions<TServices>): Promise<ToolcraftHTTPServer>;
17
25
  export declare function runHTTPMCP<TServices extends object = Record<string, unknown>>(roots: Group<TServices> | Group<TServices>[], options: RunHTTPMCPOptions<TServices>): Promise<ToolcraftHTTPServerHandle>;
18
26
  export type { HttpListenOptions, HttpObservabilityEvent, HttpObservabilityOptions, RequestAuthInfo, Session, SessionStore, StreamableHttpTransportOptions, TinyHttpMcpServerOAuthOptions, TokenVerifier, VerifiedAccessToken } from "tiny-http-mcp-server/server";
19
27
  export { createJwksTokenVerifier, TokenVerificationError } from "tiny-http-mcp-server/server";
28
+ export { createAuthorizationInteractionSecurity, createInMemoryAuthorizationServerStore, createOAuthAuthorizationServer, verifyAuthorizationInteractionCsrf } from "mcp-oauth-server";
29
+ export type { AuthorizationInteraction, AuthorizationInteractionSecurity, AuthorizationServerStore, OAuthAuthorizationServer, OAuthAuthorizationServerOptions, VerifiedAuthorizationServerToken } from "mcp-oauth-server";
package/dist/http.js CHANGED
@@ -2,6 +2,45 @@ import "./node-require-shim.js";
2
2
  import { createHttpServer } from "tiny-http-mcp-server/server";
3
3
  import { createMCPServerForTransport } from "./mcp.js";
4
4
  import { enableSourceMaps } from "./stack-trim.js";
5
+ function toVerifiedAccessToken(token, issuer, verified) {
6
+ return {
7
+ token,
8
+ issuer,
9
+ audience: [verified.resource],
10
+ scopes: [...verified.scopes],
11
+ expiresAt: verified.expiresAt,
12
+ claims: {
13
+ sub: verified.subject,
14
+ client_id: verified.clientId,
15
+ aud: verified.resource,
16
+ jti: verified.tokenId
17
+ },
18
+ subject: verified.subject,
19
+ clientId: verified.clientId
20
+ };
21
+ }
22
+ export function createHTTPMCPAuthorization(options) {
23
+ const issuer = options.authorizationServer.issuer;
24
+ const resource = new URL(options.resource).href;
25
+ return {
26
+ resource,
27
+ authorizationServers: [issuer],
28
+ requiredScopes: options.requiredScopes,
29
+ scopesSupported: options.scopesSupported ?? options.requiredScopes,
30
+ verifier: {
31
+ async verify(input) {
32
+ if (input.authorizationServers.length !== 1 || input.authorizationServers[0] !== issuer) {
33
+ throw new Error("authorization server issuer does not match");
34
+ }
35
+ if (new URL(input.resource).href !== resource) {
36
+ throw new Error("protected resource does not match");
37
+ }
38
+ const verified = await options.authorizationServer.verifyAccessToken(input.token, resource);
39
+ return toVerifiedAccessToken(input.token, issuer, verified);
40
+ }
41
+ }
42
+ };
43
+ }
5
44
  function createTransportOptions(options, serverOptions) {
6
45
  return {
7
46
  ...serverOptions,
@@ -60,3 +99,4 @@ export async function runHTTPMCP(roots, options) {
60
99
  return server.listenHttp(createListenOptions(options));
61
100
  }
62
101
  export { createJwksTokenVerifier, TokenVerificationError } from "tiny-http-mcp-server/server";
102
+ export { createAuthorizationInteractionSecurity, createInMemoryAuthorizationServerStore, createOAuthAuthorizationServer, verifyAuthorizationInteractionCsrf } from "mcp-oauth-server";
@@ -23,7 +23,7 @@ const codex = allAgents.find((agent) => agent.id === "codex");
23
23
  - `parseAgentSpecifier(input)`: parses `agent` or `agent:model` input.
24
24
  - `formatAgentSpecifier(specifier)`: formats an agent specifier.
25
25
  - `normalizeAgentId(input)`: normalizes the agent part through the registry.
26
- - Agent definition exports such as `codexAgent`, `claudeCodeAgent`, and `geminiCliAgent`.
26
+ - Agent definition exports such as `codexAgent`, `claudeCodeAgent`, `geminiCliAgent`, and `piAgent`.
27
27
 
28
28
  ## Config Options
29
29
 
@@ -6,4 +6,5 @@ export { geminiCliAgent } from "./gemini-cli.js";
6
6
  export { openCodeAgent } from "./opencode.js";
7
7
  export { kimiAgent } from "./kimi.js";
8
8
  export { gooseAgent } from "./goose.js";
9
+ export { piAgent } from "./pi.js";
9
10
  export { poeAgentAgent } from "./poe-agent.js";
@@ -6,4 +6,5 @@ export { geminiCliAgent } from "./gemini-cli.js";
6
6
  export { openCodeAgent } from "./opencode.js";
7
7
  export { kimiAgent } from "./kimi.js";
8
8
  export { gooseAgent } from "./goose.js";
9
+ export { piAgent } from "./pi.js";
9
10
  export { poeAgentAgent } from "./poe-agent.js";
@@ -0,0 +1,2 @@
1
+ import type { AgentDefinition } from "../types.js";
2
+ export declare const piAgent: AgentDefinition;
@@ -0,0 +1,14 @@
1
+ export const piAgent = {
2
+ id: "pi",
3
+ name: "pi",
4
+ aliases: ["pi-agent"],
5
+ label: "Pi",
6
+ summary: "Pi coding agent (spawn-only; uses local Pi auth/settings).",
7
+ binaryName: "pi",
8
+ branding: {
9
+ colors: {
10
+ dark: "#F2F2F2",
11
+ light: "#242424"
12
+ }
13
+ }
14
+ };
@@ -1,5 +1,5 @@
1
1
  export type { AgentDefinition, ApiShapeId, OtelCaptureDefinition } from "./types.js";
2
2
  export type { AgentSpecifier } from "./specifier.js";
3
- export { claudeCodeAgent, claudeDesktopAgent, codexAgent, cursorAgent, geminiCliAgent, openCodeAgent, kimiAgent, gooseAgent, poeAgentAgent } from "./agents/index.js";
3
+ export { claudeCodeAgent, claudeDesktopAgent, codexAgent, cursorAgent, geminiCliAgent, openCodeAgent, kimiAgent, gooseAgent, piAgent, poeAgentAgent } from "./agents/index.js";
4
4
  export { allAgents, resolveAgentId } from "./registry.js";
5
5
  export { parseAgentSpecifier, formatAgentSpecifier, normalizeAgentId } from "./specifier.js";
@@ -1,3 +1,3 @@
1
- export { claudeCodeAgent, claudeDesktopAgent, codexAgent, cursorAgent, geminiCliAgent, openCodeAgent, kimiAgent, gooseAgent, poeAgentAgent } from "./agents/index.js";
1
+ export { claudeCodeAgent, claudeDesktopAgent, codexAgent, cursorAgent, geminiCliAgent, openCodeAgent, kimiAgent, gooseAgent, piAgent, poeAgentAgent } from "./agents/index.js";
2
2
  export { allAgents, resolveAgentId } from "./registry.js";
3
3
  export { parseAgentSpecifier, formatAgentSpecifier, normalizeAgentId } from "./specifier.js";
@@ -1,4 +1,4 @@
1
- import { claudeCodeAgent, claudeDesktopAgent, codexAgent, cursorAgent, geminiCliAgent, openCodeAgent, kimiAgent, gooseAgent, poeAgentAgent } from "./agents/index.js";
1
+ import { claudeCodeAgent, claudeDesktopAgent, codexAgent, cursorAgent, geminiCliAgent, openCodeAgent, kimiAgent, gooseAgent, piAgent, poeAgentAgent } from "./agents/index.js";
2
2
  function freezeAgent(agent) {
3
3
  if (agent.aliases !== undefined) {
4
4
  Object.freeze(agent.aliases);
@@ -25,6 +25,7 @@ export const allAgents = Object.freeze([
25
25
  freezeAgent(openCodeAgent),
26
26
  freezeAgent(kimiAgent),
27
27
  freezeAgent(gooseAgent),
28
+ freezeAgent(piAgent),
28
29
  freezeAgent(poeAgentAgent)
29
30
  ]);
30
31
  const lookup = new Map();
@@ -13,7 +13,7 @@ export interface AgentDefinition {
13
13
  binaryName?: string;
14
14
  readonly apiShapes?: readonly ApiShapeId[];
15
15
  readonly otelCapture?: OtelCaptureDefinition;
16
- configPath: string;
16
+ configPath?: string;
17
17
  readonly configPaths?: {
18
18
  readonly darwin: string;
19
19
  readonly linux: string;
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Poe Platform
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,192 @@
1
+ # mcp-oauth-server
2
+
3
+ Production OAuth 2.1 authorization-server primitives for MCP applications.
4
+
5
+ The package provides:
6
+
7
+ - authorization code with mandatory PKCE `S256`
8
+ - RFC 8414 authorization-server metadata
9
+ - RFC 7591 dynamic registration for public MCP clients
10
+ - exact registered redirect URI validation
11
+ - RFC 8707 resource indicators and audience-bound JWT access tokens
12
+ - JWKS publication and short-lived `at+jwt` access tokens
13
+ - rotating refresh tokens with replay-triggered family revocation
14
+ - token and grant revocation
15
+ - asynchronous durable storage interfaces
16
+ - an application-owned browser authorization interaction
17
+ - CSRF, state, nonce, and secure cookie helpers
18
+ - a Toolcraft adapter through `createHTTPMCPAuthorization()` from `toolcraft/http`
19
+
20
+ ## Availability
21
+
22
+ This package is bundled privately inside the published `toolcraft` package and
23
+ is supported through the `toolcraft/http` exports. It is not published as a
24
+ standalone npm package because that npm package name is owned outside this
25
+ repository.
26
+
27
+ ## Quick Start
28
+
29
+ ```ts
30
+ import { generateKeyPairSync } from "node:crypto";
31
+ import { exportJWK } from "jose";
32
+ import {
33
+ createHTTPMCPAuthorization,
34
+ createOAuthAuthorizationServer,
35
+ runHTTPMCP,
36
+ type AuthorizationInteraction,
37
+ type AuthorizationServerStore
38
+ } from "toolcraft/http";
39
+
40
+ const { privateKey, publicKey } = generateKeyPairSync("ec", {
41
+ namedCurve: "P-256"
42
+ });
43
+
44
+ const store: AuthorizationServerStore = createDurableStore();
45
+ const interaction: AuthorizationInteraction = {
46
+ async start({ transaction }) {
47
+ return renderApplicationAuthorizationPage(transaction);
48
+ }
49
+ };
50
+
51
+ const authorizationServer = createOAuthAuthorizationServer({
52
+ issuer: "https://auth.example.com",
53
+ resources: ["https://mcp.example.com/mcp"],
54
+ signingKey: {
55
+ algorithm: "ES256",
56
+ keyId: "2026-07",
57
+ privateKey,
58
+ publicJwk: await exportJWK(publicKey)
59
+ },
60
+ store,
61
+ interaction
62
+ });
63
+
64
+ await runHTTPMCP(groups, {
65
+ oauth: createHTTPMCPAuthorization({
66
+ authorizationServer,
67
+ resource: "https://mcp.example.com/mcp",
68
+ requiredScopes: ["mcp.read"]
69
+ }),
70
+ requestServices(context) {
71
+ if (context.auth === undefined) throw new Error("OAuth subject required");
72
+ return {
73
+ babyDaybook: loadBabyDaybookSession(context.auth.subject)
74
+ };
75
+ }
76
+ });
77
+ ```
78
+
79
+ Route requests for `/.well-known/oauth-authorization-server`,
80
+ `/.well-known/jwks.json`, `/register`, `/authorize`, `/token`, and `/revoke`
81
+ to `authorizationServer.handle(request)` in the application HTTP framework.
82
+
83
+ ## Application Authorization Interaction
84
+
85
+ `interaction.start({ request, transaction })` owns the browser experience. It
86
+ may render a login page, redirect to an upstream identity provider, or render a
87
+ one-time credential completion form. The application finishes the OAuth flow
88
+ only after authenticating its user:
89
+
90
+ ```ts
91
+ const completion = await authorizationServer.completeAuthorization({
92
+ transactionId,
93
+ subject: applicationUserId,
94
+ scopes: approvedScopes
95
+ });
96
+
97
+ return Response.redirect(completion.redirectUrl);
98
+ ```
99
+
100
+ For an Apple `intent://callback?...` completion flow:
101
+
102
+ 1. Generate the application CSRF token, upstream state, and nonce with
103
+ `createAuthorizationInteractionSecurity()`.
104
+ 2. Bind the upstream state to the pending authorization transaction in the
105
+ application's durable store.
106
+ 3. Render the callback paste form with the hidden CSRF token and returned
107
+ `Set-Cookie` value.
108
+ 4. On submission, bound the request body, verify CSRF with
109
+ `verifyAuthorizationInteractionCsrf()`, validate the exact intent callback
110
+ shape and state, and consume the application transaction once.
111
+ 5. Exchange the one-time callback immediately. Never log or persist the
112
+ callback, password, authorization code, access token, or refresh token in
113
+ plaintext.
114
+ 6. Persist only the encrypted upstream refresh session under the approved OAuth
115
+ subject, then call `completeAuthorization()`.
116
+
117
+ The application credential is deliberately absent from all package APIs so it
118
+ cannot accidentally enter OAuth transaction or token storage.
119
+
120
+ ## Durable Storage
121
+
122
+ Production deployments must implement `AuthorizationServerStore`. The
123
+ interface covers:
124
+
125
+ - dynamic clients
126
+ - browser authorization transactions
127
+ - authorization grants
128
+ - one-time authorization codes
129
+ - access-token revocation records
130
+ - refresh-token families
131
+
132
+ `takeAuthorizationTransaction()`, `takeAuthorizationCode()`, and
133
+ `rotateRefreshToken()` must be atomic. Refresh replay detection depends on the
134
+ store retaining rotated token-family relationships and revoking the family
135
+ when an old token is presented again.
136
+
137
+ `createInMemoryAuthorizationServerStore()` is intended for tests and local
138
+ development only. It is not durable and must not be used in production.
139
+
140
+ ## Subject Isolation
141
+
142
+ The access token `sub` claim is the only identity passed to Toolcraft as
143
+ `context.auth.subject`. Application service lookup must require that subject
144
+ and load only credentials stored under the same subject. Do not fall back to a
145
+ shared environment credential when a subject session is missing.
146
+
147
+ Grant and token revocation use opaque identifiers and token hashes. Raw
148
+ authorization codes, access tokens, and refresh tokens are never stored by the
149
+ provided store contract.
150
+
151
+ ## Security Requirements
152
+
153
+ - Terminate TLS before exposing any endpoint publicly.
154
+ - Keep signing private keys outside source control and rotate keys with an
155
+ overlap period long enough for issued access tokens to expire.
156
+ - Use a durable store implementation with transactional or compare-and-swap
157
+ semantics for one-time consumption and refresh rotation.
158
+ - Keep access-token lifetimes short. The default is five minutes.
159
+ - Set restrictive CSP, `Referrer-Policy: no-referrer`, and `Cache-Control:
160
+ no-store` on application authorization pages.
161
+ - Require exact redirect URI matches. Do not add wildcard or prefix matching.
162
+ - Treat every OAuth subject as a separate security boundary.
163
+ - Encrypt application-owned upstream refresh tokens at rest with a
164
+ production key-management service.
165
+ - Redact authorization headers, cookies, codes, callbacks, and tokens from
166
+ logs and traces.
167
+
168
+ ## Configuration
169
+
170
+ `createOAuthAuthorizationServer(options)` accepts:
171
+
172
+ | Option | Required | Default | Description |
173
+ | --- | --- | --- | --- |
174
+ | `issuer` | yes | none | HTTPS authorization-server issuer. Loopback HTTP is allowed for local development. |
175
+ | `resources` | yes | none | Exact protected resource identifiers accepted through the OAuth `resource` parameter. |
176
+ | `signingKey` | yes | none | Current `ES256` or `RS256` private key, public JWK, and key id. |
177
+ | `additionalPublicJwks` | no | `[]` | Previous public signing keys retained in JWKS during a key-rotation overlap. |
178
+ | `store` | yes | none | Durable `AuthorizationServerStore` implementation. |
179
+ | `interaction` | yes | none | Application-owned browser authorization hook. |
180
+ | `accessTokenTtlSeconds` | no | `300` | Signed access-token lifetime. |
181
+ | `authorizationCodeTtlSeconds` | no | `60` | One-time authorization-code lifetime. |
182
+ | `authorizationTransactionTtlSeconds` | no | `600` | Pending browser interaction lifetime. |
183
+ | `refreshTokenTtlSeconds` | no | `2592000` | Rotating refresh-token lifetime. |
184
+ | `maxRequestBodyBytes` | no | `65536` | Maximum DCR, token, and revocation request body size. |
185
+ | `now` | no | `Date.now` | Clock override for tests. |
186
+ | `randomToken` | no | cryptographic random | Opaque identifier generator override for tests. |
187
+
188
+ ## Environment Variables
189
+
190
+ This package reads no environment variables. Signing keys, durable database
191
+ connections, encryption keys, issuer URLs, and protected resource identifiers
192
+ must be passed explicitly by the application.
@@ -0,0 +1,157 @@
1
+ import { type KeyObject } from "node:crypto";
2
+ import { type JWK } from "jose";
3
+ export interface OAuthClientRecord {
4
+ id: string;
5
+ redirectUris: readonly string[];
6
+ createdAt: number;
7
+ }
8
+ export interface AuthorizationTransactionRecord {
9
+ id: string;
10
+ clientId: string;
11
+ redirectUri: string;
12
+ codeChallenge: string;
13
+ resource: string;
14
+ scopes: readonly string[];
15
+ state?: string;
16
+ createdAt: number;
17
+ expiresAt: number;
18
+ }
19
+ export interface AuthorizationCodeRecord {
20
+ tokenHash: string;
21
+ grantId: string;
22
+ clientId: string;
23
+ subject: string;
24
+ redirectUri: string;
25
+ codeChallenge: string;
26
+ resource: string;
27
+ scopes: readonly string[];
28
+ expiresAt: number;
29
+ }
30
+ export interface AuthorizationGrantRecord {
31
+ id: string;
32
+ clientId: string;
33
+ subject: string;
34
+ resource: string;
35
+ scopes: readonly string[];
36
+ createdAt: number;
37
+ revokedAt?: number;
38
+ }
39
+ export interface RefreshTokenRecord {
40
+ tokenHash: string;
41
+ familyId: string;
42
+ grantId: string;
43
+ clientId: string;
44
+ subject: string;
45
+ resource: string;
46
+ scopes: readonly string[];
47
+ createdAt: number;
48
+ expiresAt: number;
49
+ status: "active" | "rotated" | "revoked";
50
+ }
51
+ export interface AccessTokenRecord {
52
+ tokenHash: string;
53
+ tokenId: string;
54
+ grantId: string;
55
+ subject: string;
56
+ clientId: string;
57
+ resource: string;
58
+ expiresAt: number;
59
+ revokedAt?: number;
60
+ }
61
+ export type RefreshTokenRotationResult = {
62
+ status: "rotated";
63
+ previous: RefreshTokenRecord;
64
+ } | {
65
+ status: "replay";
66
+ } | {
67
+ status: "invalid";
68
+ };
69
+ export interface AuthorizationServerStore {
70
+ putClient(client: OAuthClientRecord): Promise<void>;
71
+ getClient(clientId: string): Promise<OAuthClientRecord | undefined>;
72
+ putAuthorizationTransaction(transaction: AuthorizationTransactionRecord): Promise<void>;
73
+ takeAuthorizationTransaction(transactionId: string): Promise<AuthorizationTransactionRecord | undefined>;
74
+ putAuthorizationCode(code: AuthorizationCodeRecord): Promise<void>;
75
+ takeAuthorizationCode(tokenHash: string): Promise<AuthorizationCodeRecord | undefined>;
76
+ putGrant(grant: AuthorizationGrantRecord): Promise<void>;
77
+ getGrant(grantId: string): Promise<AuthorizationGrantRecord | undefined>;
78
+ putAccessToken(token: AccessTokenRecord): Promise<void>;
79
+ getAccessToken(tokenHash: string): Promise<AccessTokenRecord | undefined>;
80
+ putRefreshToken(token: RefreshTokenRecord): Promise<void>;
81
+ rotateRefreshToken(tokenHash: string, replacementTokenHash: string, now: number, expiresAt: number): Promise<RefreshTokenRotationResult>;
82
+ revokeToken(tokenHash: string, now: number): Promise<void>;
83
+ revokeGrant(grantId: string, now: number): Promise<void>;
84
+ }
85
+ export interface AuthorizationInteractionStartContext {
86
+ request: Request;
87
+ transaction: AuthorizationTransactionRecord;
88
+ }
89
+ export interface AuthorizationInteraction {
90
+ start(context: AuthorizationInteractionStartContext): Promise<Response> | Response;
91
+ }
92
+ export interface OAuthAuthorizationServerSigningKey {
93
+ algorithm: "ES256" | "RS256";
94
+ keyId: string;
95
+ privateKey: KeyObject;
96
+ publicJwk: JWK;
97
+ }
98
+ export interface OAuthAuthorizationServerOptions {
99
+ issuer: string;
100
+ resources: readonly string[];
101
+ signingKey: OAuthAuthorizationServerSigningKey;
102
+ additionalPublicJwks?: readonly JWK[];
103
+ store: AuthorizationServerStore;
104
+ interaction: AuthorizationInteraction;
105
+ accessTokenTtlSeconds?: number;
106
+ authorizationCodeTtlSeconds?: number;
107
+ authorizationTransactionTtlSeconds?: number;
108
+ refreshTokenTtlSeconds?: number;
109
+ maxRequestBodyBytes?: number;
110
+ now?: () => number;
111
+ randomToken?: () => string;
112
+ }
113
+ export interface CompleteAuthorizationInput {
114
+ transactionId: string;
115
+ subject: string;
116
+ scopes?: readonly string[];
117
+ }
118
+ export interface CompleteAuthorizationResult {
119
+ redirectUrl: URL;
120
+ grantId: string;
121
+ }
122
+ export interface AuthorizationInteractionSecurity {
123
+ csrfToken: string;
124
+ state: string;
125
+ nonce: string;
126
+ setCookie: string;
127
+ }
128
+ export interface AuthorizationInteractionSecurityOptions {
129
+ cookieName?: string;
130
+ maxAgeSeconds?: number;
131
+ randomToken?: () => string;
132
+ }
133
+ export interface VerifyAuthorizationInteractionCsrfInput {
134
+ cookieHeader: string | null;
135
+ submittedToken: string;
136
+ cookieName?: string;
137
+ }
138
+ export interface OAuthAuthorizationServer {
139
+ issuer: string;
140
+ handle(request: Request): Promise<Response>;
141
+ completeAuthorization(input: CompleteAuthorizationInput): Promise<CompleteAuthorizationResult>;
142
+ denyAuthorization(transactionId: string, error?: string): Promise<URL>;
143
+ revokeGrant(grantId: string): Promise<void>;
144
+ verifyAccessToken(token: string, resource: string): Promise<VerifiedAuthorizationServerToken>;
145
+ }
146
+ export interface VerifiedAuthorizationServerToken {
147
+ subject: string;
148
+ clientId: string;
149
+ resource: string;
150
+ scopes: readonly string[];
151
+ tokenId: string;
152
+ expiresAt: number;
153
+ }
154
+ export declare function createAuthorizationInteractionSecurity(options?: AuthorizationInteractionSecurityOptions): AuthorizationInteractionSecurity;
155
+ export declare function verifyAuthorizationInteractionCsrf(input: VerifyAuthorizationInteractionCsrfInput): boolean;
156
+ export declare function createInMemoryAuthorizationServerStore(): AuthorizationServerStore;
157
+ export declare function createOAuthAuthorizationServer(options: OAuthAuthorizationServerOptions): OAuthAuthorizationServer;