fix: oidc hardening — sid-less consent refused, rotation race closed, iss on errors, logout honesty

From the logic audit:
- consent rejects sid-less bearers and requires a LIVE hub session
  (sessionAlive) before minting codes — a logged-out bearer can no longer
  mint downstream tokens inside its TTL
- refresh rotation race closed: consume returns whether THIS call won;
  the loser revokes the family (reuse detection now holds under
  concurrency)
- error redirects carry iss (RFC 9207) on error responses too
- logout awaits the revocation and no longer returns ok for missing or
  forged bearers
This commit is contained in:
glass beadian 2026-10-18 11:54:59 +00:00
parent e486e62220
commit 74f0802f1a
10 changed files with 355 additions and 24 deletions

View file

@ -161,11 +161,14 @@ export function validateAuthorize(params: AuthorizeParams): AuthorizeValidation
}
/** `redirectUri?error=…&error_description=…&state=…` for a redirectable failure. */
export function errorRedirect(redirectUri: string, state: string | null, error: string, description: string): string {
export function errorRedirect(redirectUri: string, state: string | null, error: string, description: string, issuer?: string): string {
const url = new URL(redirectUri);
url.searchParams.set("error", error);
url.searchParams.set("error_description", description);
if (state !== null) url.searchParams.set("state", state);
// RFC 9207 §2: iss is required on error responses too when the server
// advertises authorization_response_iss_parameter_supported.
if (issuer !== undefined) url.searchParams.set("iss", issuer);
return url.toString();
}