docs: define local-only logout visibility

This commit is contained in:
User
2026-08-22 17:44:45 +02:00
parent 912bab95b6
commit 6475ea39f9
@@ -0,0 +1,124 @@
# Local-Only Logout Visibility Design
**Date:** 2026-08-22
**Status:** approved
**Scope:** frontend visibility of the authenticated-shell logout control
**Source baseline:** `912bab9`
## 1. Purpose
ThothII has two distinct authentication journeys:
- standalone Mac and Windows installations authenticate directly in ThothII with local accounts;
- the Aritmolab server installation authenticates the user in the surrounding portal and exposes
that trusted identity to ThothII.
The current authenticated shell always renders a `Log out` button. That action is meaningful for
the standalone local-authentication journey, where ThothII owns the browser session. It is
misleading in the server journey because leaving the authenticated environment is a portal-level
operation, not a ThothII operation.
The frontend must therefore render the logout control only when the public authentication mode is
exactly `local`.
## 2. Behavioral contract
The existing `GET /auth/config` response is the sole authority for logout visibility. The frontend
applies this closed rule:
| Public authentication mode | Show `Log out` |
| --- | --- |
| `local` | yes |
| `upstream` | no |
| `oidc` | no |
| `none` | no |
| `mock` | no |
This deliberately hides the control for every current and future server-oriented non-local mode.
It does not infer deployment type from the operating system, hostname, URL, user issuer, nullable
session data, or build-time variables.
The authenticated user's display name remains visible in every mode. Only the `Log out` button is
conditional.
## 3. Frontend design
`AuthGate` already loads and validates the public authentication configuration before it requests
`GET /me`. It will derive a boolean logout capability from the retained configuration:
```text
canLogout = config.mode === "local"
```
`AuthGate` passes this capability through `AuthenticatedContent` to `AppShell`. `AppShell` uses it
only to decide whether to render the existing button. The current click handler, logout API
coordinator, authentication-state cleanup, and query/session isolation behavior remain unchanged.
The capability is passed explicitly instead of being recomputed from `AuthenticatedUser` because
legacy and upstream user representations may have nullable session data. It is also preferable to
a new environment variable because `/auth/config` already represents the backend's effective
authentication mode at runtime.
## 4. Backend and deployment impact
No backend route, authentication configuration, Compose descriptor, native `tht` command, or
packaging logic changes.
`POST /auth/logout` remains available for the local standalone flow and for existing internal
authentication behavior. Hiding a control is not treated as an authorization boundary; backend
authentication and CSRF protections remain authoritative.
Mac and Windows packages require no platform detection. Their existing local authentication
configuration produces `mode: "local"`, so they retain the button automatically. The Aritmolab
server's trusted-upstream configuration produces `mode: "upstream"`, so it loses the button
automatically.
## 5. Failure behavior
`AuthGate` continues to fail closed when `/auth/config` is unavailable or malformed; the
authenticated shell is not rendered in that state. Once the configuration has been accepted, an
unrecognized mode is already rejected by the existing parser and therefore cannot accidentally
enable logout.
The visibility change introduces no new request, fallback, or error message. In non-local modes
the button is absent and no user-initiated `POST /auth/logout` can originate from this shell
control.
## 6. Verification
Frontend component tests will prove:
1. `AuthGate` propagates logout capability for `mode: "local"` and disables it for
`mode: "upstream"`.
2. `AppShell` renders `Log out` when logout capability is enabled and preserves the existing
request-and-state-clear behavior.
3. `AppShell` keeps the authenticated identity visible but does not render `Log out` when logout
capability is disabled.
4. The focused frontend tests, the complete frontend Vitest suite, TypeScript build-mode
type-check, and production frontend build pass.
No live server mutation is required to validate this source change. A later manual server smoke
test may confirm that the deployed Aritmolab journey shows the user identity without a ThothII
logout control, while a standalone local-authentication smoke test confirms the control remains.
## 7. Non-goals
This change does not:
- implement portal or global Aritmolab logout;
- redirect users to an Aritmolab logout URL;
- remove or weaken `POST /auth/logout`;
- change login, expiry, session revocation, OIDC, or trusted-upstream behavior;
- detect Mac, Windows, or server packaging in browser code;
- alter any other authenticated-shell control or layout.
## 8. Acceptance criteria
The design is complete when:
- `Log out` is present only for public authentication mode `local`;
- the Aritmolab trusted-upstream server shell has no ThothII logout button;
- standalone Mac and Windows local-authentication behavior is unchanged;
- the username or display name remains visible in all authenticated modes;
- no backend or deployment configuration is added solely for this visibility decision;
- automated frontend tests prevent regression in both local and upstream modes.