fix(404): stop returning an empty-bodied 404 from the account pages and the auth guard #242

Sammanfogat
supernaut sammanfogade 2 incheckningar från work/139 in i main 2026-09-21 08:22:40 +00:00
Ägare

Follow-up to #134, which fixed the same bug shape in the [slug] routes. new Response(null, { status: 404 }) sends a null body, so the browser gets a 404 with nothing to render.

account.astro and en/account.astro are mechanical: the same Astro.rewrite(getRelativeLocaleUrl(lang, "/404")) the slug routes use.

guard.ts is the awkward half. It returns bare Response objects from a library function, so it has no Astro context and no language. The guard now signals instead of rendering: AdminGuard and UserGuard are a three-way union of ok, forbidden (unchanged, still an embedded 403) and not-configured (no Response). One helper, notConfiguredRedirect(lang), builds the redirect, and every caller uses it. Threading Astro context into the library would have been the larger change.

Every caller of requireUser and requireAdmin was checked before editing. requireAdmin has no callers at all, which is pre-existing dead code and left alone. All four requireUser callers are full browser navigations, form POSTs or an emailed GET link, so the empty body was user-facing in each. Three of them only knew lang from parsed form data, so request.formData() moved above the guard call. Only body parsing moved. No privileged work happens before the auth gate.

login.ts and callback.ts had the same bug and the same consequence. They establish a session rather than consume one, so they call notConfiguredRedirect directly. No third mechanism.

Deliberately left alone:

  • src/pages/api/signup.ts:76 and the two captcha endpoints. Those are fetch calls from client JavaScript, where an empty body is correct.
  • src/lib/account-page.ts:23. Unreachable now that the page-level gate on account.astro intercepts first.

Tests: src/lib/auth/guard.test.ts covers the not-configured branch of both guards, the redirect target per language, and both newly fixed routes.

Verified: pnpm lint, pnpm check, pnpm test (364 passed). grep -rn 'Response(null' src/ leaves only the four out-of-scope call sites above and two comments referencing the old pattern.

Closes #139

Follow-up to #134, which fixed the same bug shape in the `[slug]` routes. `new Response(null, { status: 404 })` sends a null body, so the browser gets a 404 with nothing to render. `account.astro` and `en/account.astro` are mechanical: the same `Astro.rewrite(getRelativeLocaleUrl(lang, "/404"))` the slug routes use. `guard.ts` is the awkward half. It returns bare `Response` objects from a library function, so it has no `Astro` context and no language. The guard now signals instead of rendering: `AdminGuard` and `UserGuard` are a three-way union of `ok`, `forbidden` (unchanged, still an embedded 403) and `not-configured` (no Response). One helper, `notConfiguredRedirect(lang)`, builds the redirect, and every caller uses it. Threading Astro context into the library would have been the larger change. Every caller of `requireUser` and `requireAdmin` was checked before editing. `requireAdmin` has no callers at all, which is pre-existing dead code and left alone. All four `requireUser` callers are full browser navigations, form POSTs or an emailed GET link, so the empty body was user-facing in each. Three of them only knew `lang` from parsed form data, so `request.formData()` moved above the guard call. Only body parsing moved. No privileged work happens before the auth gate. `login.ts` and `callback.ts` had the same bug and the same consequence. They establish a session rather than consume one, so they call `notConfiguredRedirect` directly. No third mechanism. Deliberately left alone: - `src/pages/api/signup.ts:76` and the two captcha endpoints. Those are fetch calls from client JavaScript, where an empty body is correct. - `src/lib/account-page.ts:23`. Unreachable now that the page-level gate on `account.astro` intercepts first. Tests: `src/lib/auth/guard.test.ts` covers the not-configured branch of both guards, the redirect target per language, and both newly fixed routes. Verified: `pnpm lint`, `pnpm check`, `pnpm test` (364 passed). `grep -rn 'Response(null' src/` leaves only the four out-of-scope call sites above and two comments referencing the old pattern. Closes #139
supernaut lade till 2 incheckningar 2026-09-20 22:32:02 +00:00
new Response(null, { status: 404 }) sends a null body, so the browser
renders nothing. account.astro/en/account.astro now rewrite to /404 like
the [slug] routes (#134). guard.ts has no Astro context, so it signals
"not-configured" instead of embedding a Response, and each caller turns
that into a redirect to the localized branded 404 page.
fix(404): fix the two remaining empty-bodied 404s in the auth flow
Alla kontroller lyckades
ci / ci (pull_request) Successful in 1m27s
eadba0eb2d
login.ts and callback.ts are full top-level navigations (start/finish
the Kanidm redirect), so the same empty-body 404 bug applied to them.
Both route through notConfiguredRedirect(lang) like the account pages.
supernaut tvångsskickade work/139 från eadba0eb2d
Alla kontroller lyckades
ci / ci (pull_request) Successful in 1m27s
till 3376aec0ce
Alla kontroller lyckades
ci / ci (pull_request) Successful in 1m30s
2026-09-21 08:16:40 +00:00
Jämför
supernaut sammanfogade incheckning 3a09c6c536 till main 2026-09-21 08:22:40 +00:00
supernaut tog bort grenen work/139 2026-09-21 08:22:40 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-web!242
Ingen beskrivning angiven.