pub mod config;
pub mod session;
pub mod sliding_sync;
pub mod timeline;
use anyhow::Result;
use matrix_sdk::Client;
use matrix_sdk::authentication::matrix::MatrixSession;
use matrix_sdk::authentication::SessionTokens;
use crate::client::config::ClientConfig;
use crate::persistence::matrix_state::SessionData;
pub async fn build_client(homeserver: &str) -> Result<Client> {
let config = ClientConfig::default();
let db_path = config.data_dir().join("matrix-sdk-state");
std::fs::create_dir_all(&db_path)?;
let client = Client::builder()
.homeserver_url(homeserver)
.sqlite_store(&db_path, None)
.build()
.await?;
Ok(client)
}
pub async fn restore_session(session_data: SessionData) -> Result<Client> {
let client = build_client(&session_data.homeserver_url).await?;
let user_id = matrix_sdk::ruma::OwnedUserId::try_from(session_data.user_id.as_str())
.map_err(|e| anyhow::anyhow!("Invalid user ID: {e}"))?;
let device_id = matrix_sdk::ruma::OwnedDeviceId::from(session_data.device_id.as_str());
let meta = matrix_sdk::SessionMeta { user_id, device_id };
let tokens = SessionTokens {
access_token: session_data.access_token,
refresh_token: None,
};
let session = MatrixSession { meta, tokens };
client.restore_session(session).await?;
tracing::info!("Session restored for {}", session_data.homeserver_url);
Ok(client)
}
pub async fn login_with_password(
homeserver: &str,
username: &str,
password: &str,
) -> Result<Client> {
let config = ClientConfig::default();
let store_path = config.data_dir().join("matrix-sdk-state");
if store_path.exists() {
tracing::info!("Clearing old SDK store before fresh login");
std::fs::remove_dir_all(&store_path).ok();
}
let client = build_client(homeserver).await?;
client
.matrix_auth()
.login_username(username, password)
.initial_device_display_name("Netrix")
.await?;
let session = client.matrix_auth().session()
.ok_or_else(|| anyhow::anyhow!("No session after login"))?;
crate::persistence::matrix_state::save_session(&SessionData {
homeserver_url: homeserver.to_string(),
user_id: session.meta.user_id.to_string(),
device_id: session.meta.device_id.to_string(),
access_token: session.tokens.access_token.clone(),
})
.await?;
Ok(client)
}