§9 whole-project arch+product review pass (todo §9); ran systems-architect + product-owner on the whole project (no Critical/High — a converged scaffold) and addressed the in-scope §9 customer-facing/security findings. (1) return_to deep-link login, open-redirect-safe: a gated request hit while signed out (plugin-route gate, requireSession, requireAdmin) bounces to /login?return_to=<host-relative path> via new loginRedirect(ctx) (GET/HEAD, skips /); /login bakes it into the Kratos flow — a host-relative target is wrapped through <origin>/auth/complete?return_to=<path> so the JWT mints before landing, an absolute target (§6 OAuth2 login challenge) passes to Kratos as-is; /auth/complete redirects to the requested page. (2) safeUrl()+localPath() in new pure src/safe-url.ts: safeUrl sanitises an untrusted href/src to relative-or-http(s) (else "#"), exported via plugin-api.ts (closes the contract's "planned for §9" pointer); localPath is the host-relative redirect-allowlist guard for return_to, re-checked at both /login and /auth/complete. (3) honest 503 on Ory-unreachable sign-in (views/503.ejs) instead of the misattributed catch-all 500; expired-flow 4xx still restarts. Tests-first throughout; stability-reviewer APPROVE (addressed its Medium — scoped the 503 catch so a template bug hits the 500 with a stack, not a 503). typecheck + 339 units + full scripts/ci.sh gate green. Deferred with justification: the app.ts route-table refactor (standalone change + §10 prereq), mock dashboard + public-page blessing (§10 lines 139/140), success-flash (known).
This commit is contained in:
@@ -13,6 +13,9 @@ export { can, check, GuardError, requireSession } from "./guards.ts";
|
||||
export { parseListQuery } from "./list-query.ts";
|
||||
export { readFormBody } from "./body.ts";
|
||||
export { CSRF_FIELD } from "./csrf.ts";
|
||||
// Sanitise an untrusted URL (upstream/user data) before rendering it in an href/src — partials
|
||||
// escape text but not URL schemes, so a `javascript:`/`data:` URL would be live XSS (see docs).
|
||||
export { safeUrl } from "./safe-url.ts";
|
||||
// Observability (§9): `ctx.log` (RequestContext) is the request logger; `tracedFetch` is a drop-in
|
||||
// `fetch` a plugin uses for upstream calls so they join the request's trace (client span + traceparent).
|
||||
// The `Log` class is exported so a plugin can type/construct one (e.g. `new Log("none")` in a test).
|
||||
|
||||
Reference in New Issue
Block a user