Linked Accounts
Ein Anbieter ist aktiv, wenn auf dem Server Client-ID und Secret gesetzt sind.
Anbieterliste
application/json- response
[index: integer]?curl -X GET 'https://example.com/api/v1/auth/oauth/providers'[ { "id": "google", "name": "string", "enabled": true }]Liefert die Autorisierungs-URL des Anbieters.
Web: ohne Request-Body. Der Server setzt einen kurzlebigen
HttpOnly-Cookie, der den Callback an diesen Browser bindet; der Client
leitet im selben Browser auf authorizationUrl weiter.
Mobile App: mit appRedirectUri und appCodeChallenge. Die App
erzeugt einen zufälligen Verifier (43–128 Zeichen, PKCE nach RFC 7636),
sendet appCodeChallenge = BASE64URL(SHA256(verifier)) und öffnet
authorizationUrl in einem Custom Tab. Nach der Anmeldung leitet der
Server auf appRedirectUri?ticket=… weiter (bei Fehlern
appRedirectUri?error=<CODE>). Die App löst das Ticket zusammen mit
dem Verifier über POST /auth/oauth/exchange ein. Die Serveradresse
muss die App vorher kennen.
appRedirectUri muss auf dem Server freigegeben sein
(OAUTH_APP_REDIRECT_URIS, Standard fahrtenbuch://oauth/callback).
provider*string"google""microsoft"application/json- body
appRedirectUri?stringlength <= 300appCodeChallenge?stringS256-Challenge des App-Verifiers (Base64url ohne Padding).
^[A-Za-z0-9_-]{43}$Autorisierungs-URL
application/json- response
authorizationUrl*stringuricurl -X POST 'https://example.com/api/v1/auth/oauth/google/login' \ -H 'Content-Type: application/json' \ -d '{}'{ "authorizationUrl": "http://example.com"}bearerAuthAuthorizationBearer <JWT>provider*string"google""microsoft"Autorisierungs-URL
application/json- response
authorizationUrl*stringuricurl -X POST 'https://example.com/api/v1/auth/oauth/google/link'{ "authorizationUrl": "http://example.com"}Wird vom Browser nach der Anmeldung beim Anbieter aufgerufen und leitet zurück zur Web-App: Anmeldung nach /login#oauthTicket=…, Verknüpfung nach /profilesettings?oauthLinked=<provider>, Fehler mit ?oauthError=<CODE> (z. B. OAUTH_NOT_LINKED, OAUTH_CANCELLED, OAUTH_STATE_INVALID, OAUTH_IDENTITY_IN_USE, OAUTH_PROVIDER_ALREADY_LINKED). Wurde die Anmeldung aus der App gestartet, geht die Weiterleitung an appRedirectUri?ticket=… bzw. appRedirectUri?error=<CODE>.
provider*string"google""microsoft"code?stringstate?stringerror?stringWeiterleitung zur Web-App
curl -X GET 'https://example.com/api/v1/auth/oauth/google/callback'Tauscht das Einmal-Ticket aus dem Callback gegen Tokens. Ist TOTP aktiv, antwortet der Server zuerst mit MFA_REQUIRED; das Ticket bleibt dann bis zu seinem Ablauf (5 Minuten) gültig. Tickets aus einer App-Anmeldung lassen sich nur mit dem passenden appCodeVerifier einlösen (sonst OAUTH_APP_VERIFIER_INVALID); das Gerät wird dann als mobile registriert.
application/json- body
ticket*string20 <= length <= 200totpCode?|^\\d{6}$appCodeVerifier?|Pflicht für Tickets aus einer App-Anmeldung.
^[A-Za-z0-9._~-]{43,128}$deviceId?|length <= 200deviceName?|length <= 120platform?|length <= 64appVersion?|length <= 64Erfolgreich angemeldet
application/json- response
accessToken*stringrefreshToken*stringexpiresIn*integertokenType?stringuser*curl -X POST 'https://example.com/api/v1/auth/oauth/exchange' \ -H 'Content-Type: application/json' \ -d '{ "ticket": "stringstringstringst"}'{ "accessToken": "string", "refreshToken": "string", "expiresIn": 0, "tokenType": "Bearer", "user": { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "email": "user@example.com", "loginName": "string", "displayName": "string", "firstName": "string", "lastName": "string", "role": "user", "status": "active", "locale": "de", "timezone": "Europe/Berlin", "themeMode": "light", "totpEnabled": true, "totpRequired": true, "passkeyEnabled": true, "hasPassword": true, "forcePasswordChange": true, "onboardingCompleted": true, "lastLoginAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" }}bearerAuthAuthorizationBearer <JWT>Verknüpfte Konten
application/json- response
[index: integer]?curl -X GET 'https://example.com/api/v1/auth/oauth/identities'[ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "provider": "google", "email": "string", "displayName": "string", "lastUsedAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z" }]Schlägt mit LAST_LOGIN_METHOD (409) fehl, wenn das Konto weder ein Passwort noch einen Passkey oder ein weiteres verknüpftes Konto hat.
bearerAuthAuthorizationBearer <JWT>id*stringuuidVerknüpfung getrennt
curl -X DELETE 'https://example.com/api/v1/auth/oauth/identities/497f6eca-6276-4993-bfeb-53cbbbba6f08'