diff --git a/AUTHENTICATION.md b/AUTHENTICATION.md new file mode 100644 index 0000000..0d358cc --- /dev/null +++ b/AUTHENTICATION.md @@ -0,0 +1,311 @@ +# š NoteDiscovery Authentication Guide + +## Overview + +NoteDiscovery includes a simple, secure authentication system for single-user deployments. When enabled, users must log in with a password before accessing the application. + +## ⨠Features + +- ā **Single User** - Perfect for personal/self-hosted use +- ā **Secure** - Passwords hashed with bcrypt +- ā **Session-based** - Stay logged in for 7 days (configurable) +- ā **Theme-aware** - Login page matches your selected theme +- ā **Simple Setup** - Just 3 steps to enable + +--- + +## š Quick Setup + +**ā ļø IMPORTANT:** Authentication is **disabled by default**. Follow these steps to enable it: + +### Step 1: Generate a Password Hash + +Choose one of these methods: + +**Option A: Using Docker (Recommended - No local Python needed)** + +If you're running NoteDiscovery in Docker: + +```bash +# Docker Compose +docker-compose exec notediscovery /app/generate_password_hash.sh + +# Or with docker run +docker exec -it notediscovery /app/generate_password_hash.sh +``` + +The script will prompt you for your password and output the hash. + +**Option B: Using Local Python** + +If you're running NoteDiscovery locally: + +```bash +# Install bcrypt if not already installed +pip install bcrypt + +# Run the password generator +python generate_password.py +``` + +Enter your desired password when prompted. The script will output a bcrypt hash. + +**Copy the hash** - you'll need it for the next step. + +### Step 2: Generate a Secret Key + +Generate a random secret key for session encryption: + +**Using Docker:** +```bash +docker-compose exec notediscovery python -c "import secrets; print(secrets.token_hex(32))" + +# Or with docker run +docker exec -it notediscovery python -c "import secrets; print(secrets.token_hex(32))" +``` + +**Using Local Python:** +```bash +python -c "import secrets; print(secrets.token_hex(32))" +``` + +**Copy the key** - you'll need it for the next step. + +### Step 3: Update `config.yaml` + +Edit your `config.yaml` and update the security section: + +```yaml +security: + # Enable authentication + enabled: true + + # Session secret key (paste the output from Step 3) + secret_key: "your_generated_secret_key_here" + + # Password hash (paste the output from Step 2) + password_hash: "$2b$12$..." + + # Session expiry in seconds (7 days by default) + session_max_age: 604800 +``` + +### Step 4: Restart the Application + +```bash +# If running locally +uvicorn backend.main:app --reload + +# If using Docker Compose +docker-compose restart + +# Or with docker run +docker restart notediscovery +``` + +### Step 5: Test Login + +Navigate to `http://localhost:8000` and you'll be redirected to the login page. + +Enter the password you chose in Step 2. + +--- + +## š Usage + +### Logging In + +1. Navigate to `http://localhost:8000` +2. You'll be **automatically redirected** to the login page if not authenticated +3. Enter your password (the one you generated in setup) +4. Click "š Unlock" +5. You'll be redirected back to the main app + +**Note:** The login page **automatically inherits the theme** you selected in the main app. It uses the same theme loading system as the main app (fetches CSS from `/api/themes` and stores preference in localStorage as `noteDiscoveryTheme`). + +**What happens if I'm not logged in?** +- š **Page requests** (like `/`, `/MATHJAX`, etc.) ā **Automatically redirected to login page** +- š **API requests** (like `/api/notes`) ā **Return JSON error** `{"detail": "Not authenticated"}` + +This smart routing ensures: +- ā Users always see the login page (never a JSON error) +- ā API calls get proper JSON errors (for programmatic access) +- ā No broken page loads or error messages + +### Logging Out + +**Option 1: Use the built-in logout button** + +A logout button (š Logout) automatically appears in the sidebar header when authentication is enabled. Simply click it to log out. + +**Option 2: Navigate directly** + +Visit `http://localhost:8000/logout` in your browser. + +### Changing Password + +1. Generate a new password hash: + - **Docker**: `docker-compose exec notediscovery /app/generate_password_hash.sh` + - **Local**: `python generate_password.py` +2. Update `password_hash` in `config.yaml` with the new hash +3. Restart the application: + - **Docker**: `docker-compose restart` + - **Local**: Restart uvicorn +4. All existing sessions will remain valid until they expire + +### Session Expiry + +- **Default**: 7 days (604800 seconds) +- **Custom**: Change `session_max_age` in `config.yaml` +- Sessions are cleared when you log out + +--- + +## š Security Considerations + +### ā What This Protects + +- Unauthorized access to your notes +- Viewing, creating, editing, and deleting notes +- All API endpoints + +### ā ļø What This Doesn't Protect + +This is a **simple authentication system** designed for **self-hosted, single-user** deployments. It is **NOT** suitable for: + +- ā Multi-user environments +- ā Public internet exposure without HTTPS +- ā Production SaaS applications +- ā Compliance requirements (HIPAA, GDPR, etc.) + +### š”ļø Best Practices + +1. **Use HTTPS** - Always run behind a reverse proxy (nginx, Caddy) with SSL/TLS +2. **Strong Password** - Use at least 12 characters with mixed case, numbers, and symbols +3. **Unique Secret Key** - Never reuse secret keys across applications +4. **Keep Config Secure** - Don't commit `config.yaml` with real credentials to version control +5. **VPN/Private Network** - Keep NoteDiscovery on a private network or behind a VPN + +--- + +## š« Disabling Authentication + +To disable authentication and allow open access: + +```yaml +security: + enabled: false +``` + +Restart the application, and authentication will be bypassed. + +--- + +## š Troubleshooting + +### "Invalid Password" Error + +- **Check password hash**: Ensure the hash in `config.yaml` matches your password +- **Regenerate hash**: Run `python generate_password.py` again +- **Check encoding**: Password must be UTF-8 encoded + +### "Not authenticated" Error + +- **Check session**: Your session may have expired (default: 7 days) +- **Clear cookies**: Clear your browser cookies and log in again +- **Check config**: Ensure `enabled: true` in `config.yaml` + +### Login Page Not Showing + +- **Check config**: Verify `enabled: true` in `config.yaml` +- **Check routes**: Visit `/login` directly +- **Check logs**: Look for errors in the console + +### Can't Access `/logout` + +- You must be logged in to access `/logout` +- Clear your browser cookies manually if needed + +--- + +## šØ Customizing Login Page + +The login page (`frontend/login.html`) can be customized: + +- **Theme**: Automatically inherits the theme you selected in the main app (from localStorage) +- **Logo**: Uses `/static/logo.svg` +- **Styling**: Edit the CSS in the ` + +
+Your Self-Hosted Knowledge Base
+ + + + + + +