diff --git a/docs/superpowers/specs/2026-05-06-require-web-login-design.md b/docs/superpowers/specs/2026-05-06-require-web-login-design.md new file mode 100644 index 00000000..a70e4736 --- /dev/null +++ b/docs/superpowers/specs/2026-05-06-require-web-login-design.md @@ -0,0 +1,55 @@ +# Require Web Login Design + +## Goal + +When a user opens the self-hosted Hoppscotch web frontend without an active +session, the app must not be usable. The user should see only a login page +until authentication succeeds. + +## Scope + +- Applies only to the web shell in `packages/hoppscotch-selfhost-web`. +- Does not change the desktop shell behavior. +- Does not change backend authentication endpoints or session semantics. +- Reuses the existing Hoppscotch auth platform and login UI. + +## Architecture + +The self-hosted web platform will register a root UI extension that acts as an +auth gate. The gate will subscribe to the existing `platform.auth` user stream +and render above the app only when the current platform is web and no confirmed +user exists. + +The gate has three visible states: + +- Auth check pending: show a centered spinner while `performAuthInit()` verifies + the cookie-backed session. +- Anonymous: show a full-screen login-only page using the existing + `FirebaseLogin` component. +- Authenticated: render nothing, allowing the normal Hoppscotch app to remain + usable. + +## Data Flow + +`performAuthInit()` already checks the backend session and updates +`currentUser$`. The auth gate must not perform its own token or cookie checks. +It only observes the existing stream, so login, logout, refresh, and local auth +continue to use the current implementation. + +## Route Behavior + +The gate blocks interaction with normal app routes by covering the UI, not by +redirecting. This avoids changing common router behavior and avoids breaking +special routes such as `/enter` and `/device-login`, which use the `empty` +layout and are outside the normal application shell. + +## Testing + +Add a focused unit test for the gate state logic: + +- pending auth check requires the blocking screen; +- anonymous confirmed state requires the blocking screen; +- authenticated state does not block; +- desktop platform does not block. + +Run the targeted test and a typecheck or lint command for the touched package.