diff --git a/src/main.rs b/src/main.rs index 28cbb09..6788d4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,6 +49,7 @@ pub mod token; pub mod feed_get; pub mod feed_watch; pub mod delete_record; +pub mod update_handle; #[cfg(test)] mod tests; @@ -169,6 +170,11 @@ fn main() { .alias("c"), ) ) + .command( + Command::new("update-handle") + .description("update-handle ") + .action(update_handle) + ) .command( Command::new("card") .description("-v -i -p -r -c -a -img -rare ") @@ -645,6 +651,22 @@ fn delete(c: &Context) { return res; } +fn update_handle(c: &Context) { + refresh(c); + if c.args.is_empty() { + eprintln!("Error: New handle is required."); + eprintln!("Usage: aibot update-handle "); + std::process::exit(1); + } + let new_handle = c.args[0].to_string(); + let h = async { + let str = update_handle::post_request(new_handle); + println!("{}", str.await); + }; + let res = tokio::runtime::Runtime::new().unwrap().block_on(h); + return res; +} + fn like(c: &Context) { refresh(c); if c.args.is_empty() { diff --git a/src/token.rs b/src/token.rs index 5547063..22f750c 100644 --- a/src/token.rs +++ b/src/token.rs @@ -1,15 +1,40 @@ use crate::http_client::HttpClient; use std::collections::HashMap; +use std::io::{self, Write}; pub async fn post_request(handle: String, pass: String, host: String, auth_factor_token: Option) -> String { + // First attempt with provided 2FA code (if any) + let response = create_session_request(&handle, &pass, &host, auth_factor_token.as_deref()).await; + + // Check if 2FA is required + if response.contains("AuthFactorTokenRequired") { + println!("🔐 2FA authentication required"); + println!("📧 A sign-in code has been sent to your email address"); + + // Prompt for 2FA code + print!("Enter 2FA code: "); + io::stdout().flush().unwrap(); + let mut code = String::new(); + io::stdin().read_line(&mut code).unwrap(); + let code = code.trim(); + + // Retry with 2FA code + println!("🔄 Retrying authentication with 2FA code..."); + return create_session_request(&handle, &pass, &host, Some(code)).await; + } + + response +} + +async fn create_session_request(handle: &str, pass: &str, host: &str, auth_factor_token: Option<&str>) -> String { let url = format!("https://{}/xrpc/com.atproto.server.createSession", host); let mut map = HashMap::new(); - map.insert("identifier", &handle); - map.insert("password", &pass); + map.insert("identifier", handle); + map.insert("password", pass); // Add 2FA code if provided - if let Some(code) = &auth_factor_token { + if let Some(code) = auth_factor_token { map.insert("authFactorToken", code); } diff --git a/src/update_handle.rs b/src/update_handle.rs new file mode 100644 index 0000000..b1aaf8e --- /dev/null +++ b/src/update_handle.rs @@ -0,0 +1,17 @@ +use crate::url; +use crate::http_client::HttpClient; +use serde_json::json; + +pub async fn post_request(handle: String) -> String { + let url = url(&"update_handle"); + let client = HttpClient::new(); + + let post = json!({ + "handle": handle + }); + + match client.post_json_with_auth(&url, &post).await { + Ok(response) => response, + Err(e) => format!("Error updating handle: {}", e), + } +} \ No newline at end of file