Make the user object a dynamic claim set - #25
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
11 tasks
Claims are configured per deployment, so the SDK no longer maps a fixed list of fields off the token. User now carries the claims as sent, exposes them by key and keeps the well known ones as accessors, matching the JavaScript SDK's KnownUser. The avatar also resolved the picture claim and then threw it away, because the SDK had no image loading dependency, so it always drew initials on a gradient. Coil now loads the picture, with SVG decoding on top of its raster defaults and one process wide loader so every avatar shares a cache. The gradient stays as the loading and error state, which covers pictures that cannot be decoded. The Quickstart profile screen lists every claim except the protocol ones instead of just the user ID and username. Signed-off-by: Brion <info@brionmario.com>
brionmario
force-pushed
the
dynamic-user-claims
branch
from
August 20, 2026 09:38
0c5223d to
d8a081d
Compare
rajithacharith
approved these changes
Aug 24, 2026
11 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
The profile screen in the Quickstart sample showed only the user ID and username, even when the signed in user had a first name, last name, mobile number and profile picture on their token.
The cause was in the SDK rather than the sample:
Userdeclared a fixed list of fields and the client hand picked claims into them, so any attribute a deployment configures beyond that list was dropped before the app could see it. On Android the claim map was never populated at all, which also left the avatar initials with nothing to read.The avatar never showed a profile picture either. It resolved the
pictureclaim, discarded it, and always drew initials on a gradient, because the SDK had no image loading dependency.Approach
Useris now the claim set itself. It holds the claims exactly as the server sent them,get(claim)reads any of them, andsub,username,email,displayName,givenNameandfamilyNameare properties that read the claim of the same name and nothing else. There are no fallback chains and no composed values, which mirrorsKnownUserin the JavaScript SDK.profileClaimsreturns the claims withRESERVED_CLAIMSremoved. That set holds only protocol claims, the ones describing the token rather than the user:sub,iss,aud,exp,iat,nbf,jti,azp,nonce,typ,at_hash,c_hash,sid,scope,client_id,acr,amrandauth_time. Everything else reaches the app.ThunderIDClientmaps nothing now. The sign in path builds the user straight from the decoded token, andgetUser()decodes the stored access token before falling back to the userinfo endpoint, so a session restored after a relaunch has claims too. Gson cannot fill a claim map from a flat JSON body, so the userinfo and profile update responses go through one conversion that reads the response as a map without interpreting any keys.Name and avatar precedence stays in the presentation layer where it already lived, so
UserAvatarkeeps deciding how to seed initials and which claim to use for a picture. It now also loads that picture: Coil renders it circle clipped, with SVG decoding added on top of the raster defaults, and the initials gradient serves as both the loading and the error state so an undecodable picture degrades to what the component drew before. One process wideImageLoaderis shared by every avatar rather than one per instance, so they share a memory and disk cache.Note for reviewers: this adds
io.coil-kt:coil-composeandio.coil-kt:coil-svgto the library, which consumers inherit transitively.dev.thunderid.composehad no image loading dependency before. The alternative was a slot parameter letting the app supply the image composable, keeping the SDK dependency free at the cost of making pictures opt in.Known limitation: AndroidSVG, the rasterizer behind Coil's SVG decoder, does not implement
dominant-baseline, so an SVG that centres its text with that attribute renders the text about half a cap height high. Horizontal centring, raster formats and the fallback path are unaffected.The sample's profile screen iterates
profileClaims, humanises each key for its label (given_namebecomes "Given Name") and formats values by type, so a newly configured attribute shows up without a code change.Related Issues
Related PRs
Checklist
breaking changelabel added.Security checks