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:
parent
2a8d5c0a1e
commit
603cc9854c
4 changed files with 36 additions and 9 deletions
|
|
@ -253,8 +253,9 @@ interface ReqConfig {
|
|||
|
||||
// Set by the app shell. Invoked whenever any request returns 401 so a session that ended
|
||||
// server-side (account suspended/deleted while the tab was open) can drop the user to the login
|
||||
// page. The handler itself guards against firing when we were never signed in (public pages
|
||||
// legitimately 401 on /api/me), so it's safe to call for every 401.
|
||||
// page. The handler itself guards against firing when we were never signed in, so it's safe to
|
||||
// call for every 401. (The bootstrap /api/me probe no longer 401s — it returns 200 with a null
|
||||
// user when logged out — but other protected endpoints still do.)
|
||||
let onUnauthorized: (() => void) | null = null;
|
||||
export function setUnauthorizedHandler(fn: (() => void) | null): void {
|
||||
onUnauthorized = fn;
|
||||
|
|
@ -755,7 +756,13 @@ export interface AdminDownloadQuota {
|
|||
}
|
||||
|
||||
export const api = {
|
||||
me: (): Promise<Me> => req("/api/me"),
|
||||
// Bootstrap probe: 200 always. Returns the user when signed in, or null when logged out
|
||||
// (the endpoint answers `{authenticated:false}` rather than 401, so the public landing never
|
||||
// logs a failed request to the console). React Query treats the null as data, not an error.
|
||||
me: async (): Promise<Me | null> => {
|
||||
const r = await req("/api/me");
|
||||
return r && r.authenticated ? (r as Me) : null;
|
||||
},
|
||||
accounts: (): Promise<Account[]> => req("/api/me/accounts"),
|
||||
deleteAccount: (): Promise<{ deleted: boolean }> =>
|
||||
req("/api/me/account", { method: "DELETE" }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue