@@ -344,6 +344,54 @@ impl ConnectedClient {
344344 }
345345}
346346
347+ async fn export_qr_login_token (
348+ connected : & ConnectedClient ,
349+ credentials : & ApiCredentials ,
350+ ) -> Result < tl:: enums:: auth:: LoginToken > {
351+ let result = connected
352+ . client
353+ . invoke ( & tl:: functions:: auth:: ExportLoginToken {
354+ api_id : credentials. api_id ,
355+ api_hash : credentials. api_hash . clone ( ) ,
356+ except_ids : vec ! [ ] ,
357+ } )
358+ . await
359+ . map_err ( invocation_error) ?;
360+
361+ resolve_qr_login_token_migration ( connected, result) . await
362+ }
363+
364+ async fn resolve_qr_login_token_migration (
365+ connected : & ConnectedClient ,
366+ mut result : tl:: enums:: auth:: LoginToken ,
367+ ) -> Result < tl:: enums:: auth:: LoginToken > {
368+ for _ in 0 ..4 {
369+ let tl:: enums:: auth:: LoginToken :: MigrateTo ( migrate) = result else {
370+ return Ok ( result) ;
371+ } ;
372+
373+ let old_dc_id = connected. session . home_dc_id ( ) ;
374+ let new_dc_id = migrate. dc_id ;
375+
376+ if old_dc_id != new_dc_id {
377+ connected. handle . disconnect_from_dc ( old_dc_id) ;
378+ connected. session . set_home_dc_id ( new_dc_id) . await ;
379+ }
380+
381+ result = connected
382+ . client
383+ . invoke ( & tl:: functions:: auth:: ImportLoginToken {
384+ token : migrate. token ,
385+ } )
386+ . await
387+ . map_err ( invocation_error) ?;
388+ }
389+
390+ Err ( TelegramCliError :: Message (
391+ "QR login hit repeated DC migrations; retry the login command" . into ( ) ,
392+ ) )
393+ }
394+
347395#[ async_trait( ?Send ) ]
348396impl TelegramAdapter for GrammersAdapter {
349397 async fn login ( & self , account_name : & str , request : LoginRequest ) -> Result < ( ) > {
@@ -419,24 +467,12 @@ impl TelegramAdapter for GrammersAdapter {
419467 }
420468 }
421469 LoginRequest :: UserQr => {
422- let result = connected
423- . client
424- . invoke ( & tl:: functions:: auth:: ExportLoginToken {
425- api_id : credentials. api_id ,
426- api_hash : credentials. api_hash . clone ( ) ,
427- except_ids : vec ! [ ] ,
428- } )
429- . await
430- . map_err ( invocation_error) ?;
470+ let result = export_qr_login_token ( & connected, & credentials) . await ?;
431471
432472 let token = match result {
433473 tl:: enums:: auth:: LoginToken :: Token ( t) => t,
434474 tl:: enums:: auth:: LoginToken :: Success ( _) => return Ok ( ( ) ) ,
435- tl:: enums:: auth:: LoginToken :: MigrateTo ( _) => {
436- return Err ( TelegramCliError :: Message (
437- "QR login requires a DC migration; not supported" . into ( ) ,
438- ) )
439- }
475+ tl:: enums:: auth:: LoginToken :: MigrateTo ( _) => unreachable ! ( ) ,
440476 } ;
441477
442478 let url = format ! ( "tg://login?token={}" , BASE64URL . encode( & token. token) ) ;
@@ -466,15 +502,7 @@ impl TelegramAdapter for GrammersAdapter {
466502 ) ) ;
467503 }
468504
469- let result = connected
470- . client
471- . invoke ( & tl:: functions:: auth:: ExportLoginToken {
472- api_id : credentials. api_id ,
473- api_hash : credentials. api_hash . clone ( ) ,
474- except_ids : vec ! [ ] ,
475- } )
476- . await
477- . map_err ( invocation_error) ?;
505+ let result = export_qr_login_token ( & connected, & credentials) . await ?;
478506
479507 match result {
480508 tl:: enums:: auth:: LoginToken :: Success ( _) => {
@@ -492,11 +520,7 @@ impl TelegramAdapter for GrammersAdapter {
492520 return Ok ( ( ) ) ;
493521 }
494522 tl:: enums:: auth:: LoginToken :: Token ( _) => continue ,
495- tl:: enums:: auth:: LoginToken :: MigrateTo ( _) => {
496- return Err ( TelegramCliError :: Message (
497- "DC migration during QR login" . into ( ) ,
498- ) )
499- }
523+ tl:: enums:: auth:: LoginToken :: MigrateTo ( _) => unreachable ! ( ) ,
500524 }
501525 }
502526 }
0 commit comments