Commit Graph

1191 Commits

Author SHA1 Message Date
Alfonso Grillo
b248aa9862 ffi: Add push notification support for unstable m.poll.start 2023-09-26 10:38:24 +02:00
Jonas Platte
f2c569440e ui: Remove transaction ID parameter on Timeline methods
There is no reason for it to be configurable in the high-level API,
since the timeline manages local echoes automatically.
2023-09-25 16:50:59 +02:00
Jonas Platte
cb8c71ad68 ffi: Add EventTimelineItem::can_be_replied_to 2023-09-25 11:26:51 +02:00
Jonas Platte
579f59c54b ffi: Update send_reply to not make unnecessary network requests
… and add Room::get_event_timeline_item_by_event_id so send_reply can be
called more easily by EX-iOS given its code structure.
2023-09-25 11:26:51 +02:00
Marco Romano
bd18c373fe Workaround uniffi kotlin bug with empty structs
Adds a dummy fuield to `UnstableVoiceContent`, otherwise uniffi
will generate an empty Kotlin data class which breaks compilation
(Kotlin data classes must have at least 1 field).
Upstream bug: https://github.com/mozilla/uniffi-rs/issues/1760
2023-09-21 14:28:55 +00:00
Ivan Enderlin
77d6c3144e Merge pull request #2581 from Hywan/feat-ffi-room-avatar-image-info 2023-09-21 12:24:02 +02:00
Ivan Enderlin
0989dd7fb7 feat(ui): Add the none filter
feat(ui): Add the `none` filter
2023-09-21 10:20:07 +02:00
Ivan Enderlin
7fc77a2d7e fix(ffi): RoomListItem::full_room is now async.
Because it creates a bug on iOS when using `RUNTIME.block_on` here.

This patch also adds `full_room_blocking` temporarily for Kotlin.
2023-09-21 09:35:16 +02:00
Ivan Enderlin
ce2bac6818 feat(ffi): Add RoomListEntriesDynamicFilterKind::None. 2023-09-21 09:32:12 +02:00
Jonas Platte
1a15802201 Upgrade Ruma 2023-09-20 14:19:06 +02:00
Jonas Platte
784171e261 ffi: Don't check original sender of message when editing
The timeline checks this already. The network request made for this was
wasteful and unnecessary.
2023-09-20 11:57:38 +02:00
Ivan Enderlin
8217d18117 doc(ffi): Document media_info of Room::upload_avatar. 2023-09-20 10:32:47 +02:00
Ivan Enderlin
a23d497d5c feat(ffi): Room::upload_avatar now has an Option<ImageInfo>.
This patch adds `Option<ImageInfo>` as an argument of
`Room::upload_avatar`.

To achieve that, this patch implements
`TryFrom<ImageInfo> for ruma::events::room::avatar::ImageInfo`.
2023-09-20 10:25:40 +02:00
Ivan Enderlin
dfdc32f89a feat(ffi): Rename TimelineError to MediaInfoError.
The `TimelineError` type only contains error variants used for
`ImageInfo`, `AudioInfo`, `VideoInfo`, `FileInfo` and so on. It's never
used for something strictly related to the `Timeline`.

