Backing up room keys isn't part of the outgoing requests processing
loop, instead the user is supposed to have a separate loop calling
`BackupMachine::backup()`.
Fallback keys until now have been rotated on the basis that the
homeserver tells us that a fallback key has been used.
Now this leads to various problems if the server tells us too often that
it has been used, i.e. if we receive the same sync response too often.
It leaves us also open to the homeserver being dishonest and never
telling us that the fallback key has been used.
Let's avoid all these problems by just rotating the fallback key in a
time-based manner.
Signed-off-by: Damir Jelić <poljar@termina.org.uk>
Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
Now that there is some support for [MSC2530](https://github.com/matrix-org/matrix-spec-proposals/pull/2530), I gave adding sending captions a try. ( This is my first time with Rust 😄 )
I tried it on Element X with a hardcoded caption and it seems to work well

(It even got forwarded through mautrix-whatsapp and the caption was visible on the Whatsapp side)
---
* ffi: Expose filename and formatted body fields for media captions
In relevance to MSC2530
* MSC2530: added the ability to send media with captions
Signed-off-by: Marco Antonio Alvarez <surakin@gmail.com>
* signoff
Signed-off-by: Marco Antonio Alvarez <surakin@gmail.com>
* fixing the import messup
* fix missing parameters in documentation
* fix formatting
* move optional parameters to the end
* more formatting fixes
* more formatting fixes
* rename url parameter to filename in send_attachment and helpers
* fix send_attachment documentation example
* move caption and formatted_caption into attachmentconfig
* fix formatting
* fix formatting
* fix formatting (hopefully the last one)
* updated stale comments
* simplify attachment message comments
---------
Signed-off-by: Marco Antonio Alvarez <surakin@gmail.com>
Co-authored-by: SpiritCroc <dev@spiritcroc.de>
This adds a new mechanism in the UI crate (since re-attempts to decrypt happen in the timeline, as of today — later that'll happen in the event cache) to notify whenever we run into a UTD (an event couldn't be decrypted) or a late-decryption event (after some time, a UTD could be decrypted).
This new hook will deduplicate pings for the same event (identifying events on their event id), and also implements an optional grace period. If an event was a UTD:
- if it's still a UTD after the grace period, then it's reported with a `None` `time_to_decrypt`,
- if it's not a UTD anymore (i.e. it's been decrypted in the meanwhile), then it's reported with a `time_to_decrypt` set to the time it took to decrypt the event (approximate, since it starts counting from the time the timeline receives it, not the time the SDK fails to decrypt it at first).
It's configurable as an optional hook on timeline builders. For the FFI, it's configurable at the sync service's level with a "delegate", and then the sync service will forward the hook to the timelines it creates, and the hook will forward the UTD info to the delegate.
Part of https://github.com/element-hq/element-meta/issues/2300.
---
* ui: add a new module and trait for subscribing to unable-to-decrypt notifications
and late decryptions (i.e. the key came in after the event that required it for decryption).
* timeline: hook in (!) the unable-to-decrypt hook
* timeline: prefix some test names with test_
* utd hook: delay reporting a UTDs
* ffi: add support for configuring the utd hook
* utd hook: switch strategy, have a single hook
And have the data structure contain extra information about late-decryption events.
* utd hook: rename `SmartUtdHook` to `UtdHookManager`
* ffi: configure the UTD hook with a grace period of 60 seconds
And ignore UTDs that have been late-decrypted in less than 4 seconds.
* utd hook: update documentation and satisfy the clippy gods
* ffi: introduce another UnableToDecryptInfo FFI struct that exposes simplified fields from the SDK's version
* review: introduce type alias for pending utd reports
* review: address other review comments
The idea of this patch is to explore the possibility to unify the
`all_rooms` list with the `invites` list in `RoomListService`.
Since this is entirely experimental, it's behind a new feature
flag. The feature itself can be configured at runtime by using the
new `SyncServiceBuilder::with_unified_invites_in_room_list` builder
method, or directly with `RoomListService::new_with_unified_invites`
constructor.
This is needed to be able to diff between increases and decreases of power levels ("user Alice was promoted Admin", etc.).
---
* ffi: add `previous` power levels to `OtherState::RoomPowerLevels`
This is needed to be able to diff between increases and decreases of power levels.
* ffi: please clippy
* ffi: inline initialization of `previous` and `users`
Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/3191
Allows support for fetching the unstable_features from `/_matrix/clients/versions`.
Specifically, to be used for checking the state of org.matrix.msc4028 through ffi to the clients.
---
* sdk: fetch unstable_features supported by homeserver
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
* ffi: add can_homeserver_push_encrypted_event_to_device method
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
* fix: use copied instead of dereferencing
Co-authored-by: Benjamin Bouvier <public@benj.me>
Signed-off-by: Hanadi <hanadi.tamimi@gmail.com>
* fix: move can_homeserver_push_encrypted_event_to_device logic to sdk
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
* fix: remove unused unstable features param in client builder
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
* fix: use assert instead of asserteq for bool check
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
* fix: documentation
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
* Apply suggestions from code review
Signed-off-by: Benjamin Bouvier <public@benj.me>
---------
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
Signed-off-by: Hanadi <hanadi.tamimi@gmail.com>
Signed-off-by: Benjamin Bouvier <public@benj.me>
Co-authored-by: Benjamin Bouvier <public@benj.me>
- `Room::build_power_level_changes_from_current()` was replaced by `Room::get_power_levels()`, which now returns an SDK/Ruma `RoomPowerLevels` value containing all the data we need to display these values in UI and not only the customised values.
- `Room::reset_power_levels()` was added to the FFI layer.
It maps user ids to users' power levels.
Also, make sure it just returns an empty map if this info is not available, instead of crashing.
Then use it in the FFI side to output updated data for the `RoomInfo`.
---
* sdk: create new `users_with_power_levels` fn which maps user ids to users' power levels
Also, make sure it just returns an empty map if this info is not available, instead of crashing.
* Update crates/matrix-sdk/src/room/mod.rs
Co-authored-by: Benjamin Bouvier <public@benj.me>
Signed-off-by: Jorge Martin Espinosa <angel.arasthel@gmail.com>
* Improve tests
---------
Signed-off-by: Jorge Martin Espinosa <angel.arasthel@gmail.com>
Co-authored-by: Benjamin Bouvier <public@benj.me>
This does two things:
- raise the timeout value for the `/members` queries, because they can super slow in Synapse because of nasal demons,
- and aggregate all the fields of `RoomMember` early, so users don't have to call getters to read each field.
---
* room_members: Export plain old data for room members to avoid FFI calls
Signed-off-by: Timo Kösters <timo@koesters.xyz>
* room_member: Respond to review feedback
* room_member: Remove previous RoomMember struct
* ffi: rename ExportedRoomMember to RoomMember
---------
Signed-off-by: Timo Kösters <timo@koesters.xyz>
Co-authored-by: Benjamin Bouvier <public@benj.me>
Changes:
- sdk: Add `get_user_power_level` and `get_suggested_user_role` functions so we don't need to load the whole room member list to know if a user has some power level/role.
- ffi: add an FFI fn for `get_suggested_user_role`.
- ffi: add `user_power_levels` to `RoomInfo`.
The goal of this PR is being able to fetch a user's power level or role almost immediately and avoid having to load and find the user in the room member list, which can be very slow to load (especially in EX Android).
---
* sdk: Add `get_user_power_level` and `get_suggested_user_role` functions to get the power level for a user without loading the room member list.
* ffi: add `suggested_role_for_user` fn, which calls the new `get_suggested_user_role` fn in Room
* sdk: add test
* ffi: add user power level info to `RoomInfo`
* Add changes to changelog
* sdk: Fix docs formatting
* sdk & ffi: use `&UserId` instead of `OwnedUserId`
Also, simplify error mapping.
* sdk: add extra test
* ffi: fix `OwnedUserId` -> `&UserId` conversion
* sdk: Replace `UserId::parse` with `user_id!` macro for literals in tests
* Update crates/matrix-sdk/tests/integration/room/joined.rs
Signed-off-by: Benjamin Bouvier <public@benj.me>
---------
Signed-off-by: Benjamin Bouvier <public@benj.me>
Co-authored-by: Benjamin Bouvier <public@benj.me>
To do so, we need to put the weak reference `EventCache -> Client` back into the `EventCache`.
Putting the `sdk::Room` in the `RoomEventCache` will be useful to run room queries like backpagination (aka call `Room::messages()`).
The ClientBuilder already exposes setting the proxy, but sadly the
AuthService doesn't let you configure the ClientBuilder directly (yet).
So logging in with a proxy wasn't supported until now.
* event cache: move it to the main SDK crate
* event cache: add requested Debug impl to `RoomEventCacheUpdate`
Somehow the compiler asked for it now...
* event cache: add missing copyright notice to store file
* event cache: use a weak reference to the client internally
This will make it possible to have the `Client` own an `EventCache` without a reference
cycle.
* event cache: move the spawned task to its own function
* event cache: move RwLock from EventCache::inner to the only mutable field inside EventCacheInner
* event cache: have the Client own *the* event cache
The goal is to have a unique EventCache instance overall, that's available from everywhere in
the SDK, notably when creating timelines for rooms.
Because the event cache only owns a weak reference to the client, it means the Client still
can be dropped, In turn, this will close its sender of `RoomUpdates`, which will gracefully
close the task spawned in `EventCache::new` after it's done handling the latest updates.
* event cache: process room updates one at a time
* timeline: use the client-wide event cache instead of spawning one per timeline
This now means that we're passing the "initial events" to the event cache just before initializing
the timeline. As a result, there might be previous events that the event cache saw (coming from
sync), but now we can't decide where to put them; drop previously known events in that case.
* event cache: hey, turns out we don't even need the weak back-link
Keeping it as a separate commit, to make it easier to revert later.
* event cache: remove unused errors
Keeping the error type and results, though, because we might have store errors soonish.
* fixup! event cache: move the spawned task to its own function
* event cache: manually subscribe to the event cache
It was a bad idea to have it enabled by default, since some users may not be interested in all
updates for all rooms (e.g. bots). Instead, we make it so that the event cache must be
explicitly subscribed to, and we do it in two cases:
- in the UI `TimelineBuilder::build` method, because we're interested in updates to the current
room,
- in the `RoomListService`, because we *will* be interested in updates to room derived data (e.g.
unread counts, read receipts, and so on).
This avoids a bit of fiddling when creating the event cache in the client.
This is resilient when a parent Client is forked into a child Client, because the child
`EventCache` share the same subscription as the parent's.
It doesn't make sense to set a thread identifier for the receipt of the latest event: the event might not belong to that thread, and the SDK would need to check that,
since the latest event isn't reachable from the outside world (the reason why `mark_as_read` had been introduced). So let's remove it for now, and
add comments related to threaded receipts.
This slightly changes the API when interacting from the FFI layer:
- instead of `mark_as_unread` and `mark_as_read`, there's now a single method `set_unread_flag(bool)`, which callers may call with true (i.e. unread) or false (i.e. not unread).
- there's a new method `mark_as_read` which sends a read receipt to the latest event in the timeline, using other commits from the same PR,
- forcing a room as read requires calling first `set_unread_flag(false)` then `mark_as_read()`
It's wrong that the first client, used only to determine how to log in and find the user id, try to run the encryption initialization tasks.
In particular, it should not even try to bootstrap the account, as this may send OTKs to the server, which the client will forget about as soon
as it's respawned as a database-backed client.