proxy-oidcv2/API-REFERENCE.md
2025-12-03 21:34:44 +01:00

439 lines
7.0 KiB
Markdown

# 🔌 API Reference
## Base URL
```
http://localhost:3000 (development)
https://secure.k2r.ovh (production)
```
## Authentication Endpoints
### Login Page
```
GET /auth/login-page
Returns: HTML login page
Status: 200
```
### Initiate OIDC Login
```
GET /auth/login
Redirects to: Keycloak authorization endpoint
Status: 302 (Redirect)
```
### OAuth Callback
```
POST /auth/callback
Parameters: code, state (from Keycloak)
Returns: User session created
Redirects to: Original page or /
Status: 302
```
### User Logout
```
GET /auth/logout
Effect: Session destroyed
Redirects to: Keycloak logout or /
Status: 302
```
### User Profile
```
GET /auth/profile
Returns:
{
"user": {
"sub": "user-id",
"name": "User Name",
"email": "user@example.com",
"isAdmin": false
}
}
Status: 200
Auth: Required
```
## Service Management Endpoints (Admin Only)
### Create Service
```
POST /api/services
Headers:
Content-Type: application/json
X-CSRF-Token: {token}
Body:
{
"name": "My App",
"path": "/myapp",
"targetUrl": "http://localhost:8080",
"requireAuth": true,
"description": "Optional description"
}
Returns: Created service object
Status: 201
Auth: Admin required
```
Example Response:
```json
{
"id": "uuid-here",
"name": "My App",
"path": "/myapp",
"targetUrl": "http://localhost:8080",
"requireAuth": true,
"description": "Optional description",
"enabled": true,
"createdAt": "2025-12-03T10:00:00Z",
"updatedAt": "2025-12-03T10:00:00Z"
}
```
### List All Services
```
GET /api/services
Returns: Array of service objects
Status: 200
Auth: Admin required
```
### Get Service Details
```
GET /api/services/:id
Parameters:
:id = Service ID (UUID)
Returns: Single service object
Status: 200
Auth: Admin required
```
### Update Service
```
PUT /api/services/:id
Headers:
Content-Type: application/json
X-CSRF-Token: {token}
Body: (any field to update)
{
"name": "Updated Name",
"targetUrl": "http://new-target:8080",
"requireAuth": false
}
Returns: Updated service object
Status: 200
Auth: Admin required
```
### Delete Service
```
DELETE /api/services/:id
Headers:
X-CSRF-Token: {token}
Status: 204 (No Content)
Auth: Admin required
```
### Toggle Service (Enable/Disable)
```
PATCH /api/services/:id/toggle
Headers:
Content-Type: application/json
X-CSRF-Token: {token}
Body:
{
"enabled": true
}
Returns: Updated service object
Status: 200
Auth: Admin required
```
### Get Service Access Logs
```
GET /api/services/:id/logs
Query Parameters:
?limit=100 (default: 100)
?offset=0 (default: 0)
Returns:
{
"logs": [
{
"id": 1,
"service_id": "uuid",
"user_id": "keycloak-id",
"path": "/myapp/page",
"method": "GET",
"status_code": 200,
"response_time_ms": 45,
"ip_address": "127.0.0.1",
"timestamp": "2025-12-03T10:00:00Z"
}
],
"total": 150
}
Status: 200
Auth: Admin required
```
## Dashboard Endpoints (Admin Only)
### Get Statistics
```
GET /dashboard/stats
Returns:
{
"totalServices": 5,
"enabledServices": 4,
"disabledServices": 1,
"recentActivity": [
{
"id": 1,
"action": "SERVICE_CREATED",
"user_id": "admin",
"timestamp": "2025-12-03T10:00:00Z"
}
]
}
Status: 200
Auth: Admin required
```
### Get Audit Logs
```
GET /dashboard/logs
Query Parameters:
?limit=100 (default: 100)
?offset=0 (default: 0)
Returns:
{
"logs": [
{
"id": 1,
"action": "SERVICE_CREATED",
"user_id": "admin@example.com",
"service_id": "uuid",
"ip_address": "127.0.0.1",
"details": "{}",
"timestamp": "2025-12-03T10:00:00Z"
}
],
"total": 45
}
Status: 200
Auth: Admin required
```
## Dynamic Proxy Routes
### Access Proxied Service
```
ANY /:path
Parameters:
:path = Service path (e.g., /myapp, /grafana)
Behavior:
1. Check if service exists in database
2. Verify authentication requirements
3. Proxy request to target URL
4. Log access
5. Return response
Status: Depends on target service
Auth: Checked if service.requireAuth = true
```
Example Flow:
```
GET /grafana/dashboard
Found service: path=/grafana, target=http://localhost:3001
User authenticated (OIDC session)
Proxy to: GET http://localhost:3001/dashboard
Response returned
Access logged
```
## Error Responses
### 400 Bad Request
```json
{
"error": "Missing required fields: name, path, targetUrl"
}
```
### 401 Unauthorized
```json
{
"error": "Not authenticated"
}
```
### 403 Forbidden
```json
{
"error": "Admin access required"
}
```
### 404 Not Found
```json
{
"error": "Service not found"
}
```
### 429 Too Many Requests
```json
{
"error": "Too many requests, please try again later"
}
```
### 500 Internal Server Error
```json
{
"error": "Internal server error"
}
```
## HTTP Methods
| Method | Use |
|--------|-----|
| GET | Retrieve data (safe, cacheable) |
| POST | Create new resource |
| PUT | Update entire resource |
| PATCH | Update partial resource |
| DELETE | Remove resource |
## Status Codes
| Code | Meaning |
|------|---------|
| 200 | OK - Request successful |
| 201 | Created - Resource created |
| 204 | No Content - Success, no body |
| 302 | Found - Redirect |
| 400 | Bad Request - Invalid data |
| 401 | Unauthorized - Auth required |
| 403 | Forbidden - Access denied |
| 404 | Not Found - Resource not found |
| 429 | Rate Limited - Too many requests |
| 500 | Internal Server Error |
| 503 | Service Unavailable - Target down |
## CSRF Protection
All state-changing requests (POST, PUT, DELETE, PATCH) require a CSRF token:
```
Header: X-CSRF-Token: {token}
```
The token is automatically included in HTML forms and available in `res.locals.csrfToken`.
## Rate Limiting
Default limits:
- General: 100 requests per 15 minutes
- Auth: 5 attempts per 15 minutes
Limits per IP address.
## Authentication Flow
1. User visits `GET /auth/login-page`
2. User clicks login
3. Redirected to `GET /auth/login`
4. Redirected to Keycloak
5. User authenticates on Keycloak
6. Keycloak redirects to `POST /auth/callback` with code
7. Callback validates code with Keycloak
8. Session created
9. Redirected to original page
## Common Usage Examples
### Create and Access a Service
```bash
# 1. Create service (admin)
curl -X POST http://localhost:3000/api/services \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: YOUR_TOKEN" \
-d '{
"name": "My App",
"path": "/myapp",
"targetUrl": "http://localhost:8080",
"requireAuth": true
}'
# 2. Access service (authenticated user)
curl http://localhost:3000/myapp \
-b "connect.sid=SESSION_COOKIE"
# Response proxies to http://localhost:8080/myapp
```
### List All Services and Their Status
```bash
curl http://localhost:3000/api/services \
-b "connect.sid=SESSION_COOKIE"
```
### View Access Logs for a Service
```bash
curl http://localhost:3000/api/services/SERVICE_ID/logs?limit=50 \
-b "connect.sid=SESSION_COOKIE"
```
### Get Admin Dashboard Stats
```bash
curl http://localhost:3000/dashboard/stats \
-b "connect.sid=SESSION_COOKIE"
```
---
**For more information, see README.md and ARCHITECTURE.md**