use crate::auth::{save_config, AuthConfig}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize)] struct CreateSessionRequest { identifier: String, password: String, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] struct CreateSessionResponse { did: String, handle: String, access_jwt: String, refresh_jwt: String, } pub async fn run(handle: &str, password: &str, server: &str) -> Result<(), Box> { // Add https:// if no protocol specified let server = if server.starts_with("http://") || server.starts_with("https://") { server.to_string() } else { format!("https://{}", server) }; println!("Logging in as {} to {}", handle, server); let client = reqwest::Client::new(); let url = format!("{}/xrpc/com.atproto.server.createSession", server); let req = CreateSessionRequest { identifier: handle.to_string(), password: password.to_string(), }; let res = client .post(&url) .json(&req) .send() .await?; if !res.status().is_success() { let status = res.status(); let body = res.text().await?; return Err(format!("Login failed ({}): {}", status, body).into()); } let session: CreateSessionResponse = res.json().await?; let config = AuthConfig { handle: session.handle.clone(), did: session.did.clone(), access_jwt: session.access_jwt, refresh_jwt: session.refresh_jwt, pds: server.to_string(), }; save_config(&config)?; println!("Logged in successfully!"); println!("DID: {}", session.did); println!("Handle: {}", session.handle); Ok(()) }