§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:
@@ -26,6 +26,12 @@ test("loadJwks reads a file:// set and a base64:// inline set, rejects http", ()
|
||||
assert.equal(loadJwks(`base64://${Buffer.from(inline).toString("base64")}`)[0]?.kid, "inline");
|
||||
|
||||
assert.throws(() => loadJwks("http://keto:4466/keys"), /unsupported/);
|
||||
|
||||
// Malformed sets fail loud at load, not as an opaque crypto error at verify time.
|
||||
const b64 = (o: unknown) => `base64://${Buffer.from(JSON.stringify(o)).toString("base64")}`;
|
||||
assert.throws(() => loadJwks(b64({})), /missing `keys`/);
|
||||
assert.throws(() => loadJwks(b64({ keys: ["nope"] })), /string `kty`/); // a non-object key
|
||||
assert.throws(() => loadJwks(b64({ keys: [{ kid: "x" }] })), /string `kty`/); // key missing kty
|
||||
});
|
||||
|
||||
test("cachingJwks caches within TTL, reloads after expiry", async () => {
|
||||
|
||||
Reference in New Issue
Block a user