Files
cgalo5758 0b28a9dc29 Remediate security audit findings
- Replace gorilla/csrf with net/http CrossOriginProtection
- Require valkey-password and add TLS options for session store
- End session at /logout and revoke refresh tokens
- Re-derive identity and roles from provider every five minutes
- Process each Stripe webhook event in its own Temporal workflow
- Give each outbox entry its own workflow with Temporal retries
- Guard against stale Stripe events with provider timestamps
- Derive transport security from base-url scheme
2026-09-09 13:25:43 -05:00

4.6 KiB

error-pages Specification

Purpose

Render styled, chrome-wrapped error pages for navigation requests that resolve to 404 or 500, without leaking internals, while preserving the plain-text error contract for HTMX partials and degrading safely when the error template itself cannot render.

Requirements

Requirement: Navigation error responses render styled pages

The system SHALL render styled, full-page error responses inside the standard page chrome for navigation (non-HTMX) requests that resolve to 404 or 500, and for the authentication flows' refusals whatever their status. The page SHALL show the status and a short human-readable message, and SHALL NOT expose internal details (panic values, stack traces, file paths). The styled 404 SHALL render for unauthenticated visitors too: a request for a path no route matches SHALL receive the 404 page rather than a redirect into the identity provider's sign-in flow, so a mistyped or stale URL is diagnosed as "not found" instead of misread as "signed out". Routes that do exist but require authentication keep their normal redirect-to-login behavior.

Scenario: Unknown route renders a styled 404

  • WHEN a browser issues a GET navigation request for a path no route matches
  • THEN the response SHALL have status 404
  • AND the body SHALL be the styled error page rendered inside the standard page chrome

Scenario: Anonymous visitor to an unknown route gets the 404, not a login form

  • WHEN an unauthenticated browser requests a path no route matches
  • THEN the response SHALL be the styled 404 page with status 404
  • AND the visitor SHALL NOT be redirected to the identity provider's sign-in page

Scenario: Anonymous visitor to a real protected route still reaches login

  • WHEN an unauthenticated browser requests a path that matches an authenticated route
  • THEN the normal authentication redirect applies

Scenario: Panic renders a styled 500 without leaking internals

  • WHEN a handler panics while serving a navigation request
  • THEN the recovery middleware SHALL respond with status 500 and the styled error page
  • AND the response body SHALL NOT contain the panic value or a stack trace

Scenario: A refused sign-in renders the styled page

  • WHEN a person's sign-in callback is refused because its state is stale
  • THEN the styled error page SHALL be rendered with the unchanged 400 status
  • AND it SHALL offer a route back into sign-in

Requirement: Error rendering degrades safely

Error-page rendering SHALL preserve the existing plain-text error contract for HTMX partial requests, and SHALL fall back to a plain-text error when the error template itself cannot render.

Scenario: HTMX partial requests keep text errors

  • WHEN a request carrying HX-Request: true resolves to an error status
  • THEN the response SHALL be the existing plain-text error consumed by the client-side error toast, not a full HTML page

Scenario: Template failure falls back to plain text

  • WHEN rendering the error template itself fails
  • THEN the system SHALL respond with a plain-text error carrying the same status
  • AND SHALL NOT panic or emit a partially rendered page

Requirement: The error page offers exactly one way out

The styled error page SHALL carry exactly one action, and that action SHALL name a destination the person can actually reach. The default SHALL be the dashboard. A page rendered for a refused authentication flow SHALL instead offer that flow, because the dashboard is the page the person could not reach.

The heading SHALL default to the status and its standard text, and a caller MAY replace it with a heading that names the failure, for a status line that tells the person nothing (a sign-in that expired is a 400).

The error page SHALL NOT render a location trail. The trail is rooted at the surface, the page is reachable without a session, and the page is not at a location: it is what came back instead of one. The single action is the whole navigation the page offers.

Scenario: An ordinary error page offers the dashboard

  • WHEN a navigation request resolves to a styled 404 or 500
  • THEN the page's action SHALL lead to the dashboard

Scenario: No location trail on an error page

  • WHEN either the ordinary error page or an authentication failure page is rendered
  • THEN the page SHALL carry no location trail

Scenario: A refused sign-in offers sign-in

  • WHEN the styled page is rendered for a refused sign-in
  • THEN the page's action SHALL lead to sign-in
  • AND the heading SHALL name the failure rather than the status line