use crate::services::oauth::constants::get_oauth_config;
use crate::services::oauth::types::OAuthProfileResponse;
pub async fn get_oauth_profile_from_oauth_token(
access_token: &str,
) -> Option<OAuthProfileResponse> {
let config = get_oauth_config();
let endpoint = format!("{}/api/oauth/profile", config.base_api_url);
let client = reqwest::Client::builder()
.user_agent(crate::utils::user_agent::get_user_agent())
.timeout(std::time::Duration::from_secs(10))
.build()
.ok()?;
let response = client
.get(&endpoint)
.header("Authorization", format!("Bearer {access_token}"))
.header("Content-Type", "application/json")
.send()
.await
.ok()?;
if !response.status().is_success() {
log::warn!(
"Failed to fetch OAuth profile: status={}",
response.status()
);
return None;
}
response.json().await.ok()
}
pub async fn get_oauth_profile_from_api_key(
account_uuid: &str,
api_key: &str,
) -> Option<OAuthProfileResponse> {
let config = get_oauth_config();
let endpoint = format!("{}/api/claude_cli_profile", config.base_api_url);
let client = reqwest::Client::builder()
.user_agent(crate::utils::user_agent::get_user_agent())
.timeout(std::time::Duration::from_secs(10))
.build()
.ok()?;
let response = client
.get(&endpoint)
.header("x-api-key", api_key)
.header("anthropic-beta", crate::services::oauth::types::OAUTH_BETA_HEADER)
.query(&[("account_uuid", account_uuid)])
.send()
.await
.ok()?;
if !response.status().is_success() {
log::warn!(
"Failed to fetch OAuth profile from API key: status={}",
response.status()
);
return None;
}
response.json().await.ok()
}
pub fn extract_subscription_type(profile: &OAuthProfileResponse) -> Option<String> {
let org_type = profile
.extra
.get("organization")
.and_then(|v| v.get("organization_type"))
.and_then(|v| v.as_str())?;
match org_type {
"claude_max" => Some("max".to_string()),
"claude_pro" => Some("pro".to_string()),
"claude_enterprise" => Some("enterprise".to_string()),
"claude_team" => Some("team".to_string()),
_ => None,
}
}
pub fn extract_organization_uuid(profile: &OAuthProfileResponse) -> Option<String> {
profile
.extra
.get("organization")
.and_then(|v| v.get("uuid"))
.and_then(|v| v.as_str())
.map(|s| s.to_string())
}
pub fn extract_rate_limit_tier(profile: &OAuthProfileResponse) -> Option<String> {
profile
.extra
.get("organization")
.and_then(|v| v.get("rate_limit_tier"))
.and_then(|v| v.as_str())
.map(|s| s.to_string())
}