§8 review convergence (todo §8); re-ran the architecture + product reviewers to convergence — 5 rounds, until both returned zero new actionable findings. Fixed across rounds 1-4 (tests-first): bounded every outbound Ory fetch with a timeout (src/fetch-timeout.ts withTimeout + ORY_TIMEOUT_SEC default 5, incl. the http JWKS fetch) so a hung Ory can't park a request handler; anonymous on a permission-gated plugin route now 303→/login (was a dead-end 403; signed-in-without-role still 403); an already-signed-in user is sent home from /login + /registration; the onRequest hook short-circuit now sets the fresh CSRF cookie; admin-users malformed :id → 404 (was 500) via safeDecode; parseJwks validates key element shape (fails loud at load); removed the dead COOKIE_SECRET (loaded + enforced + documented but never read); documented HYDRA_ADMIN_URL; admin recovery shows the code + links to the public /recovery instead of the browser-unreachable admin-API link; reference-plugin breadcrumb-label + pagination/datetime README notes; corrected the contract doc to not over-promise a post-login "retry". Declined: unconditional base-ctx chrome (would build the menu per request, regressing the lazy hot path). Deferred → §9: return_to-preservation for deep-link login. Stability-reviewer on the cumulative diff: APPROVE, no Critical/High (addressed its Low nits). typecheck + 310 units + the full scripts/ci.sh gate (visual 9 · auth 1 · oauth 2 · full 6) green.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { createApp } from "./app.ts";
|
||||
import { loadConfig } from "./config.ts";
|
||||
import { discoverPlugins } from "./discovery.ts";
|
||||
import { withTimeout } from "./fetch-timeout.ts";
|
||||
import { runBootHooks } from "./hooks.ts";
|
||||
import { createHydraAdmin } from "./hydra-admin.ts";
|
||||
import { createJwksProvider } from "./jwks.ts";
|
||||
@@ -11,15 +12,17 @@ import { loadMenuConfig } from "./menu-config.ts";
|
||||
|
||||
const config = loadConfig(); // validates the env (incl. enforced secrets) — fails loud at boot
|
||||
const menu = await loadMenuConfig(); // config/menu.ts override + branding — fails loud if malformed
|
||||
// Every outbound Ory call is bounded so a hung/silent Ory can't park a request handler forever.
|
||||
const oryFetch = withTimeout(fetch, config.oryTimeoutSec * 1000);
|
||||
// Ory clients for the themed self-service routes + login completion (§4).
|
||||
const kratos = createKratosPublic({ baseUrl: config.kratosPublicUrl });
|
||||
const kratosAdmin = createKratosAdmin({ baseUrl: config.kratosAdminUrl });
|
||||
const keto = createKetoClient({ readUrl: config.ketoReadUrl, writeUrl: config.ketoWriteUrl });
|
||||
const kratos = createKratosPublic({ baseUrl: config.kratosPublicUrl, fetchImpl: oryFetch });
|
||||
const kratosAdmin = createKratosAdmin({ baseUrl: config.kratosAdminUrl, fetchImpl: oryFetch });
|
||||
const keto = createKetoClient({ fetchImpl: oryFetch, readUrl: config.ketoReadUrl, writeUrl: config.ketoWriteUrl });
|
||||
// Hydra admin client for the OAuth2 login/consent challenge handshake (§6).
|
||||
const hydra = createHydraAdmin({ baseUrl: config.hydraAdminUrl });
|
||||
const hydra = createHydraAdmin({ baseUrl: config.hydraAdminUrl, fetchImpl: oryFetch });
|
||||
// Session-JWT verify key: primed at boot from the configured JWKS (file mount, base64 inline,
|
||||
// or fetched http), then served from cache with TTL refresh + rotation-on-miss (§4).
|
||||
const jwks = await createJwksProvider(config.jwksUrl);
|
||||
const jwks = await createJwksProvider(config.jwksUrl, { fetchImpl: oryFetch }); // bound an http JWKS fetch too
|
||||
|
||||
const plugins = await discoverPlugins(); // scans plugins/, validates — fails loud on a bad plugin
|
||||
console.log(`Discovered ${plugins.length} plugin(s)${plugins.length ? `: ${plugins.map((p) => p.id).join(", ")}` : ""}`);
|
||||
|
||||
Reference in New Issue
Block a user