use crate::api::EpicAPI;
use crate::api::error::EpicAPIError;
use crate::api::types::account::UserData;
use log::{error, info, warn};
use reqwest::Response;
impl EpicAPI {
pub async fn start_session(
&mut self,
exchange_token: Option<String>,
authorization_code: Option<String>,
) -> Result<bool, EpicAPIError> {
let params = match exchange_token {
None => match authorization_code {
None => [
("grant_type".to_string(), "refresh_token".to_string()),
(
"refresh_token".to_string(),
self.user_data
.refresh_token
.as_ref()
.ok_or(EpicAPIError::InvalidCredentials)?
.clone(),
),
("token_type".to_string(), "eg1".to_string()),
],
Some(auth) => [
("grant_type".to_string(), "authorization_code".to_string()),
("code".to_string(), auth),
("token_type".to_string(), "eg1".to_string()),
],
},
Some(exchange) => [
("grant_type".to_string(), "exchange_code".to_string()),
("exchange_code".to_string(), exchange),
("token_type".to_string(), "eg1".to_string()),
],
};
match self
.client
.post("https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token")
.form(¶ms)
.basic_auth(
"34a02cf8f4414e29b15921876da36f9a",
Some("daafbccc737745039dffe53d94fc76cf"),
)
.send()
.await
{
Ok(response) => self.handle_login_response(response).await,
Err(e) => {
error!("{:?}", e);
Err(EpicAPIError::NetworkError(e))
}
}
}
async fn handle_login_response(&mut self, response: Response) -> Result<bool, EpicAPIError> {
if response.status() == reqwest::StatusCode::INTERNAL_SERVER_ERROR {
error!("Server Error");
return Err(EpicAPIError::Server);
}
let new: UserData = match response.json().await {
Ok(data) => data,
Err(e) => {
error!("{:?}", e);
return Err(EpicAPIError::DeserializationError(format!("{}", e)));
}
};
self.user_data.update(new);
if let Some(m) = &self.user_data.error_message {
error!("{}", m);
return Err(EpicAPIError::APIError(m.to_string()));
}
Ok(true)
}
pub async fn resume_session(&mut self) -> Result<bool, EpicAPIError> {
let url = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/verify";
match self
.authorized_get_client(url::Url::parse(url).map_err(|_| EpicAPIError::InvalidParams)?)
.send()
.await
{
Ok(response) => self.handle_login_response(response).await,
Err(e) => {
error!("{:?}", e);
Err(EpicAPIError::NetworkError(e))
}
}
}
pub async fn start_client_credentials_session(&mut self) -> Result<bool, EpicAPIError> {
let params = [
("grant_type".to_string(), "client_credentials".to_string()),
("token_type".to_string(), "eg1".to_string()),
];
match self
.client
.post("https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token")
.form(¶ms)
.basic_auth(
"34a02cf8f4414e29b15921876da36f9a",
Some("daafbccc737745039dffe53d94fc76cf"),
)
.send()
.await
{
Ok(response) => self.handle_login_response(response).await,
Err(e) => {
error!("{:?}", e);
Err(EpicAPIError::NetworkError(e))
}
}
}
pub async fn auth_sid(&mut self, sid: &str) -> Result<bool, EpicAPIError> {
let set_sid_url = format!("https://www.epicgames.com/id/api/set-sid?sid={}", sid);
self.client
.get(&set_sid_url)
.header(
"User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) EpicGamesLauncher/17.0.1 UnrealEngine/4.23.0 Chrome/84.0.4147.38 Safari/537.36",
)
.send()
.await
.map_err(|e| {
error!("{:?}", e);
EpicAPIError::NetworkError(e)
})?;
let csrf_response = self
.client
.get("https://www.epicgames.com/id/api/csrf")
.send()
.await
.map_err(|e| {
error!("{:?}", e);
EpicAPIError::NetworkError(e)
})?;
let xsrf_token = csrf_response
.cookies()
.find(|c| c.name() == "XSRF-TOKEN")
.map(|c| c.value().to_string())
.ok_or_else(|| {
error!("XSRF-TOKEN cookie not found");
EpicAPIError::InvalidCredentials
})?;
let exchange_response = self
.client
.post("https://www.epicgames.com/id/api/exchange/generate")
.header("X-XSRF-TOKEN", &xsrf_token)
.send()
.await
.map_err(|e| {
error!("{:?}", e);
EpicAPIError::NetworkError(e)
})?;
if exchange_response.status() != reqwest::StatusCode::OK {
let body = exchange_response.text().await.unwrap_or_default();
error!("Exchange code generation failed: {}", body);
return Err(EpicAPIError::APIError(
"Exchange code generation failed".to_string(),
));
}
let exchange_data: crate::api::types::exchange_code::ExchangeCode =
exchange_response.json().await.map_err(|e| {
error!("{:?}", e);
EpicAPIError::DeserializationError(format!("{}", e))
})?;
let code = exchange_data.code.ok_or(EpicAPIError::InvalidCredentials)?;
self.start_session(Some(code), None).await
}
pub async fn invalidate_sesion(&mut self) -> bool {
if let Some(access_token) = &self.user_data.access_token {
let url = format!(
"https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/sessions/kill/{}",
access_token
);
match self.client.delete(&url).send().await {
Ok(_) => {
info!("Session invalidated");
return true;
}
Err(e) => {
warn!("Unable to invalidate session: {}", e)
}
}
};
false
}
}