Stu Mason
Stu Mason

Activity

Pull Request Merged

PR #6 merged: feat: Admin authentication and dynamic OAuth URLs

Summary

SECURITY FIX: Previously the admin dashboard was completely open - anyone with the URL could access your health data. This PR adds proper authentication.

  • Add admin account creation on first run
  • Implement login/logout with server-side sessions
  • Fix OAuth redirect_uri to use dynamic BASE_URL (no more localhost)
  • Protect all admin routes behind authentication

Security Model

  • Password hashing: Argon2 (winner of Password Hashing Competition)
  • Sessions: Server-side with HTTP-only cookies (24hr expiry)
  • Timing attacks: Constant-time password comparison
  • First-run protection: Must create admin before accessing anything

Changes

FilePurpose
admin/auth.pyAuth logic, guards, session management
core/password.pyArgon2 password hashing
models/admin_user.pyAdminUser model
templates/admin/login.htmlLogin form
templates/admin/setup_account.htmlFirst-run admin creation
alembic/versions/*_add_admin_users.pyMigration

Flow

/admin
  ├── No admin user? → /admin/setup/account (create admin)
  ├── Not logged in? → /admin/login
  ├── No OAuth setup? → /admin/setup (with dynamic callback URL)
  └── All good → /admin/dashboard

Configuration

# Optional - auto-detected from request if not set
BASE_URL=https://polar-server.example.com

# Optional - auto-generated and persisted if not set
SESSION_SECRET=your-secret-key

Test plan

  • First visit to /admin redirects to /admin/setup/account
  • Cannot bypass account creation by visiting other /admin/* routes
  • After creating account, redirects to OAuth setup
  • Logout clears session and redirects to login
  • OAuth callback uses correct URL (not localhost)
  • Password validation (min 8 chars, confirmation match)
  • Session expires after 24 hours

Breaking changes

None - existing deployments will be prompted to create admin account on first visit.


Generated with Claude Code

+1019
additions
-34
deletions
16
files changed