# Login System - Quick Start Guide ## TL;DR The MCP server now has a login page at `https://localhost/login` that authenticates users with email/password and sets a secure encrypted cookie. ## 5-Minute Setup ### 1. Create a Test User ```elixir # Start IEx iex -S mix # Create user User.create("alice", "alice@example.com", "password123", [123456, 11111]) ``` ### 2. Access Login Page Open browser: `https://localhost/login` ### 3. Login ``` Email: alice@example.com Password: password123 ``` ### 4. Success! You're redirected to the home page with an encrypted session cookie valid for 30 days. ## Routes | Route | Method | Public | Description | |-------|--------|--------|-------------| | `/login` | GET | ✅ Yes | Login page with email/password form | | `/login` | POST | ✅ Yes | Login handler (processes credentials) | | `/docs` | GET | ✅ Yes | Documentation index | | `/docs/*` | GET | ✅ Yes | Documentation files | | `/set` | GET | ✅ Yes | Legacy cookie setter | | All others | Any | ❌ No | Require authentication | ## Creating Users ```elixir User.create( username, # String - unique login name email, # String - unique email address password, # String - will be Argon2 hashed permission_keys # List of integers - [123456, 11111] ) ``` ### Permission Keys - `123456` → `"index:view"` - View index pages - `11111` → `"admin:manage"` - Admin access ## Login Flow ``` User → https://localhost/login → Enter email + password → POST /login → Validate credentials (User database) → Set encrypted cookie → Redirect to / ``` ## Authentication Errors | Error | Meaning | Solution | |-------|---------|----------| | Invalid email or password | Wrong credentials | Check email/password | | Account is locked | 5+ failed attempts | Wait 15 min or unlock manually | | Account is disabled | Inactive account | Contact admin | ## Cookie Details ``` Name: user Value: [encrypted user ID] Flags: HttpOnly, Secure, SameSite=Lax Max-Age: 30 days ``` ## Security Features - ✅ Argon2 password hashing - ✅ Encrypted session cookies - ✅ Account lockout (5 failed attempts, 15 min) - ✅ Audit logging (all attempts tracked) - ✅ CSRF protection (SameSite cookie) - ✅ No password enumeration (same error for all failures) ## Testing ### Run Test Script ```bash # In project directory iex -S mix ``` ```elixir # Load test script Code.eval_file("test_login.exs") ``` ### Manual Test 1. Create user (above) 2. Visit `https://localhost/login` 3. Enter credentials 4. Should redirect to `/` with cookie set ### Check Audit Log ```elixir iex> User.get_audit_log(limit: 10) [ %{action: "login_success", user_id: 123, ip_address: "127.0.0.1", ...}, %{action: "login_failed", user_id: 123, details: "invalid_credentials", ...} ] ``` ## Common Issues ### Can't Access Login Page - ✅ Check HTTPS server is running on port 443 - ✅ Accept self-signed certificate in browser ### Cookie Not Set - ✅ Must use HTTPS (cookies have `secure: true`) - ✅ Check browser doesn't block cookies - ✅ Clear old cookies and retry ### "User not found" After Login - ✅ Check user exists: `User.get_user(user_id)` - ✅ Check database connection - ✅ Review logs for errors ## Code Locations - **Login Routes**: `lib/my_mcp_server_router.ex:74-80` - **Login Handler**: `lib/my_mcp_server_router.ex:245-294` - **Login UI**: `lib/my_mcp_server_router.ex:193-243` - **User Auth**: `lib/user.ex:200-225` ## Next Steps - Read `LOGIN_SYSTEM.md` for detailed documentation - Review `USER_MANAGEMENT.md` for user administration - See `AUTHORIZATION.md` for permission system - Check `AUTHENTICATION.md` for security architecture ## Quick Reference ```elixir # Create user User.create("username", "email", "password", [permissions]) # Authenticate (manual test) User.authenticate("username", "password") # Get user by ID User.get_user(user_id) # Get user by email User.find_by_email("email@example.com") # Unlock account User.unlock_account("username") # Disable account User.deactivate("username") # Enable account User.activate("username") # View audit log User.get_audit_log(limit: 20) ``` ## Default Test Credentials After running test script: ``` Email: test@example.com Password: password123 ``` --- **Remember**: Change `@secret_key_base` in production!