http

16 modules

  • http/auth_shape.ts

    Canonical four-axis auth shape for action specs and route specs.

    Replaces the discriminated 'public' | 'authenticated' | 'keeper' | {role} literal that conflated authentication, account resolution, actor resolution, and authorization into a single value. The flat record names each axis the dispatcher actually walks:

    - account โ€” does the dispatcher require / load / skip the account? - actor โ€” does the dispatcher require / load / skip the acting actor? - roles โ€” disjunction of permitted roles (any-of); absent = no role check. - credential_types โ€” restricts the credential channel (e.g. daemon_token); absent = any authenticated credential.

    The same shape governs both ActionSpec.auth (in actions/action_spec.ts) and RouteSpec.auth (in http/route_spec.ts). The canonical schema lives here in http/ because that preserves the existing actions โ†’ http dependency direction (and error_schemas.ts / surface.ts consume the type).

    Registry-time invariants 1, 3, and 4 live on the schema's .superRefine so any spec that fails them throws at the Zod parse boundary. Invariant 2 (the `actor !== 'none' โŸบ input or query declares acting?: ActingActor` biconditional) needs introspection of the spec's input/query schemas, so it is enforced at registration time inside the dispatcher loops (apply_route_specs, create_rpc_endpoint, register_action_ws) via the assert_route_auth_acting_biconditional helper exported below.

  • http/common_routes.ts

    Common route spec factories for fuz_app consumers.

    Generic HTTP route factories with no auth-domain dependencies. Auth-aware route factories (account status) live in auth/account_routes.ts.

  • http/db_routes.ts

    API route specs for database administration.

    Generic PostgreSQL table browser using information_schema. Provides: list tables, view columns/rows (paginated), delete rows by PK, health check.

  • http/error_schemas.ts

    Standard error response schemas and error code constants for fuz_app routes.

    Defines ERROR_* constants (single source of truth for machine-parseable error codes), Zod schemas for error response shapes, a type for error schema maps, and derive_error_schemas to auto-populate middleware-produced errors from a route's auth requirement and input schema.

    Used in RouteSpec.errors and MiddlewareSpec.errors for surface introspection and DEV-mode validation.

  • http/ip_canonical.ts

    IP address canonicalization โ€” collapse equivalent string forms into a single key per RFC 5952 (IPv6) plus the dotted form for IPv4-mapped IPv6 addresses.

    Why this exists. Without canonicalization, the four representations ::1, ::01, ::0001, and 0:0:0:0:0:0:0:1 are the same IPv6 address but produce four distinct strings โ€” so an attacker rotating equivalent forms behind a trusted-passthrough proxy could defeat per-IP rate limiting (each form gets a fresh bucket) and pollute audit_log.ip forensics. The collision can extend to IPv4-mapped IPv6 forms (::ffff:127.0.0.1 vs 0:0:0:0:0:ffff:7f00:1 vs the bare 127.0.0.1) โ€” three keys for one address.

    Canonicalization runs through {@link canonicalize_ip} which:

    1. Lowercases and char-set filters (IP_LITERAL_CHARS) โ€” non-IP strings ('unknown', 'attacker:controlled', '::1\n') pass through unchanged so downstream strict validators can still reject them. 2. Parses via Hono's convertIPv*ToBinary family. 3. Re-emits the canonical RFC 5952 string (lowercase hex, longest-zero-run compressed, IPv4-mapped emitted in the dotted form mandated by RFC 5952 ยง5). 4. Strips the ::ffff: prefix from dotted IPv4-mapped forms so the bucket collapses to plain IPv4 โ€” the strip moves AFTER canonicalization because the dotted form is the only form the strip can recognize symmetrically.

    Mirrors zzz_server::proxy::normalize_ip (landed 2026-05-16) which uses the same parse-then-canonicalize-then-strip ordering for the same rate-limit-key-poisoning surface.

  • http/jsonrpc_errors.ts

    JSON-RPC error infrastructure for fuz_app routes.

    Provides error types, named constructors, and HTTP status mapping for the throw/catch error pattern used by apply_route_specs. Core error codes (5 standard + 10 general application). Domain-specific codes stay in consumers โ€” add by casting as JsonrpcErrorCode.

    JsonrpcErrorCode and JsonrpcErrorObject types are Zod-inferred from http/jsonrpc.ts โ€” this module re-uses those as the single source of truth.

    Complementary to http/error_schemas.ts: that module is declarative (Zod schemas for surface introspection), this one is runtime (throw + catch + map).

  • http/jsonrpc_helpers.ts

    JSON-RPC message builders, type guards, and converters.

    Used by the SAES runtime (ActionEvent, ActionPeer, transports) and the RPC endpoint dispatcher. Complements http/jsonrpc.ts (schemas) and http/jsonrpc_errors.ts (error infrastructure).

  • http/jsonrpc.ts

    JSON-RPC 2.0 envelope schemas for RPC dispatch and SAES transport.

    Params are object-only following MCP (no positional arrays); per-action spec.input narrows further. Result is the full JSON-RPC valid value space per spec ยง5 ("determined by the method invoked"): object, array, string, number, boolean, or null โ€” the per-action spec.output is the actual contract. The envelope-level loose-object-only constraint inherited from MCP would reject any action with output: z.null() / z.string() / etc. on the wire, so we relax it here while keeping MCP-superset shape on params + _meta.

    MCP _meta types (JsonrpcMcpMeta, JsonrpcRequestParamsMeta) are exported as building blocks for per-action schemas but are NOT validated at the envelope level โ€” _meta content validation belongs in per-action schemas where it produces the correct error code (invalid_params, not invalid_request).

    @source https://github.com/modelcontextprotocol/typescript-sdk @see https://www.jsonrpc.org/specification

  • http/middleware_spec.ts

    Middleware spec type โ€” named middleware layer definition.

    Separated from http/route_spec.ts so middleware modules can import this type without creating an upward dependency on routes.

  • http/origin.ts

    Request source verification middleware for API protection.

    Verifies requests are coming from expected origins/referers. CSRF protection is provided by SameSite: strict on session cookies (see auth/session_middleware.ts). This module provides origin allowlisting for locally-running services โ€” preventing untrusted websites from making requests as the user browses the web.

  • http/pending_effects.ts

    Two-queue side-effect machinery for request handlers.

    Handlers register fire-and-forget work in one of two queues, distinguished by their timing contract:

    - pending_effects: Array<Promise<void>> โ€” eager. Producers push pool writes that are already in flight (audit emits, session-touch UPDATE, api-token usage tracking). The pool write is rollback-resilient by virtue of running outside the request transaction; pushing the in-flight handle lets test mode (await_pending_effects: true) await it. - post_commit_effects: Array<() => void | Promise<void>> โ€” deferred. Producers go through emit_after_commit(ctx, fn); the flush middleware is the only site that ever invokes the thunk, and it does so after the request handler (and its wrapping db.transaction) returns. Used for WS sends and any work that must observe a committed transaction.

    The split exists because the two shapes encode different contracts: eager pushers are saying "wait for this work that's already started"; thunk pushers are saying "run this after the handler returns." Burying both behind one Array<PendingEffect> made c.var.pending_effects.push(x) ambiguous at the call site. With separate queues, the field name is the contract.

    Both RouteContext (HTTP routes) and ActionContext (RPC + WS actions) carry both queues by convention, so this module stays in http/ (every transport depends on it).

  • http/proxy.ts

    Trusted proxy configuration and middleware.

    Resolves the client IP from X-Forwarded-For only when the TCP connection originates from a configured trusted proxy. Without this middleware, get_client_ip returns 'unknown'.

  • http/route_spec.ts

    Introspectable route spec system for Hono apps.

    Routes are defined as data (method, path, auth, input/output schemas, handler), then applied to Hono. The attack surface is generated from the specs โ€” always accurate, always complete.

    Input/output schemas align with SAES ActionSpec conventions: - input: Zod schema for the request body (z.null() for no body) - output: Zod schema for the success response body - z.strictObject() for inputs (reject unknown keys)

  • http/schema_helpers.ts

    Shared pure helpers for schema introspection and middleware matching.

    Used by both http/route_spec.ts (input validation) and http/surface.ts (attack surface generation). Extracted to avoid circular dependencies between routes and middleware.

  • http/surface_query.ts

    Pure query functions over AppSurface data.

    Usable in tests, the adversarial auth runner, and future surface explorer UI. Replaces duplicated inline .filter() patterns.

    Categorical filters (filter_authenticated_routes, filter_role_routes, filter_keeper_routes) group the new flat-record RouteAuth shape into the legacy categorical buckets ('authenticated', 'role', 'keeper') for adversarial test runners and the surface explorer. The buckets are derived views over the four axes (account, actor, roles, credential_types) โ€” see http/auth_shape.ts for the canonical shape.

  • http/surface.ts

    App surface generation โ€” JSON-serializable attack surface from route and middleware specs.

    Pure schema helpers (is_null_schema, schema_to_surface, middleware_applies, merge_error_schemas) live in http/schema_helpers.ts.