diff --git a/src/commands/setup.rs b/src/commands/setup.rs index d050437..381c02d 100644 --- a/src/commands/setup.rs +++ b/src/commands/setup.rs @@ -16,7 +16,14 @@ use super::*; #[derive(Debug, Clone, Parser)] #[clap(about = "Set up a new account with steamguard-cli")] -pub struct SetupCommand; +pub struct SetupCommand { + #[clap( + long, + help = "What version of 2FA token to tell Steam to use. The token version determines the default methods that Steam will use to let you log in. If you're unsure, leave this at the default value.", + default_value = "2" + )] + pub token_version: u32, +} impl ManifestCommand for SetupCommand where @@ -45,7 +52,7 @@ where info!("Adding authenticator..."); let mut linker = AccountLinker::new(transport.clone(), tokens); loop { - match linker.link() { + match linker.link(self.token_version) { Ok(link) => { return Self::add_new_account(link, manager, account_name, linker); } @@ -92,7 +99,7 @@ where } loop { - if let Err(err) = Self::transfer_new_account(&mut linker, manager) { + if let Err(err) = self.transfer_new_account(&mut linker, manager) { error!("Failed to transfer authenticator. {}", err); info!("There's nothing else to be done right now. Wait a few minutes and try again."); match tui::prompt_char("Would you like to try again?", "yN") { @@ -257,6 +264,7 @@ impl SetupCommand { /// Transfer an existing authenticator to steamguard-cli. fn transfer_new_account( + &self, linker: &mut AccountLinker, manager: &mut AccountManager, ) -> anyhow::Result<()> @@ -273,7 +281,7 @@ impl SetupCommand { let account: SteamGuardAccount; loop { let sms_code = tui::prompt_non_empty("Enter SMS code: "); - match linker.transfer_finish(sms_code) { + match linker.transfer_finish(sms_code, self.token_version) { Ok(acc) => { account = acc; break; diff --git a/steamguard/src/accountlinker.rs b/steamguard/src/accountlinker.rs index 64cfcae..2f3229d 100644 --- a/steamguard/src/accountlinker.rs +++ b/steamguard/src/accountlinker.rs @@ -43,7 +43,7 @@ where &self.tokens } - pub fn link(&mut self) -> Result { + pub fn link(&mut self, token_version: u32) -> Result { let access_token = self.tokens.access_token(); let steam_id = access_token .decode() @@ -58,7 +58,7 @@ where // Currently, the version value determines what `EAuthSessionGuardType` values are allowed during the login process. // Version 2 allows `EAuthSessionGuardType::k_EAuthSessionGuardType_DeviceConfirmation`, where version 1 does not. // However, the device confirmation auth guard does not emit a typical 2fa confirmation, so it doesn't show up when running `steamguard confirm`. - req.set_version(2); + req.set_version(token_version); let resp = self .client @@ -178,7 +178,7 @@ where /// Begin the process of "transfering" a mobile authenticator from a different device to this device. /// - /// "Transfering" does not actually literally transfer the secrets from one device to another. Instead, it generates a new set of secrets on this device, and invalidates the old secrets on the other device. Call [`Self::transfer_finish`] to complete the process. + /// "Transfering" does not actually literally transfer the secrets from one device to another. Instead, it generates a new set of secrets for this device, and invalidates the old secrets on the other device. However, it does preserve the revocation code. Call [`Self::transfer_finish`] to complete the process. /// /// As of 2025-02-07, transfering an authenticator requires a phone number to be present on the account. If there is no phone number on the account, this method will return an error. pub fn transfer_start(&mut self) -> Result<(), TransferError> { @@ -199,6 +199,7 @@ where pub fn transfer_finish( &mut self, sms_code: impl AsRef, + token_version: u32, ) -> Result { let access_token = self.tokens.access_token(); let steam_id = access_token @@ -208,7 +209,7 @@ where let mut req = CTwoFactor_RemoveAuthenticatorViaChallengeContinue_Request::new(); req.set_sms_code(sms_code.as_ref().to_owned()); req.set_generate_new_token(true); - req.set_version(2); // Version has the same meaning as it does in AddAuthenticator Request, see `link()` above. + req.set_version(token_version); // Version has the same meaning as it does in AddAuthenticator Request, see `link()` above. let resp = self .client .remove_authenticator_via_challenge_continue(req, access_token)?;