Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sign_in problem #264

Open
0xthecableguy opened this issue Sep 17, 2024 · 6 comments
Open

sign_in problem #264

0xthecableguy opened this issue Sep 17, 2024 · 6 comments

Comments

@0xthecableguy
Copy link

0xthecableguy commented Sep 17, 2024

hello, can't authorize client via telegram

if !client.is_authorized().await? {
        if state.awaiting_phone_number {
            if let Some(phone) = msg.text() {
                state.phone_number = Some(phone.to_string());
                state.awaiting_phone_number = false;
                state.awaiting_passcode = true;
                let token = client.request_login_code(phone).await?;
                state.token = Some(Arc::new(token));
                bot.send_message(msg.chat.id, "Phone number received! Please provide the passcode.")
                    .await?;
            }
        } else if state.awaiting_passcode {
            if let Some(code) = msg.text() {
                state.passcode = Some(code.to_string());
                state.awaiting_passcode = false;
                if let Some(token) = &state.token {
                    let token = Arc::clone(token); // Clone the Arc
                    match client.sign_in(&token, code).await {
                        Ok(_) => {
                            bot.send_message(msg.chat.id, "Successfully authorized!")
                                .await?;
                        }
                        Err(SignInError::PasswordRequired(password_token)) => {
                            let hint = password_token.hint().unwrap_or("No hint");
                            state.awaiting_2fa = true;
                            state.password_token = Some(password_token.clone());
                            bot.send_message(msg.chat.id, format!("2FA required. Hint: {}. Please enter your 2FA password.", hint))
                                .await?;
                        }
                        Err(e) => {
                            bot.send_message(msg.chat.id, format!("Failed to sign in: {}", e))
                                .await?;
                            return Err(e.into());
                        }
                    }
                }
            }
        } else if state.awaiting_2fa {
            if let Some(password) = msg.text() {
                if let Some(password_token) = &state.password_token {
                    match client.check_password(password_token.clone(), password).await {
                        Ok(_) => {
                            bot.send_message(msg.chat.id, "Successfully authorized with 2FA!")
                                .await?;
                        }
                        Err(e) => {
                            bot.send_message(msg.chat.id, format!("Failed to authorize with 2FA: {}", e))
                                .await?;
                            return Err(e.into());
                        }
                    }
                }
            }
        }
    } else {
        bot.send_message(msg.chat.id, "Already authorized!")
            .await?;
    }

I got phone_number from user via telegram bot, then fall into state awaiting passcode, create token:

    let token = client.request_login_code(phone).await?;

and then i get passcode from telegram to my cellphone, typing it into bot... and got:

Incomplete login attempt. Dear ***, Telegram blocked an attempt to log into your account from a new device on 16/09/2024 at 22:46:49 UTC.

Device: app_name, 0.6.0, Mac OS 64-bit, Desktop, 14.6.1
Location: ***

Nobody gained access to your chats because the login was not completed. The code was entered correctly, but sign in was not allowed, because this code was previously shared by your account.

Please don't share login codes with others, because they allow anyone to log in to your account and access your chats.

is there any way to authorize this way?

@Lonami
Copy link
Owner

Lonami commented Sep 18, 2024

Did you use the library from crates.io, or the git version? If the former, try the git version.

@0xthecableguy
Copy link
Author

0xthecableguy commented Sep 18, 2024

i use following:

grammers = { git = "https://github.com/Lonami/grammers.git", branch = "master" }
grammers-client = { git = "https://github.com/Lonami/grammers.git", package = "grammers-client", branch = "master" }
grammers-session = { git = "https://github.com/Lonami/grammers.git", package = "grammers-session", branch = "master" }

strange thing is that telegram says me: "The code was entered correctly, but sign in was not allowed, because this code was previously shared by your account."

maybe some trouble with storing token in the user states' structures?

#[derive(Default, Clone)]
pub struct AuthStages {
    pub awaiting_phone_number: bool,
    pub awaiting_passcode: bool,
    pub awaiting_2fa: bool,
    pub phone_number: Option<String>,
    pub passcode: Option<String>,
    pub two_fa: Option<String>,
    pub client: Option<Client>,
    pub token: Option<Arc<LoginToken>>,
    pub password_token: Option<PasswordToken>,
}

