# Authentication Quick Reference

**Version 1.0** | One-page reference for developers

---

## Function Cheat Sheet

### For HTML Pages (accept cookie OR header)

```python
from app.api.deps import (
    get_current_admin_from_cookie_or_header,
    get_current_store_from_cookie_or_header,
    get_current_customer_from_cookie_or_header
)
from models.database.customer import Customer

# Admin page
@router.get("/admin/dashboard")
def admin_page(user: User = Depends(get_current_admin_from_cookie_or_header)):
    pass

# Store page
@router.get("/store/{code}/dashboard")
def store_page(user: User = Depends(get_current_store_from_cookie_or_header)):
    pass

# Customer page - NOTE: Returns Customer, not User!
@router.get("/storefront/account/dashboard")
def customer_page(customer: Customer = Depends(get_current_customer_from_cookie_or_header)):
    pass  # customer.id, customer.email, customer.store_id
```

### For API Endpoints (header only - better security)

```python
from app.api.deps import (
    get_current_admin_api,
    get_current_store_api,
    get_current_customer_api
)
from models.database.customer import Customer

# Admin API
@router.post("/api/v1/admin/stores")
def admin_api(user: User = Depends(get_current_admin_api)):
    pass

# Store API
@router.post("/api/v1/store/products")
def store_api(user: User = Depends(get_current_store_api)):
    pass  # user.token_store_id for store context

# Customer API - NOTE: Returns Customer, not User!
@router.post("/api/v1/storefront/orders")
def customer_api(request: Request, customer: Customer = Depends(get_current_customer_api)):
    pass  # customer.id, request.state.store validated to match
```

---

## Three Authentication Contexts

| Context | Cookie | Path | Role | Routes |
|---------|--------|------|------|--------|
| **Admin** | `admin_token` | `/admin` | `admin` | `/admin/*` |
| **Store** | `store_token` | `/store` | `store` | `/store/*` |
| **Customer** | `customer_token` | `/storefront` | `customer` | `/storefront/account/*` |

---

## Access Control Matrix

| User | Admin Portal | Store Portal | Shop Catalog | Customer Account |
|------|--------------|---------------|--------------|------------------|
| Admin | ✅ | ❌ | ✅ (view) | ❌ |
| Store | ❌ | ✅ | ✅ (view) | ❌ |
| Customer | ❌ | ❌ | ✅ (view) | ✅ |
| Anonymous | ❌ | ❌ | ✅ (view) | ❌ |

---

## Login Endpoints

```bash
# Admin
POST /api/v1/admin/auth/login
Body: {"username": "...", "password": "..."}

# Store
POST /api/v1/store/auth/login
Body: {"username": "...", "password": "..."}

# Customer
POST /api/v1/platform/stores/{store_id}/customers/login
Body: {"username": "...", "password": "..."}
```

**Response:**
```json
{
    "access_token": "eyJ0eXAi...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "user": {...}
}
```

Plus HTTP-only cookie is set automatically.

---

## Frontend Patterns

### Login (Store Token)

```javascript
const response = await fetch('/api/v1/admin/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username, password })
});

const data = await response.json();

// Cookie set automatically
// Optionally store for API calls
localStorage.setItem('token', data.access_token);

// Navigate (cookie automatic)
window.location.href = '/admin/dashboard';
```

### API Call (Use Token)

```javascript
const token = localStorage.getItem('token');

const response = await fetch('/api/v1/admin/stores', {
    headers: {
        'Authorization': `Bearer ${token}`
    }
});
```

### Logout

```javascript
await fetch('/api/v1/admin/auth/logout', { method: 'POST' });
localStorage.removeItem('token');
window.location.href = '/admin/login';
```

---

## Testing Commands

### curl Examples

```bash
# Login
TOKEN=$(curl -X POST http://localhost:8000/api/v1/admin/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}' \
  | jq -r '.access_token')

# Authenticated request
curl http://localhost:8000/api/v1/admin/stores \
  -H "Authorization: Bearer $TOKEN"
```

### Check Cookie in Browser

```javascript
// In DevTools console
document.cookie.split(';').forEach(c => console.log(c.trim()));
```

### Decode JWT

```javascript
function parseJwt(token) {
    return JSON.parse(atob(token.split('.')[1]));
}

console.log(parseJwt(localStorage.getItem('token')));
```

---

## Common Errors

| Error | Meaning | Solution |
|-------|---------|----------|
| `INVALID_TOKEN` | No token or invalid | Re-login |
| `TOKEN_EXPIRED` | Token expired | Re-login |
| `ADMIN_REQUIRED` | Need admin role | Use correct account |
| `INSUFFICIENT_PERMISSIONS` | Wrong role for route | Use correct portal |
| `USER_NOT_ACTIVE` | Account disabled | Contact admin |

---

## Security Rules

1. ✅ **HTML pages** use `*_from_cookie_or_header` functions
2. ✅ **API endpoints** use `*_api` functions
3. ✅ **Admins** cannot access store/customer portals
4. ✅ **Stores** cannot access admin/customer portals
5. ✅ **Customers** cannot access admin/store portals
6. ✅ **Public storefront** (`/storefront/products`) needs no auth
7. ✅ **Customer accounts** (`/storefront/account/*`) need auth

---

## Cookie Security

All cookies have:
- ✅ `HttpOnly=true` - JavaScript cannot read (XSS protection)
- ✅ `Secure=true` - HTTPS only (production)
- ✅ `SameSite=Lax` - CSRF protection
- ✅ Path restriction - Context isolation

---

## Quick Debug

1. **Auth not working?**
   - Check DevTools → Application → Cookies
   - Verify cookie name and path match route
   - Check token not expired

2. **Cross-context access denied?**
   - This is intentional security
   - Use correct portal for your role

3. **API call fails but page loads?**
   - API needs `Authorization` header
   - Page uses cookie (automatic)
   - Add header to API calls

---

## File Locations

```
app/api/
├── deps.py                         # All auth functions here
├── v1/
    ├── admin/auth.py              # Admin login
    ├── store/auth.py             # Store login
    └── public/stores/auth.py     # Customer login
```

---

## Environment Variables

```bash
JWT_SECRET_KEY=your-secret-key
JWT_ALGORITHM=HS256
JWT_EXPIRATION=3600  # 1 hour
ENVIRONMENT=production
```

---

**Full Documentation:** See [Authentication System Documentation](authentication.md)
**Questions?** Contact backend team

---

**Print this page for quick reference!**