This patch then renames `TimelineError` to `MediaInfoError`.
The `MissingMediaInfoField` variant becomes `MediaField`. The
`InvalidMediaInfoField` becomes `InvalidField`.
2023-09-20 10:00:40 +02:00
Nicolas Mauri
31cb34f909 ffi: Add support for voice messages sent as m.room.message 2023-09-19 18:11:52 +00:00
Jonas Platte
13c9b0f803 ffi: Add _blocking versions of async methods in notification_settings 2023-09-19 12:13:42 +02:00
Jonas Platte
40f701986c ffi: Add _blocking versions of async methods in session_verification 2023-09-19 12:13:42 +02:00
Jonas Platte
7f2f3053f1 ffi: Add _blocking versions of async methods in sync_service 2023-09-19 12:13:42 +02:00
Jonas Platte
0ceb93a410 ffi: Add _blocking versions of async methods in room 2023-09-19 12:13:42 +02:00
Jonas Platte
45b7e075c9 Remove unused dependencies 2023-09-18 19:56:06 +02:00
Ivan Enderlin
7198239ea6 feat(ui): RoomListService::sync_indicator takes delays as parameters
feat(ui): `RoomListService::sync_indicator` takes delays as parameters
2023-09-18 11:06:24 +02:00
Marco Romano
3bad812ff8 Use new poll event replacement types
* Bump ruma
* Use new ruma types for UnstablePollStartEventContent
* Use from/into for UnstablePollStartEventContent.
2023-09-18 11:03:41 +02:00
Ivan Enderlin
5e28257d77 feat(ui): RoomListService::sync_indicator takes delays as parameters.
Prior to this patch, we were using 2 constants to define the
sync indicator delays: `SYNC_INDICATOR_DELAY_BEFORE_SHOWING` and
`SYNC_INDICATOR_DELAY_BEFORE_HIDING`. After some discussions with
some users, it appears that it's desirable to make these values
parameterizable.

Thus, this patch updates `RoomListService::sync_indicator` to accept 2
parameters: `delay_before_showing` and `delay_before_hiding`. The patch
also updates the FFI bindings.
2023-09-18 10:44:03 +02:00
Ivan Enderlin
79231f940f feat(ffi): Improve performances of Room::members
feat(ffi): Improve performances of `Room::members`
2023-09-18 10:40:48 +02:00
Ivan Enderlin
8032c39fda at(ui): Use a dynamic limit over the RoomList entries
feat(ui): Use a dynamic limit over the `RoomList` entries
2023-09-15 17:06:51 +02:00
Ivan Enderlin
d12eda5839 feat(ui): RoomList provides entries that are limited.
For some room lists, the number of entries can be gigantic. For example,
some accounts have 800, 2500, or even 4000 rooms! It's not necessary for
the client/app to display all the 4000 rooms. First, it can create some
performance issues, second, nobody will scroll 4000 rooms to search for
a particular room :-). Such users are more likely to use a search bar or
something equivalent. The idea is that `RoomListService` will continue
to sync all the data, but only a _limited_ version of it will be shared
to the client/app.

This patch takes `RoomList::entries_with_dynamic_filter`, and improves
it to include this (dynamic) limit.

This patch renames `RoomList::entries_with_dynamic_filter`
to `::entries_with_dynamic_adapters`. It now returns a
`RoomListDynamicEntriesController`, which is a renaming of
`DynamicRoomListFilter`. Basically, the “dynamic filter” becomes a
“dynamic controller” because `RoomList::entries_with_dynamic_adapters`
manages more than a filter. It now uses
`eyeball_im_util::vector::DynamicLimit` to dynamically limit the size
of entries. And that's the major idea behind this patch.

`RoomListDynamicEntriesController::set` is renamed `::set_filter`, and 2
new methods are introduced: `add_one_page` and `reset_to_one_page`.

