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

Add 2fa compliance #12

Merged
merged 2 commits into from
Jul 21, 2024
Merged

Add 2fa compliance #12

merged 2 commits into from
Jul 21, 2024

Conversation

C0D3-M4513R
Copy link
Collaborator

@C0D3-M4513R C0D3-M4513R commented May 14, 2024

vrchatapi/specification#241

Adds 2fa support to vrcapi.
The code has been adapted from a commit, from 9 months ago, where I edited source-code.
I adapted the code to the generate.sh file.

Due to issues with compilation and bash, I needed to add the extra lines

@Rexios80
Copy link

What about the existing code doesn't support 2FA?

@C0D3-M4513R
Copy link
Collaborator Author

C0D3-M4513R commented May 14, 2024

What about the existing code doesn't support 2FA?

Previously, if you had 2fa, the response from vrchat would fail to serialise as a CurrentUser.
This would cause serde to spit out an error, which would get wrapped in the Error types.

This PR makes it way easier and way less jank to handle a 2fa-enabled user.

Edit: Also see the mentioned specification issue, where you mentioned, that you handled this manually for the Dart api.

@DerTiedemann
Copy link
Contributor

DerTiedemann commented Jul 20, 2024

I have run into the same issue, leading to me write my own crude implementation, I would love to see this PR merged <3
Edit: Based in this example

pub use vrchatapi::apis;

fn main() {
    let username =
        std::env::var("VRCHAT_USERNAME").expect("Missing VRCHAT_USERNAME environment variable");
    let password =
        std::env::var("VRCHAT_PASSWORD").expect("Missing VRCHAT_PASSWORD environment variable");

    let config = apis::configuration::Configuration {
        basic_auth: Some((username, Some(password))),
        user_agent: Some(
            "Mozilla/5.0 (Windows NT 6.1; rv:40.0) Gecko/20100101 Firefox/40.0".to_string(),
        ),
        ..Default::default()
    };

    let me =
        apis::authentication_api::get_current_user(&config).expect("Failed to get current user");
    println!("Username: {:?}", me.username);

    let online = apis::system_api::get_current_online_users(&config).unwrap();
    println!("Current Online Users: {}", online);
}

I get the following error with an account that has 2FA set up:

thread 'main' panicked at examples/online.rs:18:61:
Failed to get current user: Serde(Error("missing field `acceptedTOSVersion`", line: 1, column: 40))

This PR would fix that Serialization error and would give a clear and consise way of dealing with unknown account states via a simple match.

Copy link
Member

@ariesclark ariesclark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase your PR to the latest commit.

@C0D3-M4513R
Copy link
Collaborator Author

I was just doing exactly that.

@DerTiedemann
Copy link
Contributor

Tested with this code:

use std::io::BufRead;

pub use vrchatapi::{apis, models};

#[tokio::main]
async fn main() {
    let username =
        std::env::var("VRCHAT_USERNAME").expect("Missing VRCHAT_USERNAME environment variable");
    let password =
        std::env::var("VRCHAT_PASSWORD").expect("Missing VRCHAT_PASSWORD environment variable");

    let config = apis::configuration::Configuration {
        basic_auth: Some((username, Some(password))),
        user_agent: Some(
            "Mozilla/5.0 (Windows NT 6.1; rv:40.0) Gecko/20100101 Firefox/40.0".to_string(),
        ),
        ..Default::default()
    };

    let me = apis::authentication_api::get_current_user(&config)
        .await
        .expect("Failed to get current user");
    match me {
        vrchatapi::models::EitherUserOrTwoFactor::CurrentUser(me) => {
            println!("Current User: {}", me.display_name);
        }
        vrchatapi::models::EitherUserOrTwoFactor::RequiresTwoFactorAuth(_two_factor_type) => {
            // i should check here if its email or TOTP
            let mut code = String::new();
            let stdin = std::io::stdin();
            stdin
                .lock()
                .read_line(&mut code)
                .expect("Failed to read line");
            let resp =
                apis::authentication_api::verify2_fa(&config, models::TwoFactorAuthCode::new(code))
                    .await
                    .expect("Failed to verify 2FA");
            if !resp.verified {
                panic!("Failed to verify 2FA");
            }
        }
    }

    let online = apis::system_api::get_current_online_users(&config)
        .await
        .unwrap();
    println!("Current Online Users: {}", online);
}

Copy link
Contributor

@DerTiedemann DerTiedemann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
Trejo Chefs Kiss

@ariesclark ariesclark merged commit b1f02f4 into vrchatapi:main Jul 21, 2024
1 check passed
@C0D3-M4513R C0D3-M4513R deleted the 2fa branch July 21, 2024 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants