feat(indexeddb): Add support for key backup v1

This commit is contained in:
Benjamin Kampmann
2022-04-28 17:31:09 +02:00
parent 87ae677fc3
commit ebd85ebaa2

View File

@@ -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(