Locked/no-access users (403/denied path/expired session/trial ended) were trapped: NoAccessScreen had no logout control, and «Выйти» lived only inside UserMenu, which does not render on the no-access screen. They could not switch accounts without clearing browser basic-auth manually. - Extract logout() into shared `lib/logout.ts` (single source of truth). - UserMenu now imports it instead of a local copy (behaviour unchanged). - NoAccessScreen renders an always-available «Выйти» accent button for every variant. Mirrored across both frontends (tradein-mvp/frontend + main frontend) to keep the MIRROR invariant in sync.
25 lines
941 B
TypeScript
25 lines
941 B
TypeScript
/**
|
||
* Logout — invalidate basic_auth cache + reload.
|
||
*
|
||
* Trick: fetch на защищённый endpoint с явно неверным Basic-токеном.
|
||
* Caddy ответит 401 (because creds wrong) → браузер выкинет старые cached
|
||
* creds для этого origin. Затем hard reload — Caddy снова запросит basic_auth
|
||
* prompt, потому что cached creds invalidated.
|
||
*
|
||
* Это работает в Safari/Chrome/Firefox; legacy `ClearAuthenticationCache`
|
||
* не нужен.
|
||
*/
|
||
export async function logout(): Promise<void> {
|
||
try {
|
||
await fetch("/api/v1/me", {
|
||
headers: {
|
||
Authorization: "Basic " + btoa("logout:logout"),
|
||
},
|
||
cache: "no-store",
|
||
});
|
||
} catch {
|
||
// Сетевая ошибка — всё равно делаем hard reload.
|
||
}
|
||
// Hard reload форсит новый basic_auth handshake.
|
||
window.location.href = "/";
|
||
}
|