Properties
category: spec tags: [ux, auth, login, plan] last_updated: 2026-03-17 confidence: high
Login Page UX Improvement Plan
Two independent changes: (1) route-level logic to detect and act on an existing valid JWT cookie, and (2) visual redesign of the auth templates to match the landing page. No ATProto OAuth flow changes required.
1. JWT Detection and Auto-Redirect
Where: oauth_login() GET branch in auth_server.py.
Logic:
- Read
request.cookies.get(COOKIE_NAME) - If present, call
platform_jwt.validate_token(cookie_token) - On success: redirect to
return_to(if set and safe) or/app/ - On
ExpiredSignatureError: decode without verification to extracthandleclaim, pass asprefill_handleto template - On any other error: fall through to render login form normally
The login template pre-populates <input name="username"> with prefill_handle if provided.
2. Visual Redesign — Match Landing Page
Current state: Auth pages use Pico CSS (purple, dark theme). Landing page uses custom style.css (light, minimal, system fonts). Management panel uses Halfmoon/Bootstrap.
Approach: Replace Pico CSS in app/auth/templates/base.html with the landing page's style.css. Use same <div class="page"> wrapper and <header>/<footer> structure as index.html. Add minimal form/button styles (inline or in style.css). Consent page also extends base.html — benefits automatically.
Files to Modify
| File | Change |
|---|---|
app/auth_server.py |
JWT cookie check + pre-fill logic in GET branch of oauth_login() |
app/auth/templates/base.html |
Replace Pico CSS with style.css, match landing page HTML structure |
app/auth/templates/login.html |
Add value="{{ prefill_handle or '' }}" to username input |
static/style.css |
Add minimal form/button styles (or use inline block in base.html) |
Test Plan
test_login_get_with_valid_jwt_redirects_to_dashboard— valid cookie → 302 to/app/test_login_get_with_valid_jwt_and_return_to_redirects— valid cookie + return_to → redirecttest_login_get_with_expired_jwt_prefills_handle— expired cookie → 200 with handle pre-filledtest_login_get_with_invalid_jwt_shows_form_blank— garbage cookie → 200, no pre-fill- Visual regression: manual review against landing page
Sequencing
- Route logic (auth_server.py) — self-contained, testable immediately
- Template changes (base.html, login.html) — same or separate commit
- Optional: form styles in style.css (shared file, deserves own review)
