5.3 KiB
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:
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:
AuthGatepropagates logout capability formode: "local"and disables it formode: "upstream".AppShellrendersLog outwhen logout capability is enabled and preserves the existing request-and-state-clear behavior.AppShellkeeps the authenticated identity visible but does not renderLog outwhen logout capability is disabled.- 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 outis present only for public authentication modelocal;- 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.