# Login System Documentation

## Overview
A complete authentication system for the CGW Product Finder that integrates with the user management system. Users must log in with their credentials to access the product finder application.

## Features

### 🔐 Secure Authentication
- Password verification using PBKDF2-SHA256 hashing
- Session-based authentication with HTTP-only cookies
- Automatic session management
- Active/inactive user account checking

### 📍 Multi-Location Support
- Automatic location selection for single-location users
- Location selection page for users with multiple accessible locations
- Default location preference
- Location-based access control

### 🛡️ Security Features
- Login required decorator protects all main routes
- Inactive accounts are automatically blocked
- Sessions expire on logout or server restart
- Secure session cookies (HTTP-only, SameSite)

## User Flow

### 1. Login Process
1. User visits the app → Redirected to `/login`
2. User enters **username** and **password**
3. System validates credentials against `users.json`
4. System checks if user account is **active**
5. If valid and active:
   - Session is created
   - User accessible locations are loaded

### 2. Location Selection (if applicable)
- **Single Accessible Location**: User goes directly to main app (location selection bypassed)
- **Multiple Accessible Locations**: User is redirected to `/select-location`
  - Shows all accessible locations
  - Default location is pre-selected
  - User can choose their working location
  - Selection is saved to session
- **Note**: Default location is automatically marked as accessible when user is created

### 3. Main Application Access
- User accesses the Product Finder
- User info displayed in header (username + current location)
- Logout button available in header

## Routes

### Public Routes (No Login Required)
- `GET /login` - Login page
- `POST /api/login` - Login endpoint
- `GET /users` - User management page

### Protected Routes (Login Required)
- `GET /` - Main product finder app
- `GET /quiz` - Quiz page (alias for main app)
- `GET /image-test` - Image generation test page
- `GET /select-location` - Location selection page
- `POST /api/select-location` - Set current location

### Session Routes
- `GET /api/session` - Get current session info
- `POST /api/logout` - Logout and clear session

## API Endpoints

### POST /api/login
Authenticate user and create session.

**Request:**
```json
{
  "username": "john_doe",
  "password": "password123"
}
```

**Success Response:**
```json
{
  "status": "success",
  "message": "Login successful",
  "requiresLocationSelection": true
}
```

**Error Responses:**
```json
{
  "status": "error",
  "message": "Invalid username or password"
}
```

```json
{
  "status": "error",
  "message": "Account is inactive. Please contact an administrator."
}
```

### GET /api/session
Get current user session information.

**Response:**
```json
{
  "status": "success",
  "username": "john_doe",
  "defaultLocation": "LINDS",
  "currentLocation": "KC",
  "accessibleLocations": ["LINDS", "KC", "IOLA"]
}
```

### POST /api/select-location
Select a location for the current session.

**Request:**
```json
{
  "location": "KC"
}
```

**Response:**
```json
{
  "status": "success",
  "message": "Location selected",
  "currentLocation": "KC"
}
```

### POST /api/logout
Log out and clear session.

**Response:**
```json
{
  "status": "success",
  "message": "Logged out successfully"
}
```

## Session Data

The session stores:
- `user_id`: Index of user in users.json
- `username`: Username string
- `defaultLocation`: User's default location code
- `currentLocation`: Currently selected location code
- `accessibleLocations`: Array of location codes user can access

## Authentication Decorator

The `@login_required` decorator protects routes:

```python
@app.route('/protected-page')
@login_required
def protected_page():
    return render_template('protected.html')
```

The decorator:
1. Checks if user is logged in (has `user_id` in session)
2. Validates user still exists in users.json
3. Checks if user account is still active
4. Redirects to login if any check fails

## Getting Current User in Routes

```python
@app.route('/my-route')
@login_required
def my_route():
    user = get_current_user()
    username = session.get('username')
    current_location = session.get('currentLocation')
    
    # Use user data...
    return render_template('page.html')
```

## Location-Based Access Control

Users can only access locations they have permission for:

```python
# In users.json
{
  "username": "john_doe",
  "locationSettings": {
    "LINDS": { "accessible": true },
    "IOLA": { "accessible": false },
    "KC": { "accessible": true },
    "BMD": { "accessible": false }
  }
}
```

This user can access:
- ✅ Lindsborg (LINDS)
- ✅ KC (KC)
- ❌ Iola (IOLA)
- ❌ BMD (BMD)

## User Interface Components

### Login Page (`/login`)
- Clean, centered login form
- Username and password fields
- Submit button with loading spinner
- Link to User Management page
- Error message display

### Location Selection Page (`/select-location`)
- Shows logged-in username
- Shows default location
- Radio buttons for each accessible location
- Default location is pre-selected
- Continue and Logout buttons

### Main App Header
- User info display: `👤 username | 📍 location`
- Logout button in header
- Positioned in top-right corner

## Security Considerations

### Password Security
- Passwords are hashed using PBKDF2-SHA256
- Hashes are never reversed or displayed
- Hash verification happens server-side only

### Session Security
- Sessions use secure random keys
- Cookies are HTTP-only (not accessible via JavaScript)
- SameSite cookie policy prevents CSRF attacks
- Sessions cleared on logout

### Account Status
- Inactive accounts cannot log in
- If account is deactivated while logged in, next request will log them out
- User must have at least one accessible location

## Testing the Login System

### Test User Creation
1. Go to `/users`
2. Create a test user:
   - Username: `testuser`
   - Password: `password123`
   - Default Location: Lindsborg
   - Check "Accessible" for Lindsborg and KC

### Test Login Flow
1. Go to `/` (should redirect to `/login`)
2. Enter credentials: `testuser` / `password123`
3. Click "Sign In"
4. Since user has 2 accessible locations → redirected to `/select-location`
5. Choose a location and click "Continue"
6. Now viewing main Product Finder app
7. See user info in header
8. Click "Logout" to end session

### Test Single Location User
1. Create user with only 1 accessible location
2. Log in
3. Should go directly to main app (skip location selection)

### Test Inactive User
1. Create and log in as a user
2. In User Management, toggle user to "Inactive"
3. Try to log in → Should see "Account is inactive" message

## Troubleshooting

### "Please log in first" on all pages
- Session may have expired
- Server may have restarted (sessions are in-memory)
- Clear browser cookies and log in again

### "User not found" error
- User may have been deleted while logged in
- Log out and log back in

### Can't access certain locations
- Check user's "Accessible" checkboxes in User Management
- User must have at least one accessible location

### Stuck on location selection page
- User must have multiple accessible locations
- If this shouldn't happen, check user's location settings
- Or click "Sign Out" and contact administrator

## Future Enhancements

Potential additions:
- [ ] Remember me checkbox (persistent sessions)
- [ ] Password reset functionality  
- [ ] Session timeout after inactivity
- [ ] Login attempt limiting (brute force protection)
- [ ] Two-factor authentication
- [ ] Session management dashboard
- [ ] Location switching without re-login
- [ ] Audit log of login attempts
