fix: handle non-UUID sub claim in auth sync

Authentik JWT sub claim may not be a valid UUID.
Now derives a deterministic UUID from the sub string if parsing fails.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeroen Schweitzer
2026-01-04 17:45:05 +01:00
co-authored by Claude Opus 4.5
parent dd0997679f
commit dd5b794de4
2 changed files with 102 additions and 8 deletions
+27 -7
View File
@@ -322,7 +322,6 @@ class AuthController(BaseController):
responses={
200: {"description": "User profile with roles and preferences"},
401: {"description": "Not authenticated"},
404: {"description": "User not found in database"},
},
)
async def get_current_user_profile(
@@ -333,11 +332,16 @@ class AuthController(BaseController):
Get the current authenticated user's profile
Returns the user's profile, roles, and preferences.
Requires authentication via Bearer token or API key.
Supports both:
- Bearer token (mobile/native clients)
- NPM forward auth headers (web clients via proxy)
For forward auth users, auto-creates the user in the database
if they don't exist yet (first login via web).
"""
service = AuthService(session)
# Get authentik_id from claims (JWT 'sub' field)
# Get authentik_id from claims (JWT 'sub' field or forward auth 'uid')
authentik_id_str = user_claims.get("sub")
if not authentik_id_str or authentik_id_str == "local-user":
raise HTTPException(status_code=401, detail="Authentication required")
@@ -348,11 +352,27 @@ class AuthController(BaseController):
raise HTTPException(status_code=401, detail="Invalid user identifier")
user = await service.get_user_by_authentik_id(authentik_id)
# If user not found and using forward auth, auto-create them
if user is None:
raise HTTPException(
status_code=404,
detail="User not found - please sync via /auth/sync first",
)
auth_method = user_claims.get("auth_method")
if auth_method == "forward_auth":
# Auto-sync user from forward auth headers
logger.info(f"Auto-creating user from forward auth: {user_claims.get('email')}")
user, is_new = await service.sync_user_from_claims(
authentik_id=authentik_id,
email=user_claims.get("email", ""),
name=user_claims.get("name", user_claims.get("preferred_username", "")),
groups=user_claims.get("groups", []),
)
await session.commit()
await session.refresh(user, ["preferences", "roles"])
else:
# JWT auth but user not in DB - they need to sync first
raise HTTPException(
status_code=404,
detail="User not found - please sync via /auth/sync first",
)
return UserProfileResponse(
user=service.user_to_schema(user),