Initial commit
Dieser Commit ist enthalten in:
714
API_REFERENCE.md
Normale Datei
714
API_REFERENCE.md
Normale Datei
@ -0,0 +1,714 @@
|
||||
⎿ # V2-Docker API Reference
|
||||
|
||||
## Authentication
|
||||
|
||||
### API Key Authentication
|
||||
|
||||
All License Server API endpoints require authentication using an API key. The API key must be included in the
|
||||
request headers.
|
||||
|
||||
**Header Format:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
**API Key Management:**
|
||||
- API keys can be managed through the Admin Panel under "Lizenzserver Administration" → "System-API-Key
|
||||
generieren"
|
||||
- Keys follow the format: `AF-YYYY-[32 random characters]`
|
||||
- Only one system API key is active at a time
|
||||
- Regenerating the key will immediately invalidate the old key
|
||||
- The initial API key is automatically generated on first startup
|
||||
- To retrieve the initial API key from database: `SELECT api_key FROM system_api_key WHERE id = 1;`
|
||||
|
||||
**Error Response (401 Unauthorized):**
|
||||
```json
|
||||
{
|
||||
"error": "Invalid or missing API key",
|
||||
"code": "INVALID_API_KEY",
|
||||
"status": 401
|
||||
}
|
||||
```
|
||||
|
||||
## License Server API
|
||||
|
||||
**Base URL:** `https://api-software-undso.intelsight.de`
|
||||
|
||||
### Public Endpoints
|
||||
|
||||
#### GET /
|
||||
Root endpoint - Service status.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"service": "V2 License Server",
|
||||
"timestamp": "2025-06-19T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /health
|
||||
Health check endpoint.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"timestamp": "2025-06-19T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /metrics
|
||||
Prometheus metrics endpoint.
|
||||
|
||||
**Response:**
|
||||
Prometheus metrics in CONTENT_TYPE_LATEST format.
|
||||
|
||||
### License API Endpoints
|
||||
|
||||
All license endpoints require API key authentication via `X-API-Key` header.
|
||||
|
||||
#### POST /api/license/activate
|
||||
Activate a license on a new system.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"machine_name": "DESKTOP-ABC123",
|
||||
"app_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "License activated successfully",
|
||||
"activation": {
|
||||
"id": 123,
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"machine_name": "DESKTOP-ABC123",
|
||||
"activated_at": "2025-06-19T10:30:00Z",
|
||||
"last_heartbeat": "2025-06-19T10:30:00Z",
|
||||
"is_active": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/license/verify
|
||||
Verify an active license.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"app_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"valid": true,
|
||||
"message": "License is valid",
|
||||
"license": {
|
||||
"key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"valid_until": "2026-01-01",
|
||||
"max_users": 10
|
||||
},
|
||||
"update_available": false,
|
||||
"latest_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /api/license/info/{license_key}
|
||||
Get license information.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"license": {
|
||||
"id": 123,
|
||||
"key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"customer_name": "ACME Corp",
|
||||
"type": "perpetual",
|
||||
"valid_from": "2025-01-01",
|
||||
"valid_until": "2026-01-01",
|
||||
"max_activations": 5,
|
||||
"max_users": 10,
|
||||
"is_active": true
|
||||
},
|
||||
"activations": [
|
||||
{
|
||||
"id": 456,
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"machine_name": "DESKTOP-ABC123",
|
||||
"activated_at": "2025-06-19T10:00:00Z",
|
||||
"last_heartbeat": "2025-06-19T14:30:00Z",
|
||||
"is_active": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Session Management API Endpoints
|
||||
|
||||
**Note:** Session endpoints require that the client application is configured in the `client_configs` table.
|
||||
The default client "Account Forger" is pre-configured.
|
||||
|
||||
#### POST /api/license/session/start
|
||||
Start a new session for a license.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"machine_id": "DESKTOP-ABC123",
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
- 200 OK: Returns session_token and optional update info
|
||||
- 409 Conflict: "Es ist nur eine Sitzung erlaubt..." (single session enforcement)
|
||||
|
||||
#### POST /api/license/session/heartbeat
|
||||
Keep session alive with heartbeat.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"session_token": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** 200 OK with last_heartbeat timestamp
|
||||
|
||||
#### POST /api/license/session/end
|
||||
End an active session.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"session_token": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:** 200 OK with session duration and end reason
|
||||
|
||||
### Version API Endpoints
|
||||
|
||||
#### POST /api/version/check
|
||||
Check for available updates.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"current_version": "1.0.0",
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"update_available": true,
|
||||
"latest_version": "1.1.0",
|
||||
"download_url": "https://example.com/download/v1.1.0",
|
||||
"release_notes": "Bug fixes and performance improvements"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /api/version/latest
|
||||
Get latest version information.
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"release_date": "2025-06-20",
|
||||
"download_url": "https://example.com/download/v1.1.0",
|
||||
"release_notes": "Bug fixes and performance improvements"
|
||||
}
|
||||
```
|
||||
|
||||
## Admin Panel API
|
||||
|
||||
**Base URL:** `https://admin-panel-undso.intelsight.de`
|
||||
|
||||
### Customer API Endpoints
|
||||
|
||||
#### GET /api/customers
|
||||
Search customers for Select2 dropdown.
|
||||
|
||||
**Query Parameters:**
|
||||
- `q`: Search query
|
||||
- `page`: Page number (default: 1)
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": 123,
|
||||
"text": "ACME Corp - admin@acme.com"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"more": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### License Management API
|
||||
|
||||
- `POST /api/license/{id}/toggle` - Toggle active status
|
||||
- `POST /api/licenses/bulk-activate` - Activate multiple (license_ids array)
|
||||
- `POST /api/licenses/bulk-deactivate` - Deactivate multiple
|
||||
- `POST /api/licenses/bulk-delete` - Delete multiple
|
||||
- `POST /api/license/{id}/quick-edit` - Update validity/limits
|
||||
- `GET /api/license/{id}/devices` - List registered devices
|
||||
|
||||
#### POST /api/license/{license_id}/quick-edit
|
||||
Quick edit license properties.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"valid_until": "2027-01-01",
|
||||
"max_activations": 10,
|
||||
"max_users": 50
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "License updated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/generate-license-key
|
||||
Generate a new license key.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"license_key": "NEW1-NEW2-NEW3-NEW4"
|
||||
}
|
||||
```
|
||||
|
||||
### Device Management API
|
||||
|
||||
#### GET /api/license/{license_id}/devices
|
||||
Get devices for a license.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"id": 123,
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"machine_name": "DESKTOP-ABC123",
|
||||
"activated_at": "2025-01-01T10:00:00Z",
|
||||
"last_heartbeat": "2025-06-19T14:30:00Z",
|
||||
"is_active": true,
|
||||
"app_version": "1.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/license/{license_id}/register-device
|
||||
Register a new device.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"hardware_hash": "unique-hardware-identifier",
|
||||
"machine_name": "DESKTOP-XYZ789",
|
||||
"app_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"device_id": 456,
|
||||
"message": "Device registered successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/license/{license_id}/deactivate-device/{device_id}
|
||||
Deactivate a device.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Device deactivated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Management API
|
||||
|
||||
#### GET /api/license/{license_id}/resources
|
||||
Get resources for a license.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"resources": [
|
||||
{
|
||||
"id": 789,
|
||||
"type": "server",
|
||||
"identifier": "SRV-001",
|
||||
"status": "allocated",
|
||||
"allocated_at": "2025-06-01T10:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/resources/allocate
|
||||
Allocate resources to a license.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"license_id": 123,
|
||||
"resource_ids": [789, 790]
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"allocated": 2,
|
||||
"message": "2 resources allocated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /api/resources/check-availability
|
||||
Check resource availability.
|
||||
|
||||
**Query Parameters:**
|
||||
- `type`: Resource type
|
||||
- `count`: Number of resources needed
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"available": true,
|
||||
"count": 5,
|
||||
"resources": [
|
||||
{
|
||||
"id": 791,
|
||||
"type": "server",
|
||||
"identifier": "SRV-002"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Search API
|
||||
|
||||
#### GET /api/global-search
|
||||
Global search across all entities.
|
||||
|
||||
**Query Parameters:**
|
||||
- `q`: Search query
|
||||
- `type`: Entity type filter (customer, license, device)
|
||||
- `limit`: Maximum results (default: 20)
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"type": "customer",
|
||||
"id": 123,
|
||||
"title": "ACME Corp",
|
||||
"subtitle": "admin@acme.com",
|
||||
"url": "/customer/edit/123"
|
||||
},
|
||||
{
|
||||
"type": "license",
|
||||
"id": 456,
|
||||
"title": "XXXX-XXXX-XXXX-XXXX",
|
||||
"subtitle": "ACME Corp - Active",
|
||||
"url": "/license/edit/456"
|
||||
}
|
||||
],
|
||||
"total": 15
|
||||
}
|
||||
```
|
||||
|
||||
### Lead Management API
|
||||
|
||||
#### GET /leads/api/institutions
|
||||
Get all institutions with pagination.
|
||||
|
||||
**Query Parameters:**
|
||||
- `page`: Page number (default: 1)
|
||||
- `per_page`: Items per page (default: 20)
|
||||
- `search`: Search query
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"institutions": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Tech University",
|
||||
"contact_count": 5,
|
||||
"created_at": "2025-06-19T10:00:00Z"
|
||||
}
|
||||
],
|
||||
"total": 100,
|
||||
"page": 1,
|
||||
"per_page": 20
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /leads/api/institutions
|
||||
Create a new institution.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"name": "New University"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 101,
|
||||
"name": "New University",
|
||||
"created_at": "2025-06-19T15:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /leads/api/contacts/{contact_id}
|
||||
Get contact details.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"position": "IT Manager",
|
||||
"institution_id": 1,
|
||||
"details": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "email",
|
||||
"value": "john.doe@example.com",
|
||||
"label": "Work"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "phone",
|
||||
"value": "+49 123 456789",
|
||||
"label": "Mobile"
|
||||
}
|
||||
],
|
||||
"notes": [
|
||||
{
|
||||
"id": 1,
|
||||
"content": "Initial contact",
|
||||
"version": 1,
|
||||
"created_at": "2025-06-19T10:00:00Z",
|
||||
"created_by": "admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /leads/api/contacts/{contact_id}/details
|
||||
Add contact detail (phone/email).
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"type": "email",
|
||||
"value": "secondary@example.com",
|
||||
"label": "Secondary"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 3,
|
||||
"type": "email",
|
||||
"value": "secondary@example.com",
|
||||
"label": "Secondary"
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Management API
|
||||
|
||||
#### POST /api/resources/allocate
|
||||
Allocate resources to a license.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"license_id": 123,
|
||||
"resource_type": "domain",
|
||||
"resource_ids": [45, 46, 47]
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"allocated": 3,
|
||||
"message": "3 resources allocated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Lead Management API
|
||||
|
||||
### GET /leads/api/stats
|
||||
Get lead statistics.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"total_institutions": 150,
|
||||
"total_contacts": 450,
|
||||
"recent_activities": 25,
|
||||
"conversion_rate": 12.5,
|
||||
"by_type": {
|
||||
"university": 50,
|
||||
"company": 75,
|
||||
"government": 25
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Lead Routes (HTML Pages)
|
||||
- `GET /leads/` - Lead overview page
|
||||
- `GET /leads/create` - Create lead form
|
||||
- `POST /leads/create` - Save new lead
|
||||
- `GET /leads/edit/{lead_id}` - Edit lead form
|
||||
- `POST /leads/update/{lead_id}` - Update lead
|
||||
- `POST /leads/delete/{lead_id}` - Delete lead
|
||||
- `GET /leads/export` - Export leads
|
||||
- `POST /leads/import` - Import leads
|
||||
|
||||
## Common Response Codes
|
||||
|
||||
- `200 OK`: Successful request
|
||||
- `201 Created`: Resource created
|
||||
- `400 Bad Request`: Invalid request data
|
||||
- `401 Unauthorized`: Missing or invalid authentication
|
||||
- `403 Forbidden`: Insufficient permissions
|
||||
- `404 Not Found`: Resource not found
|
||||
- `409 Conflict`: Resource conflict (e.g., duplicate)
|
||||
- `429 Too Many Requests`: Rate limit exceeded
|
||||
- `500 Internal Server Error`: Server error
|
||||
|
||||
## Rate Limiting
|
||||
- API endpoints: 100 requests/minute
|
||||
- Login attempts: 5 per minute
|
||||
- Configurable via Admin Panel
|
||||
|
||||
## Error Response Format
|
||||
All errors return JSON with `error`, `code`, and `status` fields.
|
||||
|
||||
## Client Integration
|
||||
|
||||
Example request with required headers:
|
||||
```bash
|
||||
curl -X POST https://api-software-undso.intelsight.de/api/license/activate \
|
||||
-H "X-API-Key: AF-2025-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"hardware_hash": "unique-hardware-id",
|
||||
"machine_name": "DESKTOP-123",
|
||||
"app_version": "1.0.0"
|
||||
}'
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Credentials
|
||||
- Admin Users:
|
||||
- Username: `rac00n` / Password: `1248163264`
|
||||
- Username: `w@rh@mm3r` / Password: `Warhammer123!`
|
||||
- API Key: Generated in Admin Panel under "Lizenzserver Administration"
|
||||
|
||||
### Getting the Initial API Key
|
||||
If you need to retrieve the API key directly from the database:
|
||||
```bash
|
||||
docker exec -it v2_postgres psql -U postgres -d v2_db -c "SELECT api_key FROM system_api_key WHERE id = 1;"
|
||||
```
|
||||
|
||||
### Test Endpoints
|
||||
- Admin Panel: `https://admin-panel-undso.intelsight.de/`
|
||||
- License Server API: `https://api-software-undso.intelsight.de/`
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren