Something went wrong. Try again.
A simple text chat CLI and Proof of Concept for AT Micro.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475pub mod web;
use atproto_identity::key::{KeyData, KeyType, generate_key};use atproto_oauth::{resources::pds_resources, workflow::{OAuthClient, OAuthRequest, OAuthRequestState, TokenResponse}};
pub const OAUTH_PORT: u16 = 57676;
pub async fn login_oauth(http_client: &atproto_client::reqwest::Client, handle: &str, did_document: &atproto_identity::model::Document) -> anyhow::Result<(OAuthClient, TokenResponse, KeyData)> { let pds_endpoint = atproto_lexicon::resolve::pds_endpoint(did_document)?; let (_, authorization_server) = pds_resources(http_client, &pds_endpoint).await?; let signing_key = generate_key(KeyType::P256Private)?; let dpop_key_data = generate_key(KeyType::P256Private)?; let scope = "atproto space:gay.sylv.at-micro.room.meta?action=read".to_owned(); // let scope = "atproto repo:app.bsky.feed.post".to_owned(); let (pkce_verifier, code_challenge) = atproto_oauth::pkce::generate(); let redirect_uri = format!("http://127.0.0.1:{OAUTH_PORT}"); let oauth_client = OAuthClient { client_id: format!("http://localhost?scope={}", urlencoding::encode(&scope)), redirect_uri: redirect_uri.clone(), private_signing_key_data: signing_key, }; let oauth_request_state = OAuthRequestState { state: "0".to_owned(), code_challenge, scope, }; let par_response = atproto_oauth::workflow::oauth_init( http_client, &oauth_client, &dpop_key_data, Some(handle), &authorization_server, &oauth_request_state ).await?; let now = chrono::Utc::now(); let oauth_request = OAuthRequest { oauth_state: "0".to_owned(), subject: did_document.id.clone(), issuer: authorization_server.issuer.clone(), pkce_verifier, signing_public_key: atproto_identity::key::to_public(&oauth_client.private_signing_key_data)?.to_string(), dpop_private_key: dpop_key_data.to_string(), created_at: now, expires_at: now + chrono::Duration::seconds(par_response.expires_in as i64), };
// Begin the local OAuth process. // This will require starting a temporary web server that takes the redirect. // I am so very sorry to every terminal user ever. Please forgive me. // AT Protocol Spaces requires OAuth to function. // TODO: somehow don't require a browser for oauth let authorization_url = format!( "{}?client_id={}&request_uri={}", authorization_server.authorization_endpoint, urlencoding::encode(&oauth_client.client_id), par_response.request_uri, ); webbrowser::open(&authorization_url)?; println!("A new tab has been opened. Please navigate to your web browser to complete login.\r"); let oauth_response = web::oauth_redirect().await?;
let token_response = atproto_oauth::workflow::oauth_complete( http_client, &oauth_client, &dpop_key_data, &oauth_response.code, &did_document.id, Some(&oauth_response.iss), &oauth_request, &authorization_server ).await?; // BasicClient::new(ClientId::new("http://localhost:{OAUTH_PORT}/oauth-client-metadata.json")); Ok((oauth_client, token_response, dpop_key_data))}