customer stayed in React state, so the header kept rendering "My Account" instead of "Log in" and "Sign up". A page reload appeared to fix it — fetchMe() then returns null — which is why the symptom would have looked intermittent rather than consistently broken.
The cart badge had the same root cause: CartContext only clears its items once customer becomes null, so the old count stayed on screen too.
A failed logout leaves the session cookie valid, so the UI would report success while the customer was still signed in — and the next reload would silently sign them back in. Same class as the false "Item added" in #23.
Changes
Change
Why
logout() moved onto CustomerAuthContext, clearing customer directly
The header only updates if the context knows. Clearing directly rather than calling refresh() avoids a window where the session is gone but the UI still shows the customer signed in
logoutCustomer rejects on a non-OK response
A failed logout must not look like a successful one. Not routed through the existing handle() helper because the endpoint answers 204 with no body, which handle() would fail to parse
Account page reports the failure and stays put
Better than navigating home while still authenticated
navigate('/', { replace: true })
Back no longer returns to the account page, which would only bounce to /login now the session is gone
Cart badge — no change needed
Clears itself through the existing effect once customer is null
Tests
Four e2e tests added to auth.spec.ts, all written before the fix and confirmed failing first:
Logging out lands on / with "Log in" and "Sign up" visible and "My Account" gone
The logged-out header survives a reload — proves the session was really destroyed rather than the header merely repainted from stale client state
The account page is not left on the back stack
A failed logout reports the error and stays on the account page
Full suite: 47 backend unit, 33 e2e, stable over two consecutive runs. tsc --noEmit and npm run build clean.
Not changed
Items already reserved in a cart stay reserved until the normal expiry sweep — logging out does not release them. That is existing behaviour and outside what this issue asks for; worth its own issue if it should change.
## Fixed
Branch `fix/logout-customer-reset`, one commit, not yet pushed.
### Cause
`handleLogout` destroyed the server session and navigated home, but never told `CustomerAuthContext`:
```ts
async function handleLogout() {
await logoutCustomer();
navigate('/');
}
```
`customer` stayed in React state, so the header kept rendering "My Account" instead of "Log in" and "Sign up". A page reload appeared to fix it — `fetchMe()` then returns `null` — which is why the symptom would have looked intermittent rather than consistently broken.
The cart badge had the same root cause: `CartContext` only clears its items once `customer` becomes `null`, so the old count stayed on screen too.
### A second defect found alongside it
`logoutCustomer` ignored `res.ok`:
```ts
export function logoutCustomer(): Promise<void> {
return fetch('/api/customers/logout', { method: 'POST' }).then(() => undefined);
}
```
A failed logout leaves the session cookie valid, so the UI would report success while the customer was still signed in — and the next reload would silently sign them back in. Same class as the false "Item added" in #23.
### Changes
| Change | Why |
| --- | --- |
| `logout()` moved onto `CustomerAuthContext`, clearing `customer` directly | The header only updates if the context knows. Clearing directly rather than calling `refresh()` avoids a window where the session is gone but the UI still shows the customer signed in |
| `logoutCustomer` rejects on a non-OK response | A failed logout must not look like a successful one. Not routed through the existing `handle()` helper because the endpoint answers `204` with no body, which `handle()` would fail to parse |
| Account page reports the failure and stays put | Better than navigating home while still authenticated |
| `navigate('/', { replace: true })` | Back no longer returns to the account page, which would only bounce to `/login` now the session is gone |
| Cart badge — no change needed | Clears itself through the existing effect once `customer` is `null` |
### Tests
Four e2e tests added to `auth.spec.ts`, all written before the fix and confirmed failing first:
- Logging out lands on `/` with "Log in" and "Sign up" visible and "My Account" gone
- The logged-out header survives a reload — proves the session was really destroyed rather than the header merely repainted from stale client state
- The account page is not left on the back stack
- A failed logout reports the error and stays on the account page
Full suite: 47 backend unit, 33 e2e, stable over two consecutive runs. `tsc --noEmit` and `npm run build` clean.
### Not changed
Items already reserved in a cart stay reserved until the normal expiry sweep — logging out does not release them. That is existing behaviour and outside what this issue asks for; worth its own issue if it should change.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
As a customer, when I log off I should be redirected to the home page, and the
Log InandSign Upshould be reset.Fixed
Branch
fix/logout-customer-reset, one commit, not yet pushed.Cause
handleLogoutdestroyed the server session and navigated home, but never toldCustomerAuthContext:customerstayed in React state, so the header kept rendering "My Account" instead of "Log in" and "Sign up". A page reload appeared to fix it —fetchMe()then returnsnull— which is why the symptom would have looked intermittent rather than consistently broken.The cart badge had the same root cause:
CartContextonly clears its items oncecustomerbecomesnull, so the old count stayed on screen too.A second defect found alongside it
logoutCustomerignoredres.ok:A failed logout leaves the session cookie valid, so the UI would report success while the customer was still signed in — and the next reload would silently sign them back in. Same class as the false "Item added" in #23.
Changes
logout()moved ontoCustomerAuthContext, clearingcustomerdirectlyrefresh()avoids a window where the session is gone but the UI still shows the customer signed inlogoutCustomerrejects on a non-OK responsehandle()helper because the endpoint answers204with no body, whichhandle()would fail to parsenavigate('/', { replace: true })/loginnow the session is gonecustomerisnullTests
Four e2e tests added to
auth.spec.ts, all written before the fix and confirmed failing first:/with "Log in" and "Sign up" visible and "My Account" goneFull suite: 47 backend unit, 33 e2e, stable over two consecutive runs.
tsc --noEmitandnpm run buildclean.Not changed
Items already reserved in a cart stay reserved until the normal expiry sweep — logging out does not release them. That is existing behaviour and outside what this issue asks for; worth its own issue if it should change.