@@ -87,9 +87,9 @@ struct CliArgs {
8787 #[ arg( long) ]
8888 enable_totp : bool ,
8989
90- /// TOTP URL for 2FA login
90+ /// TOTP URI for 2FA login
9191 #[ arg( long) ]
92- totp_url : Option < String > ,
92+ totp_uri : Option < String > ,
9393
9494 /// Two-factor authentication recovery key
9595 #[ arg( long) ]
@@ -98,20 +98,26 @@ struct CliArgs {
9898
9999fn maybe_handle_twofa ( args : & CliArgs , resp : Response , token : & str , endpoint : & str ) -> Response {
100100 // If 2FA not required, just return the original response
101- if !resp. get ( "requiresTwoFA" ) . and_then ( |v| v. as_bool ( ) ) . unwrap_or ( false ) {
101+ if !resp
102+ . get ( "requiresTwoFA" )
103+ . and_then ( |v| v. as_bool ( ) )
104+ . unwrap_or ( false )
105+ {
102106 return resp;
103107 }
104-
108+
105109 verbose_log ( & args, "Two-factor authentication is required" ) ;
106-
110+
107111 let mut twofa_body: HashMap < & str , Value > = HashMap :: new ( ) ;
108112 if let Some ( recovery_key) = args. twofa_recovery_key . as_ref ( ) {
109113 twofa_body. insert ( "recoveryKey" , recovery_key. as_str ( ) . into ( ) ) ;
110114 } else {
111- // Try to generate TOTP code if URL is provided
112- let totp_code = if let Some ( totp_url) = args. totp_url . as_ref ( ) {
113- let totp = TOTP :: from_url ( totp_url) . expect ( "Failed to parse TOTP URL" ) ;
114- let code = totp. generate_current ( ) . expect ( "Failed to generate TOTP code" ) ;
115+ // Try to generate TOTP code if URI is provided
116+ let totp_code = if let Some ( totp_uri) = args. totp_uri . as_ref ( ) {
117+ let totp = TOTP :: from_url ( totp_uri) . expect ( "Failed to parse TOTP URL" ) ;
118+ let code = totp
119+ . generate_current ( )
120+ . expect ( "Failed to generate TOTP code" ) ;
115121 verbose_log ( & args, format ! ( "Generated TOTP code: {}" , code) . as_str ( ) ) ;
116122 code
117123 } else {
@@ -120,7 +126,7 @@ fn maybe_handle_twofa(args: &CliArgs, resp: Response, token: &str, endpoint: &st
120126 } ;
121127 twofa_body. insert ( "totpCode" , totp_code. into ( ) ) ;
122128 }
123-
129+
124130 make_request (
125131 args,
126132 reqwest:: Method :: POST ,
@@ -289,7 +295,7 @@ fn set_password(args: CliArgs) {
289295 Some ( & token) ,
290296 Some ( body) ,
291297 ) ;
292-
298+
293299 // Handle 2FA if required
294300 resp = maybe_handle_twofa ( & args, resp, & token, "/v2/accounts/password/finalize_2fa" ) ;
295301
@@ -356,7 +362,7 @@ fn login(args: CliArgs) {
356362 . get ( "loginToken" )
357363 . and_then ( |v| v. as_str ( ) )
358364 . expect ( "Missing loginToken field" ) ;
359-
365+
360366 let mut resp = make_request (
361367 & args,
362368 reqwest:: Method :: POST ,
@@ -365,7 +371,10 @@ fn login(args: CliArgs) {
365371 Some ( body) ,
366372 ) ;
367373
368- verbose_log ( & args, format ! ( "intermediate login token: {}" , login_token) . as_str ( ) ) ;
374+ verbose_log (
375+ & args,
376+ format ! ( "intermediate login token: {}" , login_token) . as_str ( ) ,
377+ ) ;
369378
370379 // Handle 2FA if required
371380 resp = maybe_handle_twofa ( & args, resp, login_token, "/v2/auth/login/finalize_2fa" ) ;
@@ -403,11 +412,11 @@ fn get_service_token(args: &CliArgs) {
403412
404413fn enable_totp ( args : & CliArgs ) {
405414 println ! ( "Enabling TOTP..." ) ;
406-
415+
407416 // Initialize 2FA
408417 let mut body: HashMap < & str , Value > = HashMap :: new ( ) ;
409418 body. insert ( "generateQR" , true . into ( ) ) ;
410-
419+
411420 let resp = make_request (
412421 args,
413422 reqwest:: Method :: POST ,
@@ -419,30 +428,39 @@ fn enable_totp(args: &CliArgs) {
419428 ) ,
420429 Some ( body) ,
421430 ) ;
422-
423- let totp_url = resp. get ( "url" ) . and_then ( |v| v. as_str ( ) ) . expect ( "Failed to get TOTP URL" ) ;
424- let qr_code = resp. get ( "qrCode" ) . and_then ( |v| v. as_str ( ) ) . expect ( "Failed to get QR code" ) . to_string ( ) ;
425-
426- println ! ( "TOTP URL: {}" , totp_url) ;
427-
431+
432+ let totp_uri = resp
433+ . get ( "uri" )
434+ . and_then ( |v| v. as_str ( ) )
435+ . expect ( "Failed to get TOTP URL" ) ;
436+ let qr_code = resp
437+ . get ( "qrCode" )
438+ . and_then ( |v| v. as_str ( ) )
439+ . expect ( "Failed to get QR code" )
440+ . to_string ( ) ;
441+
442+ println ! ( "TOTP URL: {}" , totp_uri) ;
443+
428444 // Open QR code in browser in a separate thread
429445 thread:: spawn ( move || {
430446 if let Err ( e) = open:: that ( qr_code) {
431447 eprintln ! ( "Failed to open QR code: {}" , e) ;
432448 }
433449 } ) ;
434-
450+
435451 // Parse TOTP URL directly with the library
436- let totp = TOTP :: from_url ( totp_url ) . expect ( "Failed to parse TOTP URL" ) ;
437-
452+ let totp = TOTP :: from_url ( totp_uri ) . expect ( "Failed to parse TOTP URL" ) ;
453+
438454 // Generate TOTP code
439- let code = totp. generate_current ( ) . expect ( "Failed to generate TOTP code" ) ;
455+ let code = totp
456+ . generate_current ( )
457+ . expect ( "Failed to generate TOTP code" ) ;
440458 verbose_log ( & args, format ! ( "Generated TOTP code: {}" , code) . as_str ( ) ) ;
441-
459+
442460 // Finalize 2FA setup
443461 let mut finalize_body: HashMap < & str , Value > = HashMap :: new ( ) ;
444462 finalize_body. insert ( "code" , code. into ( ) ) ;
445-
463+
446464 let resp = make_request (
447465 args,
448466 reqwest:: Method :: POST ,
@@ -458,7 +476,7 @@ fn enable_totp(args: &CliArgs) {
458476 if let Some ( recovery_key) = resp. get ( "recoveryKey" ) . and_then ( |v| v. as_str ( ) ) {
459477 println ! ( "Recovery key: {}" , recovery_key) ;
460478 }
461-
479+
462480 println ! ( "TOTP is now enabled" ) ;
463481}
464482
0 commit comments