use std::{future::IntoFuture, pin::Pin};
use futures_core::Future;
use matrix_sdk_base::crypto::secret_storage::SecretStorageKey;
use ruma::events::secret_storage::default_key::SecretStorageDefaultKeyEventContent;
use super::{Result, SecretStorage, SecretStore};
#[derive(Debug)]
pub struct CreateStore<'a> {
pub(super) secret_storage: &'a SecretStorage,
pub(super) passphrase: Option<&'a str>,
}
impl<'a> CreateStore<'a> {
pub fn with_passphrase(mut self, passphrase: &'a str) -> Self {
self.passphrase = Some(passphrase);
self
}
}
impl<'a> IntoFuture for CreateStore<'a> {
type Output = Result<SecretStore>;
#[cfg(target_arch = "wasm32")]
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + 'a>>;
#[cfg(not(target_arch = "wasm32"))]
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>;
fn into_future(self) -> Self::IntoFuture {
let Self { secret_storage, passphrase } = self;
Box::pin(async move {
let client_copy = secret_storage.client.to_owned();
let _guard = client_copy.locks().open_secret_store_lock.lock().await;
let new_key = if let Some(passphrase) = passphrase {
SecretStorageKey::new_from_passphrase(passphrase)
} else {
SecretStorageKey::new()
};
let content = new_key.event_content().to_owned();
secret_storage.client.account().set_account_data(content).await?;
let store = SecretStore { client: secret_storage.client.to_owned(), key: new_key };
store.export_secrets().await?;
let default_key_content =
SecretStorageDefaultKeyEventContent::new(store.key.key_id().to_owned());
store.client.account().set_account_data(default_key_content).await?;
Ok(store)
})
}
}