@@ -167,6 +167,7 @@ var s when s.StartsWith("WEAK_PASSWORD") => Lang.T("firebase_weak_password"),
167167 if ( ! IsConfigured ) return ( false , Lang . T ( "firebase_not_configured" ) ) ;
168168 if ( ! RuntimeSecrets . TryGetGoogleClientId ( out var googleClientId ) )
169169 return ( false , Lang . T ( "firebase_google_not_configured" ) ) ;
170+ RuntimeSecrets . TryGetGoogleClientSecret ( out var googleClientSecret ) ;
170171 try
171172 {
172173 // Generate PKCE code verifier + challenge
@@ -227,6 +228,7 @@ var s when s.StartsWith("WEAK_PASSWORD") => Lang.T("firebase_weak_password"),
227228 {
228229 [ "code" ] = code ,
229230 [ "client_id" ] = googleClientId ,
231+ [ "client_secret" ] = googleClientSecret ?? "" ,
230232 [ "redirect_uri" ] = redirectUri ,
231233 [ "grant_type" ] = "authorization_code" ,
232234 [ "code_verifier" ] = codeVerifier
@@ -236,7 +238,11 @@ var s when s.StartsWith("WEAK_PASSWORD") => Lang.T("firebase_weak_password"),
236238
237239 if ( ! tokenResponse . IsSuccessStatusCode )
238240 {
239- return ( false , $ "Erreur token Google: { tokenResponse . StatusCode } ") ;
241+ var detail = await FormatGoogleOAuthTokenErrorAsync ( tokenResponse ) ;
242+ return ( false ,
243+ string . IsNullOrEmpty ( detail )
244+ ? $ "Erreur token Google: { tokenResponse . StatusCode } "
245+ : $ "Erreur token Google: { tokenResponse . StatusCode } — { detail } ") ;
240246 }
241247
242248 var tokenJson = await tokenResponse . Content . ReadFromJsonAsync < JsonElement > ( ) ;
@@ -265,6 +271,31 @@ var s when s.StartsWith("WEAK_PASSWORD") => Lang.T("firebase_weak_password"),
265271 catch ( Exception ex ) { return ( false , ex . Message ) ; }
266272 }
267273
274+ /// <summary>Google returns JSON: error, error_description (e.g. redirect_uri_mismatch).</summary>
275+ private static async Task < string > FormatGoogleOAuthTokenErrorAsync ( HttpResponseMessage response )
276+ {
277+ try
278+ {
279+ var text = await response . Content . ReadAsStringAsync ( ) ;
280+ if ( string . IsNullOrWhiteSpace ( text ) )
281+ return "" ;
282+
283+ using var doc = JsonDocument . Parse ( text ) ;
284+ var root = doc . RootElement ;
285+ var err = root . TryGetProperty ( "error" , out var e ) ? e . GetString ( ) : null ;
286+ var desc = root . TryGetProperty ( "error_description" , out var d ) ? d . GetString ( ) : null ;
287+ if ( ! string . IsNullOrEmpty ( desc ) )
288+ return string . IsNullOrEmpty ( err ) ? desc : $ "{ err } : { desc } ";
289+ if ( ! string . IsNullOrEmpty ( err ) )
290+ return err ;
291+ return text . Length > 200 ? text [ .. 200 ] + "…" : text ;
292+ }
293+ catch
294+ {
295+ return "" ;
296+ }
297+ }
298+
268299 private static int FindFreePort ( )
269300 {
270301 var listener = new System . Net . Sockets . TcpListener ( IPAddress . Loopback , 0 ) ;
0 commit comments