mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-07 23:44:53 -04:00
feat(indexeddb): Add support for key backup v1
This commit is contained in:
@@ -65,6 +65,11 @@ mod KEYS {
|
||||
pub const STORE_CIPHER: &str = "store_cipher";
|
||||
pub const ACCOUNT: &str = "account";
|
||||
pub const PRIVATE_IDENTITY: &str = "private_identity";
|
||||
|
||||
// BACKUP v1
|
||||
pub const BACKUP_KEYS: &str = "backup_keys";
|
||||
pub const BACKUP_KEY_V1: &str = "backup_key_v1";
|
||||
pub const RECOVERY_KEY_V1: &str = "recovery_key_v1";
|
||||
}
|
||||
|
||||
/// An in-memory only store that will forget all the E2EE key once it's dropped.
|
||||
@@ -159,6 +164,8 @@ impl IndexeddbStore {
|
||||
db.create_object_store(KEYS::OUTGOING_SECRET_REQUESTS)?;
|
||||
db.create_object_store(KEYS::UNSENT_SECRET_REQUESTS)?;
|
||||
db.create_object_store(KEYS::SECRET_REQUESTS_BY_INFO)?;
|
||||
|
||||
db.create_object_store(KEYS::BACKUP_KEYS)?;
|
||||
}
|
||||
Ok(())
|
||||
}));
|
||||
@@ -270,6 +277,7 @@ impl IndexeddbStore {
|
||||
async fn save_changes(&self, changes: Changes) -> Result<()> {
|
||||
let mut stores: Vec<&str> = [
|
||||
(changes.account.is_some() || changes.private_identity.is_some(), KEYS::CORE),
|
||||
(changes.recovery_key.is_some() || changes.backup_version.is_some(), KEYS::BACKUP_KEYS),
|
||||
(!changes.sessions.is_empty(), KEYS::SESSION),
|
||||
(
|
||||
!changes.devices.new.is_empty()
|
||||
@@ -311,6 +319,9 @@ impl IndexeddbStore {
|
||||
let private_identity_pickle =
|
||||
if let Some(i) = changes.private_identity { Some(i.pickle().await?) } else { None };
|
||||
|
||||
let recovery_key_pickle = changes.recovery_key;
|
||||
let backup_version = changes.backup_version;
|
||||
|
||||
if let Some(a) = &account_pickle {
|
||||
tx.object_store(KEYS::CORE)?
|
||||
.put_key_val(&JsValue::from_str(KEYS::ACCOUNT), &self.serialize_value(&a)?)?;
|
||||
@@ -323,6 +334,17 @@ impl IndexeddbStore {
|
||||
)?;
|
||||
}
|
||||
|
||||
if let Some(a) = &recovery_key_pickle {
|
||||
tx.object_store(KEYS::BACKUP_KEYS)?
|
||||
.put_key_val(&JsValue::from_str(KEYS::RECOVERY_KEY_V1), &self.serialize_value(&a)?)?;
|
||||
}
|
||||
|
||||
if let Some(a) = &backup_version {
|
||||
tx.object_store(KEYS::BACKUP_KEYS)?
|
||||
.put_key_val(&JsValue::from_str(KEYS::BACKUP_KEY_V1), &self.serialize_value(&a)?)?;
|
||||
}
|
||||
|
||||
|
||||
if !changes.sessions.is_empty() {
|
||||
let sessions = tx.object_store(KEYS::SESSION)?;
|
||||
|
||||
@@ -834,6 +856,34 @@ impl IndexeddbStore {
|
||||
|
||||
tx.await.into_result().map_err(|e| e.into())
|
||||
}
|
||||
|
||||
async fn load_backup_keys(&self) -> Result<BackupKeys> {
|
||||
let key = {
|
||||
let tx = self
|
||||
.inner
|
||||
.transaction_on_one_with_mode(
|
||||
KEYS::BACKUP_KEYS,
|
||||
IdbTransactionMode::Readonly,
|
||||
)?;
|
||||
let store = tx.object_store(KEYS::BACKUP_KEYS)?;
|
||||
|
||||
let backup_version = store
|
||||
.get(&JsValue::from_str(KEYS::BACKUP_KEY_V1))?
|
||||
.await?
|
||||
.map(|i| self.deserialize_value(i))
|
||||
.transpose()?;
|
||||
|
||||
let recovery_key = store
|
||||
.get(&JsValue::from_str(KEYS::RECOVERY_KEY_V1))?
|
||||
.await?
|
||||
.map(|i| self.deserialize_value(i))
|
||||
.transpose()?;
|
||||
|
||||
BackupKeys { backup_version, recovery_key }
|
||||
};
|
||||
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
@@ -924,9 +974,8 @@ impl CryptoStore for IndexeddbStore {
|
||||
self.users_for_key_query()
|
||||
}
|
||||
|
||||
#[allow(clippy::todo)]
|
||||
async fn load_backup_keys(&self) -> Result<BackupKeys, CryptoStoreError> {
|
||||
todo!()
|
||||
self.load_backup_keys().await.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
async fn update_tracked_user(
|
||||
|
||||
Reference in New Issue
Block a user