Merge pull request #175 from dyc3/setup-update
fix using uppercase letters in username during setup causing panic
This commit is contained in:
commit
27adb3d019
5 changed files with 54 additions and 18 deletions
|
@ -318,6 +318,12 @@ impl Manifest {
|
||||||
self.entries.iter().any(|e| e.account_name.is_empty())
|
self.entries.iter().any(|e| e.account_name.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_any_uppercase_in_account_names(&self) -> bool {
|
||||||
|
self.entries
|
||||||
|
.iter()
|
||||||
|
.any(|e| e.account_name != e.account_name.to_lowercase())
|
||||||
|
}
|
||||||
|
|
||||||
/// Performs auto-upgrades on the manifest. Returns true if any upgrades were performed.
|
/// Performs auto-upgrades on the manifest. Returns true if any upgrades were performed.
|
||||||
pub fn auto_upgrade(&mut self) -> anyhow::Result<bool, ManifestAccountLoadError> {
|
pub fn auto_upgrade(&mut self) -> anyhow::Result<bool, ManifestAccountLoadError> {
|
||||||
debug!("Performing auto-upgrade...");
|
debug!("Performing auto-upgrade...");
|
||||||
|
@ -331,6 +337,14 @@ impl Manifest {
|
||||||
upgraded = true;
|
upgraded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.has_any_uppercase_in_account_names() {
|
||||||
|
debug!("Lowercasing account names");
|
||||||
|
for i in 0..self.entries.len() {
|
||||||
|
self.entries[i].account_name = self.entries[i].account_name.to_lowercase();
|
||||||
|
}
|
||||||
|
upgraded = true;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(upgraded)
|
Ok(upgraded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,7 @@ pub(crate) struct ArgsCompletions {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
#[clap(about = "Set up a new account with steamguard-cli")]
|
#[clap(about = "Set up a new account with steamguard-cli")]
|
||||||
pub(crate) struct ArgsSetup {
|
pub(crate) struct ArgsSetup {}
|
||||||
#[clap(short, long, from_global, help = "Steam username, case-sensitive.")]
|
|
||||||
pub username: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
#[clap(about = "Import an account with steamguard already set up")]
|
#[clap(about = "Import an account with steamguard already set up")]
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -275,7 +275,7 @@ fn do_login_impl(
|
||||||
login.captcha_text = tui::prompt_captcha_text(&captcha_gid);
|
login.captcha_text = tui::prompt_captcha_text(&captcha_gid);
|
||||||
}
|
}
|
||||||
Err(LoginError::NeedEmail) => {
|
Err(LoginError::NeedEmail) => {
|
||||||
println!("You should have received an email with a code.");
|
println!("You should have received an email with a code. If you did not, check your spam folder, or abort and try again.");
|
||||||
print!("Enter code: ");
|
print!("Enter code: ");
|
||||||
login.email_code = tui::prompt();
|
login.email_code = tui::prompt();
|
||||||
}
|
}
|
||||||
|
@ -349,18 +349,12 @@ fn do_subcmd_completion(args: cli::ArgsCompletions) -> Result<(), anyhow::Error>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_subcmd_setup(
|
fn do_subcmd_setup(
|
||||||
args: cli::ArgsSetup,
|
_args: cli::ArgsSetup,
|
||||||
manifest: &mut accountmanager::Manifest,
|
manifest: &mut accountmanager::Manifest,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
println!("Log in to the account that you want to link to steamguard-cli");
|
println!("Log in to the account that you want to link to steamguard-cli");
|
||||||
print!("Username: ");
|
print!("Username: ");
|
||||||
let username = if args.username.is_some() {
|
let username = tui::prompt().to_lowercase();
|
||||||
let u = args.username.unwrap();
|
|
||||||
println!("{}", u);
|
|
||||||
u
|
|
||||||
} else {
|
|
||||||
tui::prompt()
|
|
||||||
};
|
|
||||||
let account_name = username.clone();
|
let account_name = username.clone();
|
||||||
if manifest.account_exists(&username) {
|
if manifest.account_exists(&username) {
|
||||||
bail!(
|
bail!(
|
||||||
|
@ -368,8 +362,10 @@ fn do_subcmd_setup(
|
||||||
username
|
username
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
info!("Logging in to {}", username);
|
||||||
let session = do_login_raw(username).expect("Failed to log in. Account has not been linked.");
|
let session = do_login_raw(username).expect("Failed to log in. Account has not been linked.");
|
||||||
|
|
||||||
|
info!("Adding authenticator...");
|
||||||
let mut linker = AccountLinker::new(session);
|
let mut linker = AccountLinker::new(session);
|
||||||
let account: SteamGuardAccount;
|
let account: SteamGuardAccount;
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -62,6 +62,9 @@ impl AccountLinker {
|
||||||
return Err(AccountLinkError::AuthenticatorPresent);
|
return Err(AccountLinkError::AuthenticatorPresent);
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
|
// If the user has no phone number on their account, it will always return this status code.
|
||||||
|
// However, this does not mean that this status just means "no phone number". It can also
|
||||||
|
// be literally anything else, so that's why we return GenericFailure here.
|
||||||
return Err(AccountLinkError::GenericFailure);
|
return Err(AccountLinkError::GenericFailure);
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
|
@ -129,7 +132,7 @@ pub enum AccountLinkError {
|
||||||
MustConfirmEmail,
|
MustConfirmEmail,
|
||||||
#[error("Authenticator is already present.")]
|
#[error("Authenticator is already present.")]
|
||||||
AuthenticatorPresent,
|
AuthenticatorPresent,
|
||||||
#[error("Steam was unable to link the authenticator to the account. No additional information about this error is available. This is a Steam error, not a steamguard-cli error. Try adding a phone number to your Steam account, or try again later.")]
|
#[error("Steam was unable to link the authenticator to the account. No additional information about this error is available. This is a Steam error, not a steamguard-cli error. Try adding a phone number to your Steam account (which you can do here: https://store.steampowered.com/phone/add), or try again later.")]
|
||||||
GenericFailure,
|
GenericFailure,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Unknown(#[from] anyhow::Error),
|
Unknown(#[from] anyhow::Error),
|
||||||
|
|
|
@ -353,6 +353,8 @@ impl SteamApiClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Likely removed now
|
||||||
|
///
|
||||||
/// One of the endpoints that handles phone number things. Can check to see if phone is present on account, and maybe do some other stuff. It's not really super clear.
|
/// One of the endpoints that handles phone number things. Can check to see if phone is present on account, and maybe do some other stuff. It's not really super clear.
|
||||||
///
|
///
|
||||||
/// Host: steamcommunity.com
|
/// Host: steamcommunity.com
|
||||||
|
@ -442,14 +444,26 @@ impl SteamApiClient {
|
||||||
/// Provides lots of juicy information, like if the number is a VOIP number.
|
/// Provides lots of juicy information, like if the number is a VOIP number.
|
||||||
/// Host: store.steampowered.com
|
/// Host: store.steampowered.com
|
||||||
/// Endpoint: POST /phone/validate
|
/// Endpoint: POST /phone/validate
|
||||||
|
/// Body format: form data
|
||||||
|
/// Example:
|
||||||
|
/// ```form
|
||||||
|
/// sessionID=FOO&phoneNumber=%2B1+1234567890
|
||||||
|
/// ```
|
||||||
/// Found on page: https://store.steampowered.com/phone/add
|
/// Found on page: https://store.steampowered.com/phone/add
|
||||||
pub fn phone_validate(&self, phone_number: String) -> anyhow::Result<bool> {
|
pub fn phone_validate(&self, phone_number: &String) -> anyhow::Result<PhoneValidateResponse> {
|
||||||
let params = hashmap! {
|
let params = hashmap! {
|
||||||
"sessionID" => "",
|
"sessionID" => self.session.as_ref().unwrap().expose_secret().session_id.as_str(),
|
||||||
"phoneNumber" => "",
|
"phoneNumber" => phone_number.as_str(),
|
||||||
};
|
};
|
||||||
|
|
||||||
todo!();
|
let resp = self
|
||||||
|
.client
|
||||||
|
.post("https://store.steampowered.com/phone/validate")
|
||||||
|
.form(¶ms)
|
||||||
|
.send()?
|
||||||
|
.json::<PhoneValidateResponse>()?;
|
||||||
|
|
||||||
|
return Ok(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts the authenticator linking process.
|
/// Starts the authenticator linking process.
|
||||||
|
@ -648,6 +662,8 @@ pub struct AddAuthenticatorResponse {
|
||||||
pub secret_1: String,
|
pub secret_1: String,
|
||||||
/// Result code
|
/// Result code
|
||||||
pub status: i32,
|
pub status: i32,
|
||||||
|
#[serde(default)]
|
||||||
|
pub phone_number_hint: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddAuthenticatorResponse {
|
impl AddAuthenticatorResponse {
|
||||||
|
@ -678,6 +694,16 @@ pub struct FinalizeAddAuthenticatorResponse {
|
||||||
pub success: bool,
|
pub success: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct PhoneValidateResponse {
|
||||||
|
success: bool,
|
||||||
|
number: String,
|
||||||
|
is_valid: bool,
|
||||||
|
is_voip: bool,
|
||||||
|
is_fixed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct RemoveAuthenticatorResponse {
|
pub struct RemoveAuthenticatorResponse {
|
||||||
pub success: bool,
|
pub success: bool,
|
||||||
|
|
Loading…
Reference in a new issue