mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-08 11:01:35 +00:00
src/auth/oauth.ts configures @cloudflare/workers-oauth-provider: /mcp and legacy /sse protected; /authorize (ours), /token and /register (library); CIMD enabled (with global_fetch_strictly_public in wrangler.toml); scopes read:account/read:jobs/read:catalog; 1h access, 30d idle refresh; error logging by code/category only. `resource` and `authorization_servers` are derived per request origin so one build serves every environment; production sets workers_dev = false so its only origin is canonical. src/index.ts checks the environment invariant first (a misconfigured deploy fails even /token), then hands off to the provider. src/runtime.ts holds the memoized config+app. src/auth/authorize.ts validates the OAuth request via parseAuthRequest, renders unknown-client errors locally and client-validated errors as redirects, and stops at 501 — it never auto-approves. src/mcp/handler.ts is a 501 stub reachable only with a valid token. Tests (10): 401 + resource_metadata challenge on /mcp and /sse, bogus bearer → 401 not 500, health still reachable; PRM at root and /mcp paths with derived resource and this origin as issuer; AS metadata with S256, CIMD flag, "none" auth method, iss support, registration and revocation endpoints; /authorize 400 locally on malformed and unknown client, 201 DCR then 501 with no redirect. pnpm check: typecheck, eslint, prettier, 87 tests passing. Claude-Session: https://claude.ai/code/session_01H3gfN2NCx3hBXSrZXYHUQ3
31 lines
935 B
TypeScript
31 lines
935 B
TypeScript
import type { Hono } from "hono";
|
|
|
|
import { createApp } from "./app";
|
|
import { type Config, ConfigError, loadConfig } from "./config";
|
|
|
|
/**
|
|
* Per-isolate state built once from the bindings. If the bindings violate the environment
|
|
* invariant, the failure is memoized and rethrown on every call so a misconfigured deploy
|
|
* can never serve a single successful request.
|
|
*/
|
|
export interface Runtime {
|
|
readonly config: Config;
|
|
readonly app: Hono<{ Bindings: Cloudflare.Env }>;
|
|
}
|
|
|
|
let cachedRuntime: Runtime | undefined;
|
|
let cachedFailure: ConfigError | undefined;
|
|
|
|
export function getRuntime(env: unknown): Runtime {
|
|
if (cachedRuntime) return cachedRuntime;
|
|
if (cachedFailure) throw cachedFailure;
|
|
try {
|
|
const config = loadConfig(env);
|
|
cachedRuntime = { config, app: createApp(config) };
|
|
return cachedRuntime;
|
|
} catch (error) {
|
|
if (error instanceof ConfigError) cachedFailure = error;
|
|
throw error;
|
|
}
|
|
}
|