@@ -145,25 +145,36 @@ async fn list_cohorts(
145145 . filter ( |v| !v. is_empty ( ) )
146146 . map ( str:: to_owned) ;
147147
148- let resolved_email = if let Some ( id_token) = id_token_email {
149- match backend:: auth:: validate_id_token_email_for_sub ( & id_token, & claims. sub ) . await {
150- Ok ( email ) => email,
148+ let ( resolved_email, id_token_name ) = if let Some ( id_token) = id_token_email {
149+ match backend:: auth:: validate_id_token_for_sub ( & id_token, & claims. sub ) . await {
150+ Ok ( info ) => ( info . email , info . name ) ,
151151 Err ( e) => {
152152 tracing:: warn!( "Invalid x-id-token for /api/cohorts: {e}" ) ;
153- claims. email . clone ( )
153+ ( claims. email . clone ( ) , None )
154154 }
155155 }
156156 } else {
157- claims. email . clone ( )
157+ ( claims. email . clone ( ) , None )
158158 } ;
159159
160- // Ensure global user exists (creates if needed, same as WS auth flow)
161- let display_name = claims. sub . clone ( ) ; // Fallback; WS auth will update with real name
162- let global_user = state
163- . global_db
164- . ensure_global_user ( & claims. sub , & display_name, resolved_email. as_deref ( ) )
165- . await
166- . map_err ( |e| ( StatusCode :: INTERNAL_SERVER_ERROR , e. to_string ( ) ) ) ?;
160+ // Ensure global user exists. Prefer the display name from the id_token so
161+ // users who log in but haven't been added to any cohort still get their
162+ // real name persisted (previously only the WS auth flow populated the
163+ // display name, so these users stayed stuck with their Kinde sub as a
164+ // placeholder).
165+ let global_user = if let Some ( name) = id_token_name. as_deref ( ) . filter ( |n| !n. is_empty ( ) ) {
166+ state
167+ . global_db
168+ . ensure_global_user ( & claims. sub , name, resolved_email. as_deref ( ) )
169+ . await
170+ . map_err ( |e| ( StatusCode :: INTERNAL_SERVER_ERROR , e. to_string ( ) ) ) ?
171+ } else {
172+ state
173+ . global_db
174+ . find_or_create_global_user ( & claims. sub , & claims. sub , resolved_email. as_deref ( ) )
175+ . await
176+ . map_err ( |e| ( StatusCode :: INTERNAL_SERVER_ERROR , e. to_string ( ) ) ) ?
177+ } ;
167178
168179 // Link email-based pre-authorizations if we have an email
169180 if let Some ( email) = & resolved_email {
0 commit comments