fix(auth): /api/me answers 200 when logged out (no console error)

The logged-out landing probed /api/me, which 401'd, and the browser logs every
non-2xx fetch as a console error regardless of how the app handles it. The
bootstrap probe now returns 200 with {authenticated:false} via a new
optional_current_user dependency; api.me() maps that to null. The render gate
treats no-data as 'signed out' -> the landing, and a thrown error as a real
network/5xx failure. Other protected endpoints still 401, so mid-session expiry
is still caught by the global handler. Lighthouse (dev): Best Practices 96->100.
This commit is contained in:
npeter83 2026-07-04 18:17:24 +02:00
parent 2a8d5c0a1e
commit 603cc9854c
4 changed files with 36 additions and 9 deletions

View file

@ -4,7 +4,6 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
api,
getActiveAccount,
HttpError,
setActiveAccount,
setUnauthorizedHandler,
type FeedFilters,
@ -451,8 +450,9 @@ export default function App() {
}, [meQuery.data?.id]); // eslint-disable-line react-hooks/exhaustive-deps
// Any request that 401s means the session ended server-side. If we were signed in (cached
// `me` exists), reload to the login page at once (option 2 — also covers any click that hits
// the API). Guarded on cached `me` so the public login page's own /api/me 401 can't loop.
// `me` is a user object), reload to the login page at once (also covers any click that hits
// the API). Guarded on a cached user so a stray 401 while logged out (cached `me` is null)
// can't loop the public landing.
useEffect(() => {
setUnauthorizedHandler(() => {
if (queryClient.getQueryData(["me"])) {
@ -646,14 +646,15 @@ export default function App() {
return (
<div className="min-h-screen grid place-items-center text-muted">{t("common.loading")}</div>
);
if (meQuery.error instanceof HttpError && meQuery.error.status === 401)
return <Welcome />;
// /api/me answers 200 always now (null body = logged out), so a thrown error here is a real
// network/5xx failure, and no data means "not signed in" → the public landing.
if (meQuery.error)
return (
<div className="min-h-screen grid place-items-center text-muted">
{t("common.somethingWrong")}
</div>
);
if (!meQuery.data) return <Welcome />;
return (
<div className="h-screen flex bg-bg text-fg">