DriversHub: Unterschied zwischen den Versionen
Weitere Optionen
Kosmos (Diskussion | Beiträge) Die Seite wurde neu angelegt: „# Drivers Hub Backend – API-Dokumentation Repository: `CharlesWithC/HubBackend` ## 1. API-Grundlagen ### Base URL Die API besitzt **keine fest eingebaute öffentliche Base URL**. Host und API-Prefix kommen aus der Hub-Konfiguration. Beispielkonfiguration: ```json { "domain": "hub.example.com", "prefix": "/api" } ``` Damit lautet die Base URL: ```text https://hub.example.com/api ``` Ein Request auf: ```text GET /user/profile ``` wird also…“ |
Kosmos (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| Zeile 1: | Zeile 1: | ||
= API-Dokumentation = | |||
Repository: <code>CharlesWithC/HubBackend</code> | |||
== 1. API-Grundlagen == | |||
=== Base URL === | |||
Die API besitzt '''keine fest eingebaute öffentliche Base URL'''. Host und API-Prefix kommen aus der Hub-Konfiguration. | |||
Die API besitzt | |||
Beispielkonfiguration: | Beispielkonfiguration: | ||
<code>{ | |||
"domain": "hub.example.com", | |||
{ | "prefix": "/api" | ||
}</code> | |||
} | |||
Damit lautet die Base URL: | Damit lautet die Base URL: | ||
<code><nowiki>https://hub.example.com/api</nowiki></code> | |||
https://hub.example.com/api | |||
Ein Request auf: | Ein Request auf: | ||
<code>GET /user/profile</code> | |||
GET /user/profile | |||
wird also beispielsweise: | wird also beispielsweise: | ||
<code>GET <nowiki>https://hub.example.com/api/user/profile</nowiki></code> | |||
Der Prefix ist konfigurierbar und muss mit <code>/</code> beginnen. | |||
=== Swagger / OpenAPI === | |||
Wenn in der Konfiguration | Wenn in der Konfiguration | ||
<code>{ | |||
"openapi": true | |||
{ | }</code> | ||
} | |||
gesetzt wird, stellt der Server die interaktive Swagger-Dokumentation unter | gesetzt wird, stellt der Server die interaktive Swagger-Dokumentation unter | ||
<code>{prefix}/doc</code> | |||
{prefix}/doc | |||
bereit. | bereit. | ||
Bei | Bei <code>prefix: "/api"</code> also: | ||
<code><nowiki>https://hub.example.com/api/doc</nowiki></code> | |||
https://hub.example.com/api/doc | |||
Im Repository liegt außerdem: | Im Repository liegt außerdem: | ||
<code>/openapi.json</code> | |||
---- | |||
= 2. Authentifizierung = | |||
Es gibt zwei Token-Typen: | Es gibt zwei Token-Typen: | ||
# '''Bearer Token''' – für Benutzer | |||
# '''Application Token''' – für Anwendungen/Integrationen | |||
== Bearer Token == | |||
Header: | Header: | ||
<code>Authorization: Bearer <TOKEN></code> | |||
Authorization: Bearer <TOKEN> | |||
Beispiel: | Beispiel: | ||
<code>curl \ | |||
-H "Authorization: Bearer e1234567-89ab-cdef-0123-456789abcdef" \ | |||
curl \ | <nowiki>https://hub.example.com/api/user/profile</nowiki></code> | ||
Tokens sind UUID-artige, serverseitig gespeicherte Session-Tokens. Es steckt kein JWT-Payload darin. | Tokens sind UUID-artige, serverseitig gespeicherte Session-Tokens. Es steckt kein JWT-Payload darin. | ||
== Application Token == | |||
Header: | Header: | ||
<code>Authorization: Application <TOKEN></code> | |||
Authorization: Application <TOKEN> | |||
Beispiel: | Beispiel: | ||
<code>curl \ | |||
-H "Authorization: Application 12345678-1234-1234-1234-123456789abc" \ | |||
curl \ | <nowiki>https://hub.example.com/api/user/profile</nowiki></code> | ||
Application Tokens haben gegenüber normalen User-Tokens Einschränkungen. Nicht jeder authentifizierte Endpoint muss Application Tokens akzeptieren. | Application Tokens haben gegenüber normalen User-Tokens Einschränkungen. Nicht jeder authentifizierte Endpoint muss Application Tokens akzeptieren. | ||
---- | |||
= 3. Allgemeine Request-Regeln = | |||
Für praktisch alle Requests außer <code>GET</code> erwartet das Backend: | |||
<code>Content-Type: application/json</code> | |||
Für praktisch alle Requests außer | |||
Content-Type: application/json | |||
Ausnahmen sind insbesondere Tracker-Webhooks: | Ausnahmen sind insbesondere Tracker-Webhooks: | ||
<code>/tracksim/* | |||
/trucky/* | |||
/tracksim/* | /custom-tracker/* | ||
/trucky/* | /unitracker/*</code> | ||
/custom-tracker/* | |||
/unitracker/* | |||
Diese dürfen tracker-spezifische Payloads verwenden. | Diese dürfen tracker-spezifische Payloads verwenden. | ||
Standard-JSON-Request: | Standard-JSON-Request: | ||
<code>curl -X PATCH \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
-H "Content-Type: application/json" \ | |||
-d '{"name":"John Doe"}' \ | |||
"$BASE/user/profile"</code> | |||
== Fehlerformat == | |||
FastAPI-/HTTP-Fehler werden grundsätzlich in dieser Art zurückgegeben: | FastAPI-/HTTP-Fehler werden grundsätzlich in dieser Art zurückgegeben: | ||
<code>{ | |||
"error": "Fehlermeldung" | |||
{ | }</code> | ||
} | |||
Typische Statuscodes sind: | Typische Statuscodes sind: | ||
<code>400 Bad Request | |||
401 Unauthorized | |||
400 Bad Request | 403 Forbidden | ||
401 Unauthorized | 404 Not Found | ||
403 Forbidden | 409 Conflict | ||
404 Not Found | 422 Unprocessable Entity | ||
409 Conflict | 423 Locked | ||
422 Unprocessable Entity | 428 Precondition Required | ||
423 Locked | 429 Too Many Requests | ||
428 Precondition Required | 500 Internal Server Error | ||
429 Too Many Requests | 503 Service Unavailable</code> | ||
500 Internal Server Error | |||
503 Service Unavailable | |||
Bei Request-Validation wird die normale ausführliche FastAPI-422-Antwort durch: | Bei Request-Validation wird die normale ausführliche FastAPI-422-Antwort durch: | ||
<code>{ | |||
"error": "Unprocessable Entity" | |||
{ | }</code> | ||
} | |||
ersetzt. | ersetzt. | ||
---- | |||
= 4. Rate Limits = | |||
Es gibt globale und endpoint-spezifische Rate Limits. | Es gibt globale und endpoint-spezifische Rate Limits. | ||
Global: | Global: | ||
<code>300 Requests / 60 Sekunden</code> | |||
300 Requests / 60 Sekunden | |||
Nach Überschreiten kann der Client für etwa fünf Minuten global blockiert werden. | Nach Überschreiten kann der Client für etwa fünf Minuten global blockiert werden. | ||
Zusätzlich besitzen einzelne Endpoints eigene Limits. | Zusätzlich besitzen einzelne Endpoints eigene Limits. | ||
Beispiel aus | Beispiel aus <code>/auth/password</code>: | ||
<code>3 Requests / 60 Sekunden</code> | |||
---- | |||
3 Requests / 60 Sekunden | |||
--- | |||
= 5. Benutzer-IDs: <code>uid</code> vs. <code>userid</code> = | |||
Das ist für Clients besonders wichtig. | Das ist für Clients besonders wichtig. | ||
=== <code>uid</code> === | |||
Interne, eindeutige User-ID. | Interne, eindeutige User-ID. | ||
Jeder Account besitzt eine | Jeder Account besitzt eine <code>uid</code>. | ||
=== <code>userid</code> === | |||
Mitglieds-/Driver-Hub-ID. | Mitglieds-/Driver-Hub-ID. | ||
| Zeile 221: | Zeile 128: | ||
Daher können APIs je nach Einsatzzweck entweder: | Daher können APIs je nach Einsatzzweck entweder: | ||
<code>uid</code> | |||
uid | |||
oder | oder | ||
<code>userid</code> | |||
userid | |||
verlangen. | verlangen. | ||
---- | |||
= 6. Login und Authentifizierungsflow = | |||
== POST <code>/auth/password</code> == | |||
Login mit E-Mail und Passwort. | Login mit E-Mail und Passwort. | ||
=== Body === | |||
<code>{ | |||
"email": "user@example.com", | |||
{ | "password": "Secret123!", | ||
"captcha-response": "<captcha-token>" | |||
}</code> | |||
<code>captcha-response</code> sollte als '''erforderlich''' betrachtet werden, auch wenn die OpenAPI-Datei es nicht sauber als required kennzeichnet. | |||
} | |||
Unterstützte Captcha-Systeme: | Unterstützte Captcha-Systeme: | ||
<code>Cloudflare Turnstile | |||
hCaptcha</code> | |||
=== Erfolgreicher Login ohne MFA === | |||
<code>{ | |||
"token": "e....", | |||
"mfa": false | |||
}</code> | |||
{ | |||
} | |||
=== Login mit aktiviertem MFA === | |||
<code>{ | |||
"token": "f....", | |||
"mfa": true | |||
}</code> | |||
Der zurückgegebene Token ist in diesem Fall zunächst ein temporäres Auth-Ticket. | Der zurückgegebene Token ist in diesem Fall zunächst ein temporäres Auth-Ticket. | ||
Danach: | Danach: | ||
<code>POST /auth/mfa</code> | |||
POST /auth/mfa | |||
Body: | Body: | ||
<code>{ | |||
"token": "<temporary-auth-ticket>", | |||
{ | "otp": "123456" | ||
}</code> | |||
} | |||
Danach erhält man den eigentlichen Session-Token. | Danach erhält man den eigentlichen Session-Token. | ||
---- | |||
== POST <code>/auth/register</code> == | |||
Registriert einen Account per E-Mail/Passwort. | Registriert einen Account per E-Mail/Passwort. | ||
Body: | Body: | ||
<code>{ | |||
"email": "user@example.com", | |||
{ | "password": "Secret123!", | ||
"captcha-response": "<captcha-token>" | |||
}</code> | |||
} | |||
Das Passwort muss mindestens acht Zeichen lang sein. Die konkrete Prüfung berücksichtigt außerdem Groß-/Kleinbuchstaben, Zahlen und Sonderzeichen. | Das Passwort muss mindestens acht Zeichen lang sein. Die konkrete Prüfung berücksichtigt außerdem Groß-/Kleinbuchstaben, Zahlen und Sonderzeichen. | ||
| Zeile 319: | Zeile 188: | ||
Bei Erfolg wird bereits ein Session-Token ausgegeben: | Bei Erfolg wird bereits ein Session-Token ausgegeben: | ||
<code>{ | |||
"token": "e....", | |||
"mfa": false | |||
}</code> | |||
---- | |||
== POST <code>/auth/reset</code> == | |||
Startet einen Password-Reset. | Startet einen Password-Reset. | ||
<code>{ | |||
"email": "user@example.com", | |||
"captcha-response": "<captcha-token>" | |||
}</code> | |||
---- | |||
== POST <code>/auth/email</code> == | |||
Verarbeitet E-Mail-Bestätigungs-/Reset-Links. | Verarbeitet E-Mail-Bestätigungs-/Reset-Links. | ||
Query: | Query: | ||
<code>?secret=<SECRET></code> | |||
?secret=<SECRET> | |||
Bei Password-Reset ggf. Body: | Bei Password-Reset ggf. Body: | ||
<code>{ | |||
"password": "NewSecret123!" | |||
}</code> | |||
---- | |||
== Discord / Steam Login == | |||
=== GET <code>/auth/discord/callback</code> === | |||
Queryparameter: | Queryparameter: | ||
<code>code | |||
error_description | |||
callback_url</code> | |||
<code>callback_url</code> ist erforderlich. | |||
=== GET <code>/auth/steam/callback</code> === | |||
code | |||
Steam-OpenID-Callback. | Steam-OpenID-Callback. | ||
Die von Steam gelieferten Parameter müssen an diesen Endpoint weitergereicht werden. | Die von Steam gelieferten Parameter müssen an diesen Endpoint weitergereicht werden. | ||
---- | |||
= 7. Token API = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
| - | |- | ||
| GET | |GET | ||
| PATCH | |<code>/token</code> | ||
| DELETE | | |aktuellen Token validieren | ||
| GET | |- | ||
| DELETE | | |PATCH | ||
| DELETE | | |<code>/token</code> | ||
| GET | |aktuellen Token erneuern | ||
| POST | |- | ||
| DELETE | | |DELETE | ||
| DELETE | | |<code>/token</code> | ||
| POST | |aktuellen Token widerrufen | ||
| GET | |- | ||
|GET | |||
|<code>/token/list</code> | |||
|Sessions/Tokens auflisten | |||
|- | |||
|DELETE | |||
|<code>/token/hash</code> | |||
|bestimmten Token anhand Hash widerrufen | |||
|- | |||
|DELETE | |||
|<code>/token/all</code> | |||
|alle Benutzer-Tokens widerrufen | |||
|- | |||
|GET | |||
|<code>/token/application/list</code> | |||
|Application Tokens auflisten | |||
|- | |||
|POST | |||
|<code>/token/application</code> | |||
|Application Token erzeugen | |||
|- | |||
|DELETE | |||
|<code>/token/application</code> | |||
|Application Token widerrufen | |||
|- | |||
|DELETE | |||
|<code>/token/application/all</code> | |||
|alle Application Tokens widerrufen | |||
|- | |||
|POST | |||
|<code>/auth/ticket</code> | |||
|Auth-Ticket erzeugen/verwenden | |||
|- | |||
|GET | |||
|<code>/auth/ticket</code> | |||
|Auth-Ticket abrufen | |||
|} | |||
Beispiel Token-Validierung: | Beispiel Token-Validierung: | ||
<code>curl \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
curl \ | "$BASE/token"</code> | ||
Tokenliste unterstützt unter anderem: | Tokenliste unterstützt unter anderem: | ||
<code>page | |||
page_size | |||
order_by | |||
order</code> | |||
Mögliche <code>order_by</code>-Werte laut OpenAPI: | |||
<code>ip | |||
timestamp | |||
country_code | |||
user_agent | |||
last_used_timestamp</code> | |||
---- | |||
= 8. System-/Info-API = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|GET | |||
|<code>/</code> | |||
|Drivers-Hub-Informationen | |||
|- | |||
|GET | |||
|<code>/status</code> | |||
|Serverstatus | |||
|- | |||
|POST | |||
|<code>/status/database/restart</code> | |||
|Datenbankverbindung neu starten | |||
|- | |||
|GET | |||
|<code>/languages</code> | |||
|Hub- und unterstützte Sprachen | |||
|- | |||
| - | |POST | ||
| GET | |<code>/discord/role-connection/enable</code> | ||
| GET | |Discord Role Connection aktivieren | ||
| POST | |- | ||
| GET | |POST | ||
| POST | |<code>/discord/role-connection/disable</code> | ||
| POST | |Discord Role Connection deaktivieren | ||
| GET | |- | ||
| PATCH | |GET | ||
| POST | |<code>/config</code> | ||
| POST | |Konfiguration lesen | ||
| GET | |- | ||
|PATCH | |||
|<code>/config</code> | |||
|Konfiguration ändern | |||
|- | |||
|POST | |||
|<code>/config/reload</code> | |||
|Konfiguration neu laden | |||
|- | |||
|POST | |||
|<code>/restart</code> | |||
|Backend neu starten | |||
|- | |||
|GET | |||
|<code>/audit/list</code> | |||
|Audit-Log abrufen | |||
|} | |||
Administrative Endpoints sind entsprechend permission-geschützt. | Administrative Endpoints sind entsprechend permission-geschützt. | ||
---- | |||
= 9. User API = | |||
== Profile und Benutzer == | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
| - | |- | ||
| GET | |GET | ||
| GET | |<code>/user/list</code> | ||
| PATCH | |Benutzerliste | ||
| PATCH | |- | ||
| PATCH | |GET | ||
| PATCH | |<code>/user/profile</code> | ||
| PATCH | |Userprofil abrufen | ||
| POST | |- | ||
|PATCH | |||
|<code>/user/profile</code> | |||
|Name/Avatar ändern | |||
|- | |||
|PATCH | |||
|<code>/user/bio</code> | |||
|Bio ändern | |||
|- | |||
|PATCH | |||
|<code>/user/activity</code> | |||
|Aktivitätsdaten ändern | |||
|- | |||
|PATCH | |||
|<code>/user/{uid}/note</code> | |||
|persönliche Notiz über User | |||
|- | |||
|PATCH | |||
|<code>/user/{uid}/note/global</code> | |||
|globale Staff-Notiz | |||
|- | |||
|POST | |||
|<code>/user/tracker/switch</code> | |||
|aktiven Tracker wechseln | |||
|} | |||
=== GET <code>/user/profile</code> === | |||
Kann einen Benutzer anhand verschiedener IDs suchen: | Kann einen Benutzer anhand verschiedener IDs suchen: | ||
<code>userid | |||
uid | |||
userid | discordid | ||
uid | steamid | ||
discordid | truckersmpid | ||
steamid | email</code> | ||
truckersmpid | |||
email | |||
Zusätzliche Parameter: | Zusätzliche Parameter: | ||
<code>role_history_limit | |||
ban_history_limit</code> | |||
role_history_limit | |||
ban_history_limit | |||
Ohne Ziel-ID wird typischerweise das eigene Profil verwendet. | Ohne Ziel-ID wird typischerweise das eigene Profil verwendet. | ||
Beispiel: | Beispiel: | ||
<code>curl \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
curl \ | "$BASE/user/profile?uid=123"</code> | ||
Oder: | Oder: | ||
<code>curl \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
"$BASE/user/profile?discordid=123456789012345678"</code> | |||
=== PATCH <code>/user/profile</code> === | |||
Body: | Body: | ||
<code>{ | |||
"name": "New Name", | |||
{ | "avatar": "<nowiki>https://example.com/avatar.png</nowiki>" | ||
}</code> | |||
} | |||
Optionale Queryparameter: | Optionale Queryparameter: | ||
<code>uid | |||
sync_from_discord | |||
uid | sync_from_steam | ||
sync_from_discord | sync_from_truckersmp</code> | ||
sync_from_steam | |||
sync_from_truckersmp | |||
Damit können Profildaten auch von verbundenen Plattformen synchronisiert werden. | Damit können Profildaten auch von verbundenen Plattformen synchronisiert werden. | ||
---- | |||
= 10. Sprache, Zeitzone und Privacy = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
| - | |- | ||
| GET | |GET | ||
| PATCH | |<code>/user/language</code> | ||
| GET | |aktuelle Sprache | ||
| PATCH | |- | ||
| GET | |PATCH | ||
| PATCH | |<code>/user/language</code> | ||
|Sprache ändern | |||
|- | |||
|GET | |||
|<code>/user/timezone</code> | |||
|Zeitzone lesen | |||
| | |- | ||
|PATCH | |||
|<code>/user/timezone</code> | |||
|Zeitzone ändern | |||
|- | |||
|GET | |||
|<code>/user/privacy</code> | |||
|Privacy-Einstellungen | |||
|- | |||
|PATCH | |||
|<code>/user/privacy</code> | |||
|Privacy-Einstellungen ändern | |||
|} | |||
---- | |||
= 11. Password und MFA = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|PATCH | |||
|<code>/user/password</code> | |||
|Passwort ändern | |||
|- | |||
|POST | |||
|<code>/user/password/disable</code> | |||
|Password-Login deaktivieren | |||
|- | |||
|POST | |||
|<code>/user/mfa/enable</code> | |||
|TOTP-MFA aktivieren | |||
|- | |||
|POST | |||
|<code>/user/mfa/disable</code> | |||
|MFA deaktivieren | |||
|} | |||
TOTP-MFA wird bei jedem Login verwendet. | TOTP-MFA wird bei jedem Login verwendet. | ||
Für besonders kritische administrative Aktionen, insbesondere Config-Reload, kann MFA verpflichtend sein. | Für besonders kritische administrative Aktionen, insbesondere Config-Reload, kann MFA verpflichtend sein. | ||
---- | |||
= 12. User Connections = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
| - | |- | ||
| POST | |POST | ||
| PATCH | |<code>/user/resend-confirmation</code> | ||
| PATCH | |Bestätigungsmail erneut senden | ||
| PATCH | |- | ||
| PATCH | |PATCH | ||
| PATCH | |<code>/user/email</code> | ||
| DELETE | | |E-Mail verbinden/ändern | ||
|- | |||
|PATCH | |||
|<code>/user/discord</code> | |||
|Discord verbinden | |||
|- | |||
|PATCH | |||
|<code>/user/steam</code> | |||
|Steam verbinden | |||
|- | |||
|PATCH | |||
|<code>/user/truckersmp</code> | |||
|TruckersMP verbinden | |||
|- | |||
|PATCH | |||
|<code>/user/{uid}/connections</code> | |||
|Connections administrativ ändern | |||
|- | |||
|DELETE | |||
|<code>/user/{uid}/connections/{connection}</code> | |||
|Connection entfernen | |||
|} | |||
Für das Job-Tracking ist insbesondere eine verbundene Steam-ID relevant. | Für das Job-Tracking ist insbesondere eine verbundene Steam-ID relevant. | ||
---- | |||
= 13. Notifications = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
| - | |- | ||
| GET | |GET | ||
| GET | |<code>/user/notification/list</code> | ||
| DELETE | | |Notifications auflisten | ||
| PATCH | |- | ||
| GET | |GET | ||
| POST | |<code>/user/notification/{notificationid}</code> | ||
| POST | |Notification lesen | ||
|- | |||
|DELETE | |||
|<code>/user/notification</code> | |||
|Notification(s) löschen | |||
|- | |||
| | |PATCH | ||
|<code>/user/notification/{notificationid}/status/{status}</code> | |||
|Status ändern | |||
|- | |||
|GET | |||
|<code>/user/notification/settings</code> | |||
|Notification Settings | |||
|- | |||
|POST | |||
|<code>/user/notification/settings/{notification_type}/enable</code> | |||
|Typ aktivieren | |||
|- | |||
|POST | |||
|<code>/user/notification/settings/{notification_type}/disable</code> | |||
|Typ deaktivieren | |||
|} | |||
---- | |||
= 14. User Administration / Bans = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|POST | |||
|<code>/user/{uid}/accept</code> | |||
|Benutzer als Mitglied akzeptieren | |||
|- | |||
|DELETE | |||
|<code>/user/{uid}</code> | |||
|Benutzer löschen | |||
|- | |||
|GET | |||
|<code>/user/ban/list</code> | |||
|Bannliste | |||
|- | |||
|GET | |||
|<code>/user/ban</code> | |||
|Banninformationen | |||
|- | |||
|PUT | |||
|<code>/user/ban</code> | |||
|Bann erstellen | |||
|- | |||
|DELETE | |||
|<code>/user/ban</code> | |||
|Bann entfernen | |||
|- | |||
|DELETE | |||
|<code>/user/ban/history/{historyid}</code> | |||
|Bann-History-Eintrag löschen | |||
|} | |||
Das „Akzeptieren“ eines Users ist unabhängig vom Application-Plugin. | Das „Akzeptieren“ eines Users ist unabhängig vom Application-Plugin. | ||
---- | |||
= 15. Member API = | |||
--- | == Informationen == | ||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|GET | |||
|<code>/member/roles</code> | |||
|Rollen | |||
|- | |||
|GET | |||
|<code>/member/ranks</code> | |||
|Ranks | |||
|- | |||
|GET | |||
|<code>/member/perms</code> | |||
|Permissions | |||
|- | |||
|GET | |||
|<code>/member/list</code> | |||
|Mitgliederliste | |||
|- | |||
|GET | |||
|<code>/member/banner</code> | |||
|Mitgliederbanner | |||
|} | |||
== Eigene Member-Aktionen == | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|PATCH | |||
|<code>/member/roles/rank</code> | |||
|Default Rank-Rolle ändern | |||
|- | |||
|PATCH | |||
|<code>/member/roles/rank/{rank_type_id}</code> | |||
|Rank-Rolle bestimmten Typs ändern | |||
|- | |||
|GET | |||
|<code>/member/bonus/history</code> | |||
|Bonus-History | |||
|- | |||
|POST | |||
|<code>/member/bonus/claim</code> | |||
|Bonus beanspruchen | |||
|- | |||
|GET | |||
|<code>/member/bonus/notification/settings</code> | |||
|Bonus-Notification-Settings | |||
|- | |||
|PATCH | |||
|<code>/member/bonus/notification/settings</code> | |||
|Settings ändern | |||
|- | |||
|DELETE | |||
|<code>/member/roles/history/{historyid}</code> | |||
|Rollen-History löschen | |||
|- | |||
|POST | |||
|<code>/member/resign</code> | |||
|Mitgliedschaft niederlegen | |||
|} | |||
| Method | == Member Administration == | ||
| - | {| class="wikitable" | ||
| | !Method | ||
| | !Endpoint | ||
| | !Funktion | ||
|- | |||
| | |PATCH | ||
|<code>/member/{userid}/roles</code> | |||
|Rollen ändern | |||
|- | |||
|PATCH | |||
|<code>/member/{userid}/points</code> | |||
|Punkte ändern | |||
|- | |||
|POST | |||
|<code>/member/{userid}/dismiss</code> | |||
|Mitglied entlassen | |||
|} | |||
---- | |||
= 16. Driving Logs – <code>/dlog</code> = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|GET | |||
|<code>/dlog/list</code> | |||
|Fahrten auflisten | |||
|- | |||
|GET | |||
|<code>/dlog/{logid}</code> | |||
|einzelne Fahrt | |||
|- | |||
|DELETE | |||
|<code>/dlog/{logid}</code> | |||
|Fahrt löschen | |||
|- | |||
|GET | |||
|<code>/dlog/leaderboard</code> | |||
|Leaderboard | |||
|- | |||
|GET | |||
|<code>/dlog/export</code> | |||
|Fahrten exportieren | |||
|- | |||
|GET | |||
|<code>/dlog/statistics/summary</code> | |||
|aggregierte Statistik | |||
|- | |||
|GET | |||
|<code>/dlog/statistics/chart</code> | |||
|Chart-Daten | |||
|- | |||
|GET | |||
|<code>/dlog/statistics/details</code> | |||
|Detailstatistik | |||
|} | |||
Diese APIs gehören zu den mächtigeren Teilen des Backends und besitzen zahlreiche Filter für beispielsweise: | Diese APIs gehören zu den mächtigeren Teilen des Backends und besitzen zahlreiche Filter für beispielsweise: | ||
<code>Fahrer | |||
Zeiträume | |||
Fahrer | Distanz | ||
Zeiträume | Einnahmen | ||
Distanz | Schaden | ||
Einnahmen | Fahrzeug | ||
Schaden | Fracht | ||
Fahrzeug | Start-/Zielort | ||
Fracht | Spiel | ||
Start-/Zielort | Tracker</code> | ||
Spiel | |||
Tracker | |||
Die Filter sollten anhand der jeweiligen OpenAPI-Definition verwendet werden, da die Statistik-Endpoints unterschiedlich große Parametersätze besitzen. | Die Filter sollten anhand der jeweiligen OpenAPI-Definition verwendet werden, da die Statistik-Endpoints unterschiedlich große Parametersätze besitzen. | ||
---- | |||
= 17. Tracker APIs = | |||
Tracker-Routen werden nur aktiviert, wenn der entsprechende Tracker konfiguriert ist. | Tracker-Routen werden nur aktiviert, wenn der entsprechende Tracker konfiguriert ist. | ||
== TrackSim == | |||
{| class="wikitable" | |||
!Method | |||
| - | !Endpoint | ||
| POST | |- | ||
| POST | |POST | ||
| PUT | |<code>/tracksim/update</code> | ||
|- | |||
|POST | |||
|<code>/tracksim/update/route</code> | |||
|- | |||
| | |PUT | ||
|<code>/tracksim/driver/{userid}</code> | |||
| | |- | ||
| | |DELETE | ||
|<code>/tracksim/driver/{userid}</code> | |||
| | |} | ||
== Trucky == | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
|POST | |||
|<code>/trucky/update</code> | |||
|- | |||
|POST | |||
|<code>/trucky/import/{jobid}</code> | |||
|- | |||
|PUT | |||
|<code>/trucky/driver/{userid}</code> | |||
|- | |||
|DELETE | |||
|<code>/trucky/driver/{userid}</code> | |||
|} | |||
== Custom Tracker == | |||
POST / | <code>POST /custom-tracker/update</code> | ||
== UniTracker == | |||
<code>POST /unitracker/update</code> | |||
Diese Endpoints sind primär für Tracker-Server/Webhooks gedacht, nicht für den normalen Browser-Client. | Diese Endpoints sind primär für Tracker-Server/Webhooks gedacht, nicht für den normalen Browser-Client. | ||
---- | |||
= 18. Announcements Plugin = | |||
Nur vorhanden, wenn das Plugin aktiviert ist. | Nur vorhanden, wenn das Plugin aktiviert ist. | ||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|GET | |||
|<code>/announcements/types</code> | |||
|Announcement-Typen | |||
|- | |||
|GET | |||
|<code>/announcements/list</code> | |||
|Liste | |||
|- | |||
|GET | |||
|<code>/announcements/{announcementid}</code> | |||
|Eintrag | |||
|- | |||
|POST | |||
|<code>/announcements</code> | |||
|erstellen | |||
|- | |||
|PATCH | |||
|<code>/announcements/{announcementid}</code> | |||
|ändern | |||
|- | |||
|DELETE | |||
|<code>/announcements/{announcementid}</code> | |||
|löschen | |||
|} | |||
---- | |||
= 19. Applications Plugin = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
!Funktion | |||
|- | |||
|GET | |||
|<code>/applications/types</code> | |||
|Application-Typen | |||
|- | |||
|GET | |||
|<code>/applications/list</code> | |||
|Bewerbungen | |||
|- | |||
| - | |GET | ||
| GET | |<code>/applications/statistics</code> | ||
| GET | |Statistiken | ||
| GET | |- | ||
| GET | |GET | ||
| POST | |<code>/applications/{applicationid}</code> | ||
| POST | |Bewerbung | ||
| PATCH | |- | ||
| DELETE | | |POST | ||
|<code>/applications</code> | |||
|Bewerbung erstellen | |||
|- | |||
|POST | |||
|<code>/applications/{applicationid}/message</code> | |||
|Nachricht hinzufügen | |||
|- | |||
|PATCH | |||
|<code>/applications/{applicationid}/status</code> | |||
|Status ändern | |||
|- | |||
|DELETE | |||
|<code>/applications/{applicationid}</code> | |||
|löschen | |||
|} | |||
Hinweis: Das Akzeptieren einer Application akzeptiert den User nicht automatisch als Hub-Mitglied. | Hinweis: Das Akzeptieren einer Application akzeptiert den User nicht automatisch als Hub-Mitglied. | ||
---- | |||
= 20. Challenges Plugin = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
| - | |GET | ||
| GET | |<code>/challenges/list</code> | ||
| GET | |- | ||
| POST | |GET | ||
| PATCH | |<code>/challenges/{challengeid}</code> | ||
| DELETE | | |- | ||
| PUT | |POST | ||
| DELETE | | |<code>/challenges</code> | ||
|- | |||
|PATCH | |||
|<code>/challenges/{challengeid}</code> | |||
|- | |||
|DELETE | |||
|<code>/challenges/{challengeid}</code> | |||
|- | |||
|PUT | |||
|<code>/challenges/{challengeid}/delivery/{logid}</code> | |||
|- | |||
|DELETE | |||
|<code>/challenges/{challengeid}/delivery/{logid}</code> | |||
|} | |||
Die letzten beiden Calls ordnen Driving Logs einer Challenge zu bzw. entfernen sie. | Die letzten beiden Calls ordnen Driving Logs einer Challenge zu bzw. entfernen sie. | ||
---- | |||
= 21. Divisions Plugin = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
| - | |GET | ||
| GET | |<code>/divisions/list</code> | ||
| GET | |- | ||
| GET | |GET | ||
| GET | |<code>/divisions/statistics</code> | ||
| GET | |- | ||
| POST | |GET | ||
| PATCH | |<code>/divisions/{divisionid}/activity</code> | ||
|- | |||
|GET | |||
|<code>/divisions/list/pending</code> | |||
|- | |||
|GET | |||
| | |<code>/dlog/{logid}/division</code> | ||
|- | |||
|POST | |||
|<code>/dlog/{logid}/division/{divisionid}</code> | |||
|- | |||
|PATCH | |||
|<code>/dlog/{logid}/division/{divisionid}</code> | |||
|} | |||
---- | |||
= 22. Downloads Plugin = | |||
{| class="wikitable" | |||
--- | !Method | ||
!Endpoint | |||
|- | |||
|GET | |||
|<code>/downloads/list</code> | |||
|- | |||
|GET | |||
|<code>/downloads/redirect/{secret}</code> | |||
|- | |||
|GET | |||
|<code>/downloads/{downloadsid}</code> | |||
|- | |||
|POST | |||
|<code>/downloads</code> | |||
|- | |||
|PATCH | |||
|<code>/downloads/{downloadsid}</code> | |||
|- | |||
|DELETE | |||
|<code>/downloads/{downloadsid}</code> | |||
|} | |||
<code>/downloads/redirect/{secret}</code> dient dem kontrollierten Download/Redirect anhand eines Secrets. | |||
---- | |||
= 23. Economy Plugin = | |||
Das Economy-Plugin besitzt eine umfangreiche eigene API. | Das Economy-Plugin besitzt eine umfangreiche eigene API. | ||
== Economy Overview == | |||
<code>GET /economy</code> | |||
---- | |||
--- | |||
== Balance == | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
|GET | |||
|<code>/economy/balance</code> | |||
|- | |||
|GET | |||
|<code>/economy/balance/{userid}</code> | |||
|- | |||
|PATCH | |||
|<code>/economy/balance/{userid}</code> | |||
|- | |||
|GET | |||
|<code>/economy/balance/leaderboard</code> | |||
|- | |||
|POST | |||
|<code>/economy/balance/transfer</code> | |||
|- | |||
|GET | |||
|<code>/economy/balance/{userid}/transactions/list</code> | |||
|- | |||
|GET | |||
|<code>/economy/balance/{userid}/transactions/export</code> | |||
|- | |||
|POST | |||
|<code>/economy/balance/{userid}/visibility/{visibility}</code> | |||
|} | |||
---- | |||
| Method | == Garages == | ||
| - | {| class="wikitable" | ||
| GET | !Method | ||
| GET | !Endpoint | ||
| GET | |- | ||
| POST | |GET | ||
| POST | |<code>/economy/garages</code> | ||
| POST | |- | ||
|GET | |||
|<code>/economy/garages/list</code> | |||
|- | |||
|GET | |||
|<code>/economy/garages/{garageid}</code> | |||
|- | |||
|POST | |||
|<code>/economy/garages/{garageid}/purchase</code> | |||
|- | |||
|POST | |||
|<code>/economy/garages/{garageid}/transfer</code> | |||
|- | |||
|POST | |||
|<code>/economy/garages/{garageid}/sell</code> | |||
|} | |||
=== Garage Slots === | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
|GET | |||
|<code>/economy/garages/{garageid}/slots/list</code> | |||
|- | |||
|GET | |||
|<code>/economy/garages/{garageid}/slots/{slotid}</code> | |||
|- | |||
|POST | |||
|<code>/economy/garages/{garageid}/slots/purchase</code> | |||
|- | |||
|POST | |||
|<code>/economy/garages/{garageid}/slots/{slotid}/transfer</code> | |||
|- | |||
|POST | |||
|<code>/economy/garages/{garageid}/slots/{slotid}/sell</code> | |||
|} | |||
---- | |||
| Method | | == Trucks == | ||
| -- | {| class="wikitable" | ||
| GET | !Method | ||
| | !Endpoint | ||
| POST | |- | ||
| POST | |GET | ||
| POST | |<code>/economy/trucks</code> | ||
|- | |||
|GET | |||
|<code>/economy/trucks/list</code> | |||
|- | |||
|GET | |||
|<code>/economy/trucks/{vehicleid}</code> | |||
|- | |||
|GET | |||
|<code>/economy/trucks/{vehicleid}/{operation}/history</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{truckid}/purchase</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/transfer</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/relocate</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/activate</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/deactivate</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/repair</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/sell</code> | |||
|- | |||
|POST | |||
|<code>/economy/trucks/{vehicleid}/scrap</code> | |||
|} | |||
---- | |||
== Merchandise == | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
| - | |GET | ||
| GET | |<code>/economy/merch</code> | ||
| | |- | ||
| | |GET | ||
| GET | |<code>/economy/merch/list</code> | ||
| | |- | ||
| | |POST | ||
| POST | |<code>/economy/merch/{merchid}/purchase</code> | ||
| | |- | ||
|POST | |||
|<code>/economy/merch/{itemid}/transfer</code> | |||
| | |- | ||
|POST | |||
|<code>/economy/merch/{itemid}/sell</code> | |||
|} | |||
---- | |||
| POST | |||
| | |||
| POST | |||
| | |||
= 24. Events Plugin = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
|GET | |||
|<code>/events/list</code> | |||
|- | |||
|GET | |||
|<code>/events/{eventid}</code> | |||
|- | |||
|PUT | |||
|<code>/events/{eventid}/vote</code> | |||
|- | |||
|DELETE | |||
|<code>/events/{eventid}/vote</code> | |||
|- | |||
|POST | |||
|<code>/events</code> | |||
|- | |||
|PATCH | |||
|<code>/events/{eventid}</code> | |||
|- | |||
|DELETE | |||
|<code>/events/{eventid}</code> | |||
|- | |||
|PATCH | |||
|<code>/events/{eventid}/attendees</code> | |||
|} | |||
Beim Bearbeiten von Attendees werden User-IDs verwendet. | Beim Bearbeiten von Attendees werden User-IDs verwendet. | ||
---- | |||
= 25. Poll Plugin = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
| - | |GET | ||
| GET | |<code>/polls/list</code> | ||
| GET | |- | ||
| PUT | |GET | ||
| PATCH | |<code>/polls/{pollid}</code> | ||
| DELETE | | |- | ||
| POST | |PUT | ||
| PATCH | |<code>/polls/{pollid}/vote</code> | ||
| DELETE | | |- | ||
|PATCH | |||
|<code>/polls/{pollid}/vote</code> | |||
|- | |||
|DELETE | |||
page | |<code>/polls/{pollid}/vote</code> | ||
page_size | |- | ||
order_by | |POST | ||
order | |<code>/polls</code> | ||
|- | |||
|PATCH | |||
|<code>/polls/{pollid}</code> | |||
|- | |||
|DELETE | |||
orderid | |<code>/polls/{pollid}</code> | ||
pollid | |} | ||
title | <code>GET /polls/list</code> unterstützt u. a.: | ||
timestamp | <code>page | ||
end_time | page_size | ||
order_by | |||
order</code> | |||
<code>order_by</code> kann beispielsweise: | |||
<code>orderid | |||
pollid | |||
title | |||
timestamp | |||
end_time</code> | |||
sein. | sein. | ||
---- | |||
= 26. Tasks Plugin = | |||
{| class="wikitable" | |||
!Method | |||
!Endpoint | |||
|- | |||
| - | |GET | ||
| GET | |<code>/tasks/list</code> | ||
| GET | |- | ||
| POST | |GET | ||
| PATCH | |<code>/tasks/{taskid}</code> | ||
| DELETE | | |- | ||
| PUT | |POST | ||
| DELETE | | |<code>/tasks</code> | ||
| POST | |- | ||
| POST | |PATCH | ||
|<code>/tasks/{taskid}</code> | |||
|- | |||
|DELETE | |||
|<code>/tasks/{taskid}</code> | |||
|- | |||
|PUT | |||
|<code>/tasks/{taskid}/complete/mark</code> | |||
|- | |||
|DELETE | |||
|<code>/tasks/{taskid}/complete/mark</code> | |||
|- | |||
|POST | |||
|<code>/tasks/{taskid}/complete/accept</code> | |||
|- | |||
|POST | |||
|<code>/tasks/{taskid}/complete/reject</code> | |||
|} | |||
Der typische Workflow ist: | Der typische Workflow ist: | ||
<code>Task erstellen | |||
↓ | |||
User markiert Task als erledigt | |||
↓ | |||
Staff akzeptiert oder verwirft die Completion</code> | |||
---- | |||
= 27. Beispiel eines kompletten Clients = | |||
Shell-Setup: | Shell-Setup: | ||
<code>BASE="<nowiki>https://hub.example.com/api</nowiki>" | |||
TOKEN="..."</code> | |||
== Status == | |||
<code>curl -sS "$BASE/status"</code> | |||
curl -sS "$BASE/status" | |||
== Login == | |||
<code>curl -sS \ | |||
-X POST \ | |||
-H "Content-Type: application/json" \ | |||
-d '{ | |||
"email": "user@example.com", | |||
"password": "Secret123!", | |||
"captcha-response": "CAPTCHA_TOKEN" | |||
}' \ | |||
"$BASE/auth/password"</code> | |||
Response: | Response: | ||
<code>{ | |||
"token": "e1234567-89ab-cdef-0123-456789abcdef", | |||
"mfa": false | |||
}</code> | |||
== Eigenes Profil == | |||
<code>curl -sS \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
"$BASE/user/profile"</code> | |||
curl -sS \ | |||
== Fremdes Profil anhand UID == | |||
curl -sS \ | <code>curl -sS \ | ||
-H "Authorization: Bearer $TOKEN" \ | |||
"$BASE/user/profile?uid=42"</code> | |||
== Profil ändern == | |||
<code>curl -sS \ | |||
-X PATCH \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
-H "Content-Type: application/json" \ | |||
-d '{ | |||
"name": "Kosmos", | |||
"avatar": "<nowiki>https://example.com/avatar.png</nowiki>" | |||
}' \ | |||
"$BASE/user/profile"</code> | |||
== Driving Logs == | |||
curl -sS \ | <code>curl -sS \ | ||
-H "Authorization: Bearer $TOKEN" \ | |||
"$BASE/dlog/list?page=1&page_size=50"</code> | |||
== Token prüfen == | |||
<code>curl -sS \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
"$BASE/token"</code> | |||
== Logout / Token widerrufen == | |||
curl -sS \ | <code>curl -sS \ | ||
-X DELETE \ | |||
-H "Authorization: Bearer $TOKEN" \ | |||
-H "Content-Type: application/json" \ | |||
"$BASE/token"</code> | |||
---- | |||
= 28. Wichtige Besonderheiten für Client-Entwickler = | |||
=== 1. Nicht alle Endpoints sind immer vorhanden === | |||
Tracker-Endpunkte hängen von den konfigurierten Trackern ab. | Tracker-Endpunkte hängen von den konfigurierten Trackern ab. | ||
Plugin-Endpunkte hängen von den aktivierten Plugins ab. | Plugin-Endpunkte hängen von den aktivierten Plugins ab. | ||
Ein | Ein <code>404 Not Found</code> kann daher bedeuten, dass die entsprechende Funktion im aktuellen Hub deaktiviert ist. | ||
Viele Endpoints verlangen keine fest im Endpointnamen sichtbare Rolle wie | === 2. Permissions sind dynamisch === | ||
Viele Endpoints verlangen keine fest im Endpointnamen sichtbare Rolle wie <code>admin</code>. | |||
Die Autorisierung basiert auf: | Die Autorisierung basiert auf: | ||
<code>User accepted? | |||
+ | |||
User accepted? | Roles | ||
+ | + | ||
Roles | Permissions der Rollen</code> | ||
+ | |||
Permissions der Rollen | |||
Ein Benutzer muss mindestens eine passende Permission besitzen. | Ein Benutzer muss mindestens eine passende Permission besitzen. | ||
=== 3. Application Token != User Token === | |||
Ein Application Token wird vom System ausdrücklich anders behandelt. | Ein Application Token wird vom System ausdrücklich anders behandelt. | ||
Ein Client sollte daher nicht davon ausgehen, dass jeder Bearer-Endpunkt automatisch mit Application Token funktioniert. | Ein Client sollte daher nicht davon ausgehen, dass jeder Bearer-Endpunkt automatisch mit Application Token funktioniert. | ||
=== 4. OpenAPI beschreibt Responses kaum === | |||
Viele Definitionen enthalten: | Viele Definitionen enthalten: | ||
<code>"responses": {}</code> | |||
"responses": {} | |||
Für einen streng typisierten Client sollte man Response-Schemas daher aus der Implementierung bzw. aus echten Testantworten ableiten. | Für einen streng typisierten Client sollte man Response-Schemas daher aus der Implementierung bzw. aus echten Testantworten ableiten. | ||
=== 5. Captcha-Abweichung === | |||
Bei <code>/auth/password</code>, <code>/auth/register</code> und <code>/auth/reset</code> sollte der Client immer: | |||
Bei | <code>"captcha-response": "..."</code> | ||
"captcha-response": "..." | |||
mitsenden. | mitsenden. | ||
Zumindest beim Password-Login greift die Implementierung direkt auf dieses Feld zu. | Zumindest beim Password-Login greift die Implementierung direkt auf dieses Feld zu. | ||
=== 6. API-Versionierung === | |||
Die API verwendet keine Versionsnummer im URL-Pfad wie: | Die API verwendet keine Versionsnummer im URL-Pfad wie: | ||
<code>/api/v1/...</code> | |||
/api/v1/... | |||
Die Kompatibilität hängt daher von der eingesetzten HubBackend-Version ab. | Die Kompatibilität hängt daher von der eingesetzten HubBackend-Version ab. | ||
---- | |||
= 29. Empfehlung für eine eigene Integration = | |||
Für einen normalen Web-/Desktop-Client würde ich folgende Reihenfolge verwenden: | Für einen normalen Web-/Desktop-Client würde ich folgende Reihenfolge verwenden: | ||
<code>GET / | |||
↓ | |||
GET / | GET /languages | ||
↓ | |||
GET /languages | POST /auth/password | ||
↓ | |||
POST /auth/password | optional POST /auth/mfa | ||
↓ | |||
optional POST /auth/mfa | GET /token | ||
↓ | |||
GET /token | GET /user/profile | ||
↓ | |||
GET /user/profile | GET /member/perms | ||
↓ | |||
GET /member/perms | Features abhängig von Permissions anzeigen</code> | ||
Features abhängig von Permissions anzeigen | |||
Danach können beispielsweise: | Danach können beispielsweise: | ||
<code>/dlog/* | |||
/member/* | |||
/dlog/* | /announcements/* | ||
/member/* | /applications/* | ||
/announcements/* | /events/* | ||
/applications/* | /economy/*</code> | ||
/events/* | |||
/economy/* | |||
verwendet werden. | verwendet werden. | ||
Für einen generischen Client ist es sinnvoll, | Für einen generischen Client ist es sinnvoll, '''nicht''' hart anzunehmen, welche Plugins vorhanden sind, sondern die Hub-Konfiguration bzw. verfügbaren Funktionen beim Start festzustellen. | ||
---- | |||
--- | |||
/announcements/* Announcements Plugin | = 30. Kurzreferenz der API-Bereiche = | ||
/applications/* Applications Plugin | <code>/ Server/Hub Info | ||
/challenges/* Challenge Plugin | /status Status | ||
/divisions/* Division Plugin | /config Administration | ||
/downloads/* Downloads Plugin | /audit Audit Log | ||
/economy/* Economy Plugin | |||
/events/* Event Plugin | /auth/* Login / Registration | ||
/polls/* Poll Plugin | /token/* Sessions / Application Tokens | ||
/tasks/* Task Plugin | |||
/user/* Accounts | |||
/member/* Mitglieder / Rollen / Punkte | |||
/dlog/* Driving Logs & Statistiken | |||
/tracksim/* TrackSim | |||
/trucky/* Trucky | |||
/custom-tracker/* Custom Tracker | |||
/unitracker/* UniTracker | |||
/announcements/* Announcements Plugin | |||
/applications/* Applications Plugin | |||
/challenges/* Challenge Plugin | |||
/divisions/* Division Plugin | |||
/downloads/* Downloads Plugin | |||
/economy/* Economy Plugin | |||
/events/* Event Plugin | |||
/polls/* Poll Plugin | |||
/tasks/* Task Plugin</code> | |||
Aktuelle Version vom 18. August 2026, 21:52 Uhr
API-Dokumentation
Repository: CharlesWithC/HubBackend
1. API-Grundlagen
Base URL
Die API besitzt keine fest eingebaute öffentliche Base URL. Host und API-Prefix kommen aus der Hub-Konfiguration.
Beispielkonfiguration:
{
"domain": "hub.example.com",
"prefix": "/api"
}
Damit lautet die Base URL:
https://hub.example.com/api
Ein Request auf:
GET /user/profile
wird also beispielsweise:
GET https://hub.example.com/api/user/profile
Der Prefix ist konfigurierbar und muss mit / beginnen.
Swagger / OpenAPI
Wenn in der Konfiguration
{
"openapi": true
}
gesetzt wird, stellt der Server die interaktive Swagger-Dokumentation unter
{prefix}/doc
bereit.
Bei prefix: "/api" also:
https://hub.example.com/api/doc
Im Repository liegt außerdem:
/openapi.json
2. Authentifizierung
Es gibt zwei Token-Typen:
- Bearer Token – für Benutzer
- Application Token – für Anwendungen/Integrationen
Bearer Token
Header:
Authorization: Bearer <TOKEN>
Beispiel:
curl \
-H "Authorization: Bearer e1234567-89ab-cdef-0123-456789abcdef" \
https://hub.example.com/api/user/profile
Tokens sind UUID-artige, serverseitig gespeicherte Session-Tokens. Es steckt kein JWT-Payload darin.
Application Token
Header:
Authorization: Application <TOKEN>
Beispiel:
curl \
-H "Authorization: Application 12345678-1234-1234-1234-123456789abc" \
https://hub.example.com/api/user/profile
Application Tokens haben gegenüber normalen User-Tokens Einschränkungen. Nicht jeder authentifizierte Endpoint muss Application Tokens akzeptieren.
3. Allgemeine Request-Regeln
Für praktisch alle Requests außer GET erwartet das Backend:
Content-Type: application/json
Ausnahmen sind insbesondere Tracker-Webhooks:
/tracksim/*
/trucky/*
/custom-tracker/*
/unitracker/*
Diese dürfen tracker-spezifische Payloads verwenden.
Standard-JSON-Request:
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"John Doe"}' \
"$BASE/user/profile"
Fehlerformat
FastAPI-/HTTP-Fehler werden grundsätzlich in dieser Art zurückgegeben:
{
"error": "Fehlermeldung"
}
Typische Statuscodes sind:
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
409 Conflict
422 Unprocessable Entity
423 Locked
428 Precondition Required
429 Too Many Requests
500 Internal Server Error
503 Service Unavailable
Bei Request-Validation wird die normale ausführliche FastAPI-422-Antwort durch:
{
"error": "Unprocessable Entity"
}
ersetzt.
4. Rate Limits
Es gibt globale und endpoint-spezifische Rate Limits.
Global:
300 Requests / 60 Sekunden
Nach Überschreiten kann der Client für etwa fünf Minuten global blockiert werden.
Zusätzlich besitzen einzelne Endpoints eigene Limits.
Beispiel aus /auth/password:
3 Requests / 60 Sekunden
5. Benutzer-IDs: uid vs. userid
Das ist für Clients besonders wichtig.
uid
Interne, eindeutige User-ID.
Jeder Account besitzt eine uid.
userid
Mitglieds-/Driver-Hub-ID.
Diese existiert erst sinnvoll, nachdem ein Account als Mitglied angenommen wurde.
Daher können APIs je nach Einsatzzweck entweder:
uid
oder
userid
verlangen.
6. Login und Authentifizierungsflow
POST /auth/password
Login mit E-Mail und Passwort.
Body
{
"email": "user@example.com",
"password": "Secret123!",
"captcha-response": "<captcha-token>"
}
captcha-response sollte als erforderlich betrachtet werden, auch wenn die OpenAPI-Datei es nicht sauber als required kennzeichnet.
Unterstützte Captcha-Systeme:
Cloudflare Turnstile
hCaptcha
Erfolgreicher Login ohne MFA
{
"token": "e....",
"mfa": false
}
Login mit aktiviertem MFA
{
"token": "f....",
"mfa": true
}
Der zurückgegebene Token ist in diesem Fall zunächst ein temporäres Auth-Ticket.
Danach:
POST /auth/mfa
Body:
{
"token": "<temporary-auth-ticket>",
"otp": "123456"
}
Danach erhält man den eigentlichen Session-Token.
POST /auth/register
Registriert einen Account per E-Mail/Passwort.
Body:
{
"email": "user@example.com",
"password": "Secret123!",
"captcha-response": "<captcha-token>"
}
Das Passwort muss mindestens acht Zeichen lang sein. Die konkrete Prüfung berücksichtigt außerdem Groß-/Kleinbuchstaben, Zahlen und Sonderzeichen.
Eine funktionierende SMTP-Konfiguration ist für die E-Mail-Bestätigung notwendig.
Bei Erfolg wird bereits ein Session-Token ausgegeben:
{
"token": "e....",
"mfa": false
}
POST /auth/reset
Startet einen Password-Reset.
{
"email": "user@example.com",
"captcha-response": "<captcha-token>"
}
POST /auth/email
Verarbeitet E-Mail-Bestätigungs-/Reset-Links.
Query:
?secret=<SECRET>
Bei Password-Reset ggf. Body:
{
"password": "NewSecret123!"
}
Discord / Steam Login
GET /auth/discord/callback
Queryparameter:
code
error_description
callback_url
callback_url ist erforderlich.
GET /auth/steam/callback
Steam-OpenID-Callback.
Die von Steam gelieferten Parameter müssen an diesen Endpoint weitergereicht werden.
7. Token API
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /token
|
aktuellen Token validieren |
| PATCH | /token
|
aktuellen Token erneuern |
| DELETE | /token
|
aktuellen Token widerrufen |
| GET | /token/list
|
Sessions/Tokens auflisten |
| DELETE | /token/hash
|
bestimmten Token anhand Hash widerrufen |
| DELETE | /token/all
|
alle Benutzer-Tokens widerrufen |
| GET | /token/application/list
|
Application Tokens auflisten |
| POST | /token/application
|
Application Token erzeugen |
| DELETE | /token/application
|
Application Token widerrufen |
| DELETE | /token/application/all
|
alle Application Tokens widerrufen |
| POST | /auth/ticket
|
Auth-Ticket erzeugen/verwenden |
| GET | /auth/ticket
|
Auth-Ticket abrufen |
Beispiel Token-Validierung:
curl \
-H "Authorization: Bearer $TOKEN" \
"$BASE/token"
Tokenliste unterstützt unter anderem:
page
page_size
order_by
order
Mögliche order_by-Werte laut OpenAPI:
ip
timestamp
country_code
user_agent
last_used_timestamp
8. System-/Info-API
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /
|
Drivers-Hub-Informationen |
| GET | /status
|
Serverstatus |
| POST | /status/database/restart
|
Datenbankverbindung neu starten |
| GET | /languages
|
Hub- und unterstützte Sprachen |
| POST | /discord/role-connection/enable
|
Discord Role Connection aktivieren |
| POST | /discord/role-connection/disable
|
Discord Role Connection deaktivieren |
| GET | /config
|
Konfiguration lesen |
| PATCH | /config
|
Konfiguration ändern |
| POST | /config/reload
|
Konfiguration neu laden |
| POST | /restart
|
Backend neu starten |
| GET | /audit/list
|
Audit-Log abrufen |
Administrative Endpoints sind entsprechend permission-geschützt.
9. User API
Profile und Benutzer
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /user/list
|
Benutzerliste |
| GET | /user/profile
|
Userprofil abrufen |
| PATCH | /user/profile
|
Name/Avatar ändern |
| PATCH | /user/bio
|
Bio ändern |
| PATCH | /user/activity
|
Aktivitätsdaten ändern |
| PATCH | /user/{uid}/note
|
persönliche Notiz über User |
| PATCH | /user/{uid}/note/global
|
globale Staff-Notiz |
| POST | /user/tracker/switch
|
aktiven Tracker wechseln |
GET /user/profile
Kann einen Benutzer anhand verschiedener IDs suchen:
userid
uid
discordid
steamid
truckersmpid
email
Zusätzliche Parameter:
role_history_limit
ban_history_limit
Ohne Ziel-ID wird typischerweise das eigene Profil verwendet.
Beispiel:
curl \
-H "Authorization: Bearer $TOKEN" \
"$BASE/user/profile?uid=123"
Oder:
curl \
-H "Authorization: Bearer $TOKEN" \
"$BASE/user/profile?discordid=123456789012345678"
PATCH /user/profile
Body:
{
"name": "New Name",
"avatar": "https://example.com/avatar.png"
}
Optionale Queryparameter:
uid
sync_from_discord
sync_from_steam
sync_from_truckersmp
Damit können Profildaten auch von verbundenen Plattformen synchronisiert werden.
10. Sprache, Zeitzone und Privacy
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /user/language
|
aktuelle Sprache |
| PATCH | /user/language
|
Sprache ändern |
| GET | /user/timezone
|
Zeitzone lesen |
| PATCH | /user/timezone
|
Zeitzone ändern |
| GET | /user/privacy
|
Privacy-Einstellungen |
| PATCH | /user/privacy
|
Privacy-Einstellungen ändern |
11. Password und MFA
| Method | Endpoint | Funktion |
|---|---|---|
| PATCH | /user/password
|
Passwort ändern |
| POST | /user/password/disable
|
Password-Login deaktivieren |
| POST | /user/mfa/enable
|
TOTP-MFA aktivieren |
| POST | /user/mfa/disable
|
MFA deaktivieren |
TOTP-MFA wird bei jedem Login verwendet.
Für besonders kritische administrative Aktionen, insbesondere Config-Reload, kann MFA verpflichtend sein.
12. User Connections
| Method | Endpoint | Funktion |
|---|---|---|
| POST | /user/resend-confirmation
|
Bestätigungsmail erneut senden |
| PATCH | /user/email
|
E-Mail verbinden/ändern |
| PATCH | /user/discord
|
Discord verbinden |
| PATCH | /user/steam
|
Steam verbinden |
| PATCH | /user/truckersmp
|
TruckersMP verbinden |
| PATCH | /user/{uid}/connections
|
Connections administrativ ändern |
| DELETE | /user/{uid}/connections/{connection}
|
Connection entfernen |
Für das Job-Tracking ist insbesondere eine verbundene Steam-ID relevant.
13. Notifications
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /user/notification/list
|
Notifications auflisten |
| GET | /user/notification/{notificationid}
|
Notification lesen |
| DELETE | /user/notification
|
Notification(s) löschen |
| PATCH | /user/notification/{notificationid}/status/{status}
|
Status ändern |
| GET | /user/notification/settings
|
Notification Settings |
| POST | /user/notification/settings/{notification_type}/enable
|
Typ aktivieren |
| POST | /user/notification/settings/{notification_type}/disable
|
Typ deaktivieren |
14. User Administration / Bans
| Method | Endpoint | Funktion |
|---|---|---|
| POST | /user/{uid}/accept
|
Benutzer als Mitglied akzeptieren |
| DELETE | /user/{uid}
|
Benutzer löschen |
| GET | /user/ban/list
|
Bannliste |
| GET | /user/ban
|
Banninformationen |
| PUT | /user/ban
|
Bann erstellen |
| DELETE | /user/ban
|
Bann entfernen |
| DELETE | /user/ban/history/{historyid}
|
Bann-History-Eintrag löschen |
Das „Akzeptieren“ eines Users ist unabhängig vom Application-Plugin.
15. Member API
Informationen
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /member/roles
|
Rollen |
| GET | /member/ranks
|
Ranks |
| GET | /member/perms
|
Permissions |
| GET | /member/list
|
Mitgliederliste |
| GET | /member/banner
|
Mitgliederbanner |
Eigene Member-Aktionen
| Method | Endpoint | Funktion |
|---|---|---|
| PATCH | /member/roles/rank
|
Default Rank-Rolle ändern |
| PATCH | /member/roles/rank/{rank_type_id}
|
Rank-Rolle bestimmten Typs ändern |
| GET | /member/bonus/history
|
Bonus-History |
| POST | /member/bonus/claim
|
Bonus beanspruchen |
| GET | /member/bonus/notification/settings
|
Bonus-Notification-Settings |
| PATCH | /member/bonus/notification/settings
|
Settings ändern |
| DELETE | /member/roles/history/{historyid}
|
Rollen-History löschen |
| POST | /member/resign
|
Mitgliedschaft niederlegen |
Member Administration
| Method | Endpoint | Funktion |
|---|---|---|
| PATCH | /member/{userid}/roles
|
Rollen ändern |
| PATCH | /member/{userid}/points
|
Punkte ändern |
| POST | /member/{userid}/dismiss
|
Mitglied entlassen |
16. Driving Logs – /dlog
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /dlog/list
|
Fahrten auflisten |
| GET | /dlog/{logid}
|
einzelne Fahrt |
| DELETE | /dlog/{logid}
|
Fahrt löschen |
| GET | /dlog/leaderboard
|
Leaderboard |
| GET | /dlog/export
|
Fahrten exportieren |
| GET | /dlog/statistics/summary
|
aggregierte Statistik |
| GET | /dlog/statistics/chart
|
Chart-Daten |
| GET | /dlog/statistics/details
|
Detailstatistik |
Diese APIs gehören zu den mächtigeren Teilen des Backends und besitzen zahlreiche Filter für beispielsweise:
Fahrer
Zeiträume
Distanz
Einnahmen
Schaden
Fahrzeug
Fracht
Start-/Zielort
Spiel
Tracker
Die Filter sollten anhand der jeweiligen OpenAPI-Definition verwendet werden, da die Statistik-Endpoints unterschiedlich große Parametersätze besitzen.
17. Tracker APIs
Tracker-Routen werden nur aktiviert, wenn der entsprechende Tracker konfiguriert ist.
TrackSim
| Method | Endpoint |
|---|---|
| POST | /tracksim/update
|
| POST | /tracksim/update/route
|
| PUT | /tracksim/driver/{userid}
|
| DELETE | /tracksim/driver/{userid}
|
Trucky
| Method | Endpoint |
|---|---|
| POST | /trucky/update
|
| POST | /trucky/import/{jobid}
|
| PUT | /trucky/driver/{userid}
|
| DELETE | /trucky/driver/{userid}
|
Custom Tracker
POST /custom-tracker/update
UniTracker
POST /unitracker/update
Diese Endpoints sind primär für Tracker-Server/Webhooks gedacht, nicht für den normalen Browser-Client.
18. Announcements Plugin
Nur vorhanden, wenn das Plugin aktiviert ist.
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /announcements/types
|
Announcement-Typen |
| GET | /announcements/list
|
Liste |
| GET | /announcements/{announcementid}
|
Eintrag |
| POST | /announcements
|
erstellen |
| PATCH | /announcements/{announcementid}
|
ändern |
| DELETE | /announcements/{announcementid}
|
löschen |
19. Applications Plugin
| Method | Endpoint | Funktion |
|---|---|---|
| GET | /applications/types
|
Application-Typen |
| GET | /applications/list
|
Bewerbungen |
| GET | /applications/statistics
|
Statistiken |
| GET | /applications/{applicationid}
|
Bewerbung |
| POST | /applications
|
Bewerbung erstellen |
| POST | /applications/{applicationid}/message
|
Nachricht hinzufügen |
| PATCH | /applications/{applicationid}/status
|
Status ändern |
| DELETE | /applications/{applicationid}
|
löschen |
Hinweis: Das Akzeptieren einer Application akzeptiert den User nicht automatisch als Hub-Mitglied.
20. Challenges Plugin
| Method | Endpoint |
|---|---|
| GET | /challenges/list
|
| GET | /challenges/{challengeid}
|
| POST | /challenges
|
| PATCH | /challenges/{challengeid}
|
| DELETE | /challenges/{challengeid}
|
| PUT | /challenges/{challengeid}/delivery/{logid}
|
| DELETE | /challenges/{challengeid}/delivery/{logid}
|
Die letzten beiden Calls ordnen Driving Logs einer Challenge zu bzw. entfernen sie.
21. Divisions Plugin
| Method | Endpoint |
|---|---|
| GET | /divisions/list
|
| GET | /divisions/statistics
|
| GET | /divisions/{divisionid}/activity
|
| GET | /divisions/list/pending
|
| GET | /dlog/{logid}/division
|
| POST | /dlog/{logid}/division/{divisionid}
|
| PATCH | /dlog/{logid}/division/{divisionid}
|
22. Downloads Plugin
| Method | Endpoint |
|---|---|
| GET | /downloads/list
|
| GET | /downloads/redirect/{secret}
|
| GET | /downloads/{downloadsid}
|
| POST | /downloads
|
| PATCH | /downloads/{downloadsid}
|
| DELETE | /downloads/{downloadsid}
|
/downloads/redirect/{secret} dient dem kontrollierten Download/Redirect anhand eines Secrets.
23. Economy Plugin
Das Economy-Plugin besitzt eine umfangreiche eigene API.
Economy Overview
GET /economy
Balance
| Method | Endpoint |
|---|---|
| GET | /economy/balance
|
| GET | /economy/balance/{userid}
|
| PATCH | /economy/balance/{userid}
|
| GET | /economy/balance/leaderboard
|
| POST | /economy/balance/transfer
|
| GET | /economy/balance/{userid}/transactions/list
|
| GET | /economy/balance/{userid}/transactions/export
|
| POST | /economy/balance/{userid}/visibility/{visibility}
|
Garages
| Method | Endpoint |
|---|---|
| GET | /economy/garages
|
| GET | /economy/garages/list
|
| GET | /economy/garages/{garageid}
|
| POST | /economy/garages/{garageid}/purchase
|
| POST | /economy/garages/{garageid}/transfer
|
| POST | /economy/garages/{garageid}/sell
|
Garage Slots
| Method | Endpoint |
|---|---|
| GET | /economy/garages/{garageid}/slots/list
|
| GET | /economy/garages/{garageid}/slots/{slotid}
|
| POST | /economy/garages/{garageid}/slots/purchase
|
| POST | /economy/garages/{garageid}/slots/{slotid}/transfer
|
| POST | /economy/garages/{garageid}/slots/{slotid}/sell
|
Trucks
| Method | Endpoint |
|---|---|
| GET | /economy/trucks
|
| GET | /economy/trucks/list
|
| GET | /economy/trucks/{vehicleid}
|
| GET | /economy/trucks/{vehicleid}/{operation}/history
|
| POST | /economy/trucks/{truckid}/purchase
|
| POST | /economy/trucks/{vehicleid}/transfer
|
| POST | /economy/trucks/{vehicleid}/relocate
|
| POST | /economy/trucks/{vehicleid}/activate
|
| POST | /economy/trucks/{vehicleid}/deactivate
|
| POST | /economy/trucks/{vehicleid}/repair
|
| POST | /economy/trucks/{vehicleid}/sell
|
| POST | /economy/trucks/{vehicleid}/scrap
|
Merchandise
| Method | Endpoint |
|---|---|
| GET | /economy/merch
|
| GET | /economy/merch/list
|
| POST | /economy/merch/{merchid}/purchase
|
| POST | /economy/merch/{itemid}/transfer
|
| POST | /economy/merch/{itemid}/sell
|
24. Events Plugin
| Method | Endpoint |
|---|---|
| GET | /events/list
|
| GET | /events/{eventid}
|
| PUT | /events/{eventid}/vote
|
| DELETE | /events/{eventid}/vote
|
| POST | /events
|
| PATCH | /events/{eventid}
|
| DELETE | /events/{eventid}
|
| PATCH | /events/{eventid}/attendees
|
Beim Bearbeiten von Attendees werden User-IDs verwendet.
25. Poll Plugin
| Method | Endpoint |
|---|---|
| GET | /polls/list
|
| GET | /polls/{pollid}
|
| PUT | /polls/{pollid}/vote
|
| PATCH | /polls/{pollid}/vote
|
| DELETE | /polls/{pollid}/vote
|
| POST | /polls
|
| PATCH | /polls/{pollid}
|
| DELETE | /polls/{pollid}
|
GET /polls/list unterstützt u. a.:
page
page_size
order_by
order
order_by kann beispielsweise:
orderid
pollid
title
timestamp
end_time
sein.
26. Tasks Plugin
| Method | Endpoint |
|---|---|
| GET | /tasks/list
|
| GET | /tasks/{taskid}
|
| POST | /tasks
|
| PATCH | /tasks/{taskid}
|
| DELETE | /tasks/{taskid}
|
| PUT | /tasks/{taskid}/complete/mark
|
| DELETE | /tasks/{taskid}/complete/mark
|
| POST | /tasks/{taskid}/complete/accept
|
| POST | /tasks/{taskid}/complete/reject
|
Der typische Workflow ist:
Task erstellen
↓
User markiert Task als erledigt
↓
Staff akzeptiert oder verwirft die Completion
27. Beispiel eines kompletten Clients
Shell-Setup:
BASE="https://hub.example.com/api"
TOKEN="..."
Status
curl -sS "$BASE/status"
Login
curl -sS \
-X POST \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "Secret123!",
"captcha-response": "CAPTCHA_TOKEN"
}' \
"$BASE/auth/password"
Response:
{
"token": "e1234567-89ab-cdef-0123-456789abcdef",
"mfa": false
}
Eigenes Profil
curl -sS \
-H "Authorization: Bearer $TOKEN" \
"$BASE/user/profile"
Fremdes Profil anhand UID
curl -sS \
-H "Authorization: Bearer $TOKEN" \
"$BASE/user/profile?uid=42"
Profil ändern
curl -sS \
-X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Kosmos",
"avatar": "https://example.com/avatar.png"
}' \
"$BASE/user/profile"
Driving Logs
curl -sS \
-H "Authorization: Bearer $TOKEN" \
"$BASE/dlog/list?page=1&page_size=50"
Token prüfen
curl -sS \
-H "Authorization: Bearer $TOKEN" \
"$BASE/token"
Logout / Token widerrufen
curl -sS \
-X DELETE \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"$BASE/token"
28. Wichtige Besonderheiten für Client-Entwickler
1. Nicht alle Endpoints sind immer vorhanden
Tracker-Endpunkte hängen von den konfigurierten Trackern ab.
Plugin-Endpunkte hängen von den aktivierten Plugins ab.
Ein 404 Not Found kann daher bedeuten, dass die entsprechende Funktion im aktuellen Hub deaktiviert ist.
2. Permissions sind dynamisch
Viele Endpoints verlangen keine fest im Endpointnamen sichtbare Rolle wie admin.
Die Autorisierung basiert auf:
User accepted?
+
Roles
+
Permissions der Rollen
Ein Benutzer muss mindestens eine passende Permission besitzen.
3. Application Token != User Token
Ein Application Token wird vom System ausdrücklich anders behandelt.
Ein Client sollte daher nicht davon ausgehen, dass jeder Bearer-Endpunkt automatisch mit Application Token funktioniert.
4. OpenAPI beschreibt Responses kaum
Viele Definitionen enthalten:
"responses": {}
Für einen streng typisierten Client sollte man Response-Schemas daher aus der Implementierung bzw. aus echten Testantworten ableiten.
5. Captcha-Abweichung
Bei /auth/password, /auth/register und /auth/reset sollte der Client immer:
"captcha-response": "..."
mitsenden.
Zumindest beim Password-Login greift die Implementierung direkt auf dieses Feld zu.
6. API-Versionierung
Die API verwendet keine Versionsnummer im URL-Pfad wie:
/api/v1/...
Die Kompatibilität hängt daher von der eingesetzten HubBackend-Version ab.
29. Empfehlung für eine eigene Integration
Für einen normalen Web-/Desktop-Client würde ich folgende Reihenfolge verwenden:
GET /
↓
GET /languages
↓
POST /auth/password
↓
optional POST /auth/mfa
↓
GET /token
↓
GET /user/profile
↓
GET /member/perms
↓
Features abhängig von Permissions anzeigen
Danach können beispielsweise:
/dlog/*
/member/*
/announcements/*
/applications/*
/events/*
/economy/*
verwendet werden.
Für einen generischen Client ist es sinnvoll, nicht hart anzunehmen, welche Plugins vorhanden sind, sondern die Hub-Konfiguration bzw. verfügbaren Funktionen beim Start festzustellen.
30. Kurzreferenz der API-Bereiche
/ Server/Hub Info
/status Status
/config Administration
/audit Audit Log
/auth/* Login / Registration
/token/* Sessions / Application Tokens
/user/* Accounts
/member/* Mitglieder / Rollen / Punkte
/dlog/* Driving Logs & Statistiken
/tracksim/* TrackSim
/trucky/* Trucky
/custom-tracker/* Custom Tracker
/unitracker/* UniTracker
/announcements/* Announcements Plugin
/applications/* Applications Plugin
/challenges/* Challenge Plugin
/divisions/* Division Plugin
/downloads/* Downloads Plugin
/economy/* Economy Plugin
/events/* Event Plugin
/polls/* Poll Plugin
/tasks/* Task Plugin