mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-16 12:43:01 -04:00
fixing style and typos
This commit is contained in:
@@ -468,7 +468,7 @@ macro_rules! statestore_integration_tests {
|
||||
}),
|
||||
};
|
||||
|
||||
assert!(store.get_media_content(&request_file).await.unwrap().is_none(), "unexpectd media found");
|
||||
assert!(store.get_media_content(&request_file).await.unwrap().is_none(), "unexpected media found");
|
||||
assert!(store.get_media_content(&request_thumbnail).await.unwrap().is_none(), "media not found");
|
||||
|
||||
store.add_media_content(&request_file, content.clone()).await.expect("adding media failed");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#![allow(dead_code)]
|
||||
use base64::{encode_config as base64_encode, STANDARD_NO_PAD};
|
||||
use matrix_sdk_base::ruma::events::{
|
||||
GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType,
|
||||
};
|
||||
@@ -8,7 +9,6 @@ use matrix_sdk_common::ruma::{
|
||||
use matrix_sdk_store_encryption::StoreCipher;
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::IdbKeyRange;
|
||||
use base64::{STANDARD_NO_PAD, encode_config as base64_encode};
|
||||
|
||||
/// Helpers for wasm32/browser environments
|
||||
|
||||
@@ -47,29 +47,32 @@ pub trait SafeEncode {
|
||||
JsValue::from(self.as_secure_string(table_name, store_cipher))
|
||||
}
|
||||
|
||||
/// encode self securely for the given tablename with the given `store_cipher` hash_key,
|
||||
/// returns the value as a base64 encoded string without any padding.
|
||||
/// encode self securely for the given tablename with the given
|
||||
/// `store_cipher` hash_key, returns the value as a base64 encoded
|
||||
/// string without any padding.
|
||||
fn as_secure_string(&self, table_name: &str, store_cipher: &StoreCipher) -> String {
|
||||
base64_encode(
|
||||
store_cipher.hash_key(table_name, self.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
)
|
||||
}
|
||||
|
||||
/// encode self into a JsValue, internally using `as_encoded_string`
|
||||
/// to escape the value of self, and append the given counter
|
||||
fn encode_with_counter(&self, i: usize) -> JsValue {
|
||||
JsValue::from(format!("{}{}{:0000000x}",
|
||||
self.as_encoded_string(),
|
||||
KEY_SEPARATOR,
|
||||
i
|
||||
))
|
||||
JsValue::from(format!("{}{}{:0000000x}", self.as_encoded_string(), KEY_SEPARATOR, i))
|
||||
}
|
||||
|
||||
/// encode self into a JsValue, internally using `as_secure_string`
|
||||
/// to escape the value of self, and append the given counter
|
||||
fn encode_with_counter_secure(&self, table_name: &str, store_cipher: &StoreCipher, i: usize) -> JsValue {
|
||||
JsValue::from(format!("{}{}{:0000000x}",
|
||||
fn encode_with_counter_secure(
|
||||
&self,
|
||||
table_name: &str,
|
||||
store_cipher: &StoreCipher,
|
||||
i: usize,
|
||||
) -> JsValue {
|
||||
JsValue::from(format!(
|
||||
"{}{}{:0000000x}",
|
||||
self.as_secure_string(table_name, store_cipher),
|
||||
KEY_SEPARATOR,
|
||||
i
|
||||
@@ -88,7 +91,11 @@ pub trait SafeEncode {
|
||||
.map_err(|e| e.as_string().unwrap_or_else(|| "Creating key range failed".to_owned()))
|
||||
}
|
||||
|
||||
fn encode_to_range_secure(&self, table_name: &str, store_cipher: &StoreCipher) -> Result<IdbKeyRange, String> {
|
||||
fn encode_to_range_secure(
|
||||
&self,
|
||||
table_name: &str,
|
||||
store_cipher: &StoreCipher,
|
||||
) -> Result<IdbKeyRange, String> {
|
||||
let key = self.as_secure_string(table_name, store_cipher);
|
||||
IdbKeyRange::bound(
|
||||
&JsValue::from([&key, KEY_SEPARATOR].concat()),
|
||||
@@ -113,14 +120,15 @@ where
|
||||
[
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.0.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
KEY_SEPARATOR,
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.1.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,19 +155,20 @@ where
|
||||
[
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.0.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
KEY_SEPARATOR,
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.1.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
KEY_SEPARATOR,
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.2.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,24 +198,25 @@ where
|
||||
[
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.0.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
KEY_SEPARATOR,
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.1.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
KEY_SEPARATOR,
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.2.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
KEY_SEPARATOR,
|
||||
&base64_encode(
|
||||
store_cipher.hash_key(table_name, self.3.as_encoded_string().as_bytes()),
|
||||
STANDARD_NO_PAD
|
||||
STANDARD_NO_PAD,
|
||||
),
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,9 @@ use indexed_db_futures::prelude::*;
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::{MemberEvent, SyncRoomEvent},
|
||||
media::{MediaRequest, UniqueKey},
|
||||
store::{
|
||||
BoxStream, Result as StoreResult, StateChanges, StateStore, StoreError,
|
||||
},
|
||||
store::{BoxStream, Result as StoreResult, StateChanges, StateStore, StoreError},
|
||||
RoomInfo,
|
||||
};
|
||||
use matrix_sdk_store_encryption::{StoreCipher, Error as EncryptionError};
|
||||
|
||||
use matrix_sdk_common::{
|
||||
async_trait,
|
||||
ruma::{
|
||||
@@ -44,6 +40,7 @@ use matrix_sdk_common::{
|
||||
EventId, MxcUri, RoomId, RoomVersionId, UserId,
|
||||
},
|
||||
};
|
||||
use matrix_sdk_store_encryption::{Error as EncryptionError, StoreCipher};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{info, warn};
|
||||
use wasm_bindgen::JsValue;
|
||||
@@ -85,8 +82,14 @@ impl From<SerializationError> for StoreError {
|
||||
EncryptionError::Random(e) => StoreError::Encryption(e.to_string()),
|
||||
EncryptionError::Serialization(e) => StoreError::Json(e),
|
||||
EncryptionError::Encryption(e) => StoreError::Encryption(e.to_string()),
|
||||
EncryptionError::Version(found, expected) => StoreError::Encryption(format!("Bad Database Encryption Version: expected {} found {}", expected, found)),
|
||||
EncryptionError::Length(found, expected) => StoreError::Encryption(format!("The database key an invalid length: expected {} found {}", expected, found)),
|
||||
EncryptionError::Version(found, expected) => StoreError::Encryption(format!(
|
||||
"Bad Database Encryption Version: expected {} found {}",
|
||||
expected, found
|
||||
)),
|
||||
EncryptionError::Length(found, expected) => StoreError::Encryption(format!(
|
||||
"The database key an invalid length: expected {} found {}",
|
||||
expected, found
|
||||
)),
|
||||
},
|
||||
_ => StoreError::Backend(anyhow!(e)),
|
||||
}
|
||||
@@ -231,12 +234,12 @@ impl IndexeddbStore {
|
||||
{
|
||||
StoreCipher::import(passphrase, &inner)?
|
||||
} else {
|
||||
let ciph = StoreCipher::new()?;
|
||||
let cipher = StoreCipher::new()?;
|
||||
ob.put_key_val(
|
||||
&JsValue::from_str(KEYS::STORE_KEY),
|
||||
&JsValue::from_serde(&StoreKeyWrapper(ciph.export(passphrase)?))?,
|
||||
&JsValue::from_serde(&StoreKeyWrapper(cipher.export(passphrase)?))?,
|
||||
)?;
|
||||
ciph
|
||||
cipher
|
||||
};
|
||||
|
||||
tx.await.into_result()?;
|
||||
@@ -269,7 +272,8 @@ impl IndexeddbStore {
|
||||
}
|
||||
|
||||
fn encode_key<T>(&self, table_name: &str, key: T) -> JsValue
|
||||
where T: SafeEncode
|
||||
where
|
||||
T: SafeEncode,
|
||||
{
|
||||
match self.store_cipher {
|
||||
Some(ref cipher) => key.encode_secure(table_name, cipher),
|
||||
@@ -277,26 +281,31 @@ impl IndexeddbStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_to_range<T>(&self, table_name: &str, key: T) -> Result<IdbKeyRange, SerializationError>
|
||||
where T: SafeEncode
|
||||
fn encode_to_range<T>(
|
||||
&self,
|
||||
table_name: &str,
|
||||
key: T,
|
||||
) -> Result<IdbKeyRange, SerializationError>
|
||||
where
|
||||
T: SafeEncode,
|
||||
{
|
||||
match self.store_cipher {
|
||||
Some(ref cipher) => key.encode_to_range_secure(table_name, cipher),
|
||||
None => key.encode_to_range()
|
||||
}.map_err(|e| SerializationError::StoreError(StoreError::Backend(anyhow!(e))))
|
||||
None => key.encode_to_range(),
|
||||
}
|
||||
.map_err(|e| SerializationError::StoreError(StoreError::Backend(anyhow!(e))))
|
||||
}
|
||||
|
||||
|
||||
fn encode_key_with_counter<T>(&self, table_name: &str, key: &T, i: usize) -> JsValue
|
||||
where T: SafeEncode
|
||||
where
|
||||
T: SafeEncode,
|
||||
{
|
||||
match self.store_cipher {
|
||||
Some(ref cipher) => key.encode_with_counter_secure(table_name, cipher, i),
|
||||
None => key.encode_with_counter(i)
|
||||
None => key.encode_with_counter(i),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn save_filter(&self, filter_name: &str, filter_id: &str) -> Result<()> {
|
||||
let tx = self
|
||||
.inner
|
||||
@@ -304,7 +313,10 @@ impl IndexeddbStore {
|
||||
|
||||
let obj = tx.object_store(KEYS::SESSION)?;
|
||||
|
||||
obj.put_key_val(&self.encode_key(KEYS::FILTER, (KEYS::FILTER, filter_name)), &JsValue::from_str(filter_id))?;
|
||||
obj.put_key_val(
|
||||
&self.encode_key(KEYS::FILTER, (KEYS::FILTER, filter_name)),
|
||||
&JsValue::from_str(filter_id),
|
||||
)?;
|
||||
|
||||
tx.await.into_result()?;
|
||||
|
||||
@@ -401,7 +413,8 @@ impl IndexeddbStore {
|
||||
for (event_type, event) in &changes.account_data {
|
||||
store.put_key_val(
|
||||
&self.encode_key(KEYS::ACCOUNT_DATA, event_type),
|
||||
&self.serialize_event(&event)?)?;
|
||||
&self.serialize_event(&event)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,8 +444,9 @@ impl IndexeddbStore {
|
||||
let store = tx.object_store(KEYS::ROOM_INFOS)?;
|
||||
for (room_id, room_info) in &changes.room_infos {
|
||||
store.put_key_val(
|
||||
&self.encode_key(KEYS::ROOM_INFOS, room_id),
|
||||
&self.serialize_event(&room_info)?)?;
|
||||
&self.encode_key(KEYS::ROOM_INFOS, room_id),
|
||||
&self.serialize_event(&room_info)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +455,7 @@ impl IndexeddbStore {
|
||||
for (sender, event) in &changes.presence {
|
||||
store.put_key_val(
|
||||
&self.encode_key(KEYS::PRESENCE, sender),
|
||||
&self.serialize_event(&event)?
|
||||
&self.serialize_event(&event)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
@@ -451,7 +465,7 @@ impl IndexeddbStore {
|
||||
for (room_id, info) in &changes.stripped_room_infos {
|
||||
store.put_key_val(
|
||||
&self.encode_key(KEYS::STRIPPED_ROOM_INFOS, room_id),
|
||||
&self.serialize_event(&info)?
|
||||
&self.serialize_event(&info)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
@@ -471,7 +485,8 @@ impl IndexeddbStore {
|
||||
for (room, event_types) in &changes.stripped_state {
|
||||
for (event_type, events) in event_types {
|
||||
for (state_key, event) in events {
|
||||
let key = self.encode_key(KEYS::STRIPPED_ROOM_STATE, (room, event_type, state_key));
|
||||
let key = self
|
||||
.encode_key(KEYS::STRIPPED_ROOM_STATE, (room, event_type, state_key));
|
||||
store.put_key_val(&key, &self.serialize_event(&event)?)?;
|
||||
}
|
||||
}
|
||||
@@ -494,14 +509,14 @@ impl IndexeddbStore {
|
||||
MembershipState::Join => {
|
||||
joined.put_key_val_owned(
|
||||
&self.encode_key(KEYS::JOINED_USER_IDS, key),
|
||||
&self.serialize_event(&event.state_key)?
|
||||
&self.serialize_event(&event.state_key)?,
|
||||
)?;
|
||||
invited.delete(&self.encode_key(KEYS::INVITED_USER_IDS, key))?;
|
||||
}
|
||||
MembershipState::Invite => {
|
||||
invited.put_key_val_owned(
|
||||
&self.encode_key(KEYS::INVITED_USER_IDS, key),
|
||||
&self.serialize_event(&event.state_key)?
|
||||
&self.serialize_event(&event.state_key)?,
|
||||
)?;
|
||||
joined.delete(&self.encode_key(KEYS::JOINED_USER_IDS, key))?;
|
||||
}
|
||||
@@ -511,10 +526,16 @@ impl IndexeddbStore {
|
||||
}
|
||||
}
|
||||
|
||||
members.put_key_val_owned(&self.encode_key(KEYS::MEMBERS, key), &self.serialize_event(&event)?)?;
|
||||
members.put_key_val_owned(
|
||||
&self.encode_key(KEYS::MEMBERS, key),
|
||||
&self.serialize_event(&event)?,
|
||||
)?;
|
||||
|
||||
if let Some(profile) = profile_changes.and_then(|p| p.get(&event.state_key)) {
|
||||
profiles_store.put_key_val_owned(&self.encode_key(KEYS::PROFILES, key), &self.serialize_event(&profile)?)?;
|
||||
profiles_store.put_key_val_owned(
|
||||
&self.encode_key(KEYS::PROFILES, key),
|
||||
&self.serialize_event(&profile)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -528,15 +549,20 @@ impl IndexeddbStore {
|
||||
for (event_id, receipts) in &content.0 {
|
||||
for (receipt_type, receipts) in receipts {
|
||||
for (user_id, receipt) in receipts {
|
||||
let key = self.encode_key(KEYS::ROOM_USER_RECEIPTS, (room, receipt_type, user_id));
|
||||
let key = self.encode_key(
|
||||
KEYS::ROOM_USER_RECEIPTS,
|
||||
(room, receipt_type, user_id),
|
||||
);
|
||||
|
||||
if let Some((old_event, _)) =
|
||||
room_user_receipts.get(&key)?.await?.and_then(|f| {
|
||||
self.deserialize_event::<(Box<EventId>, Receipt)>(f).ok()
|
||||
})
|
||||
{
|
||||
room_event_receipts
|
||||
.delete(&self.encode_key(KEYS::ROOM_EVENT_RECEIPTS, (room, receipt_type, &old_event, user_id)))?;
|
||||
room_event_receipts.delete(&self.encode_key(
|
||||
KEYS::ROOM_EVENT_RECEIPTS,
|
||||
(room, receipt_type, &old_event, user_id),
|
||||
))?;
|
||||
}
|
||||
|
||||
room_user_receipts
|
||||
@@ -544,7 +570,10 @@ impl IndexeddbStore {
|
||||
|
||||
// Add the receipt to the room event receipts
|
||||
room_event_receipts.put_key_val(
|
||||
&self.encode_key(KEYS::ROOM_EVENT_RECEIPTS, (room, receipt_type, event_id, user_id)),
|
||||
&self.encode_key(
|
||||
KEYS::ROOM_EVENT_RECEIPTS,
|
||||
(room, receipt_type, event_id, user_id),
|
||||
),
|
||||
&self.serialize_event(&(user_id, receipt))?,
|
||||
)?;
|
||||
}
|
||||
@@ -574,7 +603,7 @@ impl IndexeddbStore {
|
||||
let stores = &[
|
||||
(KEYS::ROOM_TIMELINE, &timeline_store),
|
||||
(KEYS::ROOM_TIMELINE_METADATA, &timeline_metadata_store),
|
||||
(KEYS::ROOM_EVENT_ID_TO_POSITION, &event_id_to_position_store)
|
||||
(KEYS::ROOM_EVENT_ID_TO_POSITION, &event_id_to_position_store),
|
||||
];
|
||||
for (table_name, store) in stores {
|
||||
let range = self.encode_to_range(table_name, room_id)?;
|
||||
@@ -603,7 +632,10 @@ impl IndexeddbStore {
|
||||
let mut delete_timeline = false;
|
||||
for event in &timeline.events {
|
||||
if let Some(event_id) = event.event_id() {
|
||||
let event_key = self.encode_key(KEYS::ROOM_EVENT_ID_TO_POSITION, (room_id, event_id));
|
||||
let event_key = self.encode_key(
|
||||
KEYS::ROOM_EVENT_ID_TO_POSITION,
|
||||
(room_id, event_id),
|
||||
);
|
||||
if event_id_to_position_store
|
||||
.count_with_key_owned(event_key)?
|
||||
.await?
|
||||
@@ -621,11 +653,10 @@ impl IndexeddbStore {
|
||||
room_id
|
||||
);
|
||||
|
||||
|
||||
let stores = &[
|
||||
(KEYS::ROOM_TIMELINE, &timeline_store),
|
||||
(KEYS::ROOM_TIMELINE_METADATA, &timeline_metadata_store),
|
||||
(KEYS::ROOM_EVENT_ID_TO_POSITION, &event_id_to_position_store)
|
||||
(KEYS::ROOM_EVENT_ID_TO_POSITION, &event_id_to_position_store),
|
||||
];
|
||||
for (table_name, store) in stores {
|
||||
let range = self.encode_to_range(table_name, room_id)?;
|
||||
@@ -678,7 +709,10 @@ impl IndexeddbStore {
|
||||
AnySyncMessageLikeEvent::RoomRedaction(redaction),
|
||||
)) = event.event.deserialize()
|
||||
{
|
||||
let redacts_key = self.encode_key(KEYS::ROOM_EVENT_ID_TO_POSITION, (room_id, &redaction.redacts));
|
||||
let redacts_key = self.encode_key(
|
||||
KEYS::ROOM_EVENT_ID_TO_POSITION,
|
||||
(room_id, &redaction.redacts),
|
||||
);
|
||||
if let Some(position_key) =
|
||||
event_id_to_position_store.get_owned(redacts_key)?.await?
|
||||
{
|
||||
@@ -705,10 +739,15 @@ impl IndexeddbStore {
|
||||
}
|
||||
|
||||
metadata.start_position -= 1;
|
||||
let key = self.encode_key_with_counter(KEYS::ROOM_TIMELINE, room_id, metadata.start_position);
|
||||
let key = self.encode_key_with_counter(
|
||||
KEYS::ROOM_TIMELINE,
|
||||
room_id,
|
||||
metadata.start_position,
|
||||
);
|
||||
// Only add event with id to the position map
|
||||
if let Some(event_id) = event.event_id() {
|
||||
let event_key = self.encode_key(KEYS::ROOM_EVENT_ID_TO_POSITION, (room_id, event_id));
|
||||
let event_key = self
|
||||
.encode_key(KEYS::ROOM_EVENT_ID_TO_POSITION, (room_id, event_id));
|
||||
event_id_to_position_store.put_key_val(&event_key, &key)?;
|
||||
}
|
||||
|
||||
@@ -717,10 +756,15 @@ impl IndexeddbStore {
|
||||
} else {
|
||||
for event in &timeline.events {
|
||||
metadata.end_position += 1;
|
||||
let key = self.encode_key_with_counter(KEYS::ROOM_TIMELINE, room_id, metadata.end_position);
|
||||
let key = self.encode_key_with_counter(
|
||||
KEYS::ROOM_TIMELINE,
|
||||
room_id,
|
||||
metadata.end_position,
|
||||
);
|
||||
// Only add event with id to the position map
|
||||
if let Some(event_id) = event.event_id() {
|
||||
let event_key = self.encode_key(KEYS::ROOM_EVENT_ID_TO_POSITION, (room_id, event_id));
|
||||
let event_key = self
|
||||
.encode_key(KEYS::ROOM_EVENT_ID_TO_POSITION, (room_id, event_id));
|
||||
event_id_to_position_store.put_key_val(&event_key, &key)?;
|
||||
}
|
||||
|
||||
@@ -728,8 +772,10 @@ impl IndexeddbStore {
|
||||
}
|
||||
}
|
||||
|
||||
timeline_metadata_store
|
||||
.put_key_val_owned(&self.encode_key(KEYS::ROOM_TIMELINE_METADATA, room_id), &JsValue::from_serde(&metadata)?)?;
|
||||
timeline_metadata_store.put_key_val_owned(
|
||||
&self.encode_key(KEYS::ROOM_TIMELINE_METADATA, room_id),
|
||||
&JsValue::from_serde(&metadata)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,10 +853,8 @@ impl IndexeddbStore {
|
||||
}
|
||||
|
||||
pub async fn get_user_ids_stream(&self, room_id: &RoomId) -> Result<Vec<Box<UserId>>> {
|
||||
Ok([
|
||||
self.get_invited_user_ids(room_id).await?,
|
||||
self.get_joined_user_ids(room_id).await?
|
||||
].concat())
|
||||
Ok([self.get_invited_user_ids(room_id).await?, self.get_joined_user_ids(room_id).await?]
|
||||
.concat())
|
||||
}
|
||||
|
||||
pub async fn get_invited_user_ids(&self, room_id: &RoomId) -> Result<Vec<Box<UserId>>> {
|
||||
@@ -934,7 +978,8 @@ impl IndexeddbStore {
|
||||
receipt_type: ReceiptType,
|
||||
event_id: &EventId,
|
||||
) -> Result<Vec<(Box<UserId>, Receipt)>> {
|
||||
let range = self.encode_to_range(KEYS::ROOM_EVENT_RECEIPTS, (room_id, &receipt_type, event_id))?;
|
||||
let range =
|
||||
self.encode_to_range(KEYS::ROOM_EVENT_RECEIPTS, (room_id, &receipt_type, event_id))?;
|
||||
let tx = self.inner.transaction_on_one_with_mode(
|
||||
KEYS::ROOM_EVENT_RECEIPTS,
|
||||
IdbTransactionMode::Readonly,
|
||||
@@ -950,7 +995,8 @@ impl IndexeddbStore {
|
||||
}
|
||||
|
||||
async fn add_media_content(&self, request: &MediaRequest, data: Vec<u8>) -> Result<()> {
|
||||
let key = self.encode_key(KEYS::MEDIA, (request.source.unique_key(), request.format.unique_key()));
|
||||
let key = self
|
||||
.encode_key(KEYS::MEDIA, (request.source.unique_key(), request.format.unique_key()));
|
||||
let tx =
|
||||
self.inner.transaction_on_one_with_mode(KEYS::MEDIA, IdbTransactionMode::Readwrite)?;
|
||||
|
||||
@@ -960,7 +1006,8 @@ impl IndexeddbStore {
|
||||
}
|
||||
|
||||
async fn get_media_content(&self, request: &MediaRequest) -> Result<Option<Vec<u8>>> {
|
||||
let key = self.encode_key(KEYS::MEDIA, (request.source.unique_key(), request.format.unique_key()));
|
||||
let key = self
|
||||
.encode_key(KEYS::MEDIA, (request.source.unique_key(), request.format.unique_key()));
|
||||
self.inner
|
||||
.transaction_on_one_with_mode(KEYS::MEDIA, IdbTransactionMode::Readonly)?
|
||||
.object_store(KEYS::MEDIA)?
|
||||
@@ -1004,7 +1051,8 @@ impl IndexeddbStore {
|
||||
}
|
||||
|
||||
async fn remove_media_content(&self, request: &MediaRequest) -> Result<()> {
|
||||
let key = self.encode_key(KEYS::MEDIA, (request.source.unique_key(), request.format.unique_key()));
|
||||
let key = self
|
||||
.encode_key(KEYS::MEDIA, (request.source.unique_key(), request.format.unique_key()));
|
||||
let tx =
|
||||
self.inner.transaction_on_one_with_mode(KEYS::MEDIA, IdbTransactionMode::Readwrite)?;
|
||||
|
||||
@@ -1299,16 +1347,16 @@ mod encrypted_tests {
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
use matrix_sdk_base::statestore_integration_tests;
|
||||
|
||||
use super::{IndexeddbStore, Result, StoreCipher};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{IndexeddbStore, Result, StoreCipher};
|
||||
|
||||
async fn get_store() -> Result<IndexeddbStore> {
|
||||
let db_name = format!("test-state-encrypted-{}", Uuid::new_v4().to_hyphenated().to_string());
|
||||
let db_name =
|
||||
format!("test-state-encrypted-{}", Uuid::new_v4().to_hyphenated().to_string());
|
||||
let key = StoreCipher::new()?;
|
||||
Ok(IndexeddbStore::open_helper(db_name, Some(key)).await?)
|
||||
}
|
||||
|
||||
statestore_integration_tests! { integration }
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,6 @@ impl EncodeSecureKey for Session {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AccountInfo {
|
||||
user_id: Arc<UserId>,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use matrix_sdk_common::ruma::{
|
||||
events::{secret::request::SecretName, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType},
|
||||
events::{
|
||||
secret::request::SecretName, GlobalAccountDataEventType, RoomAccountDataEventType,
|
||||
StateEventType,
|
||||
},
|
||||
receipt::ReceiptType,
|
||||
EventEncryptionAlgorithm,
|
||||
DeviceId, EventId, MxcUri, RoomId, TransactionId, UserId,
|
||||
DeviceId, EventEncryptionAlgorithm, EventId, MxcUri, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use matrix_sdk_store_encryption::StoreCipher;
|
||||
|
||||
|
||||
pub const ENCODE_SEPARATOR: u8 = 0xff;
|
||||
|
||||
pub trait EncodeKey {
|
||||
@@ -107,11 +108,7 @@ where
|
||||
B: EncodeKey,
|
||||
{
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
[
|
||||
self.0.encode(),
|
||||
self.1.encode(),
|
||||
]
|
||||
.concat()
|
||||
[self.0.encode(), self.1.encode()].concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,12 +119,7 @@ where
|
||||
C: EncodeKey,
|
||||
{
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
[
|
||||
self.0.encode(),
|
||||
self.1.encode(),
|
||||
self.2.encode(),
|
||||
]
|
||||
.concat()
|
||||
[self.0.encode(), self.1.encode(), self.2.encode()].concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,13 +131,7 @@ where
|
||||
D: EncodeKey,
|
||||
{
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
[
|
||||
self.0.encode(),
|
||||
self.1.encode(),
|
||||
self.2.encode(),
|
||||
self.3.encode(),
|
||||
]
|
||||
.concat()
|
||||
[self.0.encode(), self.1.encode(), self.2.encode(), self.3.encode()].concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,12 +147,10 @@ impl EncodeKey for GlobalAccountDataEventType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait EncodeSecureKey {
|
||||
fn encode_secure(&self, table_name: &str, store_cipher: &StoreCipher) -> Vec<u8>;
|
||||
}
|
||||
|
||||
|
||||
impl<T: EncodeSecureKey + ?Sized> EncodeSecureKey for &T {
|
||||
fn encode_secure(&self, table_name: &str, store_cipher: &StoreCipher) -> Vec<u8> {
|
||||
T::encode_secure(self, table_name, store_cipher)
|
||||
@@ -179,7 +163,6 @@ impl<T: EncodeSecureKey + ?Sized> EncodeSecureKey for Box<T> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl EncodeSecureKey for UserId {
|
||||
fn encode_secure(&self, table_name: &str, store_cipher: &StoreCipher) -> Vec<u8> {
|
||||
let user_id = store_cipher.hash_key(table_name, self.as_bytes());
|
||||
@@ -221,10 +204,7 @@ impl EncodeSecureKey for EventId {
|
||||
impl EncodeSecureKey for MxcUri {
|
||||
fn encode_secure(&self, table_name: &str, store_cipher: &StoreCipher) -> Vec<u8> {
|
||||
let s: &str = self.as_ref();
|
||||
[
|
||||
store_cipher.hash_key(table_name, s.as_bytes()).as_slice(),
|
||||
&[ENCODE_SEPARATOR],
|
||||
].concat()
|
||||
[store_cipher.hash_key(table_name, s.as_bytes()).as_slice(), &[ENCODE_SEPARATOR]].concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +221,8 @@ impl EncodeSecureKey for GlobalAccountDataEventType {
|
||||
[
|
||||
store_cipher.hash_key(table_name, self.to_string().as_bytes()).as_slice(),
|
||||
&[ENCODE_SEPARATOR],
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +231,8 @@ impl EncodeSecureKey for StateEventType {
|
||||
[
|
||||
store_cipher.hash_key(table_name, self.to_string().as_bytes()).as_slice(),
|
||||
&[ENCODE_SEPARATOR],
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,11 +241,11 @@ impl EncodeSecureKey for RoomAccountDataEventType {
|
||||
[
|
||||
store_cipher.hash_key(table_name, self.to_string().as_bytes()).as_slice(),
|
||||
&[ENCODE_SEPARATOR],
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<A, B> EncodeSecureKey for (A, B)
|
||||
where
|
||||
A: EncodeSecureKey,
|
||||
@@ -310,4 +292,4 @@ where
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,10 @@ use anyhow::anyhow;
|
||||
use async_stream::stream;
|
||||
use futures_core::stream::Stream;
|
||||
use futures_util::stream::{self, StreamExt, TryStreamExt};
|
||||
use matrix_sdk_store_encryption::{StoreCipher, Error as KeyEncryptionError};
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::{MemberEvent, SyncRoomEvent},
|
||||
media::{MediaRequest, UniqueKey},
|
||||
store::{
|
||||
BoxStream, Result as StoreResult, StateChanges, StateStore, StoreError,
|
||||
},
|
||||
store::{BoxStream, Result as StoreResult, StateChanges, StateStore, StoreError},
|
||||
RoomInfo,
|
||||
};
|
||||
use matrix_sdk_common::{
|
||||
@@ -50,6 +47,7 @@ use matrix_sdk_common::{
|
||||
EventId, MxcUri, RoomId, RoomVersionId, UserId,
|
||||
},
|
||||
};
|
||||
use matrix_sdk_store_encryption::{Error as KeyEncryptionError, StoreCipher};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sled::{
|
||||
transaction::{ConflictableTransactionError, TransactionError},
|
||||
@@ -60,7 +58,7 @@ use tracing::{info, warn};
|
||||
|
||||
#[cfg(feature = "crypto-store")]
|
||||
use super::OpenStoreError;
|
||||
use crate::encode_key::{EncodeSecureKey, EncodeKey, ENCODE_SEPARATOR};
|
||||
use crate::encode_key::{EncodeKey, EncodeSecureKey, ENCODE_SEPARATOR};
|
||||
#[cfg(feature = "crypto-store")]
|
||||
pub use crate::CryptoStore;
|
||||
|
||||
@@ -99,8 +97,14 @@ impl Into<StoreError> for SledStoreError {
|
||||
KeyEncryptionError::Random(e) => StoreError::Encryption(e.to_string()),
|
||||
KeyEncryptionError::Serialization(e) => StoreError::Json(e),
|
||||
KeyEncryptionError::Encryption(e) => StoreError::Encryption(e.to_string()),
|
||||
KeyEncryptionError::Version(found, expected) => StoreError::Encryption(format!("Bad Database Encryption Version: expected {} found {}", expected, found)),
|
||||
KeyEncryptionError::Length(found, expected) => StoreError::Encryption(format!("The database key an invalid length: expected {} found {}", expected, found)),
|
||||
KeyEncryptionError::Version(found, expected) => StoreError::Encryption(format!(
|
||||
"Bad Database Encryption Version: expected {} found {}",
|
||||
expected, found
|
||||
)),
|
||||
KeyEncryptionError::Length(found, expected) => StoreError::Encryption(format!(
|
||||
"The database key an invalid length: expected {} found {}",
|
||||
expected, found
|
||||
)),
|
||||
},
|
||||
SledStoreError::StoreError(e) => e,
|
||||
_ => StoreError::Backend(anyhow!(self)),
|
||||
@@ -108,7 +112,6 @@ impl Into<StoreError> for SledStoreError {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const SESSION: &str = "session";
|
||||
const ACCOUNT_DATA: &str = "account-data";
|
||||
const MEMBER: &str = "member";
|
||||
@@ -173,7 +176,11 @@ impl std::fmt::Debug for SledStore {
|
||||
}
|
||||
|
||||
impl SledStore {
|
||||
fn open_helper(db: Db, path: Option<PathBuf>, store_cipher: Option<StoreCipher>) -> Result<Self> {
|
||||
fn open_helper(
|
||||
db: Db,
|
||||
path: Option<PathBuf>,
|
||||
store_cipher: Option<StoreCipher>,
|
||||
) -> Result<Self> {
|
||||
let session = db.open_tree(SESSION)?;
|
||||
let account_data = db.open_tree(ACCOUNT_DATA)?;
|
||||
|
||||
@@ -244,10 +251,14 @@ impl SledStore {
|
||||
let db =
|
||||
Config::new().temporary(true).open().map_err(|e| StoreError::Backend(anyhow!(e)))?;
|
||||
|
||||
SledStore::open_helper(db, None, Some(StoreCipher::new().expect("can't create store cipher"))).map_err(|e| e.into())
|
||||
SledStore::open_helper(
|
||||
db,
|
||||
None,
|
||||
Some(StoreCipher::new().expect("can't create store cipher")),
|
||||
)
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
|
||||
pub fn open_with_passphrase(path: impl AsRef<Path>, passphrase: &str) -> StoreResult<Self> {
|
||||
Self::inner_open_with_passphrase(path, passphrase).map_err(|e| e.into())
|
||||
}
|
||||
@@ -259,9 +270,9 @@ impl SledStore {
|
||||
let store_cipher = if let Some(inner) = db.get("store_cipher".encode())? {
|
||||
StoreCipher::import(passphrase, &inner)?
|
||||
} else {
|
||||
let ciph = StoreCipher::new()?;
|
||||
db.insert("store_cipher".encode(), ciph.export(passphrase)?)?;
|
||||
ciph
|
||||
let cipher = StoreCipher::new()?;
|
||||
db.insert("store_cipher".encode(), cipher.export(passphrase)?)?;
|
||||
cipher
|
||||
};
|
||||
|
||||
SledStore::open_helper(db, Some(path), Some(store_cipher))
|
||||
@@ -307,7 +318,7 @@ impl SledStore {
|
||||
Ok(serde_json::from_slice(event)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn encode_key<T: EncodeSecureKey + EncodeKey + ?Sized>(
|
||||
&self,
|
||||
table_name: &str,
|
||||
@@ -324,14 +335,15 @@ impl SledStore {
|
||||
&self,
|
||||
tablename: &str,
|
||||
s: &A,
|
||||
i: usize
|
||||
i: usize,
|
||||
) -> Vec<u8> {
|
||||
[
|
||||
&self.encode_key(tablename, s),
|
||||
[ENCODE_SEPARATOR].as_slice(),
|
||||
i.to_be_bytes().as_ref(),
|
||||
[ENCODE_SEPARATOR].as_slice(),
|
||||
].concat()
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
|
||||
pub async fn save_filter(&self, filter_name: &str, filter_id: &str) -> Result<()> {
|
||||
@@ -401,11 +413,17 @@ impl SledStore {
|
||||
|
||||
match event.content.membership {
|
||||
MembershipState::Join => {
|
||||
joined.insert(self.encode_key(JOINED_USER_ID, &key), event.state_key.as_str())?;
|
||||
joined.insert(
|
||||
self.encode_key(JOINED_USER_ID, &key),
|
||||
event.state_key.as_str(),
|
||||
)?;
|
||||
invited.remove(self.encode_key(INVITED_USER_ID, &key))?;
|
||||
}
|
||||
MembershipState::Invite => {
|
||||
invited.insert(self.encode_key(INVITED_USER_ID, &key), event.state_key.as_str())?;
|
||||
invited.insert(
|
||||
self.encode_key(INVITED_USER_ID, &key),
|
||||
event.state_key.as_str(),
|
||||
)?;
|
||||
joined.remove(self.encode_key(JOINED_USER_ID, &key))?;
|
||||
}
|
||||
_ => {
|
||||
@@ -499,7 +517,10 @@ impl SledStore {
|
||||
for (room, events) in &changes.stripped_members {
|
||||
for event in events.values() {
|
||||
stripped_members.insert(
|
||||
self.encode_key(STRIPPED_ROOM_MEMBER, &(room, event.state_key.to_string())),
|
||||
self.encode_key(
|
||||
STRIPPED_ROOM_MEMBER,
|
||||
&(room, event.state_key.to_string()),
|
||||
),
|
||||
self.serialize_event(&event)
|
||||
.map_err(ConflictableTransactionError::Abort)?,
|
||||
)?;
|
||||
@@ -510,7 +531,10 @@ impl SledStore {
|
||||
for (event_type, events) in event_types {
|
||||
for (state_key, event) in events {
|
||||
stripped_state.insert(
|
||||
self.encode_key(STRIPPED_ROOM_STATE, &(room, event_type.to_string(), state_key)),
|
||||
self.encode_key(
|
||||
STRIPPED_ROOM_STATE,
|
||||
&(room, event_type.to_string(), state_key),
|
||||
),
|
||||
self.serialize_event(&event)
|
||||
.map_err(ConflictableTransactionError::Abort)?,
|
||||
)?;
|
||||
@@ -533,7 +557,10 @@ impl SledStore {
|
||||
for (user_id, receipt) in receipts {
|
||||
// Add the receipt to the room user receipts
|
||||
if let Some(old) = room_user_receipts.insert(
|
||||
self.encode_key(ROOM_USER_RECEIPT, &(room, receipt_type, user_id)),
|
||||
self.encode_key(
|
||||
ROOM_USER_RECEIPT,
|
||||
&(room, receipt_type, user_id),
|
||||
),
|
||||
self.serialize_event(&(event_id, receipt))
|
||||
.map_err(ConflictableTransactionError::Abort)?,
|
||||
)? {
|
||||
@@ -541,14 +568,18 @@ impl SledStore {
|
||||
let (old_event, _): (Box<EventId>, Receipt) = self
|
||||
.deserialize_event(&old)
|
||||
.map_err(ConflictableTransactionError::Abort)?;
|
||||
room_event_receipts.remove(
|
||||
self.encode_key(ROOM_EVENT_RECEIPT, &(room, receipt_type, old_event, user_id)),
|
||||
)?;
|
||||
room_event_receipts.remove(self.encode_key(
|
||||
ROOM_EVENT_RECEIPT,
|
||||
&(room, receipt_type, old_event, user_id),
|
||||
))?;
|
||||
}
|
||||
|
||||
// Add the receipt to the room event receipts
|
||||
room_event_receipts.insert(
|
||||
self.encode_key(ROOM_EVENT_RECEIPT, &(room, receipt_type, event_id, user_id)),
|
||||
self.encode_key(
|
||||
ROOM_EVENT_RECEIPT,
|
||||
&(room, receipt_type, event_id, user_id),
|
||||
),
|
||||
self.serialize_event(&(user_id, receipt))
|
||||
.map_err(ConflictableTransactionError::Abort)?,
|
||||
)?;
|
||||
@@ -635,7 +666,10 @@ impl SledStore {
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
) -> StoreResult<impl Stream<Item = StoreResult<Box<UserId>>>> {
|
||||
Ok(self.get_joined_user_ids(room_id).await?.chain(self.get_invited_user_ids(room_id).await?))
|
||||
Ok(self
|
||||
.get_joined_user_ids(room_id)
|
||||
.await?
|
||||
.chain(self.get_invited_user_ids(room_id).await?))
|
||||
}
|
||||
|
||||
pub async fn get_invited_user_ids(
|
||||
@@ -780,8 +814,10 @@ impl SledStore {
|
||||
}
|
||||
|
||||
async fn add_media_content(&self, request: &MediaRequest, data: Vec<u8>) -> Result<()> {
|
||||
self.media
|
||||
.insert(self.encode_key(MEDIA, &(request.source.unique_key(), request.format.unique_key())), data)?;
|
||||
self.media.insert(
|
||||
self.encode_key(MEDIA, &(request.source.unique_key(), request.format.unique_key())),
|
||||
data,
|
||||
)?;
|
||||
|
||||
self.inner.flush_async().await?;
|
||||
|
||||
@@ -790,7 +826,8 @@ impl SledStore {
|
||||
|
||||
async fn get_media_content(&self, request: &MediaRequest) -> Result<Option<Vec<u8>>> {
|
||||
let db = self.clone();
|
||||
let key = self.encode_key(MEDIA, &(request.source.unique_key(), request.format.unique_key()));
|
||||
let key =
|
||||
self.encode_key(MEDIA, &(request.source.unique_key(), request.format.unique_key()));
|
||||
|
||||
spawn_blocking(move || Ok(db.media.get(key)?.map(|m| m.to_vec()))).await?
|
||||
}
|
||||
@@ -809,7 +846,9 @@ impl SledStore {
|
||||
}
|
||||
|
||||
async fn remove_media_content(&self, request: &MediaRequest) -> Result<()> {
|
||||
self.media.remove(self.encode_key(MEDIA, &(request.source.unique_key(), request.format.unique_key())))?;
|
||||
self.media.remove(
|
||||
self.encode_key(MEDIA, &(request.source.unique_key(), request.format.unique_key())),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -826,8 +865,7 @@ impl SledStore {
|
||||
}
|
||||
|
||||
async fn remove_room(&self, room_id: &RoomId) -> Result<()> {
|
||||
|
||||
let mut members_batch = sled::Batch::default();
|
||||
let mut members_batch = sled::Batch::default();
|
||||
for key in self.members.scan_prefix(self.encode_key(MEMBER, room_id)).keys() {
|
||||
members_batch.remove(key?)
|
||||
}
|
||||
@@ -843,12 +881,15 @@ impl SledStore {
|
||||
}
|
||||
|
||||
let mut joined_user_ids_batch = sled::Batch::default();
|
||||
for key in self.joined_user_ids.scan_prefix(self.encode_key(JOINED_USER_ID, room_id)).keys() {
|
||||
for key in self.joined_user_ids.scan_prefix(self.encode_key(JOINED_USER_ID, room_id)).keys()
|
||||
{
|
||||
joined_user_ids_batch.remove(key?)
|
||||
}
|
||||
|
||||
let mut invited_user_ids_batch = sled::Batch::default();
|
||||
for key in self.invited_user_ids.scan_prefix(self.encode_key(INVITED_USER_ID, room_id)).keys() {
|
||||
for key in
|
||||
self.invited_user_ids.scan_prefix(self.encode_key(INVITED_USER_ID, room_id)).keys()
|
||||
{
|
||||
invited_user_ids_batch.remove(key?)
|
||||
}
|
||||
|
||||
@@ -858,27 +899,41 @@ impl SledStore {
|
||||
}
|
||||
|
||||
let mut room_account_data_batch = sled::Batch::default();
|
||||
for key in self.room_account_data.scan_prefix(self.encode_key(ROOM_ACCOUNT_DATA, room_id)).keys() {
|
||||
for key in
|
||||
self.room_account_data.scan_prefix(self.encode_key(ROOM_ACCOUNT_DATA, room_id)).keys()
|
||||
{
|
||||
room_account_data_batch.remove(key?)
|
||||
}
|
||||
|
||||
let mut stripped_members_batch = sled::Batch::default();
|
||||
for key in self.stripped_members.scan_prefix(self.encode_key(STRIPPED_ROOM_MEMBER, room_id)).keys() {
|
||||
for key in
|
||||
self.stripped_members.scan_prefix(self.encode_key(STRIPPED_ROOM_MEMBER, room_id)).keys()
|
||||
{
|
||||
stripped_members_batch.remove(key?)
|
||||
}
|
||||
|
||||
let mut stripped_room_state_batch = sled::Batch::default();
|
||||
for key in self.stripped_room_state.scan_prefix(self.encode_key(STRIPPED_ROOM_STATE, room_id)).keys() {
|
||||
for key in self
|
||||
.stripped_room_state
|
||||
.scan_prefix(self.encode_key(STRIPPED_ROOM_STATE, room_id))
|
||||
.keys()
|
||||
{
|
||||
stripped_room_state_batch.remove(key?)
|
||||
}
|
||||
|
||||
let mut room_user_receipts_batch = sled::Batch::default();
|
||||
for key in self.room_user_receipts.scan_prefix(self.encode_key(ROOM_USER_RECEIPT, room_id)).keys() {
|
||||
for key in
|
||||
self.room_user_receipts.scan_prefix(self.encode_key(ROOM_USER_RECEIPT, room_id)).keys()
|
||||
{
|
||||
room_user_receipts_batch.remove(key?)
|
||||
}
|
||||
|
||||
let mut room_event_receipts_batch = sled::Batch::default();
|
||||
for key in self.room_event_receipts.scan_prefix(self.encode_key(ROOM_EVENT_RECEIPT, room_id)).keys() {
|
||||
for key in self
|
||||
.room_event_receipts
|
||||
.scan_prefix(self.encode_key(ROOM_EVENT_RECEIPT, room_id))
|
||||
.keys()
|
||||
{
|
||||
room_event_receipts_batch.remove(key?)
|
||||
}
|
||||
|
||||
@@ -985,7 +1040,11 @@ impl SledStore {
|
||||
}
|
||||
|
||||
let mut event_id_to_position_batch = sled::Batch::default();
|
||||
for key in self.room_event_id_to_position.scan_prefix(self.encode_key(ROOM_EVENT_ID_POSITION, &room_id)).keys() {
|
||||
for key in self
|
||||
.room_event_id_to_position
|
||||
.scan_prefix(self.encode_key(ROOM_EVENT_ID_POSITION, &room_id))
|
||||
.keys()
|
||||
{
|
||||
event_id_to_position_batch.remove(key?)
|
||||
}
|
||||
|
||||
@@ -993,7 +1052,8 @@ impl SledStore {
|
||||
(&self.room_timeline, &self.room_timeline_metadata, &self.room_event_id_to_position)
|
||||
.transaction(
|
||||
|(room_timeline, room_timeline_metadata, room_event_id_to_position)| {
|
||||
room_timeline_metadata.remove(self.encode_key(TIMELINE_METADATA, &room_id))?;
|
||||
room_timeline_metadata
|
||||
.remove(self.encode_key(TIMELINE_METADATA, &room_id))?;
|
||||
|
||||
room_timeline.apply_batch(&timeline_batch)?;
|
||||
room_event_id_to_position.apply_batch(&event_id_to_position_batch)?;
|
||||
@@ -1045,7 +1105,8 @@ impl SledStore {
|
||||
let mut delete_timeline = false;
|
||||
for event in &timeline.events {
|
||||
if let Some(event_id) = event.event_id() {
|
||||
let event_key = self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, event_id));
|
||||
let event_key =
|
||||
self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, event_id));
|
||||
if self.room_event_id_to_position.contains_key(event_key)? {
|
||||
delete_timeline = true;
|
||||
break;
|
||||
@@ -1100,7 +1161,8 @@ impl SledStore {
|
||||
AnySyncMessageLikeEvent::RoomRedaction(redaction),
|
||||
)) = event.event.deserialize()
|
||||
{
|
||||
let redacts_key = self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, redaction.redacts));
|
||||
let redacts_key =
|
||||
self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, redaction.redacts));
|
||||
if let Some(position_key) =
|
||||
self.room_event_id_to_position.get(redacts_key)?
|
||||
{
|
||||
@@ -1125,28 +1187,35 @@ impl SledStore {
|
||||
}
|
||||
|
||||
metadata.start_position -= 1;
|
||||
let key = self.encode_key_with_counter(TIMELINE, room_id, metadata.start_position);
|
||||
let key =
|
||||
self.encode_key_with_counter(TIMELINE, room_id, metadata.start_position);
|
||||
timeline_batch.insert(key.as_slice(), self.serialize_event(&event)?);
|
||||
// Only add event with id to the position map
|
||||
if let Some(event_id) = event.event_id() {
|
||||
let event_key = self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, event_id));
|
||||
let event_key =
|
||||
self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, event_id));
|
||||
event_id_to_position_batch.insert(event_key.as_slice(), key.as_slice());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for event in &timeline.events {
|
||||
metadata.end_position += 1;
|
||||
let key = self.encode_key_with_counter(TIMELINE, room_id, metadata.end_position);
|
||||
let key =
|
||||
self.encode_key_with_counter(TIMELINE, room_id, metadata.end_position);
|
||||
timeline_batch.insert(key.as_slice(), self.serialize_event(&event)?);
|
||||
// Only add event with id to the position map
|
||||
if let Some(event_id) = event.event_id() {
|
||||
let event_key = self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, event_id));
|
||||
let event_key =
|
||||
self.encode_key(ROOM_EVENT_ID_POSITION, &(room_id, event_id));
|
||||
event_id_to_position_batch.insert(event_key.as_slice(), key.as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timeline_metadata_batch.insert(self.encode_key(TIMELINE_METADATA, &room_id), serde_json::to_vec(&metadata)?);
|
||||
timeline_metadata_batch.insert(
|
||||
self.encode_key(TIMELINE_METADATA, &room_id),
|
||||
serde_json::to_vec(&metadata)?,
|
||||
);
|
||||
}
|
||||
|
||||
let ret: Result<(), TransactionError<SledStoreError>> =
|
||||
|
||||
@@ -289,8 +289,9 @@ impl StoreCipher {
|
||||
|
||||
/// Encrypt a value before it is inserted into the key/value store.
|
||||
///
|
||||
/// A value can be decrypted using the [`StoreCipher::decrypt_value_typed()`]
|
||||
/// method. This is the lower level function to `encrypt_value`, but returns the
|
||||
/// A value can be decrypted using the
|
||||
/// [`StoreCipher::decrypt_value_typed()`] method. This is the lower
|
||||
/// level function to `encrypt_value`, but returns the
|
||||
/// full `EncryptdValue`-type
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -399,8 +400,9 @@ impl StoreCipher {
|
||||
|
||||
/// Decrypt a value after it was fetchetd from the key/value store.
|
||||
///
|
||||
/// A value can be encrypted using the [`StoreCipher::encrypt_value_typed()`]
|
||||
/// method. Lower level method to [`StoreCipher::decrypt_value_typed()`]
|
||||
/// A value can be encrypted using the
|
||||
/// [`StoreCipher::encrypt_value_typed()`] method. Lower level method to
|
||||
/// [`StoreCipher::decrypt_value_typed()`]
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
@@ -427,14 +429,16 @@ impl StoreCipher {
|
||||
/// assert_eq!(value, decrypted);
|
||||
/// # Result::<_, anyhow::Error>::Ok(()) };
|
||||
/// ```
|
||||
pub fn decrypt_value_typed<T: for<'b> Deserialize<'b>>(&self, value: EncryptedValue) -> Result<T, Error> {
|
||||
pub fn decrypt_value_typed<T: for<'b> Deserialize<'b>>(
|
||||
&self,
|
||||
value: EncryptedValue,
|
||||
) -> Result<T, Error> {
|
||||
let mut plaintext = self.decrypt_value_data(value)?;
|
||||
let ret = serde_json::from_slice(&plaintext);
|
||||
plaintext.zeroize();
|
||||
Ok(ret?)
|
||||
}
|
||||
|
||||
|
||||
/// Decrypt a value after it was fetchetd from the key/value store.
|
||||
///
|
||||
/// A value can be encrypted using the [`StoreCipher::encrypt_value_data()`]
|
||||
@@ -494,7 +498,8 @@ impl MacKey {
|
||||
}
|
||||
}
|
||||
|
||||
/// Encrypted value, ready for storage, as created by the [`StoreCipher::encrypt_value_data()`]
|
||||
/// Encrypted value, ready for storage, as created by the
|
||||
/// [`StoreCipher::encrypt_value_data()`]
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct EncryptedValue {
|
||||
version: u8,
|
||||
|
||||
Reference in New Issue
Block a user