mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-05 14:35:20 -04:00
Merge branch 'main' into release-matrix-sdk-crypto-js-v0.1.0-alpha.8
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -4336,7 +4336,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma"
|
||||
version = "0.8.2"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"js_int",
|
||||
@@ -4351,7 +4351,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-appservice-api"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -4362,7 +4362,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-client-api"
|
||||
version = "0.16.2"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"bytes",
|
||||
@@ -4379,7 +4379,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-common"
|
||||
version = "0.11.3"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
"bytes",
|
||||
@@ -4412,7 +4412,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-federation-api"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -4423,7 +4423,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-identifiers-validation"
|
||||
version = "0.9.1"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"thiserror",
|
||||
@@ -4432,7 +4432,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-macros"
|
||||
version = "0.11.3"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro-crate",
|
||||
@@ -4440,14 +4440,14 @@ dependencies = [
|
||||
"quote",
|
||||
"ruma-identifiers-validation",
|
||||
"serde",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.15",
|
||||
"toml 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruma-push-gateway-api"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/ruma/ruma?rev=0143bd9b9f5dcfcaa835afb76f342c12f014f945#0143bd9b9f5dcfcaa835afb76f342c12f014f945"
|
||||
source = "git+https://github.com/ruma/ruma?rev=54a4223caa1c1052464ecdba0f1e08f126e07bcd#54a4223caa1c1052464ecdba0f1e08f126e07bcd"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
|
||||
@@ -32,8 +32,8 @@ eyeball = "0.6.0"
|
||||
eyeball-im = "0.2.0"
|
||||
futures-util = { version = "0.3.26", default-features = false, features = ["alloc"] }
|
||||
http = "0.2.6"
|
||||
ruma = { git = "https://github.com/ruma/ruma", rev = "0143bd9b9f5dcfcaa835afb76f342c12f014f945", features = ["client-api-c", "compat-user-id"] }
|
||||
ruma-common = { git = "https://github.com/ruma/ruma", rev = "0143bd9b9f5dcfcaa835afb76f342c12f014f945" }
|
||||
ruma = { git = "https://github.com/ruma/ruma", rev = "54a4223caa1c1052464ecdba0f1e08f126e07bcd", features = ["client-api-c", "compat-user-id"] }
|
||||
ruma-common = { git = "https://github.com/ruma/ruma", rev = "54a4223caa1c1052464ecdba0f1e08f126e07bcd" }
|
||||
once_cell = "1.16.0"
|
||||
serde = "1.0.151"
|
||||
serde_html_form = "0.2.0"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# v0.1.0-alpha.8
|
||||
|
||||
- Make `unused_fallback_keys` as optional in `Machine.receive_sync_changes`
|
||||
- `importCrossSigningKeys`: change the parameters to be individual keys
|
||||
rather than a `CrossSigningKeyExport` object.
|
||||
- Make `unused_fallback_keys` optional in `Machine.receive_sync_changes`
|
||||
|
||||
# v0.1.0-alpha.7
|
||||
|
||||
|
||||
@@ -19,7 +19,11 @@ cd $(dirname "$0")/..
|
||||
RUSTFLAGS='-C opt-level=z' WASM_BINDGEN_WEAKREF=1 wasm-pack build --target nodejs --scope matrix-org --out-dir pkg "${WASM_PACK_ARGS[@]}"
|
||||
|
||||
# Convert the Wasm into a JS file that exports the base64'ed Wasm.
|
||||
echo "module.exports = \`$(base64 pkg/matrix_sdk_crypto_js_bg.wasm)\`;" > pkg/matrix_sdk_crypto_js_bg.wasm.js
|
||||
{
|
||||
printf 'module.exports = `'
|
||||
base64 < pkg/matrix_sdk_crypto_js_bg.wasm
|
||||
printf '`;'
|
||||
} > pkg/matrix_sdk_crypto_js_bg.wasm.js
|
||||
|
||||
# In the JavaScript:
|
||||
# 1. Strip out the lines that load the WASM, and our new epilogue.
|
||||
|
||||
@@ -397,11 +397,11 @@ impl OlmMachine {
|
||||
|
||||
/// Export all the private cross signing keys we have.
|
||||
///
|
||||
/// The export will contain the seed for the ed25519 keys as a
|
||||
/// unpadded base64 encoded string.
|
||||
/// The export will contain the seeds for the ed25519 keys as
|
||||
/// unpadded base64 encoded strings.
|
||||
///
|
||||
/// This method returns None if we don’t have any private cross
|
||||
/// signing keys.
|
||||
/// Returns `null` if we don’t have any private cross signing keys;
|
||||
/// otherwise returns a `CrossSigningKeyExport`.
|
||||
#[wasm_bindgen(js_name = "exportCrossSigningKeys")]
|
||||
pub fn export_cross_signing_keys(&self) -> Promise {
|
||||
let me = self.inner.clone();
|
||||
@@ -413,12 +413,22 @@ impl OlmMachine {
|
||||
|
||||
/// Import our private cross signing keys.
|
||||
///
|
||||
/// The export needs to contain the seed for the ed25519 keys as
|
||||
/// an unpadded base64 encoded string.
|
||||
/// The keys should be provided as unpadded-base64-encoded strings.
|
||||
///
|
||||
/// Returns a `CrossSigningStatus`.
|
||||
#[wasm_bindgen(js_name = "importCrossSigningKeys")]
|
||||
pub fn import_cross_signing_keys(&self, export: store::CrossSigningKeyExport) -> Promise {
|
||||
pub fn import_cross_signing_keys(
|
||||
&self,
|
||||
master_key: Option<String>,
|
||||
self_signing_key: Option<String>,
|
||||
user_signing_key: Option<String>,
|
||||
) -> Promise {
|
||||
let me = self.inner.clone();
|
||||
let export = export.inner;
|
||||
let export = matrix_sdk_crypto::store::CrossSigningKeyExport {
|
||||
master_key,
|
||||
self_signing_key,
|
||||
user_signing_key,
|
||||
};
|
||||
|
||||
future_to_promise(async move {
|
||||
Ok(me.import_cross_signing_keys(export).await.map(olm::CrossSigningStatus::from)?)
|
||||
|
||||
@@ -8,6 +8,10 @@ callback interface NotificationDelegate {
|
||||
void did_receive_notification(NotificationItem notification);
|
||||
};
|
||||
|
||||
interface AuthenticationService {};
|
||||
interface Span {};
|
||||
interface NotificationService {};
|
||||
|
||||
dictionary NotificationItem {
|
||||
TimelineEvent event;
|
||||
string room_id;
|
||||
@@ -18,6 +22,8 @@ dictionary NotificationItem {
|
||||
boolean is_noisy;
|
||||
boolean is_direct;
|
||||
boolean is_encrypted;
|
||||
boolean is_read;
|
||||
u64 timestamp;
|
||||
};
|
||||
|
||||
interface TimelineEvent {};
|
||||
|
||||
@@ -11,7 +11,6 @@ use zeroize::Zeroize;
|
||||
use super::{client::Client, client_builder::ClientBuilder, RUNTIME};
|
||||
use crate::error::ClientError;
|
||||
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct AuthenticationService {
|
||||
base_path: String,
|
||||
passphrase: Option<String>,
|
||||
|
||||
@@ -18,6 +18,9 @@ pub struct NotificationItem {
|
||||
pub is_noisy: bool,
|
||||
pub is_direct: bool,
|
||||
pub is_encrypted: bool,
|
||||
pub is_read: bool,
|
||||
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
impl NotificationItem {
|
||||
@@ -45,13 +48,14 @@ impl NotificationItem {
|
||||
is_noisy,
|
||||
is_direct: room.is_direct().await?,
|
||||
is_encrypted: room.is_encrypted().await?,
|
||||
is_read: notification.read,
|
||||
timestamp: notification.ts.0.into(),
|
||||
};
|
||||
Ok(item)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct NotificationService {
|
||||
base_path: String,
|
||||
user_id: String,
|
||||
|
||||
@@ -95,7 +95,6 @@ fn span_or_event_enabled(callsite: &'static DefaultCallsite) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct Span(tracing::Span);
|
||||
|
||||
#[uniffi::export]
|
||||
|
||||
@@ -54,7 +54,7 @@ use ruma::{
|
||||
MilliSecondsSinceUnixEpoch, OwnedUserId, RoomId, UInt, UserId,
|
||||
};
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{debug, info, trace, warn};
|
||||
use tracing::{debug, info, instrument, trace, warn};
|
||||
|
||||
use crate::{
|
||||
deserialized_responses::{AmbiguityChanges, MembersResponse, SyncTimelineEvent},
|
||||
@@ -297,6 +297,7 @@ impl BaseClient {
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[instrument(skip_all, fields(room_id = ?room_info.room_id))]
|
||||
pub(crate) async fn handle_timeline(
|
||||
&self,
|
||||
room: &Room,
|
||||
@@ -438,6 +439,7 @@ impl BaseClient {
|
||||
Ok(timeline)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(room_id = ?room_info.room_id))]
|
||||
pub(crate) fn handle_invited_state(
|
||||
&self,
|
||||
events: &[Raw<AnyStrippedStateEvent>],
|
||||
@@ -467,6 +469,7 @@ impl BaseClient {
|
||||
changes.stripped_state.insert(room_info.room_id().to_owned(), state_events);
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(room_id = ?room_info.room_id))]
|
||||
pub(crate) async fn handle_state(
|
||||
&self,
|
||||
events: &[Raw<AnySyncStateEvent>],
|
||||
@@ -478,13 +481,11 @@ impl BaseClient {
|
||||
let mut user_ids = BTreeSet::new();
|
||||
let mut profiles = BTreeMap::new();
|
||||
|
||||
let room_id = room_info.room_id.clone();
|
||||
|
||||
for raw_event in events {
|
||||
let event = match raw_event.deserialize() {
|
||||
Ok(e) => e,
|
||||
Ok(ev) => ev,
|
||||
Err(e) => {
|
||||
warn!(?room_id, "Couldn't deserialize state event: {e:?}");
|
||||
warn!("Couldn't deserialize state event: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
@@ -492,7 +493,7 @@ impl BaseClient {
|
||||
room_info.handle_state_event(&event);
|
||||
|
||||
if let AnySyncStateEvent::RoomMember(member) = &event {
|
||||
ambiguity_cache.handle_event(changes, &room_id, member).await?;
|
||||
ambiguity_cache.handle_event(changes, &room_info.room_id, member).await?;
|
||||
|
||||
match member.membership() {
|
||||
MembershipState::Join | MembershipState::Invite => {
|
||||
@@ -516,12 +517,13 @@ impl BaseClient {
|
||||
.insert(event.state_key().to_owned(), raw_event.clone());
|
||||
}
|
||||
|
||||
changes.profiles.insert((*room_id).to_owned(), profiles);
|
||||
changes.state.insert((*room_id).to_owned(), state_events);
|
||||
changes.profiles.insert((*room_info.room_id).to_owned(), profiles);
|
||||
changes.state.insert((*room_info.room_id).to_owned(), state_events);
|
||||
|
||||
Ok(user_ids)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(?room_id))]
|
||||
pub(crate) async fn handle_room_account_data(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
@@ -535,6 +537,7 @@ impl BaseClient {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub(crate) async fn handle_account_data(
|
||||
&self,
|
||||
events: &[Raw<AnyGlobalAccountDataEvent>],
|
||||
@@ -580,6 +583,7 @@ impl BaseClient {
|
||||
}
|
||||
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
#[instrument(skip_all)]
|
||||
pub(crate) async fn preprocess_to_device_events(
|
||||
&self,
|
||||
to_device_events: Vec<Raw<ruma::events::AnyToDeviceEvent>>,
|
||||
@@ -656,6 +660,7 @@ impl BaseClient {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `response` - The response that we received after a successful sync.
|
||||
#[instrument(skip_all)]
|
||||
pub async fn receive_sync_response(
|
||||
&self,
|
||||
response: api::sync::sync_events::v3::Response,
|
||||
@@ -720,13 +725,21 @@ impl BaseClient {
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let Some(event) =
|
||||
new_info.ephemeral.events.iter().find_map(|e| match e.deserialize() {
|
||||
Ok(AnySyncEphemeralRoomEvent::Receipt(event)) => Some(event.content),
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
changes.add_receipts(&room_id, event);
|
||||
for raw in &new_info.ephemeral.events {
|
||||
match raw.deserialize() {
|
||||
Ok(AnySyncEphemeralRoomEvent::Receipt(event)) => {
|
||||
changes.add_receipts(&room_id, event.content);
|
||||
}
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
let event_id: Option<String> = raw.get_field("event_id").ok().flatten();
|
||||
#[rustfmt::skip]
|
||||
info!(
|
||||
?room_id, event_id,
|
||||
"Failed to deserialize ephemeral room event: {e}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if new_info.timeline.limited {
|
||||
@@ -907,6 +920,7 @@ impl BaseClient {
|
||||
/// * `room_id` - The room id this response belongs to.
|
||||
///
|
||||
/// * `response` - The raw response that was received from the server.
|
||||
#[instrument(skip_all, fields(?room_id))]
|
||||
pub async fn receive_members(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
use std::collections::BTreeMap;
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
use std::ops::Deref;
|
||||
|
||||
use ruma::{
|
||||
api::client::sync::sync_events::{
|
||||
v3::{self, Ephemeral},
|
||||
v4, DeviceLists,
|
||||
},
|
||||
DeviceKeyAlgorithm, UInt,
|
||||
use ruma::api::client::sync::sync_events::{
|
||||
v3::{self, Ephemeral},
|
||||
v4,
|
||||
};
|
||||
use tracing::{debug, info, instrument};
|
||||
|
||||
@@ -56,61 +52,35 @@ impl BaseClient {
|
||||
|
||||
let to_device_events = to_device.as_ref().map(|v4| v4.events.clone()).unwrap_or_default();
|
||||
|
||||
// Destructure the single `None` of the E2EE extension into separate objects
|
||||
// since that's what the `OlmMachine` API expects. Passing in the default
|
||||
// empty maps and vecs for this is completely fine, since the `OlmMachine`
|
||||
// assumes empty maps/vecs mean no change in the one-time key counts.
|
||||
|
||||
// We declare default values that can be referenced hereinbelow. When we try to
|
||||
// extract values from `e2ee`, that would be unfortunate to clone the
|
||||
// value just to pass them (to remove them `e2ee`) as a reference later.
|
||||
let device_one_time_keys_count = BTreeMap::<DeviceKeyAlgorithm, UInt>::default();
|
||||
let device_unused_fallback_key_types = None;
|
||||
|
||||
let (device_lists, device_one_time_keys_count, device_unused_fallback_key_types) = e2ee
|
||||
.as_ref()
|
||||
.map(|e2ee| {
|
||||
(
|
||||
e2ee.device_lists.clone(),
|
||||
&e2ee.device_one_time_keys_count,
|
||||
&e2ee.device_unused_fallback_key_types,
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
(
|
||||
DeviceLists::default(),
|
||||
&device_one_time_keys_count,
|
||||
&device_unused_fallback_key_types,
|
||||
)
|
||||
});
|
||||
|
||||
info!(
|
||||
to_device_events = to_device_events.len(),
|
||||
device_one_time_keys_count = device_one_time_keys_count.len(),
|
||||
device_one_time_keys_count = e2ee.device_one_time_keys_count.len(),
|
||||
device_unused_fallback_key_types =
|
||||
device_unused_fallback_key_types.as_ref().map(|v| v.len())
|
||||
e2ee.device_unused_fallback_key_types.as_ref().map(|v| v.len())
|
||||
);
|
||||
|
||||
// Process the to-device events and other related e2ee data. This returns a list
|
||||
// of all the to-device events that were passed in but encrypted ones
|
||||
// were replaced with their decrypted version.
|
||||
// Passing in the default empty maps and vecs for this is completely fine, since
|
||||
// the `OlmMachine` assumes empty maps/vecs mean no change in the one-time key
|
||||
// counts.
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
let to_device_events = {
|
||||
self.preprocess_to_device_events(
|
||||
let to_device_events = self
|
||||
.preprocess_to_device_events(
|
||||
to_device_events,
|
||||
&device_lists,
|
||||
device_one_time_keys_count,
|
||||
device_unused_fallback_key_types.as_deref(),
|
||||
&e2ee.device_lists,
|
||||
&e2ee.device_one_time_keys_count,
|
||||
e2ee.device_unused_fallback_key_types.as_deref(),
|
||||
)
|
||||
.await?
|
||||
};
|
||||
.await?;
|
||||
|
||||
let store = self.store.clone();
|
||||
let mut changes = StateChanges::default();
|
||||
let mut ambiguity_cache = AmbiguityCache::new(store.inner.clone());
|
||||
|
||||
if let Some(global_data) = account_data.as_ref() {
|
||||
self.handle_account_data(&global_data.global, &mut changes).await;
|
||||
if !account_data.is_empty() {
|
||||
self.handle_account_data(&account_data.global, &mut changes).await;
|
||||
}
|
||||
|
||||
let push_rules = self.get_push_rules(&changes).await?;
|
||||
@@ -118,8 +88,7 @@ impl BaseClient {
|
||||
let mut new_rooms = Rooms::default();
|
||||
|
||||
for (room_id, room_data) in rooms {
|
||||
if !room_data.invite_state.is_empty() {
|
||||
let invite_states = &room_data.invite_state;
|
||||
if let Some(invite_state) = &room_data.invite_state {
|
||||
let room = store.get_or_create_stripped_room(room_id).await;
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_state_partially_synced();
|
||||
@@ -131,11 +100,11 @@ impl BaseClient {
|
||||
changes.add_room(room_info);
|
||||
}
|
||||
|
||||
self.handle_invited_state(invite_states.as_slice(), &mut room_info, &mut changes);
|
||||
self.handle_invited_state(invite_state.as_slice(), &mut room_info, &mut changes);
|
||||
|
||||
new_rooms.invite.insert(
|
||||
room_id.clone(),
|
||||
v3::InvitedRoom::from(v3::InviteState::from(invite_states.clone())),
|
||||
v3::InvitedRoom::from(v3::InviteState::from(invite_state.clone())),
|
||||
);
|
||||
} else {
|
||||
let room = store.get_or_create_room(room_id, RoomState::Joined).await;
|
||||
@@ -160,13 +129,9 @@ impl BaseClient {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
let room_account_data = if let Some(inner_account_data) = &account_data {
|
||||
if let Some(events) = inner_account_data.rooms.get(room_id) {
|
||||
self.handle_room_account_data(room_id, events, &mut changes).await;
|
||||
Some(events.to_vec())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let room_account_data = if let Some(events) = account_data.rooms.get(room_id) {
|
||||
self.handle_room_account_data(room_id, events, &mut changes).await;
|
||||
Some(events.to_vec())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -225,10 +190,18 @@ impl BaseClient {
|
||||
}
|
||||
|
||||
// Process receipts now we have rooms
|
||||
if let Some(receipts) = &receipts {
|
||||
for (room_id, receipt_edu) in &receipts.rooms {
|
||||
if let Ok(receipt_edu) = receipt_edu.deserialize() {
|
||||
changes.add_receipts(room_id, receipt_edu.content);
|
||||
for (room_id, raw) in &receipts.rooms {
|
||||
match raw.deserialize() {
|
||||
Ok(event) => {
|
||||
changes.add_receipts(room_id, event.content);
|
||||
}
|
||||
Err(e) => {
|
||||
let event_id: Option<String> = raw.get_field("event_id").ok().flatten();
|
||||
#[rustfmt::skip]
|
||||
info!(
|
||||
?room_id, event_id,
|
||||
"Failed to deserialize ephemeral room event: {e}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,8 +210,8 @@ impl BaseClient {
|
||||
// because we want to have the push rules in place before we process
|
||||
// rooms and their events, but we want to create the rooms before we
|
||||
// process the `m.direct` account data event.
|
||||
if let Some(global_data) = account_data.as_ref() {
|
||||
self.handle_account_data(&global_data.global, &mut changes).await;
|
||||
if !account_data.is_empty() {
|
||||
self.handle_account_data(&account_data.global, &mut changes).await;
|
||||
}
|
||||
|
||||
// FIXME not yet supported by sliding sync.
|
||||
@@ -260,7 +233,7 @@ impl BaseClient {
|
||||
debug!("applied changes");
|
||||
|
||||
let device_one_time_keys_count =
|
||||
device_one_time_keys_count.iter().map(|(k, v)| (k.clone(), (*v).into())).collect();
|
||||
e2ee.device_one_time_keys_count.iter().map(|(k, v)| (k.clone(), (*v).into())).collect();
|
||||
|
||||
Ok(SyncResponse {
|
||||
rooms: new_rooms,
|
||||
@@ -268,9 +241,9 @@ impl BaseClient {
|
||||
notifications: changes.notifications,
|
||||
// FIXME not yet supported by sliding sync.
|
||||
presence: Default::default(),
|
||||
account_data: account_data.as_ref().map(|a| a.global.clone()).unwrap_or_default(),
|
||||
account_data: account_data.global.clone(),
|
||||
to_device_events,
|
||||
device_lists,
|
||||
device_lists: e2ee.device_lists.clone(),
|
||||
device_one_time_keys_count,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ use ruma::{
|
||||
self, AccountDataConfig, E2EEConfig, ExtensionsConfig, ReceiptsConfig, ToDeviceConfig,
|
||||
TypingConfig,
|
||||
},
|
||||
assign,
|
||||
events::TimelineEventType,
|
||||
OwnedRoomId,
|
||||
};
|
||||
@@ -84,18 +83,17 @@ impl SlidingSyncBuilder {
|
||||
/// does not matter.
|
||||
pub fn with_common_extensions(mut self) -> Self {
|
||||
{
|
||||
let mut cfg = self.extensions.get_or_insert_with(Default::default);
|
||||
if cfg.to_device.is_none() {
|
||||
cfg.to_device = Some(assign!(ToDeviceConfig::default(), { enabled: Some(true) }));
|
||||
let cfg = self.extensions.get_or_insert_with(Default::default);
|
||||
if cfg.to_device.enabled.is_none() {
|
||||
cfg.to_device.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.e2ee.is_none() {
|
||||
cfg.e2ee = Some(assign!(E2EEConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.e2ee.enabled.is_none() {
|
||||
cfg.e2ee.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.account_data.is_none() {
|
||||
cfg.account_data =
|
||||
Some(assign!(AccountDataConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.account_data.enabled.is_none() {
|
||||
cfg.account_data.enabled = Some(true);
|
||||
}
|
||||
}
|
||||
self
|
||||
@@ -108,26 +106,25 @@ impl SlidingSyncBuilder {
|
||||
/// does not matter.
|
||||
pub fn with_all_extensions(mut self) -> Self {
|
||||
{
|
||||
let mut cfg = self.extensions.get_or_insert_with(Default::default);
|
||||
if cfg.to_device.is_none() {
|
||||
cfg.to_device = Some(assign!(ToDeviceConfig::default(), { enabled: Some(true) }));
|
||||
let cfg = self.extensions.get_or_insert_with(Default::default);
|
||||
if cfg.to_device.enabled.is_none() {
|
||||
cfg.to_device.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.e2ee.is_none() {
|
||||
cfg.e2ee = Some(assign!(E2EEConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.e2ee.enabled.is_none() {
|
||||
cfg.e2ee.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.account_data.is_none() {
|
||||
cfg.account_data =
|
||||
Some(assign!(AccountDataConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.account_data.enabled.is_none() {
|
||||
cfg.account_data.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.receipts.is_none() {
|
||||
cfg.receipts = Some(assign!(ReceiptsConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.receipts.enabled.is_none() {
|
||||
cfg.receipts.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.typing.is_none() {
|
||||
cfg.typing = Some(assign!(TypingConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.typing.enabled.is_none() {
|
||||
cfg.typing.enabled = Some(true);
|
||||
}
|
||||
}
|
||||
self
|
||||
@@ -135,61 +132,62 @@ impl SlidingSyncBuilder {
|
||||
|
||||
/// Set the E2EE extension configuration.
|
||||
pub fn with_e2ee_extension(mut self, e2ee: E2EEConfig) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).e2ee = Some(e2ee);
|
||||
self.extensions.get_or_insert_with(Default::default).e2ee = e2ee;
|
||||
self
|
||||
}
|
||||
|
||||
/// Unset the E2EE extension configuration.
|
||||
pub fn without_e2ee_extension(mut self) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).e2ee = None;
|
||||
self.extensions.get_or_insert_with(Default::default).e2ee = E2EEConfig::default();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the ToDevice extension configuration.
|
||||
pub fn with_to_device_extension(mut self, to_device: ToDeviceConfig) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).to_device = Some(to_device);
|
||||
self.extensions.get_or_insert_with(Default::default).to_device = to_device;
|
||||
self
|
||||
}
|
||||
|
||||
/// Unset the ToDevice extension configuration.
|
||||
pub fn without_to_device_extension(mut self) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).to_device = None;
|
||||
self.extensions.get_or_insert_with(Default::default).to_device = ToDeviceConfig::default();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the account data extension configuration.
|
||||
pub fn with_account_data_extension(mut self, account_data: AccountDataConfig) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).account_data = Some(account_data);
|
||||
self.extensions.get_or_insert_with(Default::default).account_data = account_data;
|
||||
self
|
||||
}
|
||||
|
||||
/// Unset the account data extension configuration.
|
||||
pub fn without_account_data_extension(mut self) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).account_data = None;
|
||||
self.extensions.get_or_insert_with(Default::default).account_data =
|
||||
AccountDataConfig::default();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the Typing extension configuration.
|
||||
pub fn with_typing_extension(mut self, typing: TypingConfig) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).typing = Some(typing);
|
||||
self.extensions.get_or_insert_with(Default::default).typing = typing;
|
||||
self
|
||||
}
|
||||
|
||||
/// Unset the Typing extension configuration.
|
||||
pub fn without_typing_extension(mut self) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).typing = None;
|
||||
self.extensions.get_or_insert_with(Default::default).typing = TypingConfig::default();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the Receipt extension configuration.
|
||||
pub fn with_receipt_extension(mut self, receipt: ReceiptsConfig) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).receipts = Some(receipt);
|
||||
self.extensions.get_or_insert_with(Default::default).receipts = receipt;
|
||||
self
|
||||
}
|
||||
|
||||
/// Unset the Receipt extension configuration.
|
||||
pub fn without_receipt_extension(mut self) -> Self {
|
||||
self.extensions.get_or_insert_with(Default::default).receipts = None;
|
||||
self.extensions.get_or_insert_with(Default::default).receipts = ReceiptsConfig::default();
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
@@ -174,9 +174,8 @@ pub(super) async fn restore_sliding_sync_state(
|
||||
|
||||
// Let's update the `SlidingSync`.
|
||||
if let Some(since) = to_device_since {
|
||||
if let Some(to_device_ext) =
|
||||
extensions.get_or_insert_with(Default::default).to_device.as_mut()
|
||||
{
|
||||
let to_device_ext = &mut extensions.get_or_insert_with(Default::default).to_device;
|
||||
if to_device_ext.enabled == Some(true) {
|
||||
to_device_ext.since = Some(since);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,7 @@ pub use room::*;
|
||||
use ruma::{
|
||||
api::client::{
|
||||
error::ErrorKind,
|
||||
sync::sync_events::v4::{
|
||||
self, AccountDataConfig, E2EEConfig, ExtensionsConfig, ToDeviceConfig,
|
||||
},
|
||||
sync::sync_events::v4::{self, ExtensionsConfig},
|
||||
},
|
||||
assign,
|
||||
events::TimelineEventType,
|
||||
@@ -154,18 +152,18 @@ impl SlidingSync {
|
||||
/// Add the common extensions if not already configured.
|
||||
pub fn add_common_extensions(&self) {
|
||||
let mut lock = self.inner.extensions.lock().unwrap();
|
||||
let mut cfg = lock.get_or_insert_with(Default::default);
|
||||
let cfg = lock.get_or_insert_with(Default::default);
|
||||
|
||||
if cfg.to_device.is_none() {
|
||||
cfg.to_device = Some(assign!(ToDeviceConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.to_device.enabled.is_none() {
|
||||
cfg.to_device.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.e2ee.is_none() {
|
||||
cfg.e2ee = Some(assign!(E2EEConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.e2ee.enabled.is_none() {
|
||||
cfg.e2ee.enabled = Some(true);
|
||||
}
|
||||
|
||||
if cfg.account_data.is_none() {
|
||||
cfg.account_data = Some(assign!(AccountDataConfig::default(), { enabled: Some(true) }));
|
||||
if cfg.account_data.enabled.is_none() {
|
||||
cfg.account_data.enabled = Some(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +187,6 @@ impl SlidingSync {
|
||||
.unwrap()
|
||||
.get_or_insert_with(Default::default)
|
||||
.to_device
|
||||
.get_or_insert_with(Default::default)
|
||||
.since = Some(since);
|
||||
}
|
||||
|
||||
@@ -257,11 +254,8 @@ impl SlidingSync {
|
||||
//
|
||||
// The token is also loaded from storage in the `SlidingSyncBuilder::build()`
|
||||
// method.
|
||||
let mut to_device = extensions.to_device.unwrap_or_default();
|
||||
to_device.enabled = Some(true);
|
||||
|
||||
extensions.to_device = Some(to_device);
|
||||
extensions.e2ee = Some(assign!(E2EEConfig::default(), { enabled: Some(true) }));
|
||||
extensions.to_device.enabled = Some(true);
|
||||
extensions.e2ee.enabled = Some(true);
|
||||
|
||||
extensions
|
||||
} else {
|
||||
@@ -273,10 +267,10 @@ impl SlidingSync {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.and_then(|e| e.to_device.as_ref()?.since.to_owned());
|
||||
.and_then(|e| e.to_device.since.clone());
|
||||
|
||||
let mut extensions: ExtensionsConfig = Default::default();
|
||||
extensions.to_device = Some(assign!(ToDeviceConfig::default(), { since }));
|
||||
extensions.to_device.since = since;
|
||||
|
||||
extensions
|
||||
}
|
||||
@@ -642,7 +636,7 @@ impl From<&SlidingSync> for FrozenSlidingSync {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.and_then(|ext| ext.to_device.as_ref()?.since.clone()),
|
||||
.and_then(|ext| ext.to_device.since.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -660,6 +654,7 @@ pub struct UpdateSummary {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use assert_matches::assert_matches;
|
||||
use ruma::api::client::sync::sync_events::v4::{E2EEConfig, ToDeviceConfig};
|
||||
use wiremock::MockServer;
|
||||
|
||||
use super::*;
|
||||
@@ -677,9 +672,9 @@ mod test {
|
||||
// e2ee anyways.
|
||||
assert_matches!(
|
||||
extensions.to_device,
|
||||
Some(ToDeviceConfig { enabled: Some(true), since: None, .. })
|
||||
ToDeviceConfig { enabled: Some(true), since: None, .. }
|
||||
);
|
||||
assert_matches!(extensions.e2ee, Some(E2EEConfig { enabled: Some(true), .. }));
|
||||
assert_matches!(extensions.e2ee, E2EEConfig { enabled: Some(true), .. });
|
||||
|
||||
let some_since = "some_since".to_owned();
|
||||
sync.update_to_device_since(some_since.to_owned());
|
||||
@@ -690,16 +685,16 @@ mod test {
|
||||
// stickyness.
|
||||
assert_matches!(
|
||||
extensions.to_device,
|
||||
Some(ToDeviceConfig { enabled: None, since: Some(since), .. }) if since == some_since
|
||||
ToDeviceConfig { enabled: None, since: Some(since), .. } if since == some_since
|
||||
);
|
||||
assert_matches!(extensions.e2ee, None);
|
||||
assert_matches!(extensions.e2ee, E2EEConfig { enabled: None, .. });
|
||||
|
||||
let extensions = sync.prepare_extension_config(None);
|
||||
// Even if there isn't a `pos`, if we have a to-device `since` token, we put it
|
||||
// into the request.
|
||||
assert_matches!(
|
||||
extensions.to_device,
|
||||
Some(ToDeviceConfig { enabled: Some(true), since: Some(since), .. }) if since == some_since
|
||||
ToDeviceConfig { enabled: Some(true), since: Some(since), .. } if since == some_since
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -170,7 +170,7 @@ impl SlidingSyncRoom {
|
||||
self.inner.is_dm = is_dm;
|
||||
}
|
||||
|
||||
if !invite_state.is_empty() {
|
||||
if invite_state.is_some() {
|
||||
self.inner.invite_state = invite_state;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user