tauri_plugin_matrix_svelte/matrix/
session.rs

1use serde::{Deserialize, Serialize};
2use tauri::{AppHandle, Manager, Runtime, State};
3
4use crate::stronghold::{utils::BytesDto, StrongholdCollection};
5
6use matrix_sdk::Client;
7
8use std::path::PathBuf;
9
10use matrix_sdk::authentication::matrix::MatrixSession;
11
12use crate::stronghold::{self};
13
14use super::{login::get_stronghold_client_key, singletons::CLIENT};
15
16#[derive(Debug, Serialize, Deserialize)]
17pub struct ClientSession {
18    homeserver: String,
19    db_path: PathBuf,
20    passphrase: String,
21}
22
23impl ClientSession {
24    pub fn new(homeserver: String, db_path: PathBuf, passphrase: String) -> Self {
25        ClientSession {
26            homeserver,
27            db_path,
28            passphrase,
29        }
30    }
31}
32
33#[derive(Debug, Serialize, Deserialize)]
34pub struct FullMatrixSession {
35    client_session: ClientSession,
36    user_session: MatrixSession,
37}
38
39impl FullMatrixSession {
40    pub fn new(client_session: ClientSession, user_session: MatrixSession) -> Self {
41        FullMatrixSession {
42            client_session,
43            user_session,
44        }
45    }
46}
47
48pub async fn get_matrix_session_option(
49    collection_state: State<'_, StrongholdCollection>,
50    snapshot_path: PathBuf,
51    client_key: BytesDto,
52) -> anyhow::Result<Option<FullMatrixSession>> {
53    let read_session = stronghold::store::get_store_record(
54        collection_state,
55        snapshot_path,
56        client_key,
57        "current".to_string(),
58    )
59    .await?;
60
61    match read_session {
62        None => Ok(None),
63        Some(raw_session) => {
64            let session_string = String::from_utf8_lossy(&raw_session).into_owned();
65
66            let session: FullMatrixSession = serde_json::from_str(&session_string)?;
67            Ok(Some(session))
68        }
69    }
70}
71
72pub async fn restore_client_from_session(session: FullMatrixSession) -> anyhow::Result<Client> {
73    let FullMatrixSession {
74        client_session,
75        user_session,
76    } = session;
77
78    let client = Client::builder()
79        .homeserver_url(client_session.homeserver)
80        .sqlite_store(client_session.db_path, Some(&client_session.passphrase))
81        .build()
82        .await?;
83
84    client.restore_session(user_session).await?;
85
86    CLIENT
87        .set(client.clone())
88        .expect("BUG: CLIENT already set!");
89
90    Ok(client)
91}
92
93pub async fn try_get_session<R: Runtime>(
94    app_handle: &AppHandle<R>,
95    snapshot_path: PathBuf,
96) -> anyhow::Result<Option<FullMatrixSession>> {
97    let collection_state = app_handle.state::<StrongholdCollection>();
98    let client_key = get_stronghold_client_key();
99
100    stronghold::client::load_stronghold_client_or_create_it(
101        collection_state.clone(),
102        snapshot_path.clone(),
103        client_key.clone(),
104    )
105    .await?;
106
107    let session_option = get_matrix_session_option(
108        collection_state.clone(),
109        snapshot_path.clone(),
110        client_key.clone(),
111    )
112    .await?;
113
114    Ok(session_option)
115}