A _page_ is like a chunk of room entries we want to view or add. When
doing `next_page`, the limit increases to `old_limit + page_size`. The
`reset_pages` method resets the `limit` to `page_size` only.
2023-09-15 13:34:20 +02:00
Benjamin Bouvier
b9b042ec4a chore(auth): prefix Session data structures with the auth kind 2023-09-15 13:03:11 +02:00
Benjamin Bouvier
7665b15c5a chore(auth): prefix SessionTokens data structures with the auth kind 2023-09-15 13:03:11 +02:00
Benjamin Bouvier
7e142c8132 refactor(oidc): lower cognitive load by removing RegisteredClientData 2023-09-15 13:03:11 +02:00
Benjamin Bouvier
6db19198fc chore(oidc): restore_registered_client doesn't need to be async 2023-09-15 13:03:11 +02:00
Benjamin Bouvier
b749b3546f feat(auth): make the session callbacks work for the matrix auth scheme too 2023-09-14 17:42:56 +02:00
Jorge Martín
6c45e56d61 ffi: Add Client.remove_avatar function 2023-09-14 17:02:23 +02:00
Jonas Platte
84daf1f079 ffi: Add RoomListItem::room_info_blocking 2023-09-14 16:49:36 +02:00
Nicolas Mauri
6d8d174a5e ffi: RoomInfo notification mode must reflect the user-defined mode (#2545) 2023-09-14 14:23:32 +02:00
Benjamin Bouvier
67b0305a3e feat: Add a cross-process lock mechanism for OIDC token refresh (#2440)
This adds a cross-process lock for refresh to work correctly.

We want to coordinate token refresh across multiple processes. For that, we're using a cross-process lock, and a value in the database identifying the latest session tokens that are valid (a hash of the actual tokens, for security reasons).

Whenever we run into an HTTP error indicating that the tokens have been invalidated, we try to refresh the access tokens; that's already existing prior to this PR. The novelty introduced is that we take a cross-process lock before doing so, now. Taking this lock will also load a session hash from the database, and we'll compare it against the latest "known" session hash (that the current process saved into its memory).

If there's no mismatch (i.e. the database and the currently known are the same), then we're all good and can keep going with the refresh, synchronize the hashes everywhere (in-memory and database), make sure the client is notified about it (through a new user-provided callback `SaveSessionCallback`; on iOS this will save it into the device's keychain).

Otherwise, that means another process has done a refresh under our feet. In that case, we ask an authoritative source for trusted session tokens. On iOS, they're reloaded from the device keychain; that happens through a new user-provided callback `ReloadSessionCallback`. Then, we make sure that the DB and the in-memory value recall this latest value.

An embedder who would like to make use of the cross-process locking mechanism should call `client.oidc().set_session_callbacks` and `client.oidc().enable_cross_process_refresh`. If only interested with the pings for new sessions, the client may only call `client.oidc().set_session_callbacks`.

Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/2418.
Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/2476

## Future improvements

- More testing of the whole flow. Not sure if mocking will be quite fit for OIDC, as this may require setting up an HTTPS server for the authentication code exchange and other OIDC-specific flows.
- Get rid of `SessionChange`, which duplicates in some way how a client can be notified about session changes.

---

* chore: replace manual StateMemoryStore::new with derived Default

* feat: add store backing for cross-process locking in state store

* chore: rename CryptoStoreLock to CrossProcessStoreLock

* chore: generalize cross-process lock

* feat: move the cross-process locking mechanism to the main crate

* feat: add support for cross-process store lock in the state store 🥳

* feat: implement a cross-process lock for OIDC token refresh

* chore: tweak comment + function name

* feat: make restore_session safe wrt cross-process lock

* feat: add FFI method + add mechanism to reload from keychain

* fix rename

* feat: return early when there was another process refreshed tokens

* fix FFI compile error + tweak some comments

* fix: put the reload_session callback and cross-process locks behind Arc to share them across clients

* feat: Add session retrieval to FFI.

* HACKY; KIDS DON'T DO THIS AT HOME

* chore: log if the hash from db isn't the same from the one from the returned session

* make it simpler to test OIDC token refresh

* some work, that includes fixes and a first test

* feat: require that the reload_session_callback be set at the same time as the cross-process lock

* chore: traces, traces everywhere

* fix: inherit session_change_sender when creating the notification client

* Some FFI improvements to help with tokio problems

* feat: resilient mode when DB/callback disagree about session (callback wins!)

* chore: move sender.send to the finish_refreshing function

* feat: add a save_session callback in the FFI and use it to save the session in keychain while holding XP lock

* fix test expectation after adding the check 🤷

* feat: split the ClientDelegate into two parts, including brand new ClientSessionDelegate

* chore: get rid of lease lock impl in the state store, as it's now unused

* a mix of fmt + clippy

* feat: add ctor for the crossprocessrefreshlockctx

* Include user ID when retrieving session.

Necessary as this isn't known when creating the AuthenticationService.

* yo dawg, you can't block while you block

* share auth data between parent and child client, add lock, AAAAAA this is messy

* tweaks

* feat: make the cross-process store locks generic

And move the implementation to the common crate.

* chore: upgrade some code comments to doc comments in `OngoingMigration`

* feat: implement `CryptoStore::remove_custom_value`

As it's going to be used for the OIDC PR, so as to remove a remembered hash of session tokens.

* remove unneeded remnants

* correctly wait for current request to finish

* feat: make it possible to setup session delegates on android too(?)

* put the cross process stuff in its own file

* typos 🤷

* fix: detach before sending token refresh request, to make sure the response tokens are always properly saved

* kleepee

* First round of review, thanks jonas!

* review round 2. FIGHT

* remove useless logs + avoid using deref explicitly

* more specialized error when cross-process lock is enabled without session callbacks

* fix: avoid cyclic reference between the session callback and client

---------

Co-authored-by: Doug <douglase@element.io>
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-09-14 12:47:47 +02:00
Jonas Platte
03bbdce15f ffi: Add in_reply_to field to MessageLikeEventContent::RoomMessage 2023-09-14 12:18:30 +02:00
Jonas Platte
1cbcee4fea Use as_variant crate for shorter code 2023-09-13 18:33:33 +02:00
Doug
3b685e01b5 feat(bindings): Expose account management action in the bindings. 2023-09-13 14:14:02 +02:00
Doug
7d8c6521ed feat(sdk): Add an action parameter to the OIDC account URL. 2023-09-13 14:14:02 +02:00
Damir Jelić
c32f2444fc Use the base64 encoding/decoding methods from vodozemac in the bindings 2023-09-08 11:43:32 +02:00
Doug
eb865f490a chore(bindings): Handle OIDC metadata changes. (#2503)
Currently when the AuthenticationService is given updated metadata, it is ignored if a dynamic registration has already been made for a selected issuer. This PR fixes that by storing the metadata's hash and resetting the store when there is a mis-match.

Additionally it moves OidcRegistrations out of the FFI into a new authentication module in the UI crate and adds some tests.
2023-09-07 17:28:58 +00:00
Mauro Romito
fa91a74452 feat(bindings): upload user avatar 2023-09-07 18:12:16 +02:00
Doug
d7f5cd51e4 chore(bindings): Add missing contacts field on OidcConfiguration. 2023-09-07 17:43:20 +02:00
Jonas Platte
e655490b9f ffi: Add is_threaded method to timeline Message object 2023-09-07 16:54:21 +02:00
Ivan Enderlin
243cc6773a chore(ffi): Make Clippy happy. 2023-09-07 11:27:06 +02:00
Ivan Enderlin
4e50bcddc2 feat(ffi) Room::members returns a RoomMembersIterator.
This patch updates `Room::members` to return
`Result<Arc<RoomMembersIterator>, ClientError>`. This
`RoomMembersIterator` type is new, and is implemented in this patch too.

The idea behind this patch is to allow the bindings to “paginate” over
the list of members for a particular room, in case the room has 17k
members for example.
2023-09-07 11:03:16 +02:00
Ivan Enderlin
08424366d8 feat(ffi): Add ChunkIterator<T>.
This patch implements a generic `ChunkIterator` type. It's not tailored
for use via FFI, but it can be embedded inside a `uniffi::Object` for
example.
2023-09-07 11:01:39 +02:00
Benjamin Bouvier
28ab8e9efc chore: remove Client::authentication_server_info as it's duplicated from Oidc::authentication_server_info 2023-09-07 10:34:54 +02:00
Ivan Enderlin
77cc84a6d9 feat(ffi): Room::fetch_members no longer return a TaskHandle.
This patch changes the behavior of `Room::fetch_members. Since it's now
an async method, it no longer needs to return a `TaskHandle`.
2023-09-06 17:44:48 +02:00
Ivan Enderlin
f3d33efa0f feat(ffi): Make fetch_members, members and member async.
This patch makes the following methods on `Room` async: `fetch_members`,
`members`, and `member`.
2023-09-06 17:37:05 +02:00