#[derive(Default)]
pub struct AppState {
    pub user_state: Mutex<HashMap<u64, AuthStages>>,
}

@Lonami
Copy link
Owner

Lonami commented Sep 18, 2024

If the code is sent in a Telegram message, it will immediately expire.

@0xthecableguy
Copy link
Author

so how should i transfer it here

client.sign_in(&token, code)

I got the code, sending it via telegram bot, processing this message, and sending code and token to the authorization fn

@0xthecableguy
Copy link
Author

0xthecableguy commented Sep 18, 2024

pub(crate) async fn auth_data_processing(bot: Bot, msg: Message, app_state: Arc<AppState>, mut state: AuthStages) -> anyhow::Result<()> {
    let user_id = msg.from.as_ref().map(|user| user.id.0).unwrap_or(0);
    
    // Check and set client
    if state.client.is_none() {
        let session_file = format!("{}.session", msg.chat.id);
        let client = Client::connect(Config {
            session: Session::load_file_or_create(session_file.clone())?,
            api_id: API_ID,
            api_hash: API_HASH.to_string(),
            params: Default::default(),
        }).await?;
        state.client = Some(client.clone());
        // client.session().save_to_file(format!("{}.session", msg.chat.id))?;
    }
    
    let client = state.client.as_ref().unwrap();

    // Handle authorization
    if !client.is_authorized().await? {
        if state.awaiting_phone_number {
            if let Some(phone) = msg.text() {
                state.phone_number = Some(phone.to_string());
                state.awaiting_phone_number = false;
                state.awaiting_passcode = true;
                let token = client.request_login_code(phone).await?;
                state.token = Some(Arc::new(token));
                bot.send_message(msg.chat.id, "Phone number received! Please provide the passcode.")
                    .await?;
                
                let mut user_states = app_state.user_state.lock().await;
                user_states.insert(user_id, state.clone());
            }
        } else if state.awaiting_passcode {
            if let Some(code) = msg.text() {
                info!("got code: {}", code);
                state.passcode = Some(code.to_string());
                state.awaiting_passcode = false;
                if let Some(token) = state.token.as_ref() {
                    // let token = Arc::clone(token); // Clone the Arc
                    sleep(Dur::from_secs(2)).await;
                    match client.sign_in(&token, code).await {
                        Ok(_) => {
                            bot.send_message(msg.chat.id, "Successfully authorized!")
                                .await?;
                        }
                        Err(SignInError::PasswordRequired(password_token)) => {
                            let hint = password_token.hint().unwrap_or("No hint");
                            state.awaiting_2fa = true;
                            state.password_token = Some(password_token.clone());
                            bot.send_message(msg.chat.id, format!("2FA required. Hint: {}. Please enter your 2FA password.", hint))
                                .await?;
                        }
                        Err(e) => {
                            bot.send_message(msg.chat.id, format!("Failed to sign in: {}", e))
                                .await?;
                            return Err(e.into());
                        }
                    }
                }
            }
        } else if state.awaiting_2fa {
            if let Some(password) = msg.text() {
                if let Some(password_token) = &state.password_token {
                    match client.check_password(password_token.clone(), password).await {
                        Ok(_) => {
                            bot.send_message(msg.chat.id, "Successfully authorized with 2FA!")
                                .await?;
                        }
                        Err(e) => {
                            bot.send_message(msg.chat.id, format!("Failed to authorize with 2FA: {}", e))
                                .await?;
                            return Err(e.into());
                        }
                    }
                }
            }
        }
    } else {
        bot.send_message(msg.chat.id, "Already authorized!")
            .await?;
    }

    // Update the state in user_states
    let mut user_states = app_state.user_state.lock().await;
    user_states.insert(user_id, state);

    Ok(())
}

in case you would like see the code of the auth fn

@Lonami
Copy link
Owner

Lonami commented Sep 19, 2024

sending it via telegram bot

Don't. It expires.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants