Compare commits

...

5901 Commits

Author SHA1 Message Date
Damir Jelić dda080c497 sqlite: Bump the version 2024-07-19 10:18:27 +02:00
Damir Jelić a18f90bfaa chore: Fix some invalid test data 2024-07-18 17:10:00 +02:00
Damir Jelić 60ed367fd9 chore: Format the changelog a bit better 2024-07-18 17:10:00 +02:00
Damir Jelić 1157067dba chore: Prepare the matrix-sdk-crypto release 0.7.2 2024-07-18 17:10:00 +02:00
Damir Jelić 8efdba6136 crypto: Fix UserIdentity::is_verified to take into account our own identity
The `UserIdentity::is_verified()` method in the matrix-sdk-crypto crate
before version 0.7.2 doesn't take into account the verification status
of the user's own identity while performing the check and may as a result
return a value contrary to what is implied by its name and documentation.

This patch fixes this and adds a regression test.

The method itself is not used internally and as such has not a larger
impact.

Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
Signed-off-by: Damir Jelić <poljar@termina.org.uk>
2024-07-18 17:10:00 +02:00
Damir Jelić 1029e51eb3 chore: Use a released version of vodozemac (#3721) 2024-07-18 17:10:00 +02:00
Damir Jelić f25916cb5c chore: Remove an unused import 2024-05-13 12:48:30 +02:00
Damir Jelić 637e830e85 chore: Fix the formatting 2024-05-13 12:48:30 +02:00
Damir Jelić 04362cdc36 chore(crypto): Bump the version of the crypto crate to 0.7.1 2024-05-13 12:31:26 +02:00
Valere fa10bbb5dd fix(crypto): Avoid incorrect usage of private backup key
This fixes instances of key backup corruption and prevents inadvertently
logging the private backup key to the logs.
2024-05-13 12:31:26 +02:00
Benjamin Bouvier 4164effbf9 Bump matrix-sdk to 0.7.1 2024-01-22 11:27:03 +01:00
Sami J. Mäkinen 917e8c291e Upgrade aquamarine dependency 2024-01-22 11:25:56 +01:00
Jonas Platte 3e17fc2072 Add a description for matrix-sdk-ui 2024-01-05 14:23:41 +01:00
Jonas Platte f08e978540 Upgrade uniffi
… and specify a version such that publishing of the ui crate becomes possible.

We still use a git dependency for FFI crate builds because there were some
likely important breaking changes that haven't been released.

This is required to publish `matrix-sdk-ui`.
2024-01-05 14:03:44 +01:00
Jonas Platte 40b09cda2f Bump all of the versions to 0.7.0 2024-01-05 12:58:54 +01:00
Jonas Platte 2710a85897 Rename matrix-sdk-base/{Changelog => CHANGELOG.md}
… for consistency.
2024-01-05 12:58:54 +01:00
Jonas Platte 315e6c9d85 Use workspace dependencies for matrix-sdk-test 2024-01-05 12:58:54 +01:00
Benjamin Bouvier 2822f2471a Update crates/matrix-sdk/src/room/mod.rs
Signed-off-by: Benjamin Bouvier <public@benj.me>
2024-01-05 12:12:52 +01:00
Kévin Commaille b0530ba3a6 sdk: Create ReportedContentScore
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2024-01-05 12:12:52 +01:00
Kévin Commaille 844212e965 sdk: Add method to report an event
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2024-01-05 12:12:52 +01:00
Jonas Platte eb33c3754a bindings: Move matrix_sdk_ui enum definitions out of UDL 2024-01-04 17:14:44 +01:00
Richard van der Hoff cf57992346 indexeddb: logging for open sequence (#2983)
I was trying to figure out what was taking so long, so added some logging.
2024-01-04 15:10:54 +00:00
Jonas Platte d9f99f84f5 Fix Cargo warning about deafult-features
`default-features = false` was already a no-op prior to workspace dependency change,
as `matrix-sdk-crypto` has no default features.
2024-01-04 14:54:33 +01:00
Benjamin Bouvier afd05a24df Rename BaseClient::update_summary to BaseClient::set_room_info 2024-01-04 11:41:50 +01:00
Benjamin Bouvier 0f91eebc96 BaseClient::apply_changes doesn't need to be async 2024-01-04 11:41:50 +01:00
Benjamin Bouvier 0f8b99b744 Remove spurious testing guards in the read status integration test 2024-01-04 11:41:50 +01:00
Benjamin Bouvier 30714c3f92 Don't cause a spurious room info update when setting the latest event 2024-01-04 11:41:50 +01:00
Benjamin Bouvier 96b427a332 Add test showing the spurious room info update 2024-01-04 11:41:50 +01:00
Jonas Platte 1c7bf820bf Use workspace dependencies for crates/* dependencies
… except from examples (such that they remain copy-pastable).
2024-01-04 10:02:07 +01:00
Jonas Platte 24b879bbc0 Clean up Cargo manifest formattting 2024-01-04 10:02:07 +01:00
Jonas Platte 51a0bb6f3b ci: Upgrade typos action 2024-01-04 09:53:17 +01:00
Jonas Platte 9eca314511 Fix a typo 2024-01-04 09:53:17 +01:00
Jonas Platte c4724c082e Upgrade dependencies 2024-01-02 19:12:42 +01:00
manuroe 3d9d3b7ca6 Merge pull request #2977 from matrix-org/valere/long_mark_as_sent
Remove an expensive database call only used for tracing prupose
2024-01-02 13:35:36 +01:00
Valere 541d9184c6 remove expensive db call for tracing 2023-12-22 16:19:25 +01:00
Benjamin Bouvier 45bdbf5067 Add test to make sure notification count is taken into account when processing sliding sync 2023-12-22 14:45:54 +01:00
Benjamin Bouvier 04ef3d9f95 Fix: revert notification count change from read receipts PR
This was modified and then removed from the PR, and forgot to put back the previous
implementation.
2023-12-22 14:45:54 +01:00
Benjamin Bouvier 75fe874cae read receipts: don't update a RoomInfo if the read receipts haven't changed 2023-12-21 17:41:35 +01:00
Benjamin Bouvier 2a77aaa068 read receipts: update the API shape of compute_notifications 2023-12-21 15:54:19 +01:00
Benjamin Bouvier 4a686229e1 read receipts: make find_and_count_events a method of RoomReadReceipts 2023-12-21 15:54:19 +01:00
Benjamin Bouvier d64fb8241d read receipts: add test for find_and_count_events 2023-12-21 15:54:19 +01:00
Benjamin Bouvier 870d1eafb4 read receipts: add RoomReadReceipts::reset 2023-12-21 15:54:19 +01:00
Benjamin Bouvier a9905eaedd read receipts: don't count the same action multiple time per event 2023-12-21 15:54:19 +01:00
Benjamin Bouvier f1c15da87d read receipts: make count_unread_and_mention a method of RoomReadReceipts and rename it 2023-12-21 15:54:19 +01:00
Benjamin Bouvier f2b53080b6 read receipts: move RoomReadReceipts to the read_receipts.rs file 2023-12-21 15:54:19 +01:00
Benjamin Bouvier 7fe4e22076 read receipts: test count_unread_and_highlights 2023-12-21 15:54:19 +01:00
Benjamin Bouvier b6dab1a3a5 read receipts: compute_notifications doesn't need to be async 2023-12-21 15:54:19 +01:00
Andy Balaam ec833c81e0 Migrate inbound_group_session2 to fix keys incorrectly copied from old store version (#2957)
In migrate_data_for_v6, we incorrectly copied the keys in inbound_group_sessions verbatim into inbound_group_sessions2. What we should have done is re-encrypt them using the new table name, so we fix that up with a new migration here.

This caused the bug because we were looking for sessions to mark as backed up by calculating their key (from room_id and session_id) but that key did not exist, because the old sessions were stored under the incorrect keys. So no sessions were marked as backed up, and we repeatedly tried to re-mark them.
2023-12-21 14:52:02 +00:00
Ivan Enderlin de0574aa14 Merge pull request #2925 from zecakeh/create-dm-encrypted
client: Allow to create encrypted DM
2023-12-21 14:38:32 +01:00
Benjamin Bouvier fb1ff70538 Disable integration test in code coverage build
The test fails only in the codecov build, not in a local build or in the other integration test.

Needs further investigation.
2023-12-21 11:55:29 +01:00
Benjamin Bouvier d6bcbf2281 Address review comments
- copyright notice
- doc comments and better doc in general
- use static dispatch instead of &dyn T
- other misc comments
2023-12-21 11:55:29 +01:00
Benjamin Bouvier cbc832411d read receipts: add an extra num_unread_notifications field
This helps supporting cases where we want to show that a room has some activity (unread messages) but no notifications.
2023-12-21 11:55:29 +01:00
Benjamin Bouvier 843fcac3c1 read receipts: don't clone cached events for computing the read receipt state
Before this patch, we needed to clone the inner `timeline_queue` and turn it into a concrete `Vec<SyncTimelineEvent>`, just to iterate on the elements,
and because returning an iterator from a trait method is impractical. This now changes it to return the actual concrete type of `timeline_queue`, so
we don't need the extra allocations.

Ideally, matrix-sdk and matrix-sdk-base would be merged, so we don't need to use a trait at all here.
2023-12-21 11:55:29 +01:00
Benjamin Bouvier b3a8f34655 read receipts: move the unread messages and mentions counts to separate fields of RoomInfo 2023-12-21 11:55:29 +01:00
Benjamin Bouvier 73af3d9cfa Make it clear that some functions are tests or test helpers only 2023-12-21 11:55:29 +01:00
Benjamin Bouvier 09e355a7bc read receipts: add integration tests for read receipts 2023-12-21 11:55:29 +01:00
Benjamin Bouvier 9ba09b2ae8 sync: process unread notification count client-side 2023-12-21 11:55:29 +01:00
Benjamin Bouvier c9b02ad068 doc: document SlidingSyncRoomInner::timeline_queue a bit better 2023-12-21 11:55:29 +01:00
Benjamin Bouvier 07c428ec56 sdk base: add latest_read_receipt_event_id field to RoomInfo 2023-12-21 11:55:29 +01:00
Valere d4b8f88e10 Fix regenerate_olm_machine losing backup state (#2961)
* Fix regenerate_olm_machine loosing backup state

* use new helper

* clippy fix

* quick review
2023-12-21 09:43:55 +01:00
Stefan Ceriu 28a58479e7 Bring back original (slower) build style under the sequentially fla… (#2960)
* Bring back original (slower) build style under the `sequentially` flag to work around new build style hanging on older machines

* Apply suggestions from code review

Signed-off-by: Benjamin Bouvier <public@benj.me>

---------

Signed-off-by: Benjamin Bouvier <public@benj.me>
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-12-21 08:15:21 +00:00
Benjamin Bouvier 320b868694 style: remove spurious fully-qualified path 2023-12-18 15:47:45 +01:00
Benjamin Bouvier 8615b1283a sliding sync: don't cause a spurious RoomInfo update
The room_info variable in this function contains the latest_event, and later it's set as the Room's room info (`inner.inner`) field.
Calling `set_latest_event` manually here will cause an update of the `RoomInfo` subscriber, while we're not done processing the full
room, and a room info update will happen anyways later (when the entire room is processed), so this one is spurious and will only
show a partial update of the fields.
2023-12-18 15:47:45 +01:00
Benjamin Bouvier 9a4d539428 sliding sync: optimize finding the room member state event
- We can look up the session meta only once, it's not useful to do it once per event as it's
loop-invariant.
- We can look at the events backwards and stop after the first room membership event we see
in that order.
2023-12-18 15:47:45 +01:00
Kévin Commaille 4d3fc44425 Put imports behind feature
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-18 14:07:01 +01:00
Kévin Commaille 8b878c6591 Fix test
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-18 14:05:01 +01:00
Kévin Commaille 738f7f0336 client: Create DM as encrypted by default
If `e2e-encryption` feature is enabled.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-18 13:04:39 +01:00
Valere f5fb44bd80 Maybe trigger backup at end of sync (#2939)
* maybe trigger backup at end of sync

* add test for backup upload

* missing e2e cfg

* add sliding sync tests

* fix borrow

* fix indent

* fix naming from copy/paste

* Remove extracted function

* fix clippy

* style: inline a few variables only used once into their use sites

---------

Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-12-18 10:41:44 +00:00
Doug e0ba9f5a22 xtask: Use Uniffi Library mode for Kotlin too. 2023-12-18 10:34:38 +01:00
Doug b5aeea0a3b xtask: Handle multiple headers/modulemaps. 2023-12-18 10:34:38 +01:00
Ivan Enderlin 19526cea6b Merge pull request #2928 from zecakeh/qrcode-changes
verification: Expose the `QrVerificationState` and the stream for its changes
2023-12-15 12:52:50 +01:00
Ivan Enderlin 99d0b37914 Merge pull request #2951 from matrix-org/andybalaam/clarify-meaning-of-pendingbackup-sessions
Clarify the meaning of the sessions field in PendingBackup
2023-12-15 12:45:29 +01:00
Andy Balaam b21a438b7e Merge pull request #2934 from matrix-org/andybalaam/mark_sessions_as_backed_up
Provide `CryptoStore::mark_inbound_group_sessions_as_backed_up` on stores and use it in `BackupMachine::mark_request_as_sent`
2023-12-15 11:40:50 +00:00
Andy Balaam f3101baa08 Merge branch 'main' into andybalaam/mark_sessions_as_backed_up 2023-12-15 10:47:36 +00:00
Andy Balaam 0cf99db001 Delete accidentally-copied repeat_vars function
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-15 10:47:11 +00:00
Andy Balaam a032d33d21 Remove comments in favour of a separate PR with type aliases
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-15 10:40:36 +00:00
Andy Balaam 92212cc328 Clarify the meaning of the sessions field in PendingBackup
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-15 10:38:56 +00:00
Kévin Commaille 6ffb0181e4 Make sure qrcode feature is additive
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-15 11:01:03 +01:00
dependabot[bot] 614bf942c0 build(deps): bump zerocopy from 0.7.26 to 0.7.31
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.7.26 to 0.7.31.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.7.26...v0.7.31)

---
updated-dependencies:
- dependency-name: zerocopy
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 10:39:21 +01:00
Andy Balaam 512509ce8b Switch to using chunk_large_query_over in mark_inbound_group_sessions_as_backed_up
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-14 16:56:13 +00:00
Andy Balaam dfb33c9534 Move chunk_large_query_over into SqliteObjectExt so it can be reused
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-14 16:55:36 +00:00
Andy Balaam 03aad4e965 Move repeat_vars into utils so it can be reused
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-14 16:34:45 +00:00
Andy Balaam 9e67b6fcb1 Merge branch 'main' into andybalaam/mark_sessions_as_backed_up 2023-12-14 15:25:43 +00:00
Ivan Enderlin 9443f455a4 Test Media caching, and re-implement it inside MemoryStore
Test Media caching, and re-implement it inside `MemoryStore`
2023-12-14 15:51:04 +01:00
Ivan Enderlin 384deec1c8 chore(base): Simplify code. 2023-12-14 15:39:24 +01:00
Kévin Commaille 5310f41cda integration-testing: Add test for QR verification
And check room ID in SAS test.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 15:23:16 +01:00
Ivan Enderlin 95a1db8fc7 Merge pull request #2947 from matrix-org/andybalaam/use-correct-limit-in-chunk_large_query_over
Use the limit() method to find the variable limit in chunk_large_query_over
2023-12-14 14:31:40 +01:00
Ivan Enderlin 3d9dffa3b7 chore(base): Remove unused imports. 2023-12-14 14:18:56 +01:00
Andy Balaam 3d7e1d5989 Merge branch 'main' into andybalaam/use-correct-limit-in-chunk_large_query_over 2023-12-14 13:17:06 +00:00
Ivan Enderlin a46bf76d74 test(base): Improve test_media_content.
This patch improves `test_media_content` to ensure that, in case of
multiple medias, only the expected ones are removed. Previously, the
test wasn't testing _other_ medias that should be kept in case of
removals.

This patch continues to improve `test_media_content` to ensure that the
content of the media are the expected ones.

Finally, this patch updates the `MemoryStore` implementation to make
tests happy.
2023-12-14 14:15:01 +01:00
Ivan Enderlin 326935db63 feat(base): Correct implementations for MemoryStore media removal.
This patch rewrites `MemoryStore::add_media_content`,
`::get_media_content`, `::remove_media_content` and
`::remove_media_content_for_uri` to (i) work on `mxc://` URI instead
of “unique key”, and (ii) to handle removal correctly thanks to the new
`RingBuffer::remove` method.
2023-12-14 13:54:12 +01:00
Ivan Enderlin 416bc8b0e4 feat(base): Implement Media::uri.
This new method returns the `MxcUri` associated to the `Media`.
2023-12-14 13:53:23 +01:00
Ivan Enderlin edd113a17c feat(common): Implement RingBuffer::remove. 2023-12-14 13:28:17 +01:00
Ivan Enderlin 66411d7b2e Merge pull request #2946 from matrix-org/andybalaam/tests-for-repeat_vars
Unit tests for the repeat_vars function
2023-12-14 13:10:12 +01:00
Ivan Enderlin 4a53bf1f3d Merge pull request #2945 from matrix-org/andybalaam/limits-access-for-sqlite
Provide a limit() method in sqlite to find limit values
2023-12-14 13:10:02 +01:00
Andy Balaam a3aa55ce91 Use the limit() method to find the variable limit
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-14 11:31:01 +00:00
Andy Balaam 0066ae6614 Unit tests for the repeat_vars function
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-14 11:26:43 +00:00
Andy Balaam 17ebc23719 Provide a limit() method in sqlite to find limit values
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-14 11:21:25 +00:00
Ivan Enderlin cdb3449ce2 test(sdk): Test that Media::get_media_content with caching works. 2023-12-14 12:11:24 +01:00
Ivan Enderlin c5b11fc2f8 feat(sdk): Simplify code from Media::get_media_content.
If `use_cache` is true and the cache exists, let's return everything in
one go instead of declaring a `content` variable. It makes the code
easier to read and to understand.
2023-12-14 12:10:08 +01:00
Ivan Enderlin 2ad6acb930 doc(common): Add documentation for RingBuffer::drain. 2023-12-14 12:07:08 +01:00
Ivan Enderlin dac779f4fc test(base): Re-implement a super basic media cache for MemoryStore.
This is a rather over simplistic media cache implementation for the
`MemoryStore`.

It's based on a `RingBuffer` of size 20.

`remove_media_content` pops all medias until the correct one is met (if
it exists). `remove_media_content_for_uri` removes all medias, it
ignores the URI.
2023-12-14 12:04:58 +01:00
Kévin Commaille e2ea19ee77 Add rule kind to error messages
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille cc38768bf4 notification settings: Don't error if poll start rules are not found
These rules are unstable so they might not be
found in every ruleset.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille c87bd4d4ec notification settings: Log errors from requests
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille 5700c700f0 error: Use NotificationSettingsError::RuleNotFound's rule ID in display impl
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille fff9882792 notification settings: Rely more on Ruma methods
Simplifies code.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille 45f8ff11c2 notification settings: Derive Copy for enum types
This a good practice for inexpensive types
and avoids to have to call `.clone()` explicitely.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille 7c9d842d05 notification settings: Use private method to get poll start rule ID
A `From` implementation is part of the public API
and this conversion does not make sense outside of the module.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-14 11:39:42 +01:00
Kévin Commaille c3706d7ca0 notification settings: Allow to manage keywords (#2905)
* notification settings: Allow to manage keywords
* Fix wording of docs

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Signed-off-by: Kévin Commaille <76261501+zecakeh@users.noreply.github.com>
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2023-12-14 11:16:40 +01:00
Ivan Enderlin b314da37b8 feat(ffi): Timeline::send_image and send_video takes an optional thumbnail_url
feat(ffi): `Timeline::send_image` and `send_video` takes an optional `thumbnail_url`
2023-12-14 10:48:16 +01:00
Ivan Enderlin 02ba6c0dbe feat(ffi): Client::*media* are now async
feat(ffi): `Client::*media*` are now async
2023-12-14 09:14:39 +01:00
Ivan Enderlin 22d9c62262 feat(ffi): Timeline::send_image and send_video takes an optional thumbnail_url.
This patch updates `Timeline::send_image` and `Timeline::send_video` so
that `thumbnail_url` is now an `Option<String>`.

The idea is to allow sending an image or a video without a thumbnail.
2023-12-13 17:07:03 +01:00
Ivan Enderlin 18b6387a7a Merge pull request #2935 from matrix-org/rav/fix_nonmonotonic_panic
Configure `Instant` wasm polyfill to use monotonic time
2023-12-13 15:57:32 +01:00
Ivan Enderlin c5ddba2e13 feat(ffi): Client::*media* are now async.
This patch removes `RUNTIME.block_on` inside `Client::get_media_file`,
`::upload_media`, `::get_media_content` and `::get_media_thumbnail`, and
makes those methods async.
2023-12-13 15:33:01 +01:00
Kévin Commaille 9756ed28cf verification: Expose the room ID where the verification is happening
Useful if we want to know in what room
we just sent a VerificationRequest,
with UserIdentity::request_verification

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-13 15:22:13 +01:00
Richard van der Hoff 5701cea51e Configure Instant wasm polyfill to use monotonic time
With the `inaccurate` feature, this polyfill uses `Date.now()` to emulate
`Instant`, which is not monotonic, causing problems like
https://github.com/element-hq/element-web/issues/26416.
2023-12-13 12:08:54 +00:00
Andy Balaam 794b7ead7a Clippy fixes 2023-12-13 08:43:59 +00:00
Andy Balaam f879f3d866 Formatting 2023-12-13 08:32:00 +00:00
Andy Balaam 4ebb8e29b4 Provide CryptoStore::mark_sessions_as_backed_up on stores and use it in BackupMachine::mark_request_as_sent
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2023-12-12 16:09:22 +00:00
Doug d764fca7da xtask: Move all the Swift files found
… and fix build swift errors.

- The XCFramework was being built with dylibs which aren't supported on iOS
- The tests build was attempting to generate uniffi from a moved file
2023-12-12 16:51:49 +01:00
Jonas Platte 3b7f9f7361 Reapply "bindings: Use new uniffi-bindgen build mode"
This reverts commit 0d24bcf6e5.
2023-12-12 16:51:49 +01:00
Doug 73770b78bb room: Add test for unban_user. 2023-12-12 16:13:09 +01:00
Doug 7cffc34984 ffi: Support banning, unbanning and kicking users. 2023-12-12 16:13:09 +01:00
Benjamin Bouvier c4ef967523 dx: tweak debugging of user/device pairs missing a session 2023-12-11 17:11:11 +01:00
Kévin Commaille f0b378179e matrix auth: Await save_session_callback
Otherwise the future will not run.
Changes the corresponding test to fail with the old behavior.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-11 16:54:53 +01:00
Kévin Commaille ee344112f3 verification: Expose the QrVerificationState and the stream for its changes
Allows to have a similar API as SasVerification

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-11 16:13:56 +01:00
Benoit Marty 1f52aca210 Fix typo in doc. 2023-12-11 12:13:05 +01:00
Kévin Commaille 74091de8ef sdk: Make sure "testing" feature is enabled for integration tests
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-11 11:53:25 +01:00
Kévin Commaille 0f6efc391a client: Allow to create encrypted DM
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-11 11:14:19 +01:00
Mauro c707e1f17e feat(bindings): expose a function to send private read receipts (#2906) 2023-12-11 09:29:06 +00:00
Benjamin Bouvier 5ab69f7400 ffi: add emoji indices in the session verification data + use decimals as a fallback 2023-12-08 14:48:48 +01:00
Jonas Platte e652069896 sdk: Use crates.io release of mas-oidc-client 2023-12-07 17:34:36 +01:00
Benjamin Bouvier 5337c9d9ea refactoring: make it clear that notifications aren't stored in the state store
`notifications` were stored in the `StateChanges` struct, which made me think that they're then persisted in the database. It's not the case, they
were just stored there by convenience. This commit changes it to a parameter that's passed, as it's not too invasive and clearer that this is only
transient data.
2023-12-07 16:56:18 +01:00
Benjamin Bouvier 9fd52e5df7 timeline: document event_filter better 2023-12-07 10:35:42 +01:00
Benjamin Bouvier 4ab79a4085 timeline: add the room version in the event_filter parameters 2023-12-07 10:35:42 +01:00
Benjamin Bouvier a132c0a885 read receipts: apply a default event filter only for events that get rendered 2023-12-07 10:35:42 +01:00
Benjamin Bouvier 5081802177 room: try restoring from a key backup during backpagination too 2023-12-05 16:53:06 +01:00
Stefan Ceriu 736188811f ffi: expose the call member state event type for clients to check if users can join calls 2023-12-05 15:51:28 +01:00
Benoit Marty 1337fdf0b8 ffi: Expose is_invite_for_me_enabled and set_invite_for_me_enabled in notification settings 2023-12-04 17:04:19 +01:00
Ivan Enderlin 0573137835 Merge pull request #2902 from matrix-org/rav/outgoing_key_requests_switch
Crypto: add new methods for turning off room key requests
2023-12-04 15:12:33 +01:00
Ivan Enderlin 21ce2b07a7 Merge pull request #2904 from matrix-org/jme/add-typing-notice-bindings
Add FFI bindgings for `Room.typing_notice()`
2023-12-04 15:09:46 +01:00
Richard van der Hoff 6451a9dffe rename toggle -> set 2023-12-04 12:53:02 +00:00
Kévin Commaille a6af31984a Assert that the stream is pending
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-04 13:30:43 +01:00
Kévin Commaille 2de45bcb51 notification settings: Do not expose NotificationSettings::new in the public API
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-04 13:30:43 +01:00
Kévin Commaille 7bdc1448bd notification settings: Drop event handler only when last instance is dropped
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-04 13:30:43 +01:00
Kévin Commaille 511c44c588 Add test for NotificationSettings::subscribe_to_changes
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-04 13:30:43 +01:00
Kévin Commaille a915900580 notification settings: Allow to subscribe to changes
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-04 13:30:43 +01:00
Kévin Commaille e12f6fcbb7 notification settings: Accept any type that implements AsRef<str> as rule_id
Simplifies the use of this API with the Predefined{*}RuleId Ruma types.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-12-04 13:30:43 +01:00
Jorge Martín 72dfd3d1fd Add FFI bindgings for Room.typing_notice() 2023-12-01 16:19:32 +01:00
Richard van der Hoff a6c206118d changelog 2023-12-01 12:50:43 +00:00
Richard van der Hoff 2536373546 Add new methods for turning off room key requests 2023-12-01 12:47:44 +00:00
Jorge Martín 045d94ab4b Rename message inside an error, since it clashes with Kotlin's default message property in exceptions 2023-12-01 12:07:40 +01:00
Benjamin Bouvier d8c02d7e55 timeline builder: tweak comments 2023-12-01 11:05:53 +01:00
Benjamin Bouvier b20313c492 read receipts: rename ReadReceipts fields
The "read_receipts" suffix isn't useful since we're looking at the fields of `ReadReceipts` already.
2023-12-01 11:05:53 +01:00
Benjamin Bouvier c3ea2c3736 Format with rustfmt nightly. 2023-12-01 11:05:53 +01:00
Benjamin Bouvier 2c1377b2b5 read receipts: a few function renamings and add getter/setter for receipts on events 2023-12-01 11:05:53 +01:00
Benjamin Bouvier bb85af9279 read receipts: add getter/setter for the latest read receipts cache 2023-12-01 11:05:53 +01:00
Benjamin Bouvier 58ab6704ff read receipts: a few function renamings
Add the prefix `load` to make it clear this may load from the storage.
2023-12-01 11:05:53 +01:00
Benjamin Bouvier 94a64296d1 Show the wrapped error when displaying a SlidingSync::JoinError 2023-11-30 19:52:20 +01:00
Benjamin Bouvier 7d6c16956f fix: reify reformat of missing_session_devices_by_user
`itertools::format` is known to cause issues when its display implementation is being
used multiple times, as it consumes the iterator it was given (and that can only happen once,
unless caching it). This is bad, as our production apps may have multiple subscribers they will
run into a panic.

The fix is to reify the debug string before it's logged, so the tracing consumer will only see
a string, and not the display implementation that would panic on the second use.
2023-11-30 19:52:20 +01:00
Damir Jelić 916bf69e5c Enable backups and set the backup download strategy for the bindings 2023-11-30 16:51:06 +01:00
Damir Jelić 915c10e1b4 Test for the one-by-one download of room keys 2023-11-30 16:20:51 +01:00
Damir Jelić 5e122c5c5e Add a background task which downloads room keys from the backup one-by-one 2023-11-30 16:20:51 +01:00
Damir Jelić 49e5461ef7 Add a method to check if we have a room key stored locally 2023-11-30 16:20:51 +01:00
Damir Jelić 27927c676d Allow the to create a FailuresCache with different values for the max timeout 2023-11-30 16:20:51 +01:00
Damir Jelić ac5a9e106b Move the FailuresCache into the common crate 2023-11-30 16:20:51 +01:00
Damir Jelić 94c4e685fc Test for recovery 2023-11-30 15:12:22 +01:00
Damir Jelić f248e272e9 Expose the recovery stuff in the bindings 2023-11-30 15:12:22 +01:00
Damir Jelić 97026fc3a6 Recovery support
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-11-30 15:12:22 +01:00
Richard van der Hoff 1fcd5af526 indexeddb: Update storage for inbound_group_sessions (#2885)
Currently, querying for inbound group sessions which need backing up is very
inefficient: we have to search through the whole list.

Here, we change the way they are stored so that we can maintain an index of the
ones that need a backup.

Fixes: https://github.com/vector-im/element-web/issues/26488
Fixes: https://github.com/matrix-org/matrix-rust-sdk/issues/2877

---

* indexeddb: Update storage for inbound_group_sessions

Currently, querying for inbound group sessions which need backing up is very
inefficient: we have to search through the whole list.

Here, we change the way they are stored so that we can maintain an index of the
ones that need a backup.

* Rename functions for clarity

* Remove spurious log line

This was a bit verbose

* Rename constants for i_g_s store names

* improve log messages

* add a warning

* Rename `InboundGroupSessionIndexedDbObject.data`

* formatting
2023-11-30 12:01:20 +01:00
Benjamin Bouvier 8b04db666c Remove room.rs file added by mistake
Thanks @jaller94 for noticing and letting me know :)
2023-11-30 10:27:25 +01:00
Timo 1ff2c5bb3e Add recommended vscode settings in contrib/ide 2023-11-28 13:41:04 +01:00
Jonas Platte 05f0106e06 ui: Improve logging for sync update processing 2023-11-27 18:55:21 +01:00
Jonas Platte fd0f369f75 ui: Add extra tracing spans for reactions 2023-11-27 18:55:21 +01:00
Jonas Platte 39fc283353 ui: Improve logging for redactions 2023-11-27 18:55:21 +01:00
Jonas Platte 3ebd8afa49 ui: Add more logging for Timeline::retry_send 2023-11-27 18:55:21 +01:00
Jonas Platte 2483ba2cc6 ui: Raise log level for local events
Local events don't happen as often, so we can afford a higher log level.
2023-11-27 18:55:21 +01:00
Jonas Platte 2d3a458a08 ui: Improve logging for sending attachments 2023-11-27 18:55:21 +01:00
Jonas Platte 246a128ec3 ui: Add logging for send-event cancellation 2023-11-27 18:55:21 +01:00
Jonas Platte 932f12e76d ui: Improve logging for timeline resets 2023-11-27 18:55:21 +01:00
Richard van der Hoff bfe79468c6 Indexeddb: Groundwork for fixing inbound_group_session lookups (#2884)
A set of non-functional changes which lay some groundwork in preparation for fixing vector-im/element-web#26488.
2023-11-27 15:59:49 +00:00
Timo 9503eb49c7 ffi: Expose power level overwrites on room creation 2023-11-27 14:38:35 +00:00
Marco Romano ded854425a timeline: Add poll history API
Allow to retrieve the Poll history of a Room.
The poll history is a Timeline instance that filters only on poll events.
2023-11-27 14:28:40 +00:00
Jonas Platte 959e90252b ffi: Create separate timeline object, mirroring the Rust API 2023-11-27 11:55:48 +01:00
Jonas Platte e761ad8f97 ffi: Remove remove_timeline method
It was somewhat of a footgun because it affected the cached timeline in
`RoomListItem`s as well and is not used anywhere anymore.
2023-11-27 11:55:48 +01:00
Jonas Platte ceeb5e78b6 ffi: Move more things into ruma module 2023-11-24 19:25:44 +01:00
Jonas Platte 04c4284b33 ffi: Split timeline into smaller modules 2023-11-24 19:25:44 +01:00
Jonas Platte bae191b4ed ffi: Move Ruma wrappers / extension traits to new module 2023-11-24 19:25:44 +01:00
Damir Jelić ea2e85c5f5 feat: Support for server-side key backups #2666 2023-11-24 18:16:42 +01:00
Damir Jelić d6401ef278 When disabling backups first delete it from the server 2023-11-24 18:01:05 +01:00
Damir Jelić 9bba437fdd Simplify the secret inbox handling for backups 2023-11-24 18:01:05 +01:00
Damir Jelić 19e65c05cf Remove the CheckingIfUploadNeeded UploadState variant 2023-11-24 18:01:05 +01:00
Damir Jelić 369ca7024f Apply suggestions from code review
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-11-24 18:01:05 +01:00
Damir Jelić e958b1ce28 Don't run the event handler examples 2023-11-24 18:01:05 +01:00
Damir Jelić 4912cd8a40 Typos please 2023-11-24 18:01:05 +01:00
Damir Jelić c99b0e8344 Fix some clippy warnings 2023-11-24 18:01:04 +01:00
Damir Jelić b38f501902 Add an example for the room key backup support 2023-11-24 17:59:00 +01:00
Damir Jelić f37467f81f Add tests for backups 2023-11-24 17:59:00 +01:00
Damir Jelić 6239231ba0 Try to resume backups if we restore the client
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-11-24 17:59:00 +01:00
Damir Jelić aa1623b891 Add a hack so the timeline retries to decrypt if we receive room keys from backup 2023-11-24 17:59:00 +01:00
Damir Jelić 99131d0d7a Fetch the backup recovery key when we import all known secrets 2023-11-24 17:59:00 +01:00
Damir Jelić c5c62d8fda Add a client task that will upload room keys to the backup 2023-11-24 17:58:58 +01:00
Damir Jelić b909f4400d Add support for backups 2023-11-24 17:56:09 +01:00
Damir Jelić 18d69f7515 Add a ChannelObservable 2023-11-24 17:53:33 +01:00
Richard van der Hoff 456d8bb4f2 Reduce logspam during encryption (#2859)
A few different changes to reduce the number of lines that get logged during an
encryption operation.
2023-11-24 14:21:01 +00:00
Jonas Platte b277423237 sdk: Upgrade mas-oicd-client 2023-11-24 15:01:17 +01:00
Jonas Platte 4621dd4317 ffi: Upgrade opentelemetry 2023-11-24 15:01:17 +01:00
Jonas Platte 17797da71a indexeddb: Upgrade dependencies 2023-11-24 15:01:17 +01:00
Jonas Platte eec4227dfc sdk: Upgrade async-related dependencies 2023-11-24 15:01:17 +01:00
Jonas Platte 64ddfd872c sqlite: Upgrade rusqlite / deadpool-sqlite 2023-11-24 15:01:17 +01:00
Jonas Platte 19a990ad41 Update Cargo.lock
The reqwest update is held back to avoid linking issues on iOS.
2023-11-24 15:01:17 +01:00
Jonas Platte 53ad6f5fe5 Upgrade itertools 2023-11-24 15:01:17 +01:00
Jonas Platte 8038414de2 Raise minimum version for Ruma
Otherwise the matrix-sdk crate can be used with an older version of
ruma-client-api which uses different types for a sliding sync type.

The sliding sync breaking change was allowed to be part of a patch
release because sliding sync is an unstable feature in Ruma.
2023-11-24 15:01:17 +01:00
Jonas Platte 560d71ceea sdk: Implement a custom event formatter for javascript logging
Somehow `fmt::pretty` manages to be both overcomplicated and not flexible
enough.

The driver here is that I want to put the event "fields" on a separate line to
the message.
2023-11-24 13:48:35 +01:00
Richard van der Hoff 6591a6ef04 Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-11-24 12:35:36 +00:00
Benjamin Bouvier 35bac2a6c3 test: add an integration test for left rooms 2023-11-23 15:17:26 +01:00
Benjamin Bouvier 7455b90d24 Tweak debug message wording for a timeline event
Probably from a bad copy-pasta with a poll event.
2023-11-23 15:11:54 +01:00
Benjamin Bouvier 1e359576ad room list service: add a new filter to get all rooms but the left ones
This allows to get a list of all the rooms except for left ones, since they're still part of a sliding sync server response.
2023-11-23 15:06:00 +01:00
Alfonso Grillo fe02752f29 fix: EventTimelineItem.is_editable() respects poll’s preconditions for editing (#2875)
This PR fixes the `EventTimelineItem.is_editable()` function for polls.

Before this changes it always returned false.
Now it consider poll's preconditions for editing:
- The poll has no votes yet
- The poll hasn't an end event
2023-11-23 14:03:25 +00:00
Jonas Platte aa7d2a21a3 test: Fix new clippy lints 2023-11-23 14:15:21 +01:00
Jonas Platte 337f2ad415 Upgrade nightly toolchain used for ci, xtask 2023-11-23 14:15:21 +01:00
Jonas Platte c5c3850edf Use the same nightly toolchain for all xtask commands 2023-11-23 14:15:21 +01:00
Richard van der Hoff 086e988e68 crypto: Be consistent about /keys/query endpoint name
Sometimes, we called this `keys query`, sometimes `/keys/query`, and sometimes,
just for variety, `keys/query`. Generally in Matrix we talk about `/keys/query`
so let's standardise on that.
2023-11-22 14:02:39 +00:00
Val Lorentz 5c37acb81c sdk: Add method to get the set of parent spaces of a room 2023-11-22 14:31:52 +01:00
Richard van der Hoff 2aaa709b0e Reinstate tracing instrumentation on ReadOnlyDevice::encrypt (#2873)
Until https://github.com/matrix-org/matrix-rust-sdk/pull/2862,
`GroupSessionManager::encrypt_session_for` called `Device::encrypt` (via
`Device::maybe_encrypt_room_key`.

`Device::encrypt` is a thin wrapper for `ReadOnlyDevice::encrypt`, but it also
has an `instrument` annotation.

https://github.com/matrix-org/matrix-rust-sdk/pull/2862 short-cuts
`Device::encrypt` and calls `ReadOnlyDevice::encrypt` directly: that was
functionally fine but of course means that we no longer benefit from the
`instrument` annotation.

This PR rectifies the situation by pushing the annotation down to
`ReadOnlyDevice::encrypt`. It also adds some documentation for that function,
since we are using it in more places now.

(Longer-term, I think we should probably aim to get rid of `Device::encrypt`
altogether, but that's a refactor I don't want to take on today.)
2023-11-22 13:04:36 +00:00
Alfonso Grillo 8fe501c4ed ui: Add poll editing API 2023-11-22 13:46:37 +01:00
Stefan Ceriu 79c020f169 Switch from building each target individually to letting cargo figure out the optimal way 2023-11-22 12:33:26 +01:00
Damir Jelić bb4254b9c9 Prepare our /keys/claim response handling to handle multiple OTKs (#2870)
This is useful if we ever decide to switch to X3DH for the session
establishment. It also refactors a bit the /keys/claim response handling
method.

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-11-22 10:41:08 +01:00
Damir Jelić ee0010e831 Make the mocks in some notification tests a bit more specific
The mocks in some notification tests mock any PUT/DELETE request without
the request to hit a certain path. These mocks then might respond to
unintended new requests the client might make.

The tests also assert a bunch of things manually instead of using
expectations when building the mock and calling server.verify().
2023-11-22 10:02:32 +01:00
Richard van der Hoff c9ddf92e25 Disable coverage checking for js_tracing 2023-11-22 07:37:21 +00:00
Jonas Platte c7712b52e6 crypto: Use Option instead of JsOption
We don't need to distinguish null from an absent field in any of the
places we used JsOption, so a regular Option is better.
2023-11-21 16:35:07 +01:00
Richard van der Hoff ead29388f2 crypto: Add instrument annotations to various methods 2023-11-21 14:31:41 +00:00
Benjamin Bouvier 06c9a1a355 Update crates/matrix-sdk/src/sliding_sync/room.rs
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-11-21 14:50:04 +01:00
Benjamin Bouvier 0ed4a9950c test: add a unit test for the group avatar being set and unset 2023-11-21 14:50:04 +01:00
Benjamin Bouvier 844340e0f7 sliding sync: fix unsetting the avatar in a sliding sync room
The meaning of "null" and "undefined" were conflated by Ruma, previously. This updates to the latest Ruma, which changed the `avatar` type from
`Option` to `JsOption` and thus allowed us to distinguish both cases: `null` means the avatar has been unset, `undefined` means it's not changed
since the previous request.
2023-11-21 14:50:04 +01:00
Benjamin Bouvier 692be61043 test: add an integration test for avatar in group conversations 2023-11-21 14:50:04 +01:00
Jonas Platte d0b6771251 crypto: Simplify double reference handling 2023-11-21 13:15:27 +01:00
Jonas Platte 47298b9200 test: Fix indentation 2023-11-21 13:15:27 +01:00
Jonas Platte a262cb23d9 Fix rustc, clippy warnings 2023-11-21 13:15:27 +01:00
Richard van der Hoff a881cd0712 crypto: Improve logging in receive_keys_claim_response 2023-11-21 11:40:48 +01:00
Richard van der Hoff c536760fc1 Improve performance of share_room_key (#2862)
Encryption doesn't usually require access to the user identity, so we can skip loading that from the store.

Unfortunately that means a fair bit of refectoring, in the form of replacing Device with ReadOnlyDevice.

This reduces the time taken to encrypt a message in a large room from about 3 seconds to 1 second.
2023-11-20 18:46:58 +00:00
Timo 894f4c218d element call: Remove E2EEenabled flag (#2847)
This is a deprecated flag for element call using livekit. It was used to enable/disable matrix signalling event encryption. This is not relevant for embedded mode at all since there the hosting client is taking care of encryption.

---

* Remove E2EEenabled flag from the rust sdk.
This is a deprecated flag for element call using livekit. It is replaced
by the `password` and the `perParticipantE2EE` flag.
If `perParticipantE2EE` is set to `false`
and there is now password encryption is disabled implicitly.

Signed-off-by: Timo K <toger5@hotmail.de>

* `cargo +nightly fmt`

Signed-off-by: Timo K <toger5@hotmail.de>

* change test based on review

Signed-off-by: Timo K <toger5@hotmail.de>

* Apply suggestions from code review

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-11-20 16:43:33 +01:00
Jonas Platte 6472ba5109 Upgrade UniFFI 2023-11-20 11:43:05 +01:00
Benjamin Bouvier bcf33c0bcb Test that a live read receipt update received in sliding sync updates the timeline 2023-11-20 10:53:38 +01:00
Benjamin Bouvier fe541bc601 sliding sync: include read receipts into room updates so they're handled by the timeline too 2023-11-20 10:53:38 +01:00
Richard van der Hoff 2d3ee89477 delint, again 2023-11-19 14:50:02 +00:00
Richard van der Hoff cb1827f151 delint 2023-11-17 18:37:57 +00:00
Richard van der Hoff 4299697935 Implement a custom event formatter for javascript logging
Somehow `fmt::pretty` manages to be both overcomplicated and not flexible
enough.

The driver here is that I want to put the event "fields" on a separate line to
the message.
2023-11-17 18:30:21 +00:00
Richard van der Hoff 7e53c6821b Improve performance of get_missing_sessions (#2845)
Two sets of improvements to `get_missing_sessions` here:

 * Currently, for any users who have an empty device list, we call `KeyQueryManager::wait_if_user_key_query_pending`, which waits up to 5 seconds for a `/keys/query` response. (Arguably, we should be waiting longer: it is not unusual for such a request to take a while.)

   The problem is that that user's server may have been blacklisted, in which case we won't even be trying to do `/keys/query` resquests for that user, so we'll be waiting for something that never happens.

   To fix this, let's check the failures list when deciding if we should wait for a user's devices.

 * Separately, but closely related: for each user thus affected, we do the wait *in series*. This is a bit silly: there is no point waiting 50 times. We can parallelise the work.

Fixes #2793.

---

* Move `get_user_devices` to `IdentityManager`

... since it's going to need to interact with the `FailuresCache` which is
stored there.

* `get_user_devices_for_encryption`: don't wait for failed servers

* `get_missing_sessions`: wait for users in parallel

Rather than waiting for each pending user in series, do all the waits in
parallel.

* Changelog

* Update crates/matrix-sdk-crypto/src/identities/manager.rs

* Address review comments
2023-11-17 12:45:16 +01:00
Benjamin Bouvier f21a9b704b doc: update doc comment for OlmMachine::receive_sync_changes and mention it in the changelog
Fixes #2846.

Update crates/matrix-sdk-crypto/src/machine.rs

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-11-16 16:53:21 +01:00
Jonas Platte cb08e5a103 crypto: Fix some typos 2023-11-16 15:58:28 +01:00
Jonas Platte e43a25a703 Avoid verbose string conversions when logging / printing 2023-11-16 15:58:28 +01:00
Jonas Platte ee9af5f501 crypto: Remove redundant tracing event field
Already logged as part of the parent span.
2023-11-16 15:58:28 +01:00
Jonas Platte f9aeb590e0 crypto: Generalize encryption methods 2023-11-16 15:58:28 +01:00
Jonas Platte 2d2eef8b0e crypto: Improve some documentation strings 2023-11-16 15:58:28 +01:00
Jonas Platte bfd2a1c445 Upgrade ruma crates to pull in bugfixes
Includes the following bugfixes:

- Fix the name of the fallback text field for extensible events in
  `RoomMessageEventContentWithoutRelation::make_reply_to_raw()`
- Allow to deserialize `(New)ConditionalPushRule` with a missing `conditions`
  field
- Fix deserialization of `claim_keys` responses without a `failures` field
2023-11-16 11:06:19 +01:00
Timo 6e5682d8d2 ffi: Add get_element_call_required_permissions 2023-11-15 12:00:53 +01:00
Alfonso Grillo 4a428b4731 Update ruma-events 2023-11-15 11:49:42 +01:00
Mauro c24830d794 ffi: Add a method to check if MSC 4028 is enabled on the homeserver 2023-11-15 09:30:23 +00:00
Richard van der Hoff 5786b1a631 Update changelog for matrix-sdk-crypto (#2837)
- Add an entry which I forgot for #2805

 - Reorder a few other items that have been added since
 https://github.com/matrix-org/matrix-rust-sdk/pull/2591.
2023-11-10 12:19:40 +00:00
Val Lorentz 445bf3b02a Add missing "room_id" to test_json::MEMBERS
It doesn't matter at the moment as the only test using `test_json::MEMBERS`
does not rely on the event being valid, but it shows this error
nonetheless:

```
2023-11-10T08:54:29.920782Z DEBUG receive_members{room_id="!hIMjEx205EXNyjVPCV:localhost"}: matrix_sdk_base::client: Failed to deserialize member event: missing field `room_id` at line 1 column 297 event_id="$151800140517rfvjc:localhost"
```

and https://spec.matrix.org/v1.8/client-server-api/#get_matrixclientv3roomsroomidmembers
says it is a required key.
2023-11-10 09:35:47 +00:00
Richard van der Hoff 71a2d23bf3 Handle missing devices in /keys/claim responses (#2805)
Keep a record of devices that were included in a /keys/claim request, and then, if they are missing in the response, register them as "failed".
2023-11-09 18:30:10 +00:00
Damir Jelić 955d611aaa Bump our deps so we pull in the new release of ruma-client-api 2023-11-09 17:40:03 +01:00
Ivan Enderlin 0f4a175a99 Merge pull request #2833 from matrix-org/mauroromito/notification_has_mention
feat (bindings): `has_mention` in `NotificationItem`
2023-11-09 11:39:33 +01:00
Mauro b553dbb31c Merge branch 'main' into mauroromito/notification_has_mention 2023-11-09 11:14:56 +01:00
Benjamin Bouvier 1abe039582 style: decrease indent in GroupSessionManager::mark_request_as_sent 2023-11-09 11:01:50 +01:00
Benjamin Bouvier 6c490b7aec crypto: inline GroupSessionCache::get_with_id into its single callsite 2023-11-09 11:01:50 +01:00
Benjamin Bouvier c17acd5fe3 crypto: remove direct usage of GroupSessionCache::sessions_being_shared outside the struct 2023-11-09 11:01:50 +01:00
Benjamin Bouvier 8c05d09e4d crypto: remove usage of GroupSessionCache::sessions fields in external users 2023-11-09 11:01:50 +01:00
Jonas Platte 72254caf08 sdk: Enable indexeddb in docsrs feature
… so `ClientBuilder::indexeddb_store` is visible on docs.rs.
2023-11-09 09:25:39 +01:00
Mauro Romito b232cd37e8 implement has_mentions 2023-11-08 17:53:06 +01:00
Jonas Platte 6baf092bc8 sdk: Exclude query parameters from logging
Unfortunately there are a few requests like
check_registration_token_validity that include secrets in the query
parameters.
2023-11-08 10:58:42 +01:00
Jonas Platte c109119b35 sdk: Clean up http_client logging
- Log URI instead of separate homeserver, path
- Always log query parameters (not just for sliding sync)
- Only log request size for requests that could have a body based on the
  HTTP verb
2023-11-08 09:33:39 +01:00
Benjamin Bouvier 8bce5e2416 oidc: add custom hex display to SessionHash
The most important thing is that it's stable and doesn't miss any byte.
2023-11-07 16:44:27 +01:00
Benjamin Bouvier a03b29ac70 oidc(style): avoid qualifying module name when not needed 2023-11-07 16:44:27 +01:00
Benjamin Bouvier c7f7941734 oidc: use hex logging for the hashed oidc tokens 2023-11-07 16:44:27 +01:00
Kévin Commaille 8895ce40d1 Add test for PaginationOptions::until_num_items
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-11-07 12:36:01 +01:00
Kévin Commaille edf32e8941 Store back-pagination tokens in same order as timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-11-07 12:36:01 +01:00
Kévin Commaille 73ddd34cb1 Make several requests if the back-pagination token is not updated
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-11-07 12:36:01 +01:00
Kévin Commaille 0916c93641 ui: Update back-pagination token with the first or last event added
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-11-07 12:36:01 +01:00
Kévin Commaille 8a65e32e7e ui: Update back-pagination token even if chunk is empty or event fails to deserialize
Otherwise back-pagination goes in a loop because the token is never correct

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-11-07 12:36:01 +01:00
Jonas Platte 91c4bc0b3e Upgrade tracing-opentelemetry 2023-11-06 18:41:48 +01:00
Jonas Platte 6f710063b5 Upgrade mas-oidc-client 2023-11-06 18:41:48 +01:00
Jonas Platte e788a6b099 ffi: Simplify Drop implementation for Client 2023-11-06 16:16:40 +01:00
Jonas Platte 8c1baf6ba8 crypto-ffi: Simplify ManuallyDrop usage 2023-11-06 16:16:40 +01:00
Damir Jelić 99032511aa Order the changelog, new entries at the top 2023-11-06 15:17:39 +01:00
Damir Jelić 645bbd67df Remove a unused error type 2023-11-06 14:19:12 +01:00
Damir Jelić 26ede608b0 Add a method which checks if a backup decryption key matches a backup info 2023-11-06 14:19:12 +01:00
Damir Jelić 554aa0404a Add a higher level method to decrypt backed up room keys 2023-11-06 14:19:12 +01:00
Damir Jelić 3438e7de9b Add a higher level method to sign backup versions (#2819) 2023-11-06 12:50:51 +00:00
Damir Jelić 44bb9a3d8f Add a method to create an ExportedRoomKey from a BackedUpRoomKey 2023-11-06 13:41:57 +01:00
Damir Jelić bc5b190509 Add a method to get the RoomKeyBackupInfo to the BackupDecryptionKey 2023-11-06 12:41:22 +01:00
Damir Jelić 2e20f00d99 Add an example for the secret storage support 2023-11-06 10:41:44 +01:00
Damir Jelić 760053b15d Add a test for the secret storage support in the main crate 2023-11-06 10:41:44 +01:00
Damir Jelić e599fa1ccf Add secret storage support to the main SDK crate 2023-11-06 10:41:44 +01:00
Jonas Platte c7fbfd4db8 ffi: Add MediaFileHandle::persist 2023-11-06 10:32:11 +01:00
Jonas Platte ad392a1977 sdk: Add MediaFileHandle::persist 2023-11-06 10:32:11 +01:00
Jonas Platte 57136247bf ffi: Add use_cache parameter to get_media_file 2023-11-06 10:32:11 +01:00
Damir Jelić e5b06bd6d8 Enable backups in the crypto crate by default 2023-11-03 19:17:10 +01:00
Damir Jelić beb01eacfa fixup! Use the better Signatures type in the MegolmV1BackupKey type 2023-11-03 17:01:47 +01:00
Damir Jelić 1e9fab1e4e Use the better Signatures type in the MegolmV1BackupKey type 2023-11-03 17:01:47 +01:00
Benjamin Bouvier 1be7fab4fd ffi: have the (ffi) NotificationClient keep the (ffi) Client alive
Otherwise, it's possible for the `NotificationClient` to be destroyed *after* the ffi `Client`, and then the hack introduced in the previous commit won't work.
2023-11-03 16:54:54 +01:00
Benjamin Bouvier ad5761bfb5 fix(ffi): don't leak Client instances
A detached task was spawned to react upon session changes, and that task captured a clone of the current `Client`.
This caused a leak of the `Client`, because that task would never get aborted, and would not stop by itself.
The fix here consists in having `Client::set_delegate` return a task handle that needs to be stashed by the FFI
users, and cancelled when the Client gets out of scope. This fixes the leak, by removing the last reference onto
the Client.

Then, when dropping the Client, we have to drop the Stores in it. These stores may be sqlite-based stores, which
make use of deadpool. Deadpool has a sync wrapper that will call `block_on` in a `drop` method, and as such it
requires to be in the scope of a tokio runtime to run properly. To avoid breaking all abstractions and giving
access to the inners of the `Client`, the hack used here to properly be in a runtime when dropping the stores is
to replace the inner sdk `Client` in the FFI `Client::drop` method (and replace it with a dummy client that is
minimally configured and will use in-memory stores).
2023-11-03 16:54:54 +01:00
Damir Jelić efb72063ac Add a backup specific method to import room keys 2023-11-03 15:34:11 +01:00
Jonas Platte 9ef6103912 Insert strategic Box::pin to reduce async stack size 2023-11-03 12:23:59 +01:00
Jonas Platte 71c6b98d6a crypto: Box inner field of Account
This reduces its stack size to less than a third of what it previously
was and thus helps with async fn stack size problems.
2023-11-03 12:23:59 +01:00
Jonas Platte dc86835ae2 base: Box large RoomInfo fields
RoomInfo is often passed around by value, including in futures where
holding types with a large stack size is especially problematic¹.
It might make sense to move the actual data of (Base)RoomInfo into
an inner struct that is always held inside a Box or Arc, but this change
should have most of the benefits of that while being a bit simpler.

¹ https://github.com/rust-lang/rust/issues/69826
2023-11-03 12:23:59 +01:00
Benjamin Bouvier ab4c524212 crypto(perf): don't hold the cache lock while waiting on a user key query (#2806)
* crypto(fix): don't hold the cache lock while waiting on a user key query

Fixes #2802. The lock was only useful to sync the database and the in-memory cache for the users awaiting a key query request.
So it's possible to slightly tweak the API by moving the method from `SyncedKeyQueryManager` to non-synced `KeyQueryManager`, and require a
`StoreCacheGuard` (i.e. the owned lock, so we can manually drop it when we feel like so).

I've looked at all the other methods, and they do require the cache for writing into it and the store.
At the limit we could also move `SyncedKeyQueryManager::users_for_key_query`
into `KeyQueryManager`, but the lock in there is hold for a very short-time, so it shouldn't be an issue.

* Add test for the key query deadlock while waiting for the response.

* Update crates/matrix-sdk-crypto/src/machine.rs

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2023-11-03 11:36:54 +01:00
Richard van der Hoff c2f422209f Review comment: process failed devices together 2023-11-03 10:43:26 +01:00
Richard van der Hoff d90c623375 Add a test for devices with no key map 2023-11-03 10:43:26 +01:00
Richard van der Hoff abd6779210 Inline OlmMachine::receive_keys_claim_response
it's a bit pointless.
2023-11-03 10:43:26 +01:00
Richard van der Hoff d48c27dc86 Remove redundant key_id arg on create_session test helper 2023-11-03 10:43:26 +01:00
Richard van der Hoff 303417eae2 Factor out SessionManager::create_sessions
... and use it in some tests.

Simplify some of the test code by not building a whole keys/claim response.
2023-11-03 10:43:26 +01:00
Richard van der Hoff 017d72e80f Hoist check for missing OTKs to SessionManager
`Account::create_outbound_session` no longer takes an entire list of keys;
rather it takes a single key and it is up to the caller to pick a key out of
the list.

This in turn means that `SessionCreationError` loses one of its reason codes.
2023-11-03 10:43:26 +01:00
Timo d7f6231acd Add perParticipantE2EE to element call url. (#2807)
* Add `perParticipantE2EE` to element call url
* add ffi
* nightly fmt
* refactor to use enum + test
* rename to PerParticipantKeys
* cleanup (spelling + formatting)

Signed-off-by: Timo K <toger5@hotmail.de>
2023-11-03 10:42:50 +01:00
Marco Romano 6a27fc2e04 Upgrade uniffi
This will include https://github.com/mozilla/uniffi-rs/pull/1781
Which fixes https://github.com/mozilla/uniffi-rs/issues/1760
2023-11-03 10:19:20 +01:00
Jonas Platte 3481cde1dc Fix unquoted strings in tracing fields 2023-11-02 17:46:38 +01:00
Jonas Platte d821d611ba sdk: Clean up logging in sliding_sync
- Don't include pos in event data, it's available in a parent span
- Remove superfluous backtick
- Rewrap an `info!` invocation
2023-11-02 17:46:38 +01:00
Jonas Platte 4485abbfdf Replace all two uses of async-std with equivalent tokio functionality 2023-11-02 17:21:48 +01:00
Jonas Platte 2d19c7ad65 crypto: Use Option::map in UsersForKeyQuery::maybe_register_waiting_task 2023-11-02 17:21:48 +01:00
Jonas Platte 1692460b30 Simplify dependency specifications for tokio
matrix-sdk-common and matrix-sdk-crypto were repeating things that would
be inherited from the workspace dependency specification anyways.
2023-11-02 17:21:48 +01:00
Benjamin Bouvier 250d63c6da fix: change the event_type after encrypting
The event_type passed to `encrypt_room_event_raw` must be the one of the cleartext event, not `m.room.encrypted`. The returned event has the expected type.
2023-11-02 16:56:50 +01:00
Jonas Platte 0a33642851 widget: Change content to RawValue representation 2023-11-02 16:56:50 +01:00
Jonas Platte 64c9fa5542 sdk: Allow different raw JSON types for send_raw, send_state_event_raw 2023-11-02 16:56:50 +01:00
Jonas Platte d042bcce04 crypto: Optimize OutboundGroupSession::encrypt 2023-11-02 16:56:50 +01:00
Jonas Platte 7d52322687 crypto: Update raw encryption methods to take &Raw content 2023-11-02 16:56:50 +01:00
Jonas Platte b797635255 crypto: Restrict visibility of internal types
This makes it more obvious that breaking changes to these types don't
break the public API.
2023-11-02 16:56:50 +01:00
Jonas Platte d9845c1658 crypto: Put event type before content for raw encryption methods 2023-11-02 16:56:50 +01:00
Daniel Abramov 4428b525ea widget: Implement limits for requests 2023-11-02 14:56:51 +00:00
Jonas Platte b67ca2c123 ci: Increase log level for coverage job 2023-11-02 12:58:03 +01:00
Jonas Platte 7be84ca71a test: Deduplicate tracing_subscriber initialization
… and set a sensible default log level.
2023-11-02 12:58:03 +01:00
Jonas Platte 9956b56a2c test: Remove unused helpers feature from integration testing crate 2023-11-02 12:58:03 +01:00
Jonas Platte afcc7022a2 Exclude remaining Debug impls from coverage reporting 2023-11-02 12:58:03 +01:00
Benjamin Bouvier 8de33f68f3 integration tests: randomize user names better
In the previous situation, running the tests with `cargo test` would sometimes fail because despite appending the number of milliseconds since
the start of epoch to the user names, some user names would clash across different tests, leading to unexpected results. This fixes it by using
an actual RNG in there, so the names don't ever clash.
2023-11-01 07:57:46 +01:00
Damir Jelić 2efb09907b Add a minimal integration test that sends a message in an encrypted room (#2799) 2023-10-31 19:45:18 +01:00
Jonas Platte 91e7f2f722 sdk: Add changes to send-event API to changelog 2023-10-31 12:46:10 +01:00
Kévin Commaille 7e1eaddf5d Bump tracing in cargo manifest
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-31 11:18:44 +00:00
Jonas Platte 61eb9cea8c sdk: Improve documentation of send, send_raw 2023-10-31 11:13:25 +01:00
Jonas Platte a00c0c1c02 ffi: Fix outdated / misplaced comment 2023-10-31 11:13:25 +01:00
Jonas Platte 3fc1b3adb9 sdk: Update argument order for send_state_event_raw 2023-10-31 11:13:25 +01:00
Jonas Platte 1609a73e99 sdk: Update argument order for send_raw 2023-10-31 11:13:25 +01:00
Jonas Platte 8f108d4064 sdk: Fix tracing span field "encrypted" in send_raw 2023-10-31 11:13:25 +01:00
Jonas Platte 463a02a4ef sdk: Make transaction_id truly optional for send and send_raw
… by removing the parameter and returning a named future with a
builder-style `with_transaction_id` method.
2023-10-31 11:13:25 +01:00
Jonas Platte 8a1506206b sdk: Clean up logging in send_raw 2023-10-31 11:13:25 +01:00
Jonas Platte 4b702da8e8 Make IntoFuture implementations a little easier to read and write 2023-10-31 11:13:25 +01:00
Jonas Platte 18b714116e sdk: Stop re-exporting named futures in regular modules
Instead make futures modules part of the API. It is extremely uncommon
to actually refer to a type that implements `Future` by its name / path,
so it's better if these don't show up in documentation pages that are
already large and somewhat cluttered.
2023-10-31 11:13:25 +01:00
Benjamin Bouvier 380735ab46 crypto: put the KeyQueryManager in the IdentityManager 2023-10-31 10:42:14 +01:00
Benjamin Bouvier 4158d00fac crypto: rename KeyQueryManager::tracked_user_loading_lock to loaded_tracked_users 2023-10-31 10:42:14 +01:00
Benjamin Bouvier 56aff649c5 crypto: introduce a KeyQueryManager 2023-10-31 10:42:14 +01:00
Benjamin Bouvier f945a50d22 Update crates/matrix-sdk-ui/src/timeline/mod.rs 2023-10-30 16:37:03 +01:00
Kévin Commaille 901518d745 Merge compare_receipts and pub_or_priv_receipt into a more generic method
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-30 16:37:03 +01:00
Kévin Commaille 1fe4bff05c Improve docs
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-30 16:37:03 +01:00
Kévin Commaille 3690bdd6a1 ui: Add regression test for clearing read receipts
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-30 16:37:03 +01:00
Kévin Commaille 70eb400d11 ui: Add method to know the position in the timeline of a user read receipt
Even if the event it applies to is not visible

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-30 16:37:03 +01:00
Kévin Commaille 1c602a8919 ui: Clear all read receipts maps
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-30 16:37:03 +01:00
Benjamin Bouvier e4ec8f03eb crypto: remove useless fallibility of StoreTransaction::new 2023-10-30 16:08:06 +01:00
Benjamin Bouvier 597cff5d9d crypto: make it impossible to have two Accounts alive at the same time 2023-10-30 16:08:06 +01:00
Daniel Abramov 7dde4ec1e8 widget: Add reading of message-like events 2023-10-30 14:41:21 +01:00
Daniel Abramov 0f420a61dc widget: Add tests for non-allowed matrix requests 2023-10-30 14:41:21 +01:00
Benjamin Bouvier 9d5e7c59f3 Fix tracing timer API so it works with updated tracing 2023-10-30 14:34:56 +01:00
Benjamin Bouvier 1f534821f6 Bump tracing 2023-10-30 14:34:56 +01:00
Jonas Platte 245c102169 examples: Add required clap feature for example-timeline 2023-10-30 12:26:34 +01:00
Benjamin Bouvier 1da785e6cb fix(crypto): upload device keys *before* sending the keys signature during XSigning bootstrapping
There was a bug previously, that the cross-signing bootstrapping could include a signature for a device key that hadn't been uploaded yet.
This fixes it by returning a third (!) request in `bootstrap_cross_signing`, that must be sent as the second in order, and will upload
keys, if required.

Also tweaks documentation. Fixes #2749.
2023-10-27 16:22:24 +02:00
Benjamin Bouvier f917b32407 crypto: remove useless async in a few functions 2023-10-27 16:22:24 +02:00
Benjamin Bouvier 631ab26d8b Rename some variables in crypto related to cross-signing bootstrapping 2023-10-27 16:22:24 +02:00
Benjamin Bouvier 0f442b4c83 crypto: don't use a transaction when it can be avoided
The transaction is useless since the account is used in read-only mode here.
2023-10-27 16:22:24 +02:00
Richard van der Hoff 0c333ed335 Refactor olm message decryption logic (#2751)
The driver for this is really to make sure that we log a warning whenever there is an error, but tbh IMHO the result is somewhat easier to understand.
2023-10-27 12:57:18 +01:00
Jonas Platte 28c4f2dc14 base: Inline MemoryStore inherent methods into StateStore impl block
They were not used anywhere else and had no reason to exist as inherent
methods.
2023-10-27 13:53:26 +02:00
Jonas Platte 686fc99ebd sdk: Replace dashmap usage by std types 2023-10-27 13:53:26 +02:00
Jonas Platte 113bdbd835 base: Replace dashmap usage by std types 2023-10-27 13:53:26 +02:00
Benjamin Bouvier 1d90dd554c Test some verification getters in the heavyweight verification integration test 2023-10-27 13:03:20 +02:00
Jonas Platte 05a1021724 Use assert_let! instead of assert_matches! with bindings 2023-10-26 17:29:29 +02:00
Jonas Platte 23571d0257 ui: Replace qualified path with use 2023-10-26 17:29:29 +02:00
Benjamin Bouvier c533297efd test: move the mocked endpoints into their own functions
Code-motion only.
2023-10-26 17:10:57 +02:00
Benjamin Bouvier 870faa48d1 tests: add mutual verification test 2023-10-26 15:12:34 +02:00
Jonas Platte a515bc8f03 ffi: Remove tokio::Runtime::block_on usage in async fn 2023-10-25 16:16:58 +02:00
Jonas Platte bc81cc317f ui: Log event type when an event fails to deserialize 2023-10-25 15:15:09 +02:00
Stefan Ceriu 570ef38de3 Remove unused anyhow import 2023-10-24 17:00:08 +02:00
Benjamin Bouvier 468337f026 Update bindings/matrix-sdk-ffi/src/session_verification.rs 2023-10-24 17:00:08 +02:00
Stefan Ceriu 040d095a04 Change the is_verified flag source to device.is_cross_signed_by_owner as theoretically the previous implementation was wrong 2023-10-24 17:00:08 +02:00
Stefan Ceriu fa90269e7e Fixes vector-im/element-x-ios/issues/1868 - Incorrect is_verified flag after successfully running verification flow
- the inner user_identity isn't automatically updated when the flow finishes, needs to be fetched again from encryption
2023-10-24 17:00:08 +02:00
Benjamin Bouvier 93edf7a064 tests: add test for cross-signing bootstrapping and unchecked self-verification 2023-10-24 15:20:15 +02:00
Jonas Platte 79065edabf ui: Test next_event_limit for different pagination strategies 2023-10-24 14:04:07 +02:00
Jonas Platte cd1e3928ad ui: Exclude another Debug impl from coverage reporting 2023-10-24 14:04:07 +02:00
Jonas Platte 61335af40d widget: Add a test for receiving live events 2023-10-24 12:58:39 +02:00
Jonas Platte a0128a94ef base: Log when the same sync response is received twice 2023-10-24 12:58:39 +02:00
Damir Jelić 95ced18edd Implement Default for the CrossSigningKeyExport
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-10-24 11:23:45 +02:00
Damir Jelić cd310d52d4 Add a convenience method to check if we have all cross-signing keys 2023-10-24 11:23:45 +02:00
Damir Jelić dc92ce8b40 Add a convenience method to get your own device out of the store 2023-10-24 11:23:45 +02:00
Daniel Abramov b0aa0ec5de widget: Add unit test to cover possible "deadlock" 2023-10-23 22:31:56 +02:00
Daniel Abramov d81d2bf01a widget: Let machine's process() return Action 2023-10-23 22:31:56 +02:00
Richard van der Hoff 7d2d1a53bf Exclude Store from tracing
Debug output for the `Store` is extremely verbose, so we don't want to log it
every time we touch this function.
2023-10-23 19:50:25 +02:00
Benjamin Bouvier 0107bcfd0d cross-signing bootstrapping: test that failure in bootstrapping doesn't block login 2023-10-23 19:38:30 +02:00
Benjamin Bouvier e1feefcbb0 chore: make clippy happy 2023-10-23 19:38:30 +02:00
Benjamin Bouvier 456472af6c tests: for cross-signing bootstrapping 2023-10-23 19:38:30 +02:00
Benjamin Bouvier 536d1ab527 feat: allow cross-signing bootstrapping in OIDC too 2023-10-23 19:38:30 +02:00
Benjamin Bouvier 0754c75436 client builder: add a method to set encryption settings 2023-10-23 19:38:30 +02:00
Benjamin Bouvier 1c0c9b8ab3 encryption: prefix a few test case names with test_ 2023-10-23 19:38:30 +02:00
Benjamin Bouvier 11f4b54394 encryption: add documentation for the new methods 2023-10-23 19:38:30 +02:00
Damir Jelić 80bbd77f3b feat: allow automatically enabling cross-signing on login 2023-10-23 19:38:30 +02:00
Jonas Platte 6f992d1ad8 ui: Add a test for updating member profiles 2023-10-23 19:34:23 +02:00
Jonas Platte 1ce67cc9e6 test: Use DEFAULT_TEST_ROOM_ID in more places 2023-10-23 19:34:23 +02:00
Jonas Platte 254efed150 test: Rename DEFAULT_SYNC_ROOM_ID to DEFAULT_TEST_ROOM_ID
… and move to matrix-sdk-test's crate root.
2023-10-23 19:34:23 +02:00
Valere f43eb94a8c Better documentation for share_room_key (#2741)
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-10-23 18:37:56 +02:00
Damir Jelić 9ccc36ccc8 Add more tests for the secret storage support in the crypto crate 2023-10-23 18:35:54 +02:00
Benjamin Bouvier 17dead5641 read receipts: avoid allocating an indexmap consumed as an iterator thereafter 2023-10-23 17:51:10 +02:00
Benjamin Bouvier 3ea9b8ed53 Apply suggestions from code review 2023-10-23 17:26:11 +02:00
Kévin Commaille a07062a990 Use std::cmp::Ordering
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-23 17:26:11 +02:00
Kévin Commaille 7b2a502e7d ui: Add tests for initial user read receipt
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-23 17:26:11 +02:00
Kévin Commaille 177f15b2e5 ui: Allow to get latest user read receipt for any room data provider
Allows to test the method with unit test

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-23 17:26:11 +02:00
Kévin Commaille 3bd10a05c1 Add a test for receipt comparison
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-23 17:26:11 +02:00
Kévin Commaille ff83f5abcb ui: Handle read receipts in the main thread
Improves the compatibility with clients using threads

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-23 17:26:11 +02:00
Kévin Commaille ddb4bf13b1 ui: Add user_receipt method on RoomDataProvider
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-23 17:26:11 +02:00
Stefan Ceriu 0006f85103 Make reldbg inherit dbg and contain debug symbols 2023-10-23 15:31:22 +02:00
Timo 4933a50496 Add active calls to RoomInfo 2023-10-23 15:05:12 +02:00
Benjamin Bouvier a052f26748 Bump synapse image version in integration testing 2023-10-23 14:56:11 +02:00
Benjamin Bouvier b9b4e4e1e0 test: bump the sliding-sync image versions 2023-10-23 13:55:42 +02:00
Benjamin Bouvier 55257f2b8d test: remove uninteresting smoke test for sliding sync in integration suite 2023-10-23 13:55:42 +02:00
Benjamin Bouvier 6368c699c2 test: Merge the two integration test suites into a single one 2023-10-23 13:55:42 +02:00
Damir Jelić 7440ce0a0c Use the GlobalAccountDataEventType instead of a string for the event type 2023-10-23 10:24:14 +02:00
Damir Jelić fda24d312b Re-export the MacError type of the secret storage module 2023-10-23 10:24:14 +02:00
Richard van der Hoff 21a4e7d1b2 Clean up to-device message logging (#2747) 2023-10-20 17:54:27 +00:00
Richard van der Hoff ed6f658405 Fix spurious "unknown secret request" warning (#2755) 2023-10-20 18:37:17 +01:00
Daniel Abramov 4ea8ecaac8 widget: Add missing unit tests for error cases 2023-10-20 17:52:10 +02:00
Benjamin Bouvier 71627a29a6 style: use not().then() in one place 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 2f90f9d55d account: make it more obvious what Account::clone_internal is, so it can't be misused 2023-10-20 17:04:40 +02:00
Benjamin Bouvier eb5bf4d51f store cache: copy the account back into the cache if there were pending changes to it 2023-10-20 17:04:40 +02:00
Benjamin Bouvier fc35d86a69 test: use unwrap() instead of Result in a test 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 08450da5e1 crypto: move Store::mark_tracked_users_as_up_to_date to the StoreCache 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 9ecc6ddd1e crypto: move Store::tracked_users to StoreCache 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 71229dd98b crypto: remove useless parameter in receive_device_changes 2023-10-20 17:04:40 +02:00
Benjamin Bouvier a2702e6d98 crypto: move Store::update_tracked_users to the StoreCache 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 0feccc7fee crypto: remove useless call to self.cache in Store::users_for_key_query
The store cache can be filled lazily when it's actually needed. It's not needed in this
function here, and may be needed in another function the caller of this function may call
later. No need to preemptively fill the cache here.
2023-10-20 17:04:40 +02:00
Benjamin Bouvier f580966408 crypto: move Store::mark_user_as_changed to the StoreCache too 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 537ac8a269 crypto: fix test failure 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 65f4cc151c crypto: move Store::mark_tracked_users_as_changed to StoreCache 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 7c51950167 crypto: move Store::ensure_sync_tracked_users to the StoreCache 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 3030bcbf1e crypto: introduce a RwLock on the StoreCache 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 3d7a56e468 crypto: remove inner mutable shared state from Account 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 8bfcd20801 crypto: make Account not clonable and the Account in the cache optional 2023-10-20 17:04:40 +02:00
Benjamin Bouvier 3570519c0c crypto: make StoreCache::account fallible and async 2023-10-20 17:04:40 +02:00
Benjamin Bouvier a82964ac75 crypto: get rid of test-only OlmMachine::account 2023-10-20 17:04:40 +02:00
Benjamin Bouvier be96ddb24a crypto: introduce StoreCache::account() function 2023-10-20 17:04:40 +02:00
Jonas Platte 6d0ed67679 widget: Rename remaining "permissions" to capabilities
… a few uppercase Permissions were missed last time.
2023-10-20 13:28:53 +02:00
Jonas Platte 3c74809374 widget: Attach room ID to events from sync 2023-10-20 13:00:43 +02:00
Jonas Platte fc6549213b widget: Filter incoming matrix events 2023-10-20 13:00:43 +02:00
Jonas Platte f937e7d14a widget: Fix ResponseData type for notify requests 2023-10-20 13:00:43 +02:00
Daniel Abramov 9d8e5a0d08 widget: Add subscribe / unsubscribe event handling 2023-10-20 13:00:43 +02:00
Daniel Abramov 4900089669 widget: Remove obsolete allow(dead_code) 2023-10-20 13:00:43 +02:00
Jonas Platte a4fd054705 widget: Properly handle matrix driver request errors
Co-authored-by: Daniel Abramov <daniel.abramov@element.io>
2023-10-20 12:05:03 +02:00
Daniel Abramov 685c51b3af widget: Add OpenID request handling 2023-10-20 12:05:03 +02:00
Jonas Platte 70b8ac425f widget: Fix name, response fields of capabilities request 2023-10-20 09:56:36 +02:00
Jonas Platte 7582b4fda9 widget: Fix field name in supported-versions response 2023-10-20 09:56:36 +02:00
Jonas Platte a2d05ed002 widget: Remove unnecessary type wrapping
… and move some types around.
2023-10-20 09:56:36 +02:00
Jonas Platte 489d699cc5 widget: Remove unused Serialize implementation 2023-10-20 09:56:36 +02:00
Jonas Platte 561db87b64 widget: Add integration tests for sending events 2023-10-19 15:25:53 +02:00
Jonas Platte 4982f87c59 widget: Add support for send-event fromWidget requests
Co-authored-by: Daniel Abramov <daniel.abramov@element.io>
2023-10-19 15:25:53 +02:00
Jonas Platte 14cf923361 widget: Add tests for event reading requests 2023-10-19 13:01:57 +02:00
Jonas Platte 3ce7126d58 widget: Add support for read-state-event fromWidget requests
Co-authored-by: Daniel Abramov <daniel.abramov@element.io>
2023-10-19 13:01:57 +02:00
Jonas Platte 946976a561 widget: Add EventFilter::matches_state_event_with_any_state_key 2023-10-19 13:01:57 +02:00
Jonas Platte e58ee3bcf1 widget: Fix copy-paste comment error 2023-10-19 13:01:57 +02:00
Jonas Platte c0985942dd widget: Actually add request ID to process_from_widget_request span 2023-10-19 13:01:57 +02:00
Jonas Platte 3b4108e519 widget: Add Deserialize impl for StateKeySelector 2023-10-19 13:01:57 +02:00
dependabot[bot] 70524e2f5c build(deps): bump rustix from 0.37.24 to 0.37.25
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.37.24 to 0.37.25.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.37.24...v0.37.25)

---
updated-dependencies:
- dependency-name: rustix
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-19 11:58:24 +02:00
Jonas Platte d5bda8147f ffi: Remove _blocking functions
Except for full_room_blocking, which is apparently noticably faster.
They were only added as a workaround for a UniFFI bug that has now been
fixed.
2023-10-19 07:56:06 +02:00
Jonas Platte 02a0916bc2 widget: Rename "permissions" to "capabilities"
… to match the postMessage JSON API.
2023-10-18 18:17:31 +02:00
Jonas Platte 01ec91bda4 widget: Rename Capabilities to CapabilitiesState
… and move the None case into it to avoid having to wrap it in Option.
2023-10-18 18:17:31 +02:00
Jonas Platte 12db7516ef widget: Add get_supported_api_versions support
Co-authored-by: Timo K <timok@element.io>
2023-10-18 15:52:00 +00:00
Jonas Platte af71d831c6 Fix 'verifying' typos 2023-10-18 17:50:51 +02:00
Daniel Abramov b623c7c357 widget: Complete ContentLoaded implementation
And cover it with tests.
2023-10-18 16:44:03 +02:00
Mauro Romito 5f0e5c7407 added the with_mentions method 2023-10-18 15:42:14 +02:00
Jonas Platte 2c80307e53 widget: Add content_loaded initialization 2023-10-18 15:03:58 +02:00
Jonas Platte 1aef675a97 widget: Fix a small error in test code 2023-10-18 15:03:58 +02:00
Jonas Platte ea36eaa09a widget: Implement fromWidget response sending
… and send an error response when the request fails to deserialize.
2023-10-18 15:03:58 +02:00
Jonas Platte 9c71c2b733 widget: Rename process_message_from_widget to process_widget_message
… to make it clearer that it's not specifically about fromWidget messages.
2023-10-18 15:03:58 +02:00
Jonas Platte 46a8f4e841 widget: Clean up json! indentation in test 2023-10-18 15:03:58 +02:00
Daniel Abramov eb5f05d8c5 widget: Add missing driver requests 2023-10-18 14:44:46 +02:00
Jonas Platte 29fc3d0289 widget: Shorten tracing instrument args 2023-10-18 13:26:51 +02:00
Daniel Abramov 04fcc0bb87 widget: split parsing of common widget header 2023-10-18 13:26:51 +02:00
Daniel Abramov 77bae6f421 widget: add a note to the error handling 2023-10-18 13:26:51 +02:00
Daniel Abramov a99cb7c30f widget: move things around in function (chore)
So that most important functions (public interface) come first.
2023-10-18 13:26:51 +02:00
Daniel Abramov 6363cd5902 widget: extract capability negotiation into fn
We will need to re-use it when processing the `ContentLoaded` message
from a widget.
2023-10-18 13:26:51 +02:00
Jonas Platte 541c0ef559 widget: Add an integration test for immediate capability negotiation 2023-10-18 12:34:34 +02:00
Jonas Platte 65cc926612 widget: Add more tracing events 2023-10-18 12:34:34 +02:00
Jonas Platte c550fa80a7 widget: Coalesce matrix driver response messages into an enum 2023-10-18 12:34:34 +02:00
Jonas Platte 5113d6e161 widget: Don't alias ruma request type 2023-10-18 12:34:34 +02:00
Jonas Platte f910d10f6b widget: Rename Event -> IncomingMessage 2023-10-18 12:34:34 +02:00
Jonas Platte 29620144fe widget: Split up Machine::process and add more sanity checks 2023-10-18 12:34:34 +02:00
Daniel Abramov deff0a06f5 widget: Implement capability negotiation 2023-10-18 12:34:34 +02:00
Jonas Platte e038ced2c6 widget: Add toWidget & MatrixDriver response handling skeleton 2023-10-18 12:34:34 +02:00
Richard van der Hoff f75b2cd1d0 Documentation on /keys/query parsing functions (#2674)
These functions are a bit confusing, so I wrote some comments. I also factored out
`get_user_signing_key_from_response`, to reduce duplication and (IMHO) improve clarity.
2023-10-17 16:55:26 +01:00
Jonas Platte 7c4046e463 widget: Implement requesting of capabilities w/o init_on_content_load 2023-10-17 16:55:02 +02:00
Jonas Platte a4cc28f94a widget: Rename client module to machine 2023-10-17 16:55:02 +02:00
Jonas Platte de0543c2e2 widget: Rename settings#id to widget_id 2023-10-17 16:55:02 +02:00
Jonas Platte 4a1e4cd279 widget: Rename ClientApi to WidgetMachine 2023-10-17 16:55:02 +02:00
Jonas Platte a812f17ec4 widget: Clarify MatrixDriver's purpose 2023-10-17 16:55:02 +02:00
Jonas Platte 7c958498bf ui: Raise log level for prev_batch wait timeout
… since it can cause rather annoying problems with the SS proxy
if it happens.
2023-10-17 11:02:15 +02:00
Jonas Platte 06e3fc4235 widget: Add a failing (ignored) test for reading room messages 2023-10-17 10:54:51 +02:00
Jonas Platte 07951b88d3 widget: Separate reading of message and state events
… and use the state store for the latter.

Co-authored-by: Timo K <timok@element.io>
2023-10-17 10:54:51 +02:00
Jonas Platte 5775a6e628 widget: Group trait impls in client::outgoing 2023-10-17 10:54:51 +02:00
Jonas Platte 20021abee3 widget: Fix clippy warning 2023-10-17 10:54:51 +02:00
Jonas Platte b3f37459b7 widget: Reduce visibility on widget::matrix types and their methods 2023-10-17 10:54:51 +02:00
Jonas Platte 8496673310 sdk: Move WidgetSettings constructor to top of impl block 2023-10-17 10:54:51 +02:00
Richard van der Hoff 3c9f48dcb5 common: Add a tracing MakeWriter for writing to a JS Logger
Replace the old `tracing_subscriber::layer::Layer` with a `MakeWriter` which
can then be plugged into a `fmt::Subscriber`.
2023-10-16 20:10:41 +02:00
Jonas Platte 7f3fef5d8b ci: Run documentation CI workflow when un-drafting a PR 2023-10-16 15:44:20 +02:00
Timo 7ee872c4bd Fix avatar url and display name in element call link generation
Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-10-16 11:00:32 +02:00
Richard van der Hoff a433d51efc Add static lifetimes to some constants
My compiler is complaining about lack of explicit lifetimes on these consts
2023-10-13 13:59:56 +02:00
Benjamin Bouvier 41a26e30e9 oidc: use sha2 to hash everything oidc-related
Hashes computed by `compute_session_hash` may be stored in the crypto store, and may or may not
be encrypted; make them slightly more secure by using a more secure hash. Also use sha2 for
the logged hashes that are useful for debugging OIDC issues.
2023-10-13 11:06:08 +02:00
Benjamin Bouvier efb16ed5b4 oidc: remove logging of hashed token
This was useful during development of the OIDC feature, but now that it's rather stable,
let's remove it from the traces.
2023-10-13 11:06:08 +02:00
Jonas Platte 735b0d2d24 ffi: Allow MessageType to contain arbitrary msgtype values, plus body
… allows the FFI type MessageLikeEventContent to hold custom msgtypes,
which is useful for notification.
Also allows sending custom msgtypes, as long as no fields other than the
msgtype itself and body are needed.
2023-10-13 10:06:07 +02:00
Jonas Platte 51ee8209bd sdk: Use BTreeSet instead of HashSet in widget tests
… for deterministic / comparable debug formatting.
2023-10-12 18:39:47 +02:00
Jonas Platte bc0e3609d0 sdk: Rewrap strings in widget tests 2023-10-12 18:39:47 +02:00
Jonas Platte a6a4695dd4 ffi: Inline local variables in WidgetSettings conversion 2023-10-12 18:39:47 +02:00
Alfonso Grillo f826999773 feature: send voice message API (#2697)
This PR adds a ffi binding for sending voice messages in the legacy format (before extensible events). It also makes minor changes in the `matrix-sdk` crate to accomodate this change.

* Add send_voice_message api

* Update ruma-events dependency

* Fix attachment info mapping

* Remove unstable dependency in attachment.rs

* Bump ruma-events

* Fix matrix-sdk Cargo.toml

* Fix formatting issues

* Refactor Voice case

* Remove clone from AttachmentInfo

* Remove duplicate code

* Remove unused imports

* Fix formatting issue

* Rename update function
2023-10-12 16:34:09 +00:00
Jonas Platte ba2a5137dc ui: Fix missing thread relation when sending reply to threaded message 2023-10-12 16:02:34 +02:00
Alfonso Grillo eadc7b9052 feat: enable push rules when changing actions (#2708) 2023-10-12 14:41:12 +02:00
Daniel Abramov b98c4772e5 widget: Define outgoing request types
This includes the requests that are sent to the matrix client (i.e.
a request to send a matrix event) as well as requests that are sent to
the widget.

The difference between this and `Action` is that `Action` is rather
"low-level" (i.e. it has a generic `SendToWidget(String)` variant),
whereas this API is a high-level API that we will use internally to
conveniently issue and `await` for outgoing responses.
2023-10-12 12:20:13 +02:00
Kévin Commaille 10393eee8d ui: Require PaginationOptions strategy to be Sync
Otherwise PaginationOption is not Send.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-12 09:44:40 +00:00
Jonas Platte 4e86954008 Upgrade async-compat 2023-10-11 15:21:18 +02:00
Jonas Platte 4b98d24230 Upgrade UniFFI 2023-10-11 15:21:18 +02:00
Jonas Platte d54668305e ci: Run widget tests in coverage job
… the other experimental features were already getting enabled through
matrix-sdk-ui, so don't need to be enabled explicitly.
2023-10-11 15:13:08 +02:00
Daniel Abramov 9cea46c459 widget: add unit tests for Permissions 2023-10-11 15:13:08 +02:00
Daniel Abramov f0521f72d5 widget: add serialize/deserialize for permissions
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-10-11 15:13:08 +02:00
Benjamin Bouvier 77cb1b7f11 oidc: add cross-process lock test 2023-10-11 14:58:52 +02:00
Jonas Platte b8185c0c67 ui: Fix hidden lifetime warnings 2023-10-11 14:42:24 +02:00
Benjamin Bouvier 97844ea8af oidc: remove dead code 2023-10-11 14:18:55 +02:00
Benjamin Bouvier 51b6ecc0b8 oidc: add test for getters 2023-10-11 14:18:55 +02:00
Benjamin Bouvier 2ad567883c oidc: add test for session_token_stream 2023-10-11 14:18:55 +02:00
Benjamin Bouvier f74f2eda76 oidc: remove dead code
This code path could never be taken:

- the only way to set the cross_process_token_refresh_manager is from calling the same function
- this function is guarded against a lock, so it's not reentrant
- this function's only internally called, during `restore_session` or after a successful login:
both will set a session, hence those functions would fail beforehands if another session had
been set earlier.
2023-10-11 14:18:55 +02:00
Benjamin Bouvier 9e8c6e639b oidc: add comments and tarpaulin annotations 2023-10-11 14:18:55 +02:00
Kévin Commaille b14ac1f2b9 Add test for event visibility change
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille 818a1ba992 Log inconsistent state
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille d88437e707 Fix visibility of types
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille dae8c0a37f Update read receipt of prev event if visibility changed
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille d0f74a76d6 ui: Expose read receipts of hidden events on visible events
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille 54bbb05c22 ui: Rename receipt to new_receipt
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille 148c75120c ui: Move maybe_add_implicit_read_receipt as a method of TimelineInnerStateTransaction
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Kévin Commaille aca6210b6b ui: Keep track of read receipts on all events
Not only event items

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-11 12:00:09 +02:00
Benjamin Bouvier 1a56d6c0d8 fix: live-migrate LatestEvent data from the former format to the newer
#2587 introduced a breaking change in the serialized format of `RoomInfo`, changing the `event`
field format in particular, without a migration. As a result, this lead to users state stores
being invalidated for containing incorrect data, and thus being logged out.

This mitigates the issue by making sure that the LatestEvent type is either deserialized as its
newer format (aka `SerializedLatestEvent`) or its older format (aka `SyncTimelineEvent`). This
way, we maintain compatibility with the previous format. We always serialize to the new one, so
we'd only run this migration once.
2023-10-11 09:08:12 +00:00
Daniel Abramov 3567c9dc65 widget: move client into own module and split up 2023-10-11 09:50:58 +02:00
Daniel Abramov d8d136b330 widget: change signature of the ClientApi
Return `Self` and the channel to process incoming actions.
2023-10-11 09:50:58 +02:00
Daniel Abramov 5b92b0ac37 widget: move client into its own module 2023-10-11 09:50:58 +02:00
Damir Jelić c2bb76029a Rename the encrypt_with_iv method so it's clear that it also can decrypt 2023-10-10 18:15:45 +02:00
Damir Jelić 372e0d3d98 Secret storage support
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-10-10 18:15:45 +02:00
Jonas Platte 194c448047 ui: Update send_reply arguments
- `content` is now of type `RoomMessageEventContentWithoutRelation`,
  the relation was previously always overwritten if set
- `add_mentions` is now inferred from `content.mentions`
2023-10-10 17:14:55 +02:00
Richard van der Hoff 63fab7e292 Clean up duplicate/incomplete tracing 2023-10-10 14:28:06 +02:00
Richard van der Hoff 4e4077d6e0 Improve documentation on QrVerificationData (#2689)
I spent a while trying to figure out how all of this works.
2023-10-10 12:06:16 +00:00
Damir Jelić d62cf340c9 Pin reqwests to 0.11.20 2023-10-10 14:00:55 +02:00
Damir Jelić c1d24aea90 Upgrade the deps for the store-encryption and crypto-ffi crates 2023-10-10 14:00:55 +02:00
Damir Jelić 06bb81aaf2 fixup! Add a test ensuring that we didn't mess up our Device deserialization 2023-10-10 14:00:55 +02:00
Damir Jelić 235a8bd5ed Run cargo update for all the things 2023-10-10 14:00:55 +02:00
Damir Jelić 2fce44a16a Add a test ensuring that we didn't mess up our Device deserialization 2023-10-10 14:00:55 +02:00
Damir Jelić 97fe9614e5 Upgrade our pbkdf dependency 2023-10-10 14:00:55 +02:00
Damir Jelić cda0a5da13 Remove atomic from our deps 2023-10-10 14:00:55 +02:00
Jonas Platte 129a5e1acc ui: Wait for pagination token across multiple sync response notifs
… if wait_for_token flag is set for backwards-pagination.
2023-10-10 13:39:59 +02:00
Damir Jelić 04565378fa Only mark our own user identity as verified if it wasn't already 2023-10-10 13:04:09 +02:00
Damir Jelić 2843aef352 Ensure that the private cross-signing keys get persisted after invalidation 2023-10-10 13:04:09 +02:00
Damir Jelić 626df0b589 Test that the invalidated private cross-signing keys get correctly persisted 2023-10-10 13:04:09 +02:00
Damir Jelić 4918710cdc Add the ability to create a test IdentityManager with an arbitrary user ID 2023-10-10 13:04:09 +02:00
Kévin Commaille e674ccf5a4 Use timeline.items() instead of stream
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-10 12:05:57 +02:00
Kévin Commaille d25acdf237 Remove is_empty variable
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-10 12:05:57 +02:00
Kévin Commaille f7bf417996 ui: Test explicit read receipt ignored when implicit read receipt exists
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-10 12:05:57 +02:00
Kévin Commaille e778316918 ui: Do not add explicit receipts if implicit receipt is newer
Should avoid users receipts appearing on two different events in the timeline

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-10 12:05:57 +02:00
Kévin Commaille d03c255342 ui: Create ReadReceipts struct
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-10 12:05:57 +02:00
Jonas Platte a88afd818b ui: Add more tracing events around back-pagination tokens 2023-10-09 17:21:52 +02:00
Daniel Abramov 880e918a5e widget: Add missing license headers 2023-10-09 14:55:58 +00:00
Benjamin Bouvier c64d3b4b7a Introduce a store transaction for Account (#2660)
This adds a new `StoreTransaction` type, that wraps a `StoreCache` and a `Store`. The idea is that it will allow write access to the `Store` (and maintains the cache at the same time), while the `Store::cache` method will only give read-only access to the store's content.

Another new data type is introduced, `PendingChanges`, that reflects `Changes` but for fields that are properly maintained in the `StoreCache` and that one can write in the `StoreTransaction`. In the future, it wouldn't be possible to use `save_pending_changes` from the outside of a `StoreTransaction` context.

The layering is the following:

- `Store` wraps the `DynCryptoStore`, contains a reference to a `StoreCache`.
- When read-only access is sufficient, one can get a handle to the cache with `Store::cache()`.
- When a write happens, then one can create a `StoreTransaction` (later, only one at a time will be allowed, by putting the `StoreCache` behind a `RwLock`; this has been deferred to not make the PR grow too much).
- Any field in the `StoreCache` will get a method to get a reference to the cached thing: it will either load from the DB if not cached, or return the previously cached value. 
- Any field that can be written to will get a method to get a mutable reference in the `StoreTransaction`: it will either load from the cache into a `PendingChanges` scratch pad, or return the scratchpad temporary value.
- When a `StoreTransaction::commit()` happens, fields are backpropagated into the DB *and* the cache. 

Then, this `StoreTransaction` is used to update a `ReadOnlyAccount` in multiple places (and usage of `ReadOnlyAccount` is minimized so as not to require a transaction or cache function call as much as possible). With this, the read-only account only exists transiently, and it's only stored long-term in the cache.

Followup PRs include:

- making the `ReadOnlyAccount` not cloneable
- remove inner mutability from the `ReadOnlyAccount`
- add a `RwLock` on the `StoreTransaction`

Part of https://github.com/matrix-org/matrix-rust-sdk/issues/2624 + https://github.com/matrix-org/matrix-rust-sdk/issues/2000.

---

* crypto: Replace some uses of `ReadOnlyAccount` with `StaticAccountData` and identify tests

* crypto: introduce `StoreTransaction` to modify a `ReadOnlyAccount`

* crypto: introduce `save_pending_changes`, aka `save_changes` v2

* crypto: Start using `StoreTransaction`s to save the account, get rid of `Store::save_account` + `Account::save`

* crypto: use `StoreTransaction` to save an account in `keys_for_upload`

* crypto: use `StoreTransaction` and the cache in more places

* crypto: remove `Account` from the `Changes` \o/

* crypto: remove last (test-only) callers of `Store::account()`

* crypto: move `ReadOnlyAccount` inside the cache only

* crypto: use `ReadOnlyAccount` and `Account` in fewer places

whenever we can use `StaticAccountData` in place.

* crypto: make tests rely less on OlmMachine

* crypto: Don't put the `ReadOnlyAccount` behind a RwLock just yet

+ clippy
2023-10-09 14:16:06 +00:00
Kévin Commaille 41de52b6b0 ui: Reimplement compare_events_positions using all timeline events
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-09 12:13:03 +02:00
Kévin Commaille 155ec45a9e ui: Keep track of the order of all events in the Timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-10-09 12:13:03 +02:00
Ivan Enderlin 487f85b9e3 feat: Make latest_event faster regarding member profile
feat: Make `latest_event` faster regarding member profile
2023-10-09 11:41:32 +02:00
Ivan Enderlin 76ace82298 doc(ui): Fix a typo. 2023-10-09 11:22:43 +02:00
Ivan Enderlin a61bc77572 chore(base): Clean up. 2023-10-09 11:21:56 +02:00
Jonas Platte d216414608 ui: Make loop / continue comments less ambiguous 2023-10-09 11:16:03 +02:00
Jonas Platte 23390403b6 ui: Add more tracing to pagination 2023-10-09 11:16:03 +02:00
Jonas Platte d1ad16fbab ui: Document paginate_backwards_impl 2023-10-09 11:16:03 +02:00
Benjamin Bouvier 2a78b925e4 crypto: move all the Account methods in a single impl block 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 57b1442e1c crypto: rename ReadOnlyAccount to Account \o/ \o/ \o/ \o/ 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 1e9c05ad6f crypto: get rid of Account \o/ \o/ \o/ 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 05d65e9b60 crypto: move methods from Account to ReadOnlyAccount 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 850d25d8ec crypto: tweak a few code comments 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 0b818fe4a5 crypto: use a Store in the DehydratedDevice data structure as it's sufficient 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 03b4e87bd9 crypto: retrieve the StaticAccountData from the store in more places 2023-10-09 11:00:13 +02:00
Benjamin Bouvier d379d755e9 Fix: recreate a rehydrated OlmMachine with the correct DeviceId 2023-10-09 11:00:13 +02:00
Benjamin Bouvier 0013963ea5 crypto: retrieve the UserId/DeviceId from store methods instead of duplicating them 2023-10-09 11:00:13 +02:00
Daniel Abramov 0726955678 widget: minor fixes in formatting, typos, etc 2023-10-09 10:55:48 +02:00
Daniel Abramov 8e501c5d6b widget: rename widget_settings -> settings mod
To stay consistent with the rest of the concise naming "conventions"
within the `widget` module.
2023-10-09 10:55:48 +02:00
Ivan Enderlin 7842611ad9 test: Use the sync_timeline_event! macro once more. 2023-10-09 10:26:08 +02:00
Ivan Enderlin c5b137a83c test(ui): Write test for EventTimelineItem::from_latest_event with cached sender info. 2023-10-09 10:24:23 +02:00
Ivan Enderlin 438c51708d chore: Address feedbacks. 2023-10-09 09:52:29 +02:00
Damir Jelić 6c9cfe1368 Bump our vodozemac version 2023-10-06 16:19:03 +02:00
Jonas Platte d85ab43b81 crypto: Replace dashmap usage in the rest of the crate 2023-10-06 14:42:36 +02:00
Jonas Platte dfabef0036 crypto: Replace dashmap usage by std types in MemoryStore 2023-10-06 14:42:36 +02:00
Jonas Platte 131c3dbf30 crypto: Put both maps in WaitQueue behind one lock 2023-10-06 14:42:36 +02:00
Jonas Platte feba68779b Remove build as parent span of room_update_handler
… but record the relationship between them using follows_from.
2023-10-06 14:01:02 +02:00
Nicolas Mauri 108508e365 Fix: wait for disk operations to finish before returning the media file in get_media_file. (#2672)
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-10-06 09:57:48 +00:00
Jonas Platte b017e49d89 crypto: Detect and fix 'sign'-related typos 2023-10-06 11:38:32 +02:00
Jonas Platte a8158ae6bf crypto: Silence clippy false-positives
Upstream issue: https://github.com/rust-lang/rust-clippy/issues/11383
2023-10-06 10:55:17 +02:00
Jonas Platte a099c7c4a9 sdk: Replace str::to_string with to_owned 2023-10-06 10:55:17 +02:00
Timo 2120acabbb sdk: Add url creation to WidgetSettings
Signed-off-by: Timo K <toger5@hotmail.de>
2023-10-05 19:54:46 +02:00
Jonas Platte 7576a73fcb Upgrade Ruma to latest crates.io release 2023-10-05 17:46:34 +02:00
Benjamin Bouvier d8c2ad7693 ffi: use Timeline::send_single_receipt instead of Room::send_single_receipt for sending read receipts
The latter will always send a query, while the former will attempt to deduplicate sending a read receipt, if the event was already marked as read.
2023-10-05 16:59:28 +02:00
Benjamin Bouvier 1d01c32491 chore: remove unused FFI send_read_marker 2023-10-05 16:59:28 +02:00
Jonas Platte 2315c46a1d sdk: Remove sync gap broadcast channels
They were a stop-gap solution for detecting limited responses and have
been obsolete since the introduction of room update handlers.
2023-10-05 09:29:59 +02:00
Alfonso Grillo aa1b871d00 ffi: Refine NotificationSettingsError type 2023-10-04 15:58:44 +02:00
Jonas Platte 504861a532 sqlite: Upgrade deadpool, rusqlite 2023-10-04 15:43:08 +02:00
Jonas Platte d3902fe375 ci: Upgrade crate-ci/typos 2023-10-04 13:48:31 +02:00
Jonas Platte 749b4df321 ui: Move magic number to a named constant 2023-10-04 13:23:47 +02:00
Jonas Platte 7482246668 test: Test timeline reset while pagination is running 2023-10-04 13:23:47 +02:00
Jonas Platte 2bc0651c94 test: Test back-pagination request deduplication 2023-10-04 13:23:47 +02:00
Jonas Platte 7f934040bc test: Test wait_for_token functionality in back-pagination 2023-10-04 13:23:47 +02:00
Jonas Platte b9c05ca934 test: Move room messages test JSON to the only module that uses it 2023-10-04 13:23:47 +02:00
Jonas Platte 75d64e697e test: Remove unused constants from test_json::messages 2023-10-04 13:23:47 +02:00
Jonas Platte f62d561cb0 ui: Verify token before prepending events from back-pagination 2023-10-04 13:23:47 +02:00
Jonas Platte 6cfa383652 ui: Move BackPaginationStatus definition to pagination module 2023-10-04 13:23:47 +02:00
Jonas Platte 1ab305a9d8 ui: Store back-pagination tokens inside TimelineInnerMetadata 2023-10-04 13:23:47 +02:00
Jonas Platte 0dcfe4f4f5 ui: Fix a typo 2023-10-04 13:23:47 +02:00
Jonas Platte 03c70220a1 ui: Remove forwards pagination token
It's not currently used.
2023-10-04 13:23:47 +02:00
Benjamin Bouvier 0d592e4051 chore: make Client::homeserver not async by changing the underlying kind of mutex
The mutex used for the `homeserver` field is very short-lived, so use a std mutex instead, which
makes a few methods sync instead of async.
2023-10-03 14:25:48 +02:00
Alfonso Grillo 08b3c0e47e Feature: add API for setting underride push rule's actions (#2644) 2023-10-03 10:08:17 +02:00
Benjamin Bouvier 7e8827aec2 fix: make the crypto memory store write the next_batch_token only if provided
This matches the behaviors of the two other implementations.
2023-10-02 19:05:07 +02:00
Benjamin Bouvier 3fa79ce891 chore: make the crypto stores more robust by serializing save_changes()
Stores may race when performing writes, since in `save_changes` some data is pickled, and live across await points (it could be stale after an
await point). To prevent multiple threads racing when calling into `save_changes`, a new lock is introduced there.
2023-10-02 19:05:07 +02:00
Benjamin Bouvier 76c3f2a139 chore: remove a few spurious async on MemoryStore 2023-10-02 19:05:07 +02:00
Benjamin Bouvier 8d6f414375 chore: move CryptoStore::save_account to Store::save_account
as it can be implemented in terms of other methods already present in the `CryptoStore` trait.
2023-10-02 19:05:07 +02:00
Matthew Hodgson 9ddef138c1 feat: support creating emotes (#2648)
* support creating emotes

adds an emote param to message_event_content_from_markdown and
message_event_content_from_html so that clients can create
m.room.message events with msgtype emote (on the assumption
that the msgtype returned in the RoomMessageEventContentWithoutRelation
is immutable, and so can't be overridden by the client)

* lint

* switch to separate methods per review feedback
2023-10-02 18:48:33 +02:00
Benjamin Bouvier 7203ae9576 fix: use insecure OIDC whenever configuring with an http homeserver URL (#2652)
Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/2645.

The previous PR only enabled support for `server_name` homeserver configurations, this makes it work for `homeserver_url` too.
2023-10-02 10:27:30 +00:00
Ivan Enderlin 584db1d54c chore(base): Fix imports and features. 2023-10-02 10:45:08 +02:00
Ivan Enderlin 160f9233fa chore(sdk): Fix imports and features. 2023-10-02 10:44:50 +02:00
Ivan Enderlin ed759cae85 chore(ui): Replace EventTimelineItem with Self. 2023-10-02 10:11:17 +02:00
Ivan Enderlin 2f97301d5c chore(ui): Add homepage and license to Cargo.toml
chore(ui): Add `homepage` and `license` to `Cargo.toml`
2023-10-02 10:07:41 +02:00
Ivan Enderlin ba21e3bb02 feat(ui): Fallback to the slow path if profile is None. 2023-10-02 10:02:03 +02:00
Ivan Enderlin 0a119b55b3 fix(base): Fix migration helper for RoomInfo. 2023-10-02 10:01:48 +02:00
Ivan Enderlin 58998e4bbe feat(ui): Profile implements Default. 2023-10-02 09:49:56 +02:00
Ivan Enderlin 86ed582744 feat(ui): RoomDataProvider has profile_from_latest_event.
This patch renames `RoomDataProvider::profile`
to `::profile_from_user_id`. This patch also adds
`RoomDataProvider::profile_from_latest_event`.
2023-10-02 09:49:56 +02:00
Ivan Enderlin 5c55c2c51f feat(base): Rename LatestEvent::sender_profile to ::has_sender_profile. 2023-10-02 09:49:56 +02:00
Ivan Enderlin c0a3cc478d feat(base): LatestEvent has more methods.
This patch implements `LatestEvent::sender_display_name()`,
`::sender_name_ambiguous()` and `::sender_avatar_url()`.
2023-10-02 09:49:56 +02:00
Ivan Enderlin 83e7d7df11 feat(base): LatestEvent can hold a MinimalRoomMemberEvent.
This patch adds a `sender_profile: Option<MinimalRoomMemberEvent>`
field. Thus, `cache_latest_events` now receives an
`Option<&StateChanges>` and an `Option<&Store>`. The `StateChanges`
is used to read the most recent sender profile, otherwise the sender
profile will be fetch from the storage.
2023-10-02 09:49:56 +02:00
Ivan Enderlin f71a6fc738 feat(base): Latest event is represented by the new LatestEvent type.
This patch adds a new `LatestEvent` type. It wraps the
`SyncTimelineEvent` that was used before. The idea is to add more fields
onto this `LatestEvent` struct, but this patch starts easy by using
`LatestEvent` everywhere where it's required.
2023-10-02 09:49:56 +02:00
Ivan Enderlin 9027607347 doc(ui): Format doc. 2023-10-02 09:49:56 +02:00
Ivan Enderlin 84b1b741a3 feat(ui): all_rooms requires m.room.member: $LAZY.
This patch updates `all_rooms` to require the `m.room.member` state set
to `$LAZY`. That way, it's more likely to get the `m.room.member` event
associated to the latest event without needing to sync all the members.
2023-10-02 09:49:56 +02:00
Ivan Enderlin f7c008af3c chore(ui): Add repository and license to Cargo.toml. 2023-10-02 09:41:29 +02:00
kegsay 58e15f812d oidc: allow http scheme during discovery (#2642)
This is to enable entirely local stacks of Element X to work correctly. It's mostly seamless (no ffi changes) because it ties into `ClientBuilder.insecure_server_name_no_tls()`.

---------

Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-09-29 11:29:30 +00:00
Benjamin Bouvier 9cc9221808 notifications: match decryption errors more precisely when waiting for decryption in the background 2023-09-29 12:37:16 +02:00
Benjamin Bouvier e679182fb5 fix(notifications): don't hard-fail if decrypting failed
Before this commit, a call to get_notification would fail if decrypting failed on the first attempt, because `Room::decrypt_event` will hard-fail if the key wasn't found.
2023-09-29 12:37:16 +02:00
Benjamin Bouvier 787a85615c chore(notifications): tweak logs in notification client 2023-09-29 12:37:16 +02:00
Benjamin Bouvier 6a5a4db5fc fix(notifications): add a mutex to serialize e2ee encryption requests 2023-09-29 12:37:16 +02:00
Benjamin Bouvier 1cedd1097a chore(notifications): rename sliding_sync_mutex to notification_sync_mutex 2023-09-29 12:37:16 +02:00
Benjamin Bouvier 2677d16f2e chore: look ma i'm a 10x engineer ok 2023-09-29 12:25:52 +02:00
Benjamin Bouvier 1e5e13bb19 chore: make use of StaticAccountData in one extra location 2023-09-29 12:25:52 +02:00
Benjamin Bouvier 1eeee288b9 chore: move unsigned_device_keys to StaticAccountData too 2023-09-29 12:25:52 +02:00
Benjamin Bouvier e4fd8e7ac6 chore: move methods from ReadOnlyAccount to StaticAccountData 2023-09-29 12:25:52 +02:00
Valere ab2f18df3b Add new API to request missing secrets (#2641) 2023-09-29 12:12:34 +02:00
Benjamin Bouvier a1f6e2fb16 chore: clippy + remove spurious Arc 2023-09-28 17:21:53 +02:00
Benjamin Bouvier 8f541c9a09 chore: remove ReadOnlyAccount from the Account
And use the `self.store.account()` when we really need the `ReadOnlyAccount`. Also cache the immutable account data in this Account.
2023-09-28 17:21:53 +02:00
Benjamin Bouvier c01d2d990c chore: use StaticAccountData in more places
Sorry, this commit is a bit big. What happened is that I've pulled a thread: put a `StaticAccountData` there, look at caller; it seems to use only a
static account too, so keep up.

The only contender was the `OwnUserIdentity` data structure which really wants to sign things. Lucky for us, we could pass it a `ReadOnlyAccount`
from a store, in those cases, since we always had a `Store` hanging around; in the future it'll read it from the store cache, which is somewhat
identical.
2023-09-28 17:21:53 +02:00
Benjamin Bouvier 13be4b0dce chore: use a StaticAccountData in the Sas data structures 2023-09-28 17:21:53 +02:00
Benjamin Bouvier 650d99a875 chore: rename account_info/get_account_info to static_account/get_static_account 2023-09-28 17:21:53 +02:00
Benjamin Bouvier 1c311555ef chore: put the immutable parts of ReadOnlyAccount into its own data struct 2023-09-28 17:21:53 +02:00
Kévin Commaille f115bd0e25 base: Fix typo
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille 4595e2c064 indexeddb: Close DB less often during migrations
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille f3b8bdbe1e indexeddb: Migrate RoomInfo to new format
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille 23b34bfc2b indexeddb: Make sure each migration is discrete
We might need to rely on the data in the DB to already be corrected
before using it for another migration

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille d4f0f7a704 sqlite: Migrate RoomInfo to new format
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille 0856cf10fe base: Add migration helpers for converting serialized format of RoomInfo
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille cd4bc7a62c base: Return m.room.create event's content even if it is redacted
Starting with room version 11, all fields are kept when the event is redacted

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Kévin Commaille acfb999e76 base: Make BaseRoomInfo compatible with room version 11
By copying the sender field as the creator field of m.room.create's event content

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-28 16:54:03 +02:00
Benjamin Bouvier 79f408b511 feat: automatically reload the tracked users when getting the cache 2023-09-28 16:37:52 +02:00
Benjamin Bouvier c18ac12ce9 Apply suggestions from code review
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-09-28 16:37:52 +02:00
Benjamin Bouvier 216b3b9d77 feat: add a dummy StoreCacheGuard too, and make use of it 2023-09-28 16:37:52 +02:00
Benjamin Bouvier 00d6b2d2ae chore: rename Store::load_tracked_users to Store::ensure_sync_tracked_users 2023-09-28 16:37:52 +02:00
Benjamin Bouvier 2499d13839 chore: remove outdated code comment 2023-09-28 16:37:52 +02:00
Benjamin Bouvier 074bcca02e feat: introduce dummy crypto cache for the store 2023-09-28 16:37:52 +02:00
Benjamin Bouvier 851b3f2982 chore(crypto): simplify Store::load_tracked_users 2023-09-28 16:37:52 +02:00
Daniel Abramov 585508f461 sdk(widget): Add the matrix (i/o) part 2023-09-28 16:01:26 +02:00
Hubert Chathi 4478826a2f Fix a typo 2023-09-28 15:31:25 +02:00
Marco Romano 0158422dcd Bump ruma
- Bumps ruma to include https://github.com/ruma/ruma/pull/1665
- Enables ruma `compat-arbitrary-length-ids` flag instead of using the now deprecated `lax-id-validation`
2023-09-28 14:01:18 +02:00
Damir Jelić 1f695bf26e Move most of our locks in the Client into the ClientLocks struct 2023-09-28 13:06:09 +02:00
Damir Jelić e37cfe6036 Don't use a static for the mark_room_as_dm lock
Using a static lock would prevent two Client instances to call the
method at the same time.

We're going to assume that people won't have multiple Client instances
for the same user, in which case a static lock would have been helpful.

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-09-28 13:06:09 +02:00
Richard van der Hoff bcbb7c61f8 Enable the tests for encrypted indexeddb stores
Empirically, these seem to work for me, so let's re-enable them
2023-09-28 12:53:40 +02:00
Valere 4c432a66b4 Distinguish between changed and unchanged user identities (#2618) 2023-09-28 10:14:09 +02:00
Damir Jelić 24a203a126 Ensure that we can't try to mark two rooms as a DM at the same time 2023-09-27 16:24:57 +02:00
Jonas Platte cbb7b24cb5 Rewrite public widget API 2023-09-27 14:45:33 +02:00
Jonas Platte ae524b3fa6 ffi: Use FFI's tokio runtime explicitly for acquire_permissions 2023-09-27 13:13:27 +02:00
Richard van der Hoff 563072e7f8 Change the way we store gossip requests in indexeddb (#2626)
Instead of using three separate object stores, use a single one with some structured objects and indexes.

Fixes #2605 (or at least, should make whatever is going wrong much more obvious).

Consists of a series of commits which should be reviewable on their own.
2023-09-27 11:43:07 +01:00
Richard van der Hoff e3d9408d0a matrix-sdk-common: add js console tracing layer (#2620)
Implement a `tracing_subsciber` `Layer` which sends output to the javascript
console.

Obviously, this only works on the wasm32 target.

This is lifted from `matrix-rust-sdk-crypto-wasm`, so that we can use it in
tests etc for other crates.
2023-09-27 11:42:33 +01:00
Jonas Platte b35d40d111 test: Remove unused sync events from test_json 2023-09-27 10:06:32 +02:00
Jonas Platte 3196ac53b2 test: Remove TimelineTestEvent 2023-09-27 10:06:32 +02:00
Jonas Platte 145c5078f2 test: Remove example from SyncResponseBuilder docs
It is only an internal utility, we can copy-paste from other tests.
2023-09-27 10:06:32 +02:00
Jonas Platte 62ecff3e1d test: Remove outdated documentation 2023-09-27 10:06:32 +02:00
Richard van der Hoff fcd593b0bf Improve documentation on xtask ci {wasm,wasm-pack} 2023-09-26 21:30:40 +02:00
Richard van der Hoff 299256fe50 Fix IndexeddbCryptoStore::get_outgoing_secret_requests
Fix a bug which caused `get_outgoing_secret_requests` to return no data.

This is exposed as a public function, and when called that way it does *not*
expect the key to be escaped and encrypted.
2023-09-26 17:40:16 +02:00
Jonas Platte 956d5ef7e7 ffi: Update Room::edit to not make unnecessary network requests 2023-09-26 15:29:23 +02:00
Jonas Platte 2e27142336 ui: Add highlevel API for editing 2023-09-26 15:29:23 +02:00
Jonas Platte 9aa1dd725d test: Use EventBuilder for timeline edit integration test 2023-09-26 15:29:23 +02:00
Jonas Platte 6a69543f64 test: Move timeline edit integration test into new module 2023-09-26 15:29:23 +02:00
Jonas Platte 88194b6828 ui: Remove outdated documentation 2023-09-26 15:29:23 +02:00
Daniel Abramov a1d67206b6 sdk(widget): temporarily supress dead code warning 2023-09-26 13:19:38 +02:00
Daniel Abramov d017bab144 sdk(widget): add sans-io client api impl skeleton 2023-09-26 13:19:38 +02:00
Benjamin Bouvier 1180c6aef9 feat: add integration test for fetch_members causing UTDs 🧪 2023-09-26 12:33:41 +02:00
Benjamin Bouvier 43723c88ec feat: add unit tests 🧪 2023-09-26 12:33:41 +02:00
Benjamin Bouvier cb14813f84 chore: address review comments 2023-09-26 12:33:41 +02:00
Benjamin Bouvier e9362f75f2 chore: fix test that was affected by the issue
An encryption state request was failing, but before the patch, subsequent
requests would end up in success, while this wasn't the case. The new failure
introduced by this patch was a real one, because the encryption state was
not mocked as part of this test (which tries to send a message to a homeserver).
2023-09-26 12:33:41 +02:00
Benjamin Bouvier 502ecfa636 chore: get rid of the outer pinned box, weeeee 2023-09-26 12:33:41 +02:00
Benjamin Bouvier 928be57666 chore: polish DeduplicatedRequestHandler API 2023-09-26 12:33:41 +02:00
Benjamin Bouvier f5521e9e1c feat/fix: also correctly deduplicate preshare_room_key 2023-09-26 12:33:41 +02:00
Benjamin Bouvier 3aa5d12ab7 feat/fix: implement DeduplicatedRequestHandler + use it for encryption_state_request 2023-09-26 12:33:41 +02:00
Benjamin Bouvier e9d6351471 fix: also check the result of base::Client::receive_members 2023-09-26 12:33:41 +02:00
Benjamin Bouvier 120ac7150c reformat: no else after return 2023-09-26 12:33:41 +02:00
Benjamin Bouvier 2a235d8ea6 fix: signal that a concurrent request failed to the caller, instead of assuming it succeeded 2023-09-26 12:33:41 +02:00
Benjamin Bouvier a08327907c fix: don't cause that any /members request following a failed one result in immediate success 2023-09-26 12:33:41 +02:00
Jonas Platte a3799190d4 ui: Remove sender information from logs where it's not relevant 2023-09-26 11:26:25 +02:00
Jonas Platte e8528926be ui: Move debug-logging code out of main event handler logic 2023-09-26 11:26:25 +02:00
Alfonso Grillo b248aa9862 ffi: Add push notification support for unstable m.poll.start 2023-09-26 10:38:24 +02:00
Jonas Platte f47b7f02cc Use as_variant macro in more cases 2023-09-26 10:14:04 +02:00
Jonas Platte 6e15e34700 Use bool::then where applicable 2023-09-26 10:14:04 +02:00
Jonas Platte 1f08e22d0d crypto: Separate module declarations and reexports from imports 2023-09-26 10:14:04 +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 753793c451 ui: Add a test for redacting a TimelineItemContent::MembershipChange 2023-09-25 14:27:50 +02:00
Jonas Platte c791fd6f1d ui: Move m.room.message specific content types into new module
`content.rs` was approaching 1K lines, which is a lot for a single file.
2023-09-25 14:27:50 +02:00
Jonas Platte 8e2ef9b2d0 ui: Move reaction types out of event_item::content
… into their own submodule.
2023-09-25 14:27:50 +02:00
dependabot[bot] 0ae6f740b9 chore(deps): bump aes-gcm from 0.10.2 to 0.10.3
Bumps [aes-gcm](https://github.com/RustCrypto/AEADs) from 0.10.2 to 0.10.3.
- [Commits](https://github.com/RustCrypto/AEADs/compare/aes-gcm-v0.10.2...aes-gcm-v0.10.3)

---
updated-dependencies:
- dependency-name: aes-gcm
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 11:38:08 +02:00
Jonas Platte 7213cfe152 ui: Add a test for Timeline::send_reply 2023-09-25 11:26:51 +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
Jonas Platte 7430201f56 ui: Add highlevel API for replying 2023-09-25 11:26:51 +02:00
Jonas Platte dd7b3ab7d7 ui: Add timeline::error module 2023-09-25 11:26:51 +02:00
Benjamin Bouvier e8624706d4 logs(sliding sync): don't accumulate room ids when computing limited 2023-09-22 12:05:58 +02:00
Kévin Commaille d4a800aadc base: Small test code fix
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-22 10:54:09 +02:00
Kévin Commaille 9b732e1895 base: Ensure room name is not empty
Ruma used to handle this during deserialization when the field was
an Option.

Especially meaningful when computing the room name, where
an empty string means the name is not set.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-09-22 10:54:09 +02:00
Jonas Platte ff7aa63c5c ui: Ignore flaky test 2023-09-21 19:12:01 +02:00
Jonas Platte 454304a20d Enable eyeball's tracing feature 2023-09-21 19:12:01 +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
Jonas Platte fd822fc683 testing: Move last event creation code from TestTimeline to EventBuilder 2023-09-21 16:00:11 +02:00
Jonas Platte 5cf3c1e731 testing: Use EventBuilder in timeline teply integration tests 2023-09-21 16:00:11 +02:00
Jonas Platte 37912a1909 testing: Update EventBuilder method names for clarity 2023-09-21 16:00:11 +02:00
Jonas Platte c89b38b19f testing: Update EventBuilder::make_message_event_with_id argument order 2023-09-21 16:00:11 +02:00
Jonas Platte 2376f16214 testing: Change make_message_event_with_id to take event_id by reference 2023-09-21 16:00:11 +02:00
Jonas Platte 5d5f5e18de testing: Move ALICE, BOB, CAROL statics to test crate 2023-09-21 16:00:11 +02:00
Jonas Platte a5a9940ad9 testing: Extract EventBuilder out of TestTimeline 2023-09-21 16:00:11 +02:00
Jonas Platte fe2e60c60d testing: Replace TimelineTestEvent::Custom with sync_timeline_event! 2023-09-21 16:00:11 +02:00
Jonas Platte 054d26774c testing: Generalize add_timeline_event for sync response room builders 2023-09-21 16:00:11 +02:00
Jonas Platte c8a4bc799b testing: Add sync_timeline_event macro for more type safety in tests 2023-09-21 16:00:11 +02:00
Jonas Platte 82f793ec0f testing: Rename event_builder module to sync_builder
It used to contain a type named EventBuilder, but that has been renamed
to SyncResponseBuilder a while ago.
2023-09-21 16:00:11 +02:00
Ivan Enderlin cce8698e6e Merge pull request #2597 from Hywan/fix-base-poll-unstable-ruma-feature 2023-09-21 14:00:55 +02:00
Ivan Enderlin b495988424 fix(cargo): Move the unstable-msc3381 feature to matrix-sdk-base. 2023-09-21 13:19:10 +02: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 9f4b2bec05 fix(cargo): Enable unstable-msc3381 on ruma.
Without this feature:

```sh
$ cargo check -p matrix-sdk --features experimental-sliding-sync
    Checking matrix-sdk-base v0.6.1 (/Users/hwhost/Development/Element/matrix-rust-sdk/crates/matrix-sdk-base)
error[E0433]: failed to resolve: could not find `poll` in `events`
 --> crates/matrix-sdk-base/src/latest_event.rs:7:5
  |
7 |     poll::unstable_start::SyncUnstablePollStartEvent, room::message::SyncRoomMessageEvent,
  |     ^^^^ could not find `poll` in `events`

error[E0599]: no variant or associated item named `UnstablePollStart` found for enum `AnySyncMessageLikeEvent` in the current scope
  --> crates/matrix-sdk-base/src/latest_event.rs:40:68
   |
40 |         AnySyncTimelineEvent::MessageLike(AnySyncMessageLikeEvent::UnstablePollStart(poll)) => {
   |                                                                    ^^^^^^^^^^^^^^^^^ variant or associated item not found in `AnySyncMessageLikeEvent`
```

With the feature, everything goes well.
2023-09-21 11:41:02 +02:00
Ivan Enderlin 2ef05eb464 feat(sdk): Remove SlidingSyncList::room_list_filtered_stream
feat(sdk): Remove `SlidingSyncList::room_list_filtered_stream`
2023-09-21 10:31:20 +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 3d8bdba268 feat(sdk): Remove SlidingSyncList::room_list_filtered_stream.
This patch removes `SlidingSyncList::room_list_filtered_stream.
Of course, the only place where it was used,
`RoomList::entries_with_dynamic_adapters` now use `.filter` from
`VectorSubscriberExt`. It's basically less code.
2023-09-21 10:17:06 +02:00
Ivan Enderlin 424135b831 fix(ffi): RoomListItem::full_room is now async
fix(ffi): `RoomListItem::full_room` is now `async`
2023-09-21 09:55:24 +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
Ivan Enderlin ef8c82113d test(ui): Test the none filter in real life. 2023-09-21 09:32:12 +02:00
Ivan Enderlin e91f170589 feat(ui): Add the none filter.
It's the opposite of the `all` filter. This one rejects all entries.
2023-09-21 09:32:12 +02:00
Ivan Enderlin 95e8f49afc test(ui): Test an empty pattern for filters. 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
Marco Romano 9a0cc58e4a Support polls as latest event of a room 2023-09-20 09:45:25 +00: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 a37c487763 examples: Remove nonsensical room state check
Stripped state events are only received for rooms in invite state.
2023-09-19 17:57:39 +02:00
Damir Jelić eeb27adad2 Use the extracted ciphers for the file-based key export support 2023-09-19 15:23:46 +02:00
Damir Jelić 0c726d521b Add a new ciphers module for AES-CTR-256 with HMAC-SHA256
This module is mainly extracting logic we're already using for the
file-based key exporting.

Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-09-19 15:23:46 +02: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 52ce2eed23 Upgrade eyeball, eyeball-im-util
Pulls in an important bug fix for the Limit adapter.
2023-09-19 11:35:18 +02:00
Ivan Enderlin 1e80aae780 feat(ui): RoomList dynamic entries simplifications
feat(ui): `RoomList` dynamic entries simplifications
2023-09-19 11:00:35 +02:00
Ivan Enderlin af7cf3148b test(ui): Ensure that it's fine to reset_to_one_page multiple times. 2023-09-19 10:40:02 +02:00
Ivan Enderlin d0da4ae159 feat(ui): Update the limit if it's different.
Use `SharedObservable::set_if_not_eq` instead of `::set`, so that it
doesn't update the limit to the same value, which would be unnecesary in
this case.
2023-09-19 10:34:27 +02:00
Ivan Enderlin c2166c50b1 chore(ui): Remove a useless clone.
It was necessary before 0f7e5ba4b0, but it
isn't anymore.
2023-09-19 10:33:19 +02:00
Ivan Enderlin a1a5b85fd8 feat(ui): Remove one Mutex.
This patch removes the `Mutex` around `Subscriber<Option<u32>>` inside
the `RoomListDynamicEntriesController`. The `Mutex` was necessary to
get a mutable reference, so that `Subscriber::next_now` could have been
used. However, it's not necessary to use `new_now` in this particular
context. We can use `get` instead, which take an immutable reference,
thus removing the need for the `Mutex`.

A `Mutex` has a non-negligeable cost. This function can be used in a
critical hot path, and must as fast as possible.
2023-09-19 10:29:49 +02:00
Ivan Enderlin 12316ad281 feat(ui): Improve the InputCannotBeApplied displaying
feat(ui): Improve the `InputCannotBeApplied` displaying
2023-09-19 08:56:55 +02:00
Jonas Platte 97c5acff7c Use new functionality from eyeball-im-util 0.5 2023-09-18 19:56:06 +02:00
Jonas Platte 0504eafc0a Upgrade most dependencies 2023-09-18 19:56:06 +02:00
Jonas Platte beeeec34f7 sdk: Wait on sync beat asynchronously 2023-09-18 19:56:06 +02:00
Jonas Platte 45b7e075c9 Remove unused dependencies 2023-09-18 19:56:06 +02:00
Benjamin Bouvier 0ecdc2f43c fix(e2ee): query keys for untracked users even if we didn't explicitly sync members ourselves 2023-09-18 17:24:21 +02:00
Ivan Enderlin ae27164bb3 feat(ui): Improve the InputCannotBeApplied displaying. 2023-09-18 17:02:41 +02:00
Ivan Enderlin e5ba445c56 feat(sqlite) chunk_large_query_over doesn't chunk if not necessary
feat(sqlite) `chunk_large_query_over` doesn't chunk if not necessary
2023-09-18 16:33:52 +02:00
Ivan Enderlin 1f98159213 chore(sqlite): Simplify Vec capacity calculation.
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-09-18 16:20:05 +02:00
Ivan Enderlin 4c244c6d83 feat(sqlite) chunk_large_query_over doesn't chunk if not necessary.
This patch updates `chunk_large_query_over`. This function works great
when it's required to chunk some data over a query. However, if the
data don't need to be chunked, it is possible to get a quicker path that
doesn't involve 2 `Vec` allocations, nor a `split_off` of one `Vec`, nor
a `Vec::extend` (which move data in memory). The quicker path, which is
also the most likely to be hit, simply does a single `Vec` allocation,
and that's it.
2023-09-18 15:13:45 +02:00
Benjamin Bouvier 284bb9702b example(oidc): add automatic persist on session update 2023-09-18 14:34:10 +02:00
Benjamin Bouvier bed0faa143 example(oidc): add sync service integration
And allow to run with an insecure server + auto-refresh token + properly restore session using homeserver discovery
2023-09-18 14:34:10 +02:00
Benjamin Bouvier 5ff83c00c5 Add tests for OIDC (#2558)
* chore(oidc): put impl of OIDC server behind a trait and add tests for the OIDC flow

chore(oidc): add first tests for login/AuthorizationResponse

chore(oidc): add tests for finish_authorization/finish_login/refresh_access_token

chore(oidc): add test for logout

chore(🤷): clippy/fmt

* chore(oidc): move account management test to the new `tests` module

* chore(oidc): address review comments
2023-09-18 14:33:35 +02:00
Damir Jelić f44ebf1bf9 Merge pull request #2553 from matrix-org/poljar/fix-mark-dm-as-room
Add method to fetch account data and fetch the m.direct account data from the server when marking rooms as DMs
2023-09-18 11:19:48 +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
Damir Jelić 790944f216 Update crates/matrix-sdk/src/account.rs
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2023-09-18 11:04:40 +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 463b207422 feat(ui): Use an initial limit in room list dynamic entries
feat(ui): Use an initial limit in room list dynamic entries
2023-09-18 10:42:28 +02:00
Ivan Enderlin 442e6ca8c0 fix(ui): The invites sliding sync is no longer cached
fix(ui): The `invites` sliding sync is no longer cached
2023-09-18 10:42:00 +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 0f7e5ba4b0 feat(ui): Use an initial limit in room list dynamic entries.
In `RoomList::entries_with_dynamic_adapters`, we were using the
`Limit::dynamic` constructor. It builds a `Limit` stream adapter where
the limits come from a `Stream`. The immediate impact is that this
constructor does only return a new `Stream`, but it cannot return
the initial items of the vector. Thus, it wasn't possible to reset
the final `Stream` with a `VectorDiff::Reset { values }`. Instead, we
were emitting a `Clear` (from this code) then a `Append` (from the
`Limit` stream). Sadly, for some client apps, like Element X iOS, these
2 diffs (`Clear` and `Append`) result in a “rendering blink”.

Hopefully for us, now there is new constructors for `Limit`! One of them
is `Limit::dynamic_with_initial_limit`, which returns the initial items
along with the new `Stream`. That's perfect, we can reset the final
`Stream` with `Reset { values }` again, thus removing the “UI blinking”
effect in Element X iOS.

This patch switches `Limit::dynamic` to
`Limit::dynamic_with_initial_limit`, and updates/simplifies the tests
accordingly.
2023-09-18 10:21:51 +02:00
Ivan Enderlin b7240b898c fix(ci): Change tarpaulin output format from Xml to xml
fix(ci): Change tarpaulin output format from `Xml` to `xml`
2023-09-18 10:21:15 +02:00
Ivan Enderlin 17e1e81023 fix(ui): The invites sliding sync is no longer cached.
`RoomListService::new_internal` were creating the `invites` sliding
sync list, with a cache. It is not a good idea. It should not be cached.
Let's remove that :-).
2023-09-18 10:06:37 +02:00
Ivan Enderlin 005d2638cb fix(ci): Change tarpaulin output format from Xml to xml.
It's better huh?
2023-09-18 09:58:09 +02:00
Ivan Enderlin af402b3864 fix(ui): Set RoomListLoadingState initial value
fix(ui): Set `RoomListLoadingState` initial value
2023-09-18 09:55:15 +02:00
Ivan Enderlin 1cf5f3a0ee fix(ui): Set RoomListLoadingState initial value.
`RoomListLoadingState` was initialized with the `NotLoaded` state. This
is always true… except when there is a cache! If the cache contains
N rooms, the loading state should be `Loaded { … }`. Then the next
sync (if any) will update the loading state to `Loaded { … }` with
an adjusted number of rooms or something like that, but semantically
speaking, the presence of the cache should result in a `Loaded` state.

This patch fixes this behavior, and also adds the tests.
2023-09-18 09:26:37 +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 b6af934635 chore(ui): let + else FTW! 2023-09-15 16:51:08 +02:00
Damir Jelić 3fb6f206fc Record the HTTP method in our logs 2023-09-15 16:51:05 +02:00
Damir Jelić b61f2fbdc4 Test if we're doing the correct request when marking a room as a DM 2023-09-15 16:51:05 +02:00
Damir Jelić a61205088b Fetch the account data from the server before marking rooms as DMs 2023-09-15 16:51:05 +02:00
Damir Jelić de90cf413b Add a method to retrieve global account data events from the server 2023-09-15 16:47:22 +02:00
Ivan Enderlin db1125d427 chore(cargo): Back to regular eyeball. 2023-09-15 15:02:04 +02:00
Ivan Enderlin a5e19201df chore(ui): Produce Clear instead of Truncate { length: 0 }. 2023-09-15 14:43:21 +02:00
Ivan Enderlin 16bfd14b81 !fixup 2023-09-15 14:35:03 +02:00
Ivan Enderlin be6da14f16 test(ui): Add more tests. 2023-09-15 13:46:41 +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 774f695eb8 chore(doc): fix documentation 2023-09-15 13:03:11 +02:00
Benjamin Bouvier ab0982e512 chore(matrix auth): simplify a bit the code of matrix auth's refresh_access_token 2023-09-15 13:03:11 +02:00
Benjamin Bouvier 0cb5f666ae chore(oidc): remove a few unnecessary wrappers, now that OidcCtx is in an Arc'd data structure 2023-09-15 13:03:11 +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 b42cb1c43f chore(oidc): rename OidcContext to OidcCtx for symmetry with AuthCtx 2023-09-15 13:03:11 +02:00
Benjamin Bouvier 2acf21fcd4 refactor(oidc): move AuthCtx::authentication_server_info into OidcContext 2023-09-15 13:03:11 +02:00
Benjamin Bouvier 3144d87c3a refactor(oidc): put the OidcContext in the AuthCtx 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 23f4aedf47 chore(oidc): update some code comments 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 dde2f408c5 chore(sliding sync): log the room id in the limited flag computation 2023-09-14 19:14:52 +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
Jonas Platte fd17bce300 ui: Fix day divider logic
… for when a remote event is re-received while a local echo is pending.
Also simplify test_togglling_reaction integration test so it still passes.
2023-09-14 14:14:44 +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 0c4b8c602c ui: Sanitize m.room.message events in notifications
… including reply fallback stripping.
2023-09-14 12:18:30 +02:00
Jonas Platte 03bbdce15f ffi: Add in_reply_to field to MessageLikeEventContent::RoomMessage 2023-09-14 12:18:30 +02:00
Jonas Platte af400357f5 Use Self keyword more 2023-09-13 18:33:33 +02:00
Jonas Platte 4da3806a01 indexeddb: Simplify filter_map closure 2023-09-13 18:33:33 +02:00
Jonas Platte 1cbcee4fea Use as_variant crate for shorter code 2023-09-13 18:33:33 +02:00
Jonas Platte 1542abd25a ui: Adjust logs to use natural numbering 2023-09-13 15:17:55 +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
Jonas Platte 9a30878f43 ui: Fix a typo 2023-09-13 11:45:11 +02:00
Jonas Platte 958ed1855e ui: Log a warning when TimelineInnerStateTransaction is cancelled 2023-09-13 11:45:11 +02:00
Jonas Platte a1d730f87b ui: Simplify TimelineInner subscription methods 2023-09-13 11:45:11 +02:00
Jonas Platte fa0d949600 ui: Change TimelineInnerStateTransaction to be committed explicitly 2023-09-13 11:45:11 +02:00
Jonas Platte be4c376423 ui: Use ObservableVectorTransaction for timeline 2023-09-13 11:45:11 +02:00
Jonas Platte 55be56e78f ui: Move some functions to TimelineInnerMetadata 2023-09-13 11:45:11 +02:00
Jonas Platte c6fd3ec4b0 ui: Split non-items fields of TimelineInnerState into separate struct
… as a preparation for further refactorings.
2023-09-13 11:45:11 +02:00
Jonas Platte 7168df8b30 ui: Fix indentation 2023-09-13 11:45:11 +02:00
Jonas Platte 7fad343390 ui: Remove unused import 2023-09-13 11:45:11 +02:00
Jonas Platte 768f062e0c ui: Ignore flaky test
It's still compiled, but not run unless `--ignored` or `--include-ignored`
is passed on the commandline.
2023-09-13 11:40:54 +02:00
Jonas Platte 96ccd6e2bd sdk: Fix unit tests not compiling without testing feature 2023-09-12 18:31:15 +02:00
Jonas Platte a4101e2f45 Upgrade Ruma 2023-09-12 17:19:56 +02:00
Benjamin Bouvier d35a8b7fa0 chore: remove one level of indent thanks to let else 2023-09-12 17:02:42 +02:00
Benjamin Bouvier 2d932dc29f feat: don't process the limited flag for e2ee-only sliding syncs 2023-09-12 17:02:42 +02:00
Benjamin Bouvier 654a2f2495 fix(sliding sync): don't mark a response to a locally empty room as limited
When receiving a sliding sync room response for a room that had no local events in its timeline cache,
we'd mark the room as limited before, which is incorrect. It was made worse by the fact that later in
the code, we'd clear the local cache if a room was marked as limited, so this is a problem that would
repeat itself over time (assuming empty responses for that room).

This fixes it and unifies logs so there's only one log line per room, at most.

Fixes https://github.com/vector-im/element-x-android/issues/1281
Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/2540
2023-09-12 17:02:42 +02:00
Jonas Platte a53bfe5748 Some documentation cleanup 2023-09-12 09:25:19 +02:00
Benjamin Bouvier b565acd462 feat: log the x-sentry-event-id if we receive it from the server 2023-09-11 14:41:42 +02:00
Jonas Platte 6131e41183 sdk: Replace deprecated function 2023-09-08 12:35:01 +02:00
Jonas Platte d4904a01b0 Upgrade dependencies
Most notably eyeball-im-util 0.3.1, which includes an important bugfix.
2023-09-08 12:35:01 +02:00
Damir Jelić c32f2444fc Use the base64 encoding/decoding methods from vodozemac in the bindings 2023-09-08 11:43:32 +02:00
Damir Jelić 72e3079aab Use the base64 encoding/decoding functions from vodozemac 2023-09-08 11:43:32 +02:00
Damir Jelić 7e06ad130c Add a base64 prefix to the names of the base64 encoding/decoding functions 2023-09-08 11:43:32 +02:00
Richard van der Hoff 8d1308ef6a fix doc 2023-09-07 22:31:34 +01:00
Richard van der Hoff 783adb424e Impmenent Store::identity_stream_raw
An alternative to `user_identity_stream`, which does not hold a reference to
the `CryptoStore` and hence is less prone to leaking references
2023-09-07 22:17:09 +01: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
dependabot[bot] 4991450d6a chore(deps): bump webpki from 0.22.0 to 0.22.1
Bumps [webpki](https://github.com/briansmith/webpki) from 0.22.0 to 0.22.1.
- [Commits](https://github.com/briansmith/webpki/commits)

---
updated-dependencies:
- dependency-name: webpki
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-07 18:51:15 +02: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
Jonas Platte 36942e4f22 ui: Add threaded property to timeline Message type 2023-09-07 16:54:21 +02:00
Jonas Platte 619085a190 Use ObservableVectorTransaction for room list 2023-09-07 15:30:18 +02:00
Jonas Platte 71cc7318ca Upgrade eyeball-im, eyeball-im-util 2023-09-07 15:30:18 +02:00
Benjamin Bouvier dbf9e80c8f encryption sync: disable the shared pos in the encryption sync
It is racy and would require a cross-process lock held during the whole
flow (from creating the request to processing the response).
2023-09-07 14:55:55 +02:00
Benjamin Bouvier ab7ec1bc38 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.
2023-09-07 11:41:22 +02:00
Benjamin Bouvier 87be58bc2c chore: upgrade some code comments to doc comments in OngoingMigration 2023-09-07 11:41:22 +02:00
Benjamin Bouvier 685cc2bbc3 feat: make the cross-process store locks generic
And move the implementation to the common crate.
2023-09-07 11:41:22 +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 9802795d8d fix: don't overwrite the parent session when creating a child Client 2023-09-07 10:34:54 +02:00
Benjamin Bouvier 7ba06c3136 chore: unify implementations of SendRequest::into_future and Client::send_with_homeserver 2023-09-07 10:34:54 +02:00
Benjamin Bouvier 0d6e12f3cd chore: tweak implementation of Oidc::set_session_tokens to make it less contrived 2023-09-07 10:34:54 +02:00
Benjamin Bouvier bb82a068c2 chore: move the auth_data field into AuthCtx 2023-09-07 10:34:54 +02:00
Benjamin Bouvier 6c55767c73 chore: move the session_changer_sender field into AuthCtx 2023-09-07 10:34:54 +02:00
Benjamin Bouvier 7db45a4b23 chore: move the refresh_token_lock into the AuthCtx 2023-09-07 10:34:54 +02:00
Benjamin Bouvier 4802a50609 chore: put handle_refresh_tokens in the AuthCtx 2023-09-07 10:34:54 +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
Benjamin Bouvier 44a13fac9f chore(client): introduce AuthCtx to contain all data relative to auth(entication|orization) 2023-09-07 10:34:54 +02:00
Ivan Enderlin 74c5c2825a test(ci): Exponential backoff when retrying flaky tests
test(ci): Exponential backoff when retrying flaky tests
2023-09-07 09:51:17 +02:00
Ivan Enderlin f08524baa6 test(ci): Exponential backoff when retrying flaky tests.
This patch changes the backoff strategy from `fixed` to `exponential`
when a flaky test is retried. The `count` value is also updated to
3. Finally, we try to avoid the thundering herd problems with `jitter
= true`.
2023-09-07 09:12:29 +02:00
Ivan Enderlin b8dd45546d doc(sdk): Add documentation. 2023-09-07 09:06:16 +02:00
Ivan Enderlin 29fecf5109 test(ui): Adjust request_margin to avoid a flaky test
test(ui): Adjust `request_margin` to avoid a flaky test
2023-09-06 20:50:44 +02:00
Ivan Enderlin c5e4ea4e3c test(ui): Adjust request_margin to avoid a flaky test. 2023-09-06 20:34:57 +02:00
Damir Jelić 9174f120b4 Expose the user identities and devices streams in the main crate 2023-09-06 19:00:37 +02:00
Damir Jelić 578c1a473a Broadcast new and updated devices 2023-09-06 19:00:37 +02:00
Damir Jelić 53c4735944 Broadcast new and updated user identities 2023-09-06 19:00:37 +02:00
Damir Jelić 7419b2c86b Add our user ID to the CryptoStoreWrapper
This will become useful once we start broadcasting user identity
updates, we'll need to know which user identity is our own.
2023-09-06 19:00:37 +02:00
Ivan Enderlin 64bdbdcbaa feat(ui): Implement RoomListService::sync_indicator
feat(ui): Implement `RoomListService::sync_indicator`
2023-09-06 17:56:11 +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
Ivan Enderlin b8ed566d78 feat(ffi): Add bindings for RoomListService::sync_indicator.
This patch adds the `RoomListService::sync_indicator` method, along
with the `RoomListServiceSyncIndicatorListener` callback interface, and
`RoomListServiceSyncIndicator` enum.
2023-09-06 17:16:36 +02:00
Ivan Enderlin 8a1ff1967f feat(ui): Implement RoomListService::sync_indicator.
This patch implements a new method: `RoomListService::sync_indicator`.
It returns a `impl Stream<Item = SyncIndicator>` where `SyncIndicator`
is a new enum with 2 variants: `Show` and `Hide`.

`SyncIndicator` is the UI equivalent of a sync spinner/loader/toaster,
that the app might want to show to the user to indicate when a _first_
request is sent and might be slow, i.e. the first response is taking
a little bit of time to come. The term _first_ may be innapropriate as
it covers the actual first sync request, but also the recovering sync
request. It means that when a sync error happened, the sync indicator
will be shown too, which is a pretty useful information for the user.

It's not because a `SyncIndicator` should be shown that it must be send
immediately onto the `Stream`. In case of a normal network conditions,
without any delay, it can lead to a “blinking” visual effect. Some
constants configure how long it takes to consider that a request is
“slow”, and that the `SyncIndicator` is necessary to be shown (or
hidden).
2023-09-06 17:16:36 +02:00
Jonas Platte 2787d058de ui: Remove Option from return type
… of TimelineItemContent::from_suitable_latest_event_content.
It had no branches that returned None.
2023-09-06 12:59:08 +02:00
Jonas Platte 57ba63d432 base: Allow redacted events as latest event 2023-09-06 12:59:08 +02:00
Ivan Enderlin acb731af2f fix: & without an explicit lifetime name cannot be used here
fix: `&` without an explicit lifetime name cannot be used here
2023-09-06 11:04:50 +02:00
Richard van der Hoff 3f3f599877 Add OlmMachine::get_room_event_encryption_info (#2510)
Since the verification status of an event can change, we need to be able to
refetch the verification status without doing the whole decryption dance.

Hence, we expose a new `get_room_event_encryption_info` method.
2023-09-06 10:03:15 +01:00
Richard van der Hoff d116e31733 Implement new CryptoStoreWrapper (#2515)
... so that `VerificationStore` and `StoreInner` can share the same
`save_changes` impl which broadcasts updates to the broadcast channels.
2023-09-06 09:57:40 +01:00
Ivan Enderlin f13282ea30 fix: & without an explicit lifetime name cannot be used here.
This was previously accepted by the compiler but is being phased out;
it will become a hard error in a future release! See https://github.com/
rust-lang/rust/issues/115010.
2023-09-06 09:37:51 +02:00
Benjamin Bouvier 896f62eb68 fix(tests): don't reuse the same store name in multiple tests 2023-09-05 18:45:51 +02:00
Benjamin Bouvier cc469f6d4a chore: derive Default for the state MemoryStore 2023-09-05 15:44:31 +02:00
Jonas Platte 2d47aecd37 Remove the appservice feature from matrix-sdk, matrix-sdk-test 2023-09-05 15:40:38 +02:00
Jonas Platte 7d674b39aa Remove matrix-sdk-appservice
There is unfortunately no capacity for maintaining it as a first-party
component of the Rust SDK.
2023-09-05 15:40:38 +02:00
Benjamin Bouvier 11b3be1a03 feat(notification client): always retry decryption if it failed before
Now that we can decrypt on both of {single|multi} process setups (i.e. available for both android
and ios), we can enable retrying decrypting notifications by default.
2023-09-05 14:17:41 +02:00
Benjamin Bouvier f13adb24dd feat(sync service): enable the encryption sync by default 2023-09-05 14:17:41 +02:00
Benjamin Bouvier 94cfa9fc12 chore(tests): move check_requests from encryption_sync_service to sliding_sync helper file 2023-09-05 14:17:41 +02:00
Benjamin Bouvier 3d89d750fb chore: rename EncryptionSync to EncryptionSyncService 2023-09-05 14:17:41 +02:00
Benjamin Bouvier 242c5bcb37 chore(ui): move xyz/mod.rs to xyz.rs for the encryption_sync and sync_service 2023-09-05 14:17:41 +02:00
Benjamin Bouvier d6f0635023 chore: clippy + review feedback 2023-09-05 11:17:14 +02:00
Benjamin Bouvier ea2826aac6 chore(FFI): update bindings for changes to the NotificationClient builder 2023-09-05 11:17:14 +02:00
Benjamin Bouvier 508091af80 feat: use the encryption sync permit from the SyncService in the NotificationClient
Also rejigger the parameters passed to the notification client builder, so that it's always required to pass
a process setup. With that, we're one step closer to removing the retry_decryption() function and enable it
by default.
2023-09-05 11:17:14 +02:00
Benjamin Bouvier de9b6d25cd feat: have the SyncService own the EncryptionSyncPermit and add try_get_encryption_sync_permit 2023-09-05 11:17:14 +02:00
Benjamin Bouvier 9469b77741 feat: add an EncryptionSyncPermit object allowing to use an EncryptionSync
The comment above the type should help understanding what it is about.
2023-09-05 11:17:14 +02:00
Jonas Platte 06ec19b50b ui: Add test for transfering reply details 2023-09-05 10:39:48 +02:00
Jonas Platte bd99c5e72b ui: Transfer reply details from old to new item when receiving dup event 2023-09-05 10:39:48 +02:00
Jonas Platte bdddb0ce7a ui: Move reply test into a separate module 2023-09-05 10:39:48 +02:00
Jonas Platte 73a9cd40d3 sdk: Remove warning about event without txn ID
… it doesn't make sense to have as long as it's still very common to get
duplicate non-echo events from the SS proxy.
2023-09-05 10:39:48 +02:00
Ivan Enderlin 465c9bcbed test(ui): Test Timeline is reset when a user is ignored/unignored. 2023-09-04 17:39:02 +02:00
Jonas Platte 4f2477fbe8 ui: Reset the timeline when ignore user list changes 2023-09-04 17:39:02 +02:00
Ivan Enderlin cf419566e8 feat(ui): TimelineInnerStateLock::lock is replaced by ::read and ::write
feat(ui): `TimelineInnerStateLock::lock` is replaced by `::read` and `::write`
2023-09-04 15:44:13 +02:00
Damir Jelić e835d9a1cc The export_room_key method does not encrypt the room keys nor does it panic 2023-09-04 15:39:10 +02:00
Ivan Enderlin 91784ded72 feat(ui): TimelineInnerStateLock::lock is replaced by read and write.
The `Timeline` batches its updates to its subscribers (e.g. a client app,
like Element X). A batch is built every time the inner state lock of
the `Timeline` is released. On the paper, it's nice; in practise, even
a read operation on the `Timeline` leads to building a new batch. This
is inefficient and consumes resources (like CPU cycles, FFI boundary
crossings, memory allocations etc.) even if there is no update to put in
the batch: this will just batch empty updates.

To avoid that, one needs to make the difference between read or write
operations onto the inner state. Only the write operations will fire a
batch.

This patch splits the `TimelineInnerStateLock::lock` method into
`::read` and `::write`. The idea is that a read-only lock doesn't
hold a clone of the lock release observer (`lock_release_ob:
SharedObservable<()>`), it will not notify the observer. Then it's only
the write lock that holds a clone of the lock release observer, and will
notify it.

This patch updates the code accordingly as best as possible.
2023-09-04 15:05:52 +02:00
Benjamin Bouvier e8e7738dfa chore: introduce fail! macro to avoid repetitive work 2023-09-01 16:06:46 +02:00
Benjamin Bouvier 2d5f5879ab chore: remove spurious clone 2023-09-01 16:06:46 +02:00
Benjamin Bouvier 0162e62feb fix: don't save the latest_id_token upon refresh (thanks @zecakeh!) 2023-09-01 16:06:46 +02:00
Benjamin Bouvier d37656d9f0 chore: use a hash() function instead of hashing manually 2023-09-01 16:06:46 +02:00
Benjamin Bouvier 5451d39ba3 chore: move notification within the refresh_access_token_inner function 2023-09-01 15:15:02 +02:00
Benjamin Bouvier a17a7608f3 chore: add more focused logs for OIDC 2023-09-01 15:15:02 +02:00
Benjamin Bouvier 4cdef7255e fix: save the OIDC refresh token from the response (!) 2023-09-01 15:15:02 +02:00
Jonas Platte 2b18a02488 ffi: Use avatar_url from sliding sync for RoomInfo where applicable 2023-09-01 10:47:48 +02:00
Jonas Platte db565fcff3 ci: Improve caching for matrix-rust-components-swift and tarpaulin 2023-09-01 10:43:52 +02:00
Jonas Platte e02676616f sdk: Make use of clonable FnOnce in event handlers 2023-09-01 10:42:22 +02:00
Jonas Platte a6b4e04181 sdk: Revert observable diff buffer capacity change 2023-09-01 10:06:07 +02:00
Benjamin Bouvier d060ec2830 chore: add e2e-encryption cfg guards 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 51dcdac46d TERRIBLE HACK: save the pos value in the crypto store 2023-08-31 16:08:45 +02:00
Benjamin Bouvier be3616c6b2 chore: rename restore_pos_from_database to share_pos 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 05a8343d03 chore: rename previous_pos to pos 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 28d25882c2 chore: fmt + clippy 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 5eb455032e tests: add test and maintain property that in-memory pos == db pos at all times 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 6b84d03e2f feat(encryption sync): restore the stream position from the database 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 08b9f0640c feat: add a new sliding sync option to restore the stream position from the database 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 4b67a6608e feat: persist previous pos when saving/restoring a sliding sync 2023-08-31 16:08:45 +02:00
Benjamin Bouvier 941ecbfe0d chore: refactor fields restored by restore_sliding_sync_state 2023-08-31 16:08:45 +02:00
Ivan Enderlin 719cbee96e feat(ui): Fine-tuning RoomList again
feat(ui): Fine-tuning `RoomList` again
2023-08-31 12:57:27 +02:00
Benjamin Bouvier 11404010e6 chore: disable colors for logging in FFI for logcat and stdout too 2023-08-31 12:13:25 +02:00
Ivan Enderlin 4b04f15bc5 chore(ui): Naming is hard :-). 2023-08-31 12:04:14 +02:00
Doug 7e71c79072 chore(sdk): Log the OIDC refresh token (hashed). (#2486)
* chore(sdk): Log the OIDC refresh token (hashed).
* chore(sdk): Fix Clippy and PR comments.
2023-08-31 09:25:46 +00:00
Benjamin Bouvier 50a3da386e feat: enable read receipts in the room list service sliding sync 2023-08-31 11:08:56 +02:00
Benjamin Bouvier eebf271d6c chore: use a workspace dependency for assert-json-diff 2023-08-31 10:34:46 +02:00
Benjamin Bouvier 4665277842 test(sliding sync): skipping b/o mode change doesn't change parameters in other lists
w
2023-08-31 10:34:46 +02:00
Ivan Enderlin 5a0c230a2d feat(ui): visible_rooms can shrink its timeline_limit.
This patch updates the behavior of `visible_rooms` where its
`timeline_limit` is shrunk and expanded when the state machine is
recovering.
2023-08-31 10:31:44 +02:00
Ivan Enderlin 7819938149 feat(ui): invites is always defined in RoomListService.
This patch updates `RoomListService` to install the `invites` sliding
sync list from the start, along with `all_rooms`. Prior to the patch,
`invites` was installed after the first sync.

`invites` is installed in selective sync-mode with a range of `0..=0`.
After the next sync, `invites` switched its sync-mode to growing with a
batch size of `0..=19`.
2023-08-30 21:20:29 +02:00
Jonas Platte 06a19f016e ffi: Only ever call ClientDelegate methods in a blocking task
… and clean up a few unnecessary Arc's.
2023-08-30 15:29:06 +02:00
Jonas Platte 5630851062 Upgrade Ruma 2023-08-30 15:22:00 +02:00
Ivan Enderlin 6b50a8988b Merge pull request #2463 from matrix-org/jmartinesp/add-x86-64-workaround-to-crypto-sdk-in-main
Add the x86-64 Android workaround to the Crypto SDK too
2023-08-30 15:12:17 +02:00
Jonas Platte 1311ddbae3 ffi: Disable colorization of tracing fields 2023-08-30 14:07:22 +02:00
Ivan Enderlin 5564d323f5 fix(ui): Try to make RoomListService fast for gigantic accounts with various network speeds
fix(ui): Try to make `RoomListService` fast for gigantic accounts with various network speeds
2023-08-30 14:06:23 +02:00
Ivan Enderlin 3062f30e08 chore(ffi): Add the RoomListServerState::Recovering variant. 2023-08-30 13:17:05 +02:00
Ivan Enderlin e8815d83b8 feat(ui): Add a new Recovering intermediate state in RoomListService.
This patch takes inspiration of
https://github.com/matrix-org/matrix-rust-sdk/pull/2480.

This patch adds a new `Recovering` state, which is a “transition”
between `Error` and `Terminated` to `Running`. When moving from `Error`
or `Terminated` to `Recovering`, `all_rooms`' sync-mode is set to
`Selective` with its initial range. Then when moving from `Recovering`
to `Running`, `all_rooms`' sync-mode is set to `Growing` with its
initial range again. For the `invites` list, it is reset to its initial
range when moving to `Recovering` too.

`Error` and `Terminated` now act the same.
2023-08-30 13:13:16 +02:00
Jonas Platte ca0c1f567a sdk: Add widget::EventFilter matching
Co-authored-by: Timo K <toger5@hotmail.de>
Co-authored-by: Daniel Abramov <inetcrack2@gmail.com>
2023-08-30 12:57:54 +02:00
Jonas Platte 04fee2952f sdk: Split widget EventFilter into sub-types
… and move them into their own module.

Co-authored-by: Timo K <toger5@hotmail.de>
Co-authored-by: Daniel Abramov <inetcrack2@gmail.com>
2023-08-30 12:57:54 +02:00
Jonas Platte c589bd0cd1 sdk: Add extra docs for widget channels 2023-08-30 12:57:54 +02:00
Jonas Platte 959b594c43 sdk: Rename widget::Info to WidgetSettings 2023-08-30 12:57:54 +02:00
Alfonso Grillo c567f963d5 ffi: Add send fn's for poll response and poll end 2023-08-30 09:44:08 +00:00
Ivan Enderlin e3aec5ebbc fix(ui): Update batch_size of all_rooms to 100.
This patch updates the `batch_size` of `all_rooms` once in growing
sync-mode to 100. It was previously increased from 50 to 200 in
12a1f25ec3. In some situations, it
generates very large payloads that can take time to be delivered to the
user with a slow network.

This patch tries to fine-tuned the `batch_size` value.
2023-08-30 08:48:55 +02:00
Ivan Enderlin e5a5dac099 fix(ui): Revert timeline_limit to 1 for all_rooms.
This patch reverts b2cc279279. On the
paper, it was a good idea. In practise, it has revealed a bug on the
server side. The only solution to mitigate this bug for now is to revert
the `timeline_limit` to 1.
2023-08-30 08:38:05 +02:00
Nicolas Mauri 1cc11ae988 feat(ffi): Add a notification_mode property to room_info (#2460)
* feat(ffi): Add a notification_mode property to room_info
* feat(sdk): Add a notification_mode() function to Room
* Fix Rust syntax
2023-08-29 12:25:26 +00:00
Doug 58d30454ae feat(bindings): Add logo_uri to OidcConfiguration
… and make most OidcConfiguration properties optional.
2023-08-29 13:35:10 +02:00
Jonas Platte 0590543df1 ffi: Add custom tracing log formatter (#2464)
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-08-28 15:05:21 +00:00
Ivan Enderlin 30731d60d7 feat(sdk): Adjust room_list observable capacity
feat(sdk): Adjust `room_list` observable capacity
2023-08-28 16:58:05 +02:00
Benjamin Bouvier 98dafac236 feat: time how long it takes to restore lists from the cache 2023-08-28 16:52:43 +02:00
Benjamin Bouvier b6c658aefa feat: introduce timer helper 2023-08-28 16:52:43 +02:00
Ivan Enderlin c23e8863fc feat(sdk): Adjust room_list observable capacity.
Prior to this patch, we have increased the
`SlidingSyncListInner::room_list` capacity, to avoid trigger
`VectorDiff::Reset` as much as possible. Now that Element X is optimised
to handle larger diff, we can discrease this number, yeeeee :-).
2023-08-28 16:33:02 +02:00
Ivan Enderlin 9d9add39fb Merge pull request #2466 from Hywan/feat-ui-roomlist-all-rooms-timeline-limit-0 2023-08-28 15:29:27 +02:00
Ivan Enderlin b2cc279279 feat(ui): Change all_rooms to timeline_limit=0.
When a user has hundreds of rooms, `RoomListService` will fetch at worst
one event per room, which can generate large responses. Let's use a
`timeline_limit=0`.
2023-08-28 14:50:55 +02:00
aringenbach 8cb00510d2 ffi: use RoomMessageEventContentWithoutRelation for send / reply / edit 2023-08-28 11:26:51 +02:00
Nicolas Mauri 63196aa6aa fix(sdk): limit the number of retries when updating push rules. (#2461)
* fix(sdk): limit the number of retries when updating push rules.
* fix Rust format
2023-08-25 15:11:49 +00:00
Jorge Martín e7ad46f5a0 Fix formatting 2023-08-25 14:37:09 +02:00
Jonas Platte 2311edecf6 ui: Remove unused import 2023-08-25 14:14:56 +02:00
Jonas Platte aed9b20195 Silence clippy lint arc_with_non_send_sync on wasm 2023-08-25 14:14:56 +02:00
Jorge Martín 1d08ffa05e Add the x86-64 Android workaround to the Crypto SDK too 2023-08-25 13:31:12 +02:00
Jonas Platte e02aa6b132 ffi: Add Room::{room_info, subscribe_to_room_info_updates} 2023-08-25 11:39:57 +02:00
Jonas Platte 9a0869dff8 base: Add Room::subscribe_info 2023-08-25 11:39:57 +02:00
Jonas Platte 72b11d5cc6 sdk: Replace Arc<RwLock<_>> around RoomInfo with SharedObservable 2023-08-25 11:39:57 +02:00
Ivan Enderlin 8f754a4f05 fix(base): BaseClient::ignore_user_list_changes is no longer behind an Arc
fix(base): `BaseClient::ignore_user_list_changes` is no longer behind an `Arc`
2023-08-24 15:17:14 +02:00
Jonas Platte 320f5c2155 Rename feature flag for widgets 2023-08-24 14:55:55 +02:00
Jonas Platte 1c3dd38b97 ffi: Add widget API skeleton 2023-08-24 14:55:55 +02:00
Ivan Enderlin 0c21827a5a fix(base): BaseClient::ignore_user_list_changes is no longer behind an Arc.
This patch first off renames `BaseClient::ignore_user_list_changes_tx`
to `::ignore_user_list_changes`.

This patch then changes the type from `Arc<SharedObservable<_>>` to
simply `SharedObservable` as this type implement `Clone`. We basically
have a double-`Arc` here.

Finally, this patch adds documentation for this field.
2023-08-24 14:54:40 +02:00
Jonas Platte 7aa6981e37 Make update_timeline_item macro compatible with Rust 1.70
… by swapping the branches around. Previously, invocations meant to
match the found + not_found branch were actually hitting the other one
prior to Rust 1.71, likely due to parser supporting type ascription
(even though it was an unstable feature).
2023-08-24 13:42:44 +02:00
Ivan Enderlin c742affa13 feat(ui): Reduce and refresh the batch_size growing sync-mode of invites in RoomListService
feat(ui): Reduce and refresh the `batch_size` growing sync-mode of `invites` in `RoomListService`
2023-08-24 13:32:29 +02:00
Ivan Enderlin 55e8f2573b feat(ui): Add the ResetInvitesListGrowingSyncMode action in RoomList.
Inside `RoomListService`, the `State` enum handles the transition from
one state to another. In case of some `State::Error`, the `all_rooms`
sliding sync was refreshed, i.e. its sync-mode was reset to its initial
value.

This patch also refreshes the `invites` sliding sync list! It adds
the `ResetInvitesListGrowingSyncMode` action, and attaches it to the
`refresh_lists` actions.

New constants are added to represent default `batch_size` values for the
growing sync-mode for various sliding sync list. It could be helpful for
further maintenance.

This patch finally adds and updates the tests accordingly.
2023-08-24 13:07:28 +02:00
Ivan Enderlin e82607c743 chore(cargo) Update ruma
chore(cargo) Update `ruma`
2023-08-24 12:41:56 +02:00
Jonas Platte aac6294755 Rename test modules to tests
… for consistency.
2023-08-24 12:28:34 +02:00
Jonas Platte 3c8a59a43a Remove module::* imports 2023-08-24 12:28:34 +02:00
Ivan Enderlin 4e25a8c3c1 chore(cargo): Update ruma. 2023-08-24 12:17:40 +02:00
Ivan Enderlin 3dbc00cd67 feat(ui): Reduce the batch_size of invites in RoomListService.
This patch changes the `batch_size` of the sliding sync list `invites`
for `RoomListService`. Previous value was 100, new value is 20.

For accounts that have a large number of invites, it won't slow the
rendering of `visible_rooms`.
2023-08-24 10:36:04 +02:00
Marco Romano b2a1e3d268 Bump ruma 2023-08-24 07:37:10 +00:00
Jonas Platte 8deb0ff2e1 base: Handle redactions if e2ee is disabled 2023-08-23 17:20:26 +02:00
Jonas Platte 2fb6bdc24c Fix more clippy lints 2023-08-23 17:20:11 +02:00
Jonas Platte 24d2ccd5f0 base: Make BaseRoomInfo::handle_redaction private
It should only be called from RoomInfo::handle_redaction.
2023-08-23 17:19:51 +02:00
Jonas Platte 9fc5a7dc92 base: Add some logging for handle_redaction 2023-08-23 17:19:51 +02:00
Daniel Abramov 6ecd640ad7 Widget API: Initial skeleton 2023-08-23 15:08:51 +00:00
Marco Romano 3bc7b9136e ui: Add support for polls in timeline 2023-08-23 12:57:52 +00:00
Ivan Enderlin 4dbb0a7cc7 fix(ui): Tweak State of RoomListService when session is forced to expire
fix(ui): Tweak `State` of `RoomListService` when session is forced to expire
2023-08-23 13:28:08 +02:00
Ivan Enderlin 2dd1caaeab doc(sdk,ui): Fix typos. 2023-08-23 13:07:24 +02:00
Ivan Enderlin 6736a4a05f Update crates/matrix-sdk-ui/src/room_list_service/mod.rs
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-08-23 13:05:21 +02:00
Ivan Enderlin 8c234f0d0d test(ui): Test that RoomList::expire_sync_session ends up in Error. 2023-08-23 12:13:54 +02:00
Jonas Platte 4df1ee140a Fix clippy lints 2023-08-23 11:36:21 +02:00
Ivan Enderlin 0dacf6edc3 fix(ui): Tweak State of RoomList when session is forced to expire.
Usually, when the sliding sync session expires, it leads the state to
be `Error`, thus some actions (like refreshing the lists) are executed.
However, if the sync-loop has been stopped manually, the state is
`Terminated`, and when the session is forced to expire, the state
remains `Terminated`, thus the actions aren't executed as expected.
Consequently, this patch updates the state to `Error` manually.
2023-08-23 11:24:01 +02:00
Ivan Enderlin 5b28e641c4 Merge pull request #2441 from matrix-org/dependabot/cargo/rustls-webpki-0.101.4
chore(deps): bump rustls-webpki from 0.101.2 to 0.101.4
2023-08-23 09:17:11 +02:00
dependabot[bot] 9bf214925c chore(deps): bump rustls-webpki from 0.101.2 to 0.101.4
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.101.2 to 0.101.4.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.101.2...v/0.101.4)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-22 18:10:40 +00:00
Jonas Platte 0d24bcf6e5 Revert "bindings: Use new uniffi-bindgen build mode"
This reverts commit 329b6c4eb1.
2023-08-22 18:40:20 +02:00
Kévin Commaille e01421a3dd Upgrade Ruma
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-08-22 17:25:02 +02:00
Jonas Platte 329b6c4eb1 bindings: Use new uniffi-bindgen build mode 2023-08-22 11:12:55 +02:00
Jonas Platte ef0549b8b8 xtask: Use camino path types 2023-08-22 11:12:55 +02:00
Doug 60392c299d bindings: Add OIDC support to AuthenticationService
- Use OIDC for logout when appropriate.
- Allow server's that support OIDC but not passwords to work.
- Only sign out users if token refresh is explicitly refused.
- Expose the OIDC account URL.
- Support for RP initiated logout.
2023-08-22 09:06:32 +00:00
Benjamin Bouvier 4493cbf0ac chore: rework Room::sync_up so it's really async 2023-08-21 19:36:33 +02:00
Benjamin Bouvier b7e18352c4 fix: read RoomInfo data at the very last minute before saving it
Also take ownership of the sync lock in write mode, since this operation could run concurrently
to room_joined/room_left events.
2023-08-21 19:36:33 +02:00
Benjamin Bouvier 936b6980c9 chore: move SyncTokenAwareClient to the common test helpers 2023-08-21 19:36:33 +02:00
Benjamin Bouvier e262db3505 test: write an integration test for missing keys during encryption 2023-08-21 19:36:33 +02:00
Benjamin Bouvier 0d67d14201 feat: query keys for newly sync'd members when sending encrypted message 2023-08-21 19:36:33 +02:00
Jonas Platte 78ad6a6530 ui: Remove JSON on RemotEventTimelineItem when it's redacted locally 2023-08-21 15:54:25 +02:00
Jonas Platte a5a541ec98 ui: Improve comment in redaction code
(move it to a more logical place)
2023-08-21 15:54:25 +02:00
Jonas Platte d395648165 ui: Remove outdated comment
The relevant decryption work is already done in a separate async task,
spawned in `TimelineInner::retry_event_decryption_inner`.
2023-08-21 15:00:00 +02:00
Benjamin Bouvier f5ab1084eb fix: temporarily use the pip install method for the setup-matrix-synapse action
Until https://github.com/michaelkaye/setup-matrix-synapse/issues/95 is properly resolved.
2023-08-21 11:54:25 +02:00
Benjamin Bouvier 81daf5c90a test(sliding sync): add test that caused a deadlock before this PR 2023-08-21 11:48:51 +02:00
Benjamin Bouvier c0b18c291d chore: make clippy happy 2023-08-21 11:48:51 +02:00
Benjamin Bouvier 6988bd1e6f feat(sliding sync): remove the response_handling_lock and extend the position's lock responsibilities
In the previous situation, we had two locks with similar responsibilities, the `response_handling_lock`
and the `position` lock. The latter *almost* covered the former's critical zone, albeit for a single
function call, which left room for a deadlock situation (latter taken, then former, then latter).

This removes the former, and extends the critical zone of the latter up to the end of the response handling,
removing the possibility of the deadlock entirely.
2023-08-21 11:48:51 +02:00
Ivan Enderlin 54771eadcf fix(ffi): Fix a keyword conflict with Swift
fix(ffi): Fix a keyword conflict with Swift
2023-08-21 11:35:09 +02:00
Ivan Enderlin 64f3bc674e feat(ui): Create a new normalized_match_room_name filter
feat(ui): Create a new `normalized_match_room_name` filter
2023-08-21 11:27:53 +02:00
Ivan Enderlin b78372d4bb chore(cargo): Update UniFFI. 2023-08-21 11:07:32 +02:00
Ivan Enderlin 102482c6e3 fix(ffi): Fix a keyword conflict with Swift. 2023-08-21 10:32:33 +02:00
Ivan Enderlin 9973d30700 feat(ffi): Implement RoomListEntriesDynamicFilterKind::NormalizedMatchRoomName. 2023-08-21 10:22:06 +02:00
Ivan Enderlin 2821807e14 feat(ui): Create a new normalized_match_room_name filter.
This patch creates a new `normalized_match_room_name` filter for
`RoomListService`.
2023-08-21 10:19:20 +02:00
Ivan Enderlin 14f8b33136 Merge pull request #2425 from matrix-org/jonny/message-content-from-html
Add binding to create message events from HTML
2023-08-21 09:48:35 +02:00
Ivan Enderlin e9a9382b2b RoomInfo: Remove is_encrypted use sliding sync room avatars
RoomInfo: Remove is_encrypted use sliding sync room avatars
2023-08-21 09:43:05 +02:00
jonnyandrew 5497a8de2c Add binding to create message event from HTML 2023-08-18 16:03:03 +01:00
Stefan Ceriu 531d1d9761 Read the room avatar URL from the RoomListService room instead of the SDK room so that DMs are populated correcty 2023-08-18 17:54:23 +03:00
Benjamin Bouvier 88018c259f Revert upgrade to uniffi since it broke generation of swift bindings 2023-08-18 12:07:36 +02:00
Stefan Ceriu 531d8d220d Remove is_encrypted from room info as it's not used and it might do network calls and slow down room list updates 2023-08-18 11:36:01 +03:00
Ivan Enderlin d077892ad4 chore(uniffi): Update uniffi to another branch
chore(uniffi): Update `uniffi` to another branch
2023-08-17 18:29:05 +02:00
Ivan Enderlin cc46417ec5 Merge branch 'main' into hywan/fix-android-uniffi-async-bis 2023-08-17 18:27:54 +02:00
Ivan Enderlin 4d7f951128 chore(cargo): Update UniFFI to main (specific commit). 2023-08-17 18:26:21 +02:00
Ivan Enderlin 92284a353e feat(sdk): SlidingSync is able to “ignore” some errors
feat(sdk): `SlidingSync` is able to “ignore” some errors
2023-08-17 16:50:12 +02:00
Ivan Enderlin 73bb46b5ea Revert "feat(sdk): SlidingSync makes timed out silent."
This reverts commit 9b811009e1.

We have realized that the server might not handle timeouts as expected.
Thus, it's hard to know the difference between network timeout and poll
timeout (resp. the server is unreachable vs. the server has nothing to
respond with). We will come back on this later.
2023-08-17 16:27:12 +02:00
Ivan Enderlin 9b811009e1 feat(sdk): SlidingSync makes timed out silent.
As a sequel of the previous commit (d4cbcd397d), this patch updates
`SlidingSync` to “ignore” timeouts, i.e. timeouts aren't reported to the
caller, and aren't stopping the sync-loop.
2023-08-17 15:37:25 +02:00
Ivan Enderlin d4cbcd397d feat(sdk): SlidingSync is able to ignore some errors.
All errors inside `SlidingSync` are stopping the sync-loop, and errors
are returned to the caller. However, in some situation, some errors
should be ignored, i.e. they should not stop the sync-loop and they
should not be returned to the caller: the sync-loop just continues to
run. This patch does that for `Error::ResponseAlreadyReceived`. More
errors will come.

Why is it annoying? When `matrix_sdk_ui::SyncService` sees an error,
it stops all the sync-loops (`RoomListService`, `EncryptionSync`…) and
restarts them properly. In the case of `Error::ResponseAlreadyReceived`,
this is a waste of time and resources. This error is an error from the
`SlidingSync` point of view, but _not_ from the caller point of view.
2023-08-17 15:35:51 +02:00
Ivan Enderlin 932b9dee6b fix(base): Detect left room in SlidingSyncResponse
fix(base): Detect left room in `SlidingSyncResponse`
2023-08-17 15:32:58 +02:00
Ivan Enderlin 2c9981050a fix(sdk): Preventing starting a new request if the previous didn't finish
fix(sdk): Preventing starting a new request if the previous didn't finish
2023-08-17 15:29:58 +02:00
Ivan Enderlin 2a6fc16549 chore: Use serde::Raw without any feature flag. 2023-08-17 14:30:25 +02:00
Ivan Enderlin 1aef72d105 feat(base): Left room are stored in the leave list in SlidingSync.
This patch updates the `BaseClient::process_sliding_sync` method to put
the `LeftRoom` in the `SyncResponse::leave` list.

To achieve so, this patch updates
`BaseClient::process_sliding_sync_room` to returns `Option<JoinedRoom>`,
`Option<LeftRoom>` and `Option<InvitedRoom>` (previously, it was only
`JoinedRoom` and `Option<InvitedRoom>`).
2023-08-17 14:30:25 +02:00
Ivan Enderlin acc2601c5b feat(base): Look for state events in timeline for SlidingSync.
SlidingSync emits state events inside `required_state`, but _also_
sometimes inside `timeline`! This patch looks for state events inside
both entries.

The rest of the patch is composed of tests.
2023-08-17 14:30:25 +02:00
Jonas Platte 47e7360b04 ffi: Add RoomInfo 2023-08-17 12:49:03 +02:00
Jonas Platte 9b803eda12 ffi: Merge impl blocks 2023-08-17 12:49:03 +02:00
Ivan Enderlin d946664cf0 doc(sdk): Fix a typo. 2023-08-17 11:56:21 +02:00
Ivan Enderlin f9f12c2b89 fix(sdk): Preventing starting a new request if the previous didn't finish.
Imagine the following scenario:

A request $R_1$ is sent. A response $S_1$ is received and is being
handled. In the meantime, the sync-loop is instructed to skip over any
remaining work in its iteration and to jump to the next iteration. As a
consequence, $S_1$ is detached, but continues to run. In the meantime, a
new request $R_2$ starts. Since $S_1$  has _not_ finished to be handled,
the `pos` isn't updated yet, and $R_2$ starts with the _same_ `pos`
as $R_1$.

The impacts are the following:

1. Since the `pos` is the same, even if some parameters are different,
   the server will reply with the same response. It's a waste of time
   and resources (incl. network).
2. Receiving the same response could have corrupt the state. It has been
   fixed in https://github.com/matrix-org/matrix-rust-sdk/pull/2395
   though.

Point 2 has been addressed, but point 1 remains to be addresed. This
patch fixes point 1.

How? It changes the `RwLock` around `SlidingSyncInner::position` to
a `Mutex`. An `OwnedMutexGuard` is fetched by locking the mutex when
the request is generated (i.e. when `pos` is read to be put in the new
request). This `OwnedMutexGuard` is kept during the entire lifetime
of the request extend to the response handling. It is dropped/released
when the response has been fully handled, or if any error happens along
the process.

It means that it's impossible for a new request to be generated and to
be sent if a request and response is running. It solves point 1 in case
of successful response, otherwise the `pos` isn't updated because of
an error.
2023-08-17 10:09:21 +02:00
Ivan Enderlin 2718176eab chore(sdk): Move response_handling_lock inside SlidingSyncInner.
This patch moves `SlidingSync::response_handling_lock` inside
`SlidingSyncInner`. There is no reason why it's stored inside
`SlidingSync`.
2023-08-17 09:16:25 +02:00
Ivan Enderlin db9012a45e feat(base): Improve Client::deserialize_events.
This patch first off renames `Client::deserialize_events` as
`Client::deserialize_state_events`. Then, this patch initially updated
the return type of this method from `Vec<Option<_>>` to `Vec<_>` to
filter out events that failed to deserialize. The patch ultimately
updates the return type of this method to `Vec<(Raw<_>, _)>`, so that
the raw state events that map to the state event are collected too (this
is required for making `Client::handle_state` to work correctly if an
event failed to deserialized). Finally, the rest of the patch updates
the code accordingly.
2023-08-16 11:29:35 +02:00
Kévin Commaille 0dac5080c6 experimental: Expose an OpenID Connect API
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-08-16 10:39:18 +02:00
Ivan Enderlin 6c2d596603 test(sdk): Test members count.
This patch improves some existing tests, and adds more test for members
count.
2023-08-14 18:04:41 +02:00
Ivan Enderlin 758c3f7901 chore(ui): Improve error description for Error::SlidingSync
chore(ui): Improve error description for `Error::SlidingSync`
2023-08-14 15:33:39 +02:00
Ivan Enderlin bbe4df9cd6 chore(ui): Improve error description for Error::SlidingSync.
`matrix_sdk_ui::room_list_service::Error` has a `SlidingSync` variant to
report errors from `matrix_sdk::sliding_sync::Error` (to be more exact,
from `matrix_sdk::Error::SlidingSync`).

This patch updates the error message from `SlidingSync failed` to
`SlidingSync failed: <explanation>`, where `<explanation>` is the
`Display` representation of the inner error.

It will help to provide more details to the end-user when looking at
logs.
2023-08-14 15:03:38 +02:00
Ivan Enderlin 3b8f0c9a60 chore(ui): Raise a trace log into an error
chore(ui): Raise a `trace` log into an `error`
2023-08-14 14:42:25 +02:00
Ivan Enderlin b9d74d3643 feat(ui): Room::latest_event returns the Timeline local event if any
feat(ui): `Room::latest_event` returns the `Timeline` local event if any
2023-08-14 13:56:51 +02:00
Ivan Enderlin 061f8534c8 doc(ui): Update the comment of Room::latest_event. 2023-08-14 13:36:08 +02:00
Ivan Enderlin 6a7caa7257 Revert "feat(ui): Room::latest_event uses Timeline if it exists."
This reverts commit 2290bae942.
2023-08-14 13:27:56 +02:00
Ivan Enderlin f937920007 chore(ui): Raise a trace log into an warning.
The issue https://github.com/matrix-org/sliding-sync/issues/3 has been
fixed. It's safe to raise the `trace!` into an `warn!` now.
2023-08-14 13:24:28 +02:00
Ivan Enderlin 924033ed9c test(ui): Improve the remote_echo_full_trip test
test(ui): Improve the `remote_echo_full_trip` test
2023-08-14 13:23:02 +02:00
Ivan Enderlin c192343495 test(ui): Improve the remote_echo_full_trip test.
This patch improves the `remote_echo_full_trip` `Timeline` test to
ensure that until the event reaches the `Sent` state, it is indeed a
local echo.
2023-08-14 12:54:45 +02:00
Damir Jelić 4643bae284 Eliminate a race condition in the Room::request_encryption_state method
The Room::request_encryption_state method employs a DashMap to uphold a
lock, facilitating the de-duplication of requests directed to the server.

The de-duplication logic involves creating a fresh Mutex and embedding
it into the DashMap through these stages:

    1. Generate a new de-duplication mutex.
    2. Insert a mutex copy into the DashMap.
    2. Acquire the mutex.

Due to DashMap's limitation of enabling map locking solely during
insertion (step 1), a race condition emerges. Consequently, multiple
invocations of the Room::request_encryption_state method might
concurrently endeavor to insert the de-duplication mutex.

This commit removes the chance of such a race. It substitutes the
DashMap with a combination of a mutex and a BTreeMap. This adaptation
permits us to lock the map throughout all three specified operations.
2023-08-11 13:58:12 +02:00
Damir Jelić f3dd161b3a Resolve a bug causing incorrect results in Room::is_encrypted
This commit addresses a bug in the Room::is_encrypted functionality.
The issue stems from the Room::request_encryption_state method, which
Room::is_encrypted relies on. This method incorporates a de-duplication
mechanism to ensure that only a single request for the m.room.encryption
state event is made to the server.

Due to this de-duplication mechanism, Room::request_encryption_state
follows two code paths. One path receives the state event from the
server, while the other path merely waits for the first path to complete.

The primary goal of the Room::request_encryption_state method is to
furnish the requested state event. However, because the second code path
doesn't receive any content, it returns an Option.

The problem arises when Room::is_encrypted evaluates this Option. It
erroneously determines that if the Option is None, encryption remains
inactive for the room.

To rectify this, the commit proposes that Room::is_encrypted analyze the
information stored in the in-memory RoomInfo, which is maintained by the
Room::request_encryption_state method. This approach mirrors the existing
behavior of Room::is_encrypted when it processes the code path where the
m.room.encryption state event has already been retrieved.
2023-08-11 13:58:12 +02:00
Damir Jelić bd1b6e7a27 Instrument the Room::send_raw method 2023-08-11 13:58:12 +02:00
Damir Jelić eae8437321 Add a test for the Room::is_encrypted method 2023-08-11 13:58:12 +02:00
Jonas Platte d14e23a676 ffi: Remove tracing callsite column, make line optional 2023-08-11 12:10:58 +02:00
Jonas Platte f7d52dfdc1 ffi: Make tracing more flexible
… at the expense of some performance.
2023-08-11 12:10:58 +02:00
Benjamin Bouvier 6e62569b8a feat(sync service): don't intertwine the state of both sliding syncs (#2362)
## Feature

There are now three tasks running in the sync service:

- the room list sliding sync task
- the encryption sync task
- a new scheduler task, that listens to messages sent by both of the previous tasks, and will take care of cleaning up tasks, stopping the services, and setting states after it received a message.

When any of the sliding sync fails, it sends a message to the scheduler task, indicating why it stopped (error or not, was it an expired session or not). Then the scheduler task will do any necessary cleanup.

`stop()` (née `pause()`) can now make use of that scheduler task as well, by sending a report requesting to stop both tasks and services. Responsibilities are now cleanly split: in particular, I like it much better that the room list task doesn't have to stop the encryption sync itself, since it's not really its duty. (And this avoids lots of code duplication to cleanup tasks and stop services.)

## Testing

This also tests the `SyncService` states. Unfortunately it's not perfectly deterministic in two places:

- we can't predict how many requests will be sent to the server (although, with the mocking server responding in 50ms, and considering a waiting time of e.g. 300ms, it should send at least two requests).
- the test `pause()` and re`start()` the sync service at some point, and then we can't guess what the next `pos` will be, in any of the syncs: it could either be the previous value (if we aborted while processing the previous response), or the next value (meaning we could finish processing the sliding sync response).

Still, it confirms at least that pausing and resuming work as expected.

---

Fixes #2382
2023-08-11 08:55:48 +00:00
Jonas Platte 5943f5f7f3 sdk: Set content-length header when streaming HTTP request body 2023-08-11 09:21:58 +02:00
Alfonso Grillo 364a4ae5a9 ffi: Add create-poll API 2023-08-10 15:38:17 +00:00
Ivan Enderlin 0372467288 chore(uniffi): Update uniffi to another branch.
This patch switches UniFFI from
https://github.com/mozilla/uniffi-rs/pull/1684 to
https://github.com/mozilla/uniffi-rs/pull/1697.
2023-08-10 17:33:36 +02:00
Benjamin Bouvier 159786fe36 feat(notification client): bump sliding sync timeouts (#2403)
The timeouts were a bit too agressive, according to some user logs, resulting in failing to
load the event mentioned in the notification.

Here's the rationale for the new timeouts: we're only limited by the iOS process which has *at
most* 30 seconds to process a notification.

- We're running at most 3 requests of the notification sliding sync, so that will be (1+3)*3 = 12
seconds allocated for that.
- If we've found an event but it required decryption, we're running the encryption sync up to
2 times, (3+4) seconds each => 14 seconds.

At most we're eating up 26 seconds of the entire time, leaving some ballast for the rest of
the program.
2023-08-10 17:31:14 +02:00
Ivan Enderlin e9d6a9bfd7 chore: Remove unnecessary clones
chore: Remove unnecessary clones
2023-08-10 16:51:41 +02:00
Ivan Enderlin 361bc18757 fix(ui): Add m.room.member: $LAZY in the require states of visible_rooms
fix(ui): Add `m.room.member: $LAZY` in the require states of `visible_rooms`
2023-08-10 16:24:58 +02:00
Nicolas Mauri ac42d07de7 sdk+ffi: in notification settings, replace members_count by is_one_to_one for more clarity 2023-08-10 16:19:11 +02:00
Ivan Enderlin 2290bae942 feat(ui): Room::latest_event uses Timeline if it exists.
This patch optimises the previous patch by simplifying the use of
`Timeline`. If the `Timeline` exists, let's return the `latest_event`
every time: whether it is a remote _or_ a local event.
2023-08-10 16:00:06 +02:00
Ivan Enderlin e0163e67be feat(ui): Room::latest_event returns the Timeline local event if any.
This patch updates `Room::latest_event` to return the `Timeline` local
event if any.

First off, it starts by checking if a `Timeline` exists. It won't create
it if it doesn't exist! Second, it checks whether a latest event exists.
Finally it checks whether it's a local event.

This patch also updates the tests accordingly.
2023-08-10 15:59:50 +02:00
Ivan Enderlin e8cd21034b chore: Remove unnecessary clones.
The types used here are not implementing `Clone`, so calling `clone`
on them` copies the reference, which does not do anything and can be
removed.
2023-08-10 15:15:06 +02:00
Ivan Enderlin f64a46a2be Merge pull request #2396 from matrix-org/nicolas/notification_settings_user_defined_room_rules
sdk+ffi: Get the user-defined notification mode for a room and all rooms for which a user-defined rule exists.
2023-08-10 14:11:35 +02:00
Ivan Enderlin 0af918b8a7 feat(sdk): Skip Sliding Sync Response if it's been received already
feat(sdk): Skip Sliding Sync `Response` if it's been received already
2023-08-10 13:35:21 +02:00
Ivan Enderlin c5d2181549 test(sdk): Ensure that avatar is serialized as expected in FrozenSlidingSyncRoom
test(sdk): Ensure that `avatar` is serialized as expected in `FrozenSlidingSyncRoom`
2023-08-10 13:30:40 +02:00
Ivan Enderlin 2b938e3f03 doc(sdk): Fix a typo.
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-08-10 13:17:15 +02:00
Ivan Enderlin 817690206c feat(sdk): Create SlidingSync::expire_session.
For the sake of clarity, this patch extracts some code into its own
`SlidingSync::expire_session`.
2023-08-10 12:14:42 +02:00
Jonas Platte 4bfcc6669d Use simpler construction functions for tokio::broadcast::Sender 2023-08-10 12:04:40 +02:00
Jonas Platte f8eefadb2d Upgrade tokio to 1.30 2023-08-10 12:04:40 +02:00
Richard van der Hoff f51bc47949 Fix rust doc on IndexedDBStore (#2394)
it's not in-memory
2023-08-10 11:47:56 +02:00
Ivan Enderlin 5d8b0c1a0d feat(sdk): Save positions at the end of handle_response. 2023-08-10 11:31:18 +02:00
Nicolas Mauri 8c6e3949e0 sdk+ffi: allow to get all room IDs for which a user-defined rule exists. 2023-08-10 10:02:11 +02:00
Nicolas Mauri 0a52fc895e ffi: Allow to get the user-defined notification mode for a room 2023-08-10 09:51:10 +02:00
Ivan Enderlin 51c25a4456 feat(ui): Implement RoomList::entries_with_dynamic_filter
feat(ui): Implement `RoomList::entries_with_dynamic_filter`
2023-08-10 08:28:43 +02:00
Ivan Enderlin d20e82380a test(ui): Adjust pos. 2023-08-09 18:07:18 +02:00
Ivan Enderlin 1f7ce2893b feat(sdk): Skip Sliding Sync Response if it's been received already.
A Sliding Sync `v4::Response` contains a `pos` value. It helps to identify
progress during several requests/responses. If two requests with the
same `pos` are sent, the server **must** reply with the same response,
as defined in the specification.

The corollary is: If a response contains a `pos` that has already
been received, the client **must** ignore it, otherwise it can create
duplications. For example, let a response containing sync operations,
like `DELETE` or `INSERT`, with indexes: if this pair of operations are
repeated twice with the same index, it creates a broken state.

To avoid this behaviour, this patch stores the last 20 position markers
received from the server. If a response contains a `pos` that has
already been received, a (new) error is returned. As with all the other
errors, the sync-loop is stopped, and must restarted. The past positions
survive to this restart, as for the rest of the state.

When the server replies with a `M_UNKNOWN_POS`, the `pos` and the
`past_positions` are all cleared.
2023-08-09 17:18:29 +02:00
Ivan Enderlin b1b0641150 test: Ensure that avatar is serialized as expected. 2023-08-09 15:30:26 +02:00
Ivan Enderlin 696e10bdad chore: Use async_test instead of tokio::test. 2023-08-09 15:30:13 +02:00
Ivan Enderlin 0f94f93080 chore: When LSP is broken… :-) 2023-08-09 15:18:24 +02:00
Ivan Enderlin 55ba580c0d chore: Simplify Fn declaration. 2023-08-09 15:08:05 +02:00
Ivan Enderlin da7e05f18f feat(ffi): Use an enum to set dynamic filter.
This patch removes
`RoomListEntriesDynamicFilter::set_with_fuzzy_match_pattern` and
replaces it by a single `::set` method. It takes a new enum as
parameter: `RoomListEntriesDynamicFilterKind`. This enum has a
`FuzzyMatchRoomName` variant to simulate the removed method. It also
adds the `All` variant, to represent the `all` filter.
2023-08-09 15:00:09 +02:00
Ivan Enderlin f35275f4fc feat(ui): Implement a new filter: all.
This patch implements a new `all` filter.
2023-08-09 14:51:15 +02:00
Ivan Enderlin 90682270ae feat(ffi): Implement RoomList::entries_with_dynamic_filter.
First, this patch makes `RoomList::entries` infallible.

Second, this patch implements `RoomList::entries_with_dynamic_filter`.
2023-08-09 14:16:23 +02:00
Ivan Enderlin 3c46a1019b test(ui): Update some tests about fuzzy matcher.
These test cases are more easy to understand than the previous one if
you ask me.
2023-08-09 14:15:10 +02:00
Ivan Enderlin 61f481c126 test(ui): Test RoomList::entries_with_dynamic_filter.
This patch updates the tests to ensure `entries_with_dynamic_filter`
works as expected.
2023-08-09 13:53:14 +02:00
Ivan Enderlin bd2f5119db feat(ui): Rename entries_filtered to entries_with_static_filter.
Because it makes more sense.
2023-08-09 13:52:55 +02:00
Jonas Platte 1b8768becc Use AsyncCell instead of mpsc channel 2023-08-09 13:24:39 +02:00
Damir Jelić 3d3021efc0 Expose bindings to manage dehydrated devices 2023-08-09 12:32:48 +02:00
Damir Jelić 64ca96543e Initial support for dehydrated devices
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-08-09 12:32:48 +02:00
Damir Jelić 8ce3b56180 Allow an Olm Account to generate its own device id 2023-08-09 12:32:48 +02:00
Damir Jelić 3e2f531caa Split out the receive_sync_changes method into a helper
This splits the method out so the bigger chunks doesn't persist the
changes in the store.

This will be useful if we need to hijack the changes and persist them in
a different store.
2023-08-09 12:32:48 +02:00
Jonas Platte 56f771a347 ui: Remove unnecessary boxing 2023-08-09 10:46:13 +02:00
Ivan Enderlin 1ab0d2081a doc(ui): Add inline comments. 2023-08-09 10:01:24 +02:00
Ivan Enderlin 90c30e4058 ui: Add RoomList::entries_with_dynamic_filter 2023-08-09 10:01:15 +02:00
Ivan Enderlin 752e814168 fix(ui): Add m.room.member: $LAZY in the require states of visible_rooms.
This patch tries to fix https://github.com/vector-im/element-x-
ios/issues/1204 by adding the following required states in the
`visible_rooms` sliding sync list: `m.room.member: $LAZY`.
2023-08-09 09:11:20 +02:00
Benjamin Bouvier 80c9464f1e chore: fix typo in cargo xtask kotlin doc comment (#2387) 2023-08-08 16:00:20 +02:00
Benjamin Bouvier 625acb056a feat(ffi): add an optional file layer for tracing (#2384)
* feat(ffi): add an optional file logger

Also makes logging to stdout/logcat optional.

* WIP: stupidly duplicate code 🤷

* ffi: Get rid of duplication in tracing initialization

* feat: add OtlpTracingConfiguration too

* feat: log either to stdout on non-android or logcat on android

---------

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-08-08 12:37:32 +00:00
Nicolas Mauri ff9923c6a6 Allow to define the default notification mode for a given room type (#2369)
* Add a function to define the default notification mode for a given kind of room

* Code refactoring

* sdk+ffi: code refactoring
2023-08-08 14:20:17 +02:00
Kévin Commaille 1680a7d4d6 sdk: Set the refresh token lock if refresh token is missing
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-08-08 12:16:03 +02:00
Kévin Commaille 302cff6ba9 sdk: Make RefreshTokenError authentication API-agnostic
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-08-08 12:16:03 +02:00
Ivan Enderlin dc3636d766 feat(ui): Turn on cached list for SlidingSync in RoomListService
feat(ui): Turn on cached list for `SlidingSync` in `RoomListService`
2023-08-08 11:29:51 +02:00
Ivan Enderlin 87f7fc7367 chore: Update Cargo.lock. 2023-08-07 17:48:17 +02:00
Ivan Enderlin 741bb1c12d chore: Update Cargo.lock. 2023-08-07 17:20:19 +02:00
Ivan Enderlin 7e371a642a feat(ui): Turn on cached list for SlidingSync in RoomListService.
Now is a good time to re-enable the cache :-).
2023-08-07 15:54:08 +02:00
Ivan Enderlin 1c01a146b1 chore: Update Cargo.lock. 2023-08-07 12:10:44 +02:00
Jonas Platte 074fd8b335 Upgrade opentelemetry crates 2023-08-06 12:02:41 +02:00
Benjamin Bouvier 5c74a597eb nit: prefer using assert_matches! in tests 2023-08-04 17:41:47 +02:00
Benjamin Bouvier dd3cab9409 fix: don't try /context when a notification has been filtered out 2023-08-04 17:41:47 +02:00
Benjamin Bouvier aea0b00ac2 chore: add comments to get_notification about the return type 2023-08-04 17:41:47 +02:00
Benjamin Bouvier e1c928f121 fix: compute whether a room is a DM before joining it
If we were invited and joined a room, then the computation of is_direct() was happening after
joining, and depended on the presence of a global account event of type "m.direct". This event
is added by the "set_is_direct()" call thereafter, so this couldn't ever happen.

This fixes it by computing the is_direct field *before* joining the room, and then marking the
room as a DM based on that.
2023-08-04 17:41:47 +02:00
Benjamin Bouvier 7676ff509f nit: remove else after return 2023-08-04 17:41:47 +02:00
Benjamin Bouvier 10f709450e tests(notification): add integration tests for notification events 2023-08-04 17:41:47 +02:00
Jonas Platte 4ebc3d70ad Hide test helpers from documentation 2023-08-03 21:39:56 +02:00
Jonas Platte 1679669376 Remove the 'testing' feature from matrix-sdk-ui
At the expense of slightly increasing our public API, but we can always
deprecate things.
2023-08-03 21:39:56 +02:00
Jonas Platte edc6428e69 Fix clippy warnings 2023-08-03 21:39:56 +02:00
Kévin Commaille a434b97c54 sdk: Don't derive (De)serialize for AuthSession
It turns out not all authentication API sessions (i.e. OIDC) are fully (de)serializable.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-08-03 20:47:30 +02:00
Ivan Enderlin 6c0f24b657 chore: Update UniFFI fork
chore: Update UniFFI fork
2023-08-03 15:42:30 +02:00
Ivan Enderlin 2481e1f97e chore: Update UniFFI fork. 2023-08-03 15:36:52 +02:00
Benjamin Bouvier bf754667d9 chore: get rid of Client::inherit_session
It does the same as `restore_session` now. Thanks @zecakeh for finding this out!
2023-08-03 14:10:32 +02:00
Nicolas Mauri 61d4d5b096 Fix an arithmetic overflow 2023-08-02 18:25:35 +02:00
Jonas Platte ea03b821fd ffi: Use UniFFI fork with future cancellation support
Upstream PR: https://github.com/mozilla/uniffi-rs/pull/1684
2023-08-02 16:16:24 +02:00
Jonas Platte f1b4b80460 ffi: Don't spawn tokio tasks for add_timeline_listener, send_attachment 2023-08-02 16:16:24 +02:00
Jonas Platte b39d06353a Revert "ffi: Spawn tokio tasks for the remaining async fns"
This reverts commit eb4dab138e.
2023-08-02 16:16:24 +02:00
Jonas Platte 34be01ecf2 Revert "ffi: Remove async from a few functions"
This reverts commit fc3883d08e.
2023-08-02 16:16:24 +02:00
Jonas Platte 0f6dd644b5 Upgrade async-rx 2023-08-01 17:31:29 +02:00
Jonas Platte 7d9d600eda ui: Only lock TimelineInnerState once per back-pagination response 2023-08-01 17:31:29 +02:00
Jonas Platte 8ac0f099f6 ui: Exclude Debug implementation from coverage 2023-08-01 17:31:29 +02:00
Jonas Platte 640e5fbacf ffi: Use batched timeline subscription 2023-08-01 17:31:29 +02:00
Jonas Platte 9a8c6249bb ui: Add Timeline::subscribe_batched 2023-08-01 17:31:29 +02:00
Jonas Platte a65cff01f7 ui: Create subscribe integration test sub-module 2023-08-01 17:31:29 +02:00
Benjamin Bouvier 80243615c4 chore(test): make the clear_with_echoes test more deterministic 2023-08-01 15:57:12 +02:00
Benjamin Bouvier a6aaf164aa chore(sliding sync): add logs for the limited flag computation
This should help us debug issues with false negatives.
2023-08-01 15:57:12 +02:00
Benjamin Bouvier ace282126f ffi(notifications): include full timeline event again in the NotificationEvent
The full timeline event contains both the timestamp (requested in #2361) and the sender id;
now the sender id for the invite can also be contained in there, minimizing the amount of copying we're doing in the
FFI code.

Fixes #2361.
2023-08-01 15:09:18 +02:00
Nicolas Mauri 6961a7fb36 Fix is_user_mention_enabled and is_room_mention_enabled (#2357)
* Fix is_user_mention_enabled, is_room_mention_enabled

* Fix: XXX comments in UnitTests

* Update comments

* UnitTests: code refactoring
2023-08-01 14:43:32 +02:00
Jonas Platte f6d4357d52 Update Cargo.lock 2023-08-01 10:59:40 +02:00
Jonas Platte d05bd4bf2d ui: Deduplicate in-reply-to fetching 2023-08-01 09:29:18 +02:00
Benjamin Bouvier a00ff293f1 chore: apply code review suggestions again 2023-07-31 15:02:04 +02:00
Benjamin Bouvier 505267503b chore: add a comment explaining why we need a mutex 2023-07-31 15:02:04 +02:00
Benjamin Bouvier c6f00cb633 chore(clippy): use an async mutex 2023-07-31 15:02:04 +02:00
Benjamin Bouvier 6cc4364684 chore: move comment around 2023-07-31 15:02:04 +02:00
Benjamin Bouvier d165ec8646 feat: sequentialize calls to get_notification_with_sliding_sync
There must be at most one sliding sync notification per connection id. While we could use multiple ids, it seems bad
to do so, in terms of proxy performance; so this makes it so that there is at most once notification being handled
at a time.
2023-07-31 15:02:04 +02:00
Benjamin Bouvier 30a662fdc8 chore: slim down the enum variants of NotificationEvent according to popular request 2023-07-31 15:02:04 +02:00
Benjamin Bouvier 9126937901 feat: use /context query if sliding sync failed 2023-07-31 15:02:04 +02:00
Benjamin Bouvier dec5c6bc2d feat(sliding sync): save the to-device token in OlmMachine::receive_sync_changes 2023-07-31 12:24:55 +02:00
Benjamin Bouvier 719683d284 feat: allow storing a next_batch_token in the crypto stores 2023-07-31 12:24:55 +02:00
Benjamin Bouvier e3f7b9676d chore: fix Changes::is_empty() 2023-07-31 12:24:55 +02:00
Benjamin Bouvier 745bb09e38 chore: remove unused token in KeysQueryRequest 2023-07-31 12:24:55 +02:00
Benjamin Bouvier 4c4a77da34 chore: group all the arguments to receive_sync_changes in a single struct 2023-07-31 12:24:55 +02:00
Jonas Platte 33629833bd ui: Keep local echoes when clearing timeline
This is especially important for ones that failed to send (or ones that
fail post timeline clearing), since there is no way to retry them
otherwise.
2023-07-31 12:12:35 +02:00
Benjamin Bouvier 4c7e10cbf3 chore: add messages for base-client processing 2023-07-31 11:31:12 +02:00
Benjamin Bouvier dcfea138ea chore: tweak sliding sync tracing context
- include the conn_id at the stream level, not the sync_once level (that's a child scope of the stream)\
- also include whether e2ee is enabled at this level
- shorten most static logs
- remove duplicate "sending request" logs
2023-07-31 11:31:12 +02:00
Benjamin Bouvier eb7e01e8b1 chore: lower log-levels when processing sliding sync in sdk-base 2023-07-31 11:31:12 +02:00
Damir Jelić c22f6da909 Add a js feature to the qrcode crate 2023-07-31 10:08:53 +02:00
Damir Jelić 4eba72774f Bump vodozemac 2023-07-31 10:08:53 +02:00
Jonas Platte d149782e6a ui: Reuse ID when replacing UTD after retrying decryption 2023-07-31 09:53:58 +02:00
Jonas Platte 0c3d46eb1e ui: Move some functions into new timeline::util module 2023-07-31 09:53:58 +02:00
Jonas Platte 7dfe8cedbb ui: Move timeline item creation helpers into TimelineInnerState 2023-07-31 09:53:58 +02:00
Jonas Platte e5f021f5cf ui: Simplify definition of TimelineEventHandler
Take a mutable reference to TimelineInnerState, instead of individual
mutable references to its fields.
2023-07-31 09:53:58 +02:00
Jonas Platte 05c5fdd839 ui: Move Flow into EventHandlerContext 2023-07-31 09:53:58 +02:00
Jonas Platte c15ac3978e ui: Rename EventHandlerMetadata to EventHandlerContext 2023-07-31 09:53:58 +02:00
Jonas Platte 4b2cc20c6b ui: Move TimelineInner::*_internal to TimelineInnerState 2023-07-31 09:53:58 +02:00
Jonas Platte 18590c8813 ui: Move update_timeline_reaction to TimelineInnerState 2023-07-31 09:53:58 +02:00
Jonas Platte b78abd62c0 ui: Move TimelineInnerState into its own module 2023-07-31 09:53:58 +02:00
Jonas Platte b425812fd8 ui: Remove explicit default generic argument 2023-07-31 09:53:58 +02:00
Benjamin Bouvier f57b6f5491 chore(test): don't use the same database name in multiple independent tests
This should make the test less flaky.
2023-07-28 19:17:01 +02:00
Benjamin Bouvier 18e283fee9 chore: add TODO explaining that this field should be put back into the OlmMachine later 2023-07-28 15:21:12 +02:00
Benjamin Bouvier a3291a3627 fix: store the crypto store known generation in the Client, not the OlmMachine 2023-07-28 15:21:12 +02:00
Benjamin Bouvier deb8434ee9 test: add a regression test for the spurious crypto store regeneration 2023-07-28 15:21:12 +02:00
Damir Jelić 63ce957843 fix: don't rely on having sessions in cache priori to encrypting a message 2023-07-28 15:06:12 +02:00
Benjamin Bouvier 819b46f2fb test: add regression test for invalidating the OlmMachine while sending a message 2023-07-28 15:06:12 +02:00
Marco Romano 5c71087b9c Upgrade Ruma
This is to pave the way to the upcoming "polls" work.
2023-07-28 08:38:50 +00:00
Jonas Platte d865665420 ffi: Replace tracing-android by paranoid-android 2023-07-27 18:25:15 +02:00
Jonas Platte 5f5028ddd0 ffi: Remove redundant dependency specification 2023-07-27 18:25:15 +02:00
Jonas Platte 8703fea24f ffi: Simplify OTLP tracing initialization 2023-07-27 18:25:15 +02:00
Benjamin Bouvier ab363aa420 chore: slim down UpdateSummary 2023-07-27 17:21:36 +02:00
Jonas Platte b66cd58a60 ui: Reduce work for updating sender profiles
… we should not be fetching the profile if it's already set.
2023-07-27 16:45:57 +02:00
Ivan Enderlin 7892b8b74a feat(sdk+ui+ffi): Implement (SlidingSyncRoom|Room|RoomListItem)::avatar_url
feat(sdk+ui+ffi): Implement `(SlidingSyncRoom|Room|RoomListItem)::avatar_url`
2023-07-27 16:33:33 +02:00
Jonas Platte fc3883d08e ffi: Remove async from a few functions
… to hopefully work around current issues.
2023-07-27 12:37:02 +02:00
Ivan Enderlin c2a8fbd3c9 feat(ui): Implement the “fuzzy match room name” filter
feat(ui): Implement the “fuzzy match room name” filter
2023-07-27 12:32:47 +02:00
Andrew Ferrazzutti 53668d764c Return a KeysBackupRequest instead of the more generic OutgoingRequest 2023-07-27 12:12:08 +02:00
Ivan Enderlin 936a2ee25b chore(sdk): Remove one TODO in Sliding Sync
chore(sdk): Remove one `TODO` in Sliding Sync
2023-07-27 10:37:45 +02:00
Benjamin Bouvier 1f10af9fa9 chore(encryption): replace some AuthenticationRequired with NoOlmMachine
Even if the two issues are likely caused by the same root cause (the user not being
authenticated), they should be used in different contexts, in my understanding:

- the authentication required error should happen only during HTTP requests
- the absence of olm machine should be signalled when we try to get one and it's not been initialized yet

This has caused a bit of confusion when looking at debug traces today, so this patches fixes it.
2023-07-27 10:36:57 +02:00
Ivan Enderlin 38a8ad0a66 chore(ci): Make typos happy. 2023-07-27 10:10:45 +02:00
Ivan Enderlin d1d6bcdcab doc(ui): Add missing documentation. 2023-07-27 10:10:45 +02:00
Ivan Enderlin 3e93bdbc3f feat(ui): Normallize strings when doing fuzzy matching. 2023-07-27 09:20:43 +02:00
Ivan Enderlin 63ca82c66c feat(ui): Implement the “fuzzy match room name” filter.
WIP
2023-07-26 18:22:14 +02:00
Ivan Enderlin 0c16ff1ae7 chore(cargo): Update ruma. 2023-07-26 16:38:23 +02:00
Ivan Enderlin a8e5d3ab17 feat(ffi): Update RoomListItem::avatar_url.
This patch updates `RoomListItem::avatar_url` to use
`matrix_sdk_ui::room_list_service::Room::avatar_url` instead of
`matrix_sdk::Room::avatar_url`.

This patch also moves `avatar_url` before `is_direct` (so that it's the
same order as other places in the code).
2023-07-26 16:38:23 +02:00
Chris Smith af44ac6be4 ffi: Define API stub for m.poll.start and m.poll.end 2023-07-26 14:26:03 +00:00
Ivan Enderlin 38d28e9aa0 feat(ui): Implement Room::avatar_url.
This patch implements `Room::avatar_url`. It tries to calculate
the best avatar URL as much as possible. It's either the URL from
`SlidingSyncRoom::avatar_url` or from `Room::avatar_url`.
2023-07-26 16:06:11 +02:00
Ivan Enderlin 62a203f41e feat(sdk): Implement SlidingSyncRoom::avatar_url.
Based on https://github.com/ruma/ruma/pull/1607, this patch adds
support for `avatar` from a sliding sync response. This patch implements
`SlidingSyncRoom::avatar_url` to get the avatar URL of a sliding sync
room.
2023-07-26 16:06:11 +02:00
Ivan Enderlin 15a6861b8c chore(sdk): Remove one TODO.
The batch subscriber exists in `matrix_sdk_ui::RoomList` (https://
github.com/matrix-org/matrix-rust-sdk/pull/2322) instead of being added
here.

We must keep the observable capacity to 4096, but the `TODO` is no
longer relevant.

Why keeping the capacity to 4096? Because if the batch subscriber (in
`RoomList`) isn't “listened” quickly, we don't want to get a `Reset`.
2023-07-26 15:24:24 +02:00
Ivan Enderlin 163d8ca517 feat(ui): Batch the streams returned by RoomList::entries and RoomList::entries_filtered.
feat(ui): Batch the streams returned by `RoomList::entries` and `RoomList::entries_filtered`.
2023-07-26 15:18:43 +02:00
Ivan Enderlin efd1d1e9d2 chore(cargo): Use latest version of async-rx. 2023-07-26 14:25:50 +02:00
Ivan Enderlin 8a21a8a6da chore(ui): Address some feedbacks. 2023-07-26 14:19:17 +02:00
Ivan Enderlin 2302a7b377 feat(ui): Use Subscriber<State> to simply drain the batch subscriber for entries.
This patch brings a nice code simplification.

Instead of creating a new `Stream` with `tokio` based on
`Subscriber<State>`` to drain the batch subscriber for
`RoomList::entries` and `::filtered_entries`, we can _simply_ use
`Subscriber<State>` directly! It removes one dependency: `tokio-
stream`, and remove possible issues with the broadcast channel
`tokio::sync::broadcast`. The code is much simpler and straighforward.
2023-07-26 14:07:46 +02:00
Benjamin Bouvier 7469d1c7d8 chore: remove all experimental features on the UI crate
As discussed, we think the entire UI crate should be considered experimental. We've also
observed a proliferation of feature flags there (many of those are my wrong doings, sorry).
Since the one internal user (FFI) of that crate enabled all experimental features, it seems
fine to make them all default, while not providing any extra stability guarantee based on that
action.
2023-07-26 13:35:40 +02:00
Benjamin Bouvier 2cec3b0c45 feat: Run a SlidingSync when retrieving notifications to get more information (#2252)
* feat: run a room sliding sync upon receiving a notification, to get its full content

* test: add test for the new sliding-sync in notifications \o/

* fix: try to get the push rules *after* a possibly-successful event decryption

* feat: set `is_noisy` only if we could build a push context, and test it

* feat: expose the `legacy_get_notification` in the FFI layer

* feat: retrieve events with a `/context` query

* fix: also request the client's user id's member information to get their display name

* feat: include the list of invites in the notification sliding sync

* feat: repeat the query multiple times if the event hasn't been immediately found

* chore: simplify retrying decryption

* chore: fail the sliding sync when fetching a notification if not using a memory store

* chore: update test expectations + sort invites by recency

* chore: cargo fmt

* chore: simplify getting push actions

Either they were already available in the timeline event if we had to re-run decryption, or
we manually compute them. (Previous comment was incorrect, the `push_actions` are now optional
because of another PR of yours truly.)

* fixup! chore: fail the sliding sync when fetching a notification if not using a memory store

* feat: try to handle invites correctly

* chore: build a local client with an in-memory store instead of reusing the parent client

* fix: remove dubious annotation

* feat: allow cloning a Client and modify it on the fly, use that for the notification client

* feat: get rid of the with_memory_state_store public func on ClientBuilder

* feat: include sender_id in the notification invite event

* feat: put sender's id in the `NotificationSenderInfo`

* feat: inherit the parent session when creating a notification client

* chore: reformat comments

* TMP: add logs

* chore: regenerate the olm machine when inheriting a session too

* chore: keep the parent client around for legacy_get_notification/with_context
2023-07-25 17:23:01 +00:00
Benjamin Bouvier 483465e8a8 feat(sliding sync): include the connection id conn_id in the tracing context 2023-07-25 18:49:37 +02:00
Benjamin Bouvier bef9cbfacc feat: rename Protocol to Scheme + replace server_name_with_protocol by insecure_server_name_no_tls 2023-07-25 18:43:35 +02:00
Benjamin Bouvier 122349ecec feat: allow specifying a protocol along a server name 2023-07-25 18:43:35 +02:00
Benjamin Bouvier 020d5aa292 fix: use a little state machine to handle the response
and that allows to make sure that all event handlers are correctly called for all
events contained in the response.
2023-07-25 17:36:43 +02:00
Benjamin Bouvier fb5c96e380 test: add test for previous feature 2023-07-25 17:36:43 +02:00
Benjamin Bouvier 8a809dba04 feat(sliding sync): only process encryption events (resp. room events) if configured as so 2023-07-25 17:36:43 +02:00
Benjamin Bouvier da7d1b092e chore(encryption sync): lower severity of update summary logging
The proxy server can (and does) redispatch unrelated lists/rooms from other sliding sync connections,
so the encryption sync would sometimes see room events. Apparently since this is not considered a bug
in the SS proxy, so we shouldn't spam error traces every time this happens.
2023-07-25 17:36:43 +02:00
Jonas Platte 04aac7bc13 ui: Redact replied-to event inside in_reply_to in timeline 2023-07-25 15:31:14 +02:00
Jonas Platte 004a4aa765 ui: Fix redactions for state events in the timeline 2023-07-25 15:31:14 +02:00
Jonas Platte 09fea85d92 ui: Replace Message by TimelineItemContent in RepliedToEvent 2023-07-25 15:31:14 +02:00
Jonas Platte d93f4ee4cc Fix clippy lint 2023-07-25 15:31:14 +02:00
Jonas Platte eb4dab138e ffi: Spawn tokio tasks for the remaining async fns
… as a workaround for cancellation being broken in UniFFI.
2023-07-25 14:34:31 +02:00
Damir Jelić 0a361eff5c Mark our public part of the user identity as verified if we import the private part (#2298)
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-07-25 12:39:06 +02:00
Jonas Platte bf26a343da ffi: Spawn tokio tasks for async code that locks async mutexes
Since we seem to have a problem with futures being leaked in Kotlin,
which can otherwise lead to deadlocks.
2023-07-24 20:01:27 +02:00
Ivan Enderlin d60a65f82b chore: Make Clippy happy. 2023-07-24 16:59:46 +02:00
Ivan Enderlin d39cbd865b feat(ffi): RoomListEntriesListener::on_update takes a Vec<_> now.
Since `RoomList::entries` returns a batch stream, the listener
now receives a `Vec<VectorDiff<RoomListEntry>>` instead of a
`VectorDiff<RoomListEntry>`.
2023-07-24 16:53:26 +02:00
Ivan Enderlin 3bcd9680fd test(ui): Test the new batch stream on entries and filtered entries.
Only updated the macro is required here. Instead of calling
`StreamExt::now_or_never` on the `$stream`, we call `Iterator::next` on
`$entries` which is a `Vec<VectorDiff<_>>` now.
2023-07-24 16:53:26 +02:00
Ivan Enderlin 1678d0754d feat(ui): Batch the stream returned by RoomList::entries and RoomList::entries_filtered.
This patch uses a newly implemented `async-rx` crate, that provides
`StreamExt`. This trait provides new features on `Stream`, like
`StreamExt::batch_with` which allows to batch values generated by a
`Stream` into a `Vec<Stream::Item>`. The batch is drained based on
another `Stream`: every time a value is produced, it drains the batch
stream.

This feature is used in `RoomList::entries` and
`RoomList::entries_filtered` to batch `Stream<Item = VectorDiff<_>>`
into `Stream<Item = Vec<VectorDiff<_>>>`.

The “drainer” is a broadcast sender, which sends an (empty) value every
time the room list service state changes, so every time something
happens during a sync. Note that it even drains when the room list
service state jumps to `Error` or `Terminated`.
2023-07-24 16:53:26 +02:00
Ivan Enderlin ac950ac253 doc(sdk): Update documentation of RoomListEntry variants. 2023-07-24 15:12:30 +02:00
Ivan Enderlin 2e265ad9bd feat(ui): Look for Room in the ring buffer from the newest instead of the oldest
feat(ui): Look for `Room` in the ring buffer from the newest instead of the oldest
2023-07-24 15:03:53 +02:00
Jonas Platte 766be8142e ffi: Make fetch_members cancellable 2023-07-24 13:59:09 +02:00
Ivan Enderlin 5dbfa89c72 feat(ui): Look for Room in the ring buffer from the newest instead of the oldest.
In `RoomListService`, there is a cache over the `Room`s to avoid re-
computing them every time the user calls `RoomListService::room`. It
also allows async operations to have time to finish while the user
jumps back to the room list and so on.

When reading this cache, which is `matrix_sdk_common::RingBuffer`,
`RingBuffer::iter` is used with `Iter::find` to find if the
`Room` exists in the cache. The cache has a size of 128 (given by
`ROOM_OBJECT_CACHE_SIZE`), which is quite large.

`Iter::find` will iterate from the oldest to the newest room in the
cache, but realistically, I reckon we need to iterate from the newest
to the oldest room. Indeed, the app user is more likely to jump between
recently opened rooms more frequently, thus saving quite a lot of
iterations for usual cases.

One may argue than in practice, a user won't open 128 rooms anyway… :-p.
2023-07-24 09:34:36 +02:00
Jonas Platte d9f3a5476e ffi: Simplify regular (non-OTLP) tracing initialization 2023-07-21 13:59:40 +02:00
Jonas Platte 0e3cca09dd ffi: Remove duplicate dependency 2023-07-21 13:59:40 +02:00
Jonas Platte 230cacaf18 ui: Add more tracing for room update handling 2023-07-21 11:06:31 +02:00
Jonas Platte 5b639903bb ui: Add more tracing for updating sender profiles 2023-07-21 11:06:31 +02:00
Jonas Platte abab1a32aa ui: Fix a typo 2023-07-21 11:06:31 +02:00
Jonas Platte 7e1f8f4923 base: Add tracing for getting a room member 2023-07-21 11:06:31 +02:00
Jonas Platte 236f6fff88 Make example dependencies less confusing 2023-07-20 13:28:14 +02:00
Jonas Platte 80fb8ff283 ffi: Don't keep timeline locked while back-paginating 2023-07-20 12:08:41 +02:00
Richard van der Hoff c6dab4088e Rename "Recovery Key" to "Backup decryption key" (#2305)
... because there are too many "recovery keys"
2023-07-20 09:49:54 +01:00
Damir Jelić 24e3ccfbb3 Add stronger typing to the return value of receive_sync_changes in the bindings (#2297) 2023-07-19 12:43:41 +00:00
Damir Jelić 9f69c32467 Broadcast valid secrets we receive over m.secret.send
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-07-19 14:27:18 +02:00
Damir Jelić 6ea0d886f7 Introduce a secret inbox
Up until now, users had to listen for to-device events to check for
secrets that were received as an `m.secret.send` event.

This has a bunch of shortcomings:
    1. Once the has been given to the consumer, it's gone and can't be
       retrieved anymore. Secrets may get lost if an app restart happens
       before the consumer decides what to do with it.
    2. The consumer can't be sure if the event was received in a
       secure manner.

This commit ads a inbox for our received secrets where we will long-term
store all secrets we receive until the user decides to delete them.

It's deemed fine to store all secrets, since we only accept secrets we
have requested and if they have been received from a verified device of
ours.
2023-07-19 14:27:18 +02:00
Jonas Platte 689d022b7a ui: Group timeline reaction metadata into a new struct 2023-07-19 14:01:32 +02:00
Jonas Platte 340e0b7a03 ci: Use taiki-e/install-action to install protoc 2023-07-19 10:11:21 +02:00
Jonas Platte 38a2885c10 Bump eyeball-im, enable its tracing feature 2023-07-18 16:40:47 +02:00
Jonas Platte aaa84c1489 Ensure valid room state before sending requests from Room methods 2023-07-18 15:12:03 +02:00
Jonas Platte 293cd08634 Clean up double spaces in docs 2023-07-18 15:12:03 +02:00
Jonas Platte e3ba1f1cb8 Add room API changes to changelog 2023-07-18 15:12:03 +02:00
Jonas Platte f3da79e482 Split unreleased section of changelog into sub-sections 2023-07-18 15:12:03 +02:00
Jonas Platte 92df7b22ec Rename room::Common to Room
… and export it at the matrix_sdk crate root.
2023-07-18 15:12:03 +02:00
Jonas Platte db84fcd8da Merge matrix_sdk::room::common into its parent module 2023-07-18 15:12:03 +02:00
Jonas Platte 67ef9c3fa0 Remove Room enum 2023-07-18 15:12:03 +02:00
Jonas Platte 85f66b1f96 Remove room::Joined 2023-07-18 15:12:03 +02:00
Jonas Platte fbea71aaf5 Move room::Join methods to room::Common 2023-07-18 15:12:03 +02:00
Jonas Platte 3602807641 Remove invalid reference in docs 2023-07-18 15:12:03 +02:00
Jonas Platte 6ad8086905 Move get_messages related types into a new room submodule 2023-07-18 15:12:03 +02:00
Jonas Platte 0408bd5a98 Remove room::Left 2023-07-18 15:12:03 +02:00
Jonas Platte ef00ef4158 Remove room::Joined::leave
… since room::Common::leave is now public and Joined deref's to Common.
2023-07-18 15:12:03 +02:00
Jonas Platte 9c8ed429b9 Move room::Left::forget to room::Common 2023-07-18 15:12:03 +02:00
Jonas Platte 05a817305e Remove room::Invited 2023-07-18 15:12:03 +02:00
Jonas Platte 10339ca15b Remove unreachable error variant 2023-07-18 15:12:03 +02:00
Jonas Platte 4621a47304 Move invite_details from room::Invited to room::Common 2023-07-18 15:12:03 +02:00
Jonas Platte 512dc18250 Remove room::Invited::accept_invitation in favor of room::Common::join 2023-07-18 15:12:03 +02:00
Jonas Platte 677907f8c5 Remove room::Invited::reject_invitation in favor of room::Common::leave 2023-07-18 15:12:03 +02:00
Jonas Platte 67abf707ff ui: Move ReactionSenderData to reactions module and re-export publically 2023-07-18 15:05:12 +02:00
Jonas Platte 145c796294 crypto: Remove Arc from fields of types that are no longer Clone 2023-07-18 14:58:11 +02:00
Jonas Platte a1806254a8 crypto: Remove Clone from more store related types 2023-07-18 14:58:11 +02:00
Jonas Platte 7081c67c46 Remove Arc wrapping from memory store fields 2023-07-18 14:58:11 +02:00
Jonas Platte 10d9808ecf Remove dead code 2023-07-18 14:58:11 +02:00
Jonas Platte 1c26069871 Make memory stores not clonable
It's not actually necessary and allows simplifying them.
2023-07-18 14:58:11 +02:00
Benjamin Bouvier 2f2bb82fcf add tests for the previous commit 2023-07-18 14:29:58 +02:00
Benjamin Bouvier e3cac2b637 fix: Don't mark a room as limited if the SS response doesn't contain any events 2023-07-18 14:29:58 +02:00
Jonas Platte 82bbb59965 ui: Update dedup_initial test to also test ID reuse
… and make it more realistic.
2023-07-18 14:20:29 +02:00
Jonas Platte 2720bddcc4 ui: Reuse IDs when removing and re-inserting an item 2023-07-18 14:20:29 +02:00
Jonas Platte ab0d88ae3a ui: Pull out identical code in different branches 2023-07-18 14:20:29 +02:00
Jonas Platte 78ebb7f745 ui: Remove redundant semicolon 2023-07-18 14:20:29 +02:00
Jorge Martin Espinosa 26edf4169f ffi: Use forked tracing-android temporarily
… to have readable logs in Android.
2023-07-17 15:48:56 +00:00
Benjamin Bouvier 4ad95ab1a1 chore: rename SyncService::observe_state to state 2023-07-17 16:46:07 +02:00
Benjamin Bouvier 2b3b5e9e18 feat: introduce Idle initial state 2023-07-17 16:46:07 +02:00
Benjamin Bouvier f1d67ad593 chore: remove RoomListService::is_syncing
It's preferrable that users make use of the `App::observe_state/current_state` methods, instead
as there's another sliding sync in the `App` and it properly unifies the current state of both.
2023-07-17 16:46:07 +02:00
Benjamin Bouvier 766d787779 chore: don't automatically start the App 2023-07-17 16:46:07 +02:00
Benjamin Bouvier 86ef0d41f8 feat: add getter to get the current state of the App 2023-07-17 16:46:07 +02:00
Jonas Platte a503dccdcd base: Apply redaction to latest_event in RoomInfo when applicable 2023-07-17 16:36:37 +02:00
Jonas Platte 0bb7a9de7f base: Remove wrong documentation 2023-07-17 16:36:37 +02:00
Jonas Platte 8067319208 base: Add BaseRoomInfo::room_version() 2023-07-17 16:36:37 +02:00
Jonas Platte 70421cff54 base: Restrict visibility of RoomInfo#latest_event 2023-07-17 16:36:37 +02:00
Benjamin Bouvier 68a5f70a85 chore: rename App to SyncService 2023-07-17 14:38:38 +02:00
Benjamin Bouvier a939522b1b test: add test for computing the limited flag 2023-07-17 13:51:45 +02:00
Benjamin Bouvier b3183f6315 feat: compute limited approximation client-side 2023-07-17 13:51:45 +02:00
Benjamin Bouvier 2357a09d13 chore: remove spurious feature guarding against "experimental-sliding-sync"
The whole file is guarded against this feature.
2023-07-17 13:51:45 +02:00
Mauro 91ea0ee8b1 Add PowerLevels permission checks to room::Joined
… and the FFI `Room`. These were previously already available at the `room::Member` level.
2023-07-17 11:43:31 +00:00
Benjamin Bouvier d98b296fad feat: reflect that push actions may not be available for a TimelineEvent
Before this patch, the inability to compute push actions would result in an empty vector of
push actions, leading to the false assumption that there's no push actions to account for,
while we were unable to compute them properly. This changes things up so that it's now the
user's responsibility to decide what to do when those push actions are missing.
2023-07-17 13:38:33 +02:00
Kévin Commaille 1dea482e43 ui: Expose the kind of a TimelineItem
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-07-14 19:17:17 +02:00
Kévin Commaille a6a0d722b4 ui: Fix imports behind sliding-sync feature flag
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-07-14 13:05:39 +02:00
Jonas Platte d82628725f ci: Remove serverName from setup-matrix-synapse arguments
We're getting warnings because this is not a supported parameter.
2023-07-14 12:05:02 +02:00
Benjamin Bouvier ac51adf1e5 feat: split the SlidingSyncBuilder with_timeouts method into two
Following a comment from Jonas in another PR.
2023-07-14 11:29:26 +02:00
Jonas Platte bfed0907ed Remove wasm_command_bot 2023-07-14 11:07:47 +02:00
Jonas Platte b2f7ba33c8 Patch const_panic to not use packed reference 2023-07-14 10:46:52 +02:00
Jonas Platte 6d8764f4e7 Patch const_panic 2023-07-14 10:46:52 +02:00
Jonas Platte 57c5347e81 ffi: Move more types out of UDL 2023-07-14 10:46:52 +02:00
Jonas Platte 9cf1adbfa6 Upgrade UniFFI 2023-07-14 10:46:52 +02:00
Dirk Stolle 0141dab8c9 ci: Update actions/checkout in GitHub Actions workflows to v3
Signed-off-by: Dirk Stolle <striezel-dev@web.de>
2023-07-14 10:22:55 +02:00
Dirk Stolle 0461ebe739 Fix some typos
Signed-off-by: Dirk Stolle <striezel-dev@web.de>
2023-07-14 10:10:03 +02:00
Jonas Platte 81d28d1f46 ui: Remove read-only mode for timeline
It was used when getting the latest message was done through the timeline,
which is no longer the case.
2023-07-13 15:48:56 +02:00
Jonas Platte d309cb3320 crypto-ffi: Use proc-macro definition of callback interfaces 2023-07-13 14:07:27 +02:00
Jonas Platte 3c2b2756b0 ci: Fix git ref comparison 2023-07-13 13:54:59 +02:00
Jonas Platte 5f924197fd ffi: Merge impl blocks for sync and async exported methods 2023-07-13 13:13:50 +02:00
Jonas Platte aee2ef6abf ffi: Use async-uniffi instead of block_on in app module 2023-07-13 13:13:50 +02:00
Jonas Platte 6f2fee8965 Upgrade UniFFI 2023-07-13 13:13:50 +02:00
Jonas Platte 5abc781e1f Remove matrix-sdk-crypto-js
It now lives in its own repository at
https://github.com/matrix-org/matrix-rust-sdk-crypto-web
2023-07-13 13:11:02 +02:00
Richard van der Hoff 51ba4483c0 Merge pull request #2270 from matrix-org/release-matrix-sdk-crypto-js-0.1.4
matrix-sdk-crypto-js v0.1.4
2023-07-12 17:24:16 +01:00
Richard van der Hoff b62bb90c79 matrix-sdk-crypto-js v0.1.4
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 31s
2023-07-12 16:58:19 +01:00
Richard van der Hoff a4cece7dd7 crypto: Add OlmMachine::query_keys_for_users (#2267)
Sometimes we need our key query results to be as up-to-date as possible. Add a mechanism to allow that.

Closes #2263 .
2023-07-12 16:48:34 +01:00
Jonas Platte ec34036586 ci: Switch to branch-less GitHub pages workflow 2023-07-12 17:47:04 +02:00
Jonas Platte 6e10eb9efb Remove matrix-sdk-crypto-js
It now lives in its own repository at
https://github.com/matrix-org/matrix-rust-sdk-crypto-nodejs
2023-07-12 16:23:37 +02:00
Jonas Platte a554a92dec crypto: Re-export vodozemac entirely 2023-07-12 15:14:47 +02:00
Jonas Platte ccb6d7d05c Move ruma re-export from matrix-sdk to matrix-sdk-common
… since it's also useful for crypto bindings.
2023-07-12 15:14:47 +02:00
Jonas Platte f6c339a5d2 Enable ruma's new compat-upload-signatures feature 2023-07-12 12:42:31 +02:00
Jonas Platte 63babcd35a Upgrade Ruma 2023-07-12 12:42:31 +02:00
Jonas Platte 8c3af12e47 test: Rename EventBuilder to SyncResponseBuilder
… because that's what it is.
2023-07-12 10:29:29 +02:00
Richard van der Hoff e1c5f628e7 Merge pull request #2258 from matrix-org/matrix-sdk-crypto-js-0.1.3
Fix `receiveSyncChanges` js bindings, and release 0.1.3
2023-07-11 18:12:16 +01:00
Richard van der Hoff f1def2a458 fix another test
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 30s
2023-07-11 17:19:58 +01:00
Richard van der Hoff 0bd1e65b49 update changelogs 2023-07-11 16:41:45 +01:00
Richard van der Hoff fd3c4f669d matrix-sdk-crypto-js v0.1.3 2023-07-11 16:41:22 +01:00
Richard van der Hoff a3a36291ad crypto-js Fix return type of receiveSyncChanges
https://github.com/matrix-org/matrix-rust-sdk/pull/2142 introduced an
unintended change such that `receiveSyncChanges` returned an array of arrays.
2023-07-11 16:29:17 +01:00
Jonas Platte 0daf3aeb6b ui: Move echoes to the bottom immediately when retrying 2023-07-11 16:36:26 +02:00
Jonas Platte 9dc6ac45d2 ui: Fix wrong field name 2023-07-11 16:36:26 +02:00
Jonas Platte 53ac8bea14 ffi: Provide tokio context for async exported method 2023-07-11 15:54:38 +02:00
Jonas Platte 01ceec43b1 ui: Use eyeball_im's new entry API 2023-07-11 15:41:34 +02:00
Benjamin Bouvier 43bbd4200e chore: inline variable and use From<bool> for WithLocking 2023-07-11 14:07:27 +02:00
Benjamin Bouvier 2d9f7d2f89 ffi: remove bindings for manually creating EncryptionSync and RoomList 2023-07-11 14:07:27 +02:00
Benjamin Bouvier dbc8f0136b ffi: add bindings for App 2023-07-11 14:07:27 +02:00
Benjamin Bouvier dd7d4ddf7c chore: rebase 2023-07-11 14:07:27 +02:00
Benjamin Bouvier e60d04b368 doc: document the App API 2023-07-11 14:07:27 +02:00
Benjamin Bouvier 704cd7784b feat: experimental App API that wraps both the encryption sync and room list API 2023-07-11 14:07:27 +02:00
Damir Jelić 1c6d85935d Generate one-time keys when we receive new one-time key counts (#2249)
Previously we would generate one-time keys, if needed, whenever we tried
to upload them. This code-path is critically missing a `save_account()`
call and we would only persist the account once we uploaded the one-time
keys.

This patch changes things up to generate one-time keys whenever we
receive new one-time key counts from the sync response. This aligns
with the way we generate fallback keys and removes the need to introduce
a new place where we persist the `Account`.

It's still possible to re-upload the same one-time keys, in the case
where the upload process succeeds on the server side but we fail to
receive the response.

Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-07-11 10:27:04 +00:00
Benjamin Bouvier 9985a63dd3 feat: use a ring buffer for the RoomListService cache
This will limit the memory used by the cache entries (while it was unbounded before). It's now possible to do this,
since we have the `latest_room_event` handy for all the rooms; using the unbounded cache before was papering over
the lack of that feature.

We can bikeshed on the number of entries in this cache. It has to be small enough to not blow up memory (and keep
the linear search over room id fast, but it's secondary), and high enough that we don't hit the full timeline
re-build path that often.
2023-07-11 10:57:04 +02:00
Richard van der Hoff 00e85ef275 Disable debug logging for tests
Because https://github.com/jestjs/jest/issues/4156 is closed
2023-07-11 10:56:42 +02:00
Jonas Platte 879d1b189c ui: Test unique ID tracking 2023-07-10 19:19:31 +02:00
Jonas Platte a11508fa58 ui: Linkify doc bits 2023-07-10 19:19:31 +02:00
Jonas Platte 754b668fe6 ui: Move TimelineItem, TimelineItemKind into new sub-module 2023-07-10 19:19:31 +02:00
Mauro Romito bc811cc1dc ui: Add a unique ID for all timeline items
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-07-10 19:19:31 +02:00
Benjamin Bouvier 2acc13ed2c feat: add a new NotificationClient API 📬 (#2235)
* chore: rename EncryptionSyncMode variants

* feat: split the encryption sync modes into two different functions

* feat: make locking optional in the `EncryptionSync`

* feat: experimental notification client that retries decryption if it failed the first time

* fix: don't iloop retrying decryption

* chore: helper to convert from bool to `WithLocking`

* feat: don't loop and just retry decryption of the notification event linearly

* feat: remove unused set_notification_delegate

Dead code is dead.

* ffi: get rid of `get_notification_item` and introduce the `NotificationClient`

* fmt

* feat: don't swallow encryption sync errors when retrying notification event decryption

* keeping a tidy commit history is NP-hard

* will i ever learn

* chore: enable experimental-notification-client in the FFI crate

* test: add basic integration test for the common path

* Address first batch of review comments, thanks Jonas!
2023-07-10 18:06:13 +02:00
Vladimir Panteleev a094e10b35 base: Add unit test for deserialization failure of join events 2023-07-10 15:59:21 +02:00
Vladimir Panteleev ab781bf5f4 base: Fix deserialization failure leading to database corruption
f36a5b8cd7 introduced
deserialize_events, moving the deserialization out of handle_state.
However, the new code in deserialize_events used filter_map, which
caused a deserialization failure to lead to the indices of the
serialized and deserialized events to no longer match up.

This was not caught because iter::zip also does not require that its
arguments have matching lengths, causing the mismatch to cascade for
that batch of events, and persist in the store.  An application
affected by this form of corruption can, for example, call
room.get_state_events requesting events of a certain type, and getting
back events of a different type.

Fix the bug by using Option to preserve the length of
deserialize_events' return value, and add an assertion to ensure
handle_state's contract.

Signed-off-by: Vladimir Panteleev <git@cy.md>
2023-07-10 15:59:21 +02:00
Jonas Platte 6ea806bf18 base: Fix clippy lints 2023-07-10 14:03:58 +02:00
Richard van der Hoff 57ea8173ae Merge pull request #2248 from matrix-org/release-matrix-sdk-crypto-js-0.1.2
matrix-sdk-crypto-js v0.1.2
2023-07-10 12:27:10 +01:00
Richard van der Hoff bf1595309c matrix-sdk-crypto-js v0.1.2
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 30s
2023-07-10 12:03:32 +01:00
Richard van der Hoff caa70db31b Prepare changelog for v0.1.2 2023-07-10 12:03:12 +01:00
aringenbach 89aa2916c7 ui/ffi: Add timestamp to reactions 2023-07-10 10:13:53 +00:00
Benjamin Bouvier 2225e8ad80 feat: make it possible to configure the state store as an in-memory store in FFI 2023-07-10 12:04:52 +02:00
Richard van der Hoff 708a7d95a7 Add Qr.state() 2023-07-10 11:45:33 +02:00
Richard van der Hoff 0ccb1efded Enable rust-sdk tracing for device tests
... because knowing why your tests are failing is nice
2023-07-10 11:45:33 +02:00
Richard van der Hoff 0a5ef29c34 device.test: Stop pretending we have independent tests
This file claimed to have lots of tests, but actually they are not independent
- they are just one big test.

It's not ideal to have one massive test like this, but I don't really have time
to rewrite them and we should stop pretending.
2023-07-10 11:45:33 +02:00
Damir Jelić 9f68b3838f Merge pull request #2142 from matrix-org/andybalaam/cache-last-event-in-roominfo
Store the last timeline event in RoomInfo
2023-07-10 11:30:13 +02:00
Jonas Platte 0a6234f40a ffi: Send initial back-pagination status to subscriber immediately
… right as the subscriber is registered.
2023-07-10 11:07:43 +02:00
Kévin Commaille 4e52125551 ui: Allow to filter events added to the Timeline
To avoid to deal with events we are not interested in in the stream.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-07-07 22:20:14 +02:00
Richard van der Hoff 0bf99d5c73 Fix handling of SAS start events once we have shown a QR code (#2242)
Fixes #2237

Also a couple of other cleanups while I'm in the area.
2023-07-07 17:55:13 +01:00
Andy Balaam bac555d31b More CI fixes 2023-07-07 16:19:38 +01:00
Andy Balaam ff0cd7c592 Fix one more JS test 2023-07-07 15:55:29 +01:00
Andy Balaam 96098e8f8b More feature flag fiddling 2023-07-07 15:44:16 +01:00
Andy Balaam 6e84f969ad More feature flag fiddling 2023-07-07 15:42:52 +01:00
Andy Balaam 9bcc1e9e00 More JavaScript test updates 2023-07-07 15:31:09 +01:00
Andy Balaam 31e9572d42 Allow unused code for read_only 2023-07-07 15:22:45 +01:00
Andy Balaam b525491bd5 Fix warnings from CI 2023-07-07 15:20:41 +01:00
Andy Balaam c9a11a58bf Format JavaScript 2023-07-07 15:11:00 +01:00
Andy Balaam 82c7a05f01 Fixes for problems found through CI 2023-07-07 15:05:48 +01:00
Nicolas Mauri fa4c1ef00b ffi: expose the notification settings (#2223) 2023-07-07 15:07:31 +02:00
Andy Balaam a2ca168573 Provide path for a doc link 2023-07-07 13:22:28 +01:00
Andy Balaam 6cb3afe6fd Merge branch 'main' into andybalaam/cache-last-event-in-roominfo 2023-07-07 13:14:52 +01:00
Andy Balaam 3fd1542a25 Fetch sender profile when returning latest event 2023-07-07 12:59:49 +01:00
Benjamin Bouvier 1f47e165ab chore: remove a few useless async 2023-07-07 13:04:31 +02:00
Benjamin Bouvier 4e065ccee9 feat: don't recreate the cross-process lock if it already existed 2023-07-07 13:04:16 +02:00
Jonas Platte 0ef819bca7 ffi: Use proc-macros for SessionVerificationControllerDelegate 2023-07-06 18:26:40 +02:00
Jonas Platte 6f295e2571 Upgrade UniFFI 2023-07-06 18:26:40 +02:00
Jonas Platte 07a82c841f ui: Spawn a background task for decryption retrying 2023-07-06 17:55:05 +02:00
Andy Balaam 98882b9c23 Store the last timeline event in RoomInfo
and the latest few encrypted events in Room.
Use the latest event to provide a room preview, and use the encrypted
events to replace the laest event when they are decrypted.
2023-07-06 16:48:27 +01:00
Florian Duros c600c64b95 BindingsJS: Release v0.1.1 (#2234) 2023-07-06 17:25:02 +02:00
Ivan Enderlin 61ddf047e0 fix(sqlite): Prevent reaching the maximum number of parameters in an SQL statement
fix(sqlite): Prevent reaching the maximum number of parameters in an SQL statement
2023-07-06 17:07:23 +02:00
Ivan Enderlin a70e79420c fix(sqlite): Ensure there is free space for static parameters, in chunk_large_query_over. 2023-07-06 16:46:35 +02:00
Ivan Enderlin 4e20dc5047 chore(sqlite): To make a friend smile. 2023-07-06 16:27:32 +02:00
Ivan Enderlin 23dae0612d chore(sqlite): Use itertools in repeat_vars. 2023-07-06 16:22:37 +02:00
Jonas Platte fe189fda06 bindings: Rename subscribe_to_back_pagination_{status => state}
For consistency with the UI crate.
2023-07-06 15:55:49 +02:00
Florian Duros 0384a52f1e Expose the verify method for the Device in the bindings (#2229) 2023-07-06 15:46:52 +02:00
Ivan Enderlin d33e2aff2e doc(sqlite): Fix a typo. 2023-07-06 15:18:41 +02:00
Ivan Enderlin 380bce0604 fix(sqlite): Prevent reaching the maximum number of parameters in an SQL statement.
This patch introduces a new `chunk_large_query_over` function. Imagine
there is a _dynamic_ query that runs potentially large number of
parameters, so much that the maximum of parameters can be hit. Then,
this function is for you. It will execute the query on chunks of
parameters.

`chunk_large_query_over` uses `Vec::split_off` to avoid cloning `Key`s
as much as possible. It's difficult to use references here because of
the async nature of `SqliteObjectExt::prepare`.

This patch updates `get_kv_blobs`, `get_room_infos`,
`get_maybe_stripped_state_events_for_keys`, `get_profiles`,
`get_user_ids`, and `get_display_names` to use this new function.

This patch finally adds the `repeat_vars` function to replace in a
more efficient way the `vec!["?"; n].join(", ")` pattern. There is less
memory allocations.
2023-07-06 15:11:42 +02:00
Jonas Platte ae17273a37 ui: Replace loading indicator and timeline start virtual timeline items
… with a BackPaginationState observable.
2023-07-06 13:57:40 +02:00
Damir Jelić 75dbfb4d46 Remove an unnecessary unwrap in the crypto crate (#2226) 2023-07-06 12:40:04 +02:00
Ivan Enderlin f2d53a272b Merge pull request #2222 from Hywan/chore-ffi-sliding-sync-bye-bye 2023-07-06 10:11:30 +02:00
Jonas Platte 438c0076f7 ui: Remove NewEventTimelineItem 2023-07-05 17:47:06 +02:00
Jonas Platte b9f98846c8 ci: Upgrade typos 2023-07-05 17:47:06 +02:00
Ivan Enderlin 6cca4ab3e5 chore(ffi): Bye bye Sliding Sync bindings!
The `RoomList` and `EncryptionSync` API provide a better developer
experience and address concrete needs. Nobody no longer uses the Sliding
Sync bindings, so we can remove them.
2023-07-05 15:05:08 +02:00
Ivan Enderlin 96ef45afe8 feat: Immediately fail if a sliding sync request failed (follow up of #2209)
feat: Immediately fail if a sliding sync request failed (follow up of #2209)
2023-07-05 14:47:54 +02:00
Ivan Enderlin 9493c8a75d chore(sdk): Feedbacks. 2023-07-05 14:29:16 +02:00
Ivan Enderlin 1ccc0c3df3 feat(sdk): Ensure that the task sending E2EE requests cannot be detached. 2023-07-05 13:35:52 +02:00
Benjamin Bouvier 1cd87ca15d feat: Immediately fail if a sliding sync request failed
For sliding sync that starts both the actual sliding sync request along the e2ee requests,
we need to make sure that, in case of failure of sliding sync, we reset `pos` as soon as possible.
With the code before this patch, the sliding sync response might be available, but the whole
processing could be waiting for the e2ee requests to finish. In the updated version, we spawn
the e2ee requests in a background task, then run the sliding sync request immediately and fail
if it failed.

Another nice benefit is that the e2ee requests won't be interrupted in the middle of processing,
if the sliding sync changed parameters and we cancelled the whole sync a bit too early.

Fixes #2206.
2023-07-05 13:13:51 +02:00
Jonas Platte afeb5dab24 sdk: Remove questionable use of assign! macro 2023-07-05 12:16:30 +02:00
Jonas Platte 206accb5fb Bump serde_html_form 2023-07-05 11:34:50 +02:00
Jonas Platte 0b24df991e Bump bs58 2023-07-05 11:34:50 +02:00
Jonas Platte dd2fefa2f3 Bump indexmap 2023-07-05 11:34:50 +02:00
Jonas Platte 2b72df7c06 Bump itertools 2023-07-05 11:34:50 +02:00
Jonas Platte 71f7f7c69e Remove mentions of labs crates
There are none at the moment.
2023-07-05 11:34:50 +02:00
Jonas Platte 4ae63caa56 Bump bitflags dependency
2.3.3 contains some bug fixes, might be relevant.
2023-07-05 11:34:50 +02:00
Ivan Enderlin b6908c0611 feat(ui): Change all_rooms batch size to 200
feat(ui): Change `all_rooms` batch size to 200
2023-07-05 10:46:01 +02:00
Ivan Enderlin 36419a7a1f chore: get rid of previous locking crypto-store methods
chore: get rid of previous locking crypto-store methods
2023-07-05 10:35:33 +02:00
Ivan Enderlin 12a1f25ec3 feat(ui): Change all_rooms batch size to 200.
`RoomListServer` defines an `all_room` sliding sync list. This list
starts in selective sync-mode, then it switches to growing sync-mode.
The previous batch size of the growing sync-mode was 50. This patch
updates it to 200, because empirically it seems a better value for
perceived performance.

This patch also rewrites how `State::next` is written. No change in the
code, just comestic.
2023-07-05 10:28:02 +02:00
Ivan Enderlin a0f40606d4 Merge pull request #2208 from bnjbvr/only-restart-growing-on-errors
feat: Only restart growing the allRooms list in case of errors
2023-07-05 10:01:58 +02:00
Jonas Platte da43d81095 ui: Keep loading indicator at the top when processing timeline events 2023-07-05 09:52:59 +02:00
Jonas Platte 5fa293b8ed crypto: Use HashMap inside DashMap
… instead of nesting DashMaps.
The previous type was tracking mutability at very fine-grained level for
no clear reason.
2023-07-04 19:50:45 +02:00
Jonas Platte 87782e9567 ffi: Expose EventTimelineItem::origin 2023-07-04 19:50:08 +02:00
Jonas Platte f344aa7669 sdk: Add EventTimelineItem::origin 2023-07-04 19:50:08 +02:00
Mauro Romito f4929fd064 joined members is now in the notification 2023-07-04 19:39:43 +02:00
Jonas Platte cb2e97f06a Upgrade eyeball to 0.8 2023-07-04 16:22:45 +00:00
Nicolas Mauri 3db72101f3 sdk: Allow to update notification settings (#2135)
* sdk: Allow to update notification settings

* Add an event listener for push rule events

* Fix: simplify insertion and deletion of rules

* Fix: Limit rules cloning

* Fix: Unit tests

* Fix: set_room_notification_mode

* Fix: potential race condition when updating the local ruleset

* Refactor RuleCommands

* RuleCommands Unit Tests

* Fix: limit lock usage

* nit: use expression assignment by default

* nit: pass Ruleset by ownership in RuleCommands' ctor

* a few nits: use to_owned() for &str -> String; use free function for notify actions; use clone() where it's more obvious

and use explicit variants so we know we have to consider this match if we were to add a new variant later

* nit: rename RuleCommands::set_enabled to set_enabled_internal

* nit: test modules don't need to be publicized

* tidy tests

* nit: pass an owned RuleCommands in Rules::apply

* add comments/questions in Rules tests

* nit: no need to publicize the tests module

* tweak NotificationSettings tests too

* rustfmt

---------

Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-07-04 15:29:57 +00:00
Benjamin Bouvier bb34f69662 chore: get rid of previous locking crypto-store methods 2023-07-04 17:19:01 +02:00
Benjamin Bouvier e8a306132a feat: Only restart growing the allRooms list in case of errors
When the sync has been terminated and restarts (e.g. an app is going from the background to the foreground), then
the sliding sync is always restarting in growing mode, independently of the previous state of the sync (error or normal
termination). This is something the current sliding sync proxy can't handle nicely, because it prioritizes a change in
parameters over live data; as a matter of fact, to alleviate the burden of the proxy, we can try to only restart in
growing mode if we ran into an error (and not if we had a normal termination).
2023-07-04 13:06:49 +02:00
Jonas Platte 7bcc886429 Re-format with latest rustfmt 2023-07-03 18:57:05 +02:00
Jonas Platte 37023fe90b Fix new clippy lint 2023-07-03 18:57:05 +02:00
Jonas Platte cd4288391e Bump nightly toolchain version 2023-07-03 18:57:05 +02:00
Jonas Platte b681f234a3 Upgrade criterion, pprof 2023-07-03 18:08:01 +02:00
Alfonso Grillo 147cd970c4 Map MSC3488 fields for UniFFI (#2187)
* Update ruma

* Refactor send_location

* Add timeline parser

* Fix code format

* Add zoom_level

* Update ruma

* Map zoom_level

* Format code

* Cleanup

* Refactor LocationContent

* Apply suggestion

* Fix format issue
2023-07-03 13:34:07 +00:00
Ivan Enderlin 10c9a47f01 Merge pull request #2197 from Hywan/test-ui-room-list-assert-equal 2023-07-03 13:36:55 +02:00
Ivan Enderlin 746b13071e Merge pull request #2198 from Hywan/test-integration-fix 2023-07-03 13:36:06 +02:00
Ivan Enderlin c955de8331 test: Change the installer for setup-matrix-synapse.
There is a bug in Synapse and changing the installer seems to fix the
problem.
2023-07-03 12:47:24 +02:00
Ivan Enderlin 0c13b76d27 test(ui): Do strict assert comparison in some tests of RoomList.
It ensures that we know exactly what's happening here. Tests are still
valid without any changes in the expected data, but it prevents a
potential breaking.
2023-07-03 11:13:45 +02:00
Ivan Enderlin 4f84e33457 fix(ui): Add bump_event_types onto visible_rooms
fix(ui): Add `bump_event_types` onto `visible_rooms`
2023-07-03 10:04:31 +02:00
Ivan Enderlin 37ad562b4b test(sdk): Use async_test instead of tokio::test. 2023-07-03 09:36:45 +02:00
Ivan Enderlin ed2d3bc5b3 chore(ui) Use a function to configure all_rooms and visible_rooms.
The Sliding Sync list `all_rooms` and `visible_rooms` of the `RoomList`
must have the exact same configurations for `sort`, `filters`, and
`bump_event_types`. Instead of maintaining the same code, this patch
adds a new function: `configure_all_or_visible_rooms_list` that
configures the lists exactly the same. This function also explicitely
configures `sort` so that we do no rely on the default values from
`SlidingSyncListBuilder`.
2023-07-03 09:22:32 +02:00
Ivan Enderlin 627a1613df fix(ui): Add bump_event_types onto visible_rooms.
This patch configures the same `bump_event_types` for the
`visible_rooms` list than for the `all_rooms` list, so that we may be
sure that the sorting/ordering is the same between the two lists.
2023-06-30 21:48:30 +02:00
Ivan Enderlin f82fd896f9 chore(ui): Rename room_list module to room_list_service
chore(ui): Rename `room_list` module to `room_list_service`
2023-06-30 21:45:10 +02:00
Ivan Enderlin 9f90b6d4a8 chore(ui): Rename room_list module to room_list_service. 2023-06-30 19:59:13 +02:00
jonnyandrew 3180a1ba7c ffi: Expose proxy and insecure SSL settings (#2191)
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-06-30 15:31:20 +02:00
Benjamin Bouvier 4fbb3d2b63 xtask: add --features testing to most testing tasks 2023-06-30 12:41:04 +02:00
Benjamin Bouvier 66e1b94d31 test: add test for the generational counter invalidation 2023-06-30 12:41:04 +02:00
Benjamin Bouvier d642c22db7 feat: implement a generation counter for the CryptoStore lock 2023-06-30 12:41:04 +02:00
Benjamin Bouvier d72fd34325 Make pending local echoes sticky, take 2 (#2189)
* ui: Move EventSendState into timeline::event_item::local module

* [WIP] ui: Make pending local echoes stick to the bottom of the timeline

* test: update more test expectations

* chore: tweak comment to slightly better reflect reality

* nit: remove else after return

* fix: the item's insert position is insert_idx, not `items.len()` anymore

* fix: look for remote echo before local echo when processing send state

Previous code assumed that the latest timeline items would be the most recent, and that
if there was a remote echo, it would always be after the local echo, because of that.
That's not the case anymore, so we must look for possibly a remote echo first, and then
if we find it, apply the late update process.

Also, there might remain a day divider added by the local echo, if it were inserted last.
I'm not sure it covers all the cases, but I've now made it so that the day divider is removed
if it was the last element.

* feat: switch strategy; keep on pushing if there's nothing in the timeline yet

* Revert "test: update more test expectations"

This reverts commit 400cc93ba7c98042a28b5e8d5042899e854f6cff.

* test: reset test expectations

* Address review comments

* fix: don't mix up latest event with any status, with latest non-failed event index

---------

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-06-30 09:37:49 +00:00
Richard van der Hoff 5348e7cc12 Airplane -> Aeroplane
For verification-by-emoji, the spec uses the word "Aeroplane" rather than
"Airplane". Element-web expects us to use the specced words (and will otherwise
complain about the lack of i18n data).

It seems like following the spec will help maintain consistency.
2023-06-30 10:45:52 +02:00
jonnyandrew f508109d0c Fix reaction response resolution 2023-06-30 10:26:41 +02:00
Benjamin Bouvier 77290ff2c1 feat: Get rid of "common extensions"
Common extensions are confusing, and they've included `e2ee` and `to-device` by default. This is not a sane default anymore,
now that there's the concept of `EncryptionSync`: it's either we have the encryption sync that enables e2ee and to-device +
a room list sync that doesn't, OR we have a single room list that has both.

Room List was misconfigured to always use `e2ee` and `to-device`, which was incorrect when it's running with the `EncryptionSync`
in the background. This is now removed, and properly tested.
2023-06-30 09:56:29 +02:00
Richard van der Hoff 48a6bffc1e Merge branch 'release-matrix-sdk-crypto-js-0.1.0' 2023-06-29 17:02:40 +01:00
Ivan Enderlin 1958df22a9 fix(sdk): Change how SlidingSyncList::update_room_list handles updates for out of list rooms
fix(sdk): Change how `SlidingSyncList::update_room_list` handles updates for out of list rooms
2023-06-29 15:48:39 +02:00
Ivan Enderlin 91bf84714d feat(ffi): Add methods on RoomListItem so that full_room isn't necessary
feat(ffi): Add methods on `RoomListItem` so that `full_room` isn't necessary
2023-06-29 15:39:45 +02:00
Richard van der Hoff 757716c924 matrix-sdk-crypto-js v0.1.0 2023-06-29 15:22:00 +02:00
Richard van der Hoff 1b2b6c011b update changelog 2023-06-29 15:22:00 +02:00
Ivan Enderlin bd148fd422 chore(ffi): RoomListItem::is_direct returns a bool. 2023-06-29 15:14:53 +02:00
Ivan Enderlin 363b0d9ee6 doc(ffi): Add some precisions. 2023-06-29 15:07:46 +02:00
Benjamin Bouvier 73ad51879a feat: implement time lease based locks for the CryptoStore (#2140)
This implements a new time lease based lock for the `CryptoStore`, that doesn't require explicit unlocking, so that's more robust in the context of #1928, where any process may die because the device is running out of battery, or unexpected flows cause a lock to not be released properly in one or the other process.

```
//! This is a per-process lock that may be used only for very specific use
//! cases, where multiple processes might concurrently write to the same
//! database at the same time; this would invalidate crypto store caches, so
//! that should be done mindfully. Such a lock can be acquired multiple times by
//! the same process, and it remains active as long as there's at least one user
//! in a given process.
//!
//! The lock is implemented using time-based leases to values inserted in a
//! crypto store. The store maintains the lock identifier (key), who's the
//! current holder (value), and an expiration timestamp on the side; see also
//! `CryptoStore::try_take_leased_lock` for more details.
//!
//! The lock is initially acquired for a certain period of time (namely, the
//! duration of a lease, aka `LEASE_DURATION_MS`), and then a "heartbeat" task
//! renews the lease to extend its duration, every so often (namely, every
//! `EXTEND_LEASE_EVERY_MS`). Since the tokio scheduler might be busy, the
//! extension request should happen way more frequently than the duration of a
//! lease, in case a deadline is missed. The current values have been chosen to
//! reflect that, with a ratio of 1:10 as of 2023-06-23.
//!
//! Releasing the lock happens naturally, by not renewing a lease. It happens
//! automatically after the duration of the last lease, at most.
```

---

* feat: implement a time lease based lock for the crypto store
* feat: switch the crypto-store lock a time-leased based one
* chore: fix CI, don't use unixepoch in sqlite and do time math in rust
* chore: dummy implementation in indexeddb, don't run lease locks tests there
* feat: in NSE, wait the duration of a lease if first attempt to unlock failed
* feat: immediately release the lock when there are no more holders
* chore: clippy
* chore: add comment about atomic sanity
* chore: increase sleeps in timeline queue tests?
* feat: lower lease and renew durations
* feat: keep track of the extend-lease task
* fix: increment num_holders when acquiring the lock for the first time
* chore: reduce indent + abort prev renew task on non-wasm + add logs
2023-06-29 13:05:44 +00:00
Ivan Enderlin 0cd0ade2bc feat(ffi): Add methods on RoomListItem so that full_room isn't necessary.
Calling `RoomListItem::full_room` creates its associated `Timeline`.

ElementX calls `full_room` to get the `is_direct`, `avatar_url` and
`canonical_alias` values for _all_ rooms in the room list. Instead of
doing so, let's add those methods directly in `RoomListItem` so that the
`Timeline` isn't created for _all_ rooms.
2023-06-29 14:48:37 +02:00
Ivan Enderlin eab1f8783a chore(ui): Remove unecessary qualification
chore(ui): Remove unecessary qualification
2023-06-29 14:18:09 +02:00
Richard van der Hoff 9a2f6b8fb9 matrix-sdk-crypto-js v0.1.0
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 1m35s
2023-06-29 13:10:16 +01:00
Richard van der Hoff 082d166502 update changelog 2023-06-29 13:09:51 +01:00
Ivan Enderlin 717063eaa8 feat(common): Implement RingBuffer::drain
feat(common): Implement `RingBuffer::drain`
2023-06-29 13:49:37 +02:00
Ivan Enderlin 9b4d06272c chore(ui): Remove unecessary qualification. 2023-06-29 13:37:45 +02:00
Ivan Enderlin 6d67375f8e fix(ffi): Simplify Room::add_timeline_listener
fix(ffi): Simplify `Room::add_timeline_listener`
2023-06-29 13:24:05 +02:00
Ivan Enderlin e96097a085 feat(common): Implement RingBuffer::drain.
This patch implements `RingBuffefr::drain` because it's going to be
useful soon.
2023-06-29 13:22:43 +02:00
Richard van der Hoff 506d7c6f9b Add accessor for remaining time to VerificationRequest. (#2178) 2023-06-29 11:49:31 +01:00
Benjamin Bouvier 459b689953 tests: add unit tests for the CryptoStoreLock 2023-06-29 12:34:53 +02:00
Ivan Enderlin 61b7335dce chore(sdk): Log SlidingSync list updates
chore(sdk): Log SlidingSync list updates
2023-06-29 11:34:04 +02:00
Ivan Enderlin 62315d726f feat(ui): Do not update the viewport of the room list if it hasn't changed
feat(ui): Do not update the viewport of the room list if it hasn't changed
2023-06-29 11:33:45 +02:00
Ivan Enderlin 9bae039629 fix(sdk): Change how SlidingSyncList::update_room_list handles updates for out of list rooms.
So. `SlidingSyncList::update_room_list()` does the following:

1. It adjust room list entries,
2. It updates the `maximum_number_of_rooms`,
3. It applies the sync operations on the `room_list` entries,
4. It updates the `room_list` entries for rooms outside the sync
   operations.

SlidingSync answers with a `lists` and `rooms`. The `room_list` entries
is updated as follows: either a sync operation from `lists` has been
applied and the entries are updated, or `rooms` contains rooms that
are not updated by `lists` but that receive new events, and thus must
trigger an update in the `room_list` entries.

This patch changes a little bit the last part of this. Initially,
we were updating rooms that are part of `rooms` but absent of
`lists` sync operations, only **for the current list's ranges**.
But that's wrong! First, we have noticed a bug here: the
correct code wasn't `skip(start).take(end.saturating_add(1))` but
`skip(start).take(end.saturating_add(1) - start)`. Note a big deal, we
were iterating on more entries like it was necessary, but everything
was filtered later, so no bug, just useless computations. Second,
this `skip` and `take` is actually… useless. A room to which we have
subscribed can be out of any range, but we still want `room_list`
entries to receive an update for that particular room.

This patch fixes that once and for all.

In practise, the bug wasn't happening because if someone subscribes
to a room, its timeline is likely to be fetched, and updates will be
received, but still, this is better now from a SlidingSync strict point
of view.
2023-06-29 11:21:31 +02:00
Ivan Enderlin d01725dedb fix(ffi): Simplify Room::add_timeline_listener.
This patch does the following:

1. changes `add_timeline_listener` to be async, thus removing one
  `RUNTIME.block_on`.
2. simplifies the logic by adopting a more classical pattern we use
   elsewhere:
  * removes one `spawn_blocking`,
  * let's move the `listener` into the task as a `Box` instead of
    cloning it as an `Arc`.
2023-06-29 10:31:04 +02:00
Ivan Enderlin 111071c034 chore(sdk): Log SlidingSync list updates.
This patch removes an old log and adds a better one with more context.
2023-06-29 09:47:39 +02:00
Ivan Enderlin af4ebd8422 feat(ffi): Update RoomListService::apply_input to always return (). 2023-06-29 09:21:14 +02:00
Ivan Enderlin de09b781ec feat(ui): Do not update the viewport of the room list if it hasn't changed.
Imagine the room list has the viewport set to the range `0..=19`. The
user scrolls quickly to `50..=69` to see something below and immediately
scrolls back to its initial position, without stopping the scroll
at any moment in between. The app using this API might update the
viewport from `0..=19` to… `0..=19`. Updating the viewport, updates the
`visible_rooms` sliding sync list. Since a list is modified, the current
sync-loop iteration is skipped over and a new one restarts, i.e. the
current in-flight request is cancelled… for nothing.

This patch prevents this situation. The current viewport ranges is
stored in `RoomListService`. `RoomListService::apply_input` used to
return `Result<(), Error>`, now it returns `Result<InputResult, Error>`.
The `InputResult` enum is a new type. It represents whether an input has
been applied or ignored, which must be differentiate from errors.

So now, if the viewport changes and it's not different from the previous
value, `InputResult::Ignored` is returned.
2023-06-29 09:21:14 +02:00
Richard van der Hoff 5d9cc6be15 use assert_matches instead of manual panics 2023-06-28 16:32:07 +02:00
Richard van der Hoff c0c7c598b5 When refusing a verification, send cancel to the originating device
According to the spec, when a device receives a verification request and wants
to refuse it, it should send the `m.key.verification.cancel` to the originating
device, rather than broadcasting it.
2023-06-28 16:32:07 +02:00
Andy Balaam 33243cb9fb Fix comment wrongly referring to vector.
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-06-28 14:07:10 +02:00
Andy Balaam 785eccc004 Add capacity to RingBuffer 2023-06-28 14:07:10 +02:00
Andy Balaam 13c7f5b0c6 Implement Default for RingBuffer 2023-06-28 14:07:10 +02:00
Richard van der Hoff 3f2eb5828c crypto-js: wait for device updates in getIdentity
We previously did something similar for `getUserDevices` in 0da8e56a. Turns out
it's useful for `getIdentity` too.
2023-06-28 13:33:23 +02:00
Jonas Platte e732b3630a ffi: Add SendAttachmentJoinHandle 2023-06-28 12:55:56 +02:00
Jonas Platte b088339710 Revert "crypto: Add Store::room_keys_for_room_received_stream"
This reverts commit e87b3def02.
2023-06-28 12:32:18 +02:00
Jonas Platte 90e39f7be2 Revert "sdk: Re-export room_keys[_for_room]_received_stream from Encryption"
This reverts commit 04d56130c3.
2023-06-28 12:32:18 +02:00
Jonas Platte fd5b28bb51 Revert "sdk: Add room::Joined::room_keys_received_stream"
This reverts commit 9f72e2cf16.
2023-06-28 12:32:18 +02:00
Jonas Platte b53eba5ec9 Revert "ui: Use new room_key stream for retrying decryption in Timeline"
This reverts commit 06600ac53f.
2023-06-28 12:32:18 +02:00
Ivan Enderlin 07b7885915 chore(sdk): Add missingn newline. 2023-06-28 11:10:53 +02:00
Jonas Platte 06600ac53f ui: Use new room_key stream for retrying decryption in Timeline 2023-06-28 10:14:59 +02:00
Jonas Platte 9f72e2cf16 sdk: Add room::Joined::room_keys_received_stream 2023-06-28 10:14:59 +02:00
Jonas Platte 04d56130c3 sdk: Re-export room_keys[_for_room]_received_stream from Encryption 2023-06-28 10:14:59 +02:00
Jonas Platte e87b3def02 crypto: Add Store::room_keys_for_room_received_stream 2023-06-28 10:14:59 +02:00
Ivan Enderlin 07700abf75 feat: Cache the RoomListService's rooms
feat: Cache the `RoomListService`'s rooms
2023-06-28 08:58:45 +02:00
Ivan Enderlin 9ab4fa0a8b chore(sdk): Log the SyncOps
chore(sdk): Log the `SyncOp`s
2023-06-28 08:41:00 +02:00
Andy Balaam 86fe3364ed Add serialization, clear and extend to RingBuffer 2023-06-27 17:25:25 +00:00
Jonas Platte 81ca1c5072 ui: Add a test for thread message reply fallback 2023-06-27 19:23:14 +02:00
Jonas Platte 4ec8bec2fc ui: Treat thread fallback the same as a regular reply
… for now, until we add proper support for threads.
2023-06-27 19:23:14 +02:00
Benjamin Bouvier 98fed1d2eb chore: use smaller critical sections
This opens up a possible race condition where an embedder calls the method twice, generating two new rooms,
but then it's fine as long as they don't cache them somewhere, which we expect they don't.
2023-06-27 16:29:35 +02:00
Benjamin Bouvier e3df97421b chore: remove useless async 2023-06-27 16:27:31 +02:00
Jonas Platte b08480baea ui: Move message-sending loop start log event
… such that it gets the timeline builder's tracing span.
2023-06-27 16:18:04 +02:00
Benjamin Bouvier ccd5e877eb feat: Cache the RoomListService's rooms
That avoids recreating a timeline object every time a user calls `RoomListService::room()` with the same room id, so that should speed up
operations like fetching the latest event for rooms we've already entered before.
2023-06-27 16:05:26 +02:00
Damir Jelić fed583c5c6 Emit room keys after they have been persisted, not before. 2023-06-27 14:30:08 +02:00
Doug d4252c4e4a feat(bindings): Add user_agent parameter to authentication_service. 2023-06-27 12:59:22 +02:00
Ivan Enderlin 61202ec19a feat(common): Propose a simple RingBuffer implementation
feat(common): Propose a simple `RingBuffer` implementation
2023-06-26 19:52:57 +02:00
Ivan Enderlin ad1b9056ae feat(common): Add RingBuffer::is_empty. 2023-06-26 19:30:27 +02:00
aringenbach 47030e7883 ffi: Use toggle_reaction and update API 2023-06-26 16:08:50 +00:00
Ivan Enderlin d69be5ee75 feat(common): Propose a simple RingBuffer implementation.
This patch propose a very simple `RingBuffer` implementation based on
`std::collections::VecDeque`.
2023-06-26 17:49:41 +02:00
jonnyandrew 7e7996d43d ui: Add local echoes for reactions to Timeline 2023-06-26 15:17:48 +00:00
Ivan Enderlin 04580f75a8 chore(sdk): Log the SyncOps. 2023-06-26 16:04:11 +02:00
Jonas Platte 49b1e8732c Upgrade most of our dependencies
Still holding back js-sys and web-sys due to unresolved wasm-bindgen issues.
2023-06-26 14:32:24 +02:00
Ivan Enderlin ba422f861e fix(sdk): Change SlidingSyncList::room_list's capacity
fix(sdk): Change `SlidingSyncList::room_list`'s capacity
2023-06-26 14:16:05 +02:00
Ivan Enderlin 749911af60 fix(sdk): Change SlidingSyncList::room_list's capacity.
This patch changes the capacity of the internal buffer of
`ObservableVector` for `SlidingSyncList::room_list` from 16 to 4096.
With an increased capacity, we reduce the probability to send a
`VectorDiff::Reset` to subscribers. `Reset` are happening quite often
for apps using `matrix-sdk`, and it impacts their performance. This
patch tries to improve this situation. This `room-list` contains
`RoomListEntry`, which is can cheap in terms of memory, compared to the
impact of sending `Reset`s too often. That's a tradeoff.
2023-06-26 13:52:15 +02:00
Jonas Platte 0e1f74f617 Increase other sleep in test a bit 2023-06-26 11:36:24 +02:00
Jonas Platte b6353f82a8 ui: Improve logging for message-sending queue 2023-06-26 11:36:24 +02:00
Benjamin Bouvier 171c1cf25b chore: fix documentation
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-26 11:22:38 +02:00
Benjamin Bouvier b442d30848 feat: remove the in-memory cache for to_device_token in sliding sync
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-26 11:22:38 +02:00
Benjamin Bouvier 94fa888b7b feat: always enable the SS cache by default
This makes sure that the to-device prev_batch/since token is already saved to and reloaded from disk.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-26 11:22:38 +02:00
Benjamin Bouvier 69932adb7e chore: remove unreachable UI notifications module
Remnant from a bad merge/renaming.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-26 11:22:38 +02:00
Mauro 2c58c65add ffi: Allow disabling local notification filtering using push rules 2023-06-26 08:49:06 +00:00
Ivan Enderlin 8916eb6409 test(ui): Replace sleep by yield_now
test(ui): Replace `sleep` by `yield_now`
2023-06-23 16:37:00 +02:00
Jonas Platte 44ef302bc7 Increase sleep in test a bit
since it seems flaky in CI
2023-06-23 16:17:21 +02:00
Ivan Enderlin 40db35abe7 test(ui): Replace sleep by yield_now.
Eh, removing `sleep` from the tests is always a pleasure right?
2023-06-23 16:15:57 +02:00
Jonas Platte 9b802998b3 ui: Put retries in the message-sending queue 2023-06-23 14:03:27 +02:00
Jonas Platte 0a37ce50a8 ui: Allow retrying cancelled local echoes 2023-06-23 14:03:27 +02:00
Alfonso Grillo e72bae1a8f ffi: Add send_location api 2023-06-23 11:29:01 +00:00
Jonas Platte 4c24007cb8 ui: Add a queue to serialize message sending requests 2023-06-23 09:41:07 +02:00
Jonas Platte cb6d3c3c47 ui: Add a failing test for message ordering 2023-06-23 09:41:07 +02:00
David Langley 19ba18d788 ffi: Expose the senders of reactions 2023-06-23 08:56:16 +02:00
Ivan Enderlin 73de71bd42 feat(ui): Welcome to RoomListService
feat(ui): Welcome to `RoomListService`
2023-06-22 17:36:05 +02:00
Ivan Enderlin 1c6ad4a082 chore(ui): Address feedbacks. 2023-06-22 17:16:25 +02:00
Ivan Enderlin 9eadbc302f feat(ffi): Rename Client::room_list to Client::room_list_service. 2023-06-22 17:08:30 +02:00
Ivan Enderlin 93d619249c test(ui): Reduce latency of the tests. 2023-06-22 15:37:25 +02:00
Ivan Enderlin 35ee6db152 fix(ffi): Eh UniFFI, we want Tokio compat. 2023-06-22 14:59:51 +02:00
jonnyandrew 7fd5068faa ui: Deduplicate reaction senders in timeline 2023-06-22 12:42:49 +00:00
Ivan Enderlin 1631b5ba18 chore(ui): Use matrix_sdk::executor instead of tokio. 2023-06-22 14:15:10 +02:00
Valere 3fd55c0ab1 bindings: Ignore silently malformed userId in migration of tracked users (#2130)
* bindings: Ignore silently malformed userId in migration of tracked users
* Clean: collect will now never fail

Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-06-22 12:11:06 +00:00
Ivan Enderlin 083a79a408 doc(ui): Fix intra-links. 2023-06-22 14:08:09 +02:00
Ivan Enderlin f9fe7450ce Merge branch 'main' into feat-ui-roomlist-service 2023-06-22 13:48:00 +02:00
Ivan Enderlin d43d5b515e chore: Make Clippy happy. 2023-06-22 13:39:00 +02:00
Damir Jelić daa3944593 Bump Ruma 2023-06-22 13:20:37 +02:00
Benjamin Bouvier 679ec70200 feat: implement the full EncryptionSync (#2110)
* crypto: implement more primitives for the MemoryStore to work in tests

* crypto: change the shape of the `CryptoStoreLock` API

In particular:

- make the lock work across multiple threads of the same process trying to acquire it,
using `num_holders`.
- add a mechanism to get the lock only once (for the NSE process, in case the main app
had acquired the lock before).

* client: add a cross-process crypto store lock, enable it with `Encryption::enable_cross_process_store_lock`
* client: make `preshare_room_key` a critical section of the cross-process lock
* sliding sync: make it possible to define different timeouts for a `SlidingSyncInstance`

This will be handy for the NSE process on iOS, which has very little time to wait for the proxy's responses.

* feat: implement the `EncryptionSync` API (renamed from `Notification` API)
* fixup! client: add a cross-process crypto store lock, enable it with `Encryption::enable_cross_process_store_lock`
* feat: allow disabling e2ee / to-device in the RoomList API
* feat: use same SS id for main/NSE process, reload to-device token from disk before each encryption sync
* fix: better error handling if restoring the to-device token failed
* feat: add logs for the locking functions
* test: add a few tests for encryption sync
* feat: add `reload_caches` method in the `EncryptionSync` + FFI bindings
* chore: clean up FFI loop
* encryption sync: Remove unused errors, specialize some errors
* feat: include termination reason in the encryption sync loop
* feat: add more logs
* chore: fmt + clippy + doc
* comment: precise only in the presence of another process
* Tweak `room_list` APIs to include `_with_encryption` variants
* chore: rustfmt
2023-06-22 12:50:45 +02:00
Ivan Enderlin eb2213467a feat(ffi): Implement RoomList::loading_state. 2023-06-22 12:12:45 +02:00
Ivan Enderlin 398f70c9de feat(ui): Implement RoomListLoadingState.
The type is well documented. Go check it out :-).
2023-06-22 11:43:38 +02:00
Kévin Commaille 2b3d1080dc sdk: Allow to support several authentication APIs
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-22 11:21:50 +02:00
Kévin Commaille 7298df0db6 sdk: Move Session and SessionTokens to matrix_auth
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-22 11:21:50 +02:00
Kévin Commaille d6f9f08e30 sdk: Split Matrix authentication methods in a separate API
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-22 11:21:50 +02:00
Mauro Romito 528607f079 feat(bindings): get_notification_item filters out notifications given the push context 2023-06-22 11:09:45 +02:00
Ivan Enderlin c9e3d7988f feat(ui): Change how room_list::State is updated.
Instead of broadcasting an intermediate update for the `State`, it's
updated once after the sync.
2023-06-22 10:23:45 +02:00
aringenbach 726c1bca2c ui: Filter redacted reactions from the timeline 2023-06-21 16:21:39 +00:00
Ivan Enderlin d77a48cc2c feat(ffi): Implement RoomList::room. 2023-06-21 17:20:05 +02:00
Ivan Enderlin 40602e7bba chore(ffi): Update according to previous commits. 2023-06-21 17:11:26 +02:00
Ivan Enderlin b774110235 chore(ui): Move methods from RoomListService inside RoomList.
This patch moves `RoomListService::entries` and `::filtered_entries`
inside `RoomList`. It also implements `RoomList::new`. Finally,
it implements `RoomListService::all_rooms` and re-implement
`RoomListService::invites`.

Basically:

```rust
// 1.
room_list.entries().await?
// 2.
room_list.invites().await?
```

becomes:

```rust
// 1.
room_list.all_rooms().await?.entries()
// 2.
room_list.invites().await?.entries()
```

`all_rooms` and `invites` both return a `RoomList`.
2023-06-21 17:00:30 +02:00
Jonas Platte dccf0c29bf Update reldbg profile to optimize our own packages too
… and enable incremental compilation for it.
2023-06-21 16:36:40 +02:00
Ivan Enderlin b01bbe7e92 chore: Add missing copyright headers. 2023-06-21 16:29:55 +02:00
Ivan Enderlin dc061308bd chore(ui): Rename RoomList to RoomListService. 2023-06-21 16:29:03 +02:00
Ivan Enderlin 12a6f12461 feat(ui): Implement RoomList::stop_sync
feat(ui): Implement `RoomList::stop_sync`
2023-06-21 16:23:06 +02:00
Jonas Platte 895669e39b sdk: Upload thumbnail and attachment in parallel 2023-06-21 14:56:22 +02:00
Jonas Platte 54288cb4cb Fix clippy lints 2023-06-21 14:56:22 +02:00
Jonas Platte b883ec000a sdk: Clean up imports in encryption module 2023-06-21 14:56:22 +02:00
Jonas Platte 8a7da622d8 Rewrap comment 2023-06-21 14:56:22 +02:00
Ivan Enderlin e9c19c2110 doc(crypto-nodejs): Add docs on how to use tracing for local Node dev
Add docs on how to use tracing for local Node dev
2023-06-21 14:29:32 +02:00
Ivan Enderlin 9c62b3459f Merge pull request #2119 from matrix-org/valere/quick_fix_doc
Fix js binding bad comment
2023-06-21 14:17:46 +02:00
Ivan Enderlin f9452959a0 doc(ui): Fix a typo. 2023-06-21 13:52:14 +02:00
Ivan Enderlin 4ec917ca48 feat(ffi): Implement RoomList::is_syncing. 2023-06-21 11:58:44 +02:00
Ivan Enderlin 54fc0f38ea feat(ui): RoomList::sync no longer returns a TaskHandle.
Because there is `RoomList::stop_sync` now, which is better than dealing
with the `TaskHandle`.
2023-06-21 11:54:51 +02:00
Ivan Enderlin fe0b458403 chore(ffi): Update according to previous commits. 2023-06-21 11:53:58 +02:00
Ivan Enderlin 6e8e4bb39c feat(ui): Differentiate between error and termination in room_list::State.
This patch introduces `State::Error`, which replaces
`State::Termianted`. And a “new” `State::Terminated` state is added.

They do the same, but their semantics is different. `Error` is when an
error happened, and it's fine to restart the sync again. `Terminated`
is when a termination has been reached (either because SS sync-loop
has ended naturally, or because `RoomList::stop_sync` has been called),
in this case, it may not be fine to restart the sync automatically for
example.
2023-06-21 11:37:00 +02:00
Ivan Enderlin 7073e6f9e3 feat(ui): Remove the State::CarryOn state.
This patch removes the `State::CarryOn`. It turns out that `Running` and
`CarryOn` are doing exactly the same thing. So one of them is useless.
2023-06-21 11:14:29 +02:00
Ivan Enderlin f0bc6d6698 chore(ui): Rename State::FirstRooms and State::AllRooms.
This patch renames `State::FirstRooms` to `State::SettingUp`, and
`State::Running` as requested by users.

It hides the “inner Sliding Sync logic”, the Sliding Sync lists etc.
2023-06-21 11:12:51 +02:00
Ivan Enderlin a78ad89fdd feat(ffi): Implement RoomList::stop_sync.
This patch implements `RoomList::stop_sync` on the FFI bindings.

Technically, it's no more useful to store the `TaskHandle` of the
`sync`, but it's still here, in case of.
2023-06-21 09:22:50 +02:00
Ivan Enderlin ec5c1a3c70 feat(ui): Implement RoomList::stop_sync.
This patch implements `RoomList::stop_sync`. The goal is twofold:

1. It forces to stop the syncing, thus putting the state-machine into
   the `Terminated` state, which is semantically better than “stop
   polling the `sync`'s `Stream`”.

2. It literally forces to stop the syncing. It cancels pending futures,
   it cancels in-flight HTTP requests etc. It's a more robust way to
   stop the `RoomList` sync.
2023-06-21 09:20:44 +02:00
valere 1cc90c8ec0 Fix js binding bad comment 2023-06-21 09:11:09 +02:00
Valere 8a8074cada Add first_time_seen timestamp to devices 2023-06-21 08:49:44 +02:00
Ivan Enderlin 644410afe9 feat(ui): TimelineBuilder::build logs more data
feat(ui): `TimelineBuilder::build` logs more data
2023-06-20 21:12:55 +02:00
Ivan Enderlin 9755af5a9a Revert parts of #2111 because name is already cached in RoomInfo
Revert parts of #2111 because name is already cached in RoomInfo
2023-06-20 21:09:11 +02:00
Alfonso Grillo 673ac33579 ffi: Add location message type 2023-06-20 16:51:12 +00:00
Andy Balaam 5a0c35edb2 Revert parts of #2111 because name is already cached in RoomInfo 2023-06-20 14:58:17 +01:00
Nicolas Mauri 3f3fd58770 sdk: Add a Rules utility struct to manipulate a Ruleset 2023-06-20 14:56:33 +02:00
Ivan Enderlin a496471cf3 test(base): Tests for finding DM rooms
Tests for finding DM rooms
2023-06-20 12:37:47 +02:00
Andy Balaam 2a2ce5f05c Already-passing tests for get_dm_room including left rooms 2023-06-20 11:05:37 +01:00
Andy Balaam 40aab0c426 Already-passing tests for keeping users in direct_targets when they leave a DM 2023-06-20 11:05:37 +01:00
Andy Balaam 0e5d8bc904 Fix double-clone 2023-06-20 11:25:29 +02:00
Andy Balaam 02449a73ea Fix clippy warnings 2023-06-20 11:25:29 +02:00
Andy Balaam 7f8bc8f1c2 Avoid holding a lock over an await 2023-06-20 11:25:29 +02:00
Andy Balaam 149a9d4099 Cache room display name if it comes in from sync 2023-06-20 11:25:29 +02:00
Andy Balaam 75eb94357e Split out tests for room display names 2023-06-20 11:25:29 +02:00
Andy Balaam d84c8d91b5 Fix typo in comment 2023-06-20 11:25:29 +02:00
Jonas Platte 5273fa6f42 sdk: Move target-specific HTTP code into new submodules 2023-06-20 11:16:13 +02:00
Jonas Platte 4c1a351ead sdk: Remove HttpSend in favor of allowing reqwest customization 2023-06-20 11:16:13 +02:00
Jonas Platte ba9d8294b4 ffi: Make upload progress observable 2023-06-20 11:16:13 +02:00
Jonas Platte ac140c192a Make upload progress observable 2023-06-20 11:16:13 +02:00
Jonas Platte a668822fec Simplify HttpClient::send_request signature 2023-06-20 11:16:13 +02:00
Richard van der Hoff 6fc90609b6 Release crypto-js 0.1.0-alpha.11 (#2112) 2023-06-19 18:09:52 +00:00
Jonas Platte 93c911add3 ui: Use method syntax for shared::Observable methods 2023-06-19 16:46:43 +02:00
Benjamin Bouvier 55aad67338 Remove the sqlite-lock binary from the main repo
Will move it to a personal repository of mine.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-19 15:42:58 +02:00
Andrew Ferrazzutti c618094c19 Retitle tracing section 2023-06-19 09:11:15 -04:00
Ivan Enderlin 16a2121291 feat(ui): TimelineBuilder::build logs more data.
This patch updates `tracing::instrument` on `TimelineBuilder::build` so
that we can detect the circumstance of slow cases.
2023-06-19 15:06:55 +02:00
Andrew Ferrazzutti 1f141fc372 Format README.md 2023-06-19 08:25:27 -04:00
Kévin Commaille 6b40db4669 sdk: Keep all the discovered AuthenticationServerInfo
It has an account field besides the issuer field.
Also store it as immutable, the data used for authentication will be
stored in another variable.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-19 13:08:45 +02:00
Kévin Commaille 2b70d1c8c6 sdk: Export Invite
It's the type returned from Invited::invite_details() but it is not
available publicly.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-19 13:02:17 +02:00
Ivan Enderlin d105b72554 fix(sdk): Remove the Sliding Sync retry mechanism on M_UNKNOWN_POS
fix(sdk): Remove the Sliding Sync retry mechanism on `M_UNKNOWN_POS`
2023-06-19 12:37:48 +02:00
Ivan Enderlin 67ade0a2da doc(crypto): Fix a typo
doc(crypto): Fix a typo
2023-06-19 12:35:14 +02:00
Ivan Enderlin 0c85b178ac test(ui): Fix Notification test. 2023-06-19 12:16:26 +02:00
Ivan Enderlin 87a8ac7420 doc(crypto): Fix a typo. 2023-06-19 12:06:51 +02:00
Ivan Enderlin 30b7c4bd7f fix(sdk): Remove the Sliding Sync retry mechanism on M_UNKNOWN_POS.
`SlidingSync::sync` had a legacy behaviour when a `M_UNKNOWN_POS`
error was received from the server: It was resetting `pos` and sticky
parameters before re-running a sync-loop iteration, hoping to get a
valid response from the server after that. This retrying
mechanism was running up to 3 times in row (represented by the
`MAXIMUM_SLIDING_SYNC_SESSION_EXPIRATION` constant) before stopping the
`sync` for real.

While it seemed a good idea, it actually brings numerous problems:

1. Each iteration in the sync-loop generates a new request, thus making
   the `ranges` of the requests to move forwards. For `SlidingSyncList`
   that are in `Selective` sync-mode, there is no problem, but for
   `Growing` or `Paging` sync-modes, the `ranges` increased. Thus,
   when a `SlidingSync` session expires, instead of returning to
   the caller to do something clever (like what `RoomList` does: start
   again with a small range so that the “first” sync after a session
   expiration is guaranteed to be fast), it was running larger and
   larger requests, up to 3 times.
2. `M_UNKNOWN_POS` _is_ an error. Yes, `SlidingSync` must reset `pos`
   and must invalidate sticky parameters, but the `sync` must be
   stopped, and the error must be returned so that the caller can do
   something about it. Until now, this error was likely to be missed by
   the caller.
3. This legacy mechanism was forbidding `SlidingSync::sync`'s caller to
   do something with this special error. And since the caller was blind to
   this error, it disallowed more smart error management.

This patch removes this legacy retry mechanism entirely. When
`M_UNKNOWN_POS` is received from the server, `pos` is reset and sticky
parameters are invalidated as before, but the error is returned like any
other error.

This patch renames and updates an existing test that was testing sticky
parameters invalidation on `M_UNKNOWN_POS`, to include some assertions
on `pos` and to ensure that the sync-loop is stopped accordingly.
2023-06-19 11:43:27 +02:00
Benjamin Bouvier 4d3ca15be3 feat(ui): Implement Notification API (#2023)
This is the first PR for splitting the sync loop into two. This offers a new high-level API, `NotificationApi`, that makes use of a separate `SlidingSync` instance which sole role is to listen to to-device events and e2ee; it's pre-configured to do so. That means we're not force-enabling e2ee and to-device by default for every sliding sync instance, and as such we won't either generate Olm requests to the home server in general.

In the future, this new high-level API will hide some low-level dirty details so that its can be instantiated in multiple processes at the same time (lock across process, invalidate and refill crypto caches, etc.).

An embedder who would want to make use of this would need the following:

- a main sliding sync instance, without e2ee and to-device. Using the `matrix_sdk_ui::RoomList` would be the best bet, at this time.
- an instance of this `matrix_sdk_ui::NotificationApi`, with a different identifier.

Note that this is not ready to be used in an external process; or it will cause the same kind of issues that we're seeing as of today: invalid crypto caches resulting in UTD, etc.

Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/1961.
2023-06-19 08:56:58 +00:00
Damir Jelić 7c393d73c4 Merge branch 'openqrnch/main' 2023-06-19 09:40:14 +02:00
Damir Jelić 75cf572968 Fix the formatting of the sync_with_result_callbac() docstring 2023-06-19 09:39:34 +02:00
Jan Danielsson bccd3412c1 Add a missing backtick in sync_with_result_callback() documentation. 2023-06-18 15:29:58 +02:00
Ivan Enderlin 6d4874e147 doc(ui): Fix a typo. 2023-06-18 09:20:57 +02:00
Andrew Ferrazzutti bb1bfbcb48 Add docs on how to use tracing for local Node dev 2023-06-16 11:51:10 -04:00
Richard van der Hoff ef0c230bd3 crypto-js: Simplify response type of Sas::confirm (#2066)
On the javascript side, everything is just an `OutgoingRequest`, so we may
as well return a single array rather than a tuple.
2023-06-16 16:19:35 +01:00
Damir Jelić bddc88472a Clarify the comment about creating a Olm session twice
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-06-16 16:56:09 +02:00
Damir Jelić aab3d00246 Log if a session was created using a fallback key 2023-06-16 16:56:09 +02:00
Damir Jelić a94e2f06ee Ensure that we're not creating the same session twice
Usually it's impossible to create a Olm session from a pre-key message
twice. The one-time key that should be used for the 3DH step will be
used up and we're going to throw a `MissingOneTimeKey` error.

This used to be true and unproblematic until we added fallback keys,
these keys will not get discarded immediately after they have been used
once.

This means that a pre-key message, for which we already have a Session,
but decryption for it fails, might create a new Session overwriting the
existing one which will essentially reset the ratchet.
2023-06-16 16:56:09 +02:00
Damir Jelić 817dcde4d8 Test that we're not able to decrypt replayed messages 2023-06-16 16:56:09 +02:00
Benjamin Bouvier 76ed3511b5 Add a value-based lock in the CryptoStores (#2049)
This implements a value-based lock in the crypto stores. The intent is to use that for multiple processes to be able to make writes into the store concurrently, while still cooperating on who does them. In particular, we need this for #1928, since we may have up to two different processes trying to write into the crypto store at the same time.

## New methods in the `CryptoStore` trait

The idea is to introduce two new methods touching **custom values** in the crypto store:

- one to atomically insert a value, only if it was missing (so, not following the semantics of `upsert` used in the `set_custom_value`) 
- one to atomically remove a custom value

Those two operations match the semantics we want:

- take the lock only if it ain't taken already == insert an entry only if it was missing
- release the lock = remove the entry

By looking at the number of lines affected by the query, we can infer whether the insert/remove happened or not, that is, if we managed to take the lock or not.

## High-level APIs

I've also added an high-level API, `CryptoStoreLock`, that helps managing such a lock, and adds some niceties on top of that:

- exponential backoff to retry attempts at acquiring the lock, when it was already taken
- attempt to gracefully recover when the lock has been taken by an app that's been killed by the environment
- full configuration of the key / value / backoff parameters

While it'd be nice to have something like a `CryptoStoreLockGuard`, it's hard to implement without being racy, because of the `async` statements that would happen in the `Drop` method (and async drop isn't stable yet).

## Test program

There's also a test program in which I shamelessly show my rudimentary unix skills; I've put it in the `labs/` directory but this could as well be a large integration test. A parent program initially fills a custom crypto store, then creates a `pipe()` for 1-way communication with a child created with `fork()`; then the parent sends commands to the child. These commands consist in reading and writing into the crypto store, using a lock. And while the child attempts to perform these operations, the parent tries hard to get the lock at the same time. This helps figuring out a few issues and making sure that cross-process locking would work as intended.
2023-06-16 13:05:54 +00:00
Ivan Enderlin 1660c71dfd feat(ui): Add bump_event_types for all_rooms in RoomList
feat(ui): Add `bump_event_types` for `all_rooms` in `RoomList`
2023-06-16 14:52:10 +02:00
Ivan Enderlin 646fb35b3a feat(ui): Add bump_event_types for all_rooms in RoomList.
This patch configures the `bump_event_types` paramter for the
`all_rooms` list in `RoomList`.
2023-06-16 14:49:08 +02:00
Benjamin Bouvier bae1a71c81 feat: make OlmMachine resettable (#2091)
* feat: make `OlmMachine` resettable by making it an Arc<RwLock> instead of a OnceCell
* chore: fix e2e-encryption scoping
2023-06-16 12:39:08 +00:00
Ivan Enderlin 3d859674a8 fix(ui): Enable SS caching on RoomList
fix(ui): Enable SS caching on `RoomList`
2023-06-16 14:36:21 +02:00
Ivan Enderlin a75808e338 fix(ui): Enable SS caching on RoomList. 2023-06-16 14:31:45 +02:00
Ivan Enderlin dc06893130 fix(sdk): Disable the receipts extension temporarily
fix(sdk): Disable the `receipts` extension temporarily
2023-06-16 14:06:29 +02:00
Ivan Enderlin 489898fd40 fix(sdk): Disable the receipts extension temporarily.
Please see https://github.com/matrix-org/matrix-rust-sdk/issues/2037.
2023-06-16 13:40:38 +02:00
Ivan Enderlin 85b6eaa4c7 feat(ffi): Implement RoomList::invites
feat(ffi): Implement `RoomList::invites`
2023-06-16 13:31:53 +02:00
Ivan Enderlin 305d55d551 feat(base) In Sliding Sync, find out which rooms we have left from state events
In Sliding Sync, find out which rooms we have left from state events
2023-06-16 13:27:28 +02:00
Ivan Enderlin bae6fc71d0 test(ui): Add a test specifically for RoomList::invites. 2023-06-16 13:10:36 +02:00
Ivan Enderlin 7a1d59e9a2 feat(ffi): Implement RoomList::invites. 2023-06-16 12:43:36 +02:00
Ivan Enderlin e09a44831b feat(ui): Implement RoomList::invites. 2023-06-16 12:43:12 +02:00
Ivan Enderlin 5d82d5db89 feat(ui): Add the invites list in the RoomList.
The `invites` list is added when the first rooms are loaded, so that it
doesn't slow the first initial start up.
2023-06-16 12:28:42 +02:00
Richard van der Hoff 6199ca069c crypto-js: Add register_changes_callback methods to the verification classes (#2067) 2023-06-16 11:25:50 +01:00
Ivan Enderlin c9a9a5c20a fix(ui): SlidingSync::subscribe_to_room marks room as having missing members
fix(ui): `SlidingSync::subscribe_to_room` marks room as having missing members
2023-06-16 11:45:37 +02:00
Ivan Enderlin a99a7b4a5a test(sdk): Test that room subscription makes members not synced. 2023-06-16 11:23:11 +02:00
Ivan Enderlin c515643442 doc(sdk): Fix typos. 2023-06-16 10:35:32 +02:00
Ivan Enderlin d45f871106 doc(sdk): Fix intralink. 2023-06-16 10:34:48 +02:00
Ivan Enderlin 3a70b2e8ab fix(ui): SlidingSync::subscribe_to_room marks room as having missing members.
Fix https://github.com/matrix-org/matrix-rust-sdk/issues/2004.
2023-06-16 09:44:36 +02:00
Jonas Platte db5c9d8c4b ffi: Add Room::get_timeline_event_content_by_event_id 2023-06-15 17:24:18 +02:00
Ivan Enderlin ec1172c353 feat(ui+ffi): Implement RoomList::entries_loading_state
feat(ui+ffi): Implement `RoomList::entries_loading_state`
2023-06-15 17:20:42 +02:00
Ivan Enderlin 61d4850a66 chore: Make Clippy happy. 2023-06-15 16:18:08 +02:00
Ivan Enderlin 1f6a0b23f0 fix(ui): Set visible_rooms with a default range
fix(ui): Set `visible_rooms` with a default range
2023-06-15 16:08:17 +02:00
Ivan Enderlin 5673422831 test(ui): Use stream_assert to simplify the code. 2023-06-15 15:58:08 +02:00
Ivan Enderlin d935f52c86 doc(sdk): Update documentation of SlidingSyncList::state_stream. 2023-06-15 15:53:06 +02:00
Ivan Enderlin 0ff9073a14 feat(ffi): Implement RoomList::entries_loading_state.
This patch implements `RoomList::entries_loading_state`.
2023-06-15 15:50:21 +02:00
Ivan Enderlin a073c1422c test(ui): Test RoomList::entries_loading_state. 2023-06-15 15:45:30 +02:00
Ivan Enderlin 4e92738c28 feat(ui): Implement RoomList::entries_loading_state.
This patch implements `RoomList::entries_loading_state`, which
is a basic forwarding from the `all_rooms` sliding sync list'
`state_stream()` result.
2023-06-15 15:45:30 +02:00
Ivan Enderlin db6798321c feat(sdk): SlidingSyncList::state_stream returns a tuple.
This patch updates `SlidingSyncList::state_stream` to return
a tuple `(SlidingSyncListLoadingState, impl Stream<Item =
SlidingSyncListLoadingState>)`.
2023-06-15 15:45:30 +02:00
Ivan Enderlin f10f0d017d feat(sdk): Rename SlidingSyncState to SlidingSyncListLoadingState.
This patch renames `SlidingSyncState` to `SlidingSyncListLoadingState`
because:

1. It's about a list information,
2. It's about the loading state, not a generic state.
2023-06-15 15:45:28 +02:00
Ivan Enderlin 1c480398d2 fix(ui): Set visible_rooms with a default range.
The MSC3575 says that if no `ranges` for a list is provided, it defaults
to `0..=99`. We don't want that! This patch sets the default value to
`0..=19` for the `visible_rooms`.
2023-06-15 15:37:35 +02:00
Jonas Platte 52d2fa1a72 ffi: Clean up 2023-06-15 15:20:46 +02:00
Jonas Platte 12df1f38ed ffi: Remove remaining callback interfaces from UDL 2023-06-15 15:20:46 +02:00
Jonas Platte 899c0d59e6 ffi: Remove sliding sync things from UDL 2023-06-15 15:20:46 +02:00
Jonas Platte 867b3665d2 ffi: Remove re-exports from timeline module 2023-06-15 15:20:46 +02:00
Jonas Platte daf59356cb ffi: Remove room list from UDL 2023-06-15 15:20:46 +02:00
Jonas Platte 53ae4362f6 ffi: Remove unused public Rust API 2023-06-15 15:20:46 +02:00
Jonas Platte b789b9e063 ffi: Remove room / timeline things from UDL 2023-06-15 15:20:46 +02:00
Jonas Platte b1c8859eb9 Upgrade UniFFI 2023-06-15 15:20:46 +02:00
Jonas Platte 0e618bea5c ui: Don't use TryFutureExt where not necessary 2023-06-15 14:37:40 +02:00
Ivan Enderlin 31d834048f feat(fii): Implement RoomList::apply_input
feat(fii): Implement `RoomList::apply_input`
2023-06-15 13:22:09 +02:00
Benjamin Bouvier 1fd039c64f sliding sync: lazily generate and include the transaction id, only if it's useful (#2063)
* feat: lazily generate and include the transaction id, only if it's useful
* chore: add a small `LazyTransactionId` wrapper that ensures it's only created once

---------

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-15 10:30:24 +00:00
Kévin Commaille 16a63d352c base: Remove the session field from StateChanges
It is never set nor used.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-15 11:12:40 +02:00
Ivan Enderlin 59565657fa feat(ffi): Implement RoomList::apply_input.
This patch implements `RoomList::apply_input`. Usage example:

```rust
room_list.apply_input(RoomListInput::Viewport { ranges: vec![RoomListRange { start: 10, end_inclusive: 20 }]}).await?;
```
2023-06-15 11:12:17 +02:00
Ivan Enderlin ea9a85395a chore(ui): Add missing trailing commas. 2023-06-15 11:11:48 +02:00
Jonas Platte 78135fcce9 ffi: Add message_event_content_new 2023-06-15 10:44:40 +02:00
Jonas Platte 7feba6f814 ffi: Use Duration instead of u64
Resolves FIXME comment.
2023-06-15 10:44:40 +02:00
Andy Balaam 7ca3686aea Fix formatting after merge 2023-06-15 09:37:27 +01:00
Ivan Enderlin 7756b6d725 feat(ui): Implement room subscriptions in RoomList + notification counts
feat(ui): Implement room subscriptions in `RoomList` + notification counts
2023-06-15 10:28:04 +02:00
Ivan Enderlin c07bb0ec39 test(ui): Test that RoomList receives State updates even if the same.
`RoomList::state` provides a `Subscriber` to the `State`. This patch
modifies the way the state is tested, to ensure that there is always
an update broadcasted even if the state is the same (e.g. if the state
moves from `CarryOn` to `CarryOn`).
2023-06-15 09:55:57 +02:00
Ivan Enderlin ddffa00589 test(ui): Test Room::*unread_notifications(). 2023-06-15 09:40:55 +02:00
Ivan Enderlin 6e1de8a5ee fix(ffi): RoomListItem::full_room returns a Room with a Timeline. 2023-06-15 09:26:33 +02:00
Ivan Enderlin 23d5655901 feat(ui): room_list::RoomInner holds Arc to Timeline.
This patch updates `RoomInner::timeline` and `::sneaky_timeline` to
`AsyncOnceCell<Arc<Timeline>>`. Adding `Arc` allows to copy the timeline
if necessary more easily.
2023-06-15 09:24:47 +02:00
Richard van der Hoff 6b45749e17 crypto-js: Add new methods to VerificationRequest (#2068)
A couple of useful methods for accessing things in `VerificationRequest`.
2023-06-14 15:46:36 +01:00
Andy Balaam e9e1afb5a5 Merge main into andybalaam/sliding-sync-reinvite (using imerge) 2023-06-14 15:39:26 +01:00
Andy Balaam 22fd44df10 Fix comments from review feedback 2023-06-14 15:31:25 +01:00
Jonas Platte b4cd0c71bf ui: Add loading indicator before waiting for prev_batch token
… in Timeline::paginate_backwards.
2023-06-14 14:00:58 +02:00
Kévin Commaille b4fdfee7f0 base: Use batch methods in Room::get_members
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Kévin Commaille 38fc1f7b15 base: Add method to construct RoomMember from parts
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Kévin Commaille e32e9b5a22 base: Add state store method to fetch several display_names at once
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Kévin Commaille 7cba6d0849 base: Add state store method to fetch several presence events at once
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Kévin Commaille b8abd1c022 base: Add state store method to fetch several profiles at once
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Kévin Commaille 4103d1b3e3 sdk: Add room method to fetch several state events at once
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Kévin Commaille f740195eb6 base: Add state store method to fetch several state events at once
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 13:51:52 +02:00
Jonas Platte ae4ead5550 Upgrade typos CI action
… and update the config file to reduce check flakiness.
2023-06-14 12:31:32 +02:00
Jonas Platte 820d3aff65 Rewrap base64 test strings 2023-06-14 12:31:32 +02:00
Jonas Platte b3017a1073 Fix typos 2023-06-14 12:31:32 +02:00
Ivan Enderlin b9c27b5c63 feat(ui): Implement Room::*unread_notifications. 2023-06-14 12:15:16 +02:00
Ivan Enderlin 1bc455f75b feat(ffi): Room:add_timeline_listener returns a …Result.
This patch updates `Room::add_timeline_listener` to return a `RoomTimelineListenerResult`, a new type defined as:

```rust
pub RoomTimelineListenerResult {
    items: Vec<Arc<TimelineItem>>,
    items_stream: TaskHandle,
}
```

It is not possible to cancel the `items_stream` by cancelling the
`TaskHandle`. Without this, dropping `Room` won't drop the `Timeline`,
as a clone is moved inside the spawned task. As a consequence, it will
endlessly call the listener.
2023-06-14 11:56:07 +02:00
Ivan Enderlin 97e4a5cab0 chore(ffi): Remove RoomListItem::timeline.
What the FFI user wants is to subscribe a listener to the
timeline updates. This feature is already supported by
`room_item.full_room().add_timeline_listener()`.  So we can safely
remove `RoomListItem::timeline` as we are sure it's never going to be
used for now.
2023-06-14 11:13:06 +02:00
Ivan Enderlin 192b9ce808 feat(ui+ffi): Implement Room::id as a shortcut.
It's possible to do `room.inner_room().room_id()` but it's just simpler
to call `room.id()`. This patch adds this shortcut.

It's especially useful for FFI users, where creating a “full
room” (`room_item.full_room().room_id()`) may be expensive.
2023-06-14 10:59:03 +02:00
Ivan Enderlin dba397d470 feat(ffi): Add RoomListItem::subscribe and ::unsubscribe. 2023-06-14 10:56:59 +02:00
Ivan Enderlin 712b395310 feat(ui): Add Room::subscribe and ::unsubscribe.
This patch adds the `subscribe` and `unsubscribe` method on `Room`.

To achieve that, `Room` receives an `Arc<SlidingSync>`, as the
subscription methods are on `SlidingSync`. It's just easier to put them
on `Room` for the API consumer. It makes the API also more elegant.

Finally, the patch adds the appropriate test.
2023-06-14 10:51:37 +02:00
Kévin Commaille eb5af4287f sdk: Allow to get rooms filtered by room state
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 10:45:37 +02:00
Kévin Commaille c978fa6d40 base: Deprecate BaseClient::get_stripped_rooms
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 10:45:37 +02:00
Kévin Commaille ac8ea4786c base: Deprecate StateStore::get_stripped_room_infos
It is now unused.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 10:45:37 +02:00
Kévin Commaille 281870b33f base: Remove stripped rooms list from Store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 10:45:37 +02:00
Kévin Commaille bcd7e92a94 base: Allow to get rooms filtered by state
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 10:45:37 +02:00
Kévin Commaille ea219d836e base: Do not separate stripped room info
Since stripped and non-stripped room infos use the same types,
the separation is not necessary anymore.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-14 10:45:37 +02:00
Damir Jelić f67c592259 Properly support the hkdf-hmac-sha256.v2 MAC method for the SAS verification (#2064) 2023-06-14 10:17:22 +02:00
Ivan Enderlin 0db5a6a25d Merge branch 'main' into pr/2058 2023-06-14 09:55:31 +02:00
Ivan Enderlin 2c871807a3 feat(ui+ffi): Add various features to RoomList
feat(ui+ffi): Add various features to `RoomList`
2023-06-14 09:22:24 +02:00
Ivan Enderlin f55c1021c4 Merge pull request #2065 from matrix-org/rav/fix-docs
crypto-js: improvements to the documentation
2023-06-14 08:35:59 +02:00
Richard van der Hoff f78a2951e4 more doc fixes 2023-06-13 22:10:48 +01:00
Richard van der Hoff a8468cba59 crypto-js: improvements to the documentation
... mostly, writing down what things actually return.
2023-06-13 21:54:19 +01:00
Damir Jelić 48a24a6aed Use the short auth strings from the start content when accepting a verification (#2061)
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-06-13 17:33:57 +00:00
Benjamin Bouvier a79d519ff9 sliding sync: always fall back to the auto-discovered proxy URL, if any
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-13 19:33:30 +02:00
Jonas Platte 47a67d1d67 Upgrade Ruma 2023-06-13 18:33:28 +02:00
Jonas Platte adb9e60fbe common: Add executor::JoinHandle
… and simplify wasm spawn implementation.

This reduces the differences on wasm vs. non-wasm. Of course it's still
possible to rely on details of the different error types, but at least
both implement a few common traits:
`Debug`, `Display`, `Error`.
2023-06-13 16:50:33 +02:00
Andy Balaam 240a7f7aae Make set_state public to avoid unused warning 2023-06-13 13:43:46 +01:00
Andy Balaam f36a5b8cd7 Deserialise events early so we don't have to do it multiple times
We pass the already-deserialised event in to handle_state and
process_sliding_sync_room_membership, to avoid deserialising inside both
of them.
2023-06-13 13:05:14 +01:00
Andy Balaam 451398612a In Sliding Sync, find out which rooms we have left from state events
Look through m.room.member events when processing Sliding Sync
responses, finding those that refer to our user's membership, so that we
can recognise which rooms we have left.
2023-06-13 13:05:14 +01:00
Benjamin Bouvier 8aa12c929a chore: group GossipMachine fields inside an Arc-struct
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-13 12:28:37 +02:00
Andy Balaam 5c8a5466cf Use async_test to mark sliding sync tests 2023-06-13 12:15:49 +02:00
Andy Balaam 9a3060793c Extract a function for processing misc properties of a room in sliding sync 2023-06-13 12:15:49 +02:00
Andy Balaam 085c9767f0 Extract a function for processing membership of a room in sliding sync 2023-06-13 12:15:49 +02:00
Jonas Platte 2c71556ef2 Upgrade opentelemetry dependencies 2023-06-13 11:08:45 +02:00
Jonas Platte e78dbaf7c6 ffi: Don't require native-tls 2023-06-13 10:33:52 +02:00
Ivan Enderlin 15199316d3 doc(ui): Fix an intra-link. 2023-06-13 01:30:49 +02:00
Ivan Enderlin 1c8772848a feat(ui): Add the required state m.room.power_levels for all_rooms in RoomList. 2023-06-13 01:24:43 +02:00
Ivan Enderlin 9f6bc7d35f feat(ui): Configure filters for RoomList lists. 2023-06-13 01:24:43 +02:00
Ivan Enderlin 65959b07a4 feat(ui): Configure required_state for all_rooms in RoomList. 2023-06-13 01:24:43 +02:00
Ivan Enderlin 901deaf8e0 feat(ui): Enable common extensions on RoomList. 2023-06-13 01:24:43 +02:00
Ivan Enderlin 370083ee03 feat(ui,ffi): Add getter for matrix_sdk(_ffi)::Room. 2023-06-13 01:24:43 +02:00
Ivan Enderlin 5c01917f42 chore(ui): Split matrix_sdk_ui::room_list::mod.rs into smaller modules.
No code changes. This patch is just moving things around.
2023-06-13 01:24:43 +02:00
Ivan Enderlin 3547bd2f54 feat(ffi): Implement RoomList API
feat(ffi): Implement `RoomList` API
2023-06-13 01:23:24 +02:00
Ivan Enderlin 742ccea5ef doc(ffi): Fix a typo. 2023-06-13 00:37:14 +02:00
Ivan Enderlin 0233d65f02 In sliding sync, do all the same processing on an invited room as a joined one
In sliding sync, do all the same processing on an invited room as a joined one
2023-06-13 00:28:11 +02:00
Ivan Enderlin c65e98895a test(ui): Fix a test. 2023-06-13 00:27:26 +02:00
Ivan Enderlin d5211445a5 chore: Make Clippy happy. 2023-06-13 00:21:50 +02:00
Ivan Enderlin 235efaa85c fix(ffi): Do not overwrite Client's sliding_sync_proxy everytime.
The comment explains the fix correctly.
2023-06-13 00:12:41 +02:00
Ivan Enderlin b85dff347a chore(ffi): Simplify code and remove one method. 2023-06-12 23:36:35 +02:00
Ivan Enderlin dec1129106 chore(ffi): Remove Client::sliding_sync_proxy.
Instead of storing `sliding_sync_proxy` inside the `Client`, this patch
updates the code to store it inside `matrix_sdk::Client` directly.

That way, there is unique place where to store the sliding sync proxy
URL.
2023-06-12 23:29:23 +02:00
Ivan Enderlin 9bcc50fe2f feat(sdk): Client::sliding_sync_proxy is a StdRwLock.
This patch changes `matrix_sdk::Client::sliding_sync_proxy` to be a
`std::sync::RwLock<Option<Url>>` instead of `tokio::sync::RwLock<_>`.
It means that all methods reading or writing this field are sync instead
of async, which makes the code a lot more easier. Having an async-aware
lock wasn't necessary here.
2023-06-12 23:15:03 +02:00
Ivan Enderlin 7636a069b7 fix(ffi): Rollback how Sliding Sync proxy URL is computed.
I guess I know what's happening but I rollback some previous commits to
be sure it comes back on track.
2023-06-12 17:07:59 +02:00
Ivan Enderlin 8f102af801 chore: Make Clippy happy. 2023-06-12 16:47:22 +02:00
Ivan Enderlin 069743f3e1 feat(sdk): Change how Client::sliding_sync_proxy is represented. 2023-06-12 16:47:22 +02:00
Ivan Enderlin 38f8ebb6b9 feat(ffi): Add ability to force a Sliding Sync proxy URL from a restored session. 2023-06-12 16:47:22 +02:00
Andy Balaam f6d707cce8 Merge main into andybalaam/sliding-sync-process-unify-invited (using imerge) 2023-06-12 13:40:07 +01:00
Jonas Platte f883826db0 ffi: Add Room::cancel_send 2023-06-12 14:20:51 +02:00
Jonas Platte 4541ef6b90 sdk: Add Timeline::cancel_send 2023-06-12 14:20:51 +02:00
Benjamin Bouvier 29ddeb45d9 feat(sdk): implement sticky parameters (#1948)
* chore: add comments explaining what the position markers are
* feat(sdk): add scaffolding for sticky parameters
* test(sdk): add tests for the sticky parameters API
* feat(sdk): include the bump_event_types in the sticky parameters
* WIP: add TODO comments for deeply nested sticky parameters
* test(sdk): add extra test for sticky parameters
* feat: add extensions in the sticky parameters + test request generation + test since token
* chore: fix merge + get rid of unused inner extensions
* feat: use sticky parameters for lists too
* chore: Introduce the StickyManager, a reusable way to manage per-data sticky parameters
* chore: move the sticky scaffolding to its own module
* chore: clippy + fmt
* chore: get rid of `update_to_device_token`
* review: append SlidingSync prefix to Stick* data structures
* address review comments
* Replace nbsp with regular space
* Get rid of a write-access to a lock (because thanks inner mutability!)
* Add an integration test when losing `pos` in sticky parameters, and avoid `block_on`

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-12 10:46:13 +00:00
Ivan Enderlin 790dc47fca feat(ffi): Make RoomList.room non-async. 2023-06-12 12:41:12 +02:00
Ivan Enderlin 199f5708c0 chore(sdk): Tidy sliding sync processing code
Tidy sliding sync processing code
2023-06-12 11:37:40 +02:00
Andy Balaam f4aed74fb1 Fix formatting 2023-06-12 09:50:04 +01:00
Andy Balaam 323aaffe34 Merge main into andybalaam/sliding-sync-process-tidy (using imerge) 2023-06-12 09:37:37 +01:00
Andy Balaam 9a5291b2a9 Test canonical aliases in invited rooms via sliding sync 2023-06-12 10:34:04 +02:00
Andy Balaam 1e24542dd3 Handle required state in invited rooms as well as normal 2023-06-12 10:34:04 +02:00
Andy Balaam dcd5a27a2f Rename room_to_add->room_to_store 2023-06-12 10:34:04 +02:00
Andy Balaam dafee483fa Refactor process_sliding_sync to extract a method for dealing with rooms 2023-06-12 10:34:04 +02:00
Andy Balaam 0b4fba81d8 Test for adding an invited room to the client and invite list 2023-06-12 10:34:04 +02:00
Andy Balaam 34a56a70a0 Test for finding avatars in invite rooms 2023-06-12 10:34:04 +02:00
Andy Balaam 76a7ad0cbf Test for finding an avatar in a room via sliding sync 2023-06-12 10:34:04 +02:00
Ivan Enderlin 81628d15b8 doc(ffi): Fix a link. 2023-06-12 10:06:57 +02:00
Ivan Enderlin 39a4d039dd chore(ffi): Remove ability to use a custom sliding sync proxy URL. 2023-06-12 09:58:33 +02:00
Ivan Enderlin d24a1d8d6d feat(ui): Update the Sliding Sync proxy URL when creating RoomList. 2023-06-12 09:21:08 +02:00
Ivan Enderlin 2f433138dd chore(ffi): Make Clippy happy. 2023-06-12 09:07:39 +02:00
Ivan Enderlin 6301f32ee5 chore(ffi): Rename RoomListRoom to RoomListItem. 2023-06-12 09:07:39 +02:00
Ivan Enderlin 7ae8ee14eb feat(ffi): RoomListRoom::name and ::latest_event are non-async. 2023-06-12 09:07:39 +02:00
Ivan Enderlin 070965fc87 feat(ffi): Implement RoomList::rooms.
This patch implements `RoomList::rooms` to fetch one room. The type
name is `RoomListRoom` to avoid any collision with an existing `Room`
type already.

`RoomListRoom` implements `name`, `timeline` and `latest_event`.
2023-06-12 09:07:39 +02:00
Ivan Enderlin e2480be47f feat(ffi): Make RoomList::entries async.
Because we can!
2023-06-12 09:07:39 +02:00
Ivan Enderlin cb51c766a8 feat(ffi): Rename “observer” to “listener”. 2023-06-12 09:07:39 +02:00
Ivan Enderlin 68c19f4129 feat(ffi): First step for RoomList in FFI bindings. 2023-06-12 09:07:39 +02:00
Ivan Enderlin 5416ba06f5 feat(ui): Merge RoomList::state and RoomList::state_stream.
By returning a `Subscriber`, one can call `Subscriber::get` to get the
inner value. Thus, having `state` and `state_stream` is useless. It's
possible to return have `state` which returns `Subscriber`, and we get
one value for two usages.
2023-06-12 09:07:39 +02:00
Ivan Enderlin 623332b931 feat(ffi): Extract TaskHandle into itw own module. 2023-06-12 09:07:39 +02:00
Ivan Enderlin d4e983e559 feat(ui): Rename State::Enjoy to State::CarryOn. 2023-06-12 09:07:39 +02:00
Mauro 6444848511 docs: updated readme - rust version (#2047)
* docs: update readme
* removing error
2023-06-09 13:16:09 +00:00
Andy Balaam 11adcf425c In sliding sync, do all the same processing on an invited room as a joined one
The example in MSC3575 shows a room with invite_state property, but also
timeline, joined_count etc. properties. That may or may not be very
likely in practice, but I think it makes sense to check for all these
properties even when the room is an invite, and use them if they are
present.
2023-06-09 13:25:04 +01:00
Andy Balaam 7e197ec8d4 Simplify invited room sliding sync processing
Added some comments based on my understanding of MSC3575. Previously we
had a FIXME about how we were setting the room state to invite or join
based on the presence or absence of the invite_state property. I think
this behaviour is correct, so I added some comments explaining why.

The functional change here is to note that we call
store.get_or_create_stripped_room to find/create the stripped room, and
this actually deletes any room of this ID that is in the store, so our
later call to store.get_room would always fall back to getting the
stripped room, which we already have, so there was no need to do the
get_room call at all.
2023-06-09 13:14:58 +01:00
Andy Balaam 9d943e7c62 Clarify in tests that invite_state contains very minimal JSON 2023-06-09 13:14:58 +01:00
Andy Balaam 8c2cc522bc Test canonical aliases in invited rooms via sliding sync 2023-06-09 12:54:43 +01:00
Andy Balaam 4a04c70c45 Handle required state in invited rooms as well as normal 2023-06-09 12:54:43 +01:00
Andy Balaam ee8f94cb95 Rename room_to_add->room_to_store 2023-06-09 12:54:43 +01:00
Andy Balaam 24ff62befc Refactor process_sliding_sync to extract a method for dealing with rooms 2023-06-09 12:54:43 +01:00
Andy Balaam a85c481368 Test for adding an invited room to the client and invite list 2023-06-09 12:52:26 +01:00
Andy Balaam 5545c98a85 Test for finding avatars in invite rooms 2023-06-09 12:52:26 +01:00
Andy Balaam ac7c6ba84c Test for finding an avatar in a room via sliding sync 2023-06-09 12:52:26 +01:00
Kévin Commaille ae2f834345 sqlite: Return an error when DB version is invalid or missing (#2038)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-09 11:02:33 +00:00
Andy Balaam 0e30d85df4 Provide no event_id for the name state event when it comes via update_name
Also respond to a couple of minor review comments
2023-06-08 18:30:20 +02:00
Andy Balaam 02d03c55f2 Update the name of a room during sliding sync processing 2023-06-08 18:30:20 +02:00
Andy Balaam 0cff8f3697 Allow updating the name in a RoomInfo 2023-06-08 18:30:20 +02:00
Andy Balaam 0f5906a0fa Tests for processing sliding sync responses 2023-06-08 18:30:20 +02:00
Jonas Platte a977b3a8d5 ui: Use stream_assert for timeline unit tests 2023-06-08 12:25:58 +02:00
Jonas Platte 6c6c43e709 ui: Filter virtual timeline items for some tests 2023-06-08 12:25:58 +02:00
Benjamin Bouvier 43bac4995f chore: rename homeserver to sliding_sync_proxy in sliding sync
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-08 11:13:40 +02:00
Jonas Platte c8b74bec0d ci: Fixes to toolchain installation 2023-06-07 17:25:24 +02:00
Jonas Platte b5339ceaba ui: Activate sdk's testing feature for unit tests
Fixes running `cargo test` without any flags from the crate root.
2023-06-07 17:25:24 +02:00
Jonas Platte 0898c76bb7 crypto: Simplify is_cross_signing_trusted 2023-06-07 17:25:24 +02:00
Jonas Platte c19d72f0f4 Use Option::is_some_and where applicable 2023-06-07 17:25:24 +02:00
Jonas Platte 0b9c082e11 ffi: Add EventTimelineItem::transaction_id 2023-06-07 16:40:14 +02:00
Jonas Platte aa3adbd53d ui: Don't wait on prev_batch token for more than 3s 2023-06-07 16:21:48 +02:00
Jonas Platte 87510a5bc2 ffi: Add wait_for_token to PaginationOptions 2023-06-07 16:21:48 +02:00
Jonas Platte af870fcff3 ui: Allow waiting for token before starting pagination 2023-06-07 16:21:48 +02:00
Jonas Platte 1e10a54d3d ui: Fix clippy lints 2023-06-07 16:21:48 +02:00
Jonas Platte bfce4d1006 ui: Merge timeline::room_ext module into timeline::traits 2023-06-07 16:21:48 +02:00
Jonas Platte 2bcc70beb9 ui: Move timeline-internal traits into separate module 2023-06-07 16:21:48 +02:00
Damir Jelić 7552f4f72a Merge pull request #2028 from matrix-org/release-matrix-sdk-crypto-js-v0.1.0-alpha.10
Bindings JS: New release `matrix-sdk-crypto-js v0.1.0-alpha.10`
2023-06-07 15:51:24 +02:00
Jonas Platte 415c13fa90 ui: Add a test for retrying a failed send 2023-06-07 13:29:42 +02:00
Jonas Platte 0ca8369a76 ui: Fix clippy warnings 2023-06-07 13:29:42 +02:00
Jonas Platte dc05d17330 Upgrade eyeball-im-util 2023-06-07 13:29:42 +02:00
Jonas Platte 9505ace8e2 ffi: Add Room::retry_send 2023-06-07 13:29:42 +02:00
Jonas Platte df7beb4afd ui: Add Timeline::retry_send 2023-06-07 13:29:42 +02:00
Jonas Platte f1e62b0bb8 ci: Run coverage when PR is ready for review 2023-06-07 11:31:39 +02:00
Ivan Enderlin 4e29e6e347 feat(ui): Disable caching and make Timelines lazy
feat(ui): Disable caching and make `Timeline`s lazy
2023-06-07 11:29:22 +02:00
Florian Duros 81d4dc8b6e matrix-sdk-crypto-js v0.1.0-alpha.10
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 36s
2023-06-07 10:07:05 +02:00
Florian Duros 65bdb1a2e3 Update CHANGELOG.md 2023-06-07 10:06:51 +02:00
Damir Jelić 0e5e8a205c Merge pull request #2020 from matrix-org/florianduros/bindings/add-missing-key-identity
Bindings JS: Add missing keys to `UserIdentity` and `OwnUserIdentity`
2023-06-07 10:00:20 +02:00
Ivan Enderlin 5c182a0d03 sliding sync: enable read-receipts in the common extensions
sliding sync: enable read-receipts in the common extensions
2023-06-07 09:58:27 +02:00
Ivan Enderlin 3acb56aa31 feat(ui): Make Room::timeline and ::sneaky_timeline lazy.
This patch uses a new `async-once-cell` crate to make `Room::timeline`
and `Room::sneaky_timeline` by making them lazy. Their values are
computed lazily, on-demand, when calling the `Room::timeline` method or
`Room::latest_event`.
2023-06-07 09:51:56 +02:00
Ivan Enderlin a2cefedf73 RoomList API: enable account_data extension by default
`RoomList` API: enable `account_data` extension by default
2023-06-07 09:35:04 +02:00
Ivan Enderlin 169038504d fix(ui): Disable Sliding Sync caching in RoomList. 2023-06-07 09:31:52 +02:00
Benjamin Bouvier d3ddfabaef sliding sync: enable read-receipts in the common extensions
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-06 20:09:03 +02:00
Benjamin Bouvier 027db88078 sliding sync: have the RoomApi use add_list instead of add_cached_list until the perf issue of reloading has been fixed
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-06 19:36:42 +02:00
Benjamin Bouvier 3b10c235ab sliding sync: enable account data extension in room list API
This extension was enabled by both ElementX apps by default, along with the e2ee / to-device extensions that will be handled
by the new Notification API. To maintain the current behavior, it's important to re-enable this extension before getting
RoomList in production.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-06 19:35:20 +02:00
Florian Duros 198c8f6901 Prettier fix 2023-06-06 17:26:57 +02:00
Florian Duros 721a704540 Add tests 2023-06-06 17:23:16 +02:00
Florian Duros d0f3f1e657 Review fixes 2023-06-06 17:21:27 +02:00
Benjamin Bouvier f84ff148da feat(sdk): add an optional temporary directory to get_media_file
By default, get_media_file will attempt to use a default directory
for temporary files and directories. Unfortunately, there might not be
such a thing on some older Android devices, which use per-application
directories.

For this specific case, an optional temporary directory parameter
is added to the `get_media_files` parameters, so one can provide their own
temporary directory path.

This new parameter is expected to be set at least on Android; other platforms
should work just fine without it.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-06 15:20:06 +02:00
Florian Duros b4c440a5e7 Update CHANGELOG.md 2023-06-06 15:16:30 +02:00
Florian Duros b760c0e6ce Add keys to UserIdentity and OwnUserIdentity 2023-06-06 15:05:28 +02:00
Kévin Commaille 407375ad17 base: Move StateStore::get_member_event to StateStoreExt
It is a wrapper around get_state_event_static_for_key

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-06 11:56:11 +02:00
Kévin Commaille b690bcfbaf sdk: Re-export store traits
The store is exposed with `Client::store()` but the traits are not.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-06 11:56:11 +02:00
Benjamin Bouvier d1a1a0f5c5 Reuse upstream Ruma repository
This was a temporary replacement I've made, waiting for a PR of mine to be merged, and it's been merged since then. Oh well.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-06 10:04:20 +02:00
Ivan Enderlin f61fdcbdbe feat(ui): RoomList, step 1: the Foundation
feat(ui): `RoomList`, step 1: the Foundation
2023-06-05 20:50:25 +02:00
Ivan Enderlin 16932abeaa chore: Make Tarpaulin happy. 2023-06-05 20:17:19 +02:00
Ivan Enderlin e6fdcfdf52 chore: Make Clippy happy. 2023-06-05 20:05:46 +02:00
Ivan Enderlin 42df0d0e21 fix: Fix merge commit. 2023-06-05 19:43:32 +02:00
Ivan Enderlin d1bccacef9 chore: Make CI happy. 2023-06-05 19:40:51 +02:00
Ivan Enderlin 08559b58b6 Merge branch 'main' into feat-ui-roomlist 2023-06-05 19:22:33 +02:00
Ivan Enderlin ac7a576035 chore(ui): Address feedbacks. 2023-06-05 19:13:48 +02:00
Jonas Platte 9148eaaea1 sdk: Add a test for room update channels 2023-06-05 17:46:22 +02:00
Jonas Platte adb91262e0 ui: Do fully-read tracking in room update processing
… instead of separate event handlers.
2023-06-05 17:46:22 +02:00
Jonas Platte a916ef468e ui: Make some free functions TimelineInnerState methods instead 2023-06-05 17:46:22 +02:00
Jonas Platte 4986f98aa3 ui: Batch timeline object updates from sync response 2023-06-05 17:46:22 +02:00
Jonas Platte e59562725d ui: Move gappy sync response handling out of FFI 2023-06-05 17:46:22 +02:00
Jonas Platte 945a1228d0 ui: Use room subscription instead of event handler for timeline events 2023-06-05 17:46:22 +02:00
Jonas Platte 9489720386 Add Client::subscribe_to_room_updates
… and `room::Common::subscribe_to_updates` which does the same thing,
but more conveniently if one already has a room object.
2023-06-05 17:46:22 +02:00
Jonas Platte 63f7f4a903 Update event handler functions to take Option<&_> instead of &Option<_> 2023-06-05 17:46:22 +02:00
Jonas Platte 2c2285b5d7 ui: Deduplicate local and remote echo by event ID when it comes in late 2023-06-05 17:33:11 +02:00
Jonas Platte ede6bed948 ui: Move echo integration test into separate module 2023-06-05 17:33:11 +02:00
Jonas Platte 185fc9aa3c ui: Add copyright headers to integration tests 2023-06-05 17:33:11 +02:00
Jonas Platte 62817a8ef8 ui: Move pagination integration tests into separate module 2023-06-05 17:33:11 +02:00
Jonas Platte 3a5f83d9dc ffi: Include causes when stringifying anyhow::Error 2023-06-05 17:29:53 +02:00
Benjamin Bouvier 61c3a2a2c7 sliding sync: infer the storage key from the loop id and user id (#2008)
* sliding sync: infer the storage key from the loop id and user id
* chore: rename `sync_id` to `id`
* chore: check that the sliding sync id is less than 16 chars
* chore: rejigger the storage key creation logic

Now the prefix is visible only in the `format_storage_key_prefix` function, and other `format_storage_key` function will be based off that.

* chore: update sliding sync README with API updates and fix outdated information
* chore: clippy + fix test

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-05 14:51:40 +00:00
Ivan Enderlin 4a62949b6c test(sdk): Simplify a test. 2023-06-05 15:19:18 +02:00
Ivan Enderlin ad8d7caecb feat(ui): Handle RoomList's State::Terminated properly.
This patch handles errors from the Sliding Sync loop properly.

When an error is received, the `RoomList` state machine enters the
`Terminated` state. Immediately after that, the sync stream is stopped.

When the sync stream is restarted, the next state will be calculated.
When the current state is `Terminated`, the next state is the state
that led to the `Terminated` state. To avoid having a “first” huge sync
(imagine a room list of 1000 rooms, you don't want to “resume” from an
error with a first sync for 1000 rooms), lists are partially “reset”
depending of the state where the machine is in.

An important test has been added to test all possibles cases with errors
and list' states.
2023-06-05 15:09:10 +02:00
Ivan Enderlin 4bfc48b4ae feat(sdk): Simplify returned values of SlidingSync::sync.
First off, `SlidingSync::sync_once` no longer returns
`Option<UpdateSummary>` but `UpdateSummary`. It simplifies the rest of
the patch.

Next, `SlidingSync::sync` returns either `Ok(…)` and continues to sync,
or it returns `Err(…)` and it stops the sync stream immediately. No more
error could be returned with the stream to continue syncing.

Finally, the `UnknownPos` error no longer emits an err, but silently
skip over the sync-loop until the threshold is reached; which in this
case will generate a proper error.
2023-06-05 15:05:42 +02:00
Ivan Enderlin c1a24cf033 feat(ui): Implement Room::timeline and ::latest_event.
This patch changes `RoomInner` to have an `room:
Option<matrix_sdk::room::Room>` field to `room: matrix_sdk::room::Room`.
`room` is not longer an `Option`.

Then, it's easier to have a new `timeline: Timeline` field, along with a
`sneaky_timeline: Timeline` field. Both are used by the new
`Room::timeline()` and `Room::latest_event()` method.
2023-06-02 22:38:48 +02:00
Ivan Enderlin 67ef42f4c5 feat(ui): Implement RoomList::room.
This patch implements `RoomList::room`, which returns a `Result<Room>`:
the room ay or may not exist.

A new `Room` type is created. It wraps an `Arc<RoomInner>` type, so that
it's cheap to clone it.

The `RoomInner` type owns a `SlidingSyncRoom` and
`matrix_sdk::room::Room` type. If some API or data are missing on
the former, the latter acts as a backup. This is the case for the
`Room::name` method which makes it best to return a name to the caller.
2023-06-02 21:28:45 +02:00
Ivan Enderlin 537f95b683 feat(sdk): SlidingSync::get_rooms? are now async. 2023-06-02 20:59:26 +02:00
Ivan Enderlin dcad897084 test(ui): Ensure the timeline_limit is not reset. 2023-06-02 20:49:33 +02:00
Ivan Enderlin c6dae678bd sliding sync: move the bump_event_types to be per-list
sliding sync: move the `bump_event_types` to be per-list
2023-06-02 20:29:10 +02:00
Ivan Enderlin e18728aa5f feat(ui): Set timeline_limit for all_rooms and visible_rooms. 2023-06-02 20:06:50 +02:00
Ivan Enderlin 8ee84be839 doc(ui): Write documentation for RoomList. 2023-06-02 20:06:31 +02:00
Kévin Commaille 588b58c616 crypto: Remove unnecessary to_owned
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-02 12:22:26 +02:00
Kévin Commaille 3ab171ca2d chore: Update log dependency
Fixes compilation of value-bag crate with Rust nightly

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-02 12:22:26 +02:00
Benjamin Bouvier 28c8e5df71 feat(sdk): move bump_event_types to the list sub-request
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-01 18:57:45 +02:00
Benjamin Bouvier 6a58be38ca Temporarily use bnjbvr's repository for bump-event-types change in ruma
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-06-01 18:51:53 +02:00
Ivan Enderlin 2f68c86796 feat(ui): Add the RoomList Input API.
This patch lands the first design of the `Input` API. An `Input` is
something external that can be understood by the `RoomList` state
machine. The first inpuput is `Viewport` to change the “viewport” of the
`RoomList`, which translates to the change of the ranges of one specific
Sliding Sync list.
2023-06-01 16:55:29 +02:00
Ivan Enderlin 13d38993f8 feat(sdk): Expose the Range and Ranges type in matrix_sdk::sliding_sync. 2023-06-01 16:52:16 +02:00
Ivan Enderlin e2d2cf787d test(sdk): Fix according to previous commits. 2023-06-01 16:52:09 +02:00
Ivan Enderlin f5c950c54a fix(ffi): Update according to last commits. 2023-06-01 15:58:58 +02:00
Ivan Enderlin c2d082ca8d test(ui): Update the tests according to previous commits. 2023-06-01 15:58:12 +02:00
Ivan Enderlin 553b5c6db3 Merge pull request #1 from matrix-org/feat-ui-roomlist
Feat UI roomlist
2023-06-01 15:46:00 +02:00
Jonas Platte 5106255911 On-demand stream creation 2023-06-01 15:40:39 +02:00
Jonas Platte 58e8c0a7ac Fix warning 2023-06-01 15:34:13 +02:00
Jonas Platte db0217d093 Box internally 2023-06-01 15:34:07 +02:00
Ivan Enderlin 048b054a65 feat(ui): Implement RoomList::update_entries_stream_filter.
This patch implements `RoomList::update_entries_stream_filter` which
allows to… change the… entries stream filter. This patch also provides a
test for that. How nice it is.
2023-06-01 14:55:53 +02:00
Ivan Enderlin 0a1c0547b4 test(ui): Add test to ensure RoomList::sync resumes from current state. 2023-06-01 14:18:47 +02:00
Ivan Enderlin fbe1603190 feat(ui): Rethink the state machine of RoomList. 2023-06-01 14:06:02 +02:00
Damir Jelić d6d19d9111 Don't re-encode the plaintext after decrypting a backup 2023-06-01 12:56:18 +02:00
Jonas Platte 3e2bc3a514 Drop matrix-sdk-sled 2023-06-01 12:06:35 +02:00
Kévin Commaille 7cd8898f5f indexeddb: Use parentheses for the impl_state_store macro
Allows rustfmt to do its thing.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-01 11:54:29 +02:00
Kévin Commaille 83e7afab5d sdk: Allow to get stripped state events from the store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-01 11:13:24 +02:00
Kévin Commaille 645af31c59 base: Use generic types for (Raw)MemberEvent
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-06-01 11:13:24 +02:00
Ivan Enderlin a090a070ee chore(cargo): Add missing EOF. 2023-06-01 10:08:59 +02:00
Ivan Enderlin 697c92beb1 test(ui): Test RoomList::entries_stream with more cases. 2023-06-01 09:48:54 +02:00
Ivan Enderlin 954d798ac3 test(ui): Write an assert_entries_stream macro. 2023-06-01 09:48:54 +02:00
Ivan Enderlin a3c96dcb62 feat(ui): Implement RoomList::entries_stream. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 1caa8b1aa6 chore(ui): Polish after the rebase. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 4557c2a7b2 feat(ui): Add RoomList::entries.
This patch implements the `RoomList::entries` method, which allows
to get a stream of `VectorDiff` over the room list, and that can be
filtered.
2023-06-01 09:48:53 +02:00
Ivan Enderlin f058c59582 feat(sdk): Add SlidingSyncList::room_list_filtered_stream.
This patch adds a new method on `SlidingSyncList` named
`room_list_filtered_stream`, which uses the new `eyeball-im-util` crate
with its new `FilteredSubscriber` type.
2023-06-01 09:48:53 +02:00
Ivan Enderlin aa70c85e02 test(ui): Test RoomList sync from Init to Enjoy. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 1173636b35 feat(ui): Add room_list::Error. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 61f903a5a9 test(ui): Clean up a test. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 4d6a6ac17f feat(ui) Add State::Terminated in RoomList. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 26a764d9dd test(ui): Test all RoomList actions. 2023-06-01 09:48:53 +02:00
Ivan Enderlin bd175d9f66 test(sdk): Store the sync-mode in SlidingSyncListInner only for tests. 2023-06-01 09:48:53 +02:00
Ivan Enderlin f89060bbe9 chore(ui): Update after the rebase. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 01366a08df !foo 2023-06-01 09:48:53 +02:00
Ivan Enderlin 4e07ac1c76 test(ui): Improve testability of RoomList. 2023-06-01 09:48:53 +02:00
Ivan Enderlin d1708ececf feat(ui): Update according to the last patch. 2023-06-01 09:48:53 +02:00
Ivan Enderlin 4fa38d23d4 feat(sdk): SlidingSync has more non-blocking API.
This patch does several things.

First, `SlidingSync::on_list` is now async, and accept async closures.

Second, `SlidingSync::lists` and `::rooms` are behind an `AsyncRwLock`
instead of a `StdRwLock`. The rest of the patch updates the consequence
of this.
2023-06-01 09:48:53 +02:00
Ivan Enderlin 5f81d829c4 feat(ui): Create an Init state, and add state observer for RoomList. 2023-06-01 09:48:52 +02:00
Ivan Enderlin 92c3003535 !baz 2023-06-01 09:48:52 +02:00
Ivan Enderlin f47c2ba125 !bar 2023-06-01 09:48:52 +02:00
Ivan Enderlin 7706b0096b !foo 2023-06-01 09:48:52 +02:00
Ivan Enderlin 5f58438389 feat(ui): Oh, a roomlist module. 2023-06-01 09:48:51 +02:00
Ivan Enderlin 81d158889a fix(sdk): Replace a panic by a log in Sliding Sync
fix(sdk): Replace a panic by a log in Sliding Sync
2023-06-01 09:47:50 +02:00
Ivan Enderlin 29346b11f3 test(ui): Use FutureExt::now_or_never instead of .await
test(ui): Use `FutureExt::now_or_never` instead of `.await`
2023-06-01 09:41:56 +02:00
Damir Jelić 036d9bf261 Add a test to check that the backup decryption works 2023-06-01 09:31:31 +02:00
Damir Jelić 811369ba28 Fix the argument order when decoding a PkMessage 2023-06-01 09:31:31 +02:00
Ivan Enderlin 06680a284a fix(sdk): Replace a panic by a log in Sliding Sync.
This patch replaces a panic (`Option::expect`) by a `tracing::error`
log.

Imagine the Sliding Sync proxy responds with the following payload:

```json
{
    "pos": …,
    "lists": {
        …: {
            "count": …,
            "ops": [
                {
                    "op": "INSERT",
                    "index": 0,
                    "room_id": !foo:bar.org",
                }
            ]
        }
    },
    "rooms": []
}
```

It's an invalid response, as it will update the room list entry (because
it's present in `lists.$list.ops`), but the room won't be created (it's
absent in the `rooms`).

This situation creates a panic in the patched code. We don't want to
crash if the server replies with invalid data.

Ultimately, we should check that the sync operations are valid regarding
the rooms' updates.
2023-06-01 09:18:20 +02:00
Ivan Enderlin fbe8826159 test(ui): Use FutureExt::now_or_never instead of .await.
This patch uses `FutureExt::now_or_never` so that we don't wait on the
future to be resolved to get a result. If we have a bug in our code and
the test expects a value, the test will hang forever, which is not a
desired behavior. With `now_or_never`, this situation cannot happen.
2023-06-01 08:39:44 +02:00
Ivan Enderlin c82c0e46be feat(sdk): Ensure SlidingSync::sync “drains” its internal channel
feat(sdk): Ensure `SlidingSync::sync` “drains” its internal channel
2023-05-31 18:08:06 +02:00
Ivan Enderlin ae25ad557a Merge branch 'main' into fix-sdk-sliding-sync-drain-internal-channel 2023-05-31 17:34:48 +02:00
Jonas Platte d27ae257ec ffi: Remove unnecessary Deref implementations 2023-05-31 17:32:46 +02:00
Ivan Enderlin f9322c5de8 test(sdk): Ensure SlidingSync starts after it has been stopped manually
test(sdk): Ensure `SlidingSync` starts after it has been stopped manually
2023-05-31 17:30:56 +02:00
Ivan Enderlin d0d23afa5c feat(sdk): Introduce SlidingSync::internal_channel_send_if_possible.
The only reason why a sender can fail to send a message is because there
is no receiver. In the current design of `SlidingSync`, there is only
one receiver active per sync-loop. Thus, calling `SlidingSync::add_list`
may fail if `sync` has not been started. Hence the need for a new
`internal_channel_send_if_possible` method which will never fail: it
will send a message is possible, otherwise it won't do anything.

This turns more functions infallible.
2023-05-31 16:53:03 +02:00
Ivan Enderlin 875f379035 feat(sdk): Change SlidingSync's internal channel to MPMC.
`tokio::sync::broadcast` is interesting as it's possible to
generate receivers per subscribers. Being able to do that allows
us to remove the new for an `AsyncLock` around the receiver in
`SlidingSync::internal_channel`, and it can even remove the need to hold
a receiver entirely!

Another improvement is that new receivers can't receive past messages,
so we no longer need to drain the internal channel.

Another improvement is that the sender' `send` method is synchronous!
Which helps to make many functions no longer `async`.
2023-05-31 16:41:50 +02:00
Ivan Enderlin 9da1a2f48b feat(sdk): Ensure SlidingSync::sync drains its internal channel.
Something weird is happening with ElementX iOS. When
`SlidingSync::stop_sync` is called, the internal message `SyncLoopStop`
has time to be sent in the internal channel, but iOS decides to suspend
the code before the sync-loop processes it. When ElementX decides to
start the sync-loop again, it immediately processes the `SyncLoopStop`
message, and… stops the sync-loop.

This patch ensures that `SlidingSync::sync` drains the internal channel
before starting the sync-loop for real. `tokio::sync::mpsc::Receiver`
type has no `drain` method, so this patch implements its
own logic by calling `try_recv` in a loop, until it returns
`Err(TryRecvError::Empty)`.
2023-05-31 15:29:13 +02:00
Damir Jelić 2fa4410dc6 Bump the vodozemac version 2023-05-31 11:52:47 +02:00
Ivan Enderlin 70525e4612 test(sdk): Ensure SlidingSync starts after it has been stopped manually. 2023-05-31 11:18:55 +02:00
Ivan Enderlin 85b37bfcc4 chore: Remove sliding sync dead tests
chore: Remove sliding sync dead tests
2023-05-31 09:22:05 +02:00
Benjamin Bouvier 4ca8d61c56 feat(ffi): expose set_sync_mode on the sliding sync list
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-30 17:20:05 +02:00
Benjamin Bouvier 623ff6fa83 chore(sliding sync): remove useless mutex around ExtensionsConfig
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-29 17:18:42 +02:00
Benjamin Bouvier 90d7ff764c Remove dead tests
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-29 12:46:50 +02:00
Benjamin Bouvier ce9a079882 feat(sdk): use the builder pattern for the other sliding sync mode too
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-26 15:08:21 +02:00
Benjamin Bouvier fa25e4d9fc sliding sync: Rejigger the range API (#1955)
* feat: introduce SlidingSyncSelectiveModeBuilder
* feat: get rid of `CannotModifyRanges` \o/
* chore: rustfmt
* chore: remove scope in test
* chore: move request generator update to its own mod, gets rid of `set_ranges`
* chore: add comments on the request generator methods
* chore: sink one range_end definition into the match arm that matters
* ffi: remove unused `add_range` method
* test: update incorrect test expectation
* chore: make clippy happy
* address first review comments
* review: don't reuse the ranges field for two things
* chore: use a builder pattern for sliding sync selective mode
* address review comments + CI

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-26 13:40:46 +02:00
Damir Jelić df6d0aaa87 Log the one-time keys we received 2023-05-26 10:34:07 +00:00
Jonas Platte 84917bb59d Fix clippy lints 2023-05-26 12:26:00 +02:00
Jonas Platte ebe97623aa Upgrade Ruma 2023-05-26 12:26:00 +02:00
Damir Jelić def53962e4 Make the withheld reason part of the error message 2023-05-25 16:57:58 +02:00
Damir Jelić 1b2ba33039 Record the sender key when decrypting room events
This used to be the case previously, but it seems that things got lost
when we reshuffled the code here.
2023-05-25 16:57:58 +02:00
Benjamin Bouvier 631b51f43b chore: update sliding sync's README.md too
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 16:17:46 +02:00
Benjamin Bouvier 829eb30e7e chore: get rid of SlidingSync::reset_lists as it's unused
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 16:17:46 +02:00
Benjamin Bouvier 8d1b3b5b73 chore: get rid of SlidingSyncList::set_ranges, replace with SlidingSyncList::set_range (singular) in testing
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 16:17:46 +02:00
Benjamin Bouvier 9c1919ab4c chore: get rid of SlidingSyncListBuilder::set_range and replace it with add_range in tests
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 16:17:46 +02:00
Benjamin Bouvier dbd491383f chore: get rid of SlidingSyncListBuilder::reset_ranges
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 16:17:46 +02:00
Benjamin Bouvier 40a0459cb9 chore: get rid of SlidingSyncListBuilder::ranges(), replace with add_range
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 16:17:46 +02:00
Damir Jelić 8c9a54e6c8 Time out user/device pairs who have invalid one-time keys 2023-05-25 14:52:05 +02:00
Damir Jelić ac816ca1c6 Fix an indentation issue 2023-05-25 14:51:25 +02:00
Damir Jelić 2c696ae210 Fix the deserialization of encrypted m.dummy events. 2023-05-25 14:51:25 +02:00
Jonas Platte 5197e263a0 Revert "bindings: Use native async support for latest_room_message"
This reverts commit 2660e7bcf1.
2023-05-25 13:33:43 +02:00
Benjamin Bouvier 992b6b604b test: address review comments + add basic tests for to-device token
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 11:26:32 +02:00
Benjamin Bouvier 9762c63dbc chore: remove Observable wrappers for the position markers
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 11:26:32 +02:00
Benjamin Bouvier 0afe616e17 feat: put the to_device_token along the other position markers in sliding sync
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 11:26:32 +02:00
Benjamin Bouvier b4c192509b chore: remove unused FFI add_common_extensions
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-25 11:26:32 +02:00
Damir Jelić 5e3a114830 Log the message id when we share a room key 2023-05-24 12:29:15 +02:00
Damir Jelić 2e09bf63a6 Add a message id to our encrypted to-device events 2023-05-24 12:29:15 +02:00
Damir Jelić 19ca9478b7 Clean up some room key forwarding logs 2023-05-24 12:29:15 +02:00
Ivan Enderlin 17f4ba5c9b fix(sdk): Client::sliding_sync doesn't need to be async
fix(sdk): `Client::sliding_sync` doesn't need to be `async`
2023-05-24 12:26:33 +02:00
Ivan Enderlin a2a1b35622 fix(sdk): Client::sliding_sync doesn't need to be async.
The `Client::sliding_sync` method was declared as async. However, it's
not necessary as everything happening here is sync.
2023-05-24 11:56:38 +02:00
Ivan Enderlin b60a317174 feat(sdk): Implement SlidingSync::stop_sync
feat(sdk): Implement `SlidingSync::stop_sync`
2023-05-24 11:52:19 +02:00
Jonas Platte ac106c7059 bindings: Use native async for SessionVerificationController 2023-05-24 11:31:33 +02:00
Jonas Platte 2660e7bcf1 bindings: Use native async support for latest_room_message 2023-05-24 11:31:33 +02:00
Jonas Platte ffc8453c63 bindings: Use async-compat tokio runtime 2023-05-24 11:31:33 +02:00
Jonas Platte 587c5b05b1 Upgrade UniFFI 2023-05-24 11:31:33 +02:00
Ivan Enderlin 728cd5db86 fix(sdk): Restore the size of the SS channel.
Because it doesn't solve any problem, it just postpones it, making the
whole thing more difficult to debug.
2023-05-24 11:02:06 +02:00
Ivan Enderlin 512a5e77cd feat(sdk): Log when messages are sent internally by SlidingSync. 2023-05-24 11:01:42 +02:00
Ivan Enderlin e9bbf366ba chore(sdk): Simplify code. 2023-05-24 09:19:12 +02:00
Ivan Enderlin 849f83adb7 chore(sdk): Remove an allow(unused). 2023-05-24 09:06:32 +02:00
Ivan Enderlin 415778d44d feat(ffi): Implement SlidingSync::stop_sync. 2023-05-24 09:03:03 +02:00
Ivan Enderlin 47922f7f50 test(sdk): Test SlidingSync::stop_sync_loop. 2023-05-24 08:59:28 +02:00
Ivan Enderlin 7bde2cfd4a feat(sdk): Add log in SlidingSync when an internal message is received. 2023-05-24 08:44:51 +02:00
Ivan Enderlin 99bbf2a42b feat(sdk): Implement SlidingSync::stop_sync.
In case it's not obvious to drop the `Stream` returned by
`SlidingSync::sync` immediately to “stop” the sync-loop, one can use the
new `stop_sync` method to do achieve the same result.
2023-05-24 08:42:12 +02:00
Ivan Enderlin b8580b76f7 feat(sdk): Rename SlidingSync::stream to ::sync.
Because it doesn't start a stream, but a sync-loop.
2023-05-24 08:20:29 +02:00
Damir Jelić c042e1e63c Disable automatic-key-forwarding for the matrix-sdk-ffi bindings
Not completely sure why disabling this didn't work the first time. The
feature is now disabled by default in the matrix-sdk-crypto crate.
2023-05-23 16:42:34 +02:00
Damir Jelić 3db90fbe02 Use the new VerificationRequest signalling in the emoji example 2023-05-23 16:10:05 +02:00
Damir Jelić b07718b5d5 Expose the VerificationRequest signalling and states in the main crate 2023-05-23 16:10:05 +02:00
Damir Jelić e9c3aa1a2e Add a state for the VerificationRequest for when a request transitions
The `VerificationRequest` object is used to control the flow of the
verification but only up to a certain point.

Once we start handling of different specific verification flows (i.e.
SAS or QR code verification) the `VerificationRequest` object creates a
child object of the Verification type.

This patch adds a new `VerificationRequestState` variant called
`Transitioned` which holds the child verification object as associated
data.

This makes it much simpler to go through the whole verification flow by
allowing users to just listen to the `VerificationRequest::changes()`
method.
2023-05-23 16:10:05 +02:00
Florian Renaud 2cce236f4d feat(bindings): exposed set_name in Room 2023-05-22 17:58:14 +02:00
Jonas Platte 2f243bce55 Stop unconditionally enabling native-tls from matrix-sdk-ffi 2023-05-22 16:26:40 +02:00
Ivan Enderlin d27754cb61 Replace the libolm backup encryption code with a native Rust version
Replace the libolm backup encryption code with a native Rust version
2023-05-22 14:56:21 +02:00
Ivan Enderlin cc10f995ff feat(sdk): Implement SlidingSyncList::set_sync_mode
feat(sdk): Implement `SlidingSyncList::set_sync_mode`
2023-05-22 14:38:01 +02:00
Benjamin Bouvier befb5dbdb8 chore: add log when exiting the sync loop's stream
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-22 14:13:13 +02:00
Benjamin Bouvier 5c785be7dd fix(sdk): increase the internal channel receiver size up from 8 to 256
We suspect that there might be too many internal messages being pushed, causing a deadlock on the senders' side.
This attempts to increase the value of the buffer to give it more leeway.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-22 14:13:13 +02:00
Ivan Enderlin 322f5495ac fix(sdk): SlidingSyncListInner::timeline_limit and ranges are no longer observable
fix(sdk): `SlidingSyncListInner::timeline_limit` and `ranges` are no longer observable
2023-05-22 12:05:45 +02:00
Ivan Enderlin 4eee60dc9e chore(sdk): Make Clippy happy. 2023-05-22 11:32:54 +02:00
Ivan Enderlin abf8a50c0d chore(sdk): Make Clippy happy. 2023-05-22 11:24:11 +02:00
Ivan Enderlin e9399eb635 doc(sdk): Do no link to a private function. 2023-05-22 10:54:36 +02:00
Ivan Enderlin 4e00d04611 fix(sdk): SlidingSyncListInner::timeline_limit and ranges are no longer observable.
The `SlidingSyncListInner::timeline_limit` and `::ranges` fields were
observable (behind `eyeball::Observable`). It was actually useless
as those fields were never exposed to the public API, thus it was
impossible to subscribe to them.

This patch cleans up that. `timeline_limit` and `ranges` are no longer
observable.
2023-05-22 10:50:26 +02:00
Ivan Enderlin fee1a50f38 doc(sdk): Improve documentation of next_request. 2023-05-22 09:39:43 +02:00
Ivan Enderlin 6e77804070 feat(sdk): SlidingSyncList::set_sync_mode sends an internal message.
This patch updates `SlidingSyncList::set_sync_mode` to send a
`SyncLoopSkipOverCurrentIteration` internal message to the sync loop.
2023-05-22 09:38:42 +02:00
Ivan Enderlin 82f5768df3 feat(sdk): Rename SlidingSyncInternalMessage variants.
This patch renames the variant to be more explicit about what they do
instead of re-using the “for loop vocabulary”.
2023-05-22 09:37:32 +02:00
Ivan Enderlin 4ee2f2a44b chore(sdk): Run rustfmt. 2023-05-22 08:43:10 +02:00
Ivan Enderlin f37945da13 chore(comment): fix the comment for Error::CannotModifyRanges
chore(comment): fix the comment for `Error::CannotModifyRanges`
2023-05-20 18:05:13 +02:00
Ivan Enderlin 88ebd89937 doc(sdk): Fix a typo.
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-05-20 17:57:21 +02:00
Ivan Enderlin 2f29664fb8 doc(sdk): Fix a typo.
Co-authored-by: Benjamin Bouvier <public@benj.me>
2023-05-20 17:57:11 +02:00
Benjamin Bouvier da73229e8d chore(comment): fix the comment for Error::CannotModifyRanges
The comment and the check in the code were contradicting each other; the comment was wrong, and the code was right, so there's that.

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-19 16:03:59 +02:00
Damir Jelić 34aed2f939 Replace the libolm backup encryption code with a native Rust version
This patch removes our dependency to libolm completely. This should
allow WASM targets to use the backups_v1 feature of the
matrix-sdk-crypto crate as well.
2023-05-18 10:52:51 +02:00
Ivan Enderlin ff1d784e70 fix(ci): Fix path to matrix-sdk-crypto-js and allow pushd to return an error
fix(ci): Fix path to `matrix-sdk-crypto-js` and allow `pushd` to return an error
2023-05-17 20:18:03 +02:00
Ivan Enderlin 9912a4a6db doc(sdk): Fix a typo. 2023-05-17 20:16:01 +02:00
Ivan Enderlin 7b0336bb29 doc(sdk): Fix a typo. 2023-05-17 20:07:12 +02:00
Ivan Enderlin d86647db77 chore(ci): Give pushd's result a name so that it's not dropped. 2023-05-17 20:00:33 +02:00
Jonas Platte d13d41951f Silence clippy warning from macro-generated code 2023-05-17 17:20:55 +02:00
Jonas Platte f68fd6c7cf Use workspace dependencies for futures-core 2023-05-17 17:20:55 +02:00
Jonas Platte 78838e67c1 Upgrade dependencies 2023-05-17 17:20:55 +02:00
Jonas Platte 59b1fa00df Replace futures dependencies with futures-* dependencies 2023-05-17 17:20:55 +02:00
Jonas Platte 18d12b2f10 crypto: Simplify a test 2023-05-17 17:20:55 +02:00
Jonas Platte a39a6fba51 sdk: Use tokio::sync instead of futures::channel in tests
… for consistency.
2023-05-17 17:20:55 +02:00
Ivan Enderlin fc37f337fb fix(ci): Fix path to matrix-sdk-crypto-js and allow pushd to return an error.
First off, this patch changes `pushd(…)` to `pushd(…)?` so that errors
are propagated.

Second, instead of assuming that all crates live in `crates/`, let's
allow to precise a prefix, like `crates/` or `bindings/` directly in the
“folder” path of `args`.
2023-05-17 17:12:52 +02:00
Ivan Enderlin f01e8dc992 test(sdk): Test SlidingSyncList::set_sync_mode. 2023-05-17 17:10:55 +02:00
Ivan Enderlin 8bb04ed40b test(sdk): Use the Rust inclusive range syntax for ranges. 2023-05-17 17:10:55 +02:00
Ivan Enderlin d99957d370 feat(sdk): Implement SlidingSyncList::set_sync_mode.
Changing the sync-mode of a list on-the-fly is necessary to optimise the
new `RoomList` API. For example, we can start with a list in a selective
mode, a range of `0..=50` and a `timeline_limit=0` to fetch the
beginning of the room list, and then _change_ the sync-mode to growing
to continue to sync the room list in the background.

Today, this is done with 2 lists and a merge of the lists, but
(i) this is error-prone, (ii) this is not optimal. Thank to
`SlidingSyncList::set_sync_mode`, merging lists is no more necessary,
thus removing a class of bugs in client's code.
2023-05-17 17:10:55 +02:00
Ivan Enderlin 51e6e80b3b feat(sdk): SlidingSyncMode has richer variants
feat(sdk): `SlidingSyncMode` has richer variants
2023-05-17 17:10:26 +02:00
Ivan Enderlin 6dde00ebcf chore(sdk): Simplify code with a matches!. 2023-05-17 16:50:00 +02:00
Ivan Enderlin 74430e127f doc(sdk): Do not use helper constructors in the documentation. 2023-05-17 16:50:00 +02:00
Ivan Enderlin 1c175df6b3 chore(sdk): Move From impl on SSListRequestGenerator as proper constructor. 2023-05-17 16:37:11 +02:00
Ivan Enderlin ddc8d915cb doc(sdk): Fix syntax error. 2023-05-17 16:34:12 +02:00
Ivan Enderlin f8e12f6aaf doc(sdk): Update documentation according to last commits. 2023-05-17 15:42:30 +02:00
Ivan Enderlin 63feec1433 test(sdk): Test impl From<SlidingSyncMode> for …RequestGenerator`. 2023-05-17 15:32:35 +02:00
Ivan Enderlin 1a60983e8f feat(ffi): Add SlidingSyncListBuilder::sync_mode_*.
This patch replaces `sync_mode` on `SlidingSyncListBuilder` by
`sync_mode_selective`, `sync_mode_paging` and `sync_mode_growing`, which
removes the need to use `SlidingSyncMode` directly.

This patch also removes `batch_size`, `room_limit` and `no_room_limit`
as it's now arguments of `sync_mode_paging` and `sync_mode_growing`.
2023-05-17 15:18:51 +02:00
Ivan Enderlin 41c09a5ec5 feat(sdk): SlidingSyncMode has richer variants.
`SlidingSyncMode` was previously declared as:

```rust
enum SlidingSyncMode {
    Selective,
    Paging,
    Growing,
}
```

Now, the new declaration is:

```rust
enum SlidingSyncMode {
    Selective,
    Paging {
        batch_size: u32,
        maximum_number_of_rooms_to_fetch: Option<u32>,
    },
    Growing {
        batch_size: u32,
        maximum_number_of_rooms_to_fetch: Option<u32>,
    }
}
```

First off, it helps to remove the `full_sync_batch_size` and
`full_sync_maximum_number_of_rooms_to_fetch` methods and fields from
`SlidingSyncListBuilder`. It was containing default values in case of.
That was useless and needed to be fixed. Also, calling a `full_sync_*`
method with the `Selective` mode had no effect, which could disturb
the user. Well, now everything is clean on that front.

Second, `SlidingSyncListRequestGenerator` no longer has constructors,
but a `From<SlidingSyncMode>` implementation. However, the constructors
now live in `SlidingSyncMode` with `new_selective`, `new_paging` and
`new_growing` methods which are helpers. All in all, it makes creating a
`SlidingSyncListRequestGeneator` simpler: just call `sync_mode.into()`
and boom.

Finally, this patch removes the `default_with_fullsync` list builder
helper, which makes no sense at all.
2023-05-17 14:49:55 +02:00
Jonas Platte 12a02f0458 Make examples section name consistent in docs 2023-05-17 14:45:24 +02:00
Ivan Enderlin c618b03f12 feat(sdk): SlidingSync::add_list has an immediate effect
feat(sdk): `SlidingSync::add_list` has an immediate effect
2023-05-17 13:56:35 +02:00
Jonas Platte f12e827a67 Don't use block_on in no_run doctests
… and clean up formatting around the affected ones.
2023-05-17 13:49:14 +02:00
Ivan Enderlin 64cea091f9 chore(sdk): Clean up test code. 2023-05-17 13:23:21 +02:00
Ivan Enderlin 5ce9790c94 doc(sdk): Fix rebase missing doc. 2023-05-17 13:20:31 +02:00
Ivan Enderlin 39aba1dd95 fix(sdk): Rename SlidingSyncSubscribeResult to SlidingSyncAddTimelineListenerResult. 2023-05-17 13:13:17 +02:00
Ivan Enderlin b85b585bd7 feat(ffi): Make some methods async.
`SlidingSync::subscribe`, `::unsubscribe` and `::add_list` are
now async. `subscribe` has been renamed to `subscribe_to_room` and
`unsubscribe` to `unsubscribe_from_room`.

`SlidingSyncRoom::subscribe_and_add_timeline_listener` has
been removed, and replaced by a new `::subscribe_to_room` and
`::unsubscribe_from_room` methods (the `::add_timeline_listener` method
already exists).

`TaskHandle::finalizer` is no longer necessary, thus this code has been
cleaned up.
2023-05-17 13:13:17 +02:00
Ivan Enderlin 63257e6226 fix(sdk): Remove room unsubscriptions once the server has received them
fix(sdk): Remove room unsubscriptions once the server has received them
2023-05-17 11:59:16 +02:00
Ivan Enderlin 53c20fcf1a feat(sdk): SlidingSync::add_list has an immediate effect.
`SlidingSync::add_list` sends `ContinueSyncLoop` on the internal channel.
2023-05-17 11:35:53 +02:00
Damir Jelić 1510576ce1 Expose the git description and commit hash in the crypto-ffi bindings
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-05-17 09:31:52 +00:00
Ivan Enderlin 501b990248 chore(sdk): Rename SlidingSync::unsubscribe_to_room to …_from_room. 2023-05-17 11:29:26 +02:00
Valere 405db06495 refactor(crypto): get_or_load never returns crypto error 2023-05-17 09:20:37 +00:00
Jonas Platte be7e162ce1 Restore timeline integration tests
The directory had the wrong name, so it wasn't detected by Cargo.
2023-05-17 11:14:16 +02:00
Ivan Enderlin b7374a78e9 doc(sdk): Update documentation for SlidingSync::(un)subscribe_to_room. 2023-05-17 11:10:03 +02:00
Ivan Enderlin d8a9408efe fix(sdk): Remove room unsubscriptions once the server has received them.
This bug has been found by @bnjbvr, all the credits go to him. I've just
added some comments around his code.

Prior to this patch, the room unsubscription buffer
(`SlidingSync::room_unsubscriptions`) was reset before the request was
sent. So if something went wrong, the next request would not include the
room unsubscriptions.

This patch updates this behavior. First, it replaces `Vec` by `HashSet`
to avoid a O(n^2) look up.

Second, a copy of room unsubscriptions used by the request is kept, so
that it can be used to cherry-pick which room unsubscription to remove
from the buffer once a response from the server is received. It's
important to not clear the entire room unsubscriptions buffer as more
unsubscriptions could have been inserted meanwhile.
2023-05-17 10:14:34 +02:00
Ivan Enderlin 9b7122768f chore(sdk): Rename SlidingSync room subscriptions and unsubscriptions API.
Notably, this patch renames `SlidingSync::subscribe` and `::unsubscribe`
to `subscribe_to_room` and `unsubscribe_to_room`.
2023-05-17 10:01:55 +02:00
Jonas Platte 5fa2fff8e5 ui: Re-export TLS features 2023-05-17 09:58:31 +02:00
Jonas Platte 31e32c307f ui: Add missing copyright headers 2023-05-17 09:58:31 +02:00
Jonas Platte d620f83e0d Enable syntax highlighting in sliding_sync README 2023-05-17 09:58:31 +02:00
Jonas Platte cfc8effa66 Move timeline API into a new crate
… aimed at interactive user interfaces.
2023-05-17 09:58:31 +02:00
Jonas Platte 91d97cd588 sdk: Re-export matrix_sdk_base::crypto 2023-05-17 09:58:31 +02:00
Jonas Platte 910022bca6 sdk: Make useful push related methods public 2023-05-17 09:58:31 +02:00
Jonas Platte a6fe0bb34d sdk: Merge identical ensure_members, sync_members methods 2023-05-17 09:58:31 +02:00
Damir Jelić 0144826884 crypto: Log if and which fallback key got removed 2023-05-16 16:25:20 +02:00
Damir Jelić 35a0f3af25 crypto: Improve some logs around Olm decryption and encryption 2023-05-16 16:25:20 +02:00
Damir Jelić 9f1ec9ac3a crypto: Log the result of one-time key generation 2023-05-16 16:25:20 +02:00
Jonas Platte c796302a98 ffi: Fix typo in variant name 2023-05-16 11:32:15 +02:00
Richard van der Hoff 1c8d2a1225 Merge pull request #1923 from matrix-org/release-matrix-sdk-crypto-js-0.1.0-alpha.9
matrix-sdk-crypto-js v0.1.0-alpha.9
2023-05-15 19:50:53 +01:00
Ivan Enderlin df8242a23e test(sdk): New Sliding Sync integration test suite for a mocked server
test(sdk): New Sliding Sync integration test suite for a mocked server
2023-05-15 20:30:23 +02:00
Ivan Enderlin 5b55145a1c Merge branch 'main' into test-sliding-sync-room-timeline 2023-05-15 20:06:42 +02:00
Ivan Enderlin d24a3922a0 test(sdk): Avoid ambiguity in pos. 2023-05-15 20:03:02 +02:00
Richard van der Hoff 6c0afae0f4 Merge remote-tracking branch 'origin/main' into release-matrix-sdk-crypto-js-0.1.0-alpha.9
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 36s
2023-05-15 18:59:52 +01:00
Richard van der Hoff 923d425585 crypto-js: expose a constructor for SigningKeysUploadRequest (#1925)
... to help with testing.
2023-05-15 18:58:38 +01:00
Richard van der Hoff 89bf7f27f3 fix typo 2023-05-15 18:42:58 +01:00
Benjamin Bouvier 58dbe1e252 feat: add add_cached_list to SlidingSyncBuilder and SlidingSync (#1876)
This has slightly drifted from the initial design I thought about in the issue.

Instead of having `build()` be fallible and mutably borrow some substate (namely `BTreeMap<OwnedRoomId, SlidingSyncRoom>`) from `SlidingSync` (that may or may not already exist), I've introduced a new `add_cached_list` method on `SlidingSync` and `SlidingSyncBuilder`. This method hides all the underlying machinery, and injects the room data read from the list cache into the sliding sync room map.

In particular, with these changes:

- any list added with `add_list` **won't** be loaded from/written to the cache storage,
- any list added with `add_cached_list` will be cached, and an attempt to reload it from the cache will be done during this call (hence `async` + `Result`).
- `SlidingSyncBuilder::build()` now only fetches the `SlidingSync` data from the cache (assuming the storage key has been defined), not that of the lists anymore.

Fixes #1737.

Signed-off-by: Benjamin Bouvier <public@benj.me>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-05-15 16:17:45 +00:00
Benjamin Bouvier c404e378a2 test: sliding sync list fields reloaded from the cache are observable in streams
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-15 17:46:04 +02:00
Jonas Platte 549edeb73b sdk: Instrument sliding response handling task 2023-05-15 17:24:02 +02:00
Benjamin Bouvier b6302aca5c bench: add benchmarks for encrypted stores too
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-15 17:11:50 +02:00
Benjamin Bouvier 3928259bb5 bench: add restore session benchmark
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-15 17:11:50 +02:00
Richard van der Hoff 3049328078 matrix-sdk-crypto-js v0.1.0-alpha.9 2023-05-15 15:07:14 +01:00
Richard van der Hoff 3df473a56d update CHANGELOG 2023-05-15 15:07:03 +01:00
Ivan Enderlin 89384775ff chore(cargo): Update lockfile. 2023-05-15 16:04:17 +02:00
Ivan Enderlin d2e9347be4 test(sdk): Put sliding_sync behind its feature flag. 2023-05-15 16:03:54 +02:00
Richard van der Hoff 18954a6ba5 crypto-js: fix body of SignatureUploadRequest (#1917)
Currently, the `body` of a `SignatureUploadRequest` includes a spurious
`signed_keys: {...}` property in which the actual content is wrapped. Fix that.
2023-05-15 15:02:01 +01:00
Chris Smith 3449dad89b feat(bindings): expose getting member by id
Allow for retrieving a single room member by their ID.
2023-05-15 15:26:45 +02:00
Ivan Enderlin 07267767fc test(sdk): New Sliding Sync integration test suite for a mocked server. 2023-05-15 15:19:45 +02:00
Ivan Enderlin dca7800a88 chore(cargo): uuid is no longer needed. 2023-05-15 15:19:37 +02:00
Ivan Enderlin caaeb8130d feat(sdk): Remove txn_id from requests sent by SlidingSync.
We were using `txn_id` as a way to identify the running stream. Now
things are cleaner so we can remove this “debug tool”. This class of
problems should not appear anymore. For the record, the biggest problem
was the following: It was possible to start multiple `stream`s at the
same time, and thus a stream could receive a response sent by another
stream. Since we no longer need to restart SlidingSync anymore (i.e. no
need to start multiple `stream`s at the same time), this problem should
not happen.
2023-05-15 15:16:40 +02:00
Ivan Enderlin 94d5d5187f test(sdk): Rename a test about SlidingSyncRoom. 2023-05-15 15:14:58 +02:00
Ivan Enderlin d973ac1e93 doc(sdk): Add missing documentation. 2023-05-15 15:14:23 +02:00
Ivan Enderlin 6185b4050a feat(sdk): Process SlidingSync response inside handle_response.
Prior to this patch, the `v4::Response`, aka the SlidingSync response,
was processed by the client and transformed into a `SyncResponse` into
`sync_once` before being passed to `handle_response`. Now it's done in
`handle_response`.

This is not mandatory _now_, but it will be helpful in a close future.
2023-05-15 15:12:20 +02:00
Jonas Platte ee87ec7b46 Improve logs for pagination 2023-05-15 13:06:30 +02:00
Jonas Platte ab7aa68c5b Fix lints 2023-05-15 13:06:30 +02:00
Benjamin Bouvier fc8dd5a1cc Update crates/matrix-sdk/src/room/timeline/inner.rs
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-05-15 10:29:27 +02:00
Benjamin Bouvier c0f8e31e79 chore: add tracing spans for code in TimelineBuilder suspected to be slow
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-15 10:29:27 +02:00
Stefan Ceriu 7ff125dae1 chore(xtask): clean apple generated bindings directory before building new ones 2023-05-12 16:27:14 +02:00
Stefan Ceriu 593c99d377 ffi: add method for getting the build time git short sha value (#1909) 2023-05-11 18:32:09 +02:00
Ivan Enderlin 9d0c40c207 feat(sdk): Clean up and test SlidingSyncRoom
feat(sdk): Clean up and test `SlidingSyncRoom`
2023-05-11 18:03:30 +02:00
Jonas Platte 870d6d6ca3 Make timeline event Debug impls less verbose 2023-05-11 18:00:17 +02:00
Jonas Platte 1d2e45191d Make Debug impl for RequestConfig less verbose
… for the common case, and more verbose for some uncommon options that
were just never printed before.
2023-05-11 18:00:17 +02:00
Jonas Platte 30eee70e9d Add DebugStructExt helper for writing less verbose Debug impls 2023-05-11 18:00:17 +02:00
Ivan Enderlin f23fd1809b Merge branch 'main' into feat-sliding-sync-room 2023-05-11 17:47:08 +02:00
Ivan Enderlin ab96a696ae test(sdk): Add test cases for SlidingSyncRoom::update.
Test when a `SlidingSyncRoom` has received a non-empty update, and then
receives an empty-update.
2023-05-11 17:45:14 +02:00
Benjamin Bouvier 149950cc29 sliding sync: Use RangeInclusive<u32> instead of raw start/end UInt values (#1877)
* chore: use RangeInclusive instead of raw start/end integers for ranges in sliding sync
* chore: have timeline_limit use a u32 instead of a Ruma UInt
* chore: Remove all the `Into<u32>` generics on timeline_limit and ranges APIs
* chore: introduce a `Bound` type alias for u32

Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-11 14:27:46 +02:00
Jonas Platte a84960787d Fix remaining sync response Debug event content leaks
… for real this time.
2023-05-11 13:50:20 +02:00
Jonas Platte dab4cdd863 ffi: Add MediaSource::{from_json, to_json} 2023-05-11 11:06:06 +00:00
Benjamin Bouvier d6100915df bench: add sled back to the crypto benchmarks
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-11 12:31:58 +02:00
Benjamin Bouvier 5f228f408e bench: set up a Tokio context when dropping the sqlite store
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-11 12:31:58 +02:00
Kévin Commaille 93f5562343 Only send verifications requests to devices that are cross-signed (#1884)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-11 11:59:59 +02:00
Mauro Romito 18971e8b11 fix for notification item to get sender in invited rooms 2023-05-11 10:49:42 +02:00
Ivan Enderlin 68337d58f7 chore(ffi): Update according to last commit. 2023-05-11 09:18:43 +02:00
Ivan Enderlin 873bc6b2a4 Just to trigger the CI, after Github issues. 2023-05-11 09:01:32 +02:00
Jonas Platte 9842645377 Fix struct name for DebugNotification output 2023-05-10 23:42:32 +02:00
Jonas Platte 176934e359 Fix debug output for raw events
It was looking for an "event_type" field rather than just "type".
The code was also more complex than necessary.
2023-05-10 21:50:12 +02:00
Ivan Enderlin 75f3bbcf63 chore(ffi): Update according to last commit. 2023-05-10 15:57:43 +02:00
Ivan Enderlin 02cfee68c4 feat(sdk): SlidingSyncRoom is cheap to clone.
This patch changes `SlidingSyncRoom` to move all its fields inside an
inner type `SlidingSyncRoom` behind an `Arc`, so that cloning is cheap,
and all clones are sharing the same state.
2023-05-10 15:53:21 +02:00
Ivan Enderlin 09bb0fcdd3 test(sdk): Testing FrozenSlidingSyncRoom receives a subset of the timeline queue. 2023-05-10 14:42:00 +02:00
Ivan Enderlin 54bc774d62 test(sdk): Clarify a test with json! instead of a string. 2023-05-10 14:15:07 +02:00
Ivan Enderlin e2af4ccfe6 fix(ffi): Fix types. 2023-05-10 14:01:29 +02:00
Ivan Enderlin 1a50afe167 feat(sdk): Rethink the SlidingSyncList::state after a reset
feat(sdk): Rethink the `SlidingSyncList::state` after a reset
2023-05-10 13:56:57 +02:00
Ivan Enderlin 3a25608a6e feat(sdk): Rethink the SlidingSyncList::state after a reset.
A `SlidingSyncList` has a state, which can be either `NotLoaded`,
`Preloaded`, `PartiallyLoaded`, or `FullyLoaded`.

A `SlidingSyncList` can be reset, either manually when
`SlidingSyncList::reset` is called, or when a range is updated for
example.

Resetting a list is modifying its state. Prior to this patch, the state
was set to `NotLoaded`. However, it's not entirely true. This patch
updates this behavior to the following rules:

* When the state is `NotLoaded`, it's kept at this state as nothing has
  happened yet,
* When the state is `Preloaded`, the list is restored from the cache,
  but nothing has happened yet too, so it's kept at this state,
* When the state is `PartiallyLoaded` or `FullyLoaded`, it means some
  (or all) updates have been done, so the new state is `PartiallyLoaded`
  after the reset.

The list' state is used mostly by the client to know whether a loader
should be prompted to the users. The ranges are modified when the
users scroll inside the room list for example: scrolling in the room
list doesn't imply the state should go to `NotLoaded`. Some data
have potentially be loaded, so changing the ranges should result in a
`PartiallyLoaded` state. It seems more logical once explained like this.
2023-05-10 13:31:52 +02:00
Ivan Enderlin 22b2e54aca test(sdk): Test SlidingSyncRoom::update, esp. the timeline_queue. 2023-05-10 13:17:09 +02:00
Ivan Enderlin 7c21f8851c test(sdk): Test SlidingSyncRoom::state. 2023-05-10 09:35:45 +02:00
Ivan Enderlin c00b2db51b test(sdk): Test SlidingSyncRoom::prev_batch. 2023-05-10 09:35:45 +02:00
Ivan Enderlin e7e66dc17e test(sdk): Test SlidingSyncRoom::required_state. 2023-05-10 09:35:45 +02:00
Ivan Enderlin d688918036 feat(sdk): Don't update invite_state in SlidingSyncRoom.
`invite_state` is managed when the Sliding Sync response is processed/
handled by the `Client`. Inside `SlidingSyncRoom`, it's not necessary to
maintain it.
2023-05-10 09:35:45 +02:00
Ivan Enderlin bafcaa9c85 test(sdk): Test SlidingSyncRoom::*unread_notifications. 2023-05-10 09:35:45 +02:00
Ivan Enderlin 379c9d6520 test(sdk): Test SlidingSyncRoom::is_dm and ::is_initial_response. 2023-05-10 09:35:45 +02:00
Ivan Enderlin 04feb7a2a2 test(sdk): Test SlidingSyncRoom::name. 2023-05-10 09:35:45 +02:00
Ivan Enderlin de373c07a6 feat(sdk): Add a constant to represent the max number of timeline events to put in the cache.
This patch creates a constant to represent the
maximum number of timeline event to put in the cache:
`NUMBER_OF_TIMELINE_EVENTS_TO_KEEP_FOR_THE_CACHE`. Verbose, but easily
understandable.

This patch also renames a few variables.
2023-05-10 09:35:45 +02:00
Ivan Enderlin 39590c4e07 chore(sdk): Re-order methods on SlidingSyncRoom. 2023-05-10 09:35:45 +02:00
Ivan Enderlin 3a0ebbd271 doc(sdk): Update documentation. 2023-05-10 09:35:45 +02:00
Ivan Enderlin 32ef2f7c61 feat(sdk): Simplify SlidingSyncRoom::timeline_queue.
This patch simplifies `SlidingSyncRoom::timeline_queue` from

```rust
Arc<RwLock<ObservableVector<SyncTimelineEvent>>>
```

to

```rust
Vector<SyncTimelineEvent>
```

First, we don't need to be observable. It's never observed since
it's private, and even privately, it's never observed, there is no
subscriber.

Second, no lock is required as updates happen synchronously.

Third, `Arc` is not necessary. We want each clone of `SlidingSyncRoom`
to not share any state across them.

Finally, this patch simplifies the iterator + `.push_back` by a simple
`.extend` to update the `timeline_queue`. Behind the scene, `impl Extend
for Vector` actually does an iterate + `.push_back`; let's keep our code
simple though.
2023-05-10 09:35:45 +02:00
Ivan Enderlin 6afca5367d feat(sdk): Replace SlidingSyncRoom::is_cold by a real state enum.
`SlidingSyncRoom::is_cold` is not well-named. This patch introduces an
enum, named `SlidingSyncRoomState` which contains more detailed state:
`NotLoaded`, `Preloaded`, and `Loaded`.

The use of `AtomicBool` is also removed. Thus, we no longer need an
`Arc` for the state, which makes `Clone` more obvious: the state is not
shared across clones anymore.
2023-05-10 09:35:45 +02:00
Ivan Enderlin ef9bf87d89 chore(sdk): Write imports at the correct place. 2023-05-10 09:35:41 +02:00
Ivan Enderlin 349c7c3f68 feat(sdk): Remove SlidingSyncRoom::prev_batch.
A `SlidingSyncRoom` receives an Ruma
`api::client::sync::sync_events::v4:SlidingSyncRoom`. This value is
stored in the `SlidingSyncRoom::inner` field. From here, some getters
like `name()`, `is_dm()` etc. are using the `inner` field to compute a
result. There was one exception though: `prev_batch`. This value is part
of `v4::SlidingSyncRoom` but it was copied and updated in its own field:
`SlidingSyncRoom::prev_batch`.

I was wondering why. Turns out, there is no reason. Its getter
`prev_batch()` is public, but it's not used by the FFI bindings, so
basically nobody uses it (as this project is experimental as the time of
writing, we know our users).

This patch removes the `SlidingSyncRoom::prev_batch` field.

This patch also removes the `SlidingSyncRoom::prev_batch()` getter.

This patch finally removes the `FrozenSlidingSyncRoom::prev_batch` field
too.
2023-05-10 09:34:39 +02:00
Ivan Enderlin cb2bb84d88 fix(sdk): Remove SlidingSyncRoom::is_loading_more.
First, this field is not used by ElementX.

Second, this field is never updated, so it always returns `false`, which
seems… buggy and useless.
2023-05-10 09:34:38 +02:00
Ivan Enderlin 4132571270 doc(sdk): Write documentation for SlidingSyncRoom. 2023-05-10 09:34:38 +02:00
Ivan Enderlin 0038a0389a chore(sdk): Create one block for rooms, one block for lists.
This patch moves the code into dedicated blocks: one for updating the
rooms, one for updating the lists.
2023-05-10 09:34:27 +02:00
Ivan Enderlin 3e6dd1cecb feat(sdk): Don't remove and re-insert a room when it exists.
Prior to this patch, to check a room exists, it was removed from the
collection, then re-added if it exists. Instead of doing this `remove`
+ `insert` dance, we can simply use `get_mut`, which also returns an
`Option`. This patch does that, in addition to rewrite the code to use a
`match` instead of a `if` + `else`.
2023-05-10 09:21:20 +02:00
Mauro 6eeee8ee53 ffi: Expose EventTimelineItem::read_receipts and the NotificationItem#room_canonical_alias 2023-05-09 15:26:07 +00:00
Jonas Platte 2de786c516 Rename fetch_event_details to fetch_details_for_event 2023-05-09 17:25:39 +02:00
Jonas Platte 159b999485 Update call_event_handlers span to default level of info 2023-05-09 16:53:17 +02:00
Jonas Platte b6453772c3 Fix remaining sync response Debug event content leaks 2023-05-09 16:51:08 +02:00
Jonas Platte 0aa1f599c5 common: Make debug module public
… and remove re-exports of its contents from crate root.
2023-05-09 16:51:08 +02:00
Jonas Platte 1f01555e4e sdk: Add more logging and a new branch to fetch_in_reply_to_details 2023-05-09 16:26:52 +02:00
Jonas Platte c9d35a8fe5 sdk: Clean up spans for sliding sync_once 2023-05-09 12:49:43 +02:00
Benjamin Bouvier b257d0dacd chore: add the --workspace flag back in the documentation CI task
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-09 10:21:48 +02:00
Benjamin Bouvier 1aff90a96f chore: fix doc comments in code and READMEs
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-09 10:21:48 +02:00
Jonas Platte 1380e9c4ec Inline sync response structs with a single field 2023-05-09 10:08:34 +02:00
Jonas Platte 40c0f0896e Add some missing copyright headers 2023-05-09 10:08:34 +02:00
Jonas Platte aa3b2d4698 base: Don't log raw event for notifications 2023-05-09 10:08:34 +02:00
Jonas Platte 935dc6ec41 base: Remove presence events from debug output
We shouldn't be logging raw events, and there's not really a useful
subset we could include.
2023-05-09 10:08:34 +02:00
Jonas Platte ae4518c1a7 base: Remove unused Deserialize, Serialize impls 2023-05-09 10:08:34 +02:00
Jonas Platte 2d1f514a13 Box fields to reduce stack size of structs 2023-05-08 18:47:01 +02:00
Jonas Platte ce3c818156 Box futures to reduce composed future's sizes 2023-05-08 18:47:01 +02:00
Jonas Platte 1bc99a62a5 Make Store::save_changes non-lazy 2023-05-08 18:47:01 +02:00
Jonas Platte 3a74e8647b Reduce amount of local variables before .await in async fn 2023-05-08 18:47:01 +02:00
Jonas Platte c3d7a0704a A little bit of cleanup 2023-05-08 18:47:01 +02:00
Jonas Platte a8fb54ee67 Replace qualified name with use 2023-05-08 18:47:01 +02:00
Jonas Platte c5decd2294 crypto: Pass AnyToDeviceEventContent by reference
… in a few places where it doesn't need to be moved.
2023-05-08 18:47:01 +02:00
Jonas Platte 9c4cce5fd0 crypto: Clean up OlmMachine::with_store
- Remove an unnecessary else {}
- Reorder logging instructions
2023-05-08 18:47:01 +02:00
Jonas Platte 37ed3d0a59 sdk: Don't skip event reordering when re-receiving redacted event 2023-05-08 18:12:53 +02:00
Jonas Platte 3013c911fd sdk: Fix log message 2023-05-08 18:12:53 +02:00
Alfonso Grillo 7ac6ebfb7f Add invited and joined counts 2023-05-08 18:12:12 +02:00
Ivan Enderlin 43b28e6087 feat(sdk): Remove the need to “restart” SlidingSync
feat(sdk): Remove the need to “restart” `SlidingSync`
2023-05-08 17:24:36 +02:00
Ivan Enderlin 6c8a19cf01 chore: Make Clippy happy. 2023-05-08 16:58:00 +02:00
Ivan Enderlin bfcedcd49c feat(sdk): SlidingSync::*subscribe will cancel in-flight requests.
`SlidingSync::subscribe` and `SlidingSync::unsubscribe` will cancel in-
flight requests, i.e. the `SlidingSyncInternalMessage::ContinueSyncLoop`
will be sent in the internal channel, just like what `SlidingSyncList`s
already do when a parameter is changed.
2023-05-08 16:44:49 +02:00
Ivan Enderlin 748ae86a88 feat(sdk): Cloning SlidingSyncListBuilder clones the once_built closure. 2023-05-08 15:24:58 +02:00
Ivan Enderlin cfa2f1d049 chore: Make Clippy happy. 2023-05-08 14:20:18 +02:00
Ivan Enderlin 87f481ce7d !fixup 2023-05-08 14:17:39 +02:00
Ivan Enderlin 281944696a Merge branch 'main' into feat-sdk-sliding-sync-cancellation-token 2023-05-08 14:11:20 +02:00
Ivan Enderlin 673d51a9d9 test(sdk): Test SlidingSyncListBuilder::once_built. 2023-05-08 14:10:27 +02:00
Kévin Commaille f92c3649e9 ffi: Use SQLite state store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Kévin Commaille c9fde8cf89 sdk: Add bundled-sqlite Cargo feature
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Kévin Commaille 991a42d8d6 sled: Add docsrs feature for docs generation
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Kévin Commaille d7e47501e3 benchmarks: Replace sled with SQLite
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Kévin Commaille ea826a257d sdk: Replace Sled with SQLite as defaut store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Kévin Commaille 09e446b1d5 sqlite: Fix doc error
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Kévin Commaille 6bae0793f9 codecov: Add SQLite store as default crate
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-08 12:11:10 +02:00
Jonas Platte 32fafe7be3 Pin rust nightly version
Works around https://github.com/rust-lang/rust/issues/111320.
2023-05-08 10:44:14 +02:00
Ivan Enderlin 0dab71e94b fix(sdk): Fix previous merge. 2023-05-08 10:16:03 +02:00
Ivan Enderlin 150df1d6ce fix(sdk): Fix previous merge. 2023-05-08 10:07:32 +02:00
Ivan Enderlin cdb992e3b2 Merge branch 'main' into feat-sdk-sliding-sync-cancellation-token 2023-05-08 09:55:02 +02:00
Kévin Commaille 69c8b9f049 sdk: Add method to check if device is verified with cross-signing
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-06 20:06:40 +02:00
Kévin Commaille 2c3664c2b3 sdk: Document when a created room is set as direct
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-06 19:50:42 +02:00
Jonas Platte 33c84b9ffd crypto: Reduce stack size of OlmMachine 2023-05-05 14:24:44 +02:00
Jonas Platte e5375a475e crypto: Reduce stack size of Store
… and make it cheaper to clone.

Reduces the stack size of OlmMachine from 3632 bytes to 832 bytes.
2023-05-05 14:24:44 +02:00
Jonas Platte 794ab8bc9f crypto: Borrow InboundGroupSession for async fn's that don't need to own
Reduces the size of the returned futures.
2023-05-05 12:39:50 +02:00
Jonas Platte 70c2cf6fe4 sdk: Reduce size of futures in http_client 2023-05-05 12:39:50 +02:00
Jonas Platte 88580d95bf Consistently use Ruma's Owned*Id types
… for simplicity; instead of `Arc<*Id>`.
2023-05-05 12:34:15 +02:00
Mauro b9cc0b5249 ffi: Add Client::get_notification_item
… and remove NotificationService.
2023-05-05 11:27:56 +02:00
Jonas Platte 848de833cc sdk: Fill in replied-to event from timeline items when available 2023-05-05 10:54:01 +02:00
Jonas Platte 10d441f580 sdk: Log redactions of already-redacted events 2023-05-05 10:18:13 +02:00
Marcel 211690ab44 Add missing const to make epilogue.js work in ECMAScript Module compatibility mode
Signed-off-by: Marcel Radzio <mtrnord [AT] nordgedanken.dev>
2023-05-05 10:17:36 +02:00
Jonas Platte c6c5e7fca6 Add CODEOWNERS file for automatic review requests 2023-05-04 16:41:04 +02:00
Ivan Enderlin a91cd93a77 Merge pull request #1860 from bnjbvr/make-builder-build-infallible
Make `SlidingSyncListBuilder::build` infallible
2023-05-04 16:00:40 +02:00
Benjamin Bouvier e05f8001cf Mandate a Client when creating a SlidingSyncBuilder
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-04 15:42:35 +02:00
Benjamin Bouvier fd480b3a8d review: remove useless Result in FFI layer too (thanks hywan!)
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-04 15:42:35 +02:00
Benjamin Bouvier 0962b03a75 Get rid of the name() function builders?
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-04 15:42:35 +02:00
Benjamin Bouvier 3e811d5246 Make SlidingSyncListBuilder::build infallible by mandating a name in ctor
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-04 15:42:35 +02:00
Jonas Platte 3eaacaba55 sdk: Add / update copyright headers 2023-05-04 14:21:24 +02:00
Jonas Platte c5d7022272 sdk: Add a redaction test
including a check that we discard the original event if it's somehow
received again after the redaction.
2023-05-04 14:21:24 +02:00
Jonas Platte 443e729f5b sdk: Fix redaction regression 2023-05-04 14:21:24 +02:00
Jonas Platte 749b57f30a sdk: Fix logs around redactions
No need to log redaction event ID as it's already part of the span.
2023-05-04 14:21:24 +02:00
Jonas Platte 18a0c836af sdk: Move timeline redaction test to new file 2023-05-04 14:21:24 +02:00
Jonas Platte 878ab7f0e3 sdk: Don't add original form of redacted events to the timeline
If the redaction already happened server-side, it is a bug for the
server to even still have access to the non-redacted form.
We don't accept the server data in this case, and also log a warning.
2023-05-04 12:30:19 +02:00
Benjamin Bouvier 2d2874f3c0 Remove unused SlidingSyncList::new_builder
Signed-off-by: Benjamin Bouvier <public@benj.me>
2023-05-04 11:40:26 +02:00
Ivan Enderlin 769fd9cad6 Merge pull request #1844 from matrix-org/rav/signing_keys_upload_response
crypto-js: extend `mark_request_as_sent` to accept SigningKeysUploadResponses
2023-05-04 10:34:27 +02:00
Mauro 709bea839e ffi: Expose active_members_count 2023-05-04 10:31:36 +02:00
Mauro a0cebfcba2 ffi: Fix is_noisy calculation 2023-05-04 09:13:33 +02:00
Richard van der Hoff 5c9fdc51f6 fix lint 2023-05-03 14:36:39 +01:00
Richard van der Hoff c1c1b1047d Apply suggestions from code review
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-05-03 14:16:56 +01:00
Ivan Enderlin d703380f85 chore(ffi): Re-order methods. 2023-05-03 14:03:12 +02:00
Ivan Enderlin cc365215c8 feat(sdk): Introduce SlidingSyncListBuilder::once_built.
`on_built` is a method that registers a closure. This closure is called
when a list is built by `SlidingSyncListBuilder::build`. It receives
a `SlidingSyncList` and returns a `SlidingSyncList`, the list can be
updated or returned as is. It allows to configure a `SlidingSyncList`
right after it's built. `SlidingSyncBuilder::build` is responsible to
finalize the configuration, and to build all the lists. Once they are
built, the state is restored from the cache. If one wants to configure
a list before the state is restored from the cache, `once_built` will
serve well.
2023-05-03 13:42:27 +02:00
Kévin Commaille 581b4e02a1 sdk: Add timeline tests for aggregated edits, removing reply fallbacks and sanitizing HTML
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-03 13:18:36 +02:00
Kévin Commaille d6401e51c2 sdk: Move edit timeline unit tests to a separate module
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-03 13:18:36 +02:00
Kévin Commaille 4fa2c13d44 sdk: Sanitize timeline HTML input and remove reply fallbacks
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-03 13:18:36 +02:00
Kévin Commaille e8375a3770 sdk: Add constructor from m.room.message event for Message
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-05-03 13:18:36 +02:00
Stefan Ceriu 45cb5f0c2c Use a indermediary directory for attachment names that might cause conflicts 2023-05-03 13:00:56 +02:00
Stefan Ceriu 2d464cf2f7 fix(ffi): Generate correct temporary file names for media attachments 2023-05-03 13:00:56 +02:00
Alfonso Grillo 9f3e4e809c ffi: Expose power levels related APIs 2023-05-03 10:43:47 +00:00
Jonas Platte e6cdf4d753 Work around new rustfmt bug 2023-05-03 11:42:50 +02:00
Jonas Platte dddec7e7ee Revert "Add "opaque interface declarations""
This reverts commit 396e0a3567.
2023-05-03 11:42:50 +02:00
Jonas Platte 37be24ee19 sqlite: Fix compiler warnings 2023-05-03 11:42:50 +02:00
Jonas Platte e1db33e6fa Upgrade UniFFI 2023-05-03 11:42:50 +02:00
Mauro 2f413af0a8 ffi: Correct timestamp value and remove is_read flag
The timestamp value of the Notification was not reliable since it was the
timestamp in which it was generated internally, not the timestamp of when the
event was sent, now we instead expose the `origin_server_ts` of the
TimelineEvent.

`is_read` is also very unreliable, so it's just removed for now.
2023-05-02 15:00:05 +00:00
Benjamin Bouvier be41dcf300 Remove unused dependencies 2023-05-02 15:06:46 +02:00
Stefan Ceriu 17fd4dd5ca ffi: Support sending image attachments through the timeline 2023-05-02 14:54:01 +02:00
Jonas Platte 557d27a1a3 sdk: Add more convenient power level action checks to RoomMember 2023-05-02 12:59:28 +02:00
Damir Jelić 9e21678ce3 Merge pull request #1846 from matrix-org/release-matrix-sdk-crypto-js-v0.1.0-alpha.8
matrix-sdk-crypto-js v0.1.0-alpha.8
2023-05-02 12:52:06 +02:00
Damir Jelić b0ca52b203 Merge pull request #1839 from matrix-org/florianduros/tech/js-bindings-missing-dependencies-lockfile
JS Bindings: add typescript missing devDependencies and lockfile
2023-05-02 11:58:24 +02:00
Richard van der Hoff 584cd5963c Merge branch 'main' into rav/signing_keys_upload_response 2023-05-02 10:54:52 +01:00
Florian Duros 61312e53d8 Merge branch 'main' into release-matrix-sdk-crypto-js-v0.1.0-alpha.8
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 42s
2023-05-02 11:43:07 +02:00
Richard van der Hoff 8f332fddc2 crypto-js: Make importCrossSigningKeys take strings (#1843)
Currently this takes a `CrossSigningKeyExport`, but that's not a class you can
construct from the JS side. Instead, let's just pass in the individual keys.
2023-05-02 09:42:16 +00:00
Florian Duros 4df887823b Update bindings/matrix-sdk-crypto-js/README.md
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2023-05-02 11:35:50 +02:00
Florian Duros b9920ab477 bindings: Fix Wasm conversion into base64 2023-05-02 11:35:44 +02:00
Mauro 87b938b8fe ffi: Add timestamp field to NotificationItem 2023-05-02 11:16:43 +02:00
Mauro 034aa04076 ffi: Add is_read field to NotificationItem 2023-04-28 18:04:42 +02:00
Simon Farre 396e0a3567 Add "opaque interface declarations"
Using the #[derive(uniffi::Object)] on certain types make them not show up
in the .aar file when building for Android. Could not determine why that is,
but removing the derive macro, and adding the empty interface declarations
inside the UDL, makes them show up.

We can still use #[uniffi::export] and #[uniffi::constructor].

Signed-off-by: Simon Farre <simon.farre.cx@gmail.com>
2023-04-28 17:58:41 +02:00
Jonas Platte 7ef6accab8 base: Clean up sliding sync processing a bit 2023-04-28 13:36:37 +02:00
Jonas Platte d7421b3f85 base: Clean up ephemeral event handling
Log deserialization failing, and visit all events (though there should
never be two receipt events for one room in a single sync response).
2023-04-28 13:36:37 +02:00
Jonas Platte daf611b290 base: Add spans to some medium to large BaseClient methods 2023-04-28 13:36:37 +02:00
Kévin Commaille 640e74c76a chore: Update Ruma
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-28 13:12:38 +02:00
Florian Duros 8ba80fc13a matrix-sdk-crypto-js v0.1.0-alpha.8 2023-04-28 11:38:56 +02:00
Damir Jelić e6f2f65ffa Merge pull request #1838 from matrix-org/florianduros/feat/optional-unused-fallback-keys-js-bindings
JS Bindings: make `unused_fallback_keys` as optional in `machine.rs/receive_sync_changes`
2023-04-28 11:33:24 +02:00
Jonas Platte cca8ac7aea ci: Only save caches from main branch
Caches saved from a PR can't be loaded from other unrelated PRs, wasting
space and possibly getting older previously-saved caches evicted first.
2023-04-28 11:17:19 +02:00
Jonas Platte 4ee4198e83 ci: Remove build caching for infrequently used release workflows 2023-04-28 11:17:19 +02:00
Jonas Platte b4faef7867 bindings: Use proc-macros for types no longer referenced in UDL 2023-04-28 11:07:47 +02:00
Jonas Platte 34d2a20b15 ffi: Use proc-macros for constructors 2023-04-28 11:07:47 +02:00
Jonas Platte 6b8ec09365 crypto-ffi: Use proc-macros for constructors 2023-04-28 11:07:47 +02:00
Jonas Platte 8aad6156bc Upgrade UniFFI 2023-04-28 11:07:47 +02:00
Richard van der Hoff fc384367ec Update bindings/matrix-sdk-crypto-js/CHANGELOG.md 2023-04-27 20:00:21 +01:00
Richard van der Hoff 8a8c29a3b5 crypto-js: extend mark_request_sent to accept SigningKeysUploadResponses
Currently, we can't pass the response to a `SigningKeysUploadRequest` into
`mark_request_sent`, which apparently we should be able to do.

So, we need to make `SigningKeysUploadRequest` have a `type` like the other
`OutgoingRequest`s, and  add support for `SigningKeysUploadResponse` to
`OwnedResponse`.
2023-04-27 19:57:31 +01:00
Jonas Platte bafcf23a29 sdk: Use new_content of edits instead of content
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-27 19:08:28 +02:00
Florian Duros 75870dd607 Run clippy 2023-04-27 17:57:30 +02:00
Florian Duros 2de2a14ee6 Run rustfmt 2023-04-27 17:42:19 +02:00
Mauro d919642dd6 ffi: Exposing register_notification_handler in bindings 2023-04-27 17:35:46 +02:00
Florian Duros 31b81cbf6a Run prettier 2023-04-27 17:30:55 +02:00
Florian Duros cea29dbea1 Update README.md 2023-04-27 17:07:00 +02:00
Florian Duros c74ecc449e Add yarn.lock file 2023-04-27 17:04:54 +02:00
Florian Duros 643bd328d7 Add typescript as devDependencies 2023-04-27 17:04:43 +02:00
Florian Duros 2b3d5e09e2 Update changelog 2023-04-27 17:02:53 +02:00
Florian Duros 404d5003f3 unused_fallback_keys is optional in machine.rs 2023-04-27 17:00:28 +02:00
Kévin Commaille d54b4a1d5a sdk: Use new_content of edits instead of content
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-27 16:02:40 +02:00
Ivan Enderlin dbdfe560e1 doc: Fix examples. 2023-04-27 14:39:15 +02:00
Ivan Enderlin cbfa134087 feat(sdk): Remove hacks for Sliding Sync ranges
feat(sdk): Remove hacks for Sliding Sync ranges
2023-04-27 14:35:05 +02:00
Ivan Enderlin 4b51a19564 chore: Clean up tests. 2023-04-27 14:26:51 +02:00
Ivan Enderlin 58bb2dc21e chore: Fix PR feedbacks. 2023-04-27 14:16:48 +02:00
Ivan Enderlin 3a8b6696f7 test: Install SS proxy v0.99.2. 2023-04-27 14:07:39 +02:00
Ivan Enderlin 5e6720b63c feat(ffi): SlidingSync::reset_lists returns a SlidingSyncError. 2023-04-27 10:53:16 +02:00
Ivan Enderlin a719f35a3e test: Use the latest Sliding Sync proxy version. 2023-04-27 10:21:04 +02:00
Ivan Enderlin 13088dff72 test: Use the latest Sliding Sync proxy version. 2023-04-27 10:02:50 +02:00
Ivan Enderlin deeefdfe90 Revert "fix(sdk): Try to find a workaround for a bug in the SS Proxy."
This reverts commit f269202ece.
2023-04-27 09:03:12 +02:00
Kévin Commaille 6ca6a9a84a Implement SQLite state store
Co-authored-by: Jonas Platte <jplatte@matrix.org>
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 17:51:11 +02:00
Kévin Commaille 4bf15a4694 base: Implement Clone for StateChanges
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 17:51:11 +02:00
Kévin Commaille 78655bd9e2 base: Allow to get RoomMemberships as a list of MembershipStates
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 17:51:11 +02:00
Kévin Commaille 91da155b55 sqlite: Change signatures of SqliteObjectExt methods
Allows to pass owned strings as well as static strings

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 17:51:11 +02:00
Jonas Platte 40272c5989 refactor: Move sqlite crypto store migrations in new subdirectory 2023-04-26 17:51:11 +02:00
Ivan Enderlin 3b9c98d1b1 Revert "fix(sdk): Try to find workarounds about the bug in SlidingSync Proxy."
This reverts commit bd6075f6b4.
2023-04-26 17:31:47 +02:00
Ivan Enderlin 2032a9fbfb test(sdk): Fix tests and examples. 2023-04-26 17:11:47 +02:00
Kévin Commaille 1a20733225 indexeddb: Avoid unnecessary clones when deserializing events
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 16:17:38 +02:00
Ivan Enderlin 576fac99db feat(sdk): Update the FFI layer to latest commits. 2023-04-26 16:08:06 +02:00
Ivan Enderlin 4b70407bcd feat(sdk): SlidingSyncBuilder implements Clone. 2023-04-26 16:05:03 +02:00
Kévin Commaille bc240951d6 crypto: Enable decoding padded base64
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 15:56:03 +02:00
Ivan Enderlin a7659f1fcb Build Node bindings against Ubuntu 20.04
Build Node bindings against Ubuntu 20.04
2023-04-26 15:12:39 +02:00
Andrew Ferrazzutti 8e0559963e Restore "Install musl-gcc for linux-musl nodejs releases"
This reverts commit cfc6ec2c0d.
2023-04-26 20:25:57 +09:00
Ivan Enderlin f26b9fb66c Merge branch 'main' into feat-sdk-sliding-sync-cancellation-token 2023-04-26 12:19:02 +02:00
Ivan Enderlin 5d0b42c42b test(sdk): Disable SlidingSync integration tests temporarily.
Because since SlidingSync no longer restarts, the behaviour is really
different. The current way the tests are written cannot assert the full
behaviour. We need to rewrite this test suite entirely.
2023-04-26 12:08:16 +02:00
Andrew Ferrazzutti 4bbea71d51 Add comment to explain why to use Ubuntu LTS-1 2023-04-26 18:45:18 +09:00
Andrew Ferrazzutti 80de0f0bbe Build Node bindings against Ubuntu 20.04
Fixes #1808
2023-04-26 18:45:16 +09:00
Ivan Enderlin f17003f00e chore(sdk): SlidingSync::stream takes a &self. 2023-04-26 11:19:11 +02:00
Ivan Enderlin bb049489ef feat(sdk): SlidingSyncList::on_list can return a value. 2023-04-26 11:18:38 +02:00
Kévin Commaille 51a2d101b6 base: Remove RoomMemberships::UNKNOWN/KNOWN
The unknown filter can be difficult to match with MembershipState,
depending on the store implementation.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 10:12:22 +02:00
Kévin Commaille f7e8b22646 memory-store: indexeddb: Store memberships as MembershipState
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 10:12:22 +02:00
Kévin Commaille 252f4cb9a2 sled: Store memberships as strings
Storing as bitset is not future-proof.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 10:12:22 +02:00
Kévin Commaille a511500e6e indexeddb: Store memberships as strings
Storing as bitset is not future-proof.
Just fix the latest migration. We assume no-one used it yet.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 10:12:22 +02:00
Kévin Commaille 3081dabb66 base: Add method to match RoomMemberships with MembershipState
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-26 10:12:22 +02:00
Ivan Enderlin 1709089e6d feat(sdk): SlidingSync sync loop can be controled via internal messages.
The MPSC channel that has been introduced in recent commits is now used
in this patch. The `SlidingSync::stream` method can be controlled via
the `internal_channel`.

This patch updates `SlidingSync::stream` to use the `tokio::select!
` macro to select any future that resolves first between the
`internal_channel` receiver, or `SlidingSync::sync_once`. Fairness is
biaised as the `internal_channel` has the priority.

This mechanism is already used by this patch: `SlidingSyncList::reset`
will send the `SlidingSyncInternalMessage::ContinueSyncLoop` to
“continue”… well… the sync loop, i.e. it will cancel in-flight waiting
for a response.

This entire mechanism removes the need to “stop” and “start”, i.e.
“restart” the `SlidingSync::stream` method manually, which was the
source of many bugs. Now everything is controlled internally.
2023-04-26 09:50:11 +02:00
Ivan Enderlin 770d50e2ce Merge pull request #1822 from AndrewFerr/af/update-nodejs-version
Update supported Node.js versions
2023-04-26 08:37:20 +02:00
Kévin Commaille ae79fd0af5 sdk: Deprecate Common::(active/joined)_members(_no_sync)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille b8f06ec4a1 sdk-base: Deprecate Room::(active/joined)_members
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille fe6424f48c sdk: Implement Common::(active/joined)_members_no_sync with members_no_sync
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille 2010c180a8 base-sdk: Implement Room::(active/joined)_members with members
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille e98fbfce9a sdk: Allow to filter Common::members(_no_sync) by membership state
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille f68b45aa49 base-sdk:Allow to filter Room::members by membership state
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille 81a543e15b sdk-base: Deprecate get_invited_user_ids and get_joined_user_ids
get_user_ids can be used instead

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille 4ffa20abde sdk-base: Allow to filter get_user_ids results by any membership state
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Kévin Commaille 58a1ad1b93 base: Use single map for all user IDs in memory store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-25 18:03:53 +02:00
Andrew Ferrazzutti 564549e8af Update Node bindings' "engines"
Signed-off-by: Andrew Ferrazzutti <andrewf@element.io>
2023-04-25 23:59:22 +09:00
Andrew Ferrazzutti 46f69f7efd Update supported Node.js versions
Signed-off-by: Andrew Ferrazzutti <andrewf@element.io>
2023-04-25 23:51:53 +09:00
Jonas Platte c897f0ccaf ffi: Print location for tracing events 2023-04-25 12:19:55 +02:00
Jonas Platte bd3a37791b Distinguish events from live sync and sync cache in debug string 2023-04-25 11:50:06 +02:00
Simon Farre b105359b27 Expose fetch_event_details to FFI
Signed-off-by: Simon Farre <simon.farre.cx@gmail.com>
2023-04-24 20:50:06 +00:00
Ivan Enderlin c5c8ac8a7c feat(sdk): Add support for bump_event_types in SlidingSync
feat(sdk): Add support for `bump_event_types` in `SlidingSync`
2023-04-24 20:23:27 +02:00
Ivan Enderlin 2a912f7422 Merge pull request #1817 from matrix-org/revert-1779-af/nodejs-musl-gcc
Revert "Install musl-gcc for linux-musl nodejs releases"
2023-04-24 19:59:23 +02:00
Ivan Enderlin cfc6ec2c0d Revert "Install musl-gcc for linux-musl nodejs releases" 2023-04-24 19:59:01 +02:00
Ivan Enderlin 7e243c5a5b Merge branch 'main' into fix-issue-1728 2023-04-24 19:46:56 +02:00
Kévin Commaille 910c35b699 sled: Return all user IDs in get_user_ids
It would only return joined and invited user IDs,
since those are the only ones that were stored.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-24 18:54:29 +02:00
Kévin Commaille 3f1a596c8c indexeddb: Return all user IDs in get_user_ids
It would only return joined and invited user IDs,
since those are the only ones that were stored.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-24 18:54:29 +02:00
Kévin Commaille 493db9dd3f sdk-test: Add room member ban sync event
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-24 18:54:29 +02:00
Ivan Enderlin 5d63f0b215 chore(sdk): Move variables in a smaller scope to clarify the code. 2023-04-24 15:14:11 +02:00
Ivan Enderlin 304d1f445b feat(sdk): SlidingSync types share a channel to talk to each other.
`SlidingSync` has a `Receiver`, `SlidingSyncList` has a `Sender`.
2023-04-24 14:17:33 +02:00
Ivan Enderlin 30abbe3cd4 feat(sdk): SlidingSync::add_list takes a SlidingSyncListBuilder.
Prior to this patch, `SlidingSync::add_list` was taking a
`SlidingSyncList`. However, we need to inject more data when building
the list, so let's modify `add_list` to take a `SlidingSyncListBuilder`
instead. It's even better for the user as calling `build()` isn't
necessary anymore.
2023-04-24 14:14:47 +02:00
Ivan Enderlin 7f5e61831e chore(sdk): Remove a useless import. 2023-04-24 14:11:36 +02:00
Ivan Enderlin 3b8ce5c9b1 feat(sdk): Create SlidingSync::on_list. 2023-04-24 14:11:36 +02:00
Ivan Enderlin e21d1fcb93 feat(sdk): SlidingSyncList no longer implement Clone.
It's not possible to clone a `SlidingSyncList` anymore. Why? Because
it's not correct. Prior to this patch, it was possible to add a list
to a `SlidingSync` instance, then add a clone of the same list to
another `SlidingSync` instance. Weird behaviors could happen, but more
importantly, for the next Sliding Sync design we are working on, it
could lead to gigantic bugs.

Removing `Clone` from `SlidingSyncList` makes the code simpler.
For example, `SlidingSyncList.inner` no longer needs an `Arc`, or
`SlidingSync::stream` no longer needs to clone all the lists.
2023-04-24 14:11:12 +02:00
Ivan Enderlin f4e577bbe0 feat(sdk): Remove SlidingSync::pop_list.
This method is used by nobody. It's safe to remove it.
2023-04-24 14:07:27 +02:00
Jonas Platte e5f4bbdc47 Upgrade dependencies 2023-04-24 13:59:01 +02:00
Jonas Platte e15e21a3d7 ffi: Use UniFFI proc-macros for SessionVerificationController type 2023-04-24 12:42:27 +02:00
Jonas Platte 3954cab2ab ffi: Use UniFFI proc-macros for Room type 2023-04-24 12:42:27 +02:00
Jonas Platte e1a727a27f ffi: Use UniFFI proc-macros for some misellaneousc symbols 2023-04-24 12:42:27 +02:00
Jonas Platte 75e7289ede ffi: Use UniFFI proc-macros for last parts of the Client type 2023-04-24 12:42:27 +02:00
Jonas Platte 00b3057e06 ffi: Use UniFFI proc-macros for ClientBuilder::build 2023-04-24 12:42:27 +02:00
Jonas Platte 5f802c1348 ffi: Use UniFFI proc-macros as much as possible for sliding sync 2023-04-24 12:42:27 +02:00
Jonas Platte 7ab14d9428 Enable Ruma's compat-user-id feature 2023-04-24 12:42:03 +02:00
Jonas Platte d527dd37b1 Upgrade Ruma 2023-04-24 12:42:03 +02:00
Jonas Platte 24a903ccb0 Fix Cargo.lock 2023-04-24 11:17:05 +02:00
Ivan Enderlin 8aad30ea4f Merge pull request #1779 from matrix-org/af/nodejs-musl-gcc
Install musl-gcc for linux-musl nodejs releases
2023-04-24 10:51:00 +02:00
Jonas Platte c6f491861e crypto-ffi: Use proc-macros for types no longer referenced in UDL 2023-04-24 10:31:12 +02:00
Jonas Platte 055f0ff988 crypto-ffi: Use proc-macros for Verification type and methods 2023-04-24 10:31:12 +02:00
Jonas Platte 058d27e0a3 crypto-ffi: Use proc-macros for Sas methods 2023-04-24 10:31:12 +02:00
Jonas Platte cb216044e1 crypto-ffi: Use proc-macros for OlmMachine methods 2023-04-24 10:31:12 +02:00
Jonas Platte 693ced4f4d crypto-ffi: Remove unused function 2023-04-24 10:31:12 +02:00
Jonas Platte 27cf710009 crypto-ffi: Use proc-macros for VerificationRequest methods 2023-04-24 10:31:12 +02:00
Jonas Platte 5202e3e1b9 crypto-ffi: Use proc-macros for QrCode methods 2023-04-24 10:31:12 +02:00
Jonas Platte d90d7b519b crypto-ffi: Use proc-macros for types not referenced in UDL 2023-04-24 10:31:12 +02:00
Jonas Platte d15447a2c1 crypto-ffi: Use proc-macro for exporting free functions 2023-04-24 10:31:12 +02:00
Ivan Enderlin be7b79b4e5 feat(ffi): Add binding for SlidingSyncBuilder::bump_event_types.
This patch adds a new binding on `SlidingSyncBuilder` to
`matrix_sdk::SlidingSyncBuilder::bump_event_types`.
2023-04-24 10:05:00 +02:00
Ivan Enderlin 7b2b3fa78f feat(sdk): Add support for bump_event_types in SlidingSync.
The `SlidingSyncBuilder` now has a new method: `bump_event_types`, to
configure the `bump_event_types` HTTP request parameter. This value
is passed to `SlidingSync`, which is used to build the `SlidingSync`
request.
2023-04-24 10:05:00 +02:00
Ivan Enderlin 1c2e7d8c0d chore: Update Cargo.lock. 2023-04-24 09:56:55 +02:00
Valere f8e4e3d7d5 fix(bindings): Withheld code mapping 2023-04-22 21:10:56 +02:00
Jonas Platte 9ffcb8bc8a ffi: Move error type into its own module 2023-04-20 18:24:47 +02:00
Jonas Platte 4f316a130f Remove uniffi_types modules 2023-04-20 18:24:47 +02:00
Jonas Platte 7e58e72671 Upgrade UniFFI 2023-04-20 18:24:47 +02:00
Florian Duros fd739a3676 matrix-sdk-crypto-js v0.1.0-alpha.7 2023-04-20 18:24:36 +02:00
Jonas Platte 167d81e36a ci: Simplify test-all-crates job 2023-04-20 14:52:34 +02:00
Richard van der Hoff 0a0da040d2 account.rs: add some comments (#1799) 2023-04-20 13:01:44 +01:00
Jonas Platte f2d2a20987 ffi: Change make_span to be a constructor, write docs 2023-04-20 11:43:45 +02:00
Jonas Platte 29068265db ffi: Add filtering of tracing events and spans 2023-04-20 11:43:45 +02:00
Jonas Platte 50f29e5a11 ffi: Add Span::is_none 2023-04-20 11:43:45 +02:00
Jonas Platte 54bd26d683 ffi: Add Span::current 2023-04-20 11:43:45 +02:00
Jonas Platte b532d35d21 Remove root_span from Client 2023-04-20 11:43:45 +02:00
Jonas Platte bb05ac7dac ffi: Add basic tracing bindings 2023-04-20 11:43:45 +02:00
Richard van der Hoff 0da8e56a68 crypto-js: wait for device updates in getUserDevices (#1790)
Wait for up to a second for any in-flight device list updates to complete.
2023-04-20 08:58:26 +01:00
Richard van der Hoff a88f53ee85 crypto-js: Expose more data on Device (#1786)
Implement Device.algorithms and Device.isSignedByOwner for the js bindings.
2023-04-20 08:57:54 +01:00
Jonas Platte 530fceb40d Fix some rustdoc warnings 2023-04-20 09:02:28 +02:00
Jonas Platte 7d5908beef sdk: Add more data to RemoteEventTimelineItem Debug string 2023-04-20 09:02:09 +02:00
Anderas 5d94a5d2f4 Update iOS Crypto SDK docs
… and add local podspec.
2023-04-19 18:09:21 +02:00
Jonas Platte 0e08d0f9ef sdk: Make EventTimelineItem's fields pub(super)
… and avoid an unnecessary clone.
2023-04-19 14:17:16 +02:00
Jonas Platte 3f6c9956ab sdk: Move timestamp to EventTimelineItem
… from Local/RemoteEventTimelineItem.
2023-04-19 14:17:16 +02:00
Jonas Platte c97d8afa58 sdk: Remove extra visibility boundary on {Local,Remote}EventTimelineItem 2023-04-19 14:17:16 +02:00
Jonas Platte abd508676e sdk: Remove {Local,Remote}EventTimelineItem from public API 2023-04-19 14:17:16 +02:00
Jonas Platte 7376198dfa sdk: Move sender, sender_profile, content to EventTimelineItem
… from Local/RemoteEventTimelineItem.
2023-04-19 14:17:16 +02:00
Jonas Platte 2960aafe3d sdk: Make EventTimelineItem an opaque struct instead of an enum 2023-04-19 14:17:16 +02:00
Jonas Platte 4daf31f5b1 Fix clippy lint 2023-04-19 14:17:16 +02:00
Jonas Platte bf4349ffb3 base-sdk: Don't separate member events from other state events
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-19 14:04:53 +02:00
Kévin Commaille b87a4e8c20 base-sdk: Don't separate member events from other state events
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-19 13:16:55 +02:00
Alfonso Grillo 3b1ed1403d sdk: Add DM invitation to m.direct account data upon accepting it 2023-04-18 18:05:48 +02:00
Alfonso Grillo fe10bcc814 base: Use member event is_direct field for is_direct() on invited rooms 2023-04-18 18:05:48 +02:00
Jonas Platte be67c91a6b Use regular backticks in matrix-sdk-ffi/README.md 2023-04-18 15:20:51 +02:00
Jonas Platte 89c06568dd Remove unneeded explicit lifetime 2023-04-18 15:20:51 +02:00
Alfonso Grillo dffa1b16c3 sdk: Skip user's own ID when marking a room as DM 2023-04-18 13:41:34 +02:00
Jonas Platte 5bc20669c2 sdk: Implement MSC3925 for the timeline
https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3925-replace-aggregation-with-full-event.md
Implemented in Synapse 1.79.0:
https://github.com/matrix-org/synapse/releases/tag/v1.79.0
2023-04-18 13:14:33 +02:00
Jonas Platte 86930581a5 Upgrade Ruma 2023-04-18 13:14:33 +02:00
Jonas Platte 40c1252f48 sdk: Simplify handling of bundled relations in timeline 2023-04-18 13:14:33 +02:00
Alfonso Grillo cfdc9b2a82 Expose accept_invitation to UniFFI 2023-04-18 12:45:30 +02:00
Jorge Martin Espinosa c5919e3e63 Add workaround for building Android bindings with supported NDK versions (r23+) 2023-04-17 16:06:46 +00:00
Andrew Ferrazzutti 4fbdd70a53 Use local reference to workflow file 2023-04-14 20:20:59 +09:00
Andrew Ferrazzutti a78b260857 Install musl-gcc for linux-musl nodejs releases 2023-04-14 17:43:42 +09:00
Damir Jelić cd865d21c3 Drop outbound group sessions in the SQLite store
The format of the outbound group session struct has changed. We nowadays correctly rotate the group session if we can't restore it, but it's still good to avoid logging the error in this case.
2023-04-13 14:48:14 +00:00
Damir Jelić 8137c39f3a Don't log the raw Ruma sliding sync response 2023-04-13 16:14:47 +02:00
Jonas Platte f21946ef06 sdk: Avoid raw JSON in debug strings 2023-04-13 16:00:50 +02:00
Damir Jelić 730b66e26c Add withheld code support 2023-04-13 11:46:19 +02:00
Damir Jelić 316b29c95f Merge branch 'main' into valere/msc_2399 2023-04-13 10:59:05 +02:00
Jonas Platte 1e737208e5 sdk: Handle ephemeral events after timeline events 2023-04-12 16:15:35 +02:00
Jonas Platte 36b9064e51 sdk: Reduce indentation in read receipt handling code
… by factoring out a function.
2023-04-12 15:24:52 +02:00
Jonas Platte 086106a96d sdk: Simplify return type of fetch_in_reply_to_details 2023-04-12 13:16:36 +02:00
Simon Farre b9fba69dc7 ffi: Fix kotlin build failure
Workaround for https://github.com/mozilla/uniffi-rs/issues/1434
2023-04-12 10:11:07 +00:00
Simon Farre 8bad59bbe1 ffi: Add avatar_url getter for SlidingSyncRoom
Signed-off-by: Simon Farre <simon.farre.cx@gmail.com>
2023-04-11 15:47:40 +00:00
Damir Jelić 972d5cefdb If we can't load an outbound group session from the store, rotate it
An error is currently thrown if loading an outbound group session fails.
This error may only affect loading outbound group sessions, while other
store operations continue to work fine. As a result, the user is unable
to send messages, but can still use the application without any problems.

Since outbound group sessions are rotated frequently, we can simply
rotate the session if loading fails. However, if the error is related to
a more serious storage issue, persisting the newly rotated outbound group
session will also fail. If the error is specific to outbound group
sessions, the user will be able to continue using the application without
interruption.
2023-04-11 10:08:06 +02:00
Damir Jelić c73aeef2ed Fix the serialization of outbound group sessions in the SQLite store
The SQLite crypto store uses rmp_serde to serialize all the data we're
going to store. This works nicely for most things, one exception to this
is the OutboundGroupSession type.

The OutboundGroupSession type stores to-device requests to ensure that
the session doesn't get used before it is shared with the whole group
and to ensure that the to-device requests get restored if the
session gets restored after an application restart.

The to-device requests type critically contain `Raw<AnyToDeviceEvent>`,
the `Raw` type here being the serde_json::Raw type. rmp_serde seems to
serialize this just fine, but later deserialization fails.

We're avoiding the issue by using serde_json to serialize the
OutboundGroupSession.
2023-04-11 10:08:06 +02:00
Damir Jelić 0f8da0b723 Test that to-device requests in the group session can get deserialized 2023-04-11 10:08:06 +02:00
Kévin Commaille a1cfb4bcf1 sdk: Re-export CrossSigningStatus
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-04-08 21:47:10 +02:00
Ivan Enderlin f6fb082dc9 chore(sdk): Remove unused methods in sliding_sync
chore(sdk): Remove unused methods in `sliding_sync`
2023-04-06 18:02:08 +02:00
Ivan Enderlin df9f48dc38 chore(sdk): Replace to_string by to_owned. 2023-04-06 18:01:45 +02:00
Ivan Enderlin 0b4c94961d test(sdk): Fix a test. 2023-04-06 17:42:28 +02:00
Ivan Enderlin 41d44f0d49 chore(sdk): Remove unused methods.
Those methods are public, but never used by our current users.

Moreover, there is some big overlaps. For example, `storage_key`,
`cold_cache` and `no_cache` do the same thing: They update the
`storage_key` field. Or `add_fullsync_list` is just a helper that is
never used except in the tests etc.
2023-04-06 16:29:38 +02:00
Jonas Platte 29255781cc Fix comments in Cargo.toml 2023-04-06 15:49:09 +02:00
Ivan Enderlin 1756aabe35 fix(sdk): SlidingSyncList.room_list emits updates for non-moving rooms
fix(sdk): `SlidingSyncList.room_list` emits updates for non-moving rooms
2023-04-06 15:08:47 +02:00
Ivan Enderlin 4ee4906536 chore(sdk): Make Clippy happy. 2023-04-06 11:36:37 +02:00
Ivan Enderlin fbe162a1bc test(sdk): Fix an integration test in Sliding Sync.
The test does the following:

1. Create 2 (identical) lists,
2. Do a sync.
3. Assert that the 1st and 2nd lists are receiving an update,
4. Add a 3rd (identical) list,
5. Do a new sync,
6. Assert that 3rd list is receiving an update.

This last step is wrong. All lists should receive an update as they
are identical.
2023-04-06 11:29:10 +02:00
Damir Jelić cebeca85d0 fixup! Minor fixes to the withheld handling 2023-04-06 11:23:27 +02:00
Damir Jelić 8c23b6e7b2 Minor fixes to the withheld handling 2023-04-06 11:18:14 +02:00
Ivan Enderlin eb0e97b902 test(sdk): Test that SlidingSyncList.room_list receives “diff”.
This patch updates a test to ensure that `room_list` receives “diff”
for rooms that are modified by a sync operations, but also by another
updates (like a new event).
2023-04-06 11:14:09 +02:00
Ivan Enderlin 828e36e3af test(sdk): Test apply_sync_operations removes rooms that have been updated. 2023-04-06 11:14:09 +02:00
Ivan Enderlin d68a22c378 fix(sdk): SlidingSyncList.room_list emits updates for non-moving room.
The `SlidingSyncList.room_list` field is used to store the list of rooms
for a particular Sliding Sync list. It's used by the user to receive
“diff”s when a room sees its position modified. For example when a new
room receives a message, it “climbs back up” the entire room list to
be at the top place. Another example is when a new room is created,
some rooms will move around to give the new room a space. All those
moves will create “diff”.

However, the user also expects to receive a “diff” when a room has
received some updates, even if it's position doesn't change. For
example, when a room is already at the top of the list but receives a
new message: It has received an update, but its position stays the same.

This specific latter feature was implemented before, but it has been
removed by accident in https://github.com/matrix-org/matrix-rust-sdk/
pull/1699 (more specifically in https://github.com/matrix-org/matrix-
rust-sdk/pull/1699/commits/861a05be69a566d9a4ad125dc6ecb418d2b3210f).
At that time, it was not clear why the code was filtering for specific
filled room entires, to set the filled room entries, at the same
position. Zero comment, zero test. I didn't consider this as a feature
but as a bug.

So this patch re-introduces this feature. Hopefully in a more optimal
way. If a room has already triggered a first “diff” because of a
position change, it won't trigger a second “diff” because it has
received an update (which was the case before).

The `SlidingSyncList::handle_response` method has also been renamed
`update`, as it does update, whenever it comes from.

The code has been commented and documented to explain this feature.

Existing tests have been updated, especially for `apply_sync_operations`
which now ensure the `rooms_that_have_received_an_update` collections is
updated accordingly. Another test has been updated specifically to test
the “diff”s received by `room_list`.
2023-04-06 11:09:55 +02:00
Ivan Enderlin a71970d3de chore(sdk): Rephrase a panic message. 2023-04-06 10:50:20 +02:00
Ivan Enderlin c07b060080 feat(sdk): Create vectors with correct capacity to avoid reallocations.
`updated_rooms` and `updated_lists` can be created with an initial
capacity. Doing so will avoid reallocations if the vector is too small.
2023-04-06 10:49:15 +02:00
Jonas Platte b033508e9b Fix clippy lints 2023-04-06 09:57:37 +02:00
Damir Jelić ba95a7bfd8 Use BTreeMap instead of HashMap
We use BTreeMap everywhere else, so let's be consistent with that
choice.
2023-04-05 14:38:25 +02:00
Damir Jelić 64d76308c6 Use as_ref() instead of stars and ampersands 2023-04-05 14:29:49 +02:00
Damir Jelić 52fef9f373 Don't use a Result return type in the withheld handling method 2023-04-05 14:27:00 +02:00
Damir Jelić c3437ac4cf Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-04-05 14:22:19 +02:00
Damir Jelić 6fd129dcfa Remove some commented out code and fix some formatting 2023-04-05 13:22:41 +02:00
Damir Jelić 1f8c67bbb2 Use the atomic bool seralizer for the no_olm flag 2023-04-05 13:15:51 +02:00
Damir Jelić 82a4b53cf9 fixup! Apply suggestions from code review 2023-04-05 13:15:38 +02:00
Damir Jelić 673db38a72 Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-04-05 13:14:07 +02:00
Damir Jelić 50d477b91c More clippy fixes 2023-04-05 11:54:29 +02:00
Damir Jelić 1c2964f3f3 Update crates/matrix-sdk-crypto/src/types/events/room_key_withheld.rs
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-04-05 11:52:25 +02:00
Damir Jelić 92202e20e7 Fix some clippy warnings 2023-04-05 11:45:50 +02:00
Damir Jelić c032609f4d Fix the js tests now that we bumped our DB version 2023-04-05 11:34:28 +02:00
Olivier Wilkinson (reivilibre) 9c54de1817 Downgrade memory store 'Saved changes in <time>' to debug
It doesn't seem very interesting since a memory store will be fast anyway. In practice, this fills the console quickly.
2023-04-05 11:31:37 +02:00
Damir Jelić d606bd3e9f Document the new withheld content enums 2023-04-05 11:18:50 +02:00
Ivan Enderlin 7c578dccb9 fix(sdk): SlidingSync uses the same storage keys for storing *and* restoring
fix(sdk): `SlidingSync` uses the same storage keys for storing *and* restoring
2023-04-05 11:11:47 +02:00
Ivan Enderlin 5563213106 chore(test): Make Clippy happy. 2023-04-05 10:56:08 +02:00
Jonas Platte 91dc87808d ffi: Add InReplyToDetails 2023-04-05 10:50:08 +02:00
Jonas Platte 1217067f74 ffi: Rename ProfileTimelineDetails to ProfileDetails 2023-04-05 10:50:08 +02:00
Jonas Platte 5b512f020e sdk: Rename details field to event in InReplyToDetails 2023-04-05 10:50:08 +02:00
Ivan Enderlin 042d6bab72 test(sdk): Test SlidingSync is store and restored correctly. 2023-04-05 10:06:59 +02:00
Jonas Platte ef3ffda2d3 ffi: Replace EventTimelineItem::{raw, fmt_debug} by debug_info 2023-04-05 09:56:00 +02:00
Jonas Platte 3ac6b10daa sdk: Add RemoteEventTimelineItem::latest_edit_json
… and rename raw to original_json to disambiguate.
2023-04-05 09:56:00 +02:00
Ivan Enderlin be631849e8 fix(sdk): Move SlidingSync::cache_to_storage to cache.
This patch also re-uses the `format_storage_key_*` functions to use the
same key as the `restore_sliding_sync_state` function. It fixes a bug
where the keys were mismatching.
2023-04-05 09:17:54 +02:00
Ivan Enderlin fc8b9d7de4 feat(sdk): Extract SlidingSync cache functions into their own module. 2023-04-05 09:05:03 +02:00
Jonas Platte 2c38c6c371 sdk: Log in_reply_to field in timeline::Message Debug impl 2023-04-04 18:09:08 +02:00
Damir Jelić 81e2725b6f Remove DirectWithheldCode 2023-04-04 13:30:29 +02:00
Simon Farre fc56ae3dcf Expose invite_user_by_id over the FFI
This PR is self explanatory.

Exposes said function to the FFI. Defined in the .adl file,
and defined to throw `ClientError`

Signed-off-by: Simon Farre <simon.farre.cx@gmail.com>
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-04-04 09:04:54 +00:00
Chris Smith e8c56f8163 feat: expose inviter to ffi
This allows us to know who has invited us to rooms
2023-04-04 10:29:04 +02:00
Ivan Enderlin 690c3b1977 Merge pull request #1699 from Hywan/feat-sdk-sliding-sync-list-revamp-sync-mode
feat(sdk) Revamp Sliding Sync List state lifetime
2023-04-03 15:04:21 +02:00
Ivan Enderlin ac800180a7 Merge branch 'main' into feat-sdk-sliding-sync-list-revamp-sync-mode 2023-04-03 14:36:26 +02:00
Damir Jelić b7a78c865c Ensure correct Olm session selection for encrypted messages
In some cases, restoring client state from backups may cause Olm sessions
to become corrupted, resulting in a backward ratchet. As a consequence,
the receiving side is unable to decrypt messages. To address this issue,
the failed side initiates a new Olm session and sends a dummy encrypted
message.

However, this dummy message also creates a new Olm session on the
sender's side. To ensure that both sides use the same new session, we
must sort sessions by their creation timestamp before encrypting new
messages.

Although the session list was sorted correctly previously, we selected
the wrong side of the list, resulting in an outdated session being
selected instead of the newest one. This patch resolves the issue by
selecting the newest Olm session and adds a test to the session getter
logic to prevent reintroduction of this bug.
2023-04-03 13:03:09 +02:00
Ivan Enderlin aeda2d363c Merge pull request #1736 from Hywan/feat-sliding-sync-storage 2023-04-03 12:54:49 +02:00
Ivan Enderlin 69af5b3c6f feat(sdk): When a SlidingSync cache is obsolete, let's remove it.
Prior to this patch, when `SlidingSync` was built with a storage key,
the storage was read to find a previous `SlidingSync` version that
was in a cache. To put a `SlidingSync` instance in the cache, it
was serialized to JSON. When one reads from the cache, the value is
deserialized. A problem happens when the internal representation of
`SlidingSync` and other types (e.g. `SlidingSyncList`) have changed (due
to an SDK update for example): Loading a previous state from the cache
results in an error.

After discussion with the teams, clients don't want to deal with
obsolete cache values. In such a scenario, (i) they cannot interact
with the cache to remove the obsolete entry, and (ii) their only
possibility is to log out and log in the user again. What an unfriendly
user experience!

This patch modifies this behaviour. When loading a `SlidingSync` type or
a `SlidingSyncList` type from the cache, 3 cases are now handled:

1. The cache entry exists and has been successfully deserialized: in
   this case, we do our business.
2. The cache entry exists, but it wasn't possible to deserialize it: the
   cache entry is declared as obsolete, and the entire `SlidingSync`
   cache is cleaned up, so all entries for `SlidingSync` and
   `SlidingSyncList` are removed from the storage,
3. The cache entry doesn't exist: we do nothing particular.

Note that if one cache is obsolete, all cache entries are removed.
2023-04-03 12:10:50 +02:00
Ivan Enderlin 56a7854b53 Merge branch 'main' into feat-sdk-sliding-sync-list-revamp-sync-mode 2023-04-03 10:10:31 +02:00
Ivan Enderlin 60d4ac14b7 Merge pull request #1725 from Hywan/feat-remove-jack-in
feat(labs): Remove `jack-in`
2023-04-01 13:27:20 +02:00
Richard van der Hoff 78b9758377 Merge pull request #1721 from matrix-org/rav/crypto-js-releases
Fixes and documentation for crypto-js releases
2023-03-31 11:22:50 +01:00
Richard van der Hoff a5fd71a251 prettify markdown 2023-03-31 11:08:26 +01:00
Alfonso Grillo 7958a20fc1 Add short_retry on get_profile 2023-03-30 22:00:09 +02:00
Jonas Platte 6878f52885 Upgrade UniFFI 2023-03-30 21:53:02 +02:00
Ivan Enderlin ea5b4c98c1 feat(labs): Remove jack-in.
This was a fun ride, but nobody uses it, and we don't need it anymore.

Thanks for all the fishes.
2023-03-30 18:03:38 +02:00
Ivan Enderlin 60432abe0d feat(ffi): Add SlidingSync::reset_lists. 2023-03-30 18:01:17 +02:00
Ivan Enderlin 2d537e5211 feat(sdk): Add SlidingSync::reset_lists.
The `SlidingSync::stream` method no longer resets the lists everytime
it is called. If one wants to reset the lists, they need to call
`SlidingSync::reset_lists`.
2023-03-30 18:01:16 +02:00
Jonas Platte 7dd086fcdc Make sqlite bundling optional 2023-03-30 17:59:51 +02:00
Ivan Enderlin bd6075f6b4 fix(sdk): Try to find workarounds about the bug in SlidingSync Proxy.
It still about https://github.com/matrix-org/sliding-sync/issues/52. We
try to rebuilt a valid `range`. Hopefully, the bug will be fixed soon,
and we will be able to clean that temporary code.
2023-03-30 17:52:33 +02:00
Kévin Commaille 48b67759ed sdk: Make PaginationOption's custom variant's strategy return a ControlFlow
It is semantically more correct than an Option.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-30 14:39:08 +00:00
Richard van der Hoff f60c678af8 Apply suggestions from code review
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-03-30 15:38:42 +01:00
innocent fish a35d96c15e Update swift.rs 2023-03-30 16:08:06 +02:00
Alfonso Grillo ade7fabb6b Add Client::get_profile 2023-03-30 15:44:27 +02:00
Ivan Enderlin dd4cb9c793 test(sdk): Fix SlidingSync doctests. 2023-03-30 15:10:17 +02:00
Ivan Enderlin 2ace220366 chore(sdk): Rename rooms_list to room_list. 2023-03-30 15:06:19 +02:00
Richard van der Hoff 4f3f9c7af8 Fixes and documentation for crypto-js releases
The tags are supposed *not* to contain `v`, for consistency with the other
crates.
2023-03-30 13:57:15 +01:00
Richard van der Hoff 43d4e7b46a Merge pull request #1719 from matrix-org/release-matrix-sdk-crypto-js-0.1.0-alpha.6
matrix-sdk-crypto-js v0.1.0-alpha.6
2023-03-30 13:53:39 +01:00
Ivan Enderlin 4be02d0e99 test(sdk): Wait longer on the server to reply. 2023-03-30 14:43:33 +02:00
Ivan Enderlin e34708862d test(sdk): Remove a useless SS test. 2023-03-30 14:31:52 +02:00
Ivan Enderlin f269202ece fix(sdk): Try to find a workaround for a bug in the SS Proxy.
See https://github.com/matrix-org/sliding-sync/issues/52 for the
explanation. And this patch has comments explaining how I try to work
around this.
2023-03-30 14:23:59 +02:00
Kévin Commaille 408f966a50 sdk: Rename flag to update fully-read marker
Its meaning has changed since it is used in more cases.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-30 14:23:57 +02:00
Kévin Commaille 553ffe97a8 sdk: Never insert read marker in last position in timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-30 14:23:57 +02:00
Ivan Enderlin 23f16f065b fix(sdk): Make out-of-bounds DELETE a no-op. 2023-03-30 13:37:31 +02:00
Richard van der Hoff f246296ff9 matrix-sdk-crypto-js v0.1.0-alpha.6
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 34s
2023-03-30 12:26:29 +01:00
Mauro ca6faffc72 bindings: Reset the timeline when the user's ignore list is updated 2023-03-30 11:22:06 +00:00
Ivan Enderlin 4c42205633 chore(labs): Update to the latest SS version. 2023-03-30 12:57:24 +02:00
Richard van der Hoff f9881065c1 Add an API to notify apps when a megolm key is received
This is useful for applications which want to have another go at decryption
when some room keys arrive.
2023-03-30 12:29:39 +02:00
Ivan Enderlin 1af1504ef3 feat(ffi): Update to the latest Sliding Sync version. 2023-03-30 11:42:22 +02:00
Damir Jelić 7fd1c93e1a Document the fact that we require protoc to build the bindings 2023-03-30 11:06:15 +02:00
Doug a33d2ad28f bindings: Add ignore_user 2023-03-30 08:59:19 +00:00
Ivan Enderlin bd8a97cfd7 feat(sdk): Update the SyncOp::Delete operation.
It seems that the `DELETE` operation actually deletes an entry. So
let's update the code to reflect that :-).
2023-03-30 10:35:27 +02:00
Ivan Enderlin ce94fcc2e2 feat(sdk): Update the SyncOp::Insert operation.
It seems that the `INSERT` operation actually inserts a new entry. So
let's update the code to reflect that :-).
2023-03-30 10:00:21 +02:00
Ivan Enderlin a442ca1893 Merge branch 'main' into feat-sdk-sliding-sync-list-revamp-sync-mode 2023-03-29 17:29:15 +02:00
Ivan Enderlin db7746062f doc(sdk): Write more doc. 2023-03-29 17:23:37 +02:00
Ivan Enderlin bc9d5016dc chore(sdk): Move maximum_number_of_rooms's update a little bit above. 2023-03-29 17:15:07 +02:00
Ivan Enderlin 581c02307e fix(sdk): Rewrite SyncOp::Invalidate entirely.
`SyncOp::Invalidate` means _invalidating_ a particular range. When a
room is `Filled`, it becomes `Invalidated`, when it is `Invalidated` it
stays `Invalidated`, and when it is `Empty` it stays `Empty`.

Before this patch, `Empty` was becoming `Invalidated`, which apparently
is a bug.

This patch also fixes out-of-bound accesses, and adds many tests.

Finally, this patch renames `update_state` to `update_room_lists`.
2023-03-29 17:11:01 +02:00
Ivan Enderlin a4f8c35efc fix(sdk): Rewrite SyncOp::Insert entirely.
`SyncOp::Insert` means _inserting_ a new room ID. The `rooms_list`
contains all possible rooms (based on `maximum_number_of_rooms`, a value
returned by the server). Here, inserting = setting
`RoomListEntry::Filled` at a particular index of `rooms_list`, that's
it.

The previous code was doing very complex stuff, like removing things
around the `index` if something etc. It was using the requested ranges
(the range passed to the request) etc.

Applying `SyncOp` should be simple and is focused on updating
`rooms_list` only: the requested ranges have nothing to do here.

This patch also prevents against out-of-bounds acccesses, which wasn't
the case before.
2023-03-29 16:30:06 +02:00
Ivan Enderlin 2878148b0e fix(sdk): Prevent ouf of bounds accesses for SyncOp::Delete.
This patch prevents out of bounds acceses for `SyncOp::Delete`, and adds
more tests.

This patch also removes a cast from `UInt` to `u32` to `usize`. It's now
from `UInt` to `usize` directly.
2023-03-29 16:10:44 +02:00
Ivan Enderlin d6cfd871c4 feat(sdk): Protect against invalid responses from the server. 2023-03-29 15:55:02 +02:00
Ivan Enderlin 18597f8f63 fix(sdk): Fix out-of-bounds and re-implement SlidingOp::Sync handler.
First off, this patch renames `ops` to `sync_operations` and `room_ops`
to `apply_sync_operations`.

Second, the `SlidingOp::Sync` was creating an out-of-bounds access
depending of the range present in the server's response. For example, if
the `rooms_list` contains 5 elements (because the
`maximum_number_of_rooms` is set to 5), and the server replies with:

```json
{
    "op": "SYNC",
    "ranges": [3, 17],
    "room_ids": […]
}
```

the previous code was setting a new `RoomListEntry` at indices `3..=17`,
whilst the `rooms_list` contains only indices from `0..=4`. That's
annoying.

The previous code was also counting the number of `room_ids` for
nothing, just to execute the iterator that was applying the actual
changes in a `map`. Well, everything was fishy.

This patch updates the code to protect against an unexpected server's
reply by raising an `Err`. This patch also adds tests.
2023-03-29 15:30:10 +02:00
Jonas Platte 6b5f0b8ec3 Reset visible timeline when a gappy sync arrives 2023-03-29 14:00:33 +02:00
Damir Jelić 172867fd4d Simplify the withheld code receiving 2023-03-29 13:44:28 +02:00
Jonas Platte 50cc356c7b Use Observable for sliding_sync_reset_broadcast_tx 2023-03-29 13:23:24 +02:00
Jonas Platte 2ac192f307 Use str::to_owned instead of str::to_string
Expresses intent more clearly.
2023-03-29 13:23:24 +02:00
Damir Jelić 03aba95e1e Switch the FFI bindings to use the SQLite cryptostore 2023-03-29 11:44:33 +02:00
Ivan Enderlin 616e57eb1c test(sdk): Update integration test suite for SS. 2023-03-29 11:05:02 +02:00
Ivan Enderlin 5c695bbf8f feat(ffi): Update add_range calling. 2023-03-29 10:55:14 +02:00
Ivan Enderlin 861a05be69 feat(sdk): Remove updated_rooms from SlidingSyncListInner::update_state.
The `updated_rooms` argument was passed to `find_rooms_in_list` to
update the `room_list`: the update is setting the filtered room list
entry to `RoomListEntry::Filled`.

_But_, `find_rooms_in_list` was already filtering rooms which are
`Filled`. So it does… nothing: it filters rooms which are `Filled` to
update them to `Filled`.

So we can remove `find_rooms_in_list` because it becomes useless. And we
can remove `updated_rooms` too.

The `rooms_list` is updated by `rooms_ops` itself. Let's keep
modifications in one unique place.
2023-03-29 10:51:33 +02:00
Damir Jelić cf17a05ecc Restructure the withheld code types 2023-03-29 10:45:26 +02:00
Ivan Enderlin 385dd9113b feat(sdk): Simplify SlidingSyncListInner::update_state.
The `update_state` method of `SlidingSyncListInner` has basically
2 cases:

1. For an initial response,
2. For other responses.

The code between the 2 cases were almost identical. Or, they could be
identical. The few exceptions are:

* In the first case, the `rooms_list` updates were taking the
  form of a `VectorDiff::Append`, while the second case, it was a
  `VectorDiff::PushBack`.
* In the first case, the `is_cold` flag was set to `false`.

It's fine for the clients to receive only a `VectorDiff::Append` event
only. So let's make it uniform.

And it appears that the `is_cold` field is now private, and never read
anywhere else. So… it's… basically useless. We can remove it! It was
previously used here to know which flow to use, but since we can make
both flows identical, its role becomes insignificant.
2023-03-29 09:52:58 +02:00
Ivan Enderlin 3f4f9c1fbd chore(sdk): Remove a useless reference. 2023-03-29 09:52:05 +02:00
Ivan Enderlin bf163ef5ad feat(sdk): Replace checked_sub + unwrap_or_default by saturating_sub. 2023-03-29 09:23:47 +02:00
Ivan Enderlin 83cf820508 chore(sdk): More code in blocks to remove mutable variables with larger scopes. 2023-03-29 09:23:10 +02:00
Jonas Platte d680b331d0 Make tokio a workspace dependency 2023-03-28 21:08:57 +02:00
Jonas Platte cd33d8ca38 Always use RwLock and Mutex from tokio
… instead of async-lock, which we previously used on wasm.
2023-03-28 21:08:57 +02:00
Jonas Platte 9bfd88cec4 sdk: Always use tokio OnceCell
Tokio's sync module works on wasm as well.
2023-03-28 21:08:57 +02:00
Damir Jelić d5fba19655 Don't allow the no_olm withheld code sent flag to be reset 2023-03-28 14:31:55 +02:00
Ivan Enderlin ab29e1b319 !debug 2023-03-27 14:32:11 +02:00
Ivan Enderlin a2dbeda758 feat(sdk): SlidingSyncList cannot be removed from SlidingSync.
`create_range` and `SlidingSyncList::next_request` return a `Result`
instead of an `Option`. It was a legacy from the old `impl Iterator` of
`SlidingSyncListRequestGenerator`. But actually, when `create_range`
fails, it must return a `Err` value, not a `None` value.

And since it's a regular error, `sync_once` can propagate the
error. Thus, it is no longer necessary to “update” the list of
`SlidingSyncList`. It's not necessary to remove some items in this list
when the `next_request` method can no return a value: it always returns
a value, except when a error happens.
2023-03-27 14:25:40 +02:00
Damir Jelić 0d3fd31893 Clean up the withheld code types 2023-03-27 09:21:48 +02:00
dependabot[bot] 8b5de47acb chore(deps): bump openssl from 0.10.45 to 0.10.48 (#1706)
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.45 to 0.10.48.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.45...openssl-v0.10.48)

---
updated-dependencies:
- dependency-name: openssl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-25 21:12:52 +01:00
Kévin Commaille 5a7ea607c6 sdk: Use new filter constructor to enable room members lazy-loading
* sdk: Use new filter constructor to enable room members lazy-loading

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-25 21:12:09 +01:00
Flescio 09fc258f9a ffi: Make name parameter optional in CreateRoomParameters 2023-03-23 16:56:52 +00:00
Ivan Enderlin fdba90587a feat(sdk): Reset the SlidingSyncList when starting a stream. 2023-03-23 17:44:25 +01:00
Ivan Enderlin 63ed675158 doc(sdk): Extract the giant SS doc inside a README.md file.
Why? Because it takes forever to scroll to the code when opening
`sliding_sync/mod.rs` :-p.
2023-03-23 17:38:20 +01:00
Ivan Enderlin 767e9b3cf2 feat(sdk) Reset SlidingSyncList when a range is modified. 2023-03-23 16:32:53 +01:00
Ivan Enderlin 8d4ceac21f test(sdk): Continue to fix, test and clean up SlidingSyncList
test(sdk): Continue to fix, test and clean up `SlidingSyncList`
2023-03-23 13:18:09 +01:00
Ivan Enderlin d1616d5654 chore(sdk): Remove a useless comma. 2023-03-23 13:17:54 +01:00
Ivan Enderlin 492e08598c feat(sdk): Revamp SlidingSyncList::*range*.
First off, `set_ranges`, `set_range`, `add_range` and `reset_ranges`
take a `&[(U, U)]` instead of a `Vec<(U, U)>` when a vector was needed,
or takes a `(U, U)` instead of 2 arguments when it was needed.

Second, all those methods now return a `Result<(), Error>`. The
`Error::CannotModifyRanges` is raised if the chosen `SlidingSyncMode`
doesn't allow to modify ranges. Basically, `Selective` does allow a
user to modufy the ranges, but there is no real ranges with `Growing` or
`Paging`. Let's make it an explicit error.

Finally, `SlidingSyncListInner` has 2 methods: `set_ranges` and
`add_range`, but without any “ranges check”; `SlidingSyncList` does call
the inner methods, but does the checks.
2023-03-23 12:34:48 +01:00
Ivan Enderlin 6716939b6d chore(sdk): Re-order fields in SlidingSyncListInner. 2023-03-23 11:56:08 +01:00
Ivan Enderlin 73959e023b feat(sdk): Remove for FullSync suffix to sync modes. 2023-03-23 11:53:39 +01:00
Ivan Enderlin ec02d462ea feat(sdk): The SlidingSyncList.full_sync_* fields are no longer useful.
They are unused. Let's remove them.
2023-03-23 11:50:38 +01:00
Ivan Enderlin 0eee472829 feat(sdk): Remove send_updates_for_items.
This field is always set to `true` by all the clients. So let's consider
that something we always want, and let's remove code complexity.
2023-03-23 11:46:56 +01:00
Ivan Enderlin 296328e8e0 feat(sdk): Don't rename SlidingSyncState's variants when serialization.
We are going to introduce a BC break. So let's take the opportunity to
get rid off of this renamings too.
2023-03-23 11:37:53 +01:00
Ivan Enderlin 831090c92c feat(sdk): Export RoomListEntry into its own module. 2023-03-23 11:24:30 +01:00
Ivan Enderlin fa361aea16 chore(sdk): Make Clippy happy. 2023-03-23 11:18:09 +01:00
Ivan Enderlin 91e9942fcd feat(sdk): Export FrozenSlidingSyncList into its own module. 2023-03-23 11:15:24 +01:00
Kévin Commaille 5eeea83c19 sdk: Get push actions of retried decrypted events in the timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-23 10:59:55 +01:00
Kévin Commaille 98386cf527 sdk: Get push actions of decrypted events
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-23 10:59:55 +01:00
Kévin Commaille a3667a21c9 sdk: Simplify e2ee branching of Common::event
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-23 10:59:55 +01:00
Kévin Commaille fae10ae7f3 sdk: Add private method to get the current push rules
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-23 10:59:55 +01:00
Ivan Enderlin 1db8084c4f chore(sdk): Make Clippy happy. 2023-03-23 10:38:37 +01:00
Ivan Enderlin b544639187 chore(sdk): Re-ordering methods inside SlidingSyncList. 2023-03-23 10:07:19 +01:00
Ivan Enderlin 5e1fda9834 test(sdk): Update the assert_ranges macro to be able to define the first list state. 2023-03-23 10:05:34 +01:00
Ivan Enderlin 5bae1a2a4e chore(sdk): rooms_ops takes a &[(UInt, UInt)] for the ranges. 2023-03-22 16:59:45 +01:00
Ivan Enderlin defe48bf3c test(sdk): Test SlidingSyncList::get_room_id. 2023-03-22 16:45:53 +01:00
Ivan Enderlin caf55308a5 feat(sdk): Remove SlidingSyncList::rooms_updated_broadcast_stream.
This method is never used by the clients, so it's basically public dead
code. It doesn't fulfill a particular requirement nor a need, so let's
remove it.

Fixes https://github.com/matrix-org/matrix-rust-sdk/issues/1694.
2023-03-22 16:40:06 +01:00
Ivan Enderlin f2aebcb983 test(sdk): (Re)write a test for SlidingSyncListInnner::find_rooms_in_list. 2023-03-22 16:40:06 +01:00
Ivan Enderlin 2840242331 chore(sdk): Use &[…] instead of &Vec<…>.
One less pointer indirection.
2023-03-22 16:40:06 +01:00
Ivan Enderlin 69a779a7eb feat(sdk): Improve SlidingSyncListInner::find_rooms_in_list.
The `SlidingSyncListInner::find_rooms_in_list` method can be greatly
improved by using the `Iterator` API.

It was already using `Iterator::skip`, great! Let's continue by using
`Iterator::take` instead of using a stop index.

And let's use `Iterator::enumerate` to avoid using a mutable index.
2023-03-22 16:40:06 +01:00
Ivan Enderlin b7da197846 doc(sdk): Add missing documentation. 2023-03-22 16:40:06 +01:00
Ivan Enderlin 0b9b01727e feat(sdk): Remove find_rooms?_in_list from the public API.
`SlidingSyncList::find_room_in_list` and
`SlidingSyncList::find_rooms_in_list` aren't useful (and never used) by
the public consumer of this API. Let's remove it. They are only used for
internal purposes.
2023-03-22 16:40:06 +01:00
Ivan Enderlin 0d58695e39 feat(sdk): SlidingSyncListInner::update_request_generator_state returns a Result.
Before, the `update_request_generator_state` method was emitting an
`error!` log, but not an error. But that's clearly an error!

This patch updates the method to return a `Result<(), Error>`, and adds
a new variant to `Error`.
2023-03-22 16:40:06 +01:00
Ivan Enderlin f5ba7ddc4a fix(sdk): Prevent bugs, remove expensive clones, and simplify SlidingSyncList
fix(sdk): Prevent bugs, remove expensive clones, and simplify `SlidingSyncList`
2023-03-22 16:39:30 +01:00
Ivan Enderlin 7052e9ff64 doc(sdk): Fix typos. 2023-03-22 16:38:45 +01:00
Ivan Enderlin 8796bfe874 doc(sdk): Fix typos. 2023-03-22 16:16:33 +01:00
Ivan Enderlin 9e7c6c3632 feat(sdk): Remove deduplication logic from Sliding Sync
feat(sdk): Remove deduplication logic from Sliding Sync
2023-03-22 14:44:45 +01:00
Ivan Enderlin 6617e94a9d Merge pull request #1632 from Hywan/doc-sdk-sliding-sync
doc(sdk): Rephrase the Quick refreshing Section
2023-03-22 14:19:46 +01:00
Ivan Enderlin 7e8c8b1a14 chore(sdk): Make Clippy happy. 2023-03-22 13:31:48 +01:00
Ivan Enderlin 9078a30e28 chore(sdk): Move code around, and remove pub on fields of a private struct. 2023-03-22 13:17:52 +01:00
Ivan Enderlin 485ca402f4 test: Use available setter. 2023-03-22 13:17:52 +01:00
Ivan Enderlin d41293879a test(sdk): Move tests from list/request_generator.rs to list/mod.rs. 2023-03-22 13:17:52 +01:00
Ivan Enderlin d5babfbb88 test(sdk): Test SlidingSyncList::(set_)timeline_limit. 2023-03-22 13:17:52 +01:00
Ivan Enderlin b842b2f96d feat(sdk): Add getters and setters on SlidingSyncList. 2023-03-22 13:17:52 +01:00
Ivan Enderlin 32e83a942d fix(sdk): Prevent bugs, remove expensive clones, and simplify SlidingSyncList.
There are problems with `SlidingSyncListRequestGenerator`:

* It's part of the module API,
* It contains a clone of `SlidingSyncList`.

To create a `SlidingSyncListRequestGenerator`, one has to
call `SlidingSyncList::request_generator`. It was done in
`SlidingSync::stream`. The problem is that it clones `SlidingSyncList`.
So theoritically it is possible to create multiple request generators
for the _same_ list, and use them to send many requests and to update
the _same_ list with multiple responses. This is utterly error-prone and
can lead to really complex bugs to discover.

Moreover, it's a lot of clones. Cloning a
`SlidingSyncListRequestGenerator` isn't cheap as it means cloning a
`SlidingSyncList`. Moreover, cloning a `SlidingSyncList` isn't cheap as
it means cloning the entire struct.

Having `SlidingSyncListRequestGenerator` inside the module API also
makes the code of `SlidingSync` more complex (why having to deal with
lists and request generators at the same time? we must be very careful
to maintain both side by side? what if a list is removed but not its
request generator? and so on).

So. This patch simplifies all that.

First off, it extracts all the fields of `SlidingSyncList` into a
`SlidingSyncListInner` struct. Then, `SlidingSyncList` has only one
field: `Arc<SlidingSyncListInner>`. Boom, it's now cheap to clone it.

Second, `SlidingSyncListRequestGenerator` is only a
struct with constructors, but there is no extra methods.
`SlidingSyncListRequestGenerator` _no longer_ contains a
`SlidingSyncList`, and doesn't no need a list at all to work. It's just
values.

Third, `SlidingSyncList` holds a `SlidingSyncListRequestGenerator`, and
only one.

Fourth, `SlidingSyncList` (and `SlidingSyncListInner`) now has methods
to handle the internal request generator. The initial `impl Iterator for
SlidingSyncListRequestGenerator` becomes a simple
`SlidingSyncList::next_request` method.

Fifth, previously, the `SlidingSyncList::handle_response`
was never called directly by `SlidingSync`. It was called by
`SlidingSyncListRequestGenerator`! How confusing! `SlidingSync` called
`SlidingSyncListRequestGenerator::handle_response` which was calling
`SlidingSyncList::handle_response`. Now, the flow is more natural:
`SlidingSync` calls `SlidingSyncList::handle_response` and that's it.

Sixth, the `SlidingSyncList::handle_response` is now composed of 2
parts: updating the list itself, and updating the request generator. It
was kind of the case before, but onto two different types.
It was unclear which types were updating `SlidingSyncList`.
For example, `SlidingSyncList::state` was updated by…
`SlidingSyncListRequestGenerator`. Now `SlidingSyncList` is responsible
to update itself, and no one else.

Finally, `SlidingSync` no longer have to deal with
`SlidingSyncListRequestGenerator`. All it has is a set of
`SlidingSyncList`, and that's it!

The tests are still passing, hurray.
2023-03-22 13:17:50 +01:00
Ivan Enderlin d81e6a18f9 chore(sdk): Format a comment. 2023-03-22 13:15:50 +01:00
Ivan Enderlin e514415642 test(sdk): Write test suites for SlidingSyncList and siblings
test(sdk): Write test suites for `SlidingSyncList` and siblings
2023-03-22 12:29:27 +01:00
Ivan Enderlin d9096cc64c chore(sdk): Make Clippy happy. 2023-03-22 12:14:04 +01:00
Ivan Enderlin f085289d05 chore(sdk): Make Clippy happy. 2023-03-22 11:37:51 +01:00
Damir Jelić ef81168434 Fix some doc links in the send_attachment docs 2023-03-22 11:36:02 +01:00
Ivan Enderlin 1f04353668 test(sdk): Use vector! from imbl, not im. 2023-03-22 11:20:07 +01:00
Alfonso Grillo f70b6f5ecf Expose 'search users' to UniFFI (#1689) 2023-03-22 11:15:03 +01:00
Ivan Enderlin ee7dc2a7ab chore(sdk): Address PR feedback. 2023-03-22 11:06:21 +01:00
Ivan Enderlin 1256052134 chore(sdk): Clean up. 2023-03-22 11:06:21 +01:00
Ivan Enderlin 28eebe2043 doc(sdk): Explain what SlidingSyncList::handle_response does and does not. 2023-03-22 11:06:21 +01:00
Ivan Enderlin bb54ff7991 chore(sdk): Move and document the SlidingSyncList::request_generator method. 2023-03-22 11:06:21 +01:00
Ivan Enderlin aa75d02ae3 feat(sdk): SlidingSyncList::handle_response must be pub(self).
This method must be only visible to the current module, not from the
upper/super module.

Note: `pub(self)` is equivalent to no `pub` at all.
2023-03-22 11:06:21 +01:00
Ivan Enderlin eefef9a81b test(sdk): Move test to appropriate files. 2023-03-22 11:06:21 +01:00
Ivan Enderlin 15646ec1d6 test(sdk): Fix how TimelineEvent is constructed. 2023-03-22 11:06:21 +01:00
Ivan Enderlin 10380596cd chore(sdk): Format a comment. 2023-03-22 11:06:21 +01:00
Ivan Enderlin c4df1cb9aa chore(sdk): Rename an argument. 2023-03-22 11:06:21 +01:00
Ivan Enderlin c509b6c76a test(sdk): Add tests for SlidingSyncList.set_range, add_range and reset_ranges. 2023-03-22 11:06:21 +01:00
Ivan Enderlin 9c2e2238ed test(sdk): Add a test for SlidingSyncList::ranges. 2023-03-22 11:06:21 +01:00
Ivan Enderlin 2edb5d845e feat(sdk): SlidingSyncList.ranges & co. takes a Into<UInt>.
In `SlidingSyncListBuilder`, the `ranges`, `set_range`, and `add_range`
methods do not take a `u32` but a `U: Into<UInt>`. That's great!

However, in `SlidingSyncList`, the same methods take a `u32`. It makes
the API inconsistent.

This patch fixes that.
2023-03-22 11:06:18 +01:00
Ivan Enderlin 147e5f8f03 fix(sdk): Rename SlidingSyncList.set_ranges to ranges.
This patch renames `SlidingSyncList.set_ranges` to `ranges` so that
it matches the same terminology of the `SlidingSyncListBuilder` with
`ranges`, `set_range`, `add_range` and `reset_ranges`.

Consistency is important here.
2023-03-22 10:59:23 +01:00
Ivan Enderlin 8e9cabcbf9 test(sdk): Add test for SlidingSyncList::new_builder. 2023-03-22 10:59:23 +01:00
Ivan Enderlin 42af266806 fix(sdk): Fix SlidingSyncList::new_builder.
The `SlidingSyncList::new_builder` method creates a new builder from a
`SlidingSyncList`. This method was missing some configurations, like
`full_sync_maximum_numbre_of_rooms_to_fetch`, `send_updates_for_items`,
`filters`, `ranges` and `timeline_limit`.

This patchs adds those missing configurations.
2023-03-22 10:59:23 +01:00
Ivan Enderlin 7a1fb0b368 fix(sdk): Remove useless fields on SlidingSyncListBuilder.
The `SlidingSyncListBuilder` struct has a `state` and a `rooms_list`
fields. Those fields are never updated and no setters or getters exist
to use them. There are just set with defaults, and passed to the final
`SlidingSyncList` type within the `build` method.

If a field is present in a builder type, it means they can be modified,
but it's not the case. So this patch removes them.
2023-03-22 10:59:17 +01:00
Ivan Enderlin 3f72b10831 test(sdk): Write a test case for FrozenSlidingSyncList when serialized. 2023-03-22 10:58:40 +01:00
Ivan Enderlin 6bd95057b6 test(sdk): Write a test case for RoomListEntry when serialized. 2023-03-22 10:58:40 +01:00
Ivan Enderlin 859317a0f6 test(sdk): Write test suites for SlidingSyncState and SlidingSyncMode. 2023-03-22 10:58:40 +01:00
Ivan Enderlin ace3ff3754 test(sdk): Write test suites for RoomListEntry. 2023-03-22 10:58:40 +01:00
Ivan Enderlin 60b627c2ca feat(sdk): Rename RoomListEntry.freeze to .freeze_by_ref. 2023-03-22 10:58:40 +01:00
Ivan Enderlin 41615840dc feat(sdk): Remove deduplication logic from Sliding Sync.
Event deduplication is supposed to be handled by the `Timeline`. Sliding
Sync is not responsible to de-duplicate the events, in our model. Having
two different de-duplication logics (one in Sliding Sync, and one in the
Timeline) could create weird situations, and hard to debug issues.

We give it a try by removing the deduplication from Sliding Sync.
2023-03-22 10:53:23 +01:00
Ivan Enderlin d07b389f4b chore(sdk): Rename some variables. 2023-03-22 10:52:56 +01:00
Damir Jelić b2a35fc9cf Merge branch 'main' into valere/msc_2399 2023-03-21 16:41:55 +01:00
Damir Jelić 900a4f848c Don't log verification requests as sent if the request id doesn't match 2023-03-21 15:57:16 +01:00
Damir Jelić c4d73c9901 fixup! Don't send m.no_olm withheld codes out if another session is doing so 2023-03-21 15:56:58 +01:00
Damir Jelić eb9dd8fb0d Don't send m.no_olm withheld codes out if another session is doing so
The `m.no_olm` withheld code is supposed to be sent out only once for a
given device.

This patch prevents double sending of m.no_olm withheld code by adding
a test that ensures only one group session will send it out.

Previously, the logic for sharing group sessions was mostly correct, but
an edge case was forgotten where two group sessions attempted to share
the withheld code concurrently.

Although there's still a possibility for multiple m.no_olm withheld codes
to be sent out. This may happen during the propagation of the flag
remembering the fact that the `m.no_olm` code has been sent from the
OutboundGroupSession to Device. This scenario is likely unrealistic and
the consequences of sending things twice aren't problematic.
2023-03-21 15:45:32 +01:00
Jonas Platte a134cc378d Sort sliding-sync-integration-test dependencies 2023-03-21 13:31:58 +01:00
Jonas Platte a32fce6cdf Make all sliding-sync-integration-test dependencies dev-dependencies 2023-03-21 13:31:58 +01:00
Jonas Platte 9ee2d04a41 Feature-gate everything in sliding-sync-integration-test 2023-03-21 12:24:14 +01:00
Mauro 1ce1c5636e Add support for (un)ignoring users 2023-03-21 12:23:17 +01:00
Damir Jelić 8652cdf752 Test the VerificationState migration 2023-03-21 12:02:31 +01:00
Damir Jelić 32e2ea0288 Allow the old VerificationState enum to be deserialized into the new one 2023-03-21 12:02:31 +01:00
Damir Jelić 7263914f67 Remove the Apple specific auth service tests
These tests are doing real network requests towards hosts that are not
under our control.
2023-03-21 12:00:43 +01:00
Florian Renaud 76763a80fe ffi: Add binding for get_dm_room 2023-03-20 16:30:25 +00:00
Jonas Platte 72ae9dd885 Upgrade eyeball-im 2023-03-20 16:51:28 +01:00
Jonas Platte 816e722807 ffi: Inline uniffi_api modules
include_scaffolding! is expected to be used at the crate root now, and
clippy seems happy with the generated code right now.
2023-03-20 15:42:38 +01:00
Jonas Platte 1a1fe97d00 Use Rust conventions for variable names in UDL 2023-03-20 15:42:38 +01:00
Jonas Platte 16687f24f9 sdk: Fix documentation of create_room 2023-03-20 13:56:43 +01:00
Jonas Platte ea41076c82 sdk: Rename create_dm_room to create_dm and make it public 2023-03-20 13:56:43 +01:00
Jonas Platte 130dc58a5d Remove redundant cfg attributes
The whole encryption module is only enabled with e2e-encryption.
2023-03-20 13:56:43 +01:00
Jonas Platte 9d6e192b9f sdk: Move create_dm_room out of encryption module
Creating DM rooms makes sense for non-encryption-capable client as well.
2023-03-20 13:56:43 +01:00
Jonas Platte 82d1d64f85 sdk: Simplify create_dm_room
It doesn't need to call mark_as_dm itself as create_room will do that.
2023-03-20 13:56:43 +01:00
Jonas Platte 39a4dc911f Remove event contents from (Sync)TimelineEvent Debug impls 2023-03-20 13:21:41 +01:00
Alfonso Grillo a7ed8e0b45 Update account_data when creating a new dm room 2023-03-20 12:08:21 +01:00
Ivan Enderlin e64ab6cf9c Merge pull request #1677 from matrix-org/rav/update-js-bindings-prefix
matrix-sdk-crypto-js: drop `v` from release tags
2023-03-20 09:23:29 +01:00
Damir Jelić 43d883da9c Refactor the room key sharing logic 2023-03-16 19:40:30 +01:00
Richard van der Hoff 42dce635de matrix-sdk-crypto-js: drop v from release tags
Currently, the tags used for releases of this binding have the format:
"matrix-sdk-crypto-js-v0.1.0-alpha.5". This is inconsistent with tags used for
other parts of the project, which omit the `v` prefix.
2023-03-16 17:49:52 +00:00
Richard van der Hoff 7794b230e1 Merge pull request #1675 from matrix-org/release-matrix-sdk-crypto-js-v0.1.0-alpha.5
matrix-sdk-crypto-js: prepare v0.1.0-alpha.5
2023-03-16 17:38:33 +00:00
Ivan Enderlin 2d56f550aa fix(sdk): Fix, test, and clean up SlidingSyncListRequestGenerator
fix(sdk): Fix, test, and clean up `SlidingSyncListRequestGenerator`
2023-03-16 17:04:05 +01:00
Ivan Enderlin b39a224be8 doc(sdk): Use the Rust range notation to avoid ambiguity. 2023-03-16 17:03:25 +01:00
Richard van der Hoff e6bf74b7db matrix-sdk-crypto-js v0.1.0-alpha.5
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 41s
2023-03-16 13:47:55 +00:00
Ivan Enderlin 5f06dc8229 doc(sdk): Fix a typo. 2023-03-16 11:53:01 +01:00
Kévin Commaille 46d8d26b71 sdk: Fix a typo
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-16 11:40:47 +01:00
Kévin Commaille e23be44345 sdk: Store OIDC issuer as a String rather than a Url
The url crate normalizes the string, but during OIDC verification steps,
the issuer verification must be made against the exact string that was
provided.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-16 11:40:47 +01:00
Ivan Enderlin 57fb659b86 Merge pull request #1666 from zecakeh/indexeddb-crypto-version
indexeddb: Use u32 to represent version of crypto store
2023-03-16 11:12:27 +01:00
Ivan Enderlin 1933fe7a8f doc(sdk): Fix a typo. 2023-03-16 11:04:18 +01:00
Ivan Enderlin 6a6d94a065 Re-expose the vodozemac and matrix-sdk-crypto versions in the bindings
Re-expose the vodozemac and matrix-sdk-crypto versions in the bindings
2023-03-16 10:56:51 +01:00
Ivan Enderlin ccfb66c576 chore(crypto-nodejs): Fix a lint. 2023-03-16 10:39:43 +01:00
Ivan Enderlin c2d3afffff feat(crypto-nodejs): Make Versions a class, not a JS object. 2023-03-16 10:33:41 +01:00
Ivan Enderlin e1f6fd8a1e feat(ffi): Create the version and vodozemac_version functions. 2023-03-16 09:53:39 +01:00
Damir Jelić 2f377d536a fixup! Re-expose the vodozemac and matrix-sdk-crypto versions in the bindings 2023-03-16 09:53:39 +01:00
Damir Jelić 26789f22b0 fixup! Re-expose the vodozemac and matrix-sdk-crypto versions in the bindings 2023-03-16 09:53:39 +01:00
Damir Jelić 3aa1c30f5c Re-expose the vodozemac and matrix-sdk-crypto versions in the bindings 2023-03-16 09:53:37 +01:00
Ivan Enderlin 5e23bd09bc feat(ci): aarch64-apple-ios should work on rustc stable. 2023-03-16 09:01:14 +01:00
Ivan Enderlin c8bad4b86e doc(sdk): Fix a typo. 2023-03-16 08:55:25 +01:00
Ivan Enderlin 07c366983d doc(sdk): Fix a typo. 2023-03-16 08:24:05 +01:00
Ivan Enderlin 51abedda59 feat(ffi): Update SlidingStateState variants. 2023-03-16 08:21:11 +01:00
Ivan Enderlin 9d5a1fda3c doc(sdk): Fix typos or improve. 2023-03-16 08:11:45 +01:00
Damir Jelić 61ea15eb39 Merge branch 'main' into valere/msc_2399 2023-03-15 19:31:04 +01:00
Kévin Commaille fe69948926 sdk: Add a method to change the room name
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-15 17:28:08 +00:00
Valere 248b8db309 Extended verification states
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-03-15 18:16:31 +01:00
Ivan Enderlin ca5cabb7e1 doc(sdk): Fix a typo. 2023-03-15 18:08:19 +01:00
Ivan Enderlin 7a2b1e6e1f doc(sdk): Fix a typo. 2023-03-15 17:59:11 +01:00
Ivan Enderlin c0f84bb8da test(sdk): Fix tests and improve speed.
To improve the speed, we simply reduce the numbers of rooms involved in
the test.
2023-03-15 17:54:39 +01:00
Kévin Commaille 9a9b142630 indexeddb: Use u32 to represent version of crypto store
Like for the state store, the bindings expose the version as an f64
while the web API expects an unsigned integer.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-15 17:08:33 +01:00
Ivan Enderlin a2dcfa905f fix(sdk): Fix, test, and clean up SlidingSyncList.
This patch should ideally be split into multiple smaller ones, but life
is life.

This main purpose of this patch is to fix and to test
`SlidingSyncListRequestGenerator`. This quest has led me to rename
mutiple fields in `SlidingSyncList` and `SlidingSyncListBuilder`, like:

* `rooms_count` becomes `maximum_number_of_rooms`, it's not something
  the _client_ counts, but it's a maximum number given by the server,

* `batch_size` becomes `full_sync_batch_size`, so that now, it
  emphasizes that it's about full-sync only,

* `limit` becomes `full_sync_maximum_number_of_rooms_to_fetch`, so that
  now, it also emphasizes that it's about ful-sync only _and_ what the
  limit is about!

This quest has continued with the renaming of the `SlidingSyncMode`
variants. After a discussion with the ElementX team, we've agreed on the
following renamings:

* `Cold` becomes `NotLoaded`,
* `Preload` becomes `Preloaded`,
* `CatchingUp` becomes `PartiallyLoaded`,
* `Live` becomes `FullyLoaded`.

Finally, _le plat de résistance_.

In `SlidingSyncListRequestGenerator`, the `make_request_for_ranges`
has been renamed to `build_request` and no longer takes a `&mut self`
but a simpler `&self`! It didn't make sense to me that something
that make/build a request was modifying `Self`. Because the type of
`SlidingSyncListRequestGenerator::ranges` has changed, all ranges now
have a consistent type (within this module at least). Consequently, this
method no longer need to do a type conversion.

Still on the same type, the `update_state` method is much more
documented, and errors on range bounds (offset by 1) are now all fixed.

The creation of new ranges happens in a new dedicated pure function,
`create_range`. It returns an `Option` because it's possible to not be
able to compute a range (previously, invalid ranges were considered
valid). It's used in the `Iterator` implementation. This `Iterator`
implementation contains a liiiittle bit more code, but at least now
we understand what it does, and it's clear what `range_start` and
`desired_size` we calculate. By the way, the `prefetch_request` method
has been removed: it's not a prefetch, it's a regular request; it was
calculating the range. But now there is `create_range`, and since it's
pure, we can unit test it!

_Pour le dessert_, this patch adds multiple tests. It is now
possible because of the previous refactoring. First off, we test the
`create_range` in many configurations. It's pretty clear to understand,
and since it's core to `SlidingSyncListRequestGenerator`, I'm pretty
happy with how it ends. Second, we test paging-, growing- and selective-
mode with a new macro: `assert_request_and_response`, which allows to
“send” requests, and to “receive” responses. The design of `SlidingSync`
allows to mimic requests and responses, that's great. We don't really
care about the responses here, but we care about the requests' `ranges`,
and the `SlidingSyncList.state` after a response is received. It also
helps to see how ranges behaves when the state is `PartiallyLoaded`
or `FullyLoaded`.
2023-03-15 16:57:29 +01:00
Kévin Commaille 1e1e0d7e6d ci: Make sure all rendered docs examples are compiling
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-15 14:42:12 +01:00
Kévin Commaille 5d1a738162 sdk: Fix generate_image_thumbnail example in docs
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-15 14:42:12 +01:00
Jonas Platte e4e9efb7d9 ffi: Put CreateRoomParameters back into the UDL file
… to restore the default values of some fields.
2023-03-15 13:09:54 +01:00
Doug b1074e400e sdk: Add get_media_file function 2023-03-15 09:22:53 +00:00
Ivan Enderlin 9574f93320 feat(sdk): Add more Sliding Sync logs
feat(sdk): Add more Sliding Sync logs
2023-03-15 09:58:02 +01:00
Ivan Enderlin c3bcbf8952 chore(sdk): Rephrase logs a little bit. 2023-03-15 09:41:39 +01:00
Jonas Platte 739dd8cf93 Fix clippy complaint 2023-03-14 18:34:23 +01:00
Jonas Platte c7e1d617ec ffi: Use UniFFI derives for types no longer referenced in UDL 2023-03-14 18:34:23 +01:00
Jonas Platte ae85e18588 ffi: Use UniFFI proc-macros for more Client methods 2023-03-14 18:34:23 +01:00
Damir Jelić 516d849ef2 Allow room key forwarding to be enabled and disabled (#1365)
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2023-03-14 18:23:39 +01:00
Damir Jelić eb2bf61236 Merge pull request #1657 from matrix-org/poljar/session-creator-info
Improve the docs of the inbound group session type
2023-03-14 17:33:24 +01:00
Damir Jelić 0985043a6a Apply suggestions from code review
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-03-14 17:01:03 +01:00
Damir Jelić 36b739b830 Improve the docs of the inbound group session type 2023-03-14 15:50:03 +01:00
Doug eeea4f23bc fix(bindings): More authentication service server name fixes
- Trim any trailing slashes
- If server name parsing fails, try as a URL instead of throwing
- Add tests
- Fix typo & clippy
2023-03-14 14:40:19 +00:00
Alfonso Grillo c9a6898c73 Add a guide for contributing to UniFFI bindings 2023-03-14 15:39:09 +01:00
Damir Jelić 18c33aefa1 Merge pull request #1633 from matrix-org/rav/fix_wait_if_user_pending
Fix races in `wait_if_user_pending`
2023-03-14 14:59:20 +01:00
Damir Jelić 2c7c251e47 Silence an invalid clippy warning 2023-03-14 14:45:19 +01:00
Damir Jelić f3ee6c735b Fix some formatting issue where cargo fmt failed to take care of things 2023-03-14 14:28:34 +01:00
Damir Jelić 4f9cb48ef8 Use a Display implementation to record the SequenceNumber in logs 2023-03-14 14:28:27 +01:00
Damir Jelić 9880619d81 Merge branch 'main' into rav/fix_wait_if_user_pending 2023-03-14 14:26:28 +01:00
Mauro a8204987be Add convenience methods for updating a room's avatar 2023-03-14 13:03:52 +00:00
Kévin Commaille cc585974e0 sdk: Get push actions of events received via back pagination
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-14 14:02:01 +01:00
Kévin Commaille aebd5fe4eb sdk: Fix timeline highlight test
Update Ruma to fix the server default push rules.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-14 14:02:01 +01:00
Mauro 7ab134233e bindings: Set pusher from client + notification service stub
Co-authored-by: ismailgulek <ismailg@matrix.org>
2023-03-14 13:36:36 +01:00
Kévin Commaille 0f54877b31 feat(sdk): Add methods to only send receipts newer than the current ones in the timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-14 13:32:30 +01:00
Kévin Commaille 1c9aa7c907 refactor(sdk): Add private method to get the fully-read event for a timeline.
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-14 13:32:30 +01:00
Damir Jelić 4041c875d1 Merge pull request #1460 from matrix-org/andy/enhance_store
Store encryption settings
2023-03-14 12:36:42 +01:00
Andy Uhnak d226738d15 More pub(crate) methods 2023-03-14 10:43:40 +00:00
Andy Uhnak 404b95ab84 Missing migration method in UDL 2023-03-14 10:28:41 +00:00
Andy Uhnak 0d082f6b96 Update js tests 2023-03-14 10:28:15 +00:00
Andy Uhnak 5bf9182549 Fix issues after rebase 2023-03-14 10:28:15 +00:00
Andy Uhnak 1177bdd394 Indexdb migration 2023-03-14 10:28:15 +00:00
Andy Uhnak 98ca774118 Constrain store methods 2023-03-14 10:28:12 +00:00
Andy Uhnak 8f13023333 Missing stores 2023-03-14 10:27:11 +00:00
Andy Uhnak 51b3bf4c75 Add room settings migration 2023-03-14 10:27:11 +00:00
Andy Uhnak 283137f190 Introduce RoomSettings 2023-03-14 10:27:11 +00:00
Andy Uhnak 33b348c376 Constrain new api to Store struct 2023-03-14 10:27:11 +00:00
Andy Uhnak 7e7c91699f Generic key-value API 2023-03-14 10:27:11 +00:00
Andy Uhnak b4b111f91f Store encryption settings 2023-03-14 10:27:11 +00:00
Jonas Platte 0f7d839c49 Undo room_type => room_state rename in serialized form of RoomInfo 2023-03-13 16:45:44 +01:00
Jonas Platte ee6c0d9486 Simplify TimelineEvent construction 2023-03-13 16:31:19 +01:00
Jonas Platte 7121179b6a sdk: Make test code less repetitive 2023-03-13 16:31:19 +01:00
Jonas Platte 59edc22a35 Use Action covenience methods
Now Action::Coalesce will also generate a notification.
2023-03-13 16:31:19 +01:00
Jonas Platte e9058f58be Upgrade Ruma 2023-03-13 16:31:19 +01:00
Jonas Platte 7dee9648cf sdk: Clone VerificationRequest twice in generate_qr_code method again
… required for the returned Future to be Send.
2023-03-13 15:34:14 +01:00
Alfonso Grillo 786e9b5db9 Add createRoom UniFFI binding 2023-03-13 15:33:18 +01:00
valere e20db574ec Merge branch 'main' into valere/msc_2399 2023-03-13 14:51:23 +01:00
Ivan Enderlin c6c259144a chore(sdk): Rename enum variants to be consistent across all the modules. 2023-03-13 14:29:12 +01:00
Damir Jelić 58e99a645f Don't use a type alias for the sequence number
Using a wrapper type allows us to hide the internals a bit better and
we're now implementing Ord which is used in the comparison.
2023-03-13 14:17:12 +01:00
Damir Jelić 5d6cf2d33a Remove some clones when creating a /keys/query request
The part of code that converts a list of users to the actual
/keys/query request uses the chunks() method. This method operates on
the slice. Our list/vec of users gets dereferenced into a slice before
we create our chunks. The chunks can't take ownership of the data, which
in turn requires us to clone the user IDs for them to be put into the
request.

Itertools has a chunks() method which operates on an iterator which we
can utilize to remove, not only the clone, but also a collect call.

At the same time, let's make the conversion step a simple functional
mapping and document what's going on.
2023-03-13 14:17:12 +01:00
Damir Jelić 5f1a22e26f Remove some useless ? -> Ok invocations
We can just return the result directly instead of doing the error
conversion dance using the question mark operator
2023-03-13 14:17:12 +01:00
Damir Jelić 6afb6f1e27 Use an Option for the KeysQueryDetails instead of a default value
The Option conveys our intention a bit better compared to the default
value. While nothing bad can happen, since the request IDs map will be
empty by default, it's a bit scary to have a valid sequence number since
an i64 defaults to 0.
2023-03-13 14:17:12 +01:00
Ivan Enderlin 032356566e chore(sdk): Rewrite a small part of the code to make it clearer. 2023-03-13 14:07:36 +01:00
Ivan Enderlin d7468ec158 Update crates/matrix-sdk/src/sliding_sync/mod.rs
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-03-13 13:49:21 +01:00
Kévin Commaille 929538608a timeline: Expose if an event should be highlighted
Only events received via sync.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-13 13:47:06 +01:00
Kévin Commaille d5a56bcbc7 sdk: Expose calculated push actions for event handlers
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-13 13:47:06 +01:00
Kévin Commaille 84ff8980f3 sdk-base: Expose calculated push actions on event
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-13 13:47:06 +01:00
Jonas Platte 84d83dda0a base: Add RoomInfo::state accessor 2023-03-13 13:17:15 +01:00
Jonas Platte fb4b347433 base: Rename RoomType to RoomState 2023-03-13 13:17:15 +01:00
Richard van der Hoff e1c6ac9787 Merge branch 'main' into rav/fix_wait_if_user_pending 2023-03-13 11:52:11 +00:00
Ivan Enderlin 35bb18a1e8 feat(sdk): Add more Sliding Sync logs.
This patch adds more logs around `SlidingSync` to ease debugging sessions.
2023-03-13 11:41:20 +01:00
Ivan Enderlin 483bef0748 Merge pull request #1645 from Hywan/fix-sdk-fixme 2023-03-13 11:21:17 +01:00
Ivan Enderlin 3c25ad1489 doc(sdk): Remove a FIXME that is actually fixed.
The #1386 issue is closed. Yepee.
2023-03-13 09:05:32 +01:00
Jonas Platte 8d83a996a6 Handle another new clippy lint
Issue about false positives:
https://github.com/rust-lang/rust-clippy/issues/10482
2023-03-11 13:13:50 +01:00
Jonas Platte 595e34aad5 Silence new clippy lint for generated code 2023-03-11 13:13:50 +01:00
Jonas Platte cc35ee72b8 Upgrade eyeball to 0.4.0 2023-03-11 13:13:50 +01:00
Jonas Platte b148ea2fb1 Bump locked version of clap
To work around this clippy bug:
https://github.com/rust-lang/rust-clippy/issues/10421
2023-03-11 13:13:50 +01:00
Mauro 2bb66f0f2e bindings: Expose leave and reject_invitation functions to FFI 2023-03-10 18:07:13 +01:00
valere 8057a3691f unused import 2023-03-10 16:00:22 +01:00
valere 057cf0bde7 unneeded trait impl 2023-03-10 08:57:56 +01:00
valere c43d9d3e43 post rebase fix 2023-03-09 17:27:34 +01:00
Ivan Enderlin 331ea35be6 fix(sdk): SlidingSync has a lock for both pos _and_ delta_token
fix(sdk): `SlidingSync` has a lock for both `pos` _and_ `delta_token`
2023-03-09 17:10:42 +01:00
Richard van der Hoff fc9dbae23b fixup! Rewrite wait_if_user_pending to fix races 2023-03-09 16:06:37 +00:00
valere 9733d9842a Merge branch 'main' into valere/msc_2399 2023-03-09 17:04:21 +01:00
Ivan Enderlin b9fd451d54 feat(sdk): Move Client.root_span inside ClientInner
feat(sdk): Move `Client.root_span` inside `ClientInner`
2023-03-09 17:03:27 +01:00
Ivan Enderlin 3511a4a053 fix(sdk): SlidingSync has a lock for both pos _and_ delta_token.
This patch updates `SlidingSync.pos` and `.delta_token`. Each field has their
own lock. It's annoying because they must updated at the same time to not be
out-of-sync.

So a new field `SlidingSync.position` of type `SlidingSyncPositionMarkers` is
created. It holds `pos` and `delta_token. This new field is behind a single
`RwLock`.
2023-03-09 16:47:11 +01:00
Ivan Enderlin 7f52292e92 chore(sdk): Remove useless comment. 2023-03-09 16:43:41 +01:00
valere 980c9cb4f5 report partially withheld error as MissingRoomKey 2023-03-09 16:39:02 +01:00
valere 2368ac74de feat(withheld) expose withheld code in error binding 2023-03-09 16:38:38 +01:00
Ivan Enderlin cc69efc3f8 feat(sdk): Move Client.root_span inside ClientInner. 2023-03-09 15:12:11 +01:00
Richard van der Hoff 5a06c11ac0 Move UserKeyQueryResult to store
Now that `wait_if_user_key_query_pending` is in Store, it makes more sense that
the result type be in the same module.
2023-03-09 13:11:34 +00:00
Richard van der Hoff d2fdc20733 Rip out redundant KeysQueryListener 2023-03-09 13:11:34 +00:00
Richard van der Hoff 16871d1dcd Rewrite wait_if_user_pending to fix races 2023-03-09 13:11:34 +00:00
Richard van der Hoff 508f1bc976 Fix races between /sync and /keys/queries (#1619)
The comments in the code should explain the general approach, but to give an overview:

We assign a unique sequence number to each device-list-invalidation notice, and keep track 
of the sequence number at which each user was most recently invalidated. Then, when we 
build a `/keys/query` request, we take note of the current sequence number. Finally, when 
we get the response from that `/keys/query` request, we compare that sequence number
with the most-recent-invalidation of each user that is now supposedly up-to-date. All 
of that means that we can see if the user has been invalidated *since* we built the 
`/keys/query` request, in which case our request may have raced against the new device,
so we do not mark the user as up-to-date.

To make that work, we need to keep track of the sequence number for in-flight `/keys/query`
requests; we do that in the `IdentityManager`. Since there should only ever be at most one
batch of requests in flight, that is relatively easy; however, we also record the request ids
just to check that the application isn't doing something weird.

There is no need to persist the sequence numbers to permanent storage: provided the
`IdentityManager` and `Store` objects have a lifetime at least as long as an in-flight
`/keys/query` request, it is sufficient just to retain the `dirty` bit in permanent storage,
and then, when we reload the ephemeral `Store` cache, to treat everything with a `dirty`
bit as a "new" invalidation.

Fixes: #1386.
2023-03-09 10:57:20 +00:00
Ivan Enderlin 0419967158 doc(sdk): Rephrase the Quick refreshing Section.
With https://github.com/matrix-org/matrix-rust-sdk/pull/1601, it's safer to
cancel a stream at any time, as any `Future` cancellation. This documentation
section of `SlidingSync` is no longer relevant as is, and can be rephrased.
2023-03-09 11:56:33 +01:00
Ivan Enderlin da5c79482b feat(ffi): Rethink TaskHandle
feat(ffi): Rethink `TaskHandle`
2023-03-08 17:21:52 +01:00
Ivan Enderlin 4996a19b31 feat(ffi): Rethink TaskHandle.
With https://github.com/matrix-org/matrix-rust-sdk/pull/1601,
`TaskHandle::with_callback` is no longer necessary.

This patch updates `TaskHandle` as follows:

1. Before, the `handle` and `callback` fields were not mutually exclusive!
   Indeed, the `callback` field was used as an abort mechanism, but _also_ as a
   finalizer, i.e. a code that runs _after_ the cancellation of `handle`. Now
   that the callback-based solution is no longer used, we can keep one usage for
   this field and rename it `finalizer`.
2. The `handle` field is no longer optional, as it will always be set.
3. The `with_callback` method is renamed `new` as it's now the only constructor.
4. The `set_callback` method is renamed `set_finalizer`.

Tadaaa.
2023-03-08 17:09:47 +01:00
Ivan Enderlin d720861fbd fix(bindings): SlidingSync.sync returns an immediately cancellable TaskHandle
fix(bindings): `SlidingSync.sync` returns an immediately cancellable `TaskHandle`
2023-03-08 16:39:09 +01:00
Ivan Enderlin c517f38ec8 sliding-sync: process receipt extension response
sliding-sync: process receipt extension response
2023-03-08 16:29:56 +01:00
Ivan Enderlin ac863409bb doc(sdk): Remove notion of fairness. 2023-03-08 16:20:50 +01:00
Kegan Dougal 417008cc87 Clippy 2023-03-08 15:14:59 +00:00
Ivan Enderlin 5dd404d2f1 doc(sdk): Precise in which order SS responses will be handled. 2023-03-08 16:09:05 +01:00
Kegan Dougal 2c0466a8cc Unbreak tests; don't shadow 2023-03-08 15:03:41 +00:00
kegsay aec65c818b Update testing/sliding-sync-integration-test/src/lib.rs
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2023-03-08 14:51:26 +00:00
Jonas Platte 0d9d130833 Replace StateStoreDataKey::encoding_key by associated constants 2023-03-08 15:51:13 +01:00
Jonas Platte 26e259455a Adhere to module naming conventions 2023-03-08 15:51:13 +01:00
Ivan Enderlin 2f637cda6f doc(sdk): Add note about fairness of the SS lock. 2023-03-08 15:33:40 +01:00
Ivan Enderlin 64ae77ec70 feat(sdk): Run SS response handling in a single non-cancellable block. 2023-03-08 15:15:16 +01:00
Jonas Platte 932cf2ad99 Fix experimental features not compiling without encryption 2023-03-08 15:03:20 +01:00
Jonas Platte 68f8ed5a92 Add futures-util as a workspace dependency
… and always activate its `alloc` feature.
Fixes building matrix-sdk without the e2e-encryption feature.
2023-03-08 15:03:20 +01:00
Kegan Dougal 4670142a83 Clippy 2023-03-08 13:21:56 +00:00
Kegan Dougal 9a53602d73 Formatting 2023-03-08 12:58:48 +00:00
Kegan Dougal 48bf20fcca Add integration test for receipts in sliding sync 2023-03-08 12:53:23 +00:00
Mauro be6c7c8b4c Add user avatar URL caching 2023-03-08 13:30:46 +01:00
Ivan Enderlin 832146b43d feat(sdk): Create SlidingSyncInner.
Move all `SlidingSync`'s fields into a new `SlidingSyncInner` type, and then
update `SlidingSync` to contain a single `inner: Arc<SlidingSyncInner>` field.

First off, it's much simpler to understand what's behind an `Arc` for
“clonability” of `SlidingSync`, and what's not. We don't need to worry about
adding a new field that is not behind an `Arc` for a specific reason or
anything. The pattern is clear now.

Second, this is required for next commits.
2023-03-08 12:12:58 +01:00
Ivan Enderlin 66d4ced90f chore: Add some inline documentation. 2023-03-08 12:01:57 +01:00
Jonas Platte 5c2915bb6a crypto-ffi: Use uniffi derives for types no longer referenced in UDL 2023-03-08 11:12:11 +01:00
Jonas Platte fb23cbff97 crypto-ffi: Use UniFFI proc-macros for more OlmMachine methods 2023-03-08 11:12:11 +01:00
Jonas Platte 9fe880d05d Clean up formatting of olm.udl 2023-03-08 11:12:11 +01:00
Jonas Platte 7af2bea2fc Upgrade UniFFI 2023-03-08 11:12:11 +01:00
Kegan Dougal f1829faa99 Merge branch 'main' into kegan/receipts-ss 2023-03-08 09:33:48 +00:00
valere a767187ff6 add more tests 2023-03-08 10:06:46 +01:00
Ivan Enderlin 7369010964 feat(sdk): Make SlidingSync::handle_response _sync_, no more _async_.
The idea is to group all async and await points in `sync_once`. It's easier to
think about it.
2023-03-08 09:41:32 +01:00
Ivan Enderlin 07f6a3b345 chore: Remove warnings. 2023-03-08 09:35:47 +01:00
Ivan Enderlin 8f6f20bbe7 fix(bindings): SlidingSync.sync returns an immediately cancellable TaskHandle.
Before this patch, `SlidingSync::sync` was returning a callback-based
`TaskHandle`. It was waiting on the “stream loop” to finish (since it's a long-
poll, it means waiting 2*30s, cf. our code), before checking an atomic flag has
some value to decide whether it was time to leave the loop or not. So when the
user is cancelling this `TaskHandle`, a response (if any) was always handled.
But in the meantime, it was possible to start a new `sync`, and it seems like
it creates bugs.

After this patch, `SlidingSync::sync` now returns a handle-based `TaskHandle`.
It means that cancelling it will cancel the “stream loop” immediately. If
no response was in-flight from the server, that's perfect, no problem. If a
response was in-flight, the inner `pos` of the `SlidingSync` instance won't be
updated as the response won't be handled. So the server will re-send the same
response with the next sync request.

I guess it's better this way. Thoughts?
2023-03-08 09:35:47 +01:00
Ivan Enderlin 6a9cf1f9ce feat(sdk): SlidingSync::stream can match expected responses
feat(sdk): `SlidingSync::stream` can match expected responses
2023-03-08 09:14:32 +01:00
Ivan Enderlin f8ce49cc49 chore: Add documentation. 2023-03-08 08:56:38 +01:00
Ivan Enderlin 46d71acb44 chore: Update ruma to a specific revision. 2023-03-08 08:56:38 +01:00
Ivan Enderlin 9f0563eb95 feat(sdk): SlidingSync::stream can match expected responses.
This patch adds a new feature.

Each call to `SlidingSync::stream` generates a unique `stream_id`. This
`stream_id` is passed to requests as a `txn_id` field. Returned responses must
hold the same `txn_id`, otherwise it means `stream` has received unexpected
responses from another `stream` or something else.

So far, when the `txn_id` field of the response and the `stream_id` don't
match, a log with the `ERROR` level is raised. Should we do more, like ignoring
the response entirely? Not sure yet.
2023-03-08 08:56:32 +01:00
valere bd48cae28d unused import 2023-03-07 19:24:50 +01:00
valere 69749ab8fe feat(withheld) fix experimental-algorithms 2023-03-07 19:07:27 +01:00
valere 97b5a3a61b feat(withheld) cleaning 2023-03-07 19:04:44 +01:00
valere 0ec3aca727 refactor(withheld) store withheld as ShareInfo
and store no_olm sent in device
2023-03-07 18:46:52 +01:00
Kévin Commaille 18e6f10367 examples: Also handle SSO login in the login example
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 15:12:33 +01:00
Kévin Commaille d77efd7327 state-store: Replace methods to get and set key-value data
Avoid to make the API bigger when we want to add new key-value data
in the store.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 13:52:37 +01:00
Kévin Commaille 5b28c69cfc sled: Rename session store to kv
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 13:52:37 +01:00
Kévin Commaille 61796a2725 sled: Move state store keys into keys module
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 13:52:37 +01:00
Kévin Commaille f538b5e595 sled: Move the state store migrations to a separate file
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 13:52:37 +01:00
Kévin Commaille 4d1363e683 indexeddb: Merge session and sync_token stores into new kv store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 13:52:37 +01:00
Damir Jelić 9324702b04 feat(bindings): Add a method to partially migrate data 2023-03-07 13:29:00 +01:00
Jonas Platte 0c4c73084d Appease clippy 2023-03-07 12:53:32 +01:00
Jonas Platte 6ce51b5890 Remove unnecessary allow attribute 2023-03-07 12:53:32 +01:00
Jonas Platte 3ff1844da4 base: Remove unused Deserialize implementation 2023-03-07 12:53:32 +01:00
Jonas Platte 99cbf3122b ci: Work around frequent codecov upload errors 2023-03-07 11:08:09 +01:00
Kévin Commaille e09ec389d1 indexeddb: Fix migration of state store
The IndexedDB API expects an unsigned integer for the version.
The web-sys bindings expose it as a f64 so versions like 1.1 and 1.2
were used. The were converted back to uint in JS which means the version
was always 1.0 and no real upgrade was processed

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 10:04:09 +01:00
Kévin Commaille 2aec3d0502 indexeddb: Move the state store migrations to a separate file
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-07 10:04:09 +01:00
Damir Jelić 2f974c11f7 Simplify handling of sliding sync extensions
Simplify handling of sliding sync extensions

This patch simplifies the logic for handling sliding sync extensions.
These extensions are sticky, meaning that once enabled in one request,
they do not need to be repeatedly enabled for subsequent requests.

However, the previous logic tried to accommodate the case where the
extensions were initially disabled to reduce the size and processing
time of the initial response. This resulted in complex and error-prone
code.

With this patch, we have removed support for disabling to-device events
and streamlined the handling of sync extensions.

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-03-07 08:48:05 +01:00
Richard van der Hoff 79ee4b59ee matrix-sdk-crypto: enable tracing for in-crate tests 2023-03-06 19:25:47 +01:00
Jonas Platte 01a66d4874 Fix unnecessary cfg(all()) 2023-03-06 18:25:16 +01:00
valere 1ddcc97f84 refactor(withheld) collect_session_recipient result struct 2023-03-06 12:23:10 +01:00
valere c6a12304ba refactor(msc2399) avoid iterating twice on devices 2023-03-06 11:46:37 +01:00
Jonas Platte 50114f4e74 Mention changelogs in PR template 2023-03-06 10:41:18 +01:00
Jonas Platte 792b60c501 Remove most mentions of conventional commits 2023-03-06 10:41:18 +01:00
Jonas Platte d8465a2c1e Add a very basic changelog to crates/matrix-sdk 2023-03-06 10:41:18 +01:00
Damir Jelić 8550eaeed0 Make sure that syncing members is only happening if they aren't already synced 2023-03-06 10:00:00 +01:00
Damir Jelić 071ba2376e Make the majority of fields of the RoomInfo private 2023-03-06 10:00:00 +01:00
Damir Jelić 7ec98ff721 Remove a race condition when fetching members and sending out room keys 2023-03-06 10:00:00 +01:00
Florian Renaud f03f7c8d1a Fix a typo in the integration tests readme 2023-03-06 09:29:23 +01:00
Stefan Ceriu 0dd2b12141 chore(ffi): Remove now unnecessarly stored is_soft_logout session and client state property. The did_receive_auth_error(is_soft_logout) client delegate is enough. 2023-03-03 18:10:57 +01:00
Stefan Ceriu d513cb9a47 chore(ffi): remove now unused start_sync method and related properties 2023-03-03 18:10:57 +01:00
Stefan Ceriu e550c16c14 Broadcast UnknownToken API client errors, handle them on the FFI client side and send a did_receive_auth_error delegate call 2023-03-03 12:13:26 +01:00
Sam Wedgwood 0da29057f8 feat(sdk): Expose prepare_encrypted_file function
Signed-off-by: Sam Wedgwood <sam@wedgwood.dev>
2023-03-03 09:27:10 +00:00
Kegan Dougal 5881503a6a Clippy 2023-03-02 14:49:16 +00:00
kegsay e261d37756 Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-03-02 14:48:00 +00:00
Richard van der Hoff a2da63758c Use a separate GHA cache for each matrix build (#1605)
You can't update a GHA cache once you create it, so if we use the same cache
for each job in a matrix build, then we end up populating it for the first job
that completes, so any slower jobs don't get their dependencies cached.

On the other hand, if we create 20 500MB cache items on each build, we're going
to exhaust the cache storage as soon as we do a build. So, instead, let's just
do the caching for the main branch, and hope that other branches can still
benefit from it.
2023-03-02 14:10:53 +00:00
Richard van der Hoff a86754a317 Minor tweaks to the github actions configurations (#1606)
* Replace custom cancellation action with `concurrency`

* Improve step names

... so don't have three steps with the same name

* Bump version of checkout action

checkout@v2 uses an old version of nodejs, which is deprecated.
2023-03-02 14:04:59 +00:00
Kegan Dougal 5c3d02cb89 sliding-sync: process receipt extension response
Needs some kind of tests, but this should do the trick.
2023-03-02 13:53:11 +00:00
Kévin Commaille e84a43dbaa Split StateStore integration tests into a trait
To declare the tests, the macro is still used but the content of the
tests is moved in the StateStoreIntegrationTests trait.

Allows to get the proper line reported when a panic occurs,
and have linting, formatting and IDE suggestions.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-03-02 14:35:51 +01:00
Richard van der Hoff 2fe08a90c5 Reinstate protoc for a couple of GHA jobs (#1607)
Looks like #1604 broke the build :(
2023-03-02 12:47:58 +00:00
Richard van der Hoff bdb9d274ce Skip installing protoc where it is unneeded (#1604)
This seems to have been cargo-culted to lots of places where it is redundant.
2023-03-01 22:17:36 +00:00
Ivan Enderlin 862b4a3df7 chore(bindings): Clean up and code simplification on matrix_sdk_ffi::sliding_sync
chore(bindings): Clean up and code simplification on `matrix_sdk_ffi::sliding_sync`
2023-03-01 20:12:45 +01:00
Ivan Enderlin 1dccea8735 doc: Fix a typo. 2023-03-01 19:59:55 +01:00
Ivan Enderlin e1fe1279c2 Merge pull request #1598 from Hywan/chore-sdk-sliding-sync-list-cleanup
chore(sdk): Various clean up on Sliding Sync (List)
2023-03-01 16:56:57 +01:00
Richard van der Hoff 15513b0ada Clean up the way we build xtask in CI (#1600)
Currently, the cache of the xtask binary isn't working terribly well:

* we seem to build it on each run anyway, presumably because we don't cache any of the intermediate build
   artifacts. Running the binary directly rather than indirecting via "cargo" prevents this.
* There is no sharing of the cache between the "rust" and "bindings" CI, because we use different cache keys.

This PR addresses both problems, and hopefully speeds up CI a bit as a result.
2023-03-01 15:50:31 +00:00
Jonas Platte c9e6d3e2dc Make RemoteEventTimelineItem fields private, provide methods instead 2023-03-01 16:45:43 +01:00
Jonas Platte 400879c819 Make LocalEventTimelineItem fields private, provide methods instead 2023-03-01 16:45:43 +01:00
Jonas Platte aac9d9c29b Move TimelineItemContent and related types into a new submodule 2023-03-01 16:45:43 +01:00
Jonas Platte 770a67678c Move RemoteEventTimelineItem into its own module 2023-03-01 16:45:43 +01:00
Jonas Platte 1452a2124f Move LocalEventTimelineItem into its own module 2023-03-01 16:45:43 +01:00
Jonas Platte daa3b80870 Re-export and document LocalEventTimelineItem, RemoteEventTimelineItem 2023-03-01 16:45:43 +01:00
Ivan Enderlin ccd9ad7b49 chore(bindings): Simplify the code.
Rust is a beautiful language. Let's use all the great constructions it gives to
us to write pretty code.
2023-03-01 16:42:47 +01:00
Ivan Enderlin 4212980f32 chore(bindings): Remove a From<JoinHandle> for TaskHandle impl.
This implementation is never used.
2023-03-01 16:42:09 +01:00
Ivan Enderlin 9b1c5079e6 chore: cargo fmt. 2023-03-01 15:58:22 +01:00
Ivan Enderlin a341caa773 chore(sdk): Continue the move from view to list in Sliding Sync. 2023-03-01 15:46:40 +01:00
Ivan Enderlin b4bf544676 test: Continue the move from view to list in Sliding Sync. 2023-03-01 15:43:59 +01:00
Ivan Enderlin bfb55d782f chore(sdk): Clean up rooms_ops. 2023-03-01 15:38:15 +01:00
Ivan Enderlin 3bad2a84ad chore(sdk): Remove SlidingSyncListRequestGenerator::live_request. 2023-03-01 15:17:53 +01:00
Ivan Enderlin 866c91ffbc chore(sdk): Simplify code of Sliding Sync request generator. 2023-03-01 15:17:31 +01:00
Ivan Enderlin c03ba55f24 chore(sdk): Rename InnerSlidingSyncListRequestGenerator to GeneratorKind. 2023-03-01 15:04:37 +01:00
Ivan Enderlin 1f5c4feafc chore(sdk): Extract Sliding Sync request generators into their own module. 2023-03-01 15:01:02 +01:00
Ivan Enderlin 6d2055449d chore(bindings): Continue to rename view to list in Sliding Sync. 2023-03-01 14:51:34 +01:00
Ivan Enderlin f5cc6feccd chore(sdk): Split the list.rs module into list/mod.rs and list/builder.rs. 2023-03-01 14:43:58 +01:00
Ivan Enderlin c5d5deba8e chore: Continue the renaming from view to list for Sliding Sync. 2023-03-01 14:39:09 +01:00
Ivan Enderlin d829fd3376 chore(bindings): Continue the renaming from view to list for Sliding Sync. 2023-03-01 14:38:43 +01:00
Ivan Enderlin 50a248c18b chore(sdk): Continue the renaming from view to list for Sliding Sync. 2023-03-01 14:38:26 +01:00
Ivan Enderlin c366eadf33 chore(sdk): Rename variables, clean up code, improve documentation… 2023-03-01 14:35:46 +01:00
Jonas Platte 318ede131d refactor(indexeddb): Use IndexeddbStateStoreError in StateStore impl 2023-03-01 14:30:13 +01:00
Jonas Platte 146db59370 refactor(base): Add an Error type to StateStore trait 2023-03-01 14:30:13 +01:00
Ivan Enderlin 97dd68e7fc fix(sdk): Deal with missing data in Sliding Sync's responses
fix(sdk): Deal with missing data in Sliding Sync's responses
2023-03-01 14:24:24 +01:00
Ivan Enderlin 4e4c745032 chore(sdk): Update all mentions to view as list in SlidingSyncList. 2023-03-01 14:20:44 +01:00
Ivan Enderlin f03767318f chore(sdk): Update all mentions to view as list in SlidingSync and SlidingSyncBuilder. 2023-03-01 14:18:40 +01:00
Ivan Enderlin cf83112bf0 chore(sdk): Move FrozenSlidingSyncList lower in the file. 2023-03-01 13:58:55 +01:00
Ivan Enderlin 575eea4701 fix(sdk): Deal with missing data in Sliding Sync's responses.
The Sliding Sync server might not send some parts of the response, because they
were sent before and the server wants to save bandwidth. So let's update values
only when they exist.
2023-03-01 12:19:30 +01:00
Ivan Enderlin 5377bb7ecf fix(sdk): Rename SlidingSyncView to SlidingSyncList.
The specification describes “list”, not “view”. Consistency is important, so
let's rename this type!
2023-03-01 12:09:34 +01:00
Ivan Enderlin 629b74e4f5 chore(sdk): Rename the sliding_sync::view module to …::list. 2023-03-01 11:56:01 +01:00
Ivan Enderlin 9475bb4d53 chore(indexeddb): Update version of uuid
chore(indexeddb): Update version of `uuid`
2023-03-01 09:09:15 +01:00
Ivan Enderlin 452588a18e chore(indexeddb): Update version of uuid. 2023-03-01 08:26:28 +01:00
Stefan Ceriu ff5dedbb07 fix(sliding_sync): Prevent PagingFullSync and GrowingFullSync from going over the total room count 2023-02-28 18:32:11 +01:00
valere 6539dc3060 quick typo 2023-02-28 17:53:54 +01:00
valere 7b8608e4c5 refactor(withheld) better type for no_olm 2023-02-28 17:38:37 +01:00
Stefan Ceriu 5c3972938e chore: Add platform versions for swift CI tests 2023-02-28 15:06:23 +01:00
Jonas Platte b936d3e32d chore: Remove workaround for clippy bug that was fixed 2023-02-28 12:36:08 +01:00
Kévin Commaille da8d74ccc1 feat(sdk): Keep track of events read receipts in the timeline API
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-28 09:44:35 +01:00
Kévin Commaille 6aad2a661d refactor(sdk): Rename ProfileProvider to RoomDataProvider
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-28 09:44:35 +01:00
Kévin Commaille 3139204f4b fix(examples): Don't use the sled store if the session is not persisted
Running the same example twice
borks encryption.
Instead point to an example that shows how to do it.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-28 09:20:53 +01:00
Kévin Commaille 1684dbe0a1 feat(examples): Add example to persist a session
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-28 09:20:53 +01:00
Doug 9531dc195a fix(bindings): Fix double quotes when replying to a reply. 2023-02-27 18:23:49 +01:00
Sam Wedgwood abab6dcf0f docs(crypto): Fix typo
Signed-off-by: Sam Wedgwood <sam@wedgwood.dev>
2023-02-27 15:39:01 +00:00
Ivan Enderlin d699161981 chore(sdk): Code reorganization of the sliding_sync module + doc improvement
chore(sdk): Code reorganization of the `sliding_sync` module + doc improvement
2023-02-27 15:27:08 +01:00
Ivan Enderlin 927c44bec3 doc(sdk): Fix doctests + remove mentions to futures-signals. 2023-02-27 15:08:13 +01:00
Ivan Enderlin 96248248ca chore(sdk): Move UpdateSummary at the bottom of the module. 2023-02-27 13:56:04 +01:00
Ivan Enderlin b7b86fa95b fix(sdk): Few fixes and cleans up of SlidingSync itself
fix+chore(sdk): Few fixes and cleans up of `SlidingSync` itself
2023-02-27 13:50:48 +01:00
Ivan Enderlin 4f7186a840 chore(sdk): Simplify the implementation of RoomListEntry. 2023-02-27 13:49:34 +01:00
Ivan Enderlin 9b062fa782 chore(sdk): Move RoomListEntry into the sliding_sync::view module. 2023-02-27 13:43:40 +01:00
Ivan Enderlin 4d8c3172a4 chore(sdk): Extract Error into its own module. 2023-02-27 13:42:01 +01:00
Ivan Enderlin b1c9ea9aa3 chore(sdk): Move SlidingSyncMode into the sliding_sync::view module. 2023-02-27 13:38:54 +01:00
Ivan Enderlin 49eee14665 chore(sdk): Move SlidingSyncState into the sliding_sync::view module. 2023-02-27 13:38:09 +01:00
Ivan Enderlin 6cec946401 chore(sdk): Improve documentation of SlidingSync. 2023-02-27 13:36:08 +01:00
Jonas Platte d06e8ccfc5 refactor: Upgrade eyeball and use SharedObservable
… but not in sliding sync yet, where some planned refactorings might
conflict with this.
2023-02-27 13:29:28 +01:00
Ivan Enderlin ac1d5afac3 doc(sdk): Improve inline documentation with link to an issue. 2023-02-27 13:29:03 +01:00
Ivan Enderlin f51b51b19e chore(sdk): Avoid mapping to a function returning (). 2023-02-27 12:14:01 +01:00
Ivan Enderlin 16c9845a47 chore(sdk): Rename SlidingSync.failure_count to .reset_counter.
This patch cleans up the `SlidingSync::stream` method. It renames variables,
improves log messages etc.

This patch also creates a new `MAXIMUM_SLIDING_SYNC_SESSION_EXPIRATION`
constant. This value was previously hardcoded and lost in the code, now it's
easier to spot it for further updates.

This patch finally renames the `failure_count` field to `reset_counter`,
because it doesn't count the number of failure, but the number of
`ErrorKind::UnknownPos` exactly, i.e. the number of times we reset the
`SlidingSync` state.
2023-02-27 12:09:14 +01:00
Ivan Enderlin 4dbd1a7db4 fix(sdk): Fix join in SlidingSync::sync_once.
This patch cleans up the `SlidingSync::sync_once` method by renaming variables,
adding more comments, simplifying the code by reducing the number of variables
etc.

This patch also changes `futures_util::join!` to `futures_util::future::join`.
It does the same but the macro needs the `async-await-macros` feature to be
turned on, while the second works without any features.

Finally, this patch improves the log messages by making them more clear for a
new reader.
2023-02-27 11:56:16 +01:00
Ivan Enderlin e5c85410a8 doc(sdk): Fix documentation, add links etc. 2023-02-27 11:54:48 +01:00
Ivan Enderlin 98ea3f096b chore(sdk): Clean up code of SlidingSync::cache_to_storage. 2023-02-27 11:54:13 +01:00
Anderas f0986643ce chore(crypto): Log Olm session identifiers
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-02-27 10:59:30 +01:00
valere f4d4d96c8e support migration for outbound after withheld addtition 2023-02-27 09:56:56 +01:00
Ivan Enderlin b214a0e098 feat(sdk): Remove clones of large responses in Sliding Sync
feat(sdk): Remove clones of large responses in Sliding Sync
2023-02-27 09:47:26 +01:00
Ivan Enderlin 70380a6ee4 doc(sdk): Improve documentation of SlidingSync::handle_response. 2023-02-27 09:30:50 +01:00
valere 39997376af fix js binding test 2023-02-25 16:33:16 +01:00
valere 58fa9d7767 fix ci 2023-02-25 16:18:06 +01:00
valere ad18ecc2c1 cleaning 2023-02-25 10:50:37 +01:00
valere ff500fc707 fix unused result 2023-02-25 10:39:17 +01:00
valere 76a286c91d feat(withheld) sled store support 2023-02-25 10:31:23 +01:00
valere 6cc31a0e13 fix clippy 2023-02-24 17:15:51 +01:00
valere 228b963f74 feat(withheld) fix indexeddb test 2023-02-24 16:39:37 +01:00
Jonas Platte 1783cd7738 test: Remove unused constant 2023-02-24 12:39:55 +01:00
Jonas Platte 32e8cb76b0 ci: Remove unused FeatureSet variant 2023-02-24 12:39:55 +01:00
valere 81c9f57e02 clippy fix 2023-02-23 18:02:45 +01:00
Benjamin Kampmann e162c99074 feat: Handy function to update power levels of a room 2023-02-23 17:53:48 +01:00
Benjamin Kampmann 6465398322 feat: expose power_levels.user_can_do on RoomMember 2023-02-23 17:53:48 +01:00
valere 6b948711b9 feat(withheld) Integration tests 2023-02-23 17:47:57 +01:00
Ivan Enderlin f803e58e36 chore(sdk): Keep to_remove inside its own scope. 2023-02-23 16:53:16 +01:00
Ivan Enderlin 23b3e3aa10 chore(sdk): Format code a little bit. 2023-02-23 16:40:48 +01:00
Ivan Enderlin fcfdf5c57c chore(sdk): Rename a variable in SlidingSync::handle_response. 2023-02-23 16:40:48 +01:00
Ivan Enderlin 3b01e4f9a6 chore(sdk): Use T::default instead of Default::default. 2023-02-23 16:39:56 +01:00
Ivan Enderlin 3c44f87bee doc(sdk): Simplify one documentation. 2023-02-23 16:39:39 +01:00
Ivan Enderlin af6cd85cf4 chore(sdk): SlidingSyncRoom::new no longer needs a mutable inner. 2023-02-23 16:27:19 +01:00
Ivan Enderlin 54654aa0c7 chore(sdk): Simplify references, thanks Clippy. 2023-02-23 16:03:11 +01:00
Ivan Enderlin 778d1211c7 feat(bindings): Replace many scripts by one xtask
Ganfra/kotlin binding scripts
2023-02-23 15:58:40 +01:00
Ivan Enderlin c69d28ef79 feat(sdk): Remove clones of large responses in Sliding Sync.
I admit this patch is quite tricky. Please try to follow me.

So, first off, in `SlidingSyncRoom::new`, we were clearing the timeline,
because somehow it exists twice in memory at this step.

Which led me to understand how `SlidingSync::handle_response` was working.
I've clarified how this part of the code works. We are dealing with 2 kind of
responses for a specific reason: `SyncResponse` and `v4::Response`, now it's
documented and I hope it's clearer.

Then, I notice that we were passing a clone of the entire sliding sync
response (`v4::Response`) to `Client::process_sliding_sync`. I thought it was
suboptimal, so I've updated the code to take a reference. It led me to update
`BaseClient::process_sliding_sync`. It was a little bit tricky, but I reckon we
have less clones now than before.

And now, back to `SlidingSync::handle_response`, I was able to compute the
`timeline` correctly by draining it from the `v4::Response`, or by moving it
from `SyncResponse`. So it's no longer necessary to have this clearing code
inside `SlidingSyncRoom::new`. Honestly it has nothing to do at this place
before.

To conclude: We have cleaner code, and less clones.

What thing I reckon could be optimized, is that the entire `timeline`
(`Vec<TimelineEvent>`) is cloned to be passed to `Client::handle_timeline`. So
this timeline exists in 2 places: in Sliding Sync, and somewhere else. I don't
believe it's a problem now, that's how it works, but we must be aware of that.
2023-02-23 15:21:21 +01:00
Jonas Platte d0c8ec7a22 refactor: Replace remaining usage of futures-signal with eyeball(-im) 2023-02-23 15:08:41 +01:00
Doug 01e3a31a11 fix(bindings): Verify entered homeserver before proxy availability
The reported errors weren't that helpful to the user.
Additionally attempt discovery when a URL is entered before falling back to the URL directly.
2023-02-23 12:12:53 +00:00
ganfra 83dcb0eb48 xtask kotlin : fix formatting 2023-02-23 11:53:32 +01:00
Jonas Platte 6c92bf8745 refactor(sdk): Remove unused dependency 2023-02-23 11:47:51 +01:00
Jonas Platte ba6fc794b0 refactor(base): Replace futures-signals with eyeball 2023-02-23 11:47:51 +01:00
Jonas Platte 17b86b7c38 refactor(crypto): Replace futures-signals with eyeball 2023-02-23 11:47:51 +01:00
valere 9894d3c72d feature(withheld) indexeddb store implem 2023-02-23 10:13:32 +01:00
boxdot d5154577a0 feat(sdk): Add custom login method
The `Client::login_custom` allows to login by using a custom login
method. In particular, it is possible to login to Synapse which supports
JWT authentication.

Signed-off-by: boxdot <d@zerovolt.org>
2023-02-23 08:16:04 +01:00
Ivan Enderlin 5be00d5950 chore(sdk): Many clean ups in SlidingSync
chore(sdk): Many clean ups in `SlidingSync`
2023-02-22 20:16:54 +01:00
Ivan Enderlin f3928e8d35 chore(sdk): Remove an unnecessary clone in SlidingSyncRoom::update. 2023-02-22 20:03:11 +01:00
Ivan Enderlin c766d8b3ef chore(sdk): Address PR feedback. 2023-02-22 20:00:49 +01:00
Ivan Enderlin 4d33fe1c31 chore(sdk): Rename some variable inside FrozenSlidingSyncRoom. 2023-02-22 19:59:57 +01:00
Ivan Enderlin e80713e933 chore(sdk): SlidingSyncRoom::update takes ownership of room_data.
First off, it's not necessary for `SlidingSyncRoom::update` to take a reference
to `room_data: v4::SlidingSyncRoom`. When `update` is called, the iterator owns
its items.

Second, by taking ownership of `room_data`, we no longer need to clone all the
data we need to assign to `self.inner`.
2023-02-22 19:59:57 +01:00
Ivan Enderlin 5d356ca1b5 feat(sdk): Avoid locking prev_batch in SlidingSyncRoom::timeline_builder. 2023-02-22 19:59:57 +01:00
Ivan Enderlin 56daa6cb8f chore(sdk): Rename SlidingSyncRoom pub(crate) from to pub(super) new.
First off, `SlidingSyncRoom.from` doesn't need to be visible to the entire
crate, only to `crate::sliding_sync.

Second, it's a constructor, so let's call it `new`.
2023-02-22 19:59:43 +01:00
Kévin Commaille bcc04bdf35 feat(sdk): Add conversion from EventTimelineItem and VirtualTimelineItem to TimelineItem
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-22 16:59:22 +00:00
Ivan Enderlin ebe8ce3177 feat(sdk): Make SlidingSync.pos already private
feat(sdk): Make SlidingSync.pos already private
2023-02-22 17:42:30 +01:00
Ivan Enderlin 1d02515186 chore(sdk): Re-organizing the code inside sliding_sync::room.
1. Put `FrozenSlidingSyncRoom` at the bottom of the module.
2. Put merge 2 `impl SlidingSyncRoom` together.
3. Remove the `AliveRoomTimeline` type alias.
4. Improve the documentation.
2023-02-22 17:38:37 +01:00
Ivan Enderlin 0abef77408 doc(sdk): Improve documentation of SlidingSyncBuilder. 2023-02-22 17:29:40 +01:00
Jonas Platte fe7f157253 refactor(bindings): Use UniFFI proc-macros for CrossSigningStatus 2023-02-22 17:21:21 +01:00
Ivan Enderlin 5a62ec3fc1 chore(ffi) Rename StoppableSpawn to TaskHandle
chore(ffi) Rename `StoppableSpawn` to `TaskHandle`
2023-02-22 17:11:36 +01:00
Ivan Enderlin 5727726e5d feat(sdk): Make SlidingSync.pos already private.
So far, the `SlidingSync.pos` field was public to the crate. In order to avoid
breaking the internal state of this type, its visibility is now private.

However, we need to be able to change the value when testing the
`SlidingSync` type itself. To achieve that, this patch removes the old
`force_sliding_sync_pos` function, and implements 2 new functions: `set_pos`
and `pos` directly on `SlidingSync` only when `#[cfg(any(test, feature ="testing"))]`.
2023-02-22 17:07:50 +01:00
Ivan Enderlin dec4b2122b doc(sdk): Improve documentation of SlidingSyncMode. 2023-02-22 16:51:42 +01:00
Ivan Enderlin cfcafc8425 chore(ffi) Rename StoppableSpawn to TaskHandle.
Because it is what it is.
2023-02-22 16:48:46 +01:00
valere 42934ea7e4 feature(withheld) ffi bindings 2023-02-22 15:46:56 +01:00
kegsay 7e64c15145 fix: look for the right list when waiting for updates
Otherwise it will time out after 30s and then continue executing,
causing a slow test.
2023-02-22 14:42:32 +00:00
valere e56d380f65 fix store after rebase 2023-02-22 14:28:20 +01:00
ganfra f72d9c2016 Merge branch 'main' into ganfra/kotlin_binding_scripts 2023-02-22 13:31:56 +01:00
Jonas Platte 95f1867816 chore: Delete sled-state-inspector
The sled store is on its way out and nobody is using this.
2023-02-22 13:17:01 +01:00
Jonas Platte b1062a67e0 fix(sdk): Rewrite decryption retrying to fix invalid index bug
Previously, it was possible for us to use invalid indices when:

- We retried decrypting multiple events at once
- One of them (not the last) was an edit or reaction

This lead to a situation where we would remove the UTD item once
decryption for it was successfully retried, but not account for the
resulting index shift for all later timeline items.
2023-02-22 12:44:11 +01:00
Janne Heß 02a213c1b5 feat(sdk): Add support to change display names of devices
Signed-off-by: Janne Heß <janne.hess@helsinki-systems.de>
2023-02-22 10:55:54 +00:00
Archit Bhonsle 64ec5ec561 feat(crypto): Expose and re-expose the version of the matrix-sdk-crypto crate 2023-02-22 10:21:48 +00:00
ganfra 953d4c0ef7 Remove kotlin bindings for now 2023-02-22 11:00:05 +01:00
Ivan Enderlin 1469e9033c feat(crypto-nodejs): OlmMachine.initialize takes a new optional store type
feat(crypto-nodejs): `OlmMachine.initialize` takes a new optional store type
2023-02-22 10:33:26 +01:00
ganfra 260e7c2d5e Update kotlin xtask to not build aar 2023-02-22 10:28:08 +01:00
Archit Bhonsle ae4ed2e7c8 feat(crypto): Re-expose the version of vodozemac 2023-02-22 09:45:25 +01:00
valere 28fadb875a Post rebase fix 2023-02-21 17:48:05 +01:00
valere 3dbad4229a feat(withheld): sql store support 2023-02-21 15:05:14 +01:00
valere c497efc27a feat(withheld): handle incoming withheld + report error 2023-02-21 15:04:58 +01:00
valere 0154cccd4b feat(withheld) Remember no_olm and implement in memory store 2023-02-21 15:03:04 +01:00
valere 99232f2340 refactor(withheld) 2023-02-21 15:00:34 +01:00
valere 592be5bd57 feat(withheld) basic no_olm 2023-02-21 15:00:34 +01:00
valere dc0fe35103 feat(withheld) balcklist + refactoring 2023-02-21 15:00:34 +01:00
valere 7accfdc2ef feat(withheld) Implement MSC2399 2023-02-21 15:00:34 +01:00
Damir Jelić 655d7d00d0 chore(crypto): Add support for encrypted m.dummy events
This mostly just silences an incorrect log warning that we received an unsupported event.

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-02-21 14:33:14 +01:00
Jonas Platte ac5b439249 chore(sdk): Add an extra trace event to TimelineEventHandler::add 2023-02-21 12:11:03 +01:00
Jonas Platte f76bc16a10 fix(sdk): Lock timeline state once for decryption retrying
Before, we were releasing the lock and re-obtaining it between obtaining
item indices and using them for decryption retrying.
2023-02-21 12:11:03 +01:00
Jonas Platte a89a12701a refactor(sdk): Remove unneeded Arc around MutableVec 2023-02-21 10:20:11 +01:00
Jonas Platte 843fe6a239 refactor(sdk): Remove derive_builder 2023-02-21 10:20:11 +01:00
Jonas Platte cb06feea22 refactor(sled): Remove derive_builder
… and use owned Builder pattern like for Client.
2023-02-21 10:20:11 +01:00
Jonas Platte b0e7f3d031 refactor(indexeddb): Remove derive_builder
… and use owned Builder pattern like for Client.
2023-02-21 10:20:11 +01:00
Jonas Platte b96532878b refactor(sdk): Replace futures-signals with eyeball-im in the timeline 2023-02-20 18:01:31 +01:00
Ivan Enderlin b439d60b1f feat(sdk): SlidingSyncView.state, .rooms_list and .rooms_count are now private
feat(sdk): `SlidingSyncView.state`, `.rooms_list` and `.rooms_count` are now private
2023-02-20 16:25:02 +01:00
Ivan Enderlin e8af3e2d60 chore(clippy): Make Clippy happy. 2023-02-20 15:39:23 +01:00
Ivan Enderlin 1f3b8048c7 chore(jack-in): Use the latest SS API. 2023-02-20 15:39:23 +01:00
Ivan Enderlin 48257ac7cd test(sdk): SS integration test suites use the new API. 2023-02-20 15:39:23 +01:00
Matteo Ludwig dffc65007c feat(bindings): Add AudioInfo & AudioMessageContent to matrix-sdk-ffi
Signed-off-by: Matteo Ludwig <ludwig@silpion.de>
2023-02-20 14:01:06 +00:00
Ivan Enderlin 3796469a29 doc(sdk): Fix Sliding Sync examples. 2023-02-20 14:24:38 +01:00
Ivan Enderlin d49ceddfd5 feat(sdk): SlidingSyncView.state, .rooms_list and .rooms_count are now private.
Before this patch, `SlidingSyncView` has the following fields that were public:
`state`, `rooms_list` and `rooms_count`. Since they are `Mutable`, they can be
changed from the outside, and then will break the internal state of the view.
This problem is mentioned in https://github.com/matrix-org/matrix-rust-sdk/
issues/1474.

This patch solves this by making them prviate. Phew. That was simple!

But wait, we have a problem now. `matrix-sdk-ffi` was relying on them. So
this patch adds “helpers” methods on `SlidingSyncView`, like `state_stream`,
`rooms_list`, `rooms_list_stream`, `rooms_count` and `rooms_count_stream`.
Let's add new ones when it's necessary.
2023-02-20 14:22:42 +01:00
Ivan Enderlin 03c3f66c9a doc(sdk): Fix Sliding Sync examples. 2023-02-20 14:20:22 +01:00
Ivan Enderlin 7b06822687 chore(sdk): Group impl blocks for the same SlidingSyncView in a single impl block. 2023-02-20 14:15:20 +01:00
Jonas Platte 1f128c1dd6 refactor(sdk): Remove Mutable<_> around SlidingSyncView#sync_mode 2023-02-20 13:20:33 +01:00
Jonas Platte e92841d6bc refactor(sdk): Inline Mutable type aliases 2023-02-20 13:20:33 +01:00
Jonas Platte a112076664 refactor(sdk): Remove usage of MutableBTreeMap
No instance was ever subscribed to, so we can just use a regular shared RwLock.
2023-02-20 13:20:33 +01:00
Jonas Platte 2f9106a6d0 refactor(sdk): Make SlidingSync fields private 2023-02-20 13:20:33 +01:00
Ivan Enderlin 8a70df80b2 doc(sdk): Fix Sliding Sync module documentation.
doc(sdk): Fix Sliding Sync module documentation.
2023-02-20 12:23:10 +01:00
Jonas Platte cbcfd5d531 refactor(bindings): Fix SlidingSyncRoom timeline listener return type
It's an error if the room was not found, so it should be surfaced as such.
2023-02-20 12:10:13 +01:00
Ivan Enderlin b451460d8d doc(sdk): Improve Sliding Sync documentation
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-02-20 12:06:20 +01:00
Ivan Enderlin 772a94cc8c doc(sdk): Fix Sliding Sync module documentation. 2023-02-20 11:49:35 +01:00
Jonas Platte 0f077ffcd3 fix(sdk): Don't overwrite parallel updates when fetching reply details 2023-02-20 11:15:23 +01:00
Jonas Platte 9eefe9377e refactor(sdk): Move timeline functionality into TimelineInner 2023-02-20 11:15:23 +01:00
Ivan Enderlin b35f2669d2 chore(sdk): Split the sliding_sync module into smaller ones
chore(sdk): Split the `sliding_sync` module into smaller ones
2023-02-20 11:09:05 +01:00
Ivan Enderlin 4102d25ebe chore(sdk): Split the sliding_sync module into smaller ones.
It's an strict copy-paste. Nothing has changed, except the
`SlidingSyncConfigBuilder::subscriptions` method that is now public within
the crate.
2023-02-20 10:43:05 +01:00
Ivan Enderlin 177fa140fc fix(sdk): FrozenSlidingSyncRoom.timeline_queue must serialize to timeline
fix(sdk): `FrozenSlidingSyncRoom.timeline_queue` must serialize to `timeline`
2023-02-17 19:46:50 +01:00
Ivan Enderlin e0eeba21ff fix(sdk): FrozenSlidingSyncRoom.timeline_queue must serialize to timeline.
In https://github.com/matrix-org/matrix-rust-sdk/pull/1478, I've introduced
a regression. The FrozenSlidingSyncRoom.timeline` field has been renamed to
`timeline_queue`.

I didn't notice that this type can be serialized and deserialized. That's
actually a breaking change because this type is stored somewhere once
serialized. So with #1478, it was impossible to deserialize them!

This patch fixes that. It also adds a test to ensure the serialization form of
`FrozenSlidingSyncRoom` doesn't change.
2023-02-17 19:24:39 +01:00
Jonas Platte e4f94f3174 chore: Fix warnings 2023-02-17 11:30:13 +01:00
Jonas Platte c2f529ed71 chore: Run cargo update
To pull in the latest Ruma release with a bugfix for content reporting.
2023-02-17 11:30:13 +01:00
Jonas Platte 0b91ec29a4 Allow to get or send any type of receipt 2023-02-17 10:54:03 +01:00
Kévin Commaille 362a394a11 feat(sdk)!: Allow to send private read receipts and receipts in threads
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-17 10:33:09 +01:00
Kévin Commaille 6ddb22d6ab feat(sdk): Expose methods to get a user or an event's receipts
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-17 10:29:22 +01:00
Kévin Commaille a3f289c6fc feat(base)!: Allow to get any receipt type for a user or event
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-17 10:29:21 +01:00
Jonas Platte 44d8f99bc4 docs(sdk): Remove outdated documentation 2023-02-17 09:56:29 +01:00
Ivan Enderlin eb3fb6986d doc(sdk): Fix links to examples and to matrix_sdk_base
doc(sdk): Fix links to examples and to `matrix_sdk_base`
2023-02-17 08:53:00 +01:00
Ivan Enderlin b6fb25fdfa test(sliding-sync): ensure unknown pos does recover the room subscription properly
test(sliding-sync): ensure unknown pos does recover the room subscription properly
2023-02-16 18:24:17 +01:00
Mauro 679d3084aa feat(bindings): Add Room::report_content 2023-02-16 17:18:18 +00:00
Ivan Enderlin 94b60f915f test(sdk): Address feedbacks. 2023-02-16 17:54:28 +01:00
Ivan Enderlin 3bf1060705 Merge branch 'main' into ben-fix-resubscribe-problem 2023-02-16 17:44:26 +01:00
Ivan Enderlin d600af7c0e feat(crypto-nodejs): OlmMachine.initialize takes a new optional store type.
This patch allows an `OlmMachine` to use a different store than Sled, like SQLite.

A new enum is introduced: `StoreType` which 2 variants: `Sled` (the default), and `Sqlite`.

The `OlmMachine.initialize` constructor now takes a new optional `store_type:
Option<StoreType>` argument. If no value is passed, the default `StoreType`
variant will be used (as mentioned: `StoreType.Sled`).

The code has been rewritten a little bit to make the type system happy without
introducing too much type indirections.

This patch finally adds a parameterized tests that exhaustively test: no store
type, `Sled` and `Sqlite`.
2023-02-16 16:26:06 +01:00
Damir Jelić 9649100adb feat(sdk): Add a root span to our client 2023-02-16 15:31:38 +01:00
Damir Jelić 292a9831f5 refactor(crypto): Move the usage specific cross signing types into the types module 2023-02-16 14:39:07 +01:00
Damir Jelić 04d8348477 refactor(crypto): Split out the cross signing key handling method 2023-02-16 14:39:07 +01:00
Ivan Enderlin 7049bd9183 doc(sdk): Improve Sliding Sync documentation
Sliding Sync API docs & minor fixes around API accessibility
2023-02-16 14:12:45 +01:00
Ivan Enderlin 1c7ffedf1a Merge branch 'main' into ben-sliding-sync-docs 2023-02-16 14:00:56 +01:00
Ivan Enderlin 7cc06cb76d chore(sdk): Small cleans up when reading the Sliding Sync code
chore(sdk): Small cleans up when reading the Sliding Sync code
2023-02-16 13:38:04 +01:00
Ivan Enderlin 9479f23f4b fix(sdk): Reconciliate events in the timeline queue in Sliding Sync when new updates arrive
fix(sdk): Reconciliate events in the timeline queue in Sliding Sync when new updates arrive
2023-02-16 12:35:35 +01:00
Ivan Enderlin c719d6d22e doc(sdk): Fix links to examples and to matrix_sdk_base. 2023-02-16 12:08:42 +01:00
Ivan Enderlin 6aa766efd0 chore(sdk): Address PR feedback. 2023-02-16 11:58:07 +01:00
Richard van der Hoff a0807cb337 crypto-js: support npm run build:dev (#1510)
Building the crypto-js bindings in release mode is very slow and not really
necessary for local development.

`--release` is the default, so there is no need to specify it
explicitly. Instead, allow `wasm-pack` args to be specified by an env var, and
add a `build:debug` npm script which will build in debug mode.
2023-02-16 10:51:37 +00:00
Richard van der Hoff 480800b996 crypto-js: have share_room_key return ToDeviceRequests (#1516)
We already have support for proper `ToDeviceRequest` objects in
`outgoing_requests`, so let's use it in `share_room_key` as well. It's much
easier for the application to work with the proper object than an untyped json
blob.
2023-02-16 10:51:15 +00:00
Ivan Enderlin 1c0288e42b chore(sdk): Simplify code by removing a map.
In the code `if let Some(global_data) = account_data.as_ref().map(|a|
&a.global)`, the `map` is not purely necessary. This patch simplifies the code
to remove the `map` and read the `global` field later on.
2023-02-16 11:49:21 +01:00
Ivan Enderlin 0a97ac8316 chore(sdk): Address PR feedback. 2023-02-16 11:45:10 +01:00
Ivan Enderlin 46006cf108 chore(sdk): Address PR feedback. 2023-02-16 11:43:25 +01:00
Ivan Enderlin 10adb6d26b chore(sdk): Use appropriate type to remove the need of a comment.
By using `Default::default` for the parameter value, we don't know which type
we are passing to the function. Hence the useful comment `room_info.ephemeral`.
This patch changes this to `Ephemeral::default`, so that we now know what we
pass without the need of a comment.
2023-02-16 11:23:05 +01:00
Richard van der Hoff 5abab932db ci: Fail coverage job if the coverage report can't be uploaded (#1515) 2023-02-16 09:36:43 +00:00
Damir Jelić abef9fae1a chore(bindings): Use tracing-android instead of android-logger 2023-02-16 09:59:16 +01:00
Ivan Enderlin b05d6874c0 test(sdk): Update the timeline inspection when the timeline_limit is modified. 2023-02-16 09:49:36 +01:00
Jonas Platte 3f2b12c996 chore(base): Remove unused futures-channel dependency 2023-02-16 08:59:41 +01:00
Ivan Enderlin 838488702f Merge branch 'main' into test-sliding-sync-timeline-limit-duplication 2023-02-16 08:45:22 +01:00
Ivan Enderlin 6c62b5f637 test(sdk): Restore the sliding-sync Docker image to v0.99.0. 2023-02-16 08:16:03 +01:00
Richard van der Hoff 826dc46ddf Merge pull request #1511 from matrix-org/rav/trace-to-debug
crypto-js: log trace messages at debug
2023-02-15 18:13:06 +00:00
Richard van der Hoff d9e455ab82 crypto-nodejs, crypto-js: prettify the javascript codebase (#1509) 2023-02-15 17:47:32 +00:00
kegsay 19b8ab409d test: Add depends_on block for the sliding sync proxy
This prevents the proxy starting before postgres is ready, which
causes the proxy to panic.
2023-02-15 17:32:57 +00:00
Richard van der Hoff 99b61ef660 Remove redundant log_trace 2023-02-15 17:06:46 +00:00
kegsay fb467b75e0 ci: Update sliding sync integration tests job 2023-02-15 17:03:29 +00:00
Jonas Platte 9e2fa13b9c fix(sdk): Respect new server ordering when receiving duplicate events 2023-02-15 17:40:16 +01:00
Jonas Platte 38e2d0bdcd fix(sdk): Fix day divider removal logic in timeline 2023-02-15 17:40:16 +01:00
Jonas Platte e8d5d29d2c chore(sdk): Improve tracing in TimelineEventHandler::add 2023-02-15 17:40:16 +01:00
Jonas Platte 88376e85cd test(sdk): Remove TestTimeline::with_initial_events
It's not general enough for further inital event tests.
2023-02-15 17:40:16 +01:00
Ivan Enderlin b1bfb868ab chore(sdk): Make Clippy happy. 2023-02-15 17:15:03 +01:00
Ivan Enderlin 6b3a550b22 chore(sdk): Fix lints. 2023-02-15 17:08:30 +01:00
Ivan Enderlin d9f9ed9d68 fix(sdk): Reconciliate timeline queue in SlidingSync when new updates arrive.
The code is self-documented. Please read it.
2023-02-15 16:50:40 +01:00
Jonas Platte 188aaecde3 feat(sdk): Keep Timeline event handlers around longer
… if the Timeline object itself is dropped, but something is still
subscribed to its changes.
2023-02-15 15:29:04 +01:00
Richard van der Hoff d41753ea17 crypto-js: log trace messages at debug
Javascript's `console.trace` is not a good equivalent for Rust's
`Level::TRACE`.

In particular:
 * `console.trace` causes a stacktrace to be written with each message
 * Under nodejs, `console.trace` writes the message to `stderr`, while
   `console.debug` writes to stdout

`console.trace` is therefore somewhat analogous to `console.error`.

Since we already include the log level in the message, we might as well just
send trace messages to `console.debug` rather than `console.trace`.
2023-02-15 12:50:42 +00:00
Richard van der Hoff e16c113db0 crypto-js, crypto-nodejs: Run prettier in CI 2023-02-15 12:39:54 +00:00
Richard van der Hoff 3f8590f86d crypto-nodejs, crypto-js: Run prettier on source code 2023-02-15 12:39:54 +00:00
Ivan Enderlin a0bd88aefc feat(crypto-nodejs) Implement OlmMachine.close
feat(crypto-nodejs) Implement `OlmMachine.close`
2023-02-15 12:48:45 +01:00
Jonas Platte 74056de8d7 fix(sdk): Deduplicate events coming from back-pagination 2023-02-15 12:41:26 +01:00
Jonas Platte 4f14728c91 chore(sdk): Add more spans and trace events to the timeline 2023-02-15 11:08:20 +01:00
Ivan Enderlin 57b810d70c test(sdk): Test changing the sliding sync limit on-the-fly. 2023-02-15 10:13:03 +01:00
Ivan Enderlin b3fedda90c chore(sdk): Clean up useless code.
The `experimental-timeline` feature is always enabled by `experimental-sliding-
sync`. Thus we can clean up the code.
2023-02-15 10:12:56 +01:00
Jonas Platte 20e082d416 refactor(sdk): Add a Date type for day divider logic 2023-02-15 10:08:05 +01:00
Jonas Platte 9e0ff4b9a9 fix(sdk): Handle remote echo on the first message of the day correctly 2023-02-15 10:08:05 +01:00
Jonas Platte b57bd55204 refactor(sdk): Use .rev().find_map() instead of .rfind().and_then() 2023-02-15 10:08:05 +01:00
Jonas Platte 4cad934a6b refactor(sdk): Simplify day divider timestamp conversion 2023-02-15 10:08:05 +01:00
Jonas Platte aa2b2dfff4 test(sdk): Fix reference to renamed test case 2023-02-15 09:31:42 +01:00
Jonas Platte 6c2a9dae55 test(sdk): Use u64 instead of u32 for next_ts
It seems weird to artificially limit the number range to 32 bits there,
panicking inside a test on too large values is fine.
2023-02-15 09:31:42 +01:00
Jonas Platte 360864841e test(sdk): Allow tests to set the next TS, use for day divider test 2023-02-15 09:31:42 +01:00
Jonas Platte 563ba884eb test(sdk): Make next_ts part of TestTimeline 2023-02-15 09:31:42 +01:00
Jonas Platte 13ffadc32a test(sdk): Add handle_live_redacted_message_event 2023-02-15 09:31:42 +01:00
Jonas Platte e246735866 test(sdk): Shorten some method names 2023-02-15 09:31:42 +01:00
Ivan Enderlin 6593f61556 doc(crypto-nodejs): Add safety comment for OlmMachine.close. 2023-02-15 09:15:31 +01:00
Jonas Platte 423d6ace83 fix(sdk): Attempt to EX-android crash with more hacks 2023-02-14 17:53:21 +01:00
Jonas Platte ce315a5229 chore: Use fully-qualified Docker image names
This brings us closer to being able to use our Docker setup with podman too.
2023-02-14 10:19:06 +01:00
Jonas Platte ca1163c9cc test: Remove trailing spaces from docker-compose.yml 2023-02-14 10:19:06 +01:00
Jonas Platte e576af8267 test: Fix docker-compose.yml error
Seems to be accepted by some older versions of docker-compose, but not
by current ones.
2023-02-14 10:19:06 +01:00
Jonas Platte 118497f9ec test: Remove unused dependency 2023-02-13 16:59:45 +01:00
Jonas Platte ac06172cf2 test(sdk): Add timeline items accessor 2023-02-13 16:21:30 +01:00
Damir Jelić 2654e909be feat(store-encryption): Add support to export/import the cipher using a key
This is useful for platforms which might want to avoid the cost of
password based key-derivation and have the ability to securely store an
encryption key.

Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-02-13 14:08:45 +00:00
Damir Jelić a1b1862479 docs(crypto): Explain a bit better what it means that a Device owns a room key
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2023-02-13 15:00:15 +01:00
Ivan Enderlin 5001cef372 Merge pull request #1375 from Hywan/feat-crypto-nodejs-requests-more-types 2023-02-13 14:46:47 +01:00
Kévin Commaille a6f74fa22c fix(sled): Use proper table name for encoding key when redacting
Contrary to other tables that use their own name to encode their keys,
the `ROOM_INFO` table uses the `ROOM` table name to encode its keys.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-13 14:07:06 +01:00
Damir Jelić 56cfa8f4f9 fix(crypto): Always mark your own device as verified 2023-02-13 14:01:31 +01:00
Richard van der Hoff 8d642784bb fix: remove dependency on broken wasm_timer crate
`wasm_timer` doesn't work outside the browser, which prevents it being used in
tests.

We can replace it with `gloo-timers` wich uses the standard Javascript
`setTimeout`.
2023-02-13 12:41:36 +01:00
enterprisey e45bf9f9bd docs(sdk): Improve read receipt/marker explanation 2023-02-13 12:05:35 +01:00
Jonas Platte 3a516a5fce refactor(sqlite): Use internal Error in CryptoStore impl 2023-02-13 12:05:04 +01:00
Jonas Platte 9fc7d1c78b refactor(indexeddb): Use IndexeddbCryptoStoreError in CryptoStore impl 2023-02-13 12:05:04 +01:00
Jonas Platte c6f0e47077 refactor(crypto)!: Add an error type to the CryptoStore trait
This makes it easier to implement it. However, using a different error
type than CryptoStoreError is a non-trivial change, so left for the
coming commits for all stores except the memory store.
2023-02-13 12:05:04 +01:00
Kévin Commaille 96c796bb0e ci: Silence clippy::extra_unused_type_parameters in affected crates
Triggers false positives.
See discussion in https://github.com/rust-lang/rust-clippy/issues/10319.
Possibly fixed in https://github.com/rust-lang/rust-clippy/pull/10321.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-13 11:57:05 +01:00
Kévin Commaille 63fa645cea fix(indexeddb): Fix implementation of SafeEncode for tuple of 5 elements
Regression introduced by merging commit 9707d73 after efdeba7

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-13 11:57:05 +01:00
Kévin Commaille 0d4fac5962 test(base): Test collision between threaded and unthreaded receipts in store
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-12 11:04:26 +01:00
Kévin Commaille 2e497198f8 fix(stores): Separate receipts by thread
The key encoding in key-value stores is backwards-compatible so
old receipts are counted as unthreaded receipts.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-12 11:04:26 +01:00
Kévin Commaille 9707d73ead fix(indexeddb): Fix broken raw redacted state events
A fix for (de)serialization of redacted state events in Ruma made
old events undeserializable.
Bump the DB version.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-11 22:54:38 +01:00
Kévin Commaille 5ae84a9a80 fix(sled): Fix broken raw redacted state events
A fix for (de)serialization of redacted state events in Ruma made
old events undeserializable.
Bump the DB version.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-11 22:54:38 +01:00
Jonas Platte 57c3224b6b ci: Work around not being able to use matrix variables inside uses 2023-02-10 13:58:41 +01:00
Jonas Platte 4a5a0293a9 ci: Replace unmaintained actions-rs/cargo action
… we really didn't need it and can use run instead.
2023-02-10 13:58:41 +01:00
Jonas Platte 3f16b324d7 ci: Use taiki-e/install-action to install cargo-tarpaulin 2023-02-10 13:58:41 +01:00
Jonas Platte a5bfab1d55 ci: Replace unmaintained actions-rs/toolchain action
… with dtolnay/rust-toolchain.
2023-02-10 13:58:41 +01:00
Jonas Platte e430f65ce8 ci: Exclude Debug implementations from coverage reports
We don't really want to check for exact representations, and otherwise
they are really just invoked in tests that fail.
2023-02-10 13:46:00 +01:00
Jonas Platte 441626bf68 ci: Exclude uniffi-bindgen from coverage checks 2023-02-10 13:02:31 +01:00
Jonas Platte 02e51a9cb9 ci: Test sqlite crypto store in coverage check 2023-02-10 13:02:31 +01:00
Jonas Platte 4492df6fc6 test(sdk): Add a test for retrying edit decryption 2023-02-10 12:41:05 +01:00
Jonas Platte 573b672470 fix(sdk): Fix handling of UTD "insivible" events
(ones which don't produce a timeline item on their own)
2023-02-10 12:41:05 +01:00
Jonas Platte fe3c73602f refactor(sdk): Always add UTD events to the timeline
… as currently this is the only way decryption can be retried.
2023-02-10 12:41:05 +01:00
Jonas Platte fd2dc18746 refactor(sdk): Retry event decryption in timeline item order
This works better for relations.
2023-02-10 12:41:05 +01:00
Jonas Platte 55549f61be test(sdk): Split timeline tests into smaller modules 2023-02-10 12:41:05 +01:00
Jonas Platte cf359dede5 chore: Upgrade rust-cache GitHub action 2023-02-10 12:16:06 +01:00
Ivan Enderlin 13f50fbf6c fix(sdk): Remove Deref impl for SlidingSyncRoom
fix(sdk): Remove `Deref` impl for `SlidingSyncRoom`
2023-02-09 16:32:31 +01:00
Ivan Enderlin 0f7646ade1 chore: Make Clippy happy. 2023-02-09 16:16:31 +01:00
Ivan Enderlin 4e1fe3bec4 chore: Fix a function renaming. 2023-02-09 15:49:55 +01:00
Ivan Enderlin c6d99305d5 fix(labs): Fix jack-in. 2023-02-09 15:46:08 +01:00
Ivan Enderlin c86ebaddd2 Update crates/matrix-sdk/src/sliding_sync.rs
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-02-09 15:36:13 +01:00
Benjamin Kampmann 048d6a774c docs(sliding-sync): improved language
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2023-02-09 14:13:41 +01:00
Ivan Enderlin 43f2f60bfd fix(sdk): Remove Deref impl for SlidingSyncRoom.
This implementation is wrong in the sense of its semantics is not about
dereferencing a thin pointer to something, but just to give access to one
specific field of the entire structure. That's not how `Deref` is supposed to
be used.

Moreover, it creates conflict between the `SlidingSyncRoom.timeline` field,
and `SlidingSyncRoom.inner.timeline` field, which both exist, but not for the
same purposes. It creates confusion in the code.

Finally, it's better to expose proper getters to the outside world, so that we
control _and_ test _and_ know exactly what API we provide.
2023-02-09 13:09:22 +01:00
Gabriel Féron 12cbff2688 refactor(sdk): Use spawn_blocking when generating attachment thumbnails 2023-02-09 09:54:43 +01:00
Jonas Platte bdab40a772 refactor: Fix clippy lint str_to_string in sliding sync tests 2023-02-08 17:52:31 +01:00
Jonas Platte 87de9c7453 refactor(sled): Remove unused re-export 2023-02-08 17:52:31 +01:00
Benjamin Kampmann 765959758b docs(sliding-sync): Document cold-cache, reactive-api and bot-mode 2023-02-08 16:54:06 +01:00
Jonas Platte efdeba79f9 chore: Upgrade workspace dependencies 2023-02-08 16:04:29 +01:00
Jonas Platte e25061f8cb refactor(crypto)!: Unwrap unused Result 2023-02-08 16:04:29 +01:00
Jonas Platte 345f4f39f4 refactor(sqlite): Make Error more precise / useful 2023-02-08 15:44:17 +01:00
Jonas Platte e12b9e3027 refactor(sqlite): Encode olm hashes with rmp instead of serde_json
… like everything else in the sqlite crypto store.
2023-02-08 15:44:17 +01:00
Jonas Platte a22529344a refactor(sqlite): Inline inherent methods that duplicate trait methods 2023-02-08 15:44:17 +01:00
Jonas Platte 64b7c4eb59 refactor(sqlite): Make OpenStoreError more precise / useful 2023-02-08 15:44:17 +01:00
Jonas Platte 1988d1e9a3 refactor(sqlite): Move sqlite extension traits to utils module 2023-02-08 15:44:17 +01:00
Jonas Platte efc2397267 refactor(sqlite): Always use rusqlite::Error for sqlite extension traits 2023-02-08 15:44:17 +01:00
Jonas Platte ecb521205f refactor(sqlite): Move error types into new error module 2023-02-08 15:44:17 +01:00
Jonas Platte 7db40746bb refactor(sqlite): Start cleaning up cfg attributes 2023-02-08 15:44:17 +01:00
Benjamin Kampmann 3639215d53 docs(sliding-sync): long polling and quick refreshing explained 2023-02-08 13:29:38 +01:00
Benjamin Kampmann d51e9694f6 fix(sliding-sync): Set as default view mode 2023-02-08 12:43:32 +01:00
Jonas Platte ae21a56be2 chore: Add missing copyright headers 2023-02-08 11:15:02 +01:00
Kévin Commaille c252b984e0 refactor(sdk): Use a builder pattern to construct Timeline
`Timeline::with_fully_read_tracking` was public although all public
Timeline constructors enable it by default.
It is also meant to be called when constructing the timeline so
using a builder pattern makes sense.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-08 10:46:59 +01:00
Benjamin Kampmann 300fdec83f docs(sliding-sync): First half of sliding sync API docs 2023-02-07 22:41:58 +01:00
Jonas Platte ee9d47f647 refactor(crypto): Remove confusing explicit Sized bound
The bound is there by default, no need to put it in explicitly.
2023-02-07 18:45:32 +01:00
Jonas Platte 2e80073f28 refactor(crypto): Use IntoCryptoStore for OlmMachine::with_store 2023-02-07 18:45:32 +01:00
Jonas Platte c3d5932a0f refactor(crypto): Move store::{CryptoStoreError, Result} into new module 2023-02-07 18:45:32 +01:00
Doug 7fdccfcea4 chore(bindings): Rename property and use feature flag. 2023-02-07 15:22:39 +00:00
Doug 630836b3c7 chore(bindings): Store the proxy URL directly in Client. 2023-02-07 15:22:39 +00:00
Doug 3705925a22 chore(bindings): Persist the sliding sync proxy.
Added to the Session for automatic restoration.
2023-02-07 15:22:39 +00:00
Doug b7a3ab7c5b feat(ffi): Sliding sync proxy discovery. 2023-02-07 15:22:39 +00:00
Jonas Platte 5692480112 refactor(crypto): Remove unused method 2023-02-07 15:59:19 +01:00
Jonas Platte 5b63bd4cf1 refactor(crypto): Reduce direct visibility of some internal types
They weren't being exported from any public modules before.
This helps human readers as well as some compiler lints.
2023-02-07 15:59:19 +01:00
Jonas Platte 9711e1b2f5 refactor(crypto): Move (Into)CryptoStore traits into a new module 2023-02-07 15:59:19 +01:00
Damir Jelić a17346158f docs(sdk): Fix the sliding sync builder example 2023-02-07 14:26:33 +01:00
Damir Jelić 30ddbab686 refactor(sdk): Move the bulk of the sliding sync logic into a sync_once method 2023-02-07 14:26:33 +01:00
Jonas Platte b436918cb3 fix(sqlite): Fix Debug output for SqliteCryptoStore 2023-02-06 17:08:21 +01:00
Jonas Platte b20424b8b5 chore(sqlite): Undo weird formatting of TOML file 2023-02-06 17:08:21 +01:00
Ivan Enderlin 5f933b1033 feat(sdk): Simplify code by using std::cmp::min
feat(sdk): Simplify code by using `std::cmp::min`
2023-02-06 14:46:46 +01:00
Ivan Enderlin 5e8224f19c feat(sdk): Simplify code by using std::cmp::min. 2023-02-06 13:43:01 +01:00
Damir Jelić e68134dd53 chore(crypto): Improve the logs for the OlmMachine constructor 2023-02-06 13:31:00 +01:00
Damir Jelić 945c16a7fb feat(crypto): Throw an error if our user/device pair isn't what we have in the store 2023-02-06 13:31:00 +01:00
dependabot[bot] fc8cd2e7e5 chore(deps): bump tokio from 1.24.1 to 1.24.2
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.24.1 to 1.24.2.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/commits)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-04 08:27:50 +01:00
Damir Jelić 4115975135 fix(bindings): Expose the OpenTelemetry logging for other platforms as well 2023-02-03 22:30:11 +01:00
Damir Jelić 35a26be7b0 chore(sdk): Record the sliding sync pos in our logs 2023-02-03 16:51:33 +01:00
Jonas Platte 052832b4d3 fix: Don't log raw events that fail deserialization
… but do log relevant parts to allow debugging.
2023-02-03 14:35:10 +01:00
Richard van der Hoff e516e15d2b matrix-sdk-crypto-js v0.1.0-alpha.4
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 31s
2023-02-03 12:17:37 +01:00
Ivan Enderlin 2bc9407563 feat(sdk): Remove SlidingSyncView.rooms
feat(sdk): Remove `SlidingSyncView.rooms`
2023-02-03 11:51:25 +01:00
Jonas Platte 47f8b6cb79 feat(ffi): Add Room::fetch_members 2023-02-02 17:48:26 +01:00
Jonas Platte e11dd099d8 feat(sdk): Add Timeline::fetch_members 2023-02-02 17:48:26 +01:00
Jonas Platte c294a376e8 refactor(sdk): Use TimelineDetails for sender profile 2023-02-02 17:48:26 +01:00
Jonas Platte ffa0190517 refactor(sdk): Add missing feature-gate
… for fn that is only used from sliding-sync.
2023-02-02 17:48:26 +01:00
Jonas Platte 3a863fa8fb refactor(sdk): Remove unnecessary inner block in function 2023-02-02 17:48:26 +01:00
ganfra 75d396e2ec Merge branch 'main' into ganfra/kotlin_binding_scripts 2023-02-02 17:10:34 +01:00
Ivan Enderlin 672a640854 chore(labs): Update to later changes. 2023-02-02 15:27:18 +01:00
Ivan Enderlin 40010cd511 Merge branch 'main' into feat-sliding-sync-view-rooms 2023-02-02 15:26:30 +01:00
Ivan Enderlin a6d33fcd16 feat(labs): Update jack-in to the new sliding sync room API. 2023-02-02 15:22:41 +01:00
Ivan Enderlin d08606e3b9 feat(sdk): SlidingSync::get_room now takes a ref to OwnedRoomId
feat(sdk): `SlidingSync::get_room` now takes a ref to `OwnedRoomId`.
2023-02-02 14:06:14 +01:00
Ivan Enderlin ae8a8c6cc3 feat(sdk): SldingSync::get_room takes a &RoomId. 2023-02-02 13:36:32 +01:00
Ivan Enderlin 0d87d0f786 feat(sdk): Remove SlidingSyncView.rooms.
`SlidingSyncView` exposes a `room` field. Problem: It's not updated
correctly and leads to error. The canonical way to get a room is by using
`SlidingSync::get_room`. This patch thus removes `SlidingSyncView.rooms`
entirely.
2023-02-02 13:31:46 +01:00
Ivan Enderlin a9ba2dd546 feat(sdk): SlidingSync::get_room now takes a ref to OwnedRoomId.
Before this patch, `SlidingSync::get_room` was taking ownership of an
`OwnedRoomId`, to only use it as a reference. Thus, calling this method was
creating useless clones.

This patch updates `SlidingSync::get_room` to receive a reference to
`OwnedRoomId`.
2023-02-02 13:25:36 +01:00
Kévin Commaille 00638ba74c feat(sdk): Allow to fetch replied to messages
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-02-02 13:06:11 +01:00
ganfra 6a7b28c085 Merge branch 'main' into ganfra/kotlin_binding_scripts 2023-02-02 11:52:32 +01:00
ganfra 1bcd8c7aae Comment remove gradle_build 2023-02-02 11:50:47 +01:00
Jonas Platte ce973b35e9 chore: Upgrade uniffi to 0.23.0 2023-02-02 10:15:05 +01:00
Jonas Platte 8a1b1eccd6 doc(sdk): Fix docs that refer to TimelineKey 2023-02-02 10:15:05 +01:00
Jonas Platte e068b4987e doc(sdk): Document what happens when timeline event sending fails 2023-02-02 10:14:23 +01:00
Jonas Platte 3a1eb62c38 refactor(sdk): Expose event sending errors through timeline item
… instead of through the return value of Timeline::send.
2023-02-02 10:14:23 +01:00
Jonas Platte c8021cf2ba refactor(sdk): Move LocalEventTimelineItem#event_id into send_state 2023-02-02 10:14:23 +01:00
Jonas Platte a48fd77c4a refactor(sdk): Rename LocalEventTimelineItemSendState => EventSendState 2023-02-02 10:14:23 +01:00
Damir Jelić ab0e27622e feat(bindings): Add support to setup a OpenTracing based logger 2023-02-01 22:55:47 +01:00
Damir Jelić 7b044ef5dd fix(crypto): Ignore the usage and signatures when comparing cross signing keys
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-02-01 18:25:48 +01:00
Benjamin Kampmann 8a9b72ae6c test(sliding-sync): ensure unknown pos does recover the room subscription properly 2023-02-01 17:37:16 +01:00
Anderas e9cef35f99 Add matrix-sdk-sqlite with a CryptoStore implementation
Note about "Write-Ahead Log" (WAL) mode: The SQLite WAL mode has a
bunch of advantages that are quite nice to have:

1. WAL is significantly faster in most scenarios.
2. WAL provides more concurrency as readers do not block writers and a
   writer does not block readers. Reading and writing can proceed
   concurrently.
3. Disk I/O operations tends to be more sequential using WAL.
4. WAL uses many fewer fsync() operations and is thus less vulnerable
   to problems on systems where the fsync() system call is broken.

The downsides of WAL mode don't really affect us. So let's turn it on.

More info: https://www.sqlite.org/wal.html

Co-authored-by: Jonas Platte <jplatte@matrix.org>
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-02-01 15:06:59 +01:00
Damir Jelić 3a183b4c22 chore(sdk): Tweak the instrumentation for some encryption related methods 2023-02-01 10:16:14 +01:00
Richard van der Hoff 5dbee7dcdc fix(indexeddb): correctly encode Olm session keys
When we store an Olm session in the database, we encode the sender key and
session ID using the store cipher. That means that we also need to encode them
when we look them up, otherwise we won't find them.
2023-01-31 16:59:22 +01:00
Benjamin Kampmann b9b00743c9 fix(sliding-sync): catching up on new count for full-sync views 2023-01-31 15:02:19 +00:00
Benjamin Kampmann 14be1f888a test(sliding-sync): integration test for UnknownPos 2023-01-31 15:02:19 +00:00
Benjamin Kampmann a77295120a fix(sliding-sync): fixing restarting growing view 2023-01-31 15:02:19 +00:00
Benjamin Kampmann a6ad0e35b3 style(sliding-sync): improved style and docs 2023-01-31 14:03:43 +00:00
Benjamin Kampmann 5b3ec33ddc chore: Update to specific, supported ruma and sliding-sync-proxy-version. 2023-01-31 14:03:43 +00:00
Benjamin Kampmann aa10e70851 feat(sliding-sync): enable gzip when enabling sliding-sync 2023-01-31 14:03:43 +00:00
Benjamin Kampmann 826b2874ec ffi: expose sliding sync extension enabling 2023-01-31 14:03:43 +00:00
Benjamin Kampmann 8f17b6c38d feat(sliding-sync): add Receipt and Typing extension config 2023-01-31 14:03:43 +00:00
Benjamin Kampmann 9ae9c98340 test(sliding-sync): activate live views test 2023-01-31 14:03:43 +00:00
Benjamin Kampmann f6da282557 feat(sliding-sync): add delta-token support 2023-01-31 14:03:43 +00:00
Benjamin Kampmann 9ad34e8565 chore(sliding-sync): update to latest sliding-sync JSON layout 2023-01-31 14:03:43 +00:00
Benjamin Kampmann a973c372e6 chore: use local volumes for testing server 2023-01-31 14:03:43 +00:00
Ivan Enderlin 00e93e08e7 feat(sdk): Add EventTimelineItem::unique_identifier. 2023-01-31 13:21:19 +01:00
Kévin Commaille 75a2d2d92c fix(sdk): Aggregate reactions locally
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-31 12:11:44 +00:00
Jonas Platte e066346b16 feat(bindings): Clear the timeline when sliding-sync loop is reset 2023-01-31 11:49:25 +01:00
Jonas Platte 754453c135 refactor: Import tracing macros instead of using qualified paths 2023-01-31 11:49:25 +01:00
Jonas Platte c481caf060 refactor: Clean up format strings 2023-01-31 11:49:25 +01:00
Jonas Platte 6d868908cb refactor(sdk): Remove unused Result 2023-01-31 11:49:25 +01:00
Jonas Platte d2678e2f01 refactor(sdk): Remove unused async 2023-01-31 11:49:25 +01:00
Jonas Platte c24316e5e3 refactor(sdk): Remove unused lifetime parameter 2023-01-31 11:49:25 +01:00
Jonas Platte 48bc5b9b7e refactor(sdk): Work around receiving event with txn-id multiple times 2023-01-30 20:12:44 +01:00
Jonas Platte 01c828ed4b chore(sdk): Remove weird space 2023-01-30 20:12:44 +01:00
Benjamin Kampmann 102994b030 feat(sliding-sync): allow updating the timeline limit at runtime 2023-01-30 16:05:19 +00:00
Ivan Enderlin 38dfa90441 feat(sdk): LocalEventTimelineItem has a new send_state field
feat(sdk): `LocalEventTimelineItem` has a new `send_state` field
2023-01-30 14:08:47 +01:00
Ivan Enderlin 274bc20603 doc(sdk): Fix typos. 2023-01-30 13:58:00 +01:00
Ivan Enderlin c8d561d17d feat(ffi): Add LocalEventTimelineItemSendState + EventTimelineItem::local_send_state. 2023-01-30 13:51:29 +01:00
Ivan Enderlin 8ea2cef55d feat(sdk): LocalEventTimelineItem has a new send_state field.
This patch is trying to resolve the following issue:

When a local event is sent to the server, in case of an error, the
`Timeline::send` method just returned the error but it wasn't reflected inside
the `LocalEventTimelineItem` type itself. It's easy to loss this information.

So now, there is a new enum: `LocalEventTimelineItemSendState` with 3 states:

1. `NotSentYet`, when the local event has not been sent yet, it's theorically
   the initial state,
2. `SendingFailed`, when the local event has been sent but it's failed!
3. `Sent`, when the local event has been sent successfully.

Therefore, the `LocalEventTimelineItem` struct has a new field: `send_state`.

The send state is managed by its `with_event_id` method which now receives an
`Option<OwnedEventId>` (prev. `OwnedEventId` directly):

* If it's `Some(_)`, then it means we got a successful response from the server
  after the sending, so the send state is set to `Sent`,
* If it's `None`, then it means we got an error response from the server, so
  the send state is set to `SentFailed`.

(A small change: The method `TimelineInner::add_event_id` has been renamed
`TimelineInner::update_event_id_of_local_event`.)

The `Timeline::send` still returns a `Result`, but the server's response is
passed to a new method: `TimelinerInner::handle_local_event_send_response`
(it's logically named after the `handle_local_event` method), which is
responsible to call `TimelineInner:update_event_id_of_local_event` (which was
previously called directly by `Timeline::send`).

And `TimelineInner::update_event_id_of_local_event` was already calling
`LocalEventTimelineItem::with_event_id`. So everything works like a charm here.

The local send state is closely managed by `LocalEventTimelineItem`, I hope it
will avoid state breakage as much as possible.
2023-01-30 11:47:38 +01:00
Ivan Enderlin 4086492ef9 feat(sdk): EventTimelineItem is now an enum … { Local(…), Remote(…) }
feat(sdk): `EventTimelineItem` is now an `enum … { Local(…), Remote(…) }`
2023-01-30 11:03:49 +01:00
Ivan Enderlin 6bfa3df691 chore(sdk): Replace ref by &. 2023-01-30 10:20:44 +01:00
Ivan Enderlin f4607146e2 chore(sdk): Replace ref by &. 2023-01-30 10:13:54 +01:00
Ivan Enderlin 0a7193de62 chore(sdk): Remove useless custom Debug impl. 2023-01-30 09:30:12 +01:00
Ivan Enderlin 5c2e6b2743 chore(sdk): Simplify code. 2023-01-30 08:58:26 +01:00
Ivan Enderlin 47256eb4f9 chore(sdk): Remove a warning for an unused variable. 2023-01-30 08:50:47 +01:00
Ivan Enderlin 1c8d57321c chore(sdk): Remove Flow.timestamp and .raw_event. 2023-01-30 08:50:08 +01:00
Ivan Enderlin 322aa776f2 feat(sdk): Remove LocalEventTimelineItem.encryption_info and .raw, and Remote….raw is no more an Option. 2023-01-30 08:49:48 +01:00
ganfra 517b71cb06 kotlin bindings: replace shell by xtask scripts 2023-01-27 16:29:44 +01:00
Ivan Enderlin 17a9c4829d chore(sdk): Make Clippy happy. 2023-01-27 15:25:37 +01:00
Ivan Enderlin 59a5805af7 chore(sdk): Remove commented code. 2023-01-27 15:14:10 +01:00
Ivan Enderlin 882f3cad25 chore(sdk): Simplify code by using Into<EventTimelineItem> for LocalEventTimelineItem`. 2023-01-27 15:12:38 +01:00
Ivan Enderlin 5ce3c45637 chore(sdk): Simplify code by importing a type. 2023-01-27 15:07:42 +01:00
Ivan Enderlin ab617ddda0 chore(sdk): Fix a typo in an error message. 2023-01-27 15:05:27 +01:00
Ivan Enderlin 3a1c5580e7 chore(sdk): Fix a typo in an error message. 2023-01-27 15:03:49 +01:00
Ivan Enderlin 8486976804 feat(ffi): Update EventTimelineItem::reactions to return an Option. 2023-01-27 14:59:47 +01:00
Ivan Enderlin 8f13bb5ca5 feat(ffi): Add the EventTimelineItem::is_local and is_remote method. 2023-01-27 14:59:27 +01:00
Ivan Enderlin 7257cff5fe docs: Add the ffi scope. 2023-01-27 14:58:54 +01:00
Ivan Enderlin eb47869a45 feat(ffi): Remote TimelineKey. 2023-01-27 14:58:34 +01:00
Ivan Enderlin 636f4f8f8d feat(sdk): Remove the TimelineKey type. 2023-01-27 14:41:01 +01:00
Damir Jelić 819f962419 fix(sdk): Retry decryption if you initialize a Timeline with some events
The sliding sync logic has another room type called `SlidingSyncRoom`.

This room type stores a limited amount of events in something called
`AliveRoomTimeline` in a in-memory cache. This room also gets persisted
to the store via another room type called `FrozenSyncRoom`.

These types are used when clients restore their view of the room, i.e.
when the user enters the room to look at messages.

When the client enters a room, a `Timeline` object will be created, but
it will be initially populated with events coming from
`AliveRoomTimeline`.

In a hot potato contest of who should be responsible to decrypt injected
events, everybody claims to be allergic to potatoes.

This patch modifies the `Timeline` constructor that populates the
timeline with events from the `AliveTimeline` to retry decryption on the
events that the `AliveTimeline` pushes into the `Timeline`.

Note that, because the `AliveRoomTimeline` never replaces encrypted
events with decrypted ones, every time the client enters/exits the room
events well get re-decrypted.
2023-01-27 14:07:41 +01:00
Ivan Enderlin 3c9e84397a test(sdk): Update tests since the new EventTimelineItem type. 2023-01-27 14:00:41 +01:00
Ivan Enderlin f7bf6ba220 feat(sdk): Rewrite EventTimelineItem as an enum: Local and Remote. 2023-01-27 13:26:31 +01:00
Denis Kasak 539cbee087 test(crypto): Test failure when deserializing cross-signing keys with incorrect usage. 2023-01-26 17:01:00 +01:00
Damir Jelić d442cac936 refactor!(crypto): Directly deserialize into per usage cross signing key type
This moves the usage checking directly into our deserialization path.
2023-01-26 17:01:00 +01:00
Damir Jelić 72ed024303 fix(crypto): Make sure the master key self-signs as well
This is an omission from the spec where the subkeys are supposed to be
signed by the master key, but signing the master key wasn't mentioned.

This is still fine, since we always treated the master key and their
subkeys as a whole and never accepted one without the others.
2023-01-26 17:01:00 +01:00
Damir Jelić 148c4907b5 fix(crypto): Inspect the key usage when receiving cross signing keys 2023-01-26 17:01:00 +01:00
Ivan Enderlin 8c91314b58 feat(sdk): Move EventTimelineItem.event_id into TimelineKey::TransactionId
feat(sdk): Move `EventTimelineItem.event_id` into `TimelineKey::TransactionId`
2023-01-26 15:07:40 +01:00
Ivan Enderlin 9006bd1bba chore(sdk): Address review feedback. 2023-01-26 14:55:16 +01:00
Kévin Commaille 32e7209c66 refactor(sdk): Split room member events between membership and profile change
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-26 14:24:59 +01:00
Ivan Enderlin 4dfa41ce8f doc(sdk): Simplify if let into let
doc(sdk): Simplify `if let` into `let`
2023-01-26 14:24:35 +01:00
Ivan Enderlin 1a5ead58f6 feat(sdk): Move EventTimelineItem.event_id into TimelineKey::TransactionId.
To create an event next to the server, the event must be accompanied by
a transaction ID. When the server receives the event creation request, it
responds with a new event ID (which we will name `event_id_1`). Later on, when
a sync is done to the server, the server may respond with the transaction ID
and a new event ID (which we will name `event_id_2`).

The transaction ID is used to update the state of the local event. The event
ID received from the sync may ideally be the same as the one received by the
creation request's response.

Knowing that…

`EventTimelineItem` had a field: `event_id: Option<OwnedEventId>`. It was
`Some(event_id)` where `event_id` is the event ID responded by the server when
an event was created, i.e. it's `event_id_1`; otherwise it was `None`. This is
never `event_id_2`. Why?

Because `EventTimelineItem` has an other field: `key: TimelineKey`, which
represents the following states:

* `TimelineKey::TransactionId(OwnedTransactionId)`,
* `TimelineKey::EventId(OwnedEventId)`, where the event ID is `event_id_2`!

So it becomes obvious that `event_id_1` should be part of `TimelineKey`, not
`EventTimelineItem`. `TimelineKey` is where this transaction ID and event ID
logic is managed.

This patch updates `TimelineyKey::TransactionId` to be defined as:

* `TimelineKey::TransactionId { txn_id: OwnedTransactionId, event_id: Option<OwnedEventId> }`.

Why an `Option`? Because before receiving `event_id_1`, we may still want to
create a `TimelineKey`, the API must reflect that state.

So basically, `EventTimelineItem.event_id` is moved inside
`TimelineyKey::TransactionId`.
2023-01-26 11:36:42 +01:00
Jonas Platte 220617fd04 fix(sdk): Update add_event_id logs to make more sense 2023-01-26 10:59:28 +01:00
Jonas Platte a37ce68eae fix(sdk): Only look for local echoes for events appended to the timeline
… rather than prepended, or added at a specific point as replacement for
an existing timeline item.
Previously, we would log lots of useless tracing events when retrying to
decrypt UTD items.
2023-01-26 10:55:41 +01:00
Ivan Enderlin 0c4ca84eec test(sdk): Improve m.fully_read test coverage and documentation
test(sdk): Improve `m.fully_read` test coverage and documentation
2023-01-26 10:16:48 +01:00
Ivan Enderlin 77b7451f59 doc(sdk): Fix a typo. 2023-01-26 10:06:11 +01:00
Ivan Enderlin bac105a9aa doc(crypto-nodejs): Fix a typo. 2023-01-26 09:59:15 +01:00
Ivan Enderlin 832bba8a2b test(sdk): Improve m.fully_read test coverage and documentation. 2023-01-26 09:46:47 +01:00
Jonas Platte 0e39a7cbf2 chore: Upgrade Ruma 2023-01-25 18:01:12 +01:00
Jonas Platte db11940f8f test(sdk): Fix clippy warning 2023-01-25 18:01:12 +01:00
Damir Jelić 4ef654f1d1 chore: Bump the Ruma version 2023-01-25 18:01:12 +01:00
Ivan Enderlin 793e18e44f Merge pull request #1388 from matrix-org/release-matrix-sdk-crypto-js-v0.1.0-alpha.3
Release matrix-sdk-crypto-js v0.1.0-alpha.3
2023-01-25 12:56:41 +01:00
Ivan Enderlin 578b446ea4 chore(sdk): Rename a variable to clarify its content. 2023-01-25 11:00:03 +01:00
Ivan Enderlin 3fe5f13df4 doc(sdk): Simplify if let into let. 2023-01-25 10:58:46 +01:00
Ivan Enderlin 54f00dc05a feat(crypto-nodejs) Implement OlmMachine.close.
This patch fixes https://github.com/matrix-org/matrix-rust-sdk/issues/1379/.

This is similar to https://github.com/matrix-org/matrix-rust-sdk/pull/1197/.
We need to close the `OlmMachine`. Problem, `napi-rs` doesn't allow methods to
take ownership of `self`, so the following code:

```rs
fn close(self) {}
````

isn't allowed. There an [`ObjectFinalize`](https://docs.rs/napi/latest/napi/bindgen_prelude/trait.ObjectFinalize.html)
trait, but it's only called when the JS value is being collected by the GC.
It's not possible to force call `finalize` here.

This patch then introduces a new type:

```rs
enum OlmMachineInner {
  Opened(matrix_sdk_crypto::OlmMachine),
  Closed
}
```

that derefs to `matrix_sdk_crypto::OlmMachine` when its variant is `Opened`,
otherwise it panics. Calling the new `OlmMachine::close` method will change the
inner state from `Opened` to `Closed`.

Ideally, I wanted to throw an error instead of panicking, but `napi_env`
(used to build an `Env`, used to throw an error) is neither `Sync` nor `Send`.
Honestly, my knowledge of NodeJS and NAPI is too weak to implement `Sync`
and `Send` for `*mut napi_env__` safely. Especially because it can be executed
from various threads within `async fn` functions, that are driven by Tokio in
`napi-rs`. So, yeah, for the moment, it panics!
2023-01-25 09:56:21 +01:00
Benjamin Kampmann 464e40bc32 fix(ffi): add erroneously removed loop 2023-01-24 15:41:12 +00:00
Benjamin Kampmann f22660d5e9 chore(sliding-sync): more logging information 2023-01-24 15:41:12 +00:00
Andy Uhnak 2db1bc75c1 Expose MissingRoomKey decryption error 2023-01-24 16:27:02 +01:00
Damir Jelić 18ec101719 refactor!(crypto): Move some caches out of the CryptoStore implementations
This moves the caches we have for tracked users out of the Sled, and
IndexedDB, CryptoStore into the Store struct. The Store struct is a
wrapper for the CryptoStore trait, so this is the natural place where
these caches should live.

Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-01-24 15:26:33 +00:00
Doug a762b2027f feat(bindings): Expose aliases to the FFI. 2023-01-24 16:12:39 +01:00
Jonas Platte 934181be44 refactor(sdk): Update confusing variable names 2023-01-24 13:43:55 +01:00
Jonas Platte 3d34743ae9 fix(sdk): Respect server ordering for remote echoes 2023-01-24 13:43:55 +01:00
Kévin Commaille 718864bfdd refactor(sdk): Provide day divider as a timestamp
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-24 12:29:15 +01:00
Benjamin Kampmann 24ac5b9f16 feat(sliding-sync): add configuration to inform about room changes without positional update 2023-01-24 10:30:07 +00:00
Benjamin Kampmann cc835da347 fix(sliding-sync): refresh timeline if server told us we are limited 2023-01-24 10:30:07 +00:00
Benjamin Kampmann 933eec2d1d fix(sliding-sync): switch Atomic Ordering from Relaxed to SeqCst 2023-01-24 10:30:07 +00:00
Benjamin Kampmann de4a8e3e7a chore(base): additional tracing information for sliding sync responses 2023-01-24 10:30:07 +00:00
Benjamin Kampmann b08c740181 fix(ffi): don't cancel the actual spawn, instead ensure it finishes processing before stopping the loop 2023-01-24 10:30:07 +00:00
Benjamin Kampmann 950bb83f8d style: use trace! instead of tracing::trace! 2023-01-24 10:30:07 +00:00
Benjamin Kampmann a06aa43dd1 feat(sliding-sync): cache room data next to view for selective unfreezing 2023-01-24 10:30:07 +00:00
Benjamin Kampmann a572f61edf tests: additional ignored tests for future scenarios 2023-01-24 10:30:07 +00:00
Benjamin Kampmann a964585e35 fix(sliding-sync): have views go live right at response processing 2023-01-24 10:30:07 +00:00
Benjamin Kampmann 71407a636c fix(sliding-sync): use single replace on cold and empty views
Before we'd push one empty entry at a time, which lead to a lot of vecdiff updates pushed. With this
we now only push one  event after the entire operation set has been applied on the fresh
or cold view.
2023-01-24 10:30:07 +00:00
Benjamin Kampmann b7a8a93a73 chore(sliding-sync): additional tracing around unfreezing from cold cache 2023-01-24 10:30:07 +00:00
Damir Jelić 600fd62dc5 crypto(fix): Fail to decrypt if there's a key mismatch
A mismatch between the recorded Ed25519 and Curve25519 keys of the room
key and the identity keys of a Device used to be just a warning.

Considering that many clients will aggressively try to hide E2EE related
warnings let's upgrade this clear error into a full blown decryption
failure.

Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-01-24 09:14:42 +01:00
Damir Jelić 00d1437e5a chore(crypto): Log the full error messages when decrypting room events 2023-01-23 15:03:03 +01:00
Damir Jelić f774159e15 chore(crypto): Record the event id when decrypting a room event 2023-01-23 15:03:03 +01:00
Damir Jelić a1fba86f75 chore(crypto): Log the session id when we receive a room key 2023-01-23 15:03:03 +01:00
Damir Jelić 3c4d1cfb47 fix(sled): Don't load the tracked users with the Account
We might have a lot of tracked users, clients will usually have 1-10
thousand tracked users. This might slow down client startup if there are
so many tracked users.

We don't need the tracked users until we sync or try to send a message,
so load them lazily when they are first needed.
2023-01-23 13:35:51 +01:00
Damir Jelić 3ab95c74c7 refactor!(crypto): Make the methods related to tracked users async 2023-01-23 13:35:51 +01:00
Damir Jelić 8c1a81eebc chore: Fix the conventional commit type for documentation
The conventional commit specification recommends the "docs" type for
documentation related changes. This also matches the initial usage of
this type in our commit history.

While the default git-cliff config does specify a regex "^doc", where I
suspect our types have been taken from, this regex actually allows "doc"
as well as "docs" for the type.

Nevertheless, let's specify that we're using the one recommended in the
spec.
2023-01-20 20:30:06 +01:00
Richard van der Hoff acfa8a4190 docs(bindings): Fix return type documentation for get_missing_sessions 2023-01-20 20:09:42 +01:00
Richard van der Hoff 0771d73543 matrix-sdk-crypto-js v0.1.0-alpha.3
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 46s
2023-01-20 17:37:49 +00:00
Richard van der Hoff 92546acc85 chore(crypto-js): configuration for 'yarn version' 2023-01-20 17:37:40 +00:00
Richard van der Hoff c7f258d8b0 doc: Improve the documentation of "tracked users"
I had no idea what a tracked user was, so I've attempted to clarify this
somewhat for future readers.

Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-01-20 14:02:02 +01:00
Jonas Platte 1e2fd02478 doc(base): Explain purpose of BaseClient#crypto_store 2023-01-20 10:56:09 +01:00
Stefan Ceriu b0c70dc606 chore(bindings): Exclude the target folder from the debug swift package
… to improve package loading time.
2023-01-20 09:00:36 +00:00
Benjamin Kampmann 0fea33de4d feat(ffi): expose server_versions on ClientBuilder 2023-01-19 21:31:57 +00:00
Damir Jelić 053b609899 chore(sdk): Add a prefix to the request id to make it easier to grep for them 2023-01-19 15:47:08 +01:00
Damir Jelić a54a421f91 chore(sdk): Log the response/request sizes as well 2023-01-19 15:46:49 +01:00
Ivan Enderlin 78147e0d33 doc(crypto-js): Fix wording. 2023-01-18 17:22:02 +01:00
Ivan Enderlin 430c573494 feat(crypto-nodejs): Request types have more fields.
Instead of putting all request fields inside a single `body` JSON-
encoded string  field, there is now more types. There is less need to call
`JSON.parse`, and the type system will be able to catch more things.

For example, `ToDeviceRequest` now has 2 more fields: `event_type` and
`txn_id`.
2023-01-18 17:21:52 +01:00
Ivan Enderlin 9db09e22b2 feat(crypto-js): Request types have fields extracted from their “body” directly
feat(crypto-js): Request types have fields extracted from their “body” directly
2023-01-18 13:41:14 +01:00
Ivan Enderlin 94fadf74b9 feat(crypto-js): Rename RoomMessageRequest.content to .body. 2023-01-18 13:31:26 +01:00
Ivan Enderlin 7c01f8490f test(crypto-js): Test `RoomMessageRequest.content. 2023-01-18 13:14:06 +01:00
Ivan Enderlin ca00112804 test(crypto-js): Add test for in-room verification (w/ RoomMessageRequest). 2023-01-18 11:42:34 +01:00
Benjamin Kampmann 6c0ef2db51 refactor(ffi): refactor stoppable spawn to be more token-oriented 2023-01-18 10:08:58 +00:00
Benjamin Kampmann 938a03867b feat(ffi): add subscribe_and_add_timeline_listener helper fn
re-applying the fixes from ##1346
2023-01-18 10:08:58 +00:00
Ivan Enderlin 90cce1a47c chore(crypto-js): Improve documentation, and do a little clean up. 2023-01-18 10:58:59 +01:00
Ivan Enderlin c427caf473 feat(crypto-js): Rename requests extra field to body. 2023-01-18 10:58:59 +01:00
Ivan Enderlin 3ad675db5c feat(crypto-js): Extract RoomMessageRequest.event_type from EventContent. 2023-01-18 10:58:59 +01:00
Ivan Enderlin efde81646b feat(crypto-js): Extract RoomMessageRequest.content as a JSON-encoded string. 2023-01-18 10:58:59 +01:00
Ivan Enderlin 8f9859c41c feat(crypto-js): Rename the body fields to extra to avoid confusion with HTTP terminology. 2023-01-18 10:58:58 +01:00
Ivan Enderlin 6248e2bc68 test(crypto-js): Update tests according to previous commit. 2023-01-18 10:58:58 +01:00
Ivan Enderlin c0ccd55df8 feat(crypto-js): request! differentiates “extracted” and “grouped” fields. 2023-01-18 10:58:58 +01:00
Ivan Enderlin b125b2e9da test(crypto-js): Update tests according to previous commit. 2023-01-18 10:58:58 +01:00
Ivan Enderlin 3c838b2f4a feat(crypto-js): Request types have fields from their “body” directly. 2023-01-18 10:58:58 +01:00
Jonas Platte f4fba3efb7 fix(bindings): Add user_id to RoomMembership
Without that, it is useless.
2023-01-18 09:58:36 +01:00
Jonas Platte e64b2f65da Revert "refactor(bindings): Fetch latest event earlier"
This reverts commit 7d1372195cf2af56c3d8ef95ac1b183ace8a5eec.
2023-01-18 09:31:45 +01:00
Doug 9e12a88e03 feat(bindings): Allow setting the store passphrase in the bindings
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-01-18 06:45:21 +00:00
Anderas 0af38d9a76 fix(crypto): Mark our own identity as verified if we have the private part of the identity
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2023-01-17 18:41:00 +00:00
Damir Jelić ade3a09848 chore(base): Remove a leftover unwrap 2023-01-17 19:13:29 +01:00
Damir Jelić 3641e0d540 docs(crypto): Note that the in-room verification events need to be decrypted 2023-01-17 18:11:53 +01:00
Damir Jelić e1d8c72d3a chore(crypto): Improve some docs
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-01-17 18:11:53 +01:00
Damir Jelić c8d9581f8b refactor!(crypto): Don't process in-room verification implicitly 2023-01-17 18:11:53 +01:00
Kévin Commaille 8cc632ffd1 feat(sdk): Add support for state events in the timeline
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-17 12:10:19 +01:00
Kévin Commaille 1b7f4b4b42 fix(test): Fix position of prev_content in JSON
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-17 12:10:19 +01:00
Damir Jelić 928871d16e chore(sdk): Log the request body for sliding sync requests 2023-01-16 17:02:46 +01:00
Damir Jelić 87f5b251f5 chore(sdk): Add a request id counter to our HTTP client
This solves the issue of correlating different log lines that are talking
about the same request/response cycle. Plaintext logs would show this as
a flat structure, while something like Jaeger would show you a nice
tree. This allows you to reconstruct the tree in plaintext logs.
2023-01-16 17:02:46 +01:00
Damir Jelić e76272a68b chore(sdk): Improve the HTTP request sending logs 2023-01-16 17:02:46 +01:00
Damir Jelić b30c74cb01 chore(crypto): Bump the to-device event logging to debug 2023-01-16 16:23:58 +01:00
Jonas Platte 686541155f feat(sdk): Add display_name_ambiguous to timeline::Profile 2023-01-16 15:35:29 +01:00
Jonas Platte b256b6f625 refactor(bindings): Fetch latest event earlier
Does this crash?
2023-01-16 15:35:29 +01:00
Jonas Platte 7b913a0759 feat(bindings): Add EventTimelineItem::sender_profile 2023-01-16 15:35:29 +01:00
Jonas Platte 9e60a9dd3f feat(sdk): Attach profile information to timeline items 2023-01-16 15:35:29 +01:00
Jonas Platte 00bdb08973 refactor(sdk): Move locking of timeline_items into handle_remote_event 2023-01-16 15:35:29 +01:00
Jonas Platte ed70ccb988 refactor(sdk): Add trait ProfileProvider for use in TimelineInner 2023-01-16 15:35:29 +01:00
Jonas Platte e52af8a315 refactor(sdk): Make TimelineInner fields private 2023-01-16 15:35:29 +01:00
Jonas Platte b5450ee5ad test(sdk): Simplify TestTimeline construction 2023-01-16 15:35:29 +01:00
Jonas Platte b105b34cf6 refactor(sdk): Use regular struct update syntax for EventTimelineItem
The previous solution was annoying to maintain and only more efficient
without compiler optimizations.
2023-01-16 15:35:29 +01:00
Jonas Platte e0b0b632ec chore: Fix a typo 2023-01-16 11:31:03 +01:00
Jonas Platte 4febe45364 refactor(base): Make AmbiguityChange(s) non-exhaustive
They are meant to be consumed, but not created, by other crates.
2023-01-16 11:31:03 +01:00
Jonas Platte 70de11a73a refactor: Remove unused Deserialize, Serialize implementations 2023-01-16 11:31:03 +01:00
Jonas Platte 58f2d53293 doc(sdk): Update spec link 2023-01-16 11:31:03 +01:00
Doug 6540b9bb49 feat(bindings): Expose read receipts to FFI 2023-01-16 10:58:40 +01:00
Jonas Platte 6c53842599 chore: Bump ruma, vodozemac 2023-01-16 10:34:06 +01:00
Jonas Platte 663d043abb refactor: Always use Debug for logging enum or identifier values 2023-01-16 10:34:06 +01:00
Damir Jelić 386cbce344 Revert "feat(ffi): add subscribe_and_add_timeline_listener helper fn"
This reverts commit ba4e304cad.
2023-01-13 14:55:39 +01:00
Damir Jelić ece9252a3d chore(crypto): Add the sender and event type to the to-device handling span 2023-01-13 12:46:07 +01:00
Damir Jelić c13cb4957e chore(crypto): Don't use a JsOption needlessly. 2023-01-13 12:46:07 +01:00
Damir Jelić 1f34a016e5 chore(crypto): Add the to-device message id to the logs if there is one 2023-01-13 11:58:42 +01:00
Damir Jelić b8dd704658 refactor(crypto): Move the to-device event handling into a separate method 2023-01-13 11:58:42 +01:00
Benjamin Kampmann 273e96265f Merge pull request #1335 from gnunicorn/ben-sliding-sync-integration-test
Various smaller fixes on sliding-sync for elem-x:

 - Infrastructure and smoke test only for integration testing sliding-sync
 - Expose Pop and Clear on VecDiff
 - Expose adding views during sliding sync live runtime incl integration tests
 - bug fix on replacing only in-window-items in the insert-code (was leading to a wrong list setting), including integration test
2023-01-13 10:11:30 +00:00
Jonas Platte 0e3ea58aa4 Revert unrelated change 2023-01-13 10:51:52 +01:00
Benjamin Kampmann ba4e304cad feat(ffi): add subscribe_and_add_timeline_listener helper fn 2023-01-13 08:09:10 +00:00
Benjamin Kampmann 723e3a3135 tests(sliding-sync): minor style improvements 2023-01-12 19:53:57 +01:00
Kévin Commaille 1c754e663d fix(sdk): Make pagination strategy implement Send
Required when `PaginationOptions` must implement `Send`,
e.g. with `tokio::runtime::Runtime::spawn`.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-12 19:24:47 +01:00
Damir Jelić 846844e67b fixup! chore(sdk): Re-export the AmbiguityChange type 2023-01-12 19:12:01 +01:00
Damir Jelić 51d96213ba chore(sdk): Re-export the AmbiguityChange type
This was forgotten to be re-exposed after it was moved to the base
crate.
2023-01-12 19:12:01 +01:00
Damir Jelić 80868919ae fix(crypto): Make the device update logic a bit more strict and obvious
When updating a device after we receive new device keys from a
/keys/query call we implicitly check that the user and device id match
since we need to fetch the device using the mentioned ids.

This moves the check into the update method as well to make it more
explicit. We also prevent upgrades of the Ed25519 key since we don't
support any different key type anyways.
2023-01-12 17:55:06 +01:00
Damir Jelić e3e9898f88 fixup! test(crypto): Check that we sign and verify fallback keys properly 2023-01-12 17:53:22 +01:00
Damir Jelić f2055f8069 test(crypto): Check that we sign and verify fallback keys properly 2023-01-12 17:53:22 +01:00
Damir Jelić 151f87a417 chore(crypto): Improve some docs
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2023-01-12 17:37:06 +01:00
Damir Jelić 0e4f4d69b8 feat(crypto): Handle the failures field in the /keys/claim response 2023-01-12 17:37:06 +01:00
Damir Jelić 8db84a3c9e feat(crypto): Handle the failures field in the /keys/query response 2023-01-12 17:37:06 +01:00
Damir Jelić 1b18402707 feat(crypto): Add a TTL-cache that will handle failures for some requests 2023-01-12 17:37:06 +01:00
Benjamin Kampmann 6ec8ff6363 ci(coverage): ignore new sliding-sync-integration-tests for now 2023-01-12 13:51:59 +01:00
Benjamin Kampmann 906c09987f style(sliding-sync): minor style refinements 2023-01-12 13:24:16 +01:00
Benjamin Kampmann c93a9ef9a3 fix(sliding-sync): Simply room_range checking
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2023-01-12 13:24:16 +01:00
Benjamin Kampmann 51f2e773a0 fix(ffi): add Pop and Clear to VecDiff for sliding-sync 2023-01-12 13:24:16 +01:00
Benjamin Kampmann 3c6c5f4fae ci: disable broken sliding-sync-integration-test-runs 2023-01-12 13:24:16 +01:00
Benjamin Kampmann a8d49b86df feat(sliding-sync): adding views on live sliding-sync 2023-01-12 13:24:16 +01:00
Benjamin Kampmann 2949dcc773 docs: Add a Readme to explain usage 2023-01-12 13:24:16 +01:00
Benjamin Kampmann b790bf9397 test(sliding-sync): add integration test covering #1333 2023-01-12 13:24:16 +01:00
Benjamin Kampmann 91941a5360 fix(sliding-sync): ensure we are only replacing items in the requested range 2023-01-12 13:24:16 +01:00
Benjamin Kampmann fabf0d40bc test: add test for moving window and rooms 2023-01-12 13:24:16 +01:00
Benjamin Kampmann 08bec243ff ci(sliding-sync): add sliding sync integration test 2023-01-12 13:24:16 +01:00
Benjamin Kampmann 60d82fde38 test: add sliding-sync integration-testing facilities 2023-01-12 13:24:16 +01:00
Jonas Platte 866158f6ff chore(sdk): Add logging for when timeline events are not handled 2023-01-11 17:14:09 +01:00
Kévin Commaille f883293168 chore: Update Ruma
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2023-01-11 16:05:02 +01:00
Damir Jelić c6e883da68 fix(sdk): Pass in to-device events to the OlmMachine unconditionally
The sliding sync proxy seems to have started to omit the e2ee extension
completely if no changes happened to the one-time key counts.

Our sync response processing assumed that, if there are some to-device
events that need to be passed to the OlmMachine, then we'll have some
data in the e2ee extension of the response as well. In other words, it
wouldn't pass in the to-device events to the OlmMachine if the e2ee
field of the sync response is `None`.

Since the assumption isn't true, we're going to pass in default values
for the one-time key counts when the e2ee extension field of the
response is `None`.
2023-01-11 14:18:40 +01:00
Damir Jelić cdfb51a606 refactor!(sdk): Add the experimental prefix to the sliding-sync feature 2023-01-11 11:54:32 +01:00
Damir Jelić 3e88905518 chore(sdk): Make the timeline feature a dependency of the sliding sync one 2023-01-11 11:54:32 +01:00
Damir Jelić 156c351023 chore(crypto): Instrument the receive_sync_changes method
This is mainly done so we create a span with the name of the function,
since we can filter logs by the name of the span we're now able to
enable logs for this method only.
2023-01-11 11:17:58 +01:00
Jonas Platte a98c1fd00d chore: Update Cargo.lock 2023-01-10 10:19:02 +01:00
Jonas Platte f4bfbdf97d chore: Upgrade base64 2023-01-10 10:19:02 +01:00
Jonas Platte 2e30e11101 refactor: Use workspace dependencies for more crates 2023-01-10 10:19:02 +01:00
Jonas Platte 3af6ba245c refactor: Fully replace matches crate with assert_matches 2023-01-10 10:19:02 +01:00
Benjamin Kampmann db1d31c9cc fix(sliding-sync): Do not implictly activate to-device extension upon unfreeze
Previously, when we found a since-token in the frozen state, we'd always activate the to-device extensions
regardless of whether the user had activated it in their builder or didn't. With this change we are only
setting the since parameter from cache if the user actually activated the to-device extension.
2023-01-10 10:04:31 +01:00
Jonas Platte 444a82fd9e fix(sdk): Small documentation update 2023-01-10 10:01:26 +01:00
Jonas Platte 6e218bdebc feat(sdk): Make pagination more flexible and smarter
- Don't actually fire off a request when the top of the timeline has
  already been reached
- Allow making multiple requests without removing the loading indicator
  in between
2023-01-10 10:01:26 +01:00
Jonas Platte 9b3bf5a4fa feat(sdk): Add TimelineStart virtual timeline item 2023-01-10 10:01:26 +01:00
Jonas Platte 237edcd747 refactor(sdk): Move day_divider constructor to TimelineItem 2023-01-10 10:01:26 +01:00
Jonas Platte 271e925adc refactor(sdk): Add and use TimelineItem::{read_marker, is_read_marker} 2023-01-10 10:01:26 +01:00
Benjamin Kampmann 514530c19a fix(sliding-sync): ensure last index is also invalidated
Index ranges are inclusive, but our loop would stop one short. This particuarly
tricky when the selective view is moved, as we didn't properly invalidate all items.
2023-01-09 22:48:57 +00:00
Benjamin Kampmann 58aec0d126 feat(uniffi): Add support to set list filters on sliding sync view builders (#1296)
* feat(uniffi): Add support to set list filters on sliding sync view builders
* fix: expose SlidingSyncRequestListFilters via proc-macros
2023-01-09 14:45:35 +00:00
dependabot[bot] 63c8696cac chore(deps): bump tokio from 1.22.0 to 1.23.1
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.22.0 to 1.23.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.22.0...tokio-1.23.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-07 14:06:32 +01:00
Damir Jelić 6aff4fc2c0 Update the bindings to use the SAS signalling (#1300)
* feat(bindings): Expose support for manually starting SAS verifications

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
2023-01-06 10:20:40 +01:00
Jonas Platte 8375c47f42 feat(sdk): Add pagination loading indicator as a virtual timeline item 2023-01-06 09:48:44 +01:00
Jonas Platte 1b2387bcb2 refactor(sdk): Enforce no pagination overlap in timeline
… by locking the pagination token for the entire duration of the API call.
2023-01-06 09:48:44 +01:00
Jonas Platte 1e71036b19 refactor(sdk): Simplify day divider matching 2023-01-06 09:48:44 +01:00
Jonas Platte e0f5dc97a5 refactor(bindings): Avoid single letter type aliases 2023-01-05 10:53:56 +01:00
Jonas Platte 64f367d474 feat(bindings): Expose all TimelineItemContent variants 2023-01-05 10:53:56 +01:00
Jonas Platte bb39c2aa9d feat(sdk): Persist sliding-sync to-device extension since value 2023-01-04 19:05:37 +01:00
Jonas Platte b82cd7fa5a refactor(common): Simplify wasm timeout implementation
… and remove an infinitely-recursive From impl in the process.
2023-01-04 18:59:11 +01:00
Jonas Platte 6780dc0312 refactor(sdk): Increase default request timeout to 30s 2023-01-04 17:55:18 +01:00
Damir Jelić 72519b7386 chore(labs): Use clap instead of structopt for jack-in
Update to clap v4 in jack-in
2023-01-04 12:49:50 +01:00
Jonas Platte c7b41e3fca test(sdk): Add a test for TimelineInner::add_initial_events 2023-01-04 12:44:51 +01:00
Marcel Kräml 5852d751bd Updated jack-in README.md for full-sync-mode lowercase options
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2023-01-04 12:38:54 +01:00
Marcel Kräml cda596ebed Changed full_sync_mode to lowercase
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2023-01-04 12:21:14 +01:00
Jonas Platte a5e17be3a1 refactor(bindings): Only create a timeline for SlidingSyncRoom if needed 2023-01-04 11:44:07 +01:00
Jonas Platte 33cdc108b5 chore(sdk): Log number of events in add_initial_events 2023-01-04 11:44:07 +01:00
Jonas Platte c3dfd2e744 refactor(sdk): Only lock timeline items if needed in add_initial_events 2023-01-04 11:44:07 +01:00
Jonas Platte 8ab5bb7fca refactor(sdk): Use HttpError::client_api_error_kind 2023-01-04 11:44:07 +01:00
Jonas Platte 80d8a8f41f refactor: Import tracing macros 2023-01-04 11:44:07 +01:00
Jonas Platte 46fe998a33 refactor(crypto): Improve logging 2023-01-03 13:09:09 +01:00
Jonas Platte 7efbba5d8b refactor(sdk): Improve logging in timeline::event_handler 2023-01-03 13:09:09 +01:00
Jonas Platte 907d50f773 refactor(sdk): Move TimelineInnerMetadata definition to timeline::inner 2023-01-03 13:09:09 +01:00
Jonas Platte 9cba98ae1b feat(sdk): Add num_updates to timeline PaginationOutcome 2023-01-03 09:44:23 +01:00
Jonas Platte 108950c706 refactor(sdk): Remove update_timeline_item
… inlining it into its only call site.
2023-01-03 09:44:23 +01:00
Jonas Platte 4452e15489 refactor(sdk): Rename TimelineEventHandler#event_added to item_created 2023-01-03 09:44:23 +01:00
Matthew Hodgson b026d90bcf fix(sdk): Handle to-device sliding sync extension correctly
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2023-01-02 18:00:38 +00:00
Jonas Platte aa5f74ffb1 fix(sdk): Fix clippy lint 2023-01-02 12:45:50 +01:00
Jonas Platte 469c6cf104 fix(sdk): Don't log raw JSON which can contain personal data 2023-01-02 12:45:50 +01:00
Jonas Platte 3c5b005aae fix(sdk): Remove message contents from TimelineItem debug string 2023-01-02 12:45:50 +01:00
Marcel Kräml eef0bf4b91 Fixed clap for jack-in and update README.md
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2022-12-23 11:29:21 +01:00
Marcel Kräml ad1011ec53 Replace structopt with clap in jack-in
Signed-off-by: Marcel Kräml <m.kraeml@kraeml.it>
2022-12-23 11:17:02 +01:00
Jonas Platte c215ac1f4b ci: Specify which version of wasm-pack we want 2022-12-22 16:06:48 +01:00
Jonas Platte 187696aa62 ci: Use latest version of wasm-pack-action 2022-12-22 16:06:48 +01:00
Jonas Platte e1e094f2f4 chore(sdk): Lower log level of event ID duplication event 2022-12-22 14:45:41 +01:00
Damir Jelić e2d4be2050 chore: Fix our build badge 2022-12-22 11:26:29 +01:00
Jonas Platte 7dc4d47d3c refactor(sdk): Store timeline event handler handles in a Vec
… instead of individual EventHandlerDropGuard's that each individually
hold a copy of Client.
2022-12-22 10:32:03 +01:00
Jonas Platte 9bad6faedd feat(sdk): Retry event decryption on forwarded room keys 2022-12-22 08:37:17 +01:00
Jonas Platte 3a715ea822 refactor(sdk): Move timeline m.room_key handler into new module 2022-12-22 08:37:17 +01:00
Jonas Platte f58f3fe055 chore(sdk): Add more logging to decryption retrying 2022-12-22 08:37:17 +01:00
Benjamin Kampmann 6eda742fff style(sliding-sync): explain why we limit the timeline items in freeze 2022-12-21 12:51:12 +00:00
Jonas Platte 14f451c6dd feat(bindings): Add decryption retrying to matrix-sdk-ffi 2022-12-21 13:35:27 +01:00
Benjamin Kampmann 562087a70e fix(sliding-sync): properly handle rooms_count == 1. fixes #1285 2022-12-21 10:13:39 +00:00
Benjamin Kampmann e3e0eb9144 fix(sliding-sync): sync view state for selective views.
Fixes ##1284
2022-12-21 10:13:39 +00:00
Benjamin Kampmann b6d48cb31a fix(sliding-sync): limit cold storage of timeline items to 10 and drop prev-batch token in case we'd store too many 2022-12-21 10:13:39 +00:00
Ivan Enderlin e4257f9aff feat(crypto-js): Make our promises reject with Error.
feat(crypto-js): Make our promises reject with `Error`.
2022-12-21 09:49:30 +01:00
Richard van der Hoff 6b871b0a48 matrix-sdk-crypto-js: Make our promises reject with Error
It's not a hard-and-fast-rule that Javascript exceptions should be `Error`
instances, but it's certainly a convention, and one that is going to reduce
surprises if we follow.
2022-12-20 22:36:42 +00:00
Jonas Platte 561fb97a7b feat(bindings): Add virtual timeline items to matrix-sdk-ffi 2022-12-19 13:54:55 +01:00
Jonas Platte a5080b6ed9 chore: Upgrade Ruma 2022-12-19 13:50:02 +01:00
Jonas Platte 8034ac20f9 refactor(base): Keep redaction events as Raw inside StateChanges 2022-12-19 13:50:02 +01:00
Jonas Platte f5c0ea4605 doc(bindings): Update docs for Apple platforms 2022-12-19 13:44:00 +01:00
Doug ddf448aa02 doc(bindings): Update docs for Apple platforms.
Remove old bash scripts now we have the xtask.
2022-12-19 12:31:29 +00:00
Kévin Commaille b960c372ac feat(sdk): Add support for stickers in the timeline 2022-12-19 08:39:07 +00:00
Jonas Platte 05e4bc0557 refactor: Don't reserialize member events before storing them 2022-12-15 18:19:35 +01:00
Jonathan de Jong d79c70177b Lab: The Setup Pattern 2022-12-15 16:48:55 +01:00
Kateřina Churanová db7eafb7d0 fix(doc): Fix unresolved link in documentation
Signed-off-by: Kateřina Churanová <k.churanova@famedly.com>
2022-12-14 22:00:25 +01:00
Anderas 9239470c1c feat(crypto): Add signalling to the verification requests and qr code verification 2022-12-14 19:15:22 +01:00
Benjamin Kampmann dab20638f9 fix(sliding-sync): new limit should default to None in builder 2022-12-14 14:06:31 +01:00
Benjamin Kampmann 273d0a0edf feat(sliding-sync): Growing window and limit count full sync (#1270)
Add a second full-sync-up mode to sliding sync. Previously - and still the default for backwards compatibility, but now named `PagingFullSync` - was to page through the list by the page-size, de-validating the previous page of items. The newly added `GrowingFullSync` instead grows the window by the given number `batch_size` per request, starting and keeping it from `0`. In the latter we might be pushing more data over the connection and are slightly slower, but the top always stays active and thus reactive to changes.

Furthermore the developer can now configure an optional maximum number to grow/paginate the full-sync up to (so stopping before actually having reached `count` whatever is smaller). This is already exposed via FFI, too.

- [x] add new full-sync-mode
- [x] add limited sync-up mode (similar to full sync but only to a limit `n`)
- [x] implement sync-up in jack-in
2022-12-14 13:50:35 +01:00
Jonas Platte 1c12b23e4c refactor(sdk): Move PaginationOutcome out of event_item module 2022-12-14 12:38:48 +01:00
Kévin Commaille 37bea19ab5 feat(sdk): Add day dividers to the experimental timeline 2022-12-14 12:29:24 +01:00
Jonas Platte eb0c3449fa refactor(bindings): Use proc-macro frontend more in sdk-ffi 2022-12-14 12:03:13 +01:00
Jonas Platte b3f146c932 refactor(bindings): Use proc-macro frontend more in crypto-ffi 2022-12-14 12:03:13 +01:00
Jonas Platte 34d458d3a3 chore: Upgrade UniFFI 2022-12-14 12:03:13 +01:00
Benjamin Kampmann 1c55565403 Merge pull request #1255 from gnunicorn/ben-update-jack-in
Sliding Sync updates

- expose timeline listener via FFI on slidingsyncroom, too - returning a stoppable spawn
- connect room timeline and sliding-sync-room timeline together
- increase HTTP timeout on jack-in
- add jack-in support for actual timeline items.
2022-12-13 15:14:57 +00:00
Richard van der Hoff c8da05125e Merge remote-tracking branch 'origin/main' 2022-12-12 18:41:30 +00:00
Richard van der Hoff 9ec9a59509 Release 0.1.0-alpha.2
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 34s
2022-12-12 18:02:21 +00:00
Richard van der Hoff 4f9452c9b0 Fix yet another typo in package.json 2022-12-12 17:51:10 +00:00
Richard van der Hoff dfed2f1b3a Bump version
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 36s
2022-12-12 17:35:54 +00:00
Richard van der Hoff 5850ff4cfc Fix filenames in package.json 2022-12-12 17:31:54 +00:00
Doug e64a8113e9 feat(bindings): Generate a Package.swift in xtask 2022-12-12 18:04:15 +01:00
Richard van der Hoff 2a4b83b5e6 Switch to npm-publish GHA script
Release `crypto-js` / Publish 🕸 [m]-crypto-js (push) Failing after 57s
Mostly because, as of #1167, we no longer have a `publish` script.
2022-12-12 16:17:32 +00:00
Benjamin Kampmann 799447f481 Merge remote-tracking branch 'origin/main' into ben-update-jack-in 2022-12-12 15:15:14 +01:00
Benjamin Kampmann 1a0b90291c fix(jack-in): rendering formatting improvements 2022-12-12 15:14:18 +01:00
Valere 9a058b9ea0 feat(crypto): Request room keys if the decryption failure is an unknown message index
We automatically request room keys to be forwarded from our other trusted devices if a decryption failure happens because the room key is missing.

This patch introduces automatic room key requests for decryption failures if the room key is available but has been ratcheted forward. In other words, we will now request a better version of the given room key automatically as well.

Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2022-12-12 13:09:45 +01:00
Erwan Bousse 1ef645d285 feat(bindings): Use HTTPS proxy when provided as environment variable 2022-12-09 16:01:02 +01:00
valere 57e09c07dc Git Ignore generated files from kotlin bindings 2022-12-09 13:12:50 +01:00
Benjamin Kampmann 1e4c16b9a9 Merge remote-tracking branch 'origin/main' into ben-update-jack-in 2022-12-07 16:31:32 +01:00
Benjamin Kampmann 26486fc905 feat: add kotlin bindings
Merge pull request #1239 from matrix-org/ganfra/kotlin_bindings
2022-12-07 14:50:38 +00:00
Benjamin Kampmann c4884887ef fix(sliding-sync): set views to preload if we've recovered from frozen 2022-12-07 13:59:50 +00:00
Jonas Platte ddde87f14b fix(sdk): Fix remote echo event_id check
The send-event response sets the event_id field, not the timeline key.
The previous error branch wasn't actually reachable.
2022-12-07 12:32:44 +01:00
Jonas Platte 3e1fddccfd fix(sdk): De-duplicate local echoes with remote echoes without txn ID 2022-12-07 12:32:44 +01:00
Jonas Platte c1949e3fc6 refactor(sdk): Move timeline::add_event_id to TimelineInner 2022-12-07 12:32:44 +01:00
Juliette 63bc004e26 feat(bindings): Add uploading media and setting display name to FFI
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-12-07 10:40:15 +00:00
Jonas Platte e99341df69 chore(bindings): Move bindings around to work around rustfmt bug 2022-12-07 11:16:25 +01:00
Jonas Platte 7667f0c429 refactor(sled): Use open_with_database for SledCryptoStore::open 2022-12-07 11:16:25 +01:00
Jonas Platte d0609822bc refactor(sled)!: Rename SledCryptoStore::{open_with_passphrase => open}
`open_with_db` also has the passphrase parameter without mentioning it
in its name. The old name also sounded like the passphrase was required
when it's actually optional.
2022-12-07 11:16:25 +01:00
Jonas Platte 262fe5630f feat(sdk): Implement IntoFuture for LoginBuilder and SsoLoginBuilder 2022-12-07 11:13:44 +01:00
Andrew Ferrazzutti 2176b7ee39 Revise example of machine.receiveSyncChanges
Clarify that the JSON-encoded `toDeviceEvents` passed to
`OlmMachine.receiveSyncChanges` must be the list of events themselves,
instead of a wrapper object that contains the event list.

Signed-off-by: Andrew Ferrazzutti <andrewf@element.io>
2022-12-07 11:00:22 +01:00
Benjamin Kampmann 2bc738be8c feat(jack-in): sending messages via timeline API 2022-12-06 14:28:34 +01:00
Jonas Platte f5b59c3de2 refactor(sdk)!: Remove impl Into<_> around Ruma request types
The SDK used to have builder types for these request types, but they
were removed long ago.
2022-12-06 14:00:33 +01:00
ismailgulek 31e5d4d663 feat(bindings): Add members accessor to Room
Co-authored-by: Doug <douglase@element.io>
2022-12-06 12:58:30 +00:00
Jonas Platte 6a386ca5fb feat(bindings): Add sending of reactions to matrix-sdk-ffi 2022-12-06 12:48:06 +01:00
Jonas Platte a18919bf50 chore: Add a PR template 2022-12-05 14:58:33 +01:00
Jonas Platte f92153757b chore: Add CONTRIBUTING.md
… and move the testing section from README.md into it.
2022-12-05 14:58:33 +01:00
Benjamin Kampmann 83d0abc6d7 feat(sliding-sync): properly handle all timeline event types 2022-12-05 14:52:38 +01:00
Benjamin Kampmann f919ee3b7d fix(ffi): clean up sliding sync timeline API 2022-12-05 14:52:38 +01:00
Benjamin Kampmann 0bfa63b31e fix(sliding-sync): return a stoppable spawn to allow listener cancellation 2022-12-05 14:52:38 +01:00
Benjamin Kampmann 229e6b28a5 fix(ffi): connect timelines together 2022-12-05 14:52:38 +01:00
Benjamin Kampmann fee9d52dde feat(ffi): expose sliding-sync timeline 2022-12-05 14:52:38 +01:00
Benjamin Kampmann d4890807f9 fix(jack-in): bump http timeout to 90seconds 2022-12-05 14:52:38 +01:00
Damir Jelić 58f92e59fe fix(bindings): Change the is_syncing method to read the correct value 2022-12-05 14:16:01 +01:00
Damir Jelić 1f38becdd9 chore: Fix a clippy warning 2022-12-05 14:16:01 +01:00
Ivan Enderlin 2d9e8170fe feat(indexeddb): Update to indexed_db_futures 0.3.0.
It removes the fork we have introduced in https://github.com/matrix-org/matrix-rust-sdk/pull/1068
(all our patches have been merged and are part of this 0.3.0 release).
2022-12-05 14:16:01 +01:00
Kévin Commaille aeb419207a refactor(sdk): Split restore_session into two parts at the Client level (#1246)
Tokens are not necessary for the restoration of the crypto/store, only
the meta. Required for OpenID Connect support where we need the tokens to get the
meta.
2022-12-05 13:19:35 +01:00
Flix ee713d42ae chore: Bump axum 2022-12-01 13:26:07 +01:00
ganfra 97578e418c Merge branch 'main' into ganfra/kotlin_bindings 2022-11-30 20:39:42 +01:00
Benjamin Kampmann 7d69fb2314 fix(sliding-sync): fallback to invite-room if regular room can't be found (#1249)
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-11-30 13:59:25 +00:00
Jonas Platte 32cc477f54 refactor(sdk): Remove media caching from in-memory state store 2022-11-30 10:21:24 +01:00
Andy Uhnak 457c5f4fa3 Add cancel methods and rename callback method 2022-11-30 10:18:47 +01:00
Damir Jelić c604e59dcc feat(bindings): Expose the Sas::changes method over the FFI 2022-11-30 10:18:47 +01:00
Damir Jelić 026659ef68 refactor!(bindings): Return objects for the verification support
When the verification support was initially bound, Uniffi did not
support objects (the OlmMachine) returning other objects (our
verification objects). Instead we converted all the verification objects
into pure data structs which the other side had to poll for changes.

Now that Uniffi supports returning objects we can refactor this and make
the API on the other side the same as on the Rust side.
2022-11-30 10:18:47 +01:00
Jonas Platte 195ade911e refactor(sdk): Simplify signature of handle_back_paginated_event 2022-11-29 23:55:33 +01:00
Jonas Platte a881dad529 refactor(sdk): Make Timeline construction non-async 2022-11-29 23:55:33 +01:00
Jonas Platte 090b4495ea refactor(sdk): Simplify signature of handle_remote_event 2022-11-29 23:55:33 +01:00
Jonas Platte 3dfc60506f feat(sdk): Add SlidingSyncRoom::latest_event 2022-11-29 23:55:33 +01:00
Jonas Platte d4b67de9c3 refactor: Replace Timeline::latest with Timeline::latest_event 2022-11-29 23:55:33 +01:00
Jonas Platte 78e621010d refactor(sdk): Make tracking of fully-read marker in Timeline optional 2022-11-29 23:55:33 +01:00
Jonas Platte 1b0849a20c refactor(sdk): Move TimelineInner into its own module 2022-11-29 23:55:33 +01:00
Jonas Platte 32bf3143c7 doc: Hint towards test execution 2022-11-29 23:38:31 +01:00
Jonas Platte 3d22b6d5a4 chore: Upgrade Ruma 2022-11-29 15:37:18 +01:00
Flix bc29bcef38 doc: Hint towards test execution 2022-11-29 15:29:41 +01:00
Jonas Platte 859b12fca9 feat(sdk): Add debug logs for aggregated event handler execution times 2022-11-29 09:46:43 +01:00
Jonas Platte c564696a8a feat(sdk): Add tracing info to call_event_handlers 2022-11-29 09:46:43 +01:00
Benjamin Kampmann d3ff402813 feat(sliding-sync): Offline caching for Sliding Sync & session recovery (#1193)
With these changes, the user of sliding sync can configure the SlidingSync-Builder to store and recover the state from storage. For that they should call cold_cache("my-sliding-sync-key") with their preferred storage location during setup time on SlidingSyncBuilder. If a cached version is found under that key, the internal state of the rooms-list as well as each view found (identified by their name) will be set from storage immediately - allowing the user to show the last cached state. The Builder then also uses the same key to store its latest state after every update received from remote.

👉 Note on room list:
As we store a disconnected state, we are saving all RoomList entries as either Empty or Invalidated. This allows for an easier updating when the server comes back with results, as we don't track the ranges in cache - in the view of the server, we haven't seen anything yet.

👉 Note on timeline events:
This does store all existing timeline events - initial and seen during the session (as we keep track of them right now) - and will recover that state. However, as we can't be sure wether we have gaps in the timeline, the timeline items are reset upon receiving updates for them from the server.

👉 Note on (full-sync-)view:
While we are caching the server returned results (view list, room count and room info) as is, we are not caching the internal state (whether we are catching up) nor the ranges (as they are likely to be out of date) - those will be acting the same way you configured them, just with preloaded results. So for a full-sync-view, it will still do requests in batches and replace the corresponding set of rooms. Which could mean you might see the same room appear twice, though the cached one would be marked as invalidated. This might be problematic if the list the UI shows is longer than the batches fetched, but would be resolved quickly when catching up.

👉 On recovery:
When the sliding sync receives a M_UNKNOWN_POS, indicating the server has expired our session, sliding sync now transparently retries with up to three times to restart the sliding sync with full set of extensions and the latest views at their existing windows, the current room state is held. For full sync this starts a new sync-up with the existing room list staying intact. This also works from the offline at start.
2022-11-28 18:01:04 +00:00
Kateřina Churanová 08951e1c56 fix(ci): Fix unused import warnings on macos 2022-11-28 15:08:01 +01:00
Jonas Platte afda63f9e2 fix(sdk): Only retry requests on M_LIMIT_EXCEEDED or HTTP 5xx 2022-11-28 14:13:03 +01:00
Jonas Platte d7e6dd22e6 refactor(sdk): Simplify RumaApiError again
by folding Uiaa(UiaaResponse::MatrixError) into RumaApiError::ClientApi.
2022-11-28 14:13:03 +01:00
ganfra 68a6d2707f Fix naming of generated crypto .so files 2022-11-28 11:47:59 +01:00
ganfra 6666cd7a79 Use the generate .a file from cargo build as it's not stripped (instead of new target) 2022-11-25 19:20:54 +01:00
ganfra 75bb44bebf Add script to generate only crypto-ffi crate 2022-11-25 11:59:27 +01:00
ganfra 0504240878 Merge branch 'main' into ganfra/kotlin_bindings 2022-11-25 10:19:19 +01:00
Jonas Platte c0910a3693 chore: Fix a typo, upgrade typo check action 2022-11-24 22:36:46 +01:00
Kévin Commaille 183d4595aa fix(sdk): Make sure read marker can't go backwards 2022-11-24 22:15:36 +01:00
Kévin Commaille 580861cd1c fix(sdk): Rename read marker functions and variables for clarity 2022-11-24 22:15:36 +01:00
Kévin Commaille 1f761f3c13 test(sdk): Add read marker case when fully read event wasn't found 2022-11-24 18:17:43 +01:00
Kévin Commaille 5dc6416a76 fix(sdk): Fix logic if read marker event was not in the timeline 2022-11-24 18:17:43 +01:00
Jonas Platte c808a72914 feat(sdk): Add FailedToParse timeline items 2022-11-24 14:35:49 +01:00
Jonas Platte 6a1edf133d refactor(sdk): Add NewEventTimelineItem::from_content 2022-11-24 14:35:49 +01:00
Jonas Platte d0f0b650bd chore: Move impl for type after its definition 2022-11-24 14:35:49 +01:00
Jonas Platte d027005e87 chore(sdk): Rewrap info! invocation 2022-11-24 14:35:49 +01:00
Jonas Platte 43f0ba7711 chore: Appease clippy 2022-11-24 13:43:09 +01:00
Jonas Platte 8ce216974f test(sdk): Add a regression test for read marker updates 2022-11-24 13:43:09 +01:00
Jonas Platte f7d4129607 fix(sdk): Fix logic for updating an existing read marker 2022-11-24 13:43:09 +01:00
Stefan Ceriu 1107f27c3d fix(ffi): Use the right path for generated source files and only copy the generated folder contents (#1226) 2022-11-22 14:21:58 +00:00
Damir Jelić 3113f6698f chore: Don't use the term check for signature verification 2022-11-22 13:21:33 +01:00
Damir Jelić 38c38bc9f0 feat!(bindings): Expose the improved result of the verify_backup method 2022-11-22 13:21:33 +01:00
Jonas Platte de71d7e434 refactor(base): Simplify default memory store initialization 2022-11-22 11:03:45 +01:00
Jonas Platte 57a1743566 chore: Update Cargo.lock 2022-11-22 11:01:23 +01:00
Stefan Ceriu 1025d42624 fix(ffi): Fix xcframework release script, add missing module map 2022-11-22 09:55:46 +01:00
Jonas Platte fcb37b6962 feat: Support creating Timeline with initial items from sliding sync
Co-authored-by: Benjamin Kampmann <ben@gnunicorn.org>
2022-11-21 14:52:02 +01:00
bitfriend 2ab697328f fix(sdk): Make handle_back_paginated_event future Send 2022-11-18 20:57:36 +00:00
Damir Jelić eb20abe7b8 chore: The encryption feature was renamed 2022-11-18 19:53:07 +01:00
Jonas Platte fa71122e7d ci: Add sliding-sync and experimental-timeline to clippy check 2022-11-18 15:05:48 +01:00
Jonas Platte 785a3349ab refactor(sdk)!: Make sync_token accessor private 2022-11-18 14:02:41 +01:00
Jonas Platte 6329dbe6c2 refactor!: Split SyncResponse into two types
- matrix_sdk_base::sync::SyncResponse is the internal representation that
  we can update to account for sliding sync
- matrix_sdk::sync::SyncResponse is `/v3/`-specific and should not change
2022-11-18 14:02:41 +01:00
Jonas Platte ec5306978e refactor(sdk): Simplify signature of handle_sync_response 2022-11-18 14:02:41 +01:00
Jonas Platte 6b363120ef fix(sdk): Fix errors & warnings w/ experimental-timeline, w/o e2e-encryption 2022-11-18 13:39:51 +01:00
Jonas Platte 4bafb3818b feat(sdk): Add Timeline::retry_decryption 2022-11-18 13:39:51 +01:00
Jonas Platte 317965995a test(sdk): Add a test for retrying decryption of timeline items 2022-11-18 13:39:51 +01:00
Jonas Platte 74e9209e95 feat(sdk): Retry decryption of UTD timeline items 2022-11-18 13:39:51 +01:00
Jonas Platte da76a2700d refactor(sdk): Use an async lock for TimelineInnerMetadata 2022-11-18 13:39:51 +01:00
Jonas Platte ac33ca5fa0 refactor(sdk): Hold locks for the full lifetime of TimelineEventHandler
Not really necessary now, but required for thread-safe bulk updates like
we want for retrying decryption.
2022-11-18 13:39:51 +01:00
Jonas Platte 2bc0ac8fd7 refactor(sdk): Merge mutexes in TimelineInner into one 2022-11-18 13:39:51 +01:00
Damir Jelić 5a108f53cc refactor(crypto): Only use the Mutable for the inner SAS object
This patch makes the SAS signalling more robust, it ensures that we
can't forget to signal changes to the state.
2022-11-18 09:26:20 +01:00
Damir Jelić 1f2cdfc601 chore(contrib): Mitmproxy 9 has removed the HTTP prefix from the Response type 2022-11-17 12:43:56 +01:00
Jonas Platte 02165f7a05 refactor(sdk)!: Move retrying out of HttpSend trait 2022-11-17 12:32:45 +01:00
Benjamin Kampmann 98600e4c1e feat(jack-in): sending messages (#1156) 2022-11-17 11:18:27 +00:00
Jonas Platte bb6145d581 refactor!: Move large parts of deserialized_responses to matrix-sdk-base 2022-11-17 11:33:37 +01:00
Jonas Platte 975626a4f8 refactor(common)!: Remove unused TimelineSlice type 2022-11-17 11:33:37 +01:00
Jonas Platte c3aa03e486 chore: Add reldbg profile and use it for matrix-sdk-ffi iOS builds 2022-11-16 09:59:06 +01:00
Jonas Platte 51798e90bd chore: Add dbg profile and improve profile comments 2022-11-16 09:59:06 +01:00
Jonas Platte 5fa6f34e41 refactor(sdk): Use ErrorKind for get_state_events_for_key response check 2022-11-15 16:06:21 +01:00
Jonas Platte f9d2d32337 fix(xtask): Fix clippy warning 2022-11-15 16:06:21 +01:00
Jonas Platte 2dd2763d39 refactor(base): Unify identical branches and erase empty branches 2022-11-15 16:06:21 +01:00
Johannes Becker bb6cf83a39 refactor(appservice)!: Rename virtual user to appservice user 2022-11-15 15:57:31 +01:00
Damir Jelić a7dd690189 refactor(crypto): Split out the room key forwarding logic into a separate method 2022-11-15 14:57:46 +01:00
Jonas Platte e060606331 refactor(crypto): Move some code into a new method 2022-11-15 14:57:46 +01:00
Jonas Platte a30e40ed3a refactor: Introduce more early returns to reduce rightwards drift 2022-11-15 14:57:46 +01:00
Jonas Platte e59acfe28c refactor: Use let-else to remove boilerplate code 2022-11-15 14:57:46 +01:00
Jonas Platte d312aaecec refactor(crypto): Replace ? on if-else by early return 2022-11-15 14:57:46 +01:00
Jonas Platte 2528a5501b refactor(crypto): Remove unnecessary ref mut in patterns 2022-11-15 14:57:46 +01:00
Jonas Platte cf241d8c32 refactor(crypto): Merge matches and reflow comments in accept_secret 2022-11-15 14:57:46 +01:00
Jonas Platte db5d34e385 refactor(crypto): Reduce rightwards drift in test_device_signatures 2022-11-15 14:57:46 +01:00
Jonas Platte 7d2865f004 refactor(bindings): Shorten is_transaction_id_valid method 2022-11-15 14:57:46 +01:00
Jonas Platte 826705c174 chore: Bump MSRV to 1.65 2022-11-15 14:57:46 +01:00
Jonas Platte 5a1e347333 ci: Install stable toolchain for test-uniffi-codegen
The xtask is explicitly using the stable, and there is no reason to use
a less stable toolchain for this job.
2022-11-15 14:57:46 +01:00
Benjamin Kampmann 882b206144 feat(xtask): build xcframework
* Move swift build scripts into xtask (#1201)
* fix(ffi): use target_path from `cargo metadata` rather than guessing
* ci(ffi): install necessary target arch for build-framework test
* feat(xtask): copy to target without rsync.
2022-11-15 13:06:33 +01:00
Flix 8d89037296 fix: Missing ServerError after ruma update 2022-11-15 12:32:20 +01:00
Flix deb8ef801b fix: Remove the condition to only set new members in get_members 2022-11-15 12:32:20 +01:00
Flix 0a45e401e3 test: Use MemoryStore to fix problems in coverage tests 2022-11-15 12:32:20 +01:00
Flix 456e00e953 fix: Add missing not_found errors 2022-11-15 12:32:20 +01:00
Flix ab846f79f1 test: Add encryption state mock to tests where it is needed 2022-11-15 12:32:20 +01:00
Flix b1c2da9a68 fix: Don't mark encryption state to be synced on sync
As it appears, the first sync for a room might not include the
encryption state, so we cannot set the encryption state to be synced on
incoming syncs. That way, we always fetch the encryption state manually.
2022-11-15 12:32:20 +01:00
Flix 1ab33a28c9 fix: Make sure room.sync_up works under all conditions 2022-11-15 12:32:20 +01:00
Flix a3a9858bf4 refactor: Make if branches instead of early return 2022-11-15 12:32:20 +01:00
Flix 6951f7f5bf fix: Review comments 2022-11-15 12:32:20 +01:00
Flix fb8045b254 fix: Fix UDL or is_encrypted 2022-11-15 12:32:20 +01:00
Flix be7c3239a8 refactor: Adjust create_dm_room to new room API 2022-11-15 12:32:20 +01:00
Flix 956e270941 feat: Implement room sync_up method 2022-11-15 12:32:20 +01:00
Flix 65721aafb9 fix: Lock syncing to the store to avoid races 2022-11-15 12:32:20 +01:00
Flix 9d150e5cc6 fix: Adjust repeated_join test to new changes 2022-11-15 12:32:20 +01:00
Flix 43dd4452cd fix: Check encryption state in intermediate rooms 2022-11-15 12:32:20 +01:00
Flix 4abb08c4a1 feat!: Make intermediate rooms available right after joining/leaving
Co-Authored-By: Jonas Platte <jplatte@matrix.org>
Co-Authored-By: Benjamin Kampmann <ben@gnunicorn.org>
2022-11-15 12:32:20 +01:00
Jonas Platte 544da0d324 fix(sdk): Fix broken intra-doc link 2022-11-15 11:54:53 +01:00
ismailgulek 29aa9a78c3 feat(ffi): Expose file messages
Expose file messages (#1203)
2022-11-14 15:56:38 +00:00
Jonas Platte 4dc0e0ef3c chore: Upgrade Ruma 2022-11-14 15:01:53 +01:00
Gabriel Féron 680ef6b93a feat(sdk): Allow using an existing sled::Db with SledStateStore 2022-11-12 13:04:34 +00:00
Benjamin Kampmann 078855b4c9 feat(ffi): logging support for android (#1199)
* split logger into platform specific implementations
* logging support for android
* use platform independent wrapper for uniffi:exports
* activate colors for ansi-terminals
2022-11-11 12:20:19 +00:00
Damir Jelić 0d80c0e3fe chore(crypto): Improve the log for the one-time key signature error 2022-11-10 19:03:14 +01:00
ganfra 0901243440 Merge branch 'main' into ganfra/kotlin_bindings 2022-11-10 15:34:32 +01:00
ganfra fc76cc443e Fix build script 2022-11-10 15:34:00 +01:00
Jonas Platte 45cf32dfab test(sdk): Add a test for an undecryptable event 2022-11-10 13:43:46 +01:00
Jonas Platte aa4dbe4bc6 test(sdk): Add a test for editing a redacted event 2022-11-10 13:43:46 +01:00
Jonas Platte b550e9ba14 test(sdk): Add a test for an invalid edit 2022-11-10 13:43:46 +01:00
Jonas Platte 79db05cffb test(sdk): Add a unit test for redacting a reaction 2022-11-10 13:43:46 +01:00
Richard van der Hoff e45c57d8fe feat(crypto-js): allow async load of webassembly (#1198)
It turns out that Google Chrome refuses to initialise the wasm via the
synchronous `WebAssembly.Module` constructor, complaining that it is too
big. To be fair, it has a point.

Anyway, that means we need to provide a way to load the wasm
asynchronously. So, we introduce an `initAsync()` function which applications
can call before they do anything else, to load the wasm in the background.

If the app *doesn't* call `initAsync()`, then we load the wasm synchronously
the first time a function that accesses the wasm is called.
2022-11-10 11:51:37 +00:00
Ivan Enderlin 2eefb3a090 fix(indexeddb) + feat(crypto-js): Releasing IDBDatabase so that we can delete them
fix(indexeddb) + feat(crypto-js): Releasing `IDBDatabase` so that we can delete them
2022-11-10 10:40:16 +01:00
Ivan Enderlin 6754defb9b doc(crypto-js): Improve documentation of OlmMachine.close. 2022-11-10 10:21:48 +01:00
Damir Jelić 078a75ea27 chore(crypto): Log the protocols we accepted for a SAS verification 2022-11-09 16:56:23 +01:00
Damir Jelić 0d74189cde feat(crypto): Implement MSC3783
This commit adds support for the message authentication code calculation
that is using valid base64 when encoding the MAC.
2022-11-09 16:56:23 +01:00
Ivan Enderlin 196dfaea03 test(crypto-js): Test OlmMachine.close + IndexedDB clean up. 2022-11-09 14:48:37 +01:00
Ivan Enderlin f6496d01c7 feat(crypto-js): Add OlmMachine.close.
This new `OlmMachine.close` forces to drop/close the `OlmMachine` without
waiting on the JavaScript garbage collector to collect it.

`wasm-bindgen` generates the following JS glue code:

```js
close() {
    const ptr = this.__destroy_into_raw();
    wasm.olmachine_close(ptr);
}
```

And, `__destroy_into_raw` looks like this:

```js
__destroy_into_raw() {
    const ptr = this.ptr;
    this.ptr = 0;
    OlmMachineFinalization.unregister(this);
    return ptr;
}
```

It unregisters itself from the `FinalizationRegistry` correctly. We are
protected from a double-free.
2022-11-09 14:48:37 +01:00
Jonas Platte ca515997f1 feat(bindings): Expose video messages in matrix-sdk-ffi 2022-11-09 14:45:31 +01:00
Ivan Enderlin 3fe63c328f fix(indexeddb): Call IDBDatabase.close manually.
Surprisingly, `indexed_db_futures::IdbDatabase` is not closed when dropped.
Hopefully, there is a [`IdbDatabase::close(&self)`][close] method, which calls
`web_sys::IdbDatabase.close`, aka [`IDBDatabase.close`][websys-close], so let's
use it!

`IDBDatabase.close` returns immediately and closes the connection in a separate
thread. The connection isn't actually closed until all transactions created
using this connection are complete. No new transactions can be created for this
connection once this method is called. Methods that create transactions throw
an exception if a closing operation is pending.

[close]: https://github.com/Alorel/rust-indexed-db/blob/8c106eb418aecdba2f3fde80d91a4673a875fdf6/src/idb_database.rs#L73-L77
[websys-close]: https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/close
2022-11-09 14:45:00 +01:00
ismailgulek 26d690a21c Fix clippy 2022-11-09 16:34:41 +03:00
ismailgulek 045d6647b2 feat(bindings): Add support for editing messages 2022-11-09 14:15:19 +01:00
ismailgulek 7f54e4592f Expose video messages 2022-11-09 16:02:40 +03:00
ganfra 4899f98f7f Merge main into ganfra/kotlin_bindings 2022-11-08 17:25:57 +01:00
Kévin Commaille 93be96c85c feat(sdk): Add read marker logic to the timeline API 2022-11-08 13:16:09 +01:00
Jonas Platte c014f980cb chore(sdk): Remove invalid comment
I have tried for hours and have concluded it is probably not possible
even with GATs to have RawEvent borrow its inner value.
It is also not a commonly-used feature, so removing the unnecessary
clones is not that important.
2022-11-04 15:17:01 +01:00
Jonas Platte 5601435449 refactor(sdk): Simplify bounds on event handler registration methods
… by introducing a hidden trait that constrains the output type of the
associated type EventHandler::Future.
2022-11-04 15:17:01 +01:00
Jonas Platte 5b919fc9df refactor: Fix clippy lints 2022-11-04 15:17:01 +01:00
Stefan Ceriu d57666c0b8 fix(sliding_sync): remove server versions fetch
before being able to use the sliding sync builder; the versions are still fetched but at a later date (#1183)
2022-11-04 12:03:17 +00:00
Jonas Platte ce966ed6ce chore: Upgrade criterion, pprof 2022-11-04 11:14:13 +01:00
Jonas Platte 3a6d048b9f refactor(sdk)!: Rename uiaa_response methods to as_uiaa_response 2022-11-03 18:05:04 +01:00
Jonas Platte cf779822fe refactor(sdk): Merge impl blocks 2022-11-03 18:05:04 +01:00
Jonas Platte c8dd5c42e9 docs(sdk): Add more doc links to as_ruma_api_error methods 2022-11-03 18:05:04 +01:00
Jonas Platte 128c74ace5 refactor(sdk): Use server-supplied retry time when when available 2022-11-03 18:05:04 +01:00
Jonas Platte 85ea9554e5 feat(sdk): Add {RumaApiError,HttpError,Error}::as_client_api_error 2022-11-03 18:05:04 +01:00
Ivan Enderlin 5b25b8967c feat(crypto-js): Encode the WASM as base64 for portability
feat(crypto-js): Encode the WASM as base64 for portability
2022-11-03 16:44:16 +01:00
Damir Jelić 3b755fc15e chore(crypto): Fix some spelling
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-11-03 16:18:15 +01:00
Damir Jelić da61005ee4 chore(crypto): Improve the logs for the SAS state transitions 2022-11-03 16:18:15 +01:00
Damir Jelić 7a263433c7 refactor!(crypto): Add a new SAS state that waits for a key to be sent
This patch adds a couple more states to the SAS verification state
machine. Namely we add the following states:

* KeySent
* KeysExchanged

This prevents users from confirming that the short auth string matches
before they have sent out a m.key.verification.key event, which is
necessary for the other side to present the short auth string.

The KeysExchanged state functionally replaces the KeyReceived state.
Meaning that the short auth string can only presented once we
transitioned into the KeysExchanged state.

We can transition into the KeysExchanged state from the KeyReceived
state or from the KeySent state, depending on if we first receive a
m.key.verification.key event or if we first send out our own
m.key.verification.key event.

This means that, if the transition into the KeysExchanged state happens
through the KeySent state, users won't be able to tell if the transition
happened. In other words, listening to `m.key.verification` events
doesn't work anymore, users will need to use the new `Sas::changes()`
API to listen to a stream of state changes.
2022-11-03 16:18:15 +01:00
Ivan Enderlin ee27c19bf7 chore: Removing trailing spaces. 2022-11-03 15:57:20 +01:00
Ivan Enderlin 6d21df6d29 !debug off 2022-11-03 15:37:54 +01:00
Ivan Enderlin e989bc2377 fix(crypto-js): scan_qr_code takes a reference to QrCodeScan. 2022-11-03 15:37:21 +01:00
Jonas Platte 28b44a7f03 refactor!: Rename restore_login to restore_session 2022-11-03 15:34:31 +01:00
Ivan Enderlin 265ac1f97b chore(crypto-js): Configure a profiling profile for wasm-pack. 2022-11-03 14:59:22 +01:00
Ivan Enderlin d044565caa test(crypto-js): Keep qr.toBytes() local, to avoid weird GC collection. 2022-11-03 14:57:07 +01:00
Ivan Enderlin aa7d225867 feat(crypto-js): Qr.to_bytes returns a Uint8ClampedArray. 2022-11-03 13:58:17 +01:00
Stefan Ceriu af2de2d8ef chore(ffi): Reduce the log level for some not so useful logs 2022-11-03 13:26:32 +01:00
Jonas Platte a28a664302 refactor(bindings)!: Replace RestoreToken string with Session dictionary 2022-11-03 12:58:34 +01:00
Jonas Platte c1423e9326 refactor(bindings)!: Remove is_guest
It's not used by anything and should be re-introduced in the main Rust
first if it's needed.
2022-11-03 12:58:34 +01:00
Jonas Platte 8bfc186595 feat(bindings): Add TimelineItemContent::as_unable_to_decrypt 2022-11-03 12:03:33 +01:00
Jonas Platte 0cf5356f15 feat(sdk): Add UnableToDecrypt as a variant of TimelineItemContent 2022-11-03 12:03:33 +01:00
Jonas Platte c03940e6d5 chore(sdk): Reword log messages 2022-11-03 12:03:33 +01:00
Jonas Platte f93170323b refactor(sdk): Remove unnecessary pub(crate) 2022-11-03 12:03:33 +01:00
Ivan Enderlin a3cdd31713 fix(crypto-nodejs): Pass secrets to the release workflow
fix(crypto-nodejs): Pass secrets to the release workflow
2022-11-03 11:58:59 +01:00
Ivan Enderlin fb89de8267 fix(crypto-nodejs): Pass secrets to the release workflow.
See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsecrets.
2022-11-03 11:30:10 +01:00
Ivan Enderlin 223e65fc26 !debug 2022-11-03 11:08:52 +01:00
Jonas Platte b5b2eafbec refactor(base): Remove unused Error variants 2022-11-03 10:52:11 +01:00
Jonas Platte 27b0ea1aa0 refactor(crypto): Move EncryptionNotEnabled out of MegolmError
… into matrix_sdk_base::Error because it is never constructed in the
matrix_sdk_crypto crate that defines MegolmError.
2022-11-03 10:52:11 +01:00
Jonas Platte 4c4b1f3abc refactor(bindings): Use uniffi proc-macros more in sdk-ffi 2022-11-03 09:48:41 +01:00
Jonas Platte 99e621a82b chore: Upgrade UniFFI 2022-11-03 09:48:41 +01:00
ganfra 4eedbfbc11 Merge branch 'main' into ganfra/kotlin_bindings 2022-11-02 19:06:07 +01:00
Richard van der Hoff 898265b257 Clean up build script 2022-11-02 17:22:00 +00:00
Richard van der Hoff 9d400a7494 fix JS syntax 2022-11-02 17:13:58 +00:00
Ivan Enderlin a4ca6dbf38 !debug 2022-11-02 17:25:13 +01:00
Ivan Enderlin b23d30c951 fix(indexeddb): Fix wasm_bindgen::JsValue::(from|to)_serde warnings
fix(indexeddb): Fix `wasm_bindgen::JsValue::(from|to)_serde` warnings
2022-11-02 16:58:09 +01:00
Ivan Enderlin bb96ab89f8 fix(crypto-js): Make build.sh cross-platform-ish. 2022-11-02 16:57:26 +01:00
Ivan Enderlin 4cd8a8400f chore: Reorder dep names. 2022-11-02 16:38:01 +01:00
Ivan Enderlin 28d4a69552 !fixup 2022-11-02 16:32:20 +01:00
Jonas Platte a6ca114bac chore: Upgrade UniFFI 2022-11-02 16:21:16 +01:00
Ivan Enderlin 6497d6d676 feat(crypto-js): Make scripts/build.sh compatible with macOS.
This patch also improves the “phrasing”, simplifies the code a little bit etc.
Small stuff.
2022-11-02 16:19:17 +01:00
Ivan Enderlin da93cf7dc4 fix(indexeddb): Fix wasm_bindgen::JsValue::(from|to)_serde warnings.
`wasm_bindgen::JsValue::(from|to)_serde` now emit warnings because of a
circular dependency. To solve this problem, this patch now uses `gloo-utils`,
see https://rustwasm.github.io/wasm-bindgen/reference/arbitrary-data-with-serde.html#an-alternative-approach---using-json.

Ideally, we would like to use `serde_wasm_bindgen` but the behaviour isn't
the same. `gloo-utils` serializes and deserialized through JSON, whilst
`serde_wasm_bindgen` manipulates the `JsValue` directly which can be better or
worst dependending of the case. This patch conserves the JSON approach as it
was the previous and tested one.
2022-11-02 08:59:37 +01:00
Ivan Enderlin 2b4f4b17c3 chore: Update wasm-bindgen's ecosystem to latest versions. 2022-11-02 08:59:21 +01:00
Richard van der Hoff 0f104c7433 Fix unbase64 loading 2022-11-01 13:47:44 +00:00
Jonas Platte 726e4b9aa0 fix(appservice): Fix nesting of AppServiceRouter in axum::Router 2022-11-01 11:37:16 +01:00
Jonas Platte f227f583e0 chore: Upgrade ruma-client-api 2022-11-01 11:34:05 +01:00
Jonas Platte 36444cd3a0 chore: Clean up TOML formatting 2022-11-01 11:34:05 +01:00
Jonas Platte 9c489b398d chore: Upgrade clap dependency of xtask 2022-11-01 11:34:05 +01:00
Richard van der Hoff ce03f016b9 Copy unbase64.js into the right place 2022-11-01 10:19:13 +00:00
Richard van der Hoff 4557494da6 Optimise unbase64
Use a lookup table instead of a function with if statements
2022-11-01 10:18:44 +00:00
Richard van der Hoff 093856671a Encode the WASM as base64
Some nasty hackery to get around the nastiness of the JS ecosystem
2022-10-31 22:39:44 +00:00
Ivan Enderlin 471ac07c88 fix(crypto-nodejs): Set KeepAlive to false since Node.js v19
Disable keepAlive in download-lib.js, allowing node bindings to work on Node.JS 19
2022-10-31 14:35:57 +01:00
Will Hunt f4f3ca4b25 A newline 2022-10-31 13:18:16 +00:00
Will Hunt c009f54ba9 Tidy 2022-10-31 13:17:48 +00:00
Will Hunt 546dc9a652 Run CI against 19 2022-10-31 13:04:05 +00:00
Will Hunt 717f86332f Disable keepalive to prevent hanging connections 2022-10-31 12:39:23 +00:00
Jonas Platte 6c975b01b5 Revert #1151
This reverts the commits

- cacb20e3ef
- 01cc896dab
2022-10-31 12:03:23 +01:00
Ivan Enderlin 182733e984 feat(crypto-js): OlmMachine.initialize is the new constructor
feat(crypto-js): `OlmMachine.initialize` is the new constructor
2022-10-31 11:41:50 +01:00
Andy Uhnak e4964b92a2 Local trust 2022-10-31 11:14:04 +01:00
Ivan Enderlin bdf460cd91 doc(crypto-js): Rephase something.
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2022-10-31 11:07:21 +01:00
Ivan Enderlin 0276552c72 feat(crypto-js): Use WeakRef to avoid calling free manually
feat(crypto-js): Use `WeakRef` to avoid calling `free` manually
2022-10-31 11:06:45 +01:00
Ivan Enderlin 3441c6cf9a feat(crypto-js): Use WeakRef to avoid calling free manually.
By asking `wasm-bindgen` to generate JS glue code for `WeakRef` support,
it removes the need to call `free` manually to free objects, thus we reduce
potential memory leaks inside Rust. See https:// rustwasm.github.io/docs/wasm-
bindgen/reference/weak-references.html to learn more.

It uses [`FinalizationRegistry`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry)
under the hood, I reckon it's quite common and fits into Matrix's clients needs
in terms of browser support.
2022-10-28 21:02:35 +02:00
Ivan Enderlin a07f89e340 feat(crypto-js): OlmMachine.initialize is the new constructor.
While technically a type constructor can return a `Promise`, it's not
considered as idiomatic JavaScript to do that. We are changing `new OlmMachine`
to `OlmMachine.initialize`. The rest of the code is strictly the same.
2022-10-28 20:37:46 +02:00
Benjamin Kampmann cacb20e3ef fix(ffi): Remove duplicate RequireState definition, left over after #1151 (#1155) 2022-10-28 13:38:21 +02:00
Benjamin Kampmann 255d3b7a18 Merge pull request #1154 from matrix-org/stefan/sessionVerificationFixes
Sliding Sync FFI and DevEx fixes
2022-10-28 11:40:33 +02:00
Jonas Platte 6ad7d29364 refactor(sdk): When processing remote events, check for duplicates 2022-10-28 11:30:32 +02:00
Jonas Platte 333c4f0644 refactor(sdk): Move timeline event origin_server_ts and raw_event fields
… from TimelineEventMetadata to Flow because they always exist for
remote events, and never for local echoes.
2022-10-28 11:30:32 +02:00
Jonas Platte 6ce23b17a6 refactor(sdk): Update tracing event for local echo not being found 2022-10-28 11:30:32 +02:00
Benjamin Kampmann 0cb34f7c86 fix: style fixes 2022-10-28 11:01:54 +02:00
Jonas Platte 0d84cf7b74 refactor(sdk): Make Debug format of EventTimelineItem less noisy 2022-10-28 10:56:28 +02:00
Jonas Platte f2ea72224d feat(bindings): Add {TimelineItem,EventTimelineItem}::fmt_debug 2022-10-28 10:56:28 +02:00
Jonas Platte 01cc896dab refactor(bindings): Use uniffi proc-macros a little more in sdk-ffi 2022-10-28 10:55:46 +02:00
Benjamin Kampmann 278c6059ae perf(sliding-sync): run outgoing e2ee requests and sync in parallel.
And continue the loop if even we hit an error in between
2022-10-27 15:59:02 +01:00
Benjamin Kampmann d164165c7c fix(ffi): remove extra to-device processing 2022-10-27 15:57:36 +01:00
ganfra 5a9b75c3ff kotlin-bindings: remove sample 2022-10-27 14:38:17 +02:00
ganfra c7c63fa41c Merge branch 'main' into ganfra/kotlin_bindings 2022-10-27 14:37:53 +02:00
Benjamin Kampmann 0e59078211 fix(ffi): call process_sync_error of client for sliding-sync errors. break if wnated 2022-10-27 12:32:49 +01:00
Benjamin Kampmann 120d5edb03 feat(sliding-sync): Replace anyhow with proper Error type 2022-10-27 12:32:05 +01:00
Benjamin Kampmann afc33e616c revert start_sync removal 2022-10-27 12:06:06 +01:00
Jonas Platte 324411201e fix(sdk): Enable required ruma features for experimental-timeline 2022-10-27 12:56:51 +02:00
Jonas Platte e1ecc9de0d chore: Bump versions of matrix-sdk, matrix-sdk-base
… to bring them up to the released ones from the v0.6.x branch.
All changes from those versions are already present on main.
2022-10-27 12:56:37 +02:00
Jonas Platte c9c4473cd4 ci: Cache xtask for bindings checks 2022-10-27 11:58:42 +02:00
Jonas Platte 41be4c5209 ci: Test bindings generation 2022-10-27 11:58:42 +02:00
Jonas Platte 426f60a6a2 ci: Add bindings check to xtask 2022-10-27 11:58:42 +02:00
Jonas Platte eddf202a76 chore: Upgrade UniFFI 2022-10-27 11:27:28 +02:00
Stefan Ceriu d4cd8710a4 Refactor the SessionVerification flows and get them working through sliding sync 2022-10-27 10:45:05 +03:00
Benjamin Kampmann a443e7277d feat: Add sliding sync timeline events and extensions (#1054)
Add general extension framework for sliding sync, implementing the e2ee, to-device and account-data extensions as per existing proxy implementation. Add a new (ffi exposed) function to use activate the extensions.

Also extends jack-in to have permanent login and storage support now, rather than posting an access token and expose messages inside the sliding-sync layer to actually use the decrypted messages if given. Contains a lot of fixes around these aspects, too, like uploading any remaining messages from the olm-machine on every sliding-sync-request or processing even if no room data is present (which can happen now as processing only extensions might takes place).
2022-10-25 13:42:43 +02:00
Jonas Platte 2232092f11 refactor(sdk): Move timeline event handling fns to TimelineInner 2022-10-25 13:03:52 +02:00
Damir Jelić 2547d6ed64 fix(crypto): Don't create an infinite amount of streams in the SAS examples 2022-10-25 13:00:27 +02:00
Damir Jelić 6cb37520ce docs(bindings): Document the EncryptionSettings a bit better 2022-10-25 12:44:18 +02:00
Jonas Platte 50a5ec89e9 chore: Fix more clippy lints 2022-10-25 12:20:07 +02:00
Jonas Platte 285dc129c3 chore(crypto): Clean up SecretInfo::as_key implementation 2022-10-25 12:20:07 +02:00
Jonas Platte a59fdc08bb chore: Fix clippy lints
Automated with cargo clippy --fix.
2022-10-25 12:20:07 +02:00
Jonas Platte 9de98dfa65 fix(sdk): Remove token field from SyncSettings Debug output 2022-10-24 13:14:30 +02:00
Damir Jelić c03c90c1cf feat(bindings)!: Allow passing the E2EE settings when sharing a room key 2022-10-24 09:50:57 +02:00
Damir Jelić 4a6208f808 feat(crypto): Add signaling to the SAS verification
This patch adds a way for users to listen to changes in the state of a
SAS verification.

This makes it much more pleasant to go through the verification flow and
incidentally easier to document it.
2022-10-24 09:50:17 +02:00
Jonas Platte 1aa48beca9 Revert "refactor(bindings): Use new uniffi::Enum derive macro in crypto-ffi"
This reverts commit 6b9075aa42.
2022-10-20 17:41:16 +02:00
Jonas Platte e05444554d chore: Fix typo in comment 2022-10-20 14:14:18 +02:00
Jonas Platte 411095425c refactor(sdk): Make ClientBuilder::{sled_store, indexeddb_store} simple setters 2022-10-20 13:35:06 +02:00
Jonas Platte 6b9075aa42 refactor(bindings): Use new uniffi::Enum derive macro in crypto-ffi 2022-10-20 12:53:09 +02:00
Jonas Platte 01dc166293 chore: Upgrade UniFFI 2022-10-20 12:53:09 +02:00
Jonas Platte 584a82b19b fix(sdk): Remove Debug implementation for SessionTokens 2022-10-20 11:25:54 +02:00
Jonas Platte 0aba22855b fix(sdk): Don't include access and refresh token in Debug output of Session 2022-10-20 11:25:54 +02:00
Jonas Platte a50743874f chore(base): Merge consecutive impls for the same type 2022-10-20 11:25:54 +02:00
Flix 7851eefb61 refactor(base)!: Get rid of String in StoreError 2022-10-19 16:28:27 +02:00
Stefan Ceriu 8470b494f4 chore(bindings): Replace various expectations with anyhow contexts 2022-10-19 13:18:19 +02:00
Andy Uhnak c92d946777 Set local trust 2022-10-19 09:38:16 +02:00
Jonas Platte 0cfc7540cf refactor: Use workspace dependencies for tracing 2022-10-18 19:24:22 +02:00
Jonas Platte 6990c1ca5c test(base): Use tracing-subscriber for test debugging
… same as in our other crates.
2022-10-18 19:24:22 +02:00
Jonas Platte 0ee63344da chore(base): Sort dev-dependencies 2022-10-18 19:24:22 +02:00
Jonas Platte 3daaa457e1 fix(bindings): Make tracing dependency for crypto-js optional 2022-10-18 19:24:22 +02:00
Jonas Platte 7a826fb7d6 ci: Cancel all CI jobs for old commits when pushing to a PR branch 2022-10-18 17:06:42 +02:00
Jonas Platte 95dfedb70a Another test commit 2022-10-18 16:52:01 +02:00
Jonas Platte eb58dcc556 Try to make it work 2022-10-18 16:51:07 +02:00
Damir Jelić 57e9b36fac chore(bindings): Don't mention that the OlmMachine is a memory-only one 2022-10-18 15:49:09 +02:00
Damir Jelić 90865e2a0a chore(bindings): Clarify the OlmMachine constructor in the WASM bindings 2022-10-18 15:49:09 +02:00
Damir Jelić 52d96ceb60 fix(bindings): Allow setting the store without a passphrase 2022-10-18 15:49:09 +02:00
Damir Jelić 8a720af215 feat(crypto): Support transitioning from a QR verification into a SAS or scanning QR one 2022-10-18 15:18:51 +02:00
Jonas Platte bac95f4494 ci: Upgrade cancel-workflow-action 2022-10-18 15:00:35 +02:00
Jonas Platte 31293c6c2b Testing with empty commit 2022-10-18 14:39:47 +02:00
Jonas Platte 089f92d238 ci: Cancel all CI jobs for old commits when pushing to a PR branch
(not just jobs from the ci workflow file)
2022-10-18 14:23:21 +02:00
Andy Uhnak 1a466eb667 Add flow_id to logs 2022-10-18 13:09:12 +01:00
Andy Uhnak 8bbdd28a8b Use cfg-if and debug logs 2022-10-18 13:09:11 +01:00
Andy Uhnak 61452ad190 Replace QR with SAS verification 2022-10-18 13:08:47 +01:00
Flix 4816d93e96 docs: Improve documentation for custom event handler context 2022-10-18 13:39:08 +02:00
Jonas Platte f25af209e1 refactor: Use workspace dependencies for zeroize 2022-10-18 13:38:05 +02:00
Jonas Platte e6891addfb refactor: Use workspace dependencies for vodozemac 2022-10-18 13:38:05 +02:00
Jonas Platte f57b7782f4 refactor: Use workspace dependencies for ruma 2022-10-18 13:38:05 +02:00
Jonas Platte e91cee7154 fix(sdk): Always send an access token for get_profile 2022-10-18 13:31:59 +02:00
Jonas Platte 5b46fa73e1 fix(sdk): Always send an access token for get_display_name 2022-10-18 11:19:32 +02:00
Jonas Platte b309441dec fix(sdk): Don't log the access token in HttpClient::send 2022-10-17 20:04:49 +02:00
Jonas Platte 391efcec12 feat(appservice): Return a concrete type from AppService::service 2022-10-17 17:03:37 +02:00
Jonas Platte 4e583bcb8a chore: Exclude xtask from tarpaulin coverage collection 2022-10-17 15:38:42 +01:00
Benjamin Kampmann 5e621b7132 fix!: Switch to uniffi 0.21.0 and workspace-wide dependencies
Upgrade MSRV to 1.64, the first stable release to support workspace-wide depenendencies:
https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#cargo-improvements-workspace-inheritance-and-multi-target-builds
2022-10-17 15:38:04 +01:00
Benjamin Kampmann ab796cb32c ci(xtask): switch to using uniffi as a lib rather than globally installed binary 2022-10-17 15:38:04 +01:00
Richard van der Hoff dd82e0b8fc chore: Update bindings/README 2022-10-17 13:24:09 +00:00
Doug 7125730917 ci(xtask): Switch to xtask for swift; run swift tasks on macOS
Merge pull request #1023 from matrix-org/doug/swift-linux: Run Swift tests on macOS
2022-10-17 14:12:43 +02:00
Jonas Platte db2771bd17 feat(bindings): New timeline API 2022-10-17 13:40:35 +02:00
Jonas Platte 95face4aa4 chore(bindings): Delete unused code left over from old timeline API 2022-10-17 13:40:35 +02:00
Jonas Platte a7cb80df1b refactor(appservice): Clean up implementation of user_id_is_in_namespace 2022-10-13 12:13:56 +02:00
ganfra e7d5b44343 Kotlin bindings: add matrix-rust-sdk.aar file to sample 2022-10-12 18:24:30 +02:00
ganfra 47478702b2 Kotlin bindings: create build_sdk script 2022-10-12 18:24:30 +02:00
ganfra 648895e2b0 Kotlin bindings: add uniffi.toml 2022-10-12 18:24:30 +02:00
ganfra c8bddea6e1 Kotlin bindings: update Cargo.toml for kotlin generation 2022-10-12 18:24:30 +02:00
ganfra f42215180e Kotlin bindings: create project with sample, crypto and sdk modules 2022-10-12 18:24:12 +02:00
Jonas Platte 1e77e91ec4 refactor(appservice): Replace warp with axum 2022-10-12 17:32:31 +02:00
Jonas Platte 95613be6c9 chore: Remove redundant cfg attribute 2022-10-12 17:32:31 +02:00
Jonas Platte b83e6be01e refactor(sdk): Use lower-level libraries for builtin SSO server 2022-10-12 17:32:31 +02:00
Damir Jelić 086b6127e2 feat: Improve the timeline example 2022-10-12 16:12:06 +02:00
Jonas Platte 54fd40d8f5 feat(sdk): Add new timeline API 2022-10-12 16:12:06 +02:00
Damir Jelić 67d968d4fa refactor(crypto): Remove the device ID from the megolm v2 m.room.encrypted content 2022-10-12 14:37:05 +02:00
Damir Jelić 7e14857239 test(crypto): Test that megolm v2 key forwards work 2022-10-12 14:37:05 +02:00
Damir Jelić 2425cd99cf fix(crypto): Introduce the proper megolm v2 forwarded room key content 2022-10-12 14:37:05 +02:00
Damir Jelić 7c97c27441 feat(crypto): Start sending out megolm v2 room key requests 2022-10-12 14:37:05 +02:00
Damir Jelić cbadd90eff feat(crypto): Start responding to megolm v2 room key requests 2022-10-12 14:37:05 +02:00
Jonas Platte d18b57dcdd refactor: Make use of as_ruma_api_error internally 2022-10-12 12:34:09 +02:00
Jonas Platte 23c5929cfa feat(sdk): Add Error::as_ruma_api_error 2022-10-12 12:34:09 +02:00
Jonas Platte 7bfa622a57 feat(sdk): Add HttpError::as_ruma_api_error 2022-10-12 12:34:09 +02:00
Jonas Platte f4e0cab11f feat(sdk)!: Merge HttpError::UiaaError into HttpError::Api 2022-10-12 12:34:09 +02:00
Jonas Platte f07735291e Fix warnings from generated code 2022-10-10 19:24:56 +02:00
Anderas d4e7076e1d Compile Crypto FFI for MacOS 2022-10-10 18:59:25 +02:00
Jonas Platte 61e95abaf2 refactor: Use Box::default
… as suggested by clippy.
2022-10-10 18:52:59 +02:00
Damir Jelić 8763a2468c fix(crypto): Take more data into account when comparing sessions 2022-10-10 15:20:25 +02:00
Damir Jelić 8f6e3033e3 fix(crypto): Check for existing room keys when receiving a new one.
Now that we're not scoping the room keys by the Curve25519 sender key
we're opening the door of multiple devices trying to insert the same
room key into our store.

This patch changes our logic so we only store room keys from an
m.room_key event if we don't have one already or if the new key is
a better version of the one we already have.

This mostly assumes that the first room key with a given session id
is coming from the creator of the room key.
2022-10-10 15:20:25 +02:00
Damir Jelić 2f94886663 refactor(crypto)!: Don't use the Curve25519 sender key to store room keys 2022-10-10 15:20:25 +02:00
Jonas Platte 8b728d4ada ci: Pin typos version
Currently, master is broken: https://github.com/crate-ci/typos/issues/590
2022-10-06 17:27:55 +02:00
Jonas Platte 26faf0d4c0 feat(bindings): Add custom kotlin package name for crypto-ffi 2022-10-06 17:27:55 +02:00
Jonas Platte a3113bd125 refactor(bindings): Start using #[uniffi::export] for matrix-sdk-crypto-ffi 2022-10-06 17:27:55 +02:00
Jonas Platte a75d7171f8 refactor(bindings): Rename crypto-ffi UniFFI namespace
… from olm to matrix_crypto_ffi to match the lib name.
Names need to match for integration of UniFFI's proc-macro frontend.
2022-10-06 17:27:55 +02:00
Jonas Platte c3eaa864dd refactor(bindings): Unset custom lib name for crypto-ffi 2022-10-06 17:27:55 +02:00
Jonas Platte 6a561c20e2 refactor(bindings): Use uniffi::export for most of ClientBuilder's API 2022-10-06 10:56:22 +02:00
Jonas Platte 0581b8a884 refactor: Derive Default for enums 2022-10-06 10:55:49 +02:00
Jonas Platte bdfdaeb0ae chore: Upgrade async-once-cell 2022-10-06 10:55:49 +02:00
Jonas Platte c24c20f7f1 Raise MSRV to 1.62 2022-10-06 10:55:49 +02:00
Jonas Platte 6b3acf1bf7 chore(sdk): Use inline tables more in Cargo.toml
Makes the file a little more comprehensible.
2022-10-06 10:55:49 +02:00
Jonas Platte 822cdae8f3 chore(sdk): Only include derive_builder dependency for sliding-sync feature 2022-10-06 10:55:49 +02:00
Jonas Platte 4fcbb61145 refactor!: Delete the store module
It was very confusing that matrix_sdk::store::make_store_config's first
argument was either a path or a database name depending on the build
configuration. ClientBuilder::{sled_store, indexeddb_store} are also
easier to use.
2022-10-05 13:49:12 +02:00
Jonas Platte 4628481d0e refactor(bindings): Use UniFFI proc-macro frontend more 2022-10-05 12:21:44 +02:00
Jonas Platte e05de8d4ce chore: Upgrade UniFFI 2022-10-05 12:21:44 +02:00
Johannes Marbach 6bc79b04cf feat(bindings): Allow clients using matrix-sdk-ffi to set the user agent 2022-10-05 09:18:52 +02:00
Damir Jelić fa88751548 fix(crypto): Ignore duplicate verification requests 2022-10-04 13:38:07 +02:00
Andy Uhnak 09c906b1d7 Debug message 2022-10-04 11:50:16 +01:00
Andy Uhnak 6fab6ef318 Ignore duplicate verification requests 2022-10-04 11:38:08 +01:00
Lautaro Bustos d5728f235d feat(sdk): Allow configuring the presence in the SyncSettings 2022-10-03 11:52:23 +02:00
Johannes Marbach 6827c70886 chore: Ignore Swift's .build folder 2022-09-30 21:54:09 +02:00
Jonas Platte ab1a6a6b37 chore: Remove experimental-timeline Cargo feature 2022-09-30 13:48:17 +02:00
Jonas Platte 3c9c7290ae chore: Remove deprecated functions 2022-09-30 10:40:56 +00:00
Benjamin Kampmann 530f8057cc Merge pull request #1071 from matrix-org/ben-releasing-0.6
chore: crates.io only accepts versioned git deps
2022-09-29 15:02:10 +02:00
Ivan Enderlin 8e0e752f12 Merge pull request #1075 from Hywan/fix-crypto-nodejs-release-script-npm-token
fix(crypto-nodejs): Hopefully it will make `NPM_TOKEN` available in the script
2022-09-29 11:52:30 +02:00
Ivan Enderlin b1493c5217 fix(crypto-nodejs): Hopefully it will make NPM_TOKEN available in the script.
We hope that adding this to the workflow will make `NPM_TOKEN`
available from within the script.
2022-09-29 11:36:29 +02:00
Ivan Enderlin 7988dc6cf3 Mergfix(crypto-nodejs): Fix the prep release script
fix(crypto-nodejs): Fix the prep release script
2022-09-28 17:48:43 +02:00
Ivan Enderlin 180796c747 fix(crypto-nodejs): Fix the prep release script. 2022-09-28 17:46:56 +02:00
Benjamin Kampmann fefd2a6b68 chore: crates.io only accepts versioned git deps 2022-09-28 17:15:09 +02:00
Benjamin Kampmann 269bf3a706 chore: remove old release notes 2022-09-28 17:07:37 +02:00
Benjamin Kampmann 91d1ee9f09 chore: fix typos in Upgrade guide 2022-09-28 17:07:37 +02:00
Benjamin Kampmann b22fe63476 chore: More minor changes of note 2022-09-28 17:07:37 +02:00
Benjamin Kampmann 92467af4a0 docs: Upgrading typo fixes 2022-09-28 17:07:37 +02:00
Benjamin Kampmann f1f1c1bba6 chore: Version bump 2022-09-28 17:07:37 +02:00
Benjamin Kampmann ff82d6420d chore: specify which crates to release and which not 2022-09-28 17:07:37 +02:00
Benjamin Kampmann b9409b7c0f docs: more migrations guide 2022-09-28 17:07:37 +02:00
Benjamin Kampmann ea51935601 docs: Clarifications in the Upgrade guide 2022-09-28 17:07:37 +02:00
Benjamin Kampmann 2fff5d916b docs: More Upgrade guidance 2022-09-28 17:07:37 +02:00
Benjamin Kampmann d16faee68b docs: First outline of upgrades guide 2022-09-28 17:07:37 +02:00
Benjamin Kampmann df9b60a5bc chore: Ignore flaky redaction tests 2022-09-28 17:07:10 +02:00
Damir Jelić 1a57170970 test(crypto): Make sure we don't accept megolm encrypted events over to-device 2022-09-28 16:03:17 +02:00
Damir Jelić 41449d2cc3 test(crypto): Test that we reject forwarded room keys from other users 2022-09-28 16:03:17 +02:00
Damir Jelić 093fb5d0aa fix(crypto): Only accept forwarded room keys from our own trusted devices 2022-09-28 16:03:17 +02:00
Ivan Enderlin 513afa57ef feat(indexeddb): Introduce the experimental-nodejs feature
feat(indexeddb): Introduce the `experimental-nodejs` feature
2022-09-28 14:57:55 +02:00
Ivan Enderlin 25632f04d4 feat(crypto-js): Update to napi-rs 2.9.1
feat(crypto-js): Update to `napi-rs` 2.9.1
2022-09-28 14:52:03 +02:00
Ivan Enderlin 7922786e0c chore: Fix formatting. 2022-09-28 14:34:16 +02:00
Ivan Enderlin 9a006c58f5 feat(crypto-js): Update to napi-rs 2.9.1 2022-09-28 14:30:40 +02:00
Ivan Enderlin 9f4385e639 feat(indexeddb): Introduce the experimental-nodejs feature.
By default, the new `experimental-nodejs` feature is
disabled. However, when enabled, it uses our own fork of
`indexed_db_futures` that make it work on Node.js, and so this entire
`matrix-sdk-indexebdb` crate.
2022-09-28 14:27:37 +02:00
Damir Jelić e79b683560 fix(crypto): Drop the redundant event_type field from ToDeviceEvent<C> 2022-09-28 11:27:44 +02:00
Damir Jelić 27e4675df0 fix(crypto) Fix the zeroizing serialization of to-device events
The crypto crate consumes to-device events, if needed decrypts them, and
in the end reserializes while zeroizing secrets.

It needs to do this reserialization cycle as loslessly as possible, this
is why we have a bunch of BTreeMaps lying in events and contents that
capture unknown fields.

The Deserialize implementation of ToDeviceEvent<C> put the event type
into this BTreeMap but the Serialize implementation figures it out from
the EventType trait of the content.

This patch simplifies things by putting the event type into
ToDeviceEvent<C>, this also means that we can just derive the Serialize
implementation for ToDeviceEvent<C>.
2022-09-27 21:33:06 +02:00
Benjamin Kampmann b5bd6dfee9 fix: Apply redactions to room state events in database, too (#917)
fixes #890
2022-09-27 09:24:53 +02:00
Ivan Enderlin f8b02d1a11 feat(crypto-js): Implement OlmMachine.export_room_keys and .import_room_keys
feat(crypto-js): Implement `OlmMachine.export_room_keys` and `.import_room_keys`
2022-09-27 07:26:51 +02:00
Jonas Platte 0a5ebe4dce feat(sdk): Make EventHandlerDropGuard public (#1055) 2022-09-26 18:18:12 +02:00
Benjamin Kampmann e8278b5d68 feat: add Result return value to sync_* (#1037)
Inspired by the changes in #1013 I was thinking about the use case for `sync_*` and how we handle error cases. Most notably while we give the callback the option to stop the loop, we don't really give an indication to the outside, how to interpret that cancellation: was there a failure? should we restart?

Take e.g. a connectivity issue on the wire, we'd constantly loop and just `warn`, what you might or might not see. Even if you handle that in the `sync_with_result_callback` and thus break the loop, the outer caller now still doesn't know whether everything is honky dory or whether they should restart. 

This Changes reworks that area by having all the `sync` return `Result<(), Error>`, where `()` means it was ended by the inner callback (which in `sync()` never occurs) or `Error` is the error either the inner `result_callback` found or the that was coming from the `send` in the first place. Thus allowing us to e.g. back down to sync as it was a dead wire or restart it if there was only a temporary problem. Making all that a just a bit more "rust-y".
2022-09-26 17:14:15 +02:00
Jonas Platte f054141e66 chore: Revert "feat(sdk): Make room actions return typed room objects" 2022-09-26 14:13:25 +02:00
Jonas Platte 1a6d5e7b26 Revert "feat(sdk): Make room actions return typed room objects"
This reverts commit febfcf9796.
2022-09-26 14:01:52 +02:00
Jonas Platte d3e5a3b7db Revert "test: Add test for repeated joining and leaving"
This partially reverts commit df4ee7db4c.
The changes to logging and ci-start.sh are kept.
2022-09-26 12:31:12 +02:00
Jonas Platte 92809590b1 Revert "feat(examples): Add an example that lets you create rooms"
This reverts commit 01f8ed10aa.
2022-09-26 12:23:08 +02:00
Jonas Platte 00d388f3d3 Revert "feat(sdk): Make room actions return typed room objects"
This reverts commit febfcf9796.
2022-09-26 12:19:36 +02:00
Jonas Platte 59901b6349 Update Cargo.lock 2022-09-26 12:19:36 +02:00
Johannes Becker 914ac5279e chore: Make clippy happy 2022-09-23 17:01:01 +02:00
Johannes Becker c23976f975 refactor(appservice): Move example to top-level 2022-09-23 17:01:01 +02:00
Emelie Graven cb94d60e0e feat(appservice): Add default request config
This adds a default RequestConfig to use when creating new virtual
clients.
2022-09-22 14:25:00 +02:00
Ivan Enderlin df50a5446f test(crypto-js): Test InboundGrounSession.sessionId and .hasBeenImported. 2022-09-22 11:31:28 +02:00
Ivan Enderlin 62ab263d0e test(crypto-js): Test OlmMachine.(en|de)crypt_exported_room_keys. 2022-09-22 11:27:12 +02:00
Emelie Graven 2818551d62 refactor(appservice)!: Use builder pattern 2022-09-22 10:38:17 +02:00
Emelie Graven c29b0f154a chore: Add rust.vim edition workaround 2022-09-22 10:38:17 +02:00
Ivan Enderlin 6fa04a0ba1 feat(crypto-js): Implement OlmMachine.(en|de)crypt_exported_room_keys. 2022-09-21 18:00:15 +02:00
Ivan Enderlin dee14c4ee4 doc(crypto-js): Improve documentation of OlmMachine.import_room_keys. 2022-09-21 17:50:28 +02:00
Ivan Enderlin 5b919dd840 test(crypto-js): Test OlmMachine.import_room_keys. 2022-09-21 17:46:23 +02:00
Ivan Enderlin 406fc58720 feat(crypto-js): Implement OlmMachine.import_room_keys. 2022-09-21 17:37:23 +02:00
Ivan Enderlin b4cec6e1bb feat(crypto-js): Implement OlmMachine.export_room_keys. 2022-09-21 16:03:51 +02:00
Ivan Enderlin 6be0fc1fae feat(sdk): Rename (export|import)_keys to (export|import)_room_keys
feat(sdk): Rename `(export|import)_keys` to `(export|import)_room_keys`
2022-09-21 16:03:29 +02:00
Ivan Enderlin 782b256ea9 test(crypto): Rename OlmMachine.export_keys to OlmMachine.export_room_keys. 2022-09-21 13:43:25 +02:00
Ivan Enderlin 82670022f9 feat(crypto-ffi): Update olm.udl. 2022-09-21 13:24:25 +02:00
Ivan Enderlin b8c41e805b feat(sdk): Rename decrypt_key_export to decrypt_room_key_export. 2022-09-21 13:18:24 +02:00
Ivan Enderlin e3d63c5593 feat(sdk): Rename encrypt_key_export to encrypt_room_key_export. 2022-09-21 13:16:08 +02:00
Ivan Enderlin 0222a8fec2 feat(sdk): Rename OlmMachine.import_keys to .import_room_keys.
Because that's what it does :-).
2022-09-21 13:12:07 +02:00
Ivan Enderlin b442247946 feat(sdk): Rename OlmMachine.export_keys to .export_room_keys.
Because that's what it does :-).
2022-09-21 13:03:42 +02:00
Ivan Enderlin c0ebeee730 feat(crypto-js): Implement OlmMachine.get_identity
feat(crypto-js): Implement `OlmMachine.get_identity`
2022-09-21 10:44:18 +02:00
Stefan Ceriu a46b8f392a Switch ffi layer logs output to stderr instead of stdout 2022-09-21 08:24:09 +02:00
Jonas Platte b12da9d4db refactor!: Move JS-specific functionality behind a Cargo feature
… for matrix-sdk, matrix-sdk-base, matrix-sdk-common and matrix-sdk-crypto.
matrix-sdk-indexeddb as well as the JS bindings and wasm_command_bot are
left as-is because they will likely always require JS.
2022-09-20 14:08:21 +02:00
Stefan Ceriu 6f5681f7c2 feat(bindings): Expose method for fetching media thumbnails 2022-09-19 10:56:22 +00:00
Jonas Platte fee0db03c8 ci: Don't collect coverage for labs 2022-09-19 12:15:13 +02:00
Jonas Platte b2ce906bce ci: Don't report coverage inside test code 2022-09-19 12:15:13 +02:00
Jonas Platte e45d6f45fd refactor: Replace str::to_string with to_owned 2022-09-16 17:45:43 +02:00
Ivan Enderlin 84aa85958c test(crypto-js): Test OlmMachine.getIdentity. 2022-09-16 11:23:32 +02:00
Jonas Platte b941c16b7d chore(sdk): Upgrade derive_builder 2022-09-16 11:17:24 +02:00
Ivan Enderlin 1a5379881e test(crypto-js): Test EventId. 2022-09-16 11:11:06 +02:00
Ivan Enderlin 0c4b85e1f9 feat(crypto-js): Implement OwnUserIdentity and UserIdentity. 2022-09-16 11:02:34 +02:00
Ivan Enderlin 602dbe42f2 doc(crypto): Fix a typo. 2022-09-16 10:57:02 +02:00
Ivan Enderlin d3d316ee6c chore(crypto-js): Add helper to cast from JS Array to Vec<T>. 2022-09-16 10:46:28 +02:00
Jonas Platte 494969ed49 chore: Fix clippy lints 2022-09-15 20:48:22 +02:00
Kévin Commaille 34ed04958f fix(sdk): Export RoomKeyImportError 2022-09-15 18:35:59 +02:00
Jonas Platte 8da456055d refactor: Use event handlers in emoji_verification example 2022-09-15 18:33:58 +02:00
Jonas Platte ef462c786a refactor(sdk): Clean up sync_with_callback implementation 2022-09-15 17:53:32 +02:00
Benjamin Kampmann 1a50f42402 fix(jack-in): limit log4rs features to minimum 2022-09-15 17:08:09 +02:00
Benjamin Kampmann 020a75d55c feat: implement " MSC 3575: sliding sync " behind a feature flag (#728)
* starting with jack-in

* starting by flying tui

* connecting to real server, showing info

* add .env to gitignore

* infrastructure for tests

* display loading time for syncv2

* minor design updates

* initial sync

* finalise first edition of sliding sync

* directly link to sliding sync and show rooms list

* nicer UI, toggle logs

* passing through sliding sync homeserver

* separate syncs and disable v2 autostart

* selecting rooms

* nicer view

* configurable batches and more default needed events

* selecting rooms

* calculate and show status info per room

* precalculated room stats

* restructure code to allow for cancellation of streams

* finish up merge updates

* fix calculation error in room list len

* cleaning up system flow

* fixing sync up

* new multi-view API

* move sliding sync in separate module

* fixing format

* adding and clearning views

* expose filters and timeline limits

* renamed

* adding room subscriptions to sliding sync

* update summary

* live fetching and subscriptions in jack-in

* subscribe to selected room

* starting to switch to tuireal - using example

* status bar and first linkup

* re-adding rooms

* implementing port for customised update event

* showing details and timeline

* fix formatting

* cleaner UI, updating details quickly

* make it green

* implement other Ops

* proper handling of invalidation

* saving sliding sync results to db, too

* saving new prev_batch field if given

* split events and timeline

* cleaning up

* live updates

* upgrading to latest ruma and matrix-sdk

* Update tui-logger to fix the broken build

* fixing latest ruma sliding-sync-branch updates

* feat: first set of ffi sliding sync

* expose sliding sync via FFI

* implement un-/subscribe

* implement view state updates

* updating to latest JSON format and ruma update

* implementing room selecting for new data model

* fixing room selection

* fixing feature flag requirements for sliding-sync

* fixing style, clippy and docs

* style(sliding-sync): fixing rust format styles

* fix(ffi): fixing sliding sync merge failure

* fix(jack-in): update jack-in to latest ruma

* fix(sliding-sync): need to have a version set before polling proxy

* expose sliding sync builder over ffi

* add SlidingSyncViewBuilder

* add forgotten changes on sdk itself

* new file logger feature on jack for deeper logging

* fix(http-client): log the raw request we are sending out

* feat(sliding-sync): better logging

* fix(sliding-sync): switch to full-listen after reaching live state in full-sync and make sure we replace the correct entries

* feat(ffi): expose sliding sync view ranges

* fix(ffi): fixing sliding sync start_sync loop to actually loop

* feat(sliding-sync): allow lookup of room data

* feat(sliding-sync-ffi): fetching name of room

* feat(ffi): expose unread_notifications of rooms

* feat(ffi): stoppable spawn for sliding sync

* fix(ffi): expose has_unread_notifications on room

* feat(sliding-sync): latest room message

* fix(sliding-sync): update to latest ruma layout

* doc(sliding-sync): adding docs to builder fns

* feat(sliding-sync): extra signal on the view to inform about general updates

* fix(sync-v4-ffi): expose new callbacks via ffi

* fix(sliding-sync): reduce default required states to make things faster

* fix(sliding-sync): fix build params

* feat(jack-in): extended instrumentation

* fix(sliding-sync): unbreak faulty feature-gate

* fix(sliding-sync-ffi): mut where mut is due

* fix(sdk): allow separate homeserver on every request to unbreak using send on client while in sliding sync on a proxy

* fix(jack-in): update to latest dependencies, that work

* feat(ffi): helper to patch sliding sync room into regular room

* style(jack-in): cargo fmt

* fix(sliding-sync): Update to latest ruma changes

* fix(sliding-sync): fix missing FFI updates to latest ruma

* feat(sliding-sync)!: simplify stream cancellation, cancel ffi sync if already existing

* fix: timeline backwards pagination must work without synctoken

* fix(sliding-sync): clarify order of messaes in alive TL; pick correct last item

* fix: update view delegate api for clarity

* style(jack-in): fix cargo warnings

* feat(sliding-sync): update room details

* fix(sliding-sync): only update room info selectively when given

* fix(sliding-sync-ffi): convert and store counts as u32, check against 0 for has notificaitons

* style: cargo fmt, file endings and a few other minor style fixes

* docs(jack-in): improving CLI and Readme

* feat(sliding-sync): allow setting of required event_states on viewbuilder

* style(sliding-sync): docs and minor fixes

* style(sliding-sync): various clippy fixes

* style(jack-in): clippy suggestions applied

* fix(sliding-sync): Delegate becomes observer

* test(sdk): adding test for request config

* docs: Fixing copyright header

* style(ffi): Nicer naming of params for observer

* fix(ffi): sliding sync is not optional for now

* fix(sdk): remove superflusous tracing instrumentation

* fix(sdk): use structured logging

* fix(jack-in): removed unneded log import

* fix(jack-in): use server_name rather than deprecated user_id on ClientBuilder

* style: typo and clippy

* style(sliding-sync): clippy and formatting

* fix(sliding-sync): cleaning up minor syntax issues

* fix: remove unneded feature-definition section

* fix(sliding-sync): minor fixes as per review

* fix(sliding-sync): Make Builders owned

* fix(sliding-sync): more minor style improvements

* fix(sliding-sync): minor style improvements

* fix(sliding-sync): remove homeserver from RequestConfig, use specific internal fn instead

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
2022-09-15 11:45:29 +00:00
Ivan Enderlin f4e0c6e243 feat(crypto-js): Start implementing OlmMachine.get_identity. 2022-09-15 10:32:57 +02:00
Ivan Enderlin 01f1b9b846 feat(crypto-js): Implement EventId. 2022-09-15 10:32:57 +02:00
Ivan Enderlin abcd287496 chore(crypto-js): Simplify code with a lovely macro. 2022-09-15 10:32:57 +02:00
Ivan Enderlin cf96a3ba2e feat(crypto-js): Implement key verification
feat(crypto-js): Implement key verification
2022-09-15 10:13:51 +02:00
Ivan Enderlin 9d2e0fe8ad doc(crypto-js): Fix typos. 2022-09-15 09:59:27 +02:00
Jonas Platte 83d5e567eb feat(bindings): Update send_reply to accept markdown 2022-09-14 22:10:16 +02:00
Benjamin Kampmann a47d8669cd feat: log out facilities
Merge pull request #1013 from matrix-org/ismail/logout

Add logout facilities to `client` and helpers to ffi for tracking the soft-logout issued by a server. Further more this adapts the `sync_with_callback` by adding a new `sync_with_result_callback` that hands the entire `Result` to the callback.
2022-09-14 15:15:47 +02:00
ismailgulek 0643292d76 Fix formatting 2022-09-14 15:07:05 +03:00
ismailgulek 8a26ba8343 Add a warning on sync error 2022-09-14 14:29:30 +03:00
ismailgulek cc1c6aedcb Revert sync_with_callback api call changes 2022-09-14 14:17:30 +03:00
ismailgulek 55cf573142 Implement the new sync with result callback method 2022-09-14 14:10:01 +03:00
Stefan Ceriu c5006081e6 feat(bindings): Add method for sending plain text replies 2022-09-14 10:21:23 +00:00
Ivan Enderlin 4c4fcf91c1 chore(crypto-js): Inline vodozemac dependency. 2022-09-14 10:01:03 +02:00
Ivan Enderlin 6842fb97fd chore(crypto-js): Make Clippy happy. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 8027a3036c test(crypto-js): Remove dependency to canvas. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 1d9ac6e60c chore(crypto-js): Fix typos. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 2f35b2cfc6 feat(crypto-js): QrCodeScan implements Debug. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 7edd6a148c doc(crypto-js): Fix module documentation. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 3b526ea412 doc(crypto-js): Add missing documentation. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 1c50cee5d7 feat(crypto-js): Implement Sas and Qr cancel* methods. 2022-09-14 09:58:09 +02:00
Ivan Enderlin cb95c59194 test(crypto-js): Test m.key.verification.start and .done for QR code. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 792b4581ab feat(crypto-js): Implement Qr.reciprocate and .confirm_scanning. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 58ea598c68 feat(crypto-js): Implement VerificationRequest.scan_qr_code. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 581c537396 test(crypto-js): Properly test `Qr.toQrCode. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 9834b67bd5 feat(crypto-js): QrCode.renderIntoBuffer returns an Uint8ClampedArray. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 6f89d02599 test(crypto-js): Test QrCode.render_into_buffer. 2022-09-14 09:58:09 +02:00
Ivan Enderlin cbb5080837 test(crypto-js): Properly test Qr.toBytes. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 6a05f834a9 test(crypto-js): Test Qr.toBytes. 2022-09-14 09:58:09 +02:00
Ivan Enderlin c7e0b3ee31 test(crypto-js): Testing key verification workflow until QR code generation. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 0d57983e1b feat(crypto-js): Implement VerificationRequest.generate_qr_code. 2022-09-14 09:58:09 +02:00
Ivan Enderlin bbfc076c7f test(crypto-js): Inject bootstrap cross signing keys when setting up machines. 2022-09-14 09:58:09 +02:00
Ivan Enderlin e367d8574d feat(crypto-js): Implement OlmMachine.bootstrap_cross_signing. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 1be17d354d feat(crypto-js): Implement OlmMachine.(export|import)_cross_signing_keys. 2022-09-14 09:58:09 +02:00
Ivan Enderlin e8331cc40c feat(crypto-js): Enable the qrcode feature by default. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 71a2fac46f test(crypto-js): Reorganize the tests a little bit. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 8948333e1e test(crypto-js): Test until m.key.verification.done \o/. 2022-09-14 09:58:09 +02:00
Ivan Enderlin c471a6fb4d test(crypto-js): Split the Key Verification test case into a test suite. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 6239d31bcf test(crypto-js): Test the Emoji and decimals implementations. 2022-09-14 09:58:09 +02:00
Ivan Enderlin b5a8103023 feat(crypto-js): Implement Sas.accept. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 95709bb4b3 test(crypto-js): Test the Sas implementation. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 14f22979c0 feat(crypto-js): Implement VerificationRequest.start_sas. 2022-09-14 09:58:09 +02:00
Ivan Enderlin e6141d8efc test(crypto-js): Continue to test m.key.verification.request and .ready. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 155b187d45 test(crypto-js): Write first tests for key verification. 2022-09-14 09:58:09 +02:00
Ivan Enderlin e659c724cd chore(crypto-js): Some methods have been renamed. 2022-09-14 09:58:09 +02:00
Ivan Enderlin e00b9221b9 feat(crypto-js): Implement Device.request_verification. 2022-09-14 09:58:09 +02:00
Ivan Enderlin b6f01b3cec feat(crypto-js): Implement the Device and UserDevice API. 2022-09-14 09:58:09 +02:00
Ivan Enderlin 53e21e0c26 feat(crypto-js): Start implementation key verification API. 2022-09-14 09:58:06 +02:00
Ivan Enderlin 9155989060 feat(crypto): Simplify code and add documentation. 2022-09-14 09:56:33 +02:00
Doug bb62437369 feat(bindings): Expose redact method to FFI 2022-09-13 23:06:11 +02:00
Damir Jelić 6e6c474bcb chore(base): Bump the lru crate 2022-09-13 16:03:42 +02:00
Damir Jelić 8ba33f6fd3 chore: Bump vodozemac to a released version 2022-09-13 16:03:42 +02:00
ismailgulek 2591bcbca9 Fix PR remarks 2022-09-13 15:47:26 +03:00
ismailgulek 18a8b2f275 Merge branch 'main' into ismail/logout 2022-09-13 13:01:57 +03:00
ismailgulek f4764bbd8a Fix PR comment 2022-09-13 13:01:38 +03:00
Jonas Platte e46e13d1bf chore: Upgrade Ruma 2022-09-13 08:32:59 +00:00
Kévin Commaille 97995b7bf6 fix(sdk): Re-export qrcode encoding and decoding error types 2022-09-12 19:27:30 +02:00
ismailgulek b4f0438c1a Move processing sync errors into a separate method 2022-09-12 18:40:50 +03:00
ismailgulek 076de488e7 Avoid too much indentation 2022-09-12 17:54:55 +03:00
ismailgulek d0d8e38a1d Merge branch 'main' into ismail/logout 2022-09-12 17:38:24 +03:00
Damir Jelić aac41fc82a refactor(crypto): Remove the forwarding chains
These aren't really useful since they can be easily spoofed by any room
key forwarder.
2022-09-12 16:03:05 +02:00
ismailgulek 268ecea7fe Fix new format error 2022-09-12 16:55:03 +03:00
ismailgulek 24be8a8e82 Update tests 2022-09-12 16:29:46 +03:00
ismailgulek 3cc6fe5dea Fix format errors 2022-09-12 15:35:45 +03:00
Ivan Enderlin d1b2bfcaa4 feat(qrcode): Remove decoding QR code from an image
feat(qrcode): Remove decoding QR code from an image
2022-09-12 13:33:42 +02:00
Ivan Enderlin a0edd2f8d8 test(qrcode): Restore image only for one test. 2022-09-12 12:42:18 +02:00
Ivan Enderlin 478529f230 chore: Update Cargo.lock. 2022-09-12 12:28:31 +02:00
Ivan Enderlin 9411801245 feat(qrcode): Remove decoding QR code from an image.
This patch removes the `decode_image` (default) feature for this
`matrix-sdk-qrcode` crate.

First reason is that `rqrr` panics for some particular QR codes, and
we don't want to panic.

Second reason is that it's not a feature that is used. For Element on
iOS and Android, it's very unlikely that every frame from the camera
will be sent to `matrix-sdk-qrcode` to see if it can be decoded. So
it's obvious that an external library is used to read the bytes from
the QR code, that are then sent to `matrix-sdk-qrcode`. For Element on
Web, it's basically the same argument.

This feature is actually used only in our tests to ensure the
generated QR code is valid, but it sometimes fails due to `rqrr`
(cf. First reason).
2022-09-12 12:15:49 +02:00
ismailgulek 361313fbea Merge branch 'main' into ismail/logout 2022-09-12 13:10:21 +03:00
Ivan Enderlin 2a94f575b8 feat(qrcode): Allow VerificationData to receive a flow ID
feat(qrcode): Allow `VerificationData` to receive a flow ID
2022-09-12 12:10:11 +02:00
Ivan Enderlin f9d09b60d5 chore(crypto): Reduce the size of AnyDecryptedOlmEvent.
`AnyDecryptedOlmEvent::Custom` contains at least 440 bytes, while the
second-largest variant (`RoomKey`) contains at least 0 bytes. Let's
box `Custom` so that the size of `AnyDecryptedOlmEvent` stays low.
2022-09-12 11:57:45 +02:00
ismailgulek 03477afb26 Add initial_device_name and device_id parameters to login method 2022-09-12 12:53:28 +03:00
ismailgulek 6b66a1de56 Introduce did_update_restore_token delegate method 2022-09-12 12:52:27 +03:00
ismailgulek 519a005d16 Introduce is_soft_logout flag on Client and did_receive_auth_error delegate method 2022-09-12 12:51:35 +03:00
Ivan Enderlin 7831e0cd89 chore(crypto): Use to_owned instead of to_string. 2022-09-12 09:49:30 +02:00
Ivan Enderlin 70eeffbbb0 doc(qrcode): Update documentation.
Since we have switched to Vodozemac, those values don't need to be
unpadded base64 anymore.
2022-09-12 09:47:38 +02:00
Jonas Platte 831e802dd0 refactor(bindings): Move some more functions and methods out of UDL 2022-09-09 14:30:23 +02:00
Jonas Platte ab0c144f51 chore: Upgrade UniFFI 2022-09-09 14:30:23 +02:00
Jonas Platte dc05c6e2b8 chore: Silence clippy lint 2022-09-09 12:51:57 +02:00
Jonas Platte 3a6397fdba chore: Update Cargo.lock 2022-09-09 12:51:57 +02:00
Jonas Platte 4a481f09d1 fix(base): Make tokio dev-dependency arch-dependent 2022-09-09 12:51:57 +02:00
Ivan Enderlin fa6745bb60 feat(qrcode): DecodingError::Identifier is no longer useful. 2022-09-08 16:14:30 +02:00
Ivan Enderlin cb21d89229 test(qrcode): Removing decode_invalid_room_id.
A room ID can no longer be invalid, it's just a string representing
either a `EventId` (we can validate that but…) or a `TransactionId`
(which is an opaque string, so it can be anything).
2022-09-08 16:12:21 +02:00
Ivan Enderlin 12b1ec5ef9 feat(crypto): VerificationData takes a flow ID, removing a panic.
This patch updates `QrVerification::new_cross`, by passing a flow ID
as an owned `String` to `VerificationData`, thus removing a panic, and
allowing QR code verification to happen outside a room.
2022-09-08 15:43:26 +02:00
Ivan Enderlin aa1a47831a chore(crypto): Use longer variable names. 2022-09-08 15:43:09 +02:00
Ivan Enderlin cc5034f4b9 feat(qrcode): Allow VerificationData to receive a flow ID.
This patch updates `VerificationData` to receive a flow ID,
represented as an owned `String`, instead of an `OwnedEventId`. Why?
Because QR code verification can happen outside a room. In such
scenario, there is no event ID, but a transaction ID, unified behind
the `matrix_sdk_crypto::FlowId` enum. `VerificationData` doesn't
really care about that details. Proof is that `QrVerificationData`
receives an owned `String`, which is then casted into an
`OwnedEventId` to match this API properly; but at the top, it just
receives a string.

This patch brings also a little bit of clean up while editing code
around.
2022-09-08 15:37:01 +02:00
Jonas Platte 3be8c9585d refactor(sdk): Make SyncSettings Debug repr more compact 2022-09-08 12:13:30 +02:00
Jonas Platte d810fa6883 test(sdk): Enable logging for tests 2022-09-08 12:13:30 +02:00
Jonas Platte a744447bb5 test: Respect RUST_LOG in integration-testing 2022-09-08 12:13:30 +02:00
Damir Jelić 9252e2c7a9 refactor(sdk): Fetch the content using the new account data methods
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-09-07 13:38:42 +02:00
Damir Jelić 282072b6b0 chore(bindings): Fix a typo 2022-09-07 13:38:42 +02:00
Timothy Hobbs e997da0e72 feat(sdk): Make created_dm_room public 2022-09-07 13:38:42 +02:00
Benjamin Kampmann b3f3d0a95e fix(sdk): proper implementation of stripped info preference
Merge pull request #979 from FlixCoder/cleanup

Fixes a problem, where non-stripped information of the room had predecence in all scenarios of the memory-, sled- and indexeddb-store, thought according to the spec, we prefer the full info only until we've received new stripped info (from another invite). This fixes that to be in line with the spec by removing stripped data when we see a full-event and keep stripped info preferred if found (so, after you joined, stripped data is removed and when you knocked or are invited again, it is preferred), without ever deleting full data. It also adds nice unit- and integration tests to ensure this works as intended.
2022-09-06 15:47:14 +02:00
ismailgulek 42767968ec Implement logout method on Client 2022-09-06 15:56:14 +03:00
Benjamin Kampmann 68a8a214ee Update testing/matrix-sdk-integration-testing/assets/ci-start.sh 2022-09-06 12:42:54 +02:00
Jonas Platte 5adec41b6b test: Use a weak password hash for crypto-store testing
This speeds up the crypto-store tests a lot.
2022-09-05 16:58:12 +02:00
Flix b816307ea9 fix: Listen only to events after sending the request 2022-09-05 16:41:55 +02:00
Flix a182578722 fix: Fix rooms being returned in wrong state and having wrong state 2022-09-05 16:41:55 +02:00
Flix 8b5368ff06 chore: Clean up various mini things 2022-09-05 16:41:52 +02:00
Flix a368caf2b0 test: Add StateStore integration test for stripped/non-stripped 2022-09-05 16:33:31 +02:00
Flix df4ee7db4c test: Add test for repeated joining and leaving 2022-09-05 16:33:31 +02:00
Damir Jelić 321e56cff8 fix(examples): Listen to the done event in the emoji verification example
Nowadays all verifications send a done event, so this is the safer
option.
2022-09-05 15:54:45 +02:00
Damir Jelić a640312503 feat(crypto): Add method to format emojis
This patch adds a method to format a list of emojis in a a terminal
friendly way.

This method was borrowed from weechat-matrix but it's also quite useful
in our own emoji verification example.
2022-09-05 15:54:45 +02:00
Damir Jelić b2452ae92c feat(examples): Add a verbosity flag to the emoji example
Since this example prints out messages to stdout, it becomes quite hard
to see when we ask for user input if all the logging is going on.

This patch adds a standard verbosity flag which disables all logging by
default.
2022-09-05 15:54:45 +02:00
Jonas Platte a25b2d4418 refactor(crypto): Clean up cryptostore_integration_tests macro 2022-09-05 15:44:14 +02:00
Jonas Platte 5f6775f47c ci: Only cancel running CI for previous commits on PRs 2022-09-05 15:01:38 +02:00
Jonas Platte c2a222278d ci: Consistently indent job steps 2022-09-05 15:01:38 +02:00
Jonas Platte 567b230cb7 ci: Cache xtask binary 2022-09-05 15:01:38 +02:00
Jonas Platte 8535c16bc8 ci: Don't require fmt to run before typo check and clippy 2022-09-05 15:01:38 +02:00
Jonas Platte d009d0475e ci: Move appservice and style back into ci workflow
Required for job dependencies.
2022-09-05 15:01:38 +02:00
Jonas Platte 6b8cf3c02a chore: Remove pre-commit configuration and CI job
It was not really being used.
2022-09-05 15:01:38 +02:00
Jonas Platte edfc0cbe20 refactor(sdk): Deprecate ClientBuilder::user_id 2022-09-05 12:43:21 +02:00
Jonas Platte 91186d8a25 doc(sdk): Replace deprecated method in doctest 2022-09-05 11:55:49 +02:00
Jonas Platte 090d67b6ef refactor(sdk): Move module-level documentation inside the module files 2022-09-05 11:55:49 +02:00
Jonas Platte fd4957f533 test(sdk): Address commented-out code in a test 2022-09-05 11:55:49 +02:00
Jonas Platte 08760bd4c0 refactor(sdk): Make base_client field of Client private 2022-09-05 11:55:49 +02:00
Jonas Platte b769827313 refactor(sdk)!: Move media methods from Client to a new type 2022-09-05 11:55:49 +02:00
Jonas Platte 79b5854c83 feat(sdk): Add request_config method to Client 2022-09-05 11:55:49 +02:00
Jonas Platte 38324f6c60 refactor(sdk): Use Client::send in Client::upload 2022-09-05 11:55:49 +02:00
Jonas Platte 33bce0b18d refactor(sdk): Move RoomMember into room module 2022-09-05 11:55:49 +02:00
Jonas Platte 245ecea263 feat(sdk): Add support for AnySyncTimelineEvent in event handlers 2022-09-05 11:55:17 +02:00
Jonas Platte d4ac1bffd0 refactor(sdk): Rename EventKind to HandlerKind
It's somewhat different as MessageLike, OriginalMessageLike and
RedactedMessageLike are not three distinct event kinds in Ruma.
2022-09-05 11:55:17 +02:00
Jonas Platte d6af63e37b refactor(sdk): Run event handlers for the same event concurrently 2022-09-05 11:55:17 +02:00
Jonas Platte 57dde2c4d3 refactor(sdk): Avoid duplicate work and fix event handler call order
Previously, when both a possibly-redacted timeline event handler and a
non-redacted timeline timeline event handler would apply to multiple
events in a sync response, they would individually run for every event
in order. With this change, they will instead both be called
for one event before the next is processed.
2022-09-05 11:55:17 +02:00
Kévin Commaille 6f3813a65f Re-export vodozemac errors in a separate module 2022-09-05 11:44:42 +02:00
Kévin Commaille 433f75ae57 Remove dead error variants 2022-09-05 11:44:42 +02:00
Kévin Commaille 8f0fb08fe7 feat(sdk): Re-export matrix-sdk-crypto errors 2022-09-05 11:44:42 +02:00
Jonas Platte 4f6ff5c0d3 refactor(sdk): Make use of new Default impls from Ruma 2022-09-02 15:03:00 +02:00
Jonas Platte c4d46f233e chore: Upgrade ruma 2022-09-02 15:03:00 +02:00
Damir Jelić faf0ce5007 chore(examples): Remove some empty useless attributes 2022-09-02 14:54:33 +02:00
Damir Jelić c5e6178b70 refactor(examples): Add proxy support to the emoji verification example 2022-09-02 14:54:33 +02:00
Jonas Platte bf9f431e22 refactor(sdk): Use new account_data method internally 2022-09-02 14:09:17 +02:00
Damir Jelić 4b673cfe9c chore: Fix a bunch of clippy warnings 2022-09-02 11:39:06 +02:00
Benjamin Kampmann 0079f1d569 Merge pull request #977 from zecakeh/fix-examples-autojoin
fix(examples): Fix examples that accept invites
2022-09-02 11:14:40 +02:00
Damir Jelić a71292cb16 chore(crypto): Remove a bunch of unnecessary allow deprecated attributes 2022-09-01 17:08:24 +02:00
Damir Jelić cc813b049e fix(crypto): Set the correct algorithm when exporting a room key 2022-09-01 17:08:24 +02:00
Damir Jelić 1b06d8ca51 refactor(crypto): Start using the customized room key request event type 2022-09-01 17:08:24 +02:00
Damir Jelić 4338d5e534 refactor(crypto): Add a customized room key request event type 2022-09-01 17:08:24 +02:00
Jonas Platte 4c98dfb42a feat(bindings): Enable socks proxy support in matrix-sdk-ffi 2022-09-01 15:07:15 +02:00
Jonas Platte dacaef3ddd fix(bindings): Reduce scope of RwLock read lock
Fixes a clippy lint.
2022-09-01 13:40:47 +02:00
Jonas Platte e4267cc4fd refactor(sdk)! Make upload take &[u8] instead of impl Read
The use of `io::Read` wasn't helping since we had to buffer the whole
file in memory anyways, and we are unlikely to get around that in the
near future.
2022-09-01 13:40:47 +02:00
Jonas Platte 16ac69a967 chore: Simplify integration testing macro 2022-09-01 13:11:05 +02:00
Ivan Enderlin 193da88320 feat(crypto): Rename verified and deleted to is_*
feat(crypto): Rename `verified` and `deleted` to `is_*`
2022-09-01 10:50:05 +02:00
Ivan Enderlin 0d6a19e388 chore: verified has been renamed is_verified. 2022-09-01 10:35:51 +02:00
Flix f49e9be905 feat: Expose client of rooms for extensions 2022-09-01 10:01:18 +02:00
Jonas Platte a954518d73 ci: Stop ignoring .lock files in typos config explicitly
Typos now ignores .lock files automatically without any configuration.
2022-09-01 09:33:40 +02:00
Damir Jelić 16d9ed230a chore(examples): Use automatic links for some URLs 2022-08-31 18:43:47 +02:00
Ivan Enderlin 82b647a888 doc(crypto): Fix typos in the documentation
doc(crypto): Fix typos in the documentation
2022-08-31 17:26:56 +02:00
Ivan Enderlin 2e74983c79 chore: Fix other is_verified. 2022-08-31 17:16:05 +02:00
Ivan Enderlin ffebc7c313 doc(crypto): Fix typos in the documentation 2022-08-31 17:09:33 +02:00
Ivan Enderlin 7d1b60a3b1 doc(crypto): Fix a link. 2022-08-31 16:52:00 +02:00
Ivan Enderlin 53c5158eca doc(crypto): Update link to `is_verified. 2022-08-31 16:45:52 +02:00
Ivan Enderlin 3eab9ca8e5 feat(crypto): Rename verified and deleted to is_*. 2022-08-31 16:44:59 +02:00
Doug 36b41ac1c6 chore(bindings): Replace failing test. 2022-08-31 16:22:59 +02:00
Doug 8a8cc5f230 chore(bindings): Use Swift package for tests. 2022-08-31 16:22:59 +02:00
Jonas Platte 96384d9447 feat(bindings): Add account data interaction to sdk-ffi
Co-authored-by: Doug <douglase@element.io>
2022-08-31 14:40:23 +02:00
Stefan Ceriu bb04a1e041 chore(bindings): Fix Xcode project after sdk-ffi namespace change 2022-08-31 10:51:04 +00:00
Jonas Platte d416e64a7e refactor(sdk): Return only content from Account::account_data[_raw]
Since global account data events only consist of the type that is known
to the user anyways, and the content.
2022-08-31 12:19:35 +02:00
Jonas Platte aedf807025 doc(sdk): Add an example for set_account_data 2022-08-31 12:19:35 +02:00
Jonas Platte 77afa26217 feat(sdk): Add account_data[_raw] accessors to Account 2022-08-31 12:19:35 +02:00
Jonas Platte f1a03ececd feat(sdk): Add public set_account_data[_raw] to Account 2022-08-31 12:19:35 +02:00
Jonas Platte f8502720c3 fix(bindings): Pass library file to uniffi-bindgen
… so that functions bridged via #[uniffi::export] are included in the
generated Swift API.
2022-08-31 11:52:37 +02:00
Jonas Platte 84f9414aa4 refactor(bindings): Simplify debug build script 2022-08-31 11:52:37 +02:00
Jonas Platte 9cfddc4c65 refactor(bindings): Update namespace name for matrix-sdk-ffi 2022-08-31 11:52:37 +02:00
Damir Jelić 01f8ed10aa feat(examples): Add an example that lets you create rooms 2022-08-31 11:51:50 +02:00
Damir Jelić 6bb9a7a7d7 docs(crypto): Improve some docs about the forwarded curve chains
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-08-30 17:14:29 +02:00
Damir Jelić 75fb3b81a7 fix(crypto): Fix the deserialization of exported inbound group sessions 2022-08-30 17:14:29 +02:00
Damir Jelić 504ad39c27 fix(crypto): Fix the deserialization of inbound group group_sessions
Inbound group sessions would fail to be deserialized if there was a
forwarding curve chain, this patch fixes it so we go through base64 when
we deserialize this field.
2022-08-30 17:14:29 +02:00
Benjamin Kampmann d20db7c7c1 Merge pull request #981 from Hywan/fix-crypto-js-npm-publish
chore(crypto-js): Add `npm run pack`
2022-08-30 08:50:39 +02:00
Ivan Enderlin 1bfcc52a1f chore(crypto-js): Add npm run pack.
This patch introduces a new `pack` NPM script, which runs `wasm-pack
pack` behind the scene.

This patch modifies the `publish` NPM script to run the `pack` script
as a pre-script (so… in the `prepublish` script).

Finally, this patch no longer uses `$npm_execpath` as it doesn't work
on Windows. It should be `%npm_execpath%`. It's not obvious to make
scripts interoperable, so we will stick with `npm` for now.
2022-08-29 14:22:39 +02:00
Damir Jelić a8362e389e Document the receive_supported_keys method in the gossiping module 2022-08-29 10:21:04 +02:00
Damir Jelić fe35e7c9fa ci: Test the experimental-algorithms feature of the crypto crate 2022-08-29 10:21:04 +02:00
Damir Jelić 5768188da8 Fix some clippy warnings 2022-08-29 10:21:04 +02:00
Damir Jelić 1e451a92e0 Add some missing docs to the Olm Session 2022-08-29 10:21:04 +02:00
Damir Jelić 12c1b80bc9 Remove a dead code allowed attribute 2022-08-29 10:21:04 +02:00
Damir Jelić 7fda431d5f Remove the usage of the Ruma EventEncryptionAlgorithm 2022-08-29 10:21:04 +02:00
Damir Jelić 337fbb591d Put the new megolm algorithm behind the experimental feature flag 2022-08-29 10:21:04 +02:00
Damir Jelić 8cca01369a Put the new olm algorithm behind a feature flag 2022-08-29 10:21:04 +02:00
Damir Jelić 8cdc609876 Move the EventEncryptionAlgorithm into a more logical place 2022-08-29 10:21:04 +02:00
Damir Jelić 0673ad315f Add support for megolm.v2 forwarded keys 2022-08-29 10:21:04 +02:00
Damir Jelić 3aaf70cb5a Support the new algorithms in the gossiping tests 2022-08-29 10:21:04 +02:00
Damir Jelić b00e963a21 Add support for the new algorithms in the bindings 2022-08-29 10:21:04 +02:00
Damir Jelić 7d98d87c5a Enable the new olm/megolm algorithms 2022-08-29 10:21:04 +02:00
Damir Jelić fb840f73a3 Add support for the m.megolm.v2.aes-sha2 room key content 2022-08-29 10:21:04 +02:00
Damir Jelić e935f59039 Add support for the m.megolm.v2.aes-sha2 algorithm 2022-08-29 10:21:04 +02:00
Damir Jelić 3df6797419 Add support for the m.olm.v1.curve25519-aes-sha2 algorithm 2022-08-29 10:21:04 +02:00
Damir Jelić eaf1f27831 refactor(crypto): Use our own enum for the encryption algorithms 2022-08-29 10:21:04 +02:00
Damir Jelić 748eff40f0 docs(crypto): Improve some docs around event trust states
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-08-29 09:50:38 +02:00
Damir Jelić 0084117de9 docs(crypto): Fix some spelling and improve a couple of docs
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2022-08-29 09:50:38 +02:00
Damir Jelić a4af5bf4e1 fix(crypto): Improve the code checking if a decrypted event is trusted
This now takes into account if the room key was imported, i.e. received
as a forward. We also do the check of the Ed25519 key now.
2022-08-29 09:50:38 +02:00
Damir Jelić 27d4228269 fix(crypto): Check the Ed25519 key when we receive an Olm encrypted event 2022-08-29 09:50:38 +02:00
Kévin Commaille dc39c8d96b fix(examples): Fix examples that accept invites
Spawn a task for accepting the invite otherwise the call never returns and sync stops.
2022-08-26 18:15:56 +02:00
Jonas Platte d427632230 chore: Add more backticks in comments 2022-08-25 18:09:13 +02:00
Jonas Platte 6ddc8ba36f refactor!: Rename [Sync]RoomEvent to [Sync]TimelineEvent 2022-08-25 18:09:13 +02:00
Jonas Platte 4be2f3aa04 chore: Upgrade ruma 2022-08-25 18:09:13 +02:00
Jonas Platte f6c404cb32 feat(sdk): Allow event enums to be used as the first event handler argument 2022-08-25 17:19:44 +02:00
Jonas Platte 20a6a16152 refactor(sdk): Split EventHandlerMap into separate maps
One for room-specific event handlers, one for non-room-specific ones.
2022-08-25 17:19:44 +02:00
Jonas Platte 5a1853b0d5 refactor(sdk): Split event_handler module into more files 2022-08-25 17:19:44 +02:00
Jonas Platte 9183f5d4ef refactor(sdk): Move event handler fields from Client into a new struct 2022-08-25 17:19:44 +02:00
Ivan Enderlin 973833c643 feat(crypto-js): Add store configuration to the OlmMachine constructor
feat(crypto-js): Add store configuration to the `OlmMachine` constructor
2022-08-25 11:37:45 +02:00
Ivan Enderlin ce4f7e2254 Merge branch 'main' into feat-crypto-js-store 2022-08-25 11:22:22 +02:00
Jonas Platte 0018749e15 feat(sdk): Allow Raw<_> to be used as the first event handler argument 2022-08-24 18:35:09 +02:00
Ivan Enderlin 9c414bbe9f feat(crypto-js): Implement OlmMachine.sign and .cross_signing_status
feat(crypto-js): Implement `OlmMachine.sign` and `.cross_signing_status`
2022-08-24 09:48:03 +02:00
Jonas Platte 0b8462423a chore: Reduce indirect dependencies of examples 2022-08-23 18:30:44 +02:00
Jonas Platte 2313c099fa chore(bindings): Replace parking_lot RwLock by std RwLock 2022-08-23 18:30:44 +02:00
Ivan Enderlin 85795a92b6 chore(crypto-js): Make Clippy happy. 2022-08-23 17:38:32 +02:00
Ivan Enderlin ef8207fbaa chore(crypto-js): Make Clippy happy. 2022-08-23 17:06:07 +02:00
Jonas Platte f83292fc75 refactor: Start using UniFFI proc-macro frontend 2022-08-23 16:47:08 +02:00
Jonas Platte 5faed2e635 Upgrade UniFFI 2022-08-23 16:47:08 +02:00
Ivan Enderlin 9722a4c415 chore(crypto-js): Use IndexeddbCryptoStore only for wasm32. 2022-08-23 16:46:09 +02:00
Ivan Enderlin 432449b009 chore(crypto-js): Make cargo fmt happy. 2022-08-23 15:08:51 +02:00
Ivan Enderlin 04634d5f39 chore(crypto-js): Fix a typo in an error message. 2022-08-23 15:04:50 +02:00
Ivan Enderlin ef56f76978 doc(crypto-js): Fix a typo. 2022-08-23 15:03:26 +02:00
Ivan Enderlin 527c727e4a test(crypto-js): Improve test cases. 2022-08-23 15:00:39 +02:00
Ivan Enderlin d947448c64 test(crypto-js): Add more test case when store is not configured correctly. 2022-08-23 15:00:39 +02:00
Ivan Enderlin d497883669 doc(crypto-js): Add more docmuentation and more error messages. 2022-08-23 15:00:39 +02:00
Ivan Enderlin 7f07ac52ef feat(crypto-js): Add store configuration to the OlmMachine constructor.
The `OlmMachine` constructor now has 2 more optional arguments:
`store_name` and `store_passphrase`, to use Indexed DB as the backend
to store the Olm machine keys, rather than having an in-memory Olm
machine.

Node.js is used to test our binding. Indexed DB is absent of
Node.js. So, firstly, we are using the `fake-indexeddb` JavaScript
library to mimic the same API inside Node.js. And, secondly, we use
our own fork of the `indexed_db_futures` Rust crate to provide add
support for Node.js too ([PR is
here](https://github.com/Alorel/rust-indexed-db/pull/11)). It
basically looks in the Node.js global environment if the `indexedDB`
getter is present, just like it is already done for `Window` on any
browser, or `WorkerGlobalScope` for workers.
2022-08-23 15:00:33 +02:00
Jonas Platte 9462061a5a chore: Upgrade ruma 2022-08-23 14:28:21 +02:00
Ivan Enderlin d508237078 chore(crypto-js): Add a release workflow for crypto-js
chore(crypto-js): Add a release workflow for `crypto-js`
2022-08-23 10:49:29 +02:00
Ivan Enderlin 331f8b381f doc(crypto-js): Update documentation for the release workflow. 2022-08-22 15:10:01 +02:00
Ivan Enderlin 2481618608 chore(crypto-js): Create the Github release with the NPM package attached.
This patch updates the `publish` NPM script to explicitly run
`wasm-pack pack` to create the NPM package in the `pkg/`
directory. This patch also updates the Github Action workflow for the
`matrix-sdk-crypto-js` release, to create a new Github Release, with
the NPM package attached as an asset file.
2022-08-22 14:37:09 +02:00
Jonas Platte dd78a8cecd refactor(sdk)!: Make room type constructors private
… and avoid unnecessary clones before calling them.
2022-08-22 13:16:05 +02:00
Ivan Enderlin 39077b185b chore(crypto-js): Add a release workflow for crypto-js.
This patch adds a new `npm run publish` script that:

1. Run `npm run prepublish` (which runs the `build` and `test` scripts),
2. Run `wasm-pack publish`.

Note 1: The `prepublish` script is using the `$npm_execpath`
environment variable instead of just “`npm`”, so that if someone is
using `yarn` or another JavaScript package manager, it _should_ work
(not tested yet).

Note 2: `wasm-pack publish` is run without running `wasm-pack login`
before that. _But_ we are updating the registry URL in the NPM
configuration file in the Github Action workflow, see below.

This patch then creates a new Github Action workflow that is triggered
when a new tag of the form `matrix-sdk-crypto-js-v[0_9]+.*` is
pushed. This workflow runs `npm run publish` basically, but before
that, it updates the NPM configuration file by setting a value for
`//registry.npmjs.org/:_authToken`. Thus, running `wasm-pack login` is
not necessary.
2022-08-22 12:14:44 +02:00
Benjamin Kampmann 68107e6285 Merge pull request #963 from gnunicorn/ben-update-ruma
chore: Update ruma
2022-08-18 16:13:15 +02:00
Benjamin Kampmann 549c829000 chore: Update ruma 2022-08-18 15:52:08 +02:00
Jonas Platte 3581d83389 chore: Upgrade Ruma 2022-08-17 10:15:05 +02:00
Jonas Platte 260b604615 refactor(sdk)!: Split strongly-typed state event functions into two
One for empty state keys under the existing name, one for non-empty
state keys with a `_for_key` suffix.
2022-08-17 10:15:05 +02:00
Ivan Enderlin a1dca23c3c Merge pull request #958 from Hywan/feat-crypto-js-attachment 2022-08-17 10:12:04 +02:00
Benjamin Kampmann 9fd5a8b3b1 Merge pull request #960 from matrix-org/poljar/delete-device-log-improvement
Improve the log line when we think our device has been deleted
2022-08-17 09:46:26 +02:00
Damir Jelić 180822dd18 chore(crypto): Improve the message when we think that we have been deleted 2022-08-16 18:32:14 +02:00
Damir Jelić 20477ab7da chore(crypto): Log our identity keys when we think our device has been deleted 2022-08-16 18:31:30 +02:00
Damir Jelić 06f39696d3 chore(crypto): Improve some logs in the Olm message handling code 2022-08-16 16:18:50 +02:00
Damir Jelić 6f5443f8a0 chore(crypto): Log some info when we try to create an Olm session from a pre-key message 2022-08-16 16:18:50 +02:00
Ivan Enderlin 45a66f3321 doc(crypto-nodejs): Fix a typo. 2022-08-16 16:06:04 +02:00
Ivan Enderlin 7f35691236 feat(crypto-js): Implemented the Attachment API.
Implement the `Attachment.encrypt` and `Attachment.decrypt` methods,
along with its `EncryptedAttachment` companion.

The trick is to avoid copies as much as possible. Instead of dealing
with `Uint8Array` as I've initially done, `&[u8]` and `Vec<u8>` is
passed instead. `wasm-bindgen` is smart enough to do as few copies as
possible (from JavaScript to Wasm's memory is required, and we don't
want to do more), while typing everything as `Uint8Array`.

`EncryptedAttachment.encryptedData` returns a copy of the data
everytime it is called, and that's the last copy I'm not happy with.
2022-08-16 15:56:36 +02:00
Benjamin Kampmann e8d51a4cba Merge pull request #956 from gnunicorn/ben-fix-encode-key
fix(sled): Remove unused `from` on EncodeUnchecked
2022-08-16 15:51:36 +02:00
Benjamin Kampmann 7feffec9c0 fix(sled): feature-gate EncodeUnchecked::from 2022-08-16 15:18:46 +02:00
Ivan Enderlin 8e74834342 doc(crypto-js): Add missing module documentation. 2022-08-16 12:31:19 +02:00
Ivan Enderlin 070637b0ef chore(crypto-js): Fix style. 2022-08-16 12:21:02 +02:00
Ivan Enderlin 2dffe03c8d feat(crypto-js): Implement OlmMachine.sign. 2022-08-16 12:16:01 +02:00
Ivan Enderlin 3f0509e7b1 fix(crypto-js): Add missing Debug impl. 2022-08-16 12:16:01 +02:00
Ivan Enderlin 2275643ea0 chore(crypto-js): Move Vodozemac types into their own Rust module. 2022-08-16 12:16:01 +02:00
Ivan Enderlin 0fa6ff6955 feat(crypto-js): Add DeviceKeyId, DeviceKeyAlgorith and DeviceKeyAlgorithmName. 2022-08-16 12:16:01 +02:00
Ivan Enderlin 997a6ed0ad feat(crypto-js): Implement OlmMachine.cross_signing_status. 2022-08-16 12:16:01 +02:00
Ivan Enderlin fd220f197b doc: Add link to online documentation for crypto-js and crypto-nodejs
doc: Add link to online documentation for crypto-js and crypto-nodejs
2022-08-16 10:21:39 +02:00
Ivan Enderlin 655e62814b doc(crypto-nodejs) Add link to online documentation. 2022-08-16 10:06:22 +02:00
Ivan Enderlin c2468b2f2e doc(crypto-js) Add link to online documentation. 2022-08-16 10:04:54 +02:00
Benjamin Kampmann e0ae4f60e3 docs(examples): update instructions for wasm_command_bot example
Merge pull request #952 from chrisguida/chrisguida/wasm-bot-readme -
2022-08-16 09:48:33 +02:00
Chris Guida 2beb13cc3e update instructions for wasm_command_bot example 2022-08-15 17:56:54 -05:00
Damir Jelić 78dcff9259 chore(crypto): Fix an indentation issue
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-08-15 11:39:43 +02:00
Damir Jelić 0bd58a7741 refactor(crypto): Simplify the Curve25519 check when fetching a device
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-08-15 11:39:43 +02:00
Damir Jelić 405c3938b7 refactor(crypto): Use the Curve25519 key type in more places 2022-08-15 11:39:43 +02:00
Damir Jelić bd5ea8b0f7 fix(crypto): Fix some error messages 2022-08-15 11:39:43 +02:00
Jonas Platte 24c042e974 refactor(base): Deserialize events at the expected type
… rather than deserializing at an enum type and taking the same branch
for getting a different enum variant¹ as failed deserialization.

¹ which should be impossible anyways
2022-08-15 11:05:22 +02:00
Jonas Platte d236cde0c7 refactor(base): Use StateStoreExt in a few places 2022-08-15 11:05:22 +02:00
Jonas Platte d2f39bc18f feat(base): Add StateStoreExt for statically-typed event retrieval 2022-08-15 11:05:22 +02:00
Jonas Platte 96165f5602 chore(bindings): Use ? operator instead of and_then chaining 2022-08-15 11:05:22 +02:00
Damir Jelić 4a13b8d207 ci: Ignore thead when checking for spelling 2022-08-14 10:20:28 +02:00
Damir Jelić c9c09adb38 chore: Fix some newly detected typos 2022-08-14 10:20:28 +02:00
Jonas Platte aedbbcdde7 fix(sdk)!: Remove SyncEvent implementation for InitialStateEvent
Initial state events aren't actually received through sync, they're sent from
the client to the server when creating a room.

This change makes it impossible to register event handlers for initial state
events. Previously, this was allowed, but the event handler was never called.
2022-08-13 20:21:28 +02:00
Jonas Platte 97f37acb4a chore: Reduce indirect dependencies of sled-state-inspector 2022-08-13 13:08:11 +02:00
Damir Jelić 0b5bfeadea chore(crypto): Add a missing semicolon
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-08-13 09:58:57 +02:00
Damir Jelić 6d60acfff4 chore(common): Fix a clippy warning 2022-08-13 09:58:57 +02:00
Damir Jelić 3d56af442d refactor(crypto): Utilize the decrypted Olm event type more
This patch adds some more stronger guarantees that received room key
events and other similarly security critical event types are only
handled if they have been received over a secure Olm channel.
2022-08-13 09:58:57 +02:00
Damir Jelić ae18b01c25 refactor(crypto): Use the SigningKeys collection for inbound group sessions 2022-08-11 16:43:42 +02:00
Damir Jelić 4692a12cd7 refactor(crypto): Create a custom collection type for signed keys 2022-08-11 16:43:42 +02:00
Jonas Platte 344309c1bf chore: Track Cargo.lock to make binding staticlibs reproducible 2022-08-11 13:32:32 +02:00
Jonas Platte 87094a9111 chore: Document dependency upgrade issues 2022-08-11 13:16:10 +02:00
Jonas Platte adf3f9d434 chore(appservice): Upgrade serde_yaml 2022-08-11 13:15:57 +02:00
Jonas Platte 158bd24b40 chore: Bump pprof dependency 2022-08-11 13:09:09 +02:00
Jonas Platte 8e368d86b7 chore: Use the latest git version of UniFFI 2022-08-11 12:56:17 +02:00
Jonas Platte 0fe714df86 chore: Upgrade sled-state-inspector dependencies 2022-08-11 11:59:50 +02:00
Jonas Platte 936f0371de chore: Use once_cell instead of lazy_static in integration test crate 2022-08-11 10:45:04 +02:00
Jonas Platte ecc800a319 chore: Sort dependencies of integration test crate 2022-08-11 10:32:12 +02:00
docweirdo febfcf9796 feat(sdk): Make room actions return typed room objects
… by waiting for the corresponding event confirming the action. Affects:

* Creating a room
* (Re-)Joining a room
* Leaving a room
* Accepting an invitation
* Rejecting an invitation
2022-08-10 17:32:38 +02:00
Damir Jelić 3f0a68082a feat(crypto): Add a setting to only send room keys to trusted devices 2022-08-10 13:31:15 +02:00
Damir Jelić 18861bb595 refactor(crypto): Add a dedicated error for inbound group session exporting 2022-08-10 13:28:54 +02:00
Damir Jelić 329d461a2f feat(crypto): Add customized event type for the forwarded room key 2022-08-10 13:28:54 +02:00
Jonas Platte 4914c595e9 fix(sdk): Further relax event / notification handler bounds on WASM
This allows capturing non-`Send` / -`Sync` values in handler closures.
2022-08-10 12:54:36 +02:00
Jonas Platte ad80839ffd fix(sdk): Make event handler futures non-Send on wasm 2022-08-09 14:25:57 +02:00
Jonas Platte 0701561e45 feat(common): Add SendOutsideWasm, SyncOutsideWasm 2022-08-09 14:25:57 +02:00
Jonas Platte 25030780b0 test(sdk): Run event handler tests on wasm 2022-08-09 14:25:57 +02:00
Jonas Platte 327a404d60 test(sdk): Move test client creation into separate module 2022-08-09 14:25:57 +02:00
Damir Jelić 06e096f6cc fix(examples): Fix the in-room emoji verification example 2022-08-09 14:04:11 +02:00
Damir Jelić a025163dae test(crypto): Test that we correctly preserve relations in an encryption cycle 2022-08-09 14:04:11 +02:00
Damir Jelić 19fcff56de chore(crypto): Make the relation copying code when decrypting a bit simpler 2022-08-09 14:04:11 +02:00
Damir Jelić edf81fb325 fix(crypto): Correctly copy over the relation when encrypting 2022-08-09 14:04:11 +02:00
Damir Jelić 08338acac2 fix(crypto): Fix the deserialization of relations 2022-08-09 14:04:11 +02:00
Kévin Commaille 52e70f1955 refactor(sdk): Don't require the whole session for sending
Allow to send requests when only the access token is available.

Remove the unreachable UserIdRequired error.
2022-08-09 12:26:33 +02:00
Jonas Platte e788ec6b07 ci: Only test one node.js version on macOS 2022-08-08 18:06:54 +02:00
Jonas Platte d3d108deb8 chore: Add missing copyright headers 2022-08-08 16:28:48 +02:00
Jonas Platte bd65d9b7a6 doc(sdk): Remove usage of deprecated function in doctest 2022-08-05 16:16:41 +02:00
Jonas Platte 230bb67763 refactor(sdk): Remove Clone requirement on event handlers 2022-08-05 16:16:41 +02:00
Jonas Platte 10a37f6d51 chore(sdk): Add EventHandlerDropGuard
It isn't used for now, but will be soon.
2022-08-05 16:16:41 +02:00
Jonas Platte 5156fb7dd4 refactor(sdk): Move add_event_handler_impl to event_handler module 2022-08-05 16:16:41 +02:00
Jonas Platte 3b03ad804f refactor(sdk)!: Swap the async lock around event handlers for a sync one 2022-08-05 16:16:41 +02:00
Damir Jelić 603176f521 chore(crypto): Bump vodozemac
Vodozemac got some new knobs to twiddle with. This patch updates
vodozemac and sets the knobs to use the olm/megolm v1 supported
encryption schemes.
2022-08-05 14:06:42 +02:00
Jonas Platte dfec17e6af chore: Disable testing of crates without tests
This reduces the amount of "running 0 tests" spam when testing the whole
workspace and makes testing a little faster overall.
2022-08-05 11:10:31 +02:00
Kévin Commaille 7623f93bb3 fix(sdk)!: Make set_homeserver private
A user shouldn't need to change the homeserver after creating the client.
2022-08-05 09:55:55 +02:00
Jonas Platte a60620306c ci: Update tarpaulin.toml 2022-08-04 23:43:49 +02:00
Jonas Platte 1fea48359d ci: Checkout head ref instead of merge commit for coverage
… this *should* fix bogus coverage change reporting.
2022-08-04 23:43:49 +02:00
Jonas Platte 054dfa98a0 ci: Upgrade checkout action 2022-08-04 23:43:49 +02:00
Damir Jelić 593d4e6062 perf(crypto): Use an RwLock for the OutboundGroupSession 2022-08-04 17:36:03 +02:00
Jonas Platte 5a94ba7b80 refactor(sled)!: Align open_with_database with its documentation
It now takes a passphrase instead of a store cipher as the second argument.
2022-08-04 17:04:31 +02:00
Jonas Platte e1b7f3be05 refactor(sled): Simplify test code 2022-08-04 17:04:31 +02:00
Jonas Platte 6bed51f016 refactor(indexeddb)!: Use &str for name in public API 2022-08-04 17:04:31 +02:00
Jonas Platte 4db162b8a2 chore(indexeddb): Clean up Result usage 2022-08-04 17:04:31 +02:00
Jonas Platte 0b1bdd66f9 refactor(indexeddb): Export error types 2022-08-04 17:04:31 +02:00
Jonas Platte a4f3c3a070 refactor!: Give sled / indexeddb types unique names 2022-08-04 17:04:31 +02:00
Jonas Platte df7895d2c6 chore(indexeddb): Rename cryptostore => crypto_store
… for consistency with state_store.
2022-08-04 17:04:31 +02:00
Jonas Platte 694c36d741 chore(sled): Rename cryptostore => crypto_store
… for consistency with state_store.
2022-08-04 17:04:31 +02:00
Benjamin Kampmann b5329f99f1 Merge pull request #903 from gnunicorn/ben-getting-started-example
Improving examples
2022-08-04 15:41:26 +02:00
Damir Jelić f055e939e7 refactor(crypto): Use the vodozemac method to decide if a session is better
This patch delegates the decision making if a session is better to
vodozemac. Vodozemac has better insights if a group session can be
considered to be better.
2022-08-04 15:09:09 +02:00
Benjamin Kampmann c4c7c2bb23 docs: remove unused import and fix style of custom events example 2022-08-04 15:02:39 +02:00
Benjamin Kampmann efc0556124 doc: follow naming convention and use generated types from ruma 2022-08-04 13:31:16 +02:00
Benjamin Kampmann 9d588f7e00 doc: add example for sending and reacting on custom events 2022-08-04 13:13:48 +02:00
Benjamin Kampmann 323974fe4c Merge remote-tracking branch 'origin/main' into ben-getting-started-example 2022-08-04 12:22:42 +02:00
Benjamin Kampmann 3bdb2f22ea build(crypto-js): Pin yarg-parser to 21.0.1 to prevent upgrade bug
We are effected by https://github.com/yargs/yargs-parser/issues/452
through the transient dependency of jest on yargs
2022-08-04 12:21:18 +02:00
Damir Jelić ddf8577c84 refactor(crypto): Start using our own event types when we encrypt 2022-08-04 11:16:02 +02:00
Benjamin Kampmann 90c2dcdbc0 style: fix clippy lints 2022-08-04 11:02:28 +02:00
Benjamin Kampmann fe4bc0dc75 doc: fix docs of getting started bot 2022-08-03 17:07:59 +02:00
Benjamin Kampmann 69c8cdf304 Revert "fix: limit indexeddb features to target arch to stop clippy from complaining"
This reverts commit d54612b6e2.
2022-08-03 16:40:17 +02:00
Benjamin Kampmann daf92d7745 Merge remote-tracking branch 'origin/main' into ben-getting-started-example 2022-08-03 16:39:50 +02:00
Benjamin Kampmann ccbd9e5712 chore: rename Readme.md to README.md 2022-08-03 16:39:14 +02:00
Jonas Platte 2430d7f267 chore: Remove unneeded docsrs Cargo features 2022-08-03 15:33:53 +02:00
Damir Jelić 3ca3016539 refactor(crypto): Use the curve 25519 key type for inbound group sessions 2022-08-03 15:28:24 +02:00
Jonas Platte bbbd7942b0 fix(indexeddb): Export MigrationConflictStrategy 2022-08-03 15:17:05 +02:00
Jonas Platte 1a5953e01e chore(indexeddb): Appease clippy 2022-08-03 15:17:05 +02:00
Jonas Platte 3a19d8e5bf chore(indexeddb): Reduce target_arch feature gates
This allows smoother development as a regular 'cargo check' will
validate most of the code. It also makes rust-analyzer work for the
crate without any configuration.
2022-08-03 15:17:05 +02:00
Jonas Platte 0b7d0aa780 chore(common): Make timeout tests deterministic
… as well as simpler, and faster.
2022-08-03 14:54:43 +02:00
Jonas Platte 82f4e57a2c feat(sled): Print a clear error message when attempting to build on wasm 2022-08-03 14:48:45 +02:00
Jonas Platte 9714ce9edf refactor(sdk): Check permissible feature configuration in build script
… instead of through `compile_error!` invocations. This helps avoid
unhelpful errors from the unsupported feature configuration by aborting
compilation earlier.
2022-08-03 14:48:45 +02:00
Benjamin Kampmann 9538596fbb doc: Add getting-started example autojoin & command bot with plenty of source docs 2022-08-03 13:05:25 +02:00
Benjamin Kampmann 35be128139 docs: add Readme to examples root 2022-08-03 12:06:50 +02:00
Benjamin Kampmann d54612b6e2 fix: limit indexeddb features to target arch to stop clippy from complaining 2022-08-03 12:00:54 +02:00
Benjamin Kampmann a1bf53a331 Merge remote-tracking branch 'origin/main' into ben-getting-started-example 2022-08-03 11:39:50 +02:00
Kévin Commaille 9064e7b02d feat(sdk): Add support for refresh tokens 2022-08-03 10:42:28 +02:00
Damir Jelić ae261c2091 refactor(crypto): Refactor the key sharing tests a bit 2022-08-02 16:48:05 +02:00
Damir Jelić 968792ea00 refactor(crypto): Split out the forwarded room key accepting method 2022-08-02 16:48:05 +02:00
Benjamin Kampmann 42c88e840f Merge pull request #905 from gnunicorn/ben-fix-integration-test-coverage
ci: add backend server for integration test with tarpaulin
2022-08-02 16:14:26 +02:00
Benjamin Kampmann 38a71972e5 ci: add backend server for integration test with tarpaulin 2022-08-02 15:42:45 +02:00
Benjamin Kampmann d8caaed1ce docs: only document default workspace members, not all 2022-08-02 15:24:48 +02:00
Benjamin Kampmann 67e63c0d35 ci: update xtask, add ci to build examples 2022-08-02 15:13:27 +02:00
Benjamin Kampmann 4c7ddd7512 refactor: move examples from crates/matrix-sdk into separate crates in examples/ 2022-08-02 15:06:04 +02:00
Jonas Platte 9fca639f9b feat(sdk): Add room::Common::add_event_handler 2022-08-02 13:38:30 +02:00
Benjamin Kampmann 6cb87c64b5 Merge pull request #855 from gnunicorn/gnunicorn/issue833
Integration tests against an actual synapse server
2022-08-02 12:22:48 +02:00
Benjamin Kampmann a5875ff75d ci: update codecov config to exclude all testing crates 2022-08-02 10:59:18 +02:00
Benjamin Kampmann 9bb02f2419 fix: fix path to testing crate 2022-08-02 10:58:53 +02:00
Benjamin Kampmann 65be06ebad Merge remote-tracking branch 'origin/main' into gnunicorn/issue833 2022-08-02 10:32:09 +02:00
Damir Jelić 154538c4c9 fix(crypto): Make the secret receiving logic more obvious.
This patch ensures that the received secret has been sent by one of our
verified devices. We already ensure so for the secrets we import, since
we check that the cross signing keys match the public keys of our own
user idenity.

No other secrets get imported by this method but it could quite easily
become an issue if we start accepting more secret types.
2022-08-02 09:35:38 +02:00
Damir Jelić f23c16cf88 refactor(crypto): Split out the methods to receive a secret 2022-08-02 09:35:38 +02:00
Jonas Platte 165973121c fix(sdk): Make remove_event_handler work with room-specific handlers
As part of that, store only the ID, not the whole key in
EventHandlerWrapper, because the key is getting bigger with room_id.
2022-08-01 23:57:00 +02:00
Jonas Platte 31903d3cbc chore(sdk): Simplify remove_event_handler test 2022-08-01 23:55:44 +02:00
Jonas Platte 108f299e92 refactor(sdk): Inline handle_sync_events_wrapped_with into all callers
It was too generic to be readable.
2022-08-01 23:55:44 +02:00
Jonas Platte eb78815be5 refactor(sdk): Create non-generic fn call_event_handlers
Extracted out of handle_sync_events_wrapped_with.
2022-08-01 23:55:44 +02:00
Jonas Platte 0716f6afaa feat(sdk): Add Client::add_room_event_handler 2022-08-01 23:55:44 +02:00
Jonas Platte 78169d516e refactor(sdk): Avoid unnecessary double map lookup 2022-08-01 23:55:44 +02:00
Jonas Platte 061fe104a9 chore(sdk): Move EventHandler{Fut,Fn} into event_handler module 2022-08-01 23:55:43 +02:00
Benjamin Kampmann f91bdb28ba Merge pull request #897 from gnunicorn/ben-fix-documentation-generation
Fix documentation generation
2022-08-01 22:37:21 +02:00
Benjamin Kampmann 14429af511 Update .github/workflows/documentation.yml
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-08-01 22:19:46 +02:00
Benjamin Kampmann 1e6e00b0c0 ci(integration-testing): split integration test off from regular tests 2022-08-01 18:54:33 +02:00
docweirdo 744bd8d0d2 feat(common): Add a generically usable timeout function 2022-08-01 18:23:30 +02:00
Benjamin Kampmann 06ad079099 Merge pull request #895 from matrix-org/ben-add-editoconfig
build: Adding .editorconfig
2022-08-01 15:23:58 +02:00
Benjamin Kampmann 7dfadd1848 ci(integration-testing): split integration test off from regular tests 2022-08-01 15:20:13 +02:00
Benjamin Kampmann 5089c1a7e9 ci(docs): force npm generated bindings if existing 2022-08-01 14:56:26 +02:00
Benjamin Kampmann c15a4bcdd4 build: Adding .editorconfig 2022-08-01 14:33:05 +02:00
Benjamin Kampmann 729836cf70 Merge pull request #894 from gnunicorn/ben-add-js-docs
ci(js) add npm docs of bindings to pages
2022-08-01 13:35:17 +02:00
Benjamin Kampmann 2d21c30639 Merge remote-tracking branch 'origin/main' into gnunicorn/issue833 2022-08-01 13:28:28 +02:00
Benjamin Kampmann 3842426788 ci: Remove unneeded github action params 2022-08-01 13:27:00 +02:00
Benjamin Kampmann c27016b2e7 testing: fix review grumbles 2022-08-01 13:01:50 +02:00
Benjamin Kampmann d0f58d0879 ci(js) add npm docs of bindings to pages 2022-08-01 12:17:36 +02:00
Kévin Commaille 4cdc91844e chore(ci): Fix new clippy warnings 2022-07-30 12:58:18 +02:00
Jonas Platte fe5d8fb40e refactor: Deprecate ClientBuilder::{crypto_store, state_store} 2022-07-29 17:22:12 +02:00
Jonas Platte ffb4c6d6ef docs: Use new ClientBuilder methods in examples 2022-07-29 17:22:12 +02:00
Jonas Platte 93c4c5d128 feat(sdk): Add ClientBuilder::indexeddb_store 2022-07-29 17:22:12 +02:00
Jonas Platte ec3a6e4b15 feat(sdk): Add ClientBuilder::sled_store 2022-07-29 17:22:12 +02:00
Jonas Platte ecbcf734b9 docs(sled): Clean up make_store_config description 2022-07-29 17:22:12 +02:00
Jonas Platte 75f08aed69 docs(sdk): Fix outdated description of ClientBuilder::store_config 2022-07-29 17:22:12 +02:00
Jonas Platte 255955555d refactor(sdk): Add back register_event_handler[_context] as deprecated methods
… using their original signatures so upgrading matrix-sdk is easier.
2022-07-29 14:39:28 +02:00
Jonas Platte 27b858308c refactor(sdk)!: Rename {register => add}_event_handler[_context]
It's shorter and better fits with the new remove_event_handler method.
2022-07-29 14:39:28 +02:00
Jonas Platte a21ac5d6e4 Disable debug-info for the dev profile 2022-07-29 11:28:47 +02:00
Damir Jelić 4db041ce9a docs(crypto): Improve the wording on the recipient collection method
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-07-29 10:20:36 +02:00
Damir Jelić c194e08942 fix(crypto): Rotate the outbound group session if the algorithm changes 2022-07-29 10:20:36 +02:00
Damir Jelić 713e96d3a8 fix(crypto): Store intermediate changes to the outbound group session
This fixes a bug where we would lose already generated to-device
requests carrying an m.room_key when the client gets restarted.

This only happens if the request was generated after the initial
share of the room key. Such requests get generated if a new device
or member join the group.
2022-07-29 10:01:58 +02:00
Jonas Platte b36f79a1bb doc: Make rustfmt format code blocks in documentation 2022-07-28 20:06:12 +02:00
Jonas Platte 504464c1e8 chore: Remove edition from .rustfmt.toml
It will be picked up from Cargo.toml.
2022-07-28 20:06:12 +02:00
Doug b884c5baae chore(bindings/ffi): Print each step when building XCFramework. 2022-07-28 13:37:02 +02:00
Doug c15fb5e5b7 fix(sdk): Reduce retry length on homeserver discovery 2022-07-28 13:37:02 +02:00
Damir Jelić 0555216f37 chore(crypto): Introduce a helper function to convert events in tests 2022-07-28 12:48:12 +02:00
Damir Jelić 03a4814a1a refactor(crypto): Use our own type for megolm 2022-07-28 12:48:12 +02:00
Damir Jelić 80c7f057cc refactor(crypto): Use our own struct for encrypted to-device events 2022-07-28 12:48:12 +02:00
Damir Jelić 7e70997e1c feat(crypto): Add customized m.room.encrypted events 2022-07-28 12:48:12 +02:00
Damir Jelić 2bb7914611 refactor(crypto): Make the event type an associated constant 2022-07-28 12:48:12 +02:00
Benjamin Kampmann c8c793da98 Merge pull request #768 from gnunicorn/gnunicorn/issue756
Bump db version, "upgrade" path to new db in sled and indexeddb
2022-07-28 09:51:27 +02:00
Damir Jelić e501979d92 feat(bindings/ffi): Allow setting the timeline limit for the sync setup 2022-07-27 19:23:10 +02:00
Doug 57c1e68893 Rename limit to timeline_limit.
Use a u16 instead.
2022-07-27 18:03:04 +01:00
Doug a875c4b373 Expose room membership in the FFI. 2022-07-27 17:23:09 +01:00
Doug f6e215dac3 Add limit parameter to start_sync. 2022-07-27 17:22:17 +01:00
Jonas Platte 4415ed9b58 refactor: Improve tracing events
* Use fields more
* Adjust some wording
2022-07-27 17:47:01 +02:00
Benjamin Kampmann 59fc81b957 ci(xtask): bump wasm timeout to make the ci pass 2022-07-27 16:58:20 +02:00
Benjamin Kampmann 770ac193a7 fix(indexeddb): import errors 2022-07-27 15:08:51 +02:00
Benjamin Kampmann fe40b3753a Merge pull request #870 from Hywan/feat-crypto-js-npm-publish
chore: Update or add `git-cliff` config' & prepare `crypto-js` for publishing
2022-07-27 14:28:40 +02:00
Benjamin Kampmann e871114436 docs(crypto-ffi): fixing path 2022-07-27 13:43:39 +02:00
Benjamin Kampmann fb4dd4d875 test(crypto-js): fixing path 2022-07-27 13:32:26 +02:00
Benjamin Kampmann 5806b3fbe9 ci(crypto-js): use a specific node version to run tests 2022-07-27 13:23:44 +02:00
Benjamin Kampmann e1be222558 style: fixing fmt 2022-07-27 13:09:08 +02:00
Benjamin Kampmann 37f0926832 chore: prefer to user Store::builder 2022-07-27 12:59:53 +02:00
Benjamin Kampmann 936731065b fix(indexeddb): specify futures import 2022-07-27 12:53:54 +02:00
Benjamin Kampmann 088699b6a4 docs(xtask): remove comment 2022-07-27 12:20:46 +02:00
Benjamin Kampmann b2da8b7dd7 fix(examples): update to renaming 2022-07-27 12:12:17 +02:00
Benjamin Kampmann b80d3c2f2d Merge remote-tracking branch 'origin/main' into gnunicorn/issue756 2022-07-27 12:04:56 +02:00
Benjamin Kampmann eb1dfd9690 docs(indexeddb): document builder functions 2022-07-27 11:52:13 +02:00
Benjamin Kampmann 54c181a9ad chore: cleaning up builder usage in sled and indexeddb 2022-07-27 11:51:56 +02:00
Benjamin Kampmann 003c946581 chore(sled): ascending order for dependencies 2022-07-27 10:59:02 +02:00
docweirdo 82731a5e89 feat(sdk): Add support for removing event handlers 2022-07-27 05:09:22 +00:00
Damir Jelić 4175e6badf feat(bindings/ffi): Allow clients to be restored using only an access token
This functionality is important to allow clients to log in using an OIDC server. The OIDC server returns only an access token, the client needs to fetch the user ID and device ID from the Matrix server separately.

This lives in the bindings for now since OIDC support in Matrix is being actively developed.
2022-07-26 17:10:50 +02:00
Benjamin Kampmann 008c0f4659 Merge pull request #860 from matrix-org/doug/client-path
Use a consistent store path when logging in through the FFI.
2022-07-26 16:33:32 +02:00
Doug a951a273e7 Rebase and rename method.
Add a device ID parameter to restore_with_access_token
2022-07-26 15:00:02 +01:00
Doug f13f590b7f Add login_access_token to the FFI auth service. 2022-07-26 15:00:02 +01:00
Doug 1eadd0ba2d Revert changes to store path. Use whoami for path. 2022-07-26 14:50:51 +01:00
Doug 3b8a2ca2d7 Add missing path method to IndexeddbStore. 2022-07-26 14:50:51 +01:00
Doug b6b1f904e0 Fix clippy warning. 2022-07-26 14:50:51 +01:00
Doug f31528c926 Allow a client to be built without a store path.
Throw an error on login if it is missing.
2022-07-26 14:50:51 +01:00
Doug 05fab8c394 Add a store_path method on the FFI client. 2022-07-26 14:48:37 +01:00
Jonas Platte e37e62c92c chore(sdk): Fix event handler test
It wasn't actually testing typing and power-levels event handlers before.
2022-07-26 11:11:10 +02:00
Jonas Platte d162dd07d5 refactor(sdk): Split SyncEvent::ID into KIND and TYPE
This should make things slightly easier to read.
2022-07-25 20:33:43 +02:00
Jonas Platte 42d3ebbe87 chore: Remove ugly commas right before closing parentheses 2022-07-25 20:30:13 +02:00
Jonas Platte 4e7bd6760a chore: Replace qualified uses of tracing macros with imports 2022-07-25 20:30:13 +02:00
Jonas Platte ab9476960b chore(sled): Fix line length overflow 2022-07-25 20:30:13 +02:00
Jonas Platte b3092bd1d9 chore(indexeddb): Remove unnecessary .to_string() call in test code 2022-07-25 20:30:13 +02:00
Jonas Platte c2ad4b7d82 fix(appservice): Respond with a non-stringified empty object
warp::reply::json() serializes its argument to JSON, passing it an
already-serialized JSON string doesn't do the right thing.
2022-07-25 20:30:13 +02:00
Jonas Platte f8e729f7f3 chore: Use implicit named arguments for formatting macros more 2022-07-25 20:30:12 +02:00
Jonas Platte 5c88bd1595 refactor(sdk): Remove ID from EventHandler
Turns out it wasn't actually needed.
2022-07-25 20:30:12 +02:00
Damir Jelić 204441f2b3 Fix a formatting issue in a doc example
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-07-25 19:06:15 +02:00
Damir Jelić 79d13148fb chore: Remove TryFrom/TryInto imports 2022-07-25 19:06:15 +02:00
Julian Sparber c247de95b6 client: Remove redudant delay after sync error
If the last sync was less then a 1s ago we wait for a 1s, it doesn't
make sense to wait an additional second on an error. Also the stream
sync api returns the error after a delay of 1s, which doesn't make
sense.
2022-07-25 12:01:28 +02:00
Johannes Becker 6d87dd8011 refactor(appservice)!: Make USER_MEMBER const private" 2022-07-22 09:33:42 +02:00
Jonas Platte 4b6a28da0d chore(sdk): Fix line length overflow in common.rs 2022-07-21 19:24:42 +02:00
Benjamin Kampmann bf6e1b594d fix(integration-tests): requires multi-threading feature from tokio 2022-07-21 18:06:48 +02:00
Benjamin Kampmann 59332e46b5 switch to multithreaded tokio test runner 2022-07-21 17:58:50 +02:00
Benjamin Kampmann c070b96a68 Merge remote-tracking branch 'origin/main' into gnunicorn/issue833 2022-07-21 17:37:49 +02:00
Benjamin Kampmann d68d6ead69 chore: let's check the logs 2022-07-21 17:31:58 +02:00
Benjamin Kampmann f34c2f0574 ci: fix typos 2022-07-21 17:28:38 +02:00
Benjamin Kampmann aad167b792 style(indexeddb): fixing rust fmt 2022-07-21 17:25:43 +02:00
Benjamin Kampmann 814a30064f fix(sled-inspector): new builder fn 2022-07-21 17:18:43 +02:00
Ivan Enderlin 6ce5d0b507 chore(crypto-js): Add cliff.toml for git-cliff. 2022-07-21 15:50:11 +02:00
Ivan Enderlin db7824efbd chore(crypto-nodejs): Update Conventional Commits types. 2022-07-21 15:49:26 +02:00
Ivan Enderlin ee4702d04a feat(bindings/crypto-js) Update package name, and use package scope. 2022-07-21 15:47:55 +02:00
Ivan Enderlin d68b6ea64d doc: Fix formatting. 2022-07-21 15:47:00 +02:00
Ivan Enderlin 49bc950fdd doc: Add missing scope for matrix-sdk-crypto. 2022-07-21 15:46:21 +02:00
Ivan Enderlin 7001113877 doc: Propose conventional commits scopes & types
doc: Propose conventional commits scopes & types
2022-07-21 15:44:43 +02:00
Ivan Enderlin c0d3099e2e doc: Propose conventional commits types. 2022-07-21 15:43:31 +02:00
Ivan Enderlin 49e5d73d83 doc: Propose conventional commits scopes. 2022-07-21 13:59:31 +02:00
Benjamin Kampmann 2ffaaeeae2 docs(sled): fixing examples and utils 2022-07-21 13:18:15 +02:00
Benjamin Kampmann 60eef8967f fix(sled-store): apply review requests 2022-07-21 11:52:04 +02:00
Benjamin Kampmann ed893ed5b0 Merge remote-tracking branch 'origin/main' into gnunicorn/issue756 2022-07-21 11:38:10 +02:00
Jonas Platte 4e2bd14a27 chore: Silence buggy clippy lint 2022-07-21 11:30:13 +02:00
Jonas Platte 0b3b757120 refactor: Make Store type internal to base crate 2022-07-21 11:30:13 +02:00
Jonas Platte 63d01dd20e refactor(base): Stop using Store type in store integration tests 2022-07-21 11:30:13 +02:00
Jonas Platte a43005dec2 refactor(base): Add RoomInfo::new constructor 2022-07-21 11:30:13 +02:00
Jonas Platte 4187aa400f refactor: Remove Store type usage from sled-state-inspector
Requires using more explicit syntax for some calls because SledStore has
methods of the same names with different (harder to use) signatures.
2022-07-21 11:30:13 +02:00
Jonas Platte cf8f3bf7cc refactor(sdk)!: Update MessageOptions API once again
… to match the latest changes in Ruma.
2022-07-21 11:18:09 +02:00
Jonas Platte 5b66bed1f0 chore: Remove unused imports from example 2022-07-21 11:18:09 +02:00
Benjamin Kampmann 1668c173e6 Merge pull request #836 from matrix-org/ben-release-crypto-nodes-beta0
Release crypto-nodejs beta1
2022-07-21 10:59:46 +02:00
Jonas Platte 76fd9bd963 fix(sdk): Call to-device handlers 2022-07-21 10:30:13 +02:00
Benjamin Kampmann 6f18e35b72 Merge remote-tracking branch 'origin/main' into ben-release-crypto-nodes-beta0 2022-07-21 10:25:26 +02:00
Johannes Becker 5f7e91c2e7 refactor(appservice)!: Cleanup 2022-07-21 09:01:53 +02:00
Jonas Platte 45829efa7e feat(bindings): Tracing configuration through FFI 2022-07-20 16:38:51 +02:00
Kévin Commaille a6bd7fc82f chore: Update Ruma 2022-07-20 12:18:06 +00:00
Stefan Ceriu 5c53a5f699 chore(bindings/apple): Remove unnecessary +nightly flag from debug builds 2022-07-20 14:53:00 +03:00
Stefan Ceriu 021bf55074 feat(bindings/sdk-ffi): Expose full tracing configuration string through ffi. 2022-07-20 13:39:15 +03:00
Stefan Ceriu 0043de4028 Update bindings/matrix-sdk-ffi/Cargo.toml
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-07-20 13:28:58 +03:00
Stefan Ceriu f9bb86c52f feat(bindings/sdk-ffi): Allow ffi users to configure tracing and log levels 2022-07-20 12:56:42 +03:00
Stefan Ceriu 1cd18f49aa chore(bindings/apple): Remove now unnecessary debug script module import following module map rename 2022-07-20 12:29:36 +03:00
Benjamin Kampmann 8b160dfd38 Merge pull request #857 from matrix-org/doug/homeserver-details
Add a `HomeserverLoginDetails` to the FFI's auth service.
2022-07-20 10:27:09 +02:00
Doug 77f7dbbbc8 Support server URLs. Join homeserver details futures. 2022-07-19 16:16:03 +01:00
Ivan Enderlin fe590735c1 fix(bindings/crypto-nodejs): Fix CI typo
fix(bindings/crypto-nodejs): Rrrrr
2022-07-19 16:43:40 +02:00
Ivan Enderlin 0360b13cdb fix(bindings/crypto-nodejs): Rrrrr 2022-07-19 16:12:43 +02:00
Jonas Platte f30419446f refactor(sdk)!: Make from in MessageOptions optional 2022-07-19 15:25:16 +02:00
Doug 93d879f356 Add homeserver_details property. 2022-07-19 12:48:00 +01:00
Benjamin Kampmann c20c23bc19 Merge pull request #856 from matrix-org/fixing-clippy-lint
style(crypto): use matches for legibility
2022-07-19 12:54:44 +02:00
Johannes Becker a174d0f669 sdk: Make from in MessageOptions optional 2022-07-19 12:46:48 +02:00
Doug a10a26a68d Tidy up authentication service.
Add HomeserverLoginDetails
2022-07-19 11:36:34 +01:00
Benjamin Kampmann 1940ebefcb style(crypto): use matches for legibility 2022-07-19 12:22:53 +02:00
Benjamin Kampmann b91217f53b Merge remote-tracking branch 'origin/main' into gnunicorn/issue833 2022-07-19 12:19:20 +02:00
Benjamin Kampmann 3d3db96734 style(integration-tests): minor rust fmt fixes 2022-07-19 12:11:13 +02:00
Benjamin Kampmann b24f7b7ad7 ci(integration-tests): switch to non-docker github action 2022-07-19 12:05:49 +02:00
Benjamin Kampmann 9502d32941 Merge remote-tracking branch 'origin/main' into gnunicorn/issue833 2022-07-19 12:03:47 +02:00
Benjamin Kampmann 9318c2f1e8 ci(crypto-nodejs): switch to main branch 2022-07-19 11:36:30 +02:00
Benjamin Kampmann 2d03cb5c79 Merge pull request #852 from zecakeh/test-bulk-member
test(sdk): Split tests for permalinks
2022-07-19 11:34:48 +02:00
Johannes Becker aa8206d6c8 chore: Bump ruma 2022-07-18 19:32:16 +02:00
Johannes Becker f937d82336 chore: Bump ruma 2022-07-18 16:46:34 +00:00
Benjamin Kampmann 3f71818704 ci(test): switch from docker to compose 2022-07-18 18:10:41 +02:00
Benjamin Kampmann 025db83af3 ci(test): cancel previous calls and fix the docker logs cmd 2022-07-18 18:06:54 +02:00
Benjamin Kampmann 8520976417 style(test): fix styles of integration tests 2022-07-18 17:55:31 +02:00
Benjamin Kampmann 06cab75df3 ci(sdk): Add integration tests to CI 2022-07-18 17:39:51 +02:00
Benjamin Kampmann 47a8c62f44 fix(sdk): fetch invitiation details without sync 2022-07-18 17:39:29 +02:00
Benjamin Kampmann e2f1f01cb2 test(sdk): creating integration tests for invitations 2022-07-18 17:33:09 +02:00
Ivan Enderlin fdef2dd86d feat(bindings/crypto-js): Redirect panics and logs into JavaScript console
feat(bindings/crypto-js): Redirect panics and logs into JavaScript console
2022-07-18 14:59:50 +02:00
Ivan Enderlin c72ec36b3a chore(style) Make cargo fmt happy. 2022-07-18 14:39:39 +02:00
Benjamin Kampmann e3febd6f1f refactore(test): move testing out of regular build environment 2022-07-18 14:37:51 +02:00
Kévin Commaille b98e3d80a0 test(sdk): Split tests for permalinks 2022-07-18 13:39:37 +02:00
Kévin Commaille c0a7b17324 test: Add method to create room member events in bulk 2022-07-18 13:39:37 +02:00
Kévin Commaille 66c5d5311e test: Add methods to add events in bulk 2022-07-18 13:39:36 +02:00
Stefan Ceriu f215c92d0b fix(bindings/apple): Remove briding header as no longer needed after corectly naming the module map 2022-07-18 13:09:39 +02:00
Stefan Ceriu d571ca718d fix(bindings/apple): Allow any platform OS simulator to run the Apple specific unit tests. 2022-07-18 13:09:39 +02:00
Kévin Commaille 37eb058dac test: Reorganize JSON responses and events 2022-07-18 10:46:45 +02:00
Kévin Commaille 45ecd89387 test: Build sync response per room and event type
Allow to have more customizable and complete responses
2022-07-18 10:46:45 +02:00
Kévin Commaille 5d916e4a67 test: Expose default room ID used in sync JSON responses 2022-07-18 10:46:45 +02:00
Ivan Enderlin daa0fc0206 doc(bindings/crypto-js): Fix typos. 2022-07-18 10:05:05 +02:00
Ivan Enderlin 3d1c96fbec feat(bindings/crypto-js): Redirect errors to console.error. 2022-07-18 09:51:44 +02:00
Ivan Enderlin decd3fcb43 feat(bindings/crypto-js) Simplify code for feature = "tracing".
This patch creates one `inner` module for when `feature = "tracing"`,
and one for when `no(feature = "tracing")`. Then, let's expose
everything from `inner::*`.

This patch also replaces `Tracing.install` by `new Tracing`. In case
of `not(feature = "tracing")`, `new Tracing` raises an error.

The goal is to remove all the `#[cfg(…)]` annotations everywhere. Now
there is only 2 of them.
2022-07-18 09:44:42 +02:00
Ivan Enderlin c763ce3f41 feat(bindings/crypto-js): Tracing can be installed more than once. 2022-07-18 09:23:37 +02:00
Johannes Becker 09c56ea057 feat(appservice)!: Allow specifying device id for registration 2022-07-14 15:23:21 +02:00
github-actions 163ce94806 Tagging Crypto-Node.js for release 2022-07-14 10:40:57 +00:00
Benjamin Kampmann ebfa235dab chore(crypto-nodejs): Update changelog for beta.1 2022-07-14 12:31:04 +02:00
Benjamin Kampmann 0112396c99 ci(crypto-nodejs): trigger build for new tag 2022-07-14 12:31:04 +02:00
Benjamin Kampmann 8170d2c996 Merge remote-tracking branch 'origin/main' into ben-release-crypto-nodes-beta-1 2022-07-14 11:40:45 +02:00
Benjamin Kampmann 41de3e0af8 Merge pull request #844 from Hywan/fix-issue-842
fix(bindings/crypto-nodejs): Fix pre-built download link
2022-07-14 11:36:15 +02:00
Benjamin Kampmann 81bf300000 Merge pull request #839 from johannescpk/appservice/virtual-users
feat(appservice): Add method to get virtual user map
2022-07-14 11:31:02 +02:00
Benjamin Kampmann 594e8c04cd Merge pull request #840 from matrix-org/jplatte/optional-dep-features
Remove implicit features for optional dependencies
2022-07-14 11:30:03 +02:00
Benjamin Kampmann b6d94ab7c6 Merge pull request #845 from Hywan/fix-issue-843
fix(bindings/crypto-js): Use `cross-env` to pass envvar on Windows
2022-07-14 11:28:57 +02:00
Ivan Enderlin 283c5ff51e fix(bindings/crypto-js): Let's not deal with Console.group.
Events and spans from `tracing` can happen asynchronously, and could
mess the `Console.group` structure.
2022-07-14 09:04:44 +02:00
Ivan Enderlin bb631f2f79 feat(bindings/crypto-js): Add ability to turn Tracing on and off, and change logger min level.
The patch updates the code to use `tracing_subscriber::reload`, so
that we get a `Handle` that can be used to modify the tracing at
runtime.

This patch also adds a new `tracing` feature.

This patch finally adds a test suite for the `Tracing` API.
2022-07-14 09:04:13 +02:00
Ivan Enderlin d39baf1295 test(bindings/crypto-js): Encrypt and decrypt a valid message. 2022-07-14 09:04:13 +02:00
Ivan Enderlin f5016dbb97 feat(bindings/crypto-js): Define Layer.max_level_hint. 2022-07-14 09:04:13 +02:00
Ivan Enderlin e7d0ee4379 !fixup 2022-07-14 09:04:13 +02:00
Ivan Enderlin 70561f9649 feat(bindings/crypto-js): Add the userLogger function to enable logging into Console. 2022-07-14 09:04:13 +02:00
Ivan Enderlin 8f8bd40e8d feat(bindings/crypto-js): Redirect Rust panics to JavaScript console. 2022-07-14 09:04:13 +02:00
Ivan Enderlin 04d326eec1 doc(bindings/crypto-nodejs): Fix package name in the README.md
Fix package name in readme for nodejs bindings
2022-07-14 08:39:53 +02:00
Ivan Enderlin 3567d19359 fix(bindings/crypto-js): Use cross-env to pass envvar on Windows. 2022-07-14 08:26:57 +02:00
Ivan Enderlin 65b1dfef6f fix(bindings/crypto-nodejs): Fix pre-built download link. 2022-07-14 08:14:45 +02:00
Travis Ralston 4f1718e587 Fix package name in readme for nodejs bindings 2022-07-13 13:45:07 -06:00
Jonas Platte 3c5f30d41e refactor: Remove implicit features for optional dependencies
Consistently use `dep:` syntax for optional dependencies so they don't
implicitly act as features of their own.
2022-07-13 18:55:41 +02:00
Jonas Platte 529bdc8e0a refactor: Remove unused optional dependencies 2022-07-13 18:23:52 +02:00
Johannes Becker f55a86dd66 feat(appservice): Add method to get virtual user map 2022-07-13 17:16:12 +02:00
Benjamin Kampmann f87764fabb ci(ffi-apple): fixing ffi build for apple
Merge pull request #806 from matrix-org/stefan/ffi-workflow-optimization
2022-07-13 11:58:26 +02:00
Stefan Ceriu 65654de7eb chore: sdk-ffi apple - try building the framework on x86_64 outside of Xcode 2022-07-13 11:19:07 +02:00
Stefan Ceriu 399bbc25e9 chore: sdk-ffi apple - run the CI build script from the Xcode project and only for the active architecture 2022-07-13 11:19:06 +02:00
Stefan Ceriu c61dbb657e chore: sdk-ffi apple - drop sample project deployment target to iOS 15 and macOS 12, disable catalyst. 2022-07-13 11:19:06 +02:00
Stefan Ceriu a73b104c59 chore: sdk-ffi apple - rename modulemap to module.modulemap as per xcframework specifications 2022-07-13 11:19:06 +02:00
Stefan Ceriu c10961f068 chore: sdk-ffi apple - remove mac catalyst target support 2022-07-13 11:19:06 +02:00
Benjamin Kampmann 15e22cba47 Merge pull request #837 from johannescpk/appservice/refactor-cleanup
refactor(appservice)!: Improve API and cleanup docs
2022-07-13 11:16:47 +02:00
Johannes Becker ec00af0bca refactor(appservice)!: Improve API and cleanup docs 2022-07-13 10:11:43 +02:00
Benjamin Kampmann a4f1c404f6 ci(crypto-nodejs): set npm publish level to public
Release Crypto-Node.js / Upload prebuilt libraries (gcc-aarch64-linux-gnu g++-aarch64-linux-gnu, ubuntu-latest, aarch64-unknown-linux-gnu) (push) Failing after 45s
Release Crypto-Node.js / Upload prebuilt libraries (gcc-arm-linux-gnueabihf, ubuntu-latest, arm-unknown-linux-gnueabihf) (push) Failing after 41s
Release Crypto-Node.js / Upload prebuilt libraries (gcc-i686-linux-gnu g++-i686-linux-gnu, ubuntu-latest, i686-unknown-linux-gnu) (push) Failing after 30s
Release Crypto-Node.js / Upload prebuilt libraries (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Failing after 42s
Release Crypto-Node.js / Upload prebuilt libraries (ubuntu-latest, x86_64-unknown-linux-musl) (push) Failing after 35s
Release Crypto-Node.js / Upload prebuilt libraries (macos-latest, aarch64-apple-darwin) (push) Has been cancelled
Release Crypto-Node.js / Upload prebuilt libraries (macos-latest, x86_64-apple-darwin) (push) Has been cancelled
Release Crypto-Node.js / Upload prebuilt libraries (windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
Release Crypto-Node.js / Upload prebuilt libraries (windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
Release Crypto-Node.js / Upload prebuilt libraries (windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
Release Crypto-Node.js / Package nodejs package (push) Has been cancelled
2022-07-12 19:28:59 +02:00
Benjamin Kampmann 402d061d42 ci(crypto-nodejs): fixing path to npm package for publishing 2022-07-12 18:02:59 +02:00
Benjamin Kampmann 2a1bc372fc chore(crypto-nodejs): setting version 2022-07-12 17:35:46 +02:00
Benjamin Kampmann bcab2a6d8c ci(crypto-nodejs): setting base branch 2022-07-12 17:24:34 +02:00
Benjamin Kampmann 703b3a3561 ci(crypto-nodejs): Fixing typo in workflow 2022-07-12 17:18:54 +02:00
Benjamin Kampmann 36f62ce67f ci(crypto-nodejs): Use regular npm version to set version 2022-07-12 17:14:15 +02:00
Benjamin Kampmann 9bc605a76d ci(crypto-nodejs): FIxing name and directory for action 2022-07-12 17:11:20 +02:00
Benjamin Kampmann 13a6825af7 ci(crypto-nodejs): Fix workflow syntax error 2022-07-12 17:07:49 +02:00
Benjamin Kampmann c5796991e8 chore(crypto-nodejs): Adding changelog 2022-07-12 17:05:40 +02:00
Benjamin Kampmann 9a45325683 ci(crypto-nodejs): use org-wide secrets (#835) 2022-07-12 17:00:44 +02:00
Ivan Enderlin 0bde5ccf38 feat(bindings/crypto-nodejs): Add #[napi(strict)] to force type checking from JavaScript (#829)
* feat(bindings/crypto-nodejs): Add `#[napi(strict)]` to force type checking from JavaScript.

* chore(bindings/crypto-nodejs): Use our own fork of `napi-rs` for the moment.
2022-07-12 16:24:24 +02:00
Benjamin Kampmann 94b635c074 build(crypto-nodejs): Crypto Node.js release infrastructure (#763)
* feat(crypto-nodejs): Download lib binary in postinstall

* build(crypto-nodejs): Workflow to prebuild napi bindings

* ci(crypto-nodejs): Disable broken target, install without download

* ci(apple-ffi): Don't run for drafts

* ci(coverage): Don't run for draft PRs

* fix(crypto-nodejs): bind to current version for download

* fix(crypto-nodejs): Ignore libs and package

* ci(crypto-nodejs): Build and upload NPM package

* fix(crypto-nodejs): Set proper target list

* ci(crypto-nodejs): Remove FreeBSD from build pipeline

* ci(crypto-nodejs): Linkers for linux cross compile

* ci(crypto-nodejs): Add arm64 build for windows

* ci(crypto-nodejs): Proper linkers for arm and musl

* ci(crypto-nodejs): Correct apt command for musl

* fix(crypto-nodejs): Drop arm64 linux musl support

* ci(crypto-nodejs): Manual Workflow trigger process

* chore(crypto-nodejs): Get Github to pickup our action

* ci(crypto-nodejs): Add i686 Linux built

* ci(crypto-nodejs): Configure cliff for nodejs changelogs

* ci(crypto-nodejs): Proper gcc for i868 targets

* docs(crypto-nodejs): Add supported targets for npm install

* ci(crypto-nodejs): Limit building of binaries to tags

* style: consol.log -> console.info; Improve docs

Co-authored-by: Ivan Enderlin <ivan@mnt.io>

* activate for testing

* fix broken merge

* 0.1.0

* fix(js): put in the proper package name

* activate for PR for testing

* fix(nodejs): getting ready for publishing

* ci(crypto-nodejs): Adding docs and fixing naming for workflows

* typo: missed one

* fixing package name

Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2022-07-12 16:05:57 +02:00
Benjamin Kampmann f69123b0d8 style(indexeddb): rust fmt 2022-07-12 13:11:50 +02:00
Benjamin Kampmann 15be2dc45e Merge pull request #832 from johannescpk/sdk/identity-assertion-session
fix(sdk): Can't assert identity without session
2022-07-12 12:25:46 +02:00
Johannes Becker 420ca26bf5 fix(sdk): Can't assert identity without session 2022-07-12 10:44:56 +02:00
Benjamin Kampmann c1f0c73728 fix(indexeddb): New migration didn't create schema for new db 2022-07-11 16:18:29 +02:00
Benjamin Kampmann 54ed1af223 Merge remote-tracking branch 'origin/main' into gnunicorn/issue756 2022-07-11 15:17:03 +02:00
Benjamin Kampmann 6a57461f74 feat(indexeddb)!: Implement StateStoreBuilder pattern to configure migration preferences 2022-07-11 14:28:09 +02:00
Kévin Commaille 2d0653894c refactor(test): Rename LOGOUT to EMPTY
This name is more accurate for its uses.
2022-07-09 17:59:45 +02:00
Damir Jelić 47cfac7f4c test: Optimize sha2 even in debug builds
This makes the tests finish on my machine twice as fast. This works
mainly because some tests utilize pbkdf2 to derive a key from a
passphrase.
2022-07-08 18:47:36 +02:00
Kévin Commaille 9539cbcfb9 test(appservice): Replace mockito with wiremock 2022-07-08 16:33:29 +02:00
Kévin Commaille 9778518347 test(sdk): Replace mockito with wiremock 2022-07-08 16:33:29 +02:00
Ivan Enderlin dc2276cd8a feat(bindings/crypto-nodejs): Implement an Attachment API.
feat(bindings/crypto-nodejs): Implement an `Attachment` API.
2022-07-08 16:26:19 +02:00
Damir Jelić f1c880ff5f feat(bindings/ffi): Add an authentication service
This adds a basic authentication service to the bindings that abstracts away the Client until a login has been completed successfully.
2022-07-08 12:24:15 +02:00
Damir Jelić 93e5728d65 test(sdk): Move the integration tests
This moves the bulk of the Client tests into integration tests.
2022-07-08 12:08:27 +02:00
Damir Jelić a7af96d081 feat(crypto): Customized event types
This patch adds customized event types, currently only for the
m.room_key and m.secret.send to-device events.

This allows us to:
    a) Deserialize the session_key field into a vodozemac type
    b) Control when we zeroize secrets better
2022-07-07 19:20:42 +02:00
Benjamin Kampmann d7b974ac04 build(xtask): indexeddb alias for ci wasm-commands 2022-07-07 18:35:54 +02:00
Benjamin Kampmann aae9b5c6d8 refactor(test)!: More debugging info on errors in async_test macro 2022-07-07 18:35:16 +02:00
Doug 0dee880cd0 Address PR comments. 2022-07-07 17:15:12 +01:00
Ivan Enderlin f0190b4601 feat(bindings/crypto-nodejs): Transform timeout into milliseconds
feat(bindings/crypto-nodejs): Transform `timeout` into milliseconds
2022-07-07 14:54:18 +02:00
Ivan Enderlin 6d83f01e73 fix(sdk): THe MediaEncryptionInfo.web_key has been renamed. 2022-07-07 13:59:36 +02:00
Ivan Enderlin 2eb5fc77f5 feat(bindings/crypto-nodejs): Remove Clone impl for MediaEncryptionInfo.
We don't want to clone a struct that contains a secret.

However, on the Node.js side, we can only receive arguments by
references. The problem we have is that we cannot transfer the
ownership of `MediaEncryptionInfo` to `AttachmentDecryptor` because we
don't own it. To simulate this behavior, we use `Option.take`.

A new method then appears:
`EncryptedAttachment.hasMediaEncryptionInfoBeenConsumed` to know if
the media encryption info has been consumed by `Attachment.decrypt`
already or not. That way, we can decrypt only once. It is possible to
do a JSON-encoded backup of the media encryption info by calling
`EncryptedAttachment.mediaEncryptionInfo` though.
2022-07-07 13:53:46 +02:00
Kévin Commaille 5ab8bd0885 Fix missing import 2022-07-07 13:24:54 +02:00
Kévin Commaille ee69863912 Move event permalink test 2022-07-07 13:19:31 +02:00
Kévin Commaille e87d599f84 Merge remote-tracking branch 'upstream/main' into integration-tests 2022-07-07 13:16:09 +02:00
Ivan Enderlin 0b011d9097 doc(bindings/crypto-nodejs): Add link to the specification. 2022-07-07 13:15:14 +02:00
Ivan Enderlin 0f5851cc01 chore(crypto): Rename MediaEncryptionInfo.web_key to .key. 2022-07-07 13:14:05 +02:00
Kévin Commaille d6a2f15c68 Simplify use of via
Due to a ruma upgrade
2022-07-07 12:30:15 +02:00
Kévin Commaille 36a47c28ed Add note that the event should be part of the room 2022-07-07 12:30:15 +02:00
Kévin Commaille 900016b249 feat(sdk): Get a permalink for an event 2022-07-07 12:30:15 +02:00
Kévin Commaille de60a24602 Remove __test feature 2022-07-07 11:26:49 +02:00
Ivan Enderlin 29c10b8424 feat(bindings/crypto-nodejs): Convert timeout from u128 to u64.
First, u128 has a bug in `serde`,
cf. https://github.com/serde-rs/json/issues/625.

Second, we don't need to represent the timeout as a u128, it's clearly
too large. This patch tries to convert it to u64. It should never
fail, but we propagate the error anyway.
2022-07-07 11:12:12 +02:00
Johannes Becker 4b856ce9d6 fix(sdk): Use the local config variable to decide identity assertion 2022-07-07 10:16:23 +02:00
Ivan Enderlin c043daede0 test(crypto): Fix a test. 2022-07-07 10:15:24 +02:00
Ivan Enderlin 9f6988f766 Merge branch 'main' into fix-issue-796 2022-07-07 10:11:43 +02:00
Ivan Enderlin ed0709373d fix(crypto): Rename web_key to key for MediaEncryptionInfo.
Based on the [Section 11.11.1.6.1 Extensions to `m.room.message`
msgtypes](https://spec.matrix.org/v1.2/client-server-api/#extensions-to-mroommessage-msgtypes),
the parameter for the JSON Web Key is named `key`, not `web_key`. This
patch fixes that by renaming the field when serializing and
deserializing.
2022-07-07 10:04:34 +02:00
Ivan Enderlin acf9b15571 feat(bindings/crypto-nodejs): Use latest napi-rs version to avoid cloning Uint8Array.
The new `napi-rs` release includes a patch that avoids cloning and
copying data inside a `Uint8Array`
(https://github.com/napi-rs/napi-rs/pull/1224), it now returns a
“Node.js reference” of it.

This new `napi-rs` release also includes one of our patch,
https://github.com/napi-rs/napi-rs/pull/1200, which means we no longer
need to depend on our fork.
2022-07-07 09:49:34 +02:00
Charles Wright ba39185679 Fix build errors 2022-07-06 18:08:02 +02:00
Benjamin Kampmann dc40309cbe feat(sled): Introduce SledStoreBuilder, allow migration conflict strategy configuration 2022-07-06 17:51:51 +02:00
Doug da277c4978 Create a new client on login.
More clippy errors.
2022-07-06 12:43:02 +01:00
Doug 9925d73e7b Fix typos and clippy errors. 2022-07-06 11:52:33 +01:00
Benjamin Kampmann d465b70bea refactor(indexeddb)!: Rename SerializationError to IndexedDBStoreError 2022-07-06 12:18:58 +02:00
Doug fec879f0f3 Simplify AuthenticationError for now. 2022-07-06 10:29:13 +01:00
Doug 91427b82a5 Use an Optional client instead of failable init. 2022-07-05 18:14:25 +01:00
Ivan Enderlin d7739369ae chore(bindings/crypto-nodejs): Remove useless napi::Result. 2022-07-05 17:45:09 +02:00
Ivan Enderlin 4fd24eebea feat(bindings/crypto-nodejs): Implement an Attachment API.
This patch provides a new API to encrypt and decrypt attachment,
i.e. big buffer of type `Uint8Array`.

It's based on `matrix_sdk_crypto::AttachmentEncryptor` and `AttachmentDecryptor`.
2022-07-05 17:31:52 +02:00
Benjamin Kampmann 73daec3757 Merge pull request #810 from gnunicorn/expose-invite-details
feat(sdk): Expose details of invite for invited room
2022-07-05 14:56:05 +02:00
Benjamin Kampmann d9f3b257b4 Apply suggestions from code review
Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2022-07-05 14:38:53 +02:00
Damir Jelić 771c33d710 chore(crypto): Bump vodozemac
Vodozemac used to accept and return strings when encrypting and
decrypting. This is quite unusual for a pure cryptographic library so we
switched towards the usual setup where we encrypt/decrypt raw bytes.

Since we do encrypt/decrypt JSON strings in Matrix land, we do the
string conversions over here.
2022-07-05 13:23:50 +02:00
Doug 56adf6a89b Add a client_container with locks. 2022-07-05 11:43:10 +01:00
Ivan Enderlin e5a7a975a3 feat(bindings/crypto-nodejs): Transform timeout into milliseconds. 2022-07-05 12:05:53 +02:00
Ivan Enderlin f3e69a2352 fix(bindings/cryto-nodejs): Fix memory corruption in async functions
fix(bindings/cryto-nodejs): Fix memory corruption in async functions
2022-07-05 10:25:16 +02:00
Ivan Enderlin 607d7ebc22 fix(bindings/cryto-nodejs): Fix memory corruption in async functions.
In async functions, the Node.js GC may or may not (that's a random
behavior) collect the arguments passed to the function as soon as it
returns. The function may not be executed yet, since it's async. Thus,
it leads to memory corruption: The function tries to read later on the
value inside an argument and… it crashes at best.

To avoid this bug, there is no other choice than cloning the values
before the function returns, in its “sync path” (so before any
transformation of an `.await` point into an “async block”).

The performance impact is not “massive”, I'm not sure it could be
noticeable easily since it is most of the time related to identifiers
(e.g. `UserId`), which are cheap to clone. I have to find the balance
here, and cloning offers the best trade off from my point of view.
2022-07-05 09:07:20 +02:00
Doug 0178b71437 Add basic AuthenticationService to the FFI. 2022-07-04 16:55:50 +01:00
Kévin Commaille dd6a902240 test(sdk): Move integration tests 2022-07-04 16:22:20 +02:00
Kévin Commaille 4eb1337dc8 ci: Remove whitespaces in config file 2022-07-04 16:22:19 +02:00
Benjamin Kampmann 81f02f0d0b Merge pull request #804 from gnunicorn/ben-hunting-the-nodjs-segfault
Hunting the nodejs segfault bug, long-term
2022-07-04 15:25:09 +02:00
Ivan Enderlin 76fe6d54ac feat(bindings/crypto-*): Add fallback_keys field to KeysUploadRequest
feat(bindings/crypto-*): Add `fallback_keys` field to `KeysUploadRequest`
2022-07-04 15:02:38 +02:00
Ivan Enderlin eb358889e9 Merge branch 'main' into fix-issue-800 2022-07-04 14:31:28 +02:00
Ivan Enderlin c82631c414 feat(bindings/crypto-js): Implement OlmMachine.sign
feat(bindings/crypto-js): Implement `OlmMachine.sign`
2022-07-04 14:16:27 +02:00
Ivan Enderlin fb4a940a26 chore: Make Clippy happy… 2022-07-04 13:50:28 +02:00
Ivan Enderlin 05561a8777 chore(crypto): Make Clippy happy. 2022-07-04 13:06:14 +02:00
Ivan Enderlin 909ada43d7 chore(base): Make Clippy happy.
So, Clippy suggests to change `(&member).into()` to `member.into()`
but it's the same, and `From<T>` is not implemented for this `T`, only
`From<&T>` is present. Thus, to deceive Clippy, I'm using
`std::borrow::Borrow` here. Not super happy with that though…
2022-07-04 12:00:42 +02:00
Ivan Enderlin 6176b3b658 feat(bindings/crypto-ffi): Add fallback_keys field to KeysUpload. 2022-07-04 11:49:45 +02:00
Ivan Enderlin 566227576e feat(bindings/crypto-js): Add fallback_keys field to KeysUploadRequest. 2022-07-04 11:47:27 +02:00
Ivan Enderlin d6c0ef1497 feat(bindings/crypto-nodejs): Add fallback_keys field to KeysUploadRequest. 2022-07-04 11:47:15 +02:00
Ivan Enderlin f72a14890d chore(crypto) Make Clippy happy. 2022-07-04 11:42:50 +02:00
Ivan Enderlin 62378b4abc Merge branch 'main' into fix-issue-797 2022-07-04 11:24:33 +02:00
Ivan Enderlin f96069f591 chore(store-encryption): Call DerefMut manually.
Clippy on nigtly is raising a warning, which is turned into an error
on the CI. It's the [`explicit_auto_deref`
lint](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref). I
suspect it's a false-positive but I'm not sure. Anyway, to workaround
this and unblock our CI, let's call `DerefMut::deref_mut` manually:
it's clearer anyway.
2022-07-04 11:00:23 +02:00
Ivan Enderlin 59615d4ae3 chore(bindings/crypto-nodejs): Clean up based on feedback. 2022-07-04 10:17:11 +02:00
Benjamin Kampmann fd38c757e4 feat(sdk): Expose details of invite for invited room 2022-07-01 19:44:27 +02:00
Jonas Platte 861d899541 refactor(base): Remove an unnecessary allocation 2022-07-01 16:16:29 +02:00
Jonas Platte fd08c9e7da refactor(base): Remove check for own user in notification handling
This is now done in Ruma.
Reverts commit bc78095611.
2022-07-01 16:16:29 +02:00
Jonas Platte cffb565a5f chore: Allow some usage of deprecated fields
… to allow CI to succeed. They should be removed soon.
2022-07-01 16:16:29 +02:00
Jonas Platte f20d1c3d76 chore: Upgrade ruma 2022-07-01 16:16:29 +02:00
Jonas Platte e4f6c0cc58 chore(sdk): Remove feature ruma/appservice-api-helper
No longer used as of https://github.com/matrix-org/matrix-rust-sdk/pull/710
2022-07-01 16:16:29 +02:00
Jonas Platte d3ae99eb22 chore: Silence new clippy lint 2022-07-01 12:39:46 +02:00
Jonas Platte bc47caa356 chore: Remove unnecessary map_err's 2022-07-01 11:55:28 +02:00
Ivan Enderlin afa96f1bf4 test(bindings/crypto-nodejs): Add more signing test cases. 2022-06-30 16:58:39 +02:00
Ivan Enderlin c99f42347c chore(bindings/crypto-nodejs): Simplify code by removing matches!. 2022-06-30 16:52:08 +02:00
Ivan Enderlin 51cb35502d doc(bindings/crypto-nodejs): Add missing documentation. 2022-06-30 16:50:33 +02:00
Ivan Enderlin b59077e83d chore(bindings/crypto-nodejs): Replacing into_iter by iter on &BTreeMap.
Calling `into_iter` on `&BTreeMap` will not consume it. It has the
same effect as calling `iter`. So let's do it.
2022-06-30 16:48:44 +02:00
Ivan Enderlin 3f197734d9 feat(bindings/crypto-nodejs) Implement OlmMachine.sign.
This patch first implements the new `Signatures`, `Signature` and `MaybeSignature` types.

Then, it moves some Vodozemac types into their own module, and
implements the new `Ed25519Signature` type.

Finally, it implements `OlmMachine.sign`.
2022-06-30 16:44:07 +02:00
Benjamin Kampmann 1961403512 ci(crypto-nodejs): Only build non-release version on failure, improve CI build time 2022-06-30 12:53:51 +02:00
Benjamin Kampmann f1ebbfd245 ci(crypto-nodejs): Create non-release build of version and upload everything as artifacts upon failure 2022-06-30 12:24:21 +02:00
Ivan Enderlin 0458ed9be1 feat(bindings/crypto-js): Implement DeviceKeyId, DeviceKeyAlgorithm and DeviceKeyAlgorithmName. 2022-06-30 08:51:36 +02:00
Ivan Enderlin 12c7b76fea feat(bindings/crypto-js): Implement `OlmMachine.crossSigningStatus. 2022-06-30 08:33:28 +02:00
Marcel a8601e186a fix(appservice): Don't process the same transaction twice 2022-06-29 16:17:25 +00:00
Stefan Ceriu 8a2d13feea feat(bindings): Session verification through FFI 2022-06-29 13:59:52 +02:00
Benjamin Kampmann e2ca56114e Merge pull request #785 from zecakeh/room-permalink
feat(sdk): Add method to get a room permalink
2022-06-29 13:58:25 +02:00
Anderas 3c6d159a04 refactor: Use ClientBuilder pattern in SDK FFI
Co-authored-by: Jonas Platte <jplatte@matrix.org>
2022-06-29 13:13:31 +02:00
Benjamin Kampmann 464bc43290 Merge pull request #793 from Hywan/test-crypto-nodejs-timeout
test(crypto-nodejs): Increase timeout
2022-06-29 12:58:11 +02:00
Kévin Commaille 297861e186 Fix docs styling 2022-06-29 12:20:57 +02:00
Kévin Commaille 8313029e33 Split into methods for both Matrix URI formats 2022-06-29 12:02:26 +02:00
Ivan Enderlin 913bdd683e feat(crypto-js): Change the package name
feat(crypto-js): Change the package name
2022-06-28 19:28:58 +02:00
Ivan Enderlin 041b9bc405 feat(crypto-js): Change the package name. 2022-06-28 17:05:21 +02:00
Ivan Enderlin 1526f76686 test(crypto-nodejs): Increase timeout.
For some unknown reasons, sometimes, randomly, one test (initializing
an `OlmMachine` with a local store with a passphrase) can take more
than 5s, only on Github Actions. Let's increase the test timeout value
so that the entire test suite doesn't fail.
2022-06-28 16:47:46 +02:00
Kévin Commaille f0e0194ff2 feat(sdk): Add method to get a room permalink
Include routing for room IDs
2022-06-26 13:38:01 +02:00
Kévin Commaille ebc7177438 feat(base): Add method to get Room alt aliases 2022-06-26 12:01:51 +02:00
Ivan Enderlin 091fab8a2a chore(bindings): Move matrix-sdk-ffi and matrix-sdk-crypto-ffi into the bindings/ directory
chore(bindings): Move `matrix-sdk-ffi` and `matrix-sdk-crypto-ffi` into the `bindings/` directory
2022-06-23 15:54:32 +02:00
Ivan Enderlin 818d715395 chore: Implement feedback. 2022-06-23 15:53:19 +02:00
Ivan Enderlin 5a0089da52 doc(bindings): Mention bindings in the top README.md file. 2022-06-23 15:12:51 +02:00
Ivan Enderlin 68b6c19dd4 test: Ensure all crates members of the workspace are compiled & tested. 2022-06-23 14:10:31 +02:00
Ivan Enderlin c29e2b9563 !fixup 2022-06-23 11:35:42 +02:00
Ivan Enderlin ecc28efd53 chore(bindings): Move matrix-sdk-ffi and matrix-sdk-crypto-ffi into the bindings/ directory. 2022-06-23 11:31:59 +02:00
Jonas Platte f3a61020e7 refactor(sdk): Rewrite sso login to be easier to read 2022-06-22 17:17:52 +02:00
Jonas Platte a423e92246 chore: Consistently capitalize 'device ID' 2022-06-22 17:17:52 +02:00
Jonas Platte b5d7f10c6b feature: Introduce a login builder API
This improves the readability of login calls.
The old login API is kept, but deprecated.
2022-06-22 17:17:52 +02:00
Ivan Enderlin 931eabf55c chore(bindings): Move crypto-nodejs and crypto-js into the bindings/ directory
chore(bindings): Move `crypto-nodejs` and `crypto-js` into the `bindings/` directory
2022-06-22 16:33:20 +02:00
Ivan Enderlin 8cd7fa9fb0 chore: Implement feedback. 2022-06-22 16:03:37 +02:00
Ivan Enderlin 1604f24136 chore(test): Fix YAML. 2022-06-22 16:03:37 +02:00
Ivan Enderlin 3da737b9e2 chore(test): Shorten job name for test-matrix-sdk-crypto-nodejs.
In the Github UI, we can only see:

    🐧 [m]-crypto-nodejs, Node.js…

What interests us is the Node.js version number.
2022-06-22 16:03:37 +02:00
Ivan Enderlin 2ffcc1a415 chore: Use [m] as an alias for matrix-sdk. 2022-06-22 16:03:37 +02:00
Ivan Enderlin 829dab42c5 chore(test): Rename the test-matrix-sdk-crypto-js job. 2022-06-22 16:03:37 +02:00
Ivan Enderlin 54acd314cc chore(test): Move the wasm workflow inside the ci workflow. 2022-06-22 16:03:37 +02:00
Ivan Enderlin 74953031ee chore(test): Use os-name in step name for test-appservice. 2022-06-22 16:03:37 +02:00
Ivan Enderlin 0436eb9349 chore(ci): Rephrase a little bit the Github Actions steps. 2022-06-22 16:03:37 +02:00
Ivan Enderlin a23bb8f5a0 chore(docs): Rephrase a little bit the Github Actions steps. 2022-06-22 11:57:41 +02:00
Ivan Enderlin 8db58986fb chore(bindings): Move crypto-nodejs and crypto-js into the bindings/ directory.
`matrix-sdk-crypto-nodejs` and `matrix-sdk-crypto-js` are no longer
default members of the Cargo virtual workspace. The Github Actions
workflows for the bindings now live in a `bindings_ci.yml` files
(ideally, it should be in a subdirectory,
`.github/workflows/bindings/ci.yml` but it doesn't work).
2022-06-22 11:54:49 +02:00
Ivan Enderlin 6ad323bc4e test: Run tests faster with nextest
test: Run tests faster with `nextest`
2022-06-22 09:56:02 +02:00
Ivan Enderlin b0d51fdfa5 test: There is no doctest for matrix-sdk-crypto-ffi. 2022-06-22 09:26:51 +02:00
Ivan Enderlin 3bfc68d476 test: Add missing cargo-nextest installation.
This patch also changes the step's name from Clippy to Test.
2022-06-22 09:26:51 +02:00
Ivan Enderlin eb33333925 test: Run doctests manually.
`cargo-nextest` doesn't support doctests for now, so we must run them
“manually” by running a separate `cargo test --doc` command.
2022-06-22 09:26:51 +02:00
Ivan Enderlin d9475c131a test(xtask): Remove xtask -- ci test as it is unused. 2022-06-22 09:26:48 +02:00
Ivan Enderlin 399862d955 test: Run tests faster with nextest.
> [`cargo-nextest`](https://nexte.st/index.html) is a next-generation
> test runner for Rust projects.

This patch installs and uses `nextest` to run our own tests.

Comparing `cargo test` and `cargo nextest` with hyperfine provides the
following results:

```sh
$ hyperfine 'cargo test --workspace' 'cargo nextest run --workspace && cargo test --doc'
Benchmark 1: cargo test --workspace
  Time (mean ± σ):     51.785 s ±  2.066 s    [User: 183.471 s, System: 10.563 s]
  Range (min … max):   49.151 s … 56.641 s    10 runs

Benchmark 2: cargo nextest run --workspace && cargo test --doc
  Time (mean ± σ):     44.556 s ±  0.894 s    [User: 192.213 s, System: 11.441 s]
  Range (min … max):   43.170 s … 45.762 s    10 runs
```

Benchmark 2 is 1.16 times faster than Benchmark 1.
2022-06-22 09:26:07 +02:00
Ivan Enderlin 2c1f5fed8d feat(crypto-js): Migrate tests and polish the API
feat(crypto-js): Migrate tests and polish the API
2022-06-21 12:04:45 +02:00
Ivan Enderlin 8b2237fa7a Merge branch 'main' into feat-crypto-js-next 2022-06-21 11:38:48 +02:00
Ivan Enderlin e5ea2a770b chore(crypto-js): Implement feedback from PR. 2022-06-21 11:25:58 +02:00
Jonas Platte 5f31e9d131 chore: Add missing json language specification to docs 2022-06-20 22:33:35 +02:00
Jonas Platte 6cb9c11b88 chore: Remove unnecessary pub visibility from OnceCell imports 2022-06-20 22:33:35 +02:00
Jonas Platte a00c130fc3 feature: Allow passing already-Arc'ed stores to StoreConfig methods 2022-06-20 18:00:33 +02:00
Jonas Platte 4971802e75 chore: Replace usage of Store with Arc<dyn StateStore> 2022-06-17 17:35:33 +02:00
Jonas Platte 8690addfd5 chore: Add Clone impl for ClientBuilder 2022-06-17 14:59:22 +02:00
Jonas Platte 00a20f325b chore: Add Clone impl for StoreConfig
… by storing the stores inside Arc's instead of Box'es.
2022-06-17 14:59:22 +02:00
Jonas Platte a4e4bfe833 refactor(sdk)!: Change store builder methods from Box<dyn Trait> to impl Trait
To migrate, don't box the store before passing it to `builder.state_store` or
`builder.crypto_store` (remove `Box::new`).
2022-06-17 14:59:22 +02:00
Jonas Platte 02aa537f2a chore: Keep uniffi version in sync across deps, CI 2022-06-17 13:37:07 +02:00
Benjamin Kampmann 5316d2e6e7 fix(indexeddb): Upgrade version to latest state store pattern 2022-06-16 13:17:45 +02:00
Benjamin Kampmann 7adef1d24e fix(sled): Upgrade db version to latest changes 2022-06-16 13:17:35 +02:00
Anderas c755e19fb3 Merge pull request #765 from matrix-org/andy/crypto_ffi
Build Crypto iOS framework
2022-06-16 11:25:39 +01:00
Jonas Platte 8250c24525 chore: Undo pinning of clap 2022-06-15 20:47:55 +02:00
Andy Uhnak fe29fa57eb Build Crypto iOS framework 2022-06-15 13:52:21 +01:00
Ivan Enderlin c564b1a5e1 feat(crypto-nodejs): Add store_path and store_passphrase to the OlmMachine constructor
feat(crypto-nodejs): Add `store_path` and `store_passphrase` to the `OlmMachine` constructor
2022-06-15 07:28:29 +02:00
Benjamin Kampmann 9d691e238a Merge pull request #759 from Hywan/fix-codecov-labs
chore(test): Remove `labs` from the projects + exclude `matrix-sdk-indexeddb` from code coverage report
2022-06-14 20:29:07 +02:00
Ivan Enderlin 520e2f30f7 doc(crypto-js): Add missing module documentation. 2022-06-14 16:54:22 +02:00
Ivan Enderlin c56ab5928c test(crypto-js): Add a workflow to test matrix-sdk-crypto-js. 2022-06-14 16:34:08 +02:00
Ivan Enderlin f8cd2310be feat(crypto-js): Implement OlmMachine.decryptRoomEvent & siblings. 2022-06-14 16:16:54 +02:00
Ivan Enderlin 073fb45580 feat(crypto-nodejs): Define Node.js versions policy.
We now support only “current”, “active” or “maintenance” versions
according to https://nodejs.org/en/about/releases/, which are
compatible with NAPI v6.
2022-06-14 16:05:01 +02:00
Ivan Enderlin 3833d35348 chore(crypto-nodejs): Drop Node.js v12.17.
There is a segfault with `napi-rs` and Node.js in v12.17. It's an old
version, it may be fair to drop its support for now. Let's see if
people would need it in the future, we may work on `napi-rs` to fix
this bug in case it's really necessary.
2022-06-14 16:05:01 +02:00
Ivan Enderlin 83b730d1c8 chore(crypto-nodejs): Make the code compatible with Node.js < 18. 2022-06-14 16:05:01 +02:00
Ivan Enderlin 6477cc5072 feat(crypto-nodejs): Add store_path and store_passphrase to the OlmMachine constructor.
This patch adds the `store_path` and the `store_passphrase` arguments
to the `OlmMachine` constructor to use a `CryptoStore` instead of
having an in-memory Olm machine.
2022-06-14 16:05:01 +02:00
Ivan Enderlin 2117b36a75 chore(test): Exclude matrix-sdk-indexeddb from code coverage report. 2022-06-14 16:04:41 +02:00
Ivan Enderlin 5e8ed3bcbf chore(test): Remove labs from the projects.
It's already part of the `ignore` section.
2022-06-14 16:04:41 +02:00
Jonas Platte 87639a4c4c fix(appservice): Remove erroneous ? operator 2022-06-14 15:20:24 +02:00
Amanda Graven de04aba5b3 fix(appservice): Remove erroneous ? operator 2022-06-14 15:02:55 +02:00
Amanda Graven 5243091bec test(appservice): Virtual client membership
Test that virtual clients get assigned the correct membership to rooms
when processing received transactions.
2022-06-14 14:39:54 +02:00
Amanda Graven 1d746f1ef1 fix(appservice): Virtual client non-membership
Don't assume virtual client membership is join if none is stored, since
that leads to a client being told it's joined in rooms it has no
membership of. The main appservice client still assumes it's joined
every room it receives transaction events about.
2022-06-14 14:39:54 +02:00
Ivan Enderlin 56d74e25b8 test(crypto-js): Finish to migrate the test suites + code clean up. 2022-06-14 14:09:52 +02:00
Ivan Enderlin a758d98f84 feat(crypto-nodejs): Update license. 2022-06-14 12:12:27 +02:00
Ivan Enderlin 5adae6fd41 feat(crypto-js): Migrate tests and polish the API. 2022-06-14 12:12:27 +02:00
Damir Jelić 38d771cca6 ci(coverage): Set the correct out format for CI coverage reports 2022-06-14 12:01:03 +02:00
Jonas Platte dd4c329f57 chore: Prevent clap upgrades beyond 3.2 2022-06-14 11:02:19 +02:00
Jonas Platte e3edf0139a Enable rustdoc-map nightly feature via .cargo/config.toml
… instead of using -Z on the command line.
2022-06-13 14:30:10 +02:00
Jonas Platte d07001a581 chore: Work around a cargo bug 2022-06-13 14:30:10 +02:00
Ivan Enderlin 62b8169ac2 chore(test): Ajust code coverage configurations (tarpaulin and codecov)
chore(test):  Code Coverage must ignore some `matrix-sdk-crypto-(js|nodejs)`
2022-06-13 14:24:22 +02:00
Ivan Enderlin d35063412f chore(test): Ignore matrix-sdk-test-macros and matrix-sdk-ffi. 2022-06-13 12:52:37 +02:00
Damir Jelić 1a162e5dd5 test(crypto): Test the double verification cancellation 2022-06-13 12:30:52 +02:00
Damir Jelić b8069af8ba fix(crypto): Cancel the verification flow if we multiple verifications
The spec claims that we should cancel verifications if multiple
verifications are attempted at once[1]:
    When the same device attempts to initiate multiple verification
    attempts, the recipient should cancel all attempts with that device.

So let's start doing this.

[1]: https://spec.matrix.org/v1.2/client-server-api/#error-and-exception-handling
2022-06-13 12:30:52 +02:00
Damir Jelić fa3e192c37 docs(crypto): Improve the signature verification docs some more
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-06-13 12:12:09 +02:00
Damir Jelić efc53569ed refactor(crypto): Rename our is_signed_by methods 2022-06-13 12:12:09 +02:00
Damir Jelić 5c12132569 refactor(crypto): Introduce a SignedJsonObject trait
This should mostly remove the wild west of signature verification. We
define a trait that tells us which objects can contain signatures and
thus can be passed on to signature verification methods.

It also should be slightly more efficient, since we removed a bunch of
duplicate canonicalization steps.
2022-06-13 12:12:09 +02:00
Amanda Graven 251a38285c perf(appservice): Cache namespace regexes 2022-06-13 11:57:50 +02:00
Ivan Enderlin b500fa1daa chore(test): Configure Tarpaulin to collect data from matrix-sdk-common. 2022-06-13 11:27:22 +02:00
Ivan Enderlin 4430dae421 chore(test): Configure Tarpaulin to ignore more crates. 2022-06-13 11:25:54 +02:00
Ivan Enderlin eead09984c chore(test): Ask codecov.io to ignore the crates/matrix-sdk-crypto-ffi directory. 2022-06-13 11:25:38 +02:00
Ivan Enderlin dcfcac0bd3 chore(test): Ask codecov.io to ignore labs and xtask directories. 2022-06-13 11:24:10 +02:00
Jonas Platte dc32fc282d Remove sync_token from BaseClient
… as it is also accessible as self.store.sync_token in BaseClient methods.
2022-06-13 11:10:12 +02:00
Jonas Platte b6eed09564 Make session field in Store private
… for cleaner encapsulation.
2022-06-13 11:10:12 +02:00
Jonas Platte 29ba171953 Simplify ownership of server_versions
We couldn't originally take references to it when it was behind RwLock,
with OnceCell this is no longer a problem.
2022-06-13 11:10:12 +02:00
Jonas Platte 9e9152745c Remove homeserver_url from HttpClient 2022-06-13 11:10:12 +02:00
Jonas Platte 12d1607cdc Remove session from HttpClient 2022-06-13 11:10:12 +02:00
Jonas Platte 6c8b520f14 Remove unused Clone impls on private types 2022-06-13 11:10:12 +02:00
Jonas Platte fedcdb1e63 chore: Add some more tracing events 2022-06-13 11:10:12 +02:00
Jonas Platte 1cfd69a880 chore: Improve doc comment formatting 2022-06-13 11:10:12 +02:00
Ivan Enderlin dad035d170 chore(test): Configure tarpaulin to use its config file. 2022-06-13 10:46:29 +02:00
Ivan Enderlin 3c14acf163 chore(test): Exclude matrix-sdk-crypto-(js|nodejs) from code coverage reports. 2022-06-13 10:38:07 +02:00
Ivan Enderlin 253affeb0c feat(crypto-nodejs) Implement missing APIs
feat(crypto-nodejs) Implement missing APIs
2022-06-09 21:38:41 +02:00
Ivan Enderlin fe4ddfde89 chore(crypto-nodejs): Remove clone calls when possible. 2022-06-09 21:15:25 +02:00
Ivan Enderlin 8a332ca9e1 chore(crypto-nodejs): Implement feedbacks / polish. 2022-06-09 18:02:29 +02:00
Ivan Enderlin 506f57a22c feat(crypto-nodejs): Enable traace filtering and change the env var to MATRIX_LOG. 2022-06-09 14:06:42 +02:00
Damir Jelić 8b05f9276f fix(sdk): Remove a duplicate Session cell from the HttpClient 2022-06-09 13:37:42 +02:00
Damir Jelić e8b2655d52 docs(crypto-ffi): Explain what a timeout of 0 means when fetching identities 2022-06-09 11:58:23 +02:00
Damir Jelić 537ef1409b test(crypto): Test that we're now notifying when we receive a /keys/query 2022-06-09 11:58:23 +02:00
Damir Jelić e2bf3d0d18 chore(crypto-js): Silence some doc warnings 2022-06-09 11:58:23 +02:00
Damir Jelić d188ef3386 feat(crypto): Add a way wait for a keys/query to be done when fetching identities. 2022-06-09 11:58:23 +02:00
Damir Jelić ba7ccb40cc feat(crypto): Wait for a key query to be done if we're claming one-time keys 2022-06-09 11:58:23 +02:00
Ivan Enderlin 1b2c644277 test(crypto-nodejs): Set up CI to run the test suites. 2022-06-09 11:34:16 +02:00
Benjamin Kampmann 6a853d0173 Merge pull request #744 from matrix-org/jplatte/readme
chore: Fix `main` docs link in readme
2022-06-09 10:51:58 +02:00
Jonas Platte 7487b24fe3 chore: Fix main docs link in readme 2022-06-09 10:21:04 +02:00
Amanda Graven 5c4f2b3430 fix(appservice): Make membership keys consistent
Correct the inconsistency between the keys used for reading and writing
the membership of a virtual user in the appservice's namespace
2022-06-08 10:42:35 +02:00
Stefan Ceriu 901b670a22 Use the nightly toolchain together with the newly introduced target-applies-to-host on the sdk-ffi crate debug builds to avoid cache corruption issues. Switched back to debug mode as the internal tokio crashes went away 2022-06-08 08:55:28 +02:00
Jonas Platte 28d6e2821b chore: Replace new usage of Box<UserId> 2022-06-07 21:12:43 +02:00
Jonas Platte 7f0b74a39d fixup! style: Remove usage of assign! macro from doctests 2022-06-07 21:07:34 +02:00
Jonas Platte 7b6869310f style: Make assign! formatting consistent 2022-06-07 21:07:34 +02:00
Jonas Platte 445b2e627d style: Remove usage of assign! macro from examples 2022-06-07 21:07:34 +02:00
Jonas Platte 0e206506d9 style: Remove usage of assign! macro from doctests 2022-06-07 21:07:34 +02:00
Jonas Platte 0fb1d72100 style: Use anyhow::Ok in more places 2022-06-07 21:07:34 +02:00
Ivan Enderlin 6d8c54deb5 chore(crypto-nodejs): Add missing newline. 2022-06-07 17:03:02 +02:00
Ivan Enderlin 07620452df chore(crypto-node): Make Clippy happy. 2022-06-07 16:50:26 +02:00
Jonas Platte 099db20555 Use target-applies-to-host to avoid unnecessary cache invalidation 2022-06-07 16:43:17 +02:00
Ivan Enderlin 75571c2c30 fix(crypto-js): Fix missing symbol. 2022-06-07 16:42:34 +02:00
Ivan Enderlin 8c95b1c4cf chore(crypto-nodejs): Fix a typo. 2022-06-07 16:40:54 +02:00
Ivan Enderlin 530c268e61 doc(crypto-nodejs): Include the README.md in the generated documentation. 2022-06-07 16:35:22 +02:00
Ivan Enderlin 99dcf84340 chore(crypto-nodejs): Use napi::Result when possible. 2022-06-07 16:28:55 +02:00
Ivan Enderlin 2a76d17bd9 doc(crypto-nodejs): Generate JavaScript/TypeScript documentation. 2022-06-07 16:26:23 +02:00
Ivan Enderlin 15af364c97 Merge branch 'main' into feat-crypto-nodejs-next 2022-06-07 15:31:03 +02:00
Ivan Enderlin ec7724f393 doc(crypto-nodejs): Improve the README.md. 2022-06-07 15:27:35 +02:00
Ivan Enderlin 1e7d509920 chore(crypto-nodejs): Clean up. 2022-06-07 14:45:20 +02:00
Ivan Enderlin 520758bf1e test(crypto-nodejs): Finish the OlmMachine test suite. 2022-06-07 14:42:24 +02:00
Benjamin Kampmann 7f49618d35 Merge pull request #729 from gnunicorn/gnunicorn/issue609
Ensure all data state stores save is encrypted
2022-06-07 12:41:38 +02:00
Benjamin Kampmann a308771a7a fix(sled): Deserialize encrypted TimelineMetadata properly 2022-06-07 12:22:54 +02:00
Benjamin Kampmann 2c4379909c fix(sled): Wrap [u8] encoding in an explicit type to prevent accidential misuse 2022-06-07 12:22:54 +02:00
Damir Jelić d4f49ca334 chore: Fix some new clippy warnings 2022-06-07 11:41:29 +02:00
Damir Jelić c97bb83af9 refactor(base): Remove a bunch of OlmMachine wrapper methods
The whole machine is nowadays exposed through the base Client, so no
need to re-expose individual methods that don't add more functionality.
2022-06-07 11:41:29 +02:00
Ivan Enderlin 12c53bb2bc test(crypto-nodejs): Add more test cases. 2022-06-07 11:05:19 +02:00
Damir Jelić 7fd973c563 refactor(crypto-ffi): Make use of the BackupRecoveryKey type instead of a string 2022-06-07 10:47:19 +02:00
Benjamin Kampmann f8dae723c3 style: Fix review remarks 2022-06-07 10:20:55 +02:00
Benjamin Kampmann 8ccf78c025 fix(indexeddb): Ensure all values are encrypted (namely filters and timeline metadata) if asked to 2022-06-07 10:20:40 +02:00
Benjamin Kampmann 47bb73cf89 fix(sled): Ensure timeline metadata is also saved encrypted 2022-06-07 10:20:27 +02:00
Benjamin Kampmann f3d952839e style: Clean up rustfmt and clippy 2022-06-07 10:19:43 +02:00
Benjamin Kampmann 85ea9279dc fix(indexeddb): Use random db in plain test for consistency 2022-06-07 10:19:27 +02:00
Benjamin Kampmann be159356cd fix(sled): Encrypt custom key and value 2022-06-07 10:19:23 +02:00
Benjamin Kampmann 571b5e61cf fix(sled): Encrypt media content 2022-06-07 10:19:20 +02:00
Benjamin Kampmann 77af11bcbc fix(sled): Encrypt saved sync_token 2022-06-07 10:19:20 +02:00
Benjamin Kampmann 335251695a fix(sled): Encrypt saved filters 2022-06-07 10:19:17 +02:00
Benjamin Kampmann bf17012d6b test(base): Add integration store test for saving filters 2022-06-07 10:19:13 +02:00
Benjamin Kampmann 328ebdba9c fix(sled): Encrypt saved user_ids 2022-06-07 10:19:08 +02:00
Benjamin Kampmann c359b011fa refactor(sled): Rename for consistency event -> value 2022-06-07 10:19:04 +02:00
Ivan Enderlin 07fed7f4df test(crypto-nodejs): Continue to test OlmMachine and add tracing support. 2022-06-06 16:27:32 +02:00
Ivan Enderlin 0ed74d8c31 test(crypto-nodejs): Test OlmMachine.receiveSyncChanges, .outgoingRequests and .markRequestAsSent. 2022-06-06 12:09:37 +02:00
Ivan Enderlin 35d7cab330 feat(crypto-nodejs): Rename requests request_id to id + add type. 2022-06-06 12:08:58 +02:00
Ivan Enderlin 407e27d176 feat(crypto-nodejs): Make changed and left optional in DeviceLists constructor. 2022-06-06 10:27:32 +02:00
Damir Jelić 0f758a643c refactor(crypto): Make the boolean parameter for the backup verification clearer 2022-06-03 16:29:17 +02:00
Damir Jelić fd2ae1ed8f docs(crypto): Improve some backup verfication docs
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-06-03 16:29:17 +02:00
Damir Jelić 2b13c0832f refactor(crypto): Introduce a struct for the backup info 2022-06-03 16:29:17 +02:00
Damir Jelić b3fbd15270 feat(crypto): Improve the API to verify backups
This API change allows us to inspect why a backup is considered to be
trusted instead of just returning a boolean telling us if it's trusted
or not.
2022-06-03 16:29:17 +02:00
Amanda Graven 4e3e393596 refactor(appservice): Better virtual client sync
Store the membership state of clients in the appservice's namespace, and
construct sync events based on that information
2022-06-03 15:03:31 +02:00
Jonas Platte 7f81e7c61b chore: Optimize quote even in debug mode 2022-06-03 14:48:48 +02:00
Ivan Enderlin a75ae16b79 test(crypto-nodejs): Add more test suites. 2022-06-02 15:58:30 +02:00
Ivan Enderlin 9ebc61ad0f test(crypto-nodejs): Adding more test suites. 2022-06-02 15:24:22 +02:00
Ivan Enderlin 0d66480cd6 fix(crypto-nodejs): OlmMachine.new effectively raises an error.
Returning an `napi::Error` doesn't raise it. We must return a
`Result<_, napi::Error>` to ensure `napi` will raise the error as
expected.
2022-06-02 15:23:25 +02:00
Ivan Enderlin 02802e9088 feat(crypto-nodejs): EncryptionSettings.rotation_period and .…_period_messages are now BigInt. 2022-06-02 13:59:00 +02:00
Ivan Enderlin 1a6adc6d41 chore(crypto-nodejs): Ignore package-lock.json for now. 2022-06-02 11:10:55 +02:00
Ivan Enderlin 6d10d6150c test(crypto-nodejs): Add some test suites. 2022-06-02 11:09:57 +02:00
Damir Jelić fb1a2f6d94 feat(appservice): Add support for appservice login
An appservice can log in by providing a valid appservice token and a user within the appservice’s namespace.

This allows the appservice to acquire a scoped access token for a single user. matrix-appservice-sdk can now take a persisted device id for virtual users. If e2ee is enabled, it will automatically perform an appservice login to create the an E2EE backed session for the virtual user.
2022-06-02 10:36:33 +02:00
Damir Jelić bdee4e0547 refactor(crypto): Use a result type for invalid signatures 2022-06-02 09:31:37 +02:00
Denis Kasak 42d5eec8b7 docs(crypto): Improve Signature doc comment. 2022-06-02 09:31:37 +02:00
Damir Jelić e50c1465ea docs(crypto): Improve some signature verification related docs
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-06-02 09:31:37 +02:00
Damir Jelić 5827cc9a39 refactor(crypto): Use ? instead of nesting closures when searching for a key
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-06-02 09:31:36 +02:00
Damir Jelić c95fd93666 fix(types): Allow Ed25519 signatures to be invalid
Since signatures can be uploaded by anyone, unlike one-time keys which
might only be uploaded by the given device for themselves, a Signatures
struct might fail to be deserialized because a signature was maliciously
attached to the object by someone else.

We don't want to fail to deserialize all the signatures just because
someone attached an invalid one. We still would like to have the
signature be deserialized into its proper type if possible so the Raw<T>
pattern was not used.
2022-06-02 09:31:36 +02:00
Damir Jelić d96fcf7199 refactor(crypto): Return a Signatures struct in the sign method 2022-06-02 09:31:36 +02:00
Damir Jelić e2348471db fix(crypto): Make fetching of the first cross signing key more robust 2022-06-02 09:31:36 +02:00
Ivan Enderlin 8e120eb648 doc(crypto-nodejs): Write missing documentation. 2022-06-02 09:23:26 +02:00
Ivan Enderlin c573985c64 chore(crypto-nodejs): Add a .gitignore for artifacts. 2022-06-02 09:19:17 +02:00
Ivan Enderlin 6a996c7657 doc(crypto-nodejs): Write missing documentation and clean up the code. 2022-06-02 09:18:26 +02:00
Ivan Enderlin 7bb96e0ece chore(crypto-node): Use Either7 (new pending feature). 2022-06-01 22:38:52 +02:00
Ivan Enderlin dc7f0389b1 chore(crypto-node): Document and add napi(getter) when necessary. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 5d4b3a0457 feat(crypto-nodejs): Implement OlmMachine.decrypt_room_event. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 888ffb0a56 chore(crypto-node): Use Either5 + Either3 instead of Either. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 475fffb64d feat(crypto-nodejs): Implement OlmMachine.encrypt_room_event. 2022-06-01 20:55:34 +02:00
Ivan Enderlin a8b44f26ea feat(crypto-nodejs): Implement OlmMachine.share_room_key. 2022-06-01 20:55:34 +02:00
Ivan Enderlin a7697fbd32 feat(crypto-nodejs): Implement OlmMachine.get_missing_sessions. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 02e63ab9c1 chore(crypto-js): Remove a useless import. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 8d909ccabe feat(crypto-nodejs): Implement OlmMachine.mark_request_as_sent. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 2e22f6b6c0 feat(crypto-nodejs): Implement OlmMachine.outgoing_requests. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 7c85fdaf28 doc(crypto-js): Update documentation. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 1ecf90bb42 feat(crypto-nodejs): Implement OlmMachine.receive_sync_changes. 2022-06-01 20:55:34 +02:00
Ivan Enderlin e2ecba7d45 feat(crypto-nodejs): Implement OlmMachine.update_tracked_users. 2022-06-01 20:55:34 +02:00
Ivan Enderlin 8a0e0a7a4d feat(crypto-nodejs): Start implementing OlmMachine API. 2022-06-01 20:55:34 +02:00
Charlotte 🦝 Delenk c562d91533 feat(appservice): Use appservice logins for e2ee
This commit also adds a virtual user builder, which allows you to
control the device id, change the client builder, perform an appservice
login, and even restore a previously created session.

https://spec.matrix.org/v1.2/client-server-api/#appservice-login
2022-06-01 15:29:04 +01:00
Ivan Enderlin 3cf4150df2 feat: Rename OlmMachine.share_group_session to OlmMachine.share_room_key
feat: Rename `OlmMachine.share_group_session` to `OlmMachine.share_room_key`
2022-06-01 15:08:58 +02:00
Ivan Enderlin b3d52ca68c feat: Rename OlmMachine.share_group_session to OlmMachine.share_room_key.
As discussed with @poljar, the Matrix event we are creating is
`m.room.key`, so it's preferable to rename the function
`share_room_key`. Note: Olm calls the things an inbound group session,
that's where the name comes from, but it's not aligned with the
specification.
2022-06-01 14:32:11 +02:00
Ivan Enderlin e673954b98 chore: Add missing new lines at the end of files
chore: Add missing new lines at the end of files
2022-05-31 10:31:08 +02:00
Ivan Enderlin 6d7573dced chore: Add missing new lines at the end of files. 2022-05-31 10:06:35 +02:00
Ivan Enderlin 2d14452398 Merge pull request #675 from Hywan/feat-crypto-wasm
feat(crypto): Port to Wasm (in a JS host) and to NodeJS
2022-05-31 10:01:57 +02:00
Ivan Enderlin 7931c4a589 chore(crypto-js): Clean up code and make CI happy. 2022-05-31 08:44:36 +02:00
Ivan Enderlin 4db1ad350b feat(crypto-nodejs): Derive Debug for UserId. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 0debbf24d7 chore(crypto-js): Remove an unknown Clippy lint for now. 2022-05-31 08:40:16 +02:00
Ivan Enderlin bb8217d10f doc(crypto-nodejs) Disable missing docs for now. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 6ff5c8e918 chore(crypto-js): Thanks Clippy. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 7fa89f76aa chore(crypto-js): Update vodozemac's version to match matrix-sdk-crypto's. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 0335fdd07f doc(crypto): Add missing module documentation. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 3f8e3b61ff test(xtask) Replace WasmFeatureSet::MatrixSdkCrypto by *Js. 2022-05-31 08:40:16 +02:00
Ivan Enderlin efe5ea6a9c test(ci): Exclude matrix-sdk-crypto-(js|nodejs) from code coverage. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 6afeeea56c test(ci): Do not compile matrix-sdk-crypto to Wasm, but -crypto-js instead. 2022-05-31 08:40:16 +02:00
Ivan Enderlin bef1dfbf79 chore(crypto-js): Fix typos. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 51488b40d0 doc(crypto-js) Add missing documentation. 2022-05-31 08:40:16 +02:00
Ivan Enderlin b6a637893e chore(crypto-js): Fix cargo fmt. 2022-05-31 08:40:16 +02:00
Ivan Enderlin 2a4dce30b2 Merge branch 'main' into feat-crypto-wasm 2022-05-31 08:40:11 +02:00
Ivan Enderlin 3194ad1f9a feat(crypto-js): Implement OlmMachine.get_verification. 2022-05-31 08:39:34 +02:00
Ivan Enderlin ee648144a2 feat(crypto-nodejs): Split into a new crate: matrix-sdk-crypto-nodejs.
Why? Because `napi` and `wasm-bindgen` are too different. At this
step, the most notable bugs are the way `napi` is handling its proc
macros. There is too much conflicts when used with `#[cfg_attr]`. It
makes the code repetitive and harder to read and to understand (and
also to compile, we must be very careful). But on the short-term,
quickly, we will see more notable differences between `wasm-bindgen`
and `napi`, e.g. with array (in `wasm-bindgen`, we can downcast array
items into particular types, with `napi` it's going to be a very
different code).

Instead of fighting the proc macros bugs now, and having to split the
code later inside the same crate, we believe it's a good idea to split
the code now into 2 crates. At first we will see obvious code
duplications, but on the short-term, the code is likely to be more and
more different.
2022-05-31 08:39:34 +02:00
Ivan Enderlin afef9103a3 feat(crypto-js): Continue to port the API to NodeJS. 2022-05-31 08:39:34 +02:00
Ivan Enderlin 4df5ee6087 chore(crypto-js): Improve the Makefile for NodeJS support. 2022-05-31 08:39:34 +02:00
Ivan Enderlin 1a731ec385 feat(crypto-js): Rename OlmMachine.encrypt to .encrypt_room_event. 2022-05-31 08:39:34 +02:00
Ivan Enderlin 84fe78bab3 Merge branch 'main' into feat-crypto-wasm 2022-05-31 08:39:29 +02:00
Ivan Enderlin bce11b209e feat(crypto-js): Implement OlmMachine.update_tracked_users. 2022-05-31 08:38:24 +02:00
Ivan Enderlin 6c472f873f feat(crypto-js): Start adding support for NodeJS. 2022-05-31 08:38:24 +02:00
Ivan Enderlin 250b85dc79 feat(crypto): Extract js module to its own crate: matrix-sdk-crypto-js. 2022-05-31 08:38:13 +02:00
Ivan Enderlin f3ab1ae276 chore(crypto): Fix a typo. 2022-05-31 08:36:37 +02:00
Ivan Enderlin 6b2df7afdd feat(crypto): Implement `OlmMachine.get_missing_sessions. 2022-05-31 08:36:37 +02:00
Ivan Enderlin cdb252be5e chore(crypto): Move everything inside crates/matrix-sdk-crypto/. 2022-05-31 08:36:37 +02:00
Ivan Enderlin db30ef6ee4 test(crypto): Add tests for the Wasm API. 2022-05-31 08:36:37 +02:00
Ivan Enderlin da8699fe40 feat(crypto): DeviceLists.new expects Array<UserId>s now. 2022-05-31 08:36:37 +02:00
Ivan Enderlin 16b5eebe23 feat(crypto): Implement a hacky downcast function. 2022-05-31 08:36:37 +02:00
Ivan Enderlin 8161360852 feat(crypto): Add toString methods on identifier objects. 2022-05-31 08:36:37 +02:00
Ivan Enderlin f01cfe42b4 feat(crypto): Implement EncryptionSettings.new with default values. 2022-05-31 08:36:37 +02:00
Ivan Enderlin a024c9b268 docs(crypto): Add missing documentation. 2022-05-31 08:36:37 +02:00
Ivan Enderlin c20349f46f feat(crypto): Implement OlmMachine.share_group_session. 2022-05-31 08:36:37 +02:00
Ivan Enderlin e9d37d7c4e docs(crypto): Add missing docs. 2022-05-31 08:36:37 +02:00
Ivan Enderlin 8b94aed27f fix(crypto): Use txn_id for transaction_id. 2022-05-31 08:36:37 +02:00
Ivan Enderlin dc5b15e799 fix(crypto): OutgoingRequest::ToDeviceRequest was not correctly mapped. 2022-05-31 08:36:37 +02:00
Ivan Enderlin 30e9189f7b fix(crypto): Use JavaScript naming convention for OlmMachine.invalidate_group_session. 2022-05-31 08:36:37 +02:00
Ivan Enderlin b6a5d4962b Merge branch 'main' into feat-crypto-wasm 2022-05-31 08:36:30 +02:00
Ivan Enderlin ee713f928f feat(crypto): Implement OlmMachine.encrypt and .invalidate_group_session. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 444ff9936b feat(crypto): Implement RoomId. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 2451815226 feat(crypto): Implement *PublicKey.to_base64 and .length. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 86c6e601bd chore(crypto): Refactor the code with TryFrom on a tuple. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 9f159ff5a4 feat(crypto): Implement OlmMachine.mark_request_as_sent.
To implement this method, a new `responses::OwnedResponse`
intermediate type was needed. In addition to that, the `http` crate is
now required when the `js` feature is enabled.
2022-05-31 08:35:09 +02:00
Ivan Enderlin 056f34883f feat(crypto): Implement OlmMachine.trackedUsers. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 2d15f758da feat(crypto): Use JavaScript naming style for methods. 2022-05-31 08:35:09 +02:00
Ivan Enderlin acd5de3cf3 feat(crypto): Implement ServerName, and add UserId.serverName. 2022-05-31 08:35:09 +02:00
Ivan Enderlin f0bb35a96c feat(crypto): Add changed and left to the constructor of DeviceLists. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 1d38e54739 feat(crypto): Return a JsError rather than a String. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 08665dcd1c feat(crypto): Implement our own future_to_promise helper to simplify code.
`wasm_bindgen_future::future_to_promise` expects a `Future<Output =
Result<JsValue, JsValue>>`. We reimplement this function by expecting
a `Future<Output = Result<T, anyhow::Error>>` where `T:
Into<JsValue>`. That way, we apply the type conversions to `JsValue`
inside this helper rather than in the call site. Additionally, all
errors are managed automatically without having to deal with `JsError`
or `JsValue`. It makes the code simpler to read and easier to write
from my point of view.
2022-05-31 08:35:09 +02:00
Ivan Enderlin 569adb7ceb feat(crypto) Implement OlmMachine.identity_keys. 2022-05-31 08:35:09 +02:00
Ivan Enderlin fd4dff79d4 feat(crypto) Implement OlmMachine.user_id, .device_id and .display_name. 2022-05-31 08:35:09 +02:00
Ivan Enderlin fdb9fe21c6 feat(crypto) Remove existing unwrap code. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 7e5eec82c5 feat(crypto) Implement OlmMachine.outgoing_requests. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 901715bcf3 chore(crypto) Generate a smaller Wasm module. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 3aa46fa746 feat(crypto) Implement OlmMachine.receive_sync_changes & friends. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 3318789a8b feat(crypto) Implement UserId, DeviceId and OlmMachine in Wasm for JS. 2022-05-31 08:35:09 +02:00
Ivan Enderlin 0fe0910fea feat(crypto) Reduce Wasm binary size by enabling LTO. 2022-05-31 08:35:09 +02:00
Damir Jelić a11633381b Merge branch 'poljar/borrow-signature-check-fix' 2022-05-30 12:54:35 +02:00
Benjamin Kampmann 2ff6497604 Merge pull request #715 from gnunicorn/gnunicorn/issue694
docs: configure docs.rs build to contain more features
2022-05-27 22:24:02 +02:00
Damir Jelić 7f87abf408 refactor(crypto): Simplify the signature checking method 2022-05-27 21:29:58 +02:00
Damir Jelić dd49a8bd43 fix(crypto): Don't require mutable borrows when signature checking 2022-05-27 21:28:35 +02:00
Damir Jelić f8c3a1d03b Merge branch 'poljar/signatures-struct' 2022-05-27 20:58:45 +02:00
Damir Jelić 808c4c6f3c chore(crypto): Remove some indentation levels in the types module
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-05-27 20:55:17 +02:00
Damir Jelić a14549d5cc fix(crypto): Don't unwrap when converting to canonical json 2022-05-27 20:55:17 +02:00
Damir Jelić 9b5b4ab2b2 refactor(crypto): Use the Signatures struct for the CrossSigningKey 2022-05-27 20:55:17 +02:00
Damir Jelić 5756057719 refactor(crypto): Use the new Signatures struct for the DeviceKeys 2022-05-27 20:55:17 +02:00
Damir Jelić c5ef3e7c94 refactor(crypto): Turn the SignedKeySignatures into a struct 2022-05-27 20:55:17 +02:00
Damir Jelić fa7c1b60f6 feat(sdk): Replace some Mutex usage with a OnceCell
This makes some simpler getter methods non-async.
2022-05-27 16:37:51 +02:00
Julian Sparber 39b1fff218 Merge remote-tracking branch 'origin/main' into user_once_cell_for_session 2022-05-27 15:53:22 +02:00
Benjamin Kampmann c6df6b421c docs: fix target and feature-list for docsrs 2022-05-27 13:04:07 +02:00
Benjamin Kampmann f9b4fd2d12 docs: configure docs.rs build to contain more features 2022-05-27 10:44:16 +02:00
Damir Jelić e5390e18de refactor(crypto): Introduce a SignJson trait
This patch collects our json signing logic into a single place.
2022-05-27 10:39:12 +02:00
Brandon Lau 28cd0c19e9 fix(crypto-ffi): make crypto-ffi generate a static library for iOS clients 2022-05-27 10:38:21 +02:00
Damir Jelić 15ebc95cd0 chore(qrcode): Add more missing Eq implementations 2022-05-25 13:52:22 +02:00
Damir Jelić 39e12a86ca chore(crypto): Bump vodozemac 2022-05-25 13:49:00 +02:00
依云 ec9ec2567f feat: Add .resolve_room_alias() method to the Client 2022-05-24 08:43:02 +02:00
Damir Jelić fa9c91fb0e fix(crypto-ffi): Add support to encrypt custom events 2022-05-23 19:37:04 +02:00
Johannes Becker 24b71bf869 feat(appservice): Improve autojoin example 2022-05-23 14:14:05 +02:00
Benjamin Kampmann dd83cdd74b Merge pull request #704 from matrix-org/poljar/eq-store-encryption
feat(store-encryption): Derive Eq for some structs
2022-05-23 13:07:29 +02:00
Jonas Platte 453cae641b fix(docs): Remove history gh-pages branch
This should drastically reduce the repository size.
2022-05-23 12:57:45 +02:00
Damir Jelić f838b5fae8 fix(base): Fix a clippy warning about temporary variables 2022-05-23 11:35:23 +02:00
Damir Jelić 1f722f224f feat(crypto): Add a bunch of Eq implementations 2022-05-23 11:35:07 +02:00
Damir Jelić a992a4e831 feat(store-encryption): Derive Eq for some structs 2022-05-23 11:14:09 +02:00
Benjamin Kampmann 017359b081 Merge pull request #700 from gnunicorn/b-improve-coverage-reporting
Improve CI coverage reporting
2022-05-20 12:33:05 +02:00
Benjamin Kampmann 08718acd57 Merge pull request #698 from matrix-org/poljar/rename-encrypt-method
refactor(crypto): Make it clear that the encrypt method is for room events
2022-05-20 10:35:03 +02:00
Benjamin Kampmann dd1f817701 ci(CodeCoverage): exclude ffi & wasm from default project 2022-05-20 10:26:31 +02:00
Benjamin Kampmann 81db9ef4ca ci(CodeCoverage): Remove patch-level coverage reporting 2022-05-20 08:34:56 +02:00
Benjamin Kampmann e927834108 ci(CodeCoverage): split code coverage reporting in mandatory and optional areas 2022-05-20 08:34:39 +02:00
Damir Jelić f3045dbf99 fixup! refactor(crypto): Make it clear that the encrypt method is for room events 2022-05-20 08:32:50 +02:00
Jonas Platte d6c6211c00 chore: Use matrix_sdk::Result alias more 2022-05-20 07:52:39 +02:00
Jonas Platte 85949081ce chore: Consistently use anyhow for Result-returning doctests
Cuts down on syntactic noise.
2022-05-20 07:52:39 +02:00
Jonas Platte cbcc5feef2 fix(sled): Fix unused import when experimental-timeline isn't enabled 2022-05-20 07:52:39 +02:00
Jonas Platte 1b569a8fd4 chore: Consistently use anyhow::Result for example main fn's
When an `Err` is propagated out of `main`, it will be printed using
`Debug`, which is much easier to read in anyhow::Error's case. See also
https://docs.rs/anyhow/latest/anyhow/struct.Error.html#display-representations
2022-05-20 07:52:39 +02:00
Damir Jelić 813f388812 refactor(crypto): Make it clear that the encrypt method is for room events 2022-05-20 07:47:47 +02:00
Damir Jelić 552de33dbc Merge branch 'dkasak/docs-improvements' 2022-05-20 07:26:00 +02:00
Denis Kasak c3f2003eb7 docs: Slightly reword CryptoStore doc for consistency. 2022-05-19 16:22:09 +02:00
Denis Kasak 3b70d7f9ba docs: Improve wording of store module-level comment
Includes a fix to refer to the `e2e-encryption` feature instead of
`encryption` (which doesn't exist).
2022-05-19 16:22:09 +02:00
Denis Kasak c00c9d7b81 docs: Reword feature table so the wording is more uniform 2022-05-19 16:22:09 +02:00
Denis Kasak 126e8f1bd9 docs: Unify references to "cryptostore" as "crypto store" 2022-05-19 16:22:09 +02:00
Denis Kasak 9e6e76e5ed docs: Fix reference to ClientConfig in doc comment 2022-05-19 15:38:13 +02:00
Damir Jelić d1410fcded ci: Run cargo audit every day 2022-05-19 10:03:46 +02:00
Jonas Platte b955e7aad9 Use anyhow::Ok instead of turbofish on Result 2022-05-18 22:04:44 +02:00
Jonas Platte a364018c0e chore: Use serde::de::DeserializeOwned convenience trait 2022-05-18 22:04:44 +02:00
Jonas Platte 0f910b6229 fix(base): Make max_power_level reflect the current maximum only
… instead of taking into account an older maximum as well.
2022-05-18 14:03:12 +02:00
Benjamin Kampmann 736f0e7687 feat: Initial apple platforms support
Merge pull request #571 from matrix-org/jplatte/matrix-sdk-ffi
2022-05-18 13:14:29 +02:00
Stefan Ceriu 6a1b85c560 Fix xcframework debug build script 2022-05-18 13:43:29 +03:00
Benjamin Kampmann e3503fe102 ci: one more move 2022-05-18 11:56:38 +02:00
Benjamin Kampmann 4522b4e8f5 ci: move rust cache to include uniffi bindgen install 2022-05-18 11:32:03 +02:00
Benjamin Kampmann 886809b579 chore(Apple): Move apple into subfolder 2022-05-18 11:24:30 +02:00
Benjamin Kampmann 97b91a47f1 ci: Setup CI test runs FFI crate (Apple platforms support)
Merge pull request #679 from matrix-org/stefan/matrix-sdk-ffi
2022-05-18 10:52:39 +02:00
Stefan Ceriu 4b8b9db075 Have FII action only run on PRs targetting main, similar to the CI one. 2022-05-18 11:49:29 +03:00
Jonas Platte bc207f1e5c chore(sdk): Upgrade async-once-cell to 0.3.1 2022-05-18 10:31:52 +02:00
Stefan Ceriu d863b4eb75 Bump uniffi to version 0.18.0 2022-05-18 11:13:15 +03:00
Stefan Ceriu 45cb162e5a Fix sample project, cleanup tests and add github action 2022-05-18 11:08:51 +03:00
Stefan Ceriu ba2cef62b0 Move apple scripts; tweak the debug one to allow for CI builds 2022-05-18 11:08:51 +03:00
Jonas Platte 2d7fb1b61c fix(matrix-sdk): room::Common:messages() don't return decryption error
If decryption fails we want that the user still has access to
the events.
This was broken in a previous commit.
2022-05-17 18:09:09 +02:00
Julian Sparber d6f9e5f6b6 Remove extra controll flow 2022-05-17 17:52:12 +02:00
Julian Sparber 9c07ff1166 matrix-sdk: room::Common:messages() don't return decryption error
If decryption fails we want that the user still has access to
the events.
This was broken in a previous commit.
2022-05-17 17:23:32 +02:00
Julian Sparber 5bd7d17234 fix(matrix-sdk): room::Common:event() don't return decryption error 2022-05-17 17:03:28 +02:00
Benjamin Kampmann 7d439b1697 Merge pull request #680 from gnunicorn/ben-fix-docs
Fixing docs
2022-05-17 15:45:39 +02:00
Benjamin Kampmann 39f1b9d464 docs: fix link
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-05-17 13:54:37 +02:00
Benjamin Kampmann 8a86369e68 Merge branch 'ben-fix-docs' into jplatte/matrix-sdk-ffi 2022-05-17 13:39:46 +02:00
Benjamin Kampmann a19999b240 docs: fixing broken inner link 2022-05-17 13:38:07 +02:00
Benjamin Kampmann a72a05edc3 Merge remote-tracking branch 'origin/main' into jplatte/matrix-sdk-ffi 2022-05-17 13:05:24 +02:00
Julian Sparber d0cc3d9c2b Don't split links to two lines
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-05-17 12:56:24 +02:00
Benjamin Kampmann 2862934b87 style: fix clippy lints for ffi 2022-05-17 12:51:47 +02:00
Julian Sparber 3f3f9d653b Fix code style 2022-05-17 12:46:06 +02:00
Julian Sparber 83fc91f87e Add a pretty label for Session link 2022-05-17 12:39:11 +02:00
Julian Sparber 1e77c39498 Fix store example 2022-05-17 12:37:51 +02:00
Julian Sparber 1de27bcc0c Fix CI and address requested changes 2022-05-17 12:22:35 +02:00
Amanda Graven 248fff370a test(base): Remove invalid sync event from json
The test json used for mocking a sync response contained an ill-formed
event with a room_id key present in the event. Since the deserialization
ignores the room_id key, this resulted in the client's membership state
evaluating to left going by the contents of the state events, despite
the room being in the "joined" section of the sync response. This is a
violation of the spec.
2022-05-17 11:31:36 +02:00
Julian Sparber 26dd2d0e62 Merge remote-tracking branch 'origin/main' into user_once_cell_for_session 2022-05-17 11:14:28 +02:00
Benjamin Kampmann 4bbfa4345f Merge pull request #678 from Hywan/fix-crypto-doc
docs(crypto): Remove outdated documentation and use auto-link
2022-05-17 10:28:07 +02:00
Johannes Becker 5f92113627 chore: Use resolver2 for workspace 2022-05-17 10:24:28 +02:00
Ivan Enderlin 426a93f07c docs(crypto): Remove outdated documentation and use auto-link. 2022-05-17 10:08:42 +02:00
Benjamin Kampmann 0949979a1b Merge remote-tracking branch 'origin/main' into jplatte/matrix-sdk-ffi 2022-05-16 13:35:51 +02:00
Benjamin Kampmann 76144de881 Fix(SDK): add missing import for experimental-timeline feature
Merge pull request #671 from jsparber/fix_import
2022-05-13 10:33:03 +02:00
Stefan Ceriu bd4763235a chore(matrix-sdk-ffi) Use stable toolchain for targeting aarch64-apple-ios-sim 2022-05-12 16:49:49 +03:00
Julian Sparber 911b5415b9 ci: Use experimental-timeline feature 2022-05-12 13:59:18 +02:00
Julian Sparber c3fc6ff58f Fix missing import for experimental-timeline feature 2022-05-12 12:38:58 +02:00
Benjamin Kampmann 4c84f252d2 Merge pull request #667 from matrix-org/ben-releasing-base-0.5.1
Release matrix-sdk-base 0.5.1
2022-05-11 19:23:16 +02:00
Benjamin Kampmann 70c0626882 chore: tag base 0.5.1 2022-05-11 19:01:12 +02:00
Benjamin Kampmann 5570181bf8 fix(sdk): Fix regression with push rules being applied to the own user_id only instead of all but the own user_id
Merge pull request #664 from JCWasmx86/ignore_notification
2022-05-11 18:52:55 +02:00
Benjamin Kampmann 7088ff89b5 Merge pull request #665 from matrix-org/ben-releasing-0.5.0
Releasing 0.5.0
2022-05-11 18:50:34 +02:00
Benjamin Kampmann 2561ed1df9 docs: Adding release notes for 0.5.0 2022-05-11 18:16:44 +02:00
JCWasmx86 3f36528a98 fix(sdk): Fix regression 2022-05-11 18:15:33 +02:00
Benjamin Kampmann 34da27222f chore: Preparing all the small things for release
Merge pull request #657 from gnunicorn/ben-preping-for-release
2022-05-11 18:10:11 +02:00
Benjamin Kampmann aa69bda05b feat(matrix-sdk): Expose method to decrypt room events
Merge pull request #614 from jsparber/fix_decrypt_timeline
2022-05-11 17:34:19 +02:00
Benjamin Kampmann 8bdd0ffc5d docs: Update crates/matrix-sdk-crypto-ffi/README.md
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-05-11 17:32:22 +02:00
Benjamin Kampmann c21408934c chore: Mark crypto-ffi as non-publish 2022-05-11 17:31:19 +02:00
Benjamin Kampmann daa0768a04 Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-05-11 17:30:12 +02:00
Benjamin Kampmann 706ea248eb Merge pull request #660 from gnunicorn/ben-encrypt-indexeddb-cryptostore-keys
fix(indexeddb): encrypt crypto-store key
2022-05-11 17:26:41 +02:00
Benjamin Kampmann d120d9b70f style(indexeddb): fix import order 2022-05-11 17:09:29 +02:00
Benjamin Kampmann ef2754736a docs(sled): Document doubts on sled in the readme 2022-05-11 17:07:07 +02:00
Jonas Platte bc78095611 fix(sdk): Don't send notifications for your own user 2022-05-11 17:02:30 +02:00
Benjamin Kampmann 45ea472c83 Merge remote-tracking branch 'origin/main' into ben-preping-for-release 2022-05-11 16:57:40 +02:00
Benjamin Kampmann 583810726d style(indexeddb): Minor style fixes for fmt and clippy 2022-05-11 16:56:18 +02:00
JCWasmx86 5fef975ef2 fix(sdk): Don't send notifications for your own user 2022-05-11 16:52:24 +02:00
Benjamin Kampmann 86d2a74c25 Chore: adding issue tracker link to fixme 2022-05-11 15:32:09 +02:00
Benjamin Kampmann aa5e28e58f style(indexeddb): &self.store_cipher instead of Some(ref cipher) 2022-05-11 15:27:28 +02:00
Benjamin Kampmann 0080a74d3b fix(indexeddb): temporarily disable tests 2022-05-11 15:24:56 +02:00
Benjamin Kampmann 44c5244b9a style: fixing cargo format 2022-05-11 13:09:07 +02:00
Benjamin Kampmann 339d701477 fix(indexeddb): Encrypt key with store-cipher 2022-05-11 13:04:15 +02:00
Benjamin Kampmann 74a01376c7 test(sled): Add tests for encrypted crypto-store 2022-05-11 12:42:45 +02:00
Julian Sparber 379e3f27af Merge remote-tracking branch 'origin/main' into fix_decrypt_timeline 2022-05-11 12:28:43 +02:00
Julian Sparber 89e0af97af Drop trait used in room::Common::decrypt_event 2022-05-11 12:28:20 +02:00
Damir Jelić fbb369da8d refactor(crypto): Remove the dead pickle key 2022-05-11 12:02:35 +02:00
Jonas Platte 1fdd1ab23a Cleanup after rebase 2022-05-11 11:57:27 +02:00
Jonas Platte 40dcc988d6 fixup! feat: Initial apple platforms support 2022-05-11 11:07:50 +02:00
Jonas Platte 9909cb597a squash! feat: Initial apple platforms support
Enable sending of messages
2022-05-11 11:07:50 +02:00
Jonas Platte 56cfe8f231 squash! feat: Initial apple platforms support
Some FFI API cleanup
2022-05-11 11:07:50 +02:00
Jonas Platte ab9d8eb52b feat: Initial apple platforms support
Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
Co-authored-by: Benjamin Kampmann <ben.kampmann@gmail.com>
2022-05-11 11:07:42 +02:00
Julian Sparber af01c64712 Fix doc ofr room::Common::decrypt_event() 2022-05-11 11:01:54 +02:00
Julian Sparber c8233b6c85 Drop CryptoHolder and use OnceCell for OlmMachine
THe CryptoHolder is just used to hold the crypto-store till the
matrix_sdk::Session is set and it is possible to create the OlmMachine.
But with this approch we need to use a Mutex and getting the OlmMachine
becomes more expensive because of this. Therefore this replaces the
Mutex with a OnceCell. The only downside is that the BaseClient needs to
hold onto a referance to the crypto-store. (It would be possible to drop
it after the OlmMachine is created, but I don't think gives use any
improvment)
2022-05-11 10:48:12 +02:00
Julian Sparber b72bdcd7d4 Use OnceCell to store matrix_sdk::Session
Since the session can be set only once there is no point in using a
Mutex or RwLock.
2022-05-10 17:10:34 +02:00
Benjamin Kampmann ab87013125 chore: make wasm-example non-publish 2022-05-10 15:10:01 +02:00
Benjamin Kampmann e146daf2a3 chore: bump main crate 2022-05-10 15:09:41 +02:00
Julian Sparber 5501378a77 Merge remote-tracking branch 'origin/main' into fix_decrypt_timeline 2022-05-10 14:55:29 +02:00
Julian Sparber b586f1690b use trait as argument for room::Common::decrypt_event 2022-05-10 14:54:13 +02:00
Benjamin Kampmann 1c967669d9 chore: Bumping crate versions 2022-05-10 13:41:00 +02:00
Benjamin Kampmann 89a8245ce6 fix(test-macros): Add missing feature from syn 2022-05-10 13:09:27 +02:00
Benjamin Kampmann d2f251b2d5 chore: version and path fixes for releasing 2022-05-09 20:11:10 +02:00
Benjamin Kampmann c72b769389 Merge remote-tracking branch 'origin/main' into ben-preping-for-release 2022-05-09 20:09:26 +02:00
Benjamin Kampmann 41799a08ed Merge pull request #655 from matrix-org/ben-name-alignment
Align crate names
2022-05-09 20:04:02 +02:00
Benjamin Kampmann 4b2bac965d docs: Adding Readmes 2022-05-09 17:58:31 +02:00
Benjamin Kampmann c61215630b chore: Fixing missing Cargo.toml Metadata" 2022-05-09 17:43:41 +02:00
Benjamin Kampmann 23a13a77a4 Merge remote-tracking branch 'origin/main' into ben-name-alignment 2022-05-09 17:04:17 +02:00
Benjamin Kampmann cea57724e7 missed one 2022-05-09 16:39:50 +02:00
Jonas Platte 1f714e9cc5 feat(sdk): Allow OriginalSyncRoomRedactionEvent as first event handler param 2022-05-09 16:38:58 +02:00
Jonas Platte 02587bf6bf fix(sdk): Fix wrong event handler ID for redacted redaction event 2022-05-09 16:38:58 +02:00
Jonas Platte 320a20b787 chore: Add store error backend variant constructors 2022-05-09 16:38:58 +02:00
Jonas Platte 844b22fd8e chore: Remove From<Box<dyn Error + …>> impls for store errors 2022-05-09 16:38:58 +02:00
Benjamin Kampmann 26c82b3010 fix: fixing missed cases and style 2022-05-09 16:22:37 +02:00
Benjamin Kampmann 1de4a6cdd6 refactor: Rename matrix-crypto-ffi to matrix-sdk-crypto-ffi 2022-05-09 16:12:11 +02:00
Benjamin Kampmann 08f180cdb7 refactor: Rename matrix-qrcode to matrix-sdk-qrcode 2022-05-09 16:12:11 +02:00
Denis Kasak 8c3843f392 Merge pull request #654 from matrix-org/dkasak/switch-to-vodozemac-release
chore: Switch to released vodozemac
2022-05-09 12:46:15 +00:00
Denis Kasak b396232756 refactor: clippy fixes 2022-05-09 14:34:31 +02:00
Denis Kasak 9e3089074f chore: Switch to released vodozemac. 2022-05-09 14:06:05 +02:00
Julian Sparber fa37a2dea2 Fix missing referance 2022-05-09 13:58:04 +02:00
Julian Sparber 3910122fd5 Remove uneeded ref
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-05-09 13:51:03 +02:00
Julian Sparber 2919c2d5d1 matrix-sdk: Expose method to decrypt room events
The also adds an enum so that the user can give many different rust
types to the decryption method.
2022-05-09 13:12:40 +02:00
Jonas Platte 0fad7b60a9 feat(base): Properly handle redacted m.room.member events 2022-05-09 12:38:22 +02:00
Jonas Platte a2fb420635 chore(base): Use PowerLevels::for_user helper 2022-05-09 12:38:22 +02:00
Jonas Platte 6088993706 chore(base): Move MinimalStateEvent higher up the module hierarchy 2022-05-09 12:38:22 +02:00
Jonas Platte 41bcc9bdd7 chore(base): Remove unnecessary bounds on MinimalStateEvent 2022-05-09 12:38:22 +02:00
Jonas Platte dc08d5f62b chore: Update MemberEvent to allow redacted member events 2022-05-09 12:38:22 +02:00
Jonas Platte 985c7d7b36 chore: Inline From trait implementations for MemberEvent
They were each just used in a single place.
2022-05-09 12:38:22 +02:00
Jonas Platte 58bcd354f6 chore(sdk): Reduce unnecessary clones 2022-05-09 12:38:22 +02:00
Ivan Enderlin 5c6a6464c4 chore(crypto) Fix a typo in the code. 2022-05-09 11:50:40 +02:00
Ivan Enderlin d3c20b2a13 feat(crypto) Generate a cdylib for the crate.
Ask `rustc` to generate a dynamic system library, which will be useful
to generate a Wasm module.
2022-05-09 10:51:18 +02:00
Ivan Enderlin 7817af9aa6 feat(crypto) Add the js feature.
This patch updates to code to raise a compilation error if the `js`
feature is used for another architecture than `wasm32`.
2022-05-09 10:40:32 +02:00
Ivan Enderlin 7569c08ada feat(crypto) Add wasm-bindgen as a dep and simplify Cargo.toml. 2022-05-09 10:40:13 +02:00
Charlotte be2a818c84 feat(base)!: Use boxed errors in StoreError and CryptoStoreError 2022-05-06 17:05:27 +02:00
Benjamin Kampmann 8b805f9f01 Merge pull request #649 from zecakeh/display-name
DisplayName fixes
2022-05-06 14:46:49 +02:00
Benjamin Kampmann 86b9dc5e57 style(appservice): Remove allocation and make clippy happy 2022-05-06 14:08:27 +02:00
Jonas Platte 260f888a89 chore(appservice): Fix another clippy warning 2022-05-06 14:08:01 +02:00
Jonas Platte 5907fac248 chore(base): Rewrite BaseRoomInfo::handle_redaction 2022-05-06 14:08:01 +02:00
Jonas Platte 3c8da5f7e1 feat(base): Handle redactions in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte 8043b6c1e1 chore(base): Store topic event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte 4e16f79ad2 chore(base): Store tombstone event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte f93baf7ed4 chore(base): Store name event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte 9e058b6202 chore(base): Store join_rules event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte a5e81ebcc9 chore(base): Store history_visibility event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte aa7fc8ff47 chore(base): Store guest_access event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte 849fbe94f1 chore(base): Store create event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte c9527e7263 chore(base): Store canonical_alias event's ID in BaseRoomInfo 2022-05-06 14:08:01 +02:00
Jonas Platte 9a3b81178f chore(base): Store avatar event's ID in BaseRoomInfo
Required to make redactions work properly.
2022-05-06 14:08:01 +02:00
Jonas Platte 1e9e13ab63 chore(base): Use RoomInfo::room_version accessor 2022-05-06 14:08:01 +02:00
Kévin Commaille 2545e1bd72 fix(sdk): Re-export DisplayName 2022-05-06 11:35:48 +02:00
Kévin Commaille 1b8337cdc2 doc(sdk-base): Fix typo 2022-05-06 11:35:48 +02:00
Jonas Platte b95aea9cf0 chore(crypto): Fix new clippy warning 2022-05-06 11:29:35 +02:00
Julian Sparber 12cdf8c159 chore(sdk): Use OnceCell to store server versions 2022-05-06 11:08:10 +02:00
Benjamin Kampmann 2054f5deef docs(crypto-ffi) Fix a typo in the README.md
Merge pull request #645 from Hywan/doc-readme-typo
2022-05-06 08:23:28 +02:00
Benjamin Kampmann 0a6983512a Merge pull request #646 from Hywan/doc-sdk-base-readme-typo
docs(sdk-base) Fix a typo in the `README.md`
2022-05-06 08:07:34 +02:00
Ivan Enderlin 977438207c docs(sdk-base) Fix a typo in the README.md. 2022-05-05 13:42:34 +02:00
Ivan Enderlin 87b849a95b docs(crypto-ffi) Fix a typo in the README.md. 2022-05-05 13:36:39 +02:00
Damir Jelić 3a4656cedd Merge branch 'poljar/cleanup-verification-constructors' 2022-05-05 13:16:34 +02:00
Benjamin Kampmann 7e399e1e8d Merge pull request #644 from matrix-org/poljar/fix-sled-cryptostore-only-compilation
fix(sled): Fix the compilation if only the cryptostore is enabled
2022-05-05 12:43:38 +02:00
Benjamin Kampmann b9e92886de refactor!: Put timeline behind experimental-timeline-feature-flag 2022-05-05 12:31:02 +02:00
Damir Jelić 2c415abce8 fix(sled): Fix the compilation if only the cryptostore is enabled 2022-05-05 12:22:16 +02:00
Benjamin Kampmann 3de2a9ad22 feat(sled): Add state store db schema version support
Merge pull request #640 from matrix-org/gnunicorn/issue585
2022-05-05 12:13:30 +02:00
Benjamin Kampmann 0f95687bec fix(base): Don't create empty changeset for each run 2022-05-05 12:11:33 +02:00
Damir Jelić 2a5f17005d refactor(crypto): Make the transaction id non-optional in the Sas constructor 2022-05-05 11:55:00 +02:00
Benjamin Kampmann 5fce18f4dd chore: remove unneccessary feature-flag 2022-05-05 11:21:34 +02:00
Benjamin Kampmann 93b42236fe chore: Merge remote-tracking branch 'origin/main' into b-featureflag-timeline 2022-05-05 10:33:56 +02:00
Benjamin Kampmann 26935ee1c0 Fix(room)!: Calculate display_name correctly for invited rooms
- [x] Make the `DisplayName` an actual type to allow API users to localize the generic name
 - [x] tests for various naming use cases
 - [x] fix the cases where we currently calculate a faulty name, fixes #133 
 - [x] strong-typed EitherMemberEvent from storage
 - [x] add tests for eithermember in store integration tests 
 - [x] update sled store for new trait signature
 - [x] update indexeddb store for new signature
 - [x] rename `DisplayName::Computed` to `DisplayName::Calculated`
 - [x] fix renaming failing test(s)
2022-05-04 20:04:07 +02:00
Benjamin Kampmann ab08ce6ff1 style(sled): cargo fmt 2022-05-04 16:54:03 +02:00
Benjamin Kampmann ae3cd70904 feat(sled): Add store db schema version support 2022-05-04 16:39:08 +02:00
Benjamin Kampmann 7b21166784 chore: Merge remote-tracking branch 'origin/main' into b-featureflag-timeline 2022-05-04 16:17:06 +02:00
Benjamin Kampmann 403ce9b711 chore: Merge remote-tracking branch 'origin/main' into gnunicorn/issue133 2022-05-04 16:10:22 +02:00
Benjamin Kampmann 98fa629f38 fix(memstore): Separate stripped and regular user indixes 2022-05-04 16:09:54 +02:00
Benjamin Kampmann 75f0fe94e8 fix(indexeddb): Separate stripped and regular user_id indixes 2022-05-04 16:02:02 +02:00
Benjamin Kampmann c0c4c603aa refactor!: Cleaning up feature gates
Merge pull request #591 from matrix-org/ben-feature-fixup

 - [x] switches to latest rust 1.60 as MSRV
 - [x] renames `encryption`-feature to `e2e-encryption` for clarity
 - [x] combines the `*-state-store`/`*-crypto-store` features into a single feature `sled` and `indexeddb` respectivly
 - [x] and combines them with weak `e2e-encryption`-dependencies to activate the features as necessary
 - [x] moves the code back to the sled-store, where it belongs
 - [x] updates the docs accordingly

BREAKING CHANGE
2022-05-04 15:26:20 +02:00
Benjamin Kampmann 0abdebfe8b docs: typo in feature name
Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2022-05-04 15:15:06 +02:00
Benjamin Kampmann 8e2e4e6058 style(xtask): Fixing formatting 2022-05-04 13:54:55 +02:00
Benjamin Kampmann aaee28b34f style: Improved wording
As suggested in the review.

Co-authored-by: Damir Jelić <poljar@termina.org.uk>
2022-05-04 13:48:11 +02:00
Benjamin Kampmann 335a7d03c3 fix: Put all MSRV to 1.60 2022-05-04 13:41:07 +02:00
Benjamin Kampmann f61248cbbd style: Put warnings aside by feature-gating properly 2022-05-04 13:38:08 +02:00
Damir Jelić 83d6e8ea82 refactor(crypto): Simplify the verification object constructors
This patch moves all the important identities that we need for
verification into the already existing IdentitiesBeingVerified struct.

It adds a method to get those identities to the store, and streamlines
our to-device and in-room verification constructors.
2022-05-04 13:36:26 +02:00
Benjamin Kampmann fdcbd59557 fix(SDK): Put timeline behind a feature-flag 2022-05-04 12:55:01 +02:00
Benjamin Kampmann 3a06908755 fix(sled): Put timeline behind feature-flag 2022-05-04 12:42:34 +02:00
Benjamin Kampmann 5f6e0ae033 fix(base): Put further timeline features behind feature-flag 2022-05-04 12:36:53 +02:00
Benjamin Kampmann e1e919dd2c fix(indexeddb): Put timeline feature behind feature-flag 2022-05-04 12:24:21 +02:00
Benjamin Kampmann 98d2b8a0fe fix(base): Put timeline behind exprimental-timeline-feature-flag 2022-05-04 11:54:14 +02:00
Benjamin Kampmann e60d2fde7e fixing xtask wasm-pack cli command 2022-05-04 11:11:01 +02:00
Benjamin Kampmann 5d3351f5cc chore(sledstore): Revert user-id removing code 2022-05-04 10:52:42 +02:00
Jonas Platte b2273ab7a1 chore: Add semicolons after unit-typed expressions 2022-05-03 14:23:29 +02:00
Jonas Platte 17a26bfe68 chore: Use Entry::or_default() where applicable 2022-05-03 14:23:29 +02:00
Jonas Platte d44f2657f4 chore(base): Fix inconsistent order of common function parameters 2022-05-03 14:23:29 +02:00
Jonas Platte 1c3890651d chore(base): Simplify signature of handle_invited_state 2022-05-03 14:23:29 +02:00
Jonas Platte 92f3737be6 chore: Remove unneeded lint silencing 2022-05-03 14:23:29 +02:00
Benjamin Kampmann 3cc5e48aac ci: Fix new no-crypto ci wasm command 2022-05-03 12:05:34 +02:00
Damir Jelić c01cbdd3f2 fix(crypto-ffi): Allow room message requests to be marked as sent 2022-05-03 10:59:16 +02:00
ganfra 84d1af1332 [crypto-ffi] Add RoomMessage in RequestType 2022-05-03 10:49:17 +02:00
Benjamin Kampmann e3016482e1 fix: Simplify UnknownError in SDK 2022-05-03 10:28:28 +02:00
Benjamin Kampmann a58a58f30d Merge remote-tracking branch 'origin/main' into ben-feature-fixup 2022-05-03 10:21:11 +02:00
Benjamin Kampmann 7dd7f5a611 Merge pull request #626 from matrix-org/gnunicorn/issue565
Fixing benchmarking, 

fixes #565
2022-05-03 10:20:15 +02:00
Benjamin Kampmann aad0cbe496 ci(benchmarking): disable benchmark runs other than manually requested 2022-05-03 09:39:35 +02:00
Benjamin Kampmann 68d5097d96 fix(sled): Unmix stripped and regular user_ids 2022-05-03 09:03:13 +02:00
Benjamin Kampmann 06085a0c74 Merge remote-tracking branch 'origin/main' into gnunicorn/issue133 2022-05-03 08:45:24 +02:00
Benjamin Kampmann f416ebfdd8 fix(sled-store): Fix faulty mixing of stripped and regular user_ids 2022-05-03 08:44:52 +02:00
Benjamin Kampmann 4de29b8178 test(state tests): Put stripped_member test into its own DB to ensure separation 2022-05-03 08:22:57 +02:00
Benjamin Kampmann 12894aff99 ci(benchmark): Fixing output format 2022-05-02 17:01:56 +02:00
Benjamin Kampmann f20390036b fix(indexeddb): Ensure internal account info is up to date on regular save_changes 2022-05-02 16:58:21 +02:00
Benjamin Kampmann 9763c13a34 ci(benchmarks): Switch to Mr. B access token 2022-05-02 16:36:44 +02:00
Benjamin Kampmann 54c93e4982 ci(benchmarks): more specific cargo-bench params 2022-05-02 16:30:30 +02:00
Benjamin Kampmann b6d71cbeba fix(benchmarks): keep the temprorary dir until end of tests 2022-05-02 16:29:50 +02:00
Benjamin Kampmann a4ec6cb6d6 fix(sled-crypto): Ensure cryptostore.save_changes for account updates internal account_info 2022-05-02 16:29:02 +02:00
Benjamin Kampmann 1ea377bdbf chore: Merge pull request #625 from matrix-org/ben-ci-fixup
xtask fixup
2022-05-02 15:45:29 +02:00
Benjamin Kampmann 827f8c3e17 ci(benchmarking): Add github token to benchmarking 2022-05-02 14:17:13 +02:00
Benjamin Kampmann 32cd372f49 Merge remote-tracking branch 'origin/main' into ben-feature-fixup 2022-05-02 13:30:42 +02:00
Benjamin Kampmann b592fc5cac Update xtask/src/fixup.rs
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-05-02 12:44:31 +02:00
Benjamin Kampmann d077aa6a90 chore(indexeddb): Merge fixes 2022-05-02 12:07:40 +02:00
Benjamin Kampmann 392d48ba01 Merge remote-tracking branch 'origin/main' into gnunicorn/issue133 2022-05-02 11:51:26 +02:00
Benjamin Kampmann d1aa463b7c Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-05-02 11:43:37 +02:00
Benjamin Kampmann fb8ddfa07d style: Fixing name 2022-04-29 17:56:50 +02:00
Benjamin Kampmann 2803694cdf ci(benchmarks): Adding Benchmarks to CI 2022-04-29 17:54:53 +02:00
Benjamin Kampmann a7b8cc5810 ci: remove unnecessary dependency 2022-04-29 17:28:51 +02:00
Jonas Platte f8b9ec9626 chore: Remove ruma re-export from matrix-sdk-common
The user-facing re-exports in matrix-sdk-base and matrix-sdk remain.
2022-04-29 17:13:22 +02:00
Jonas Platte c3d9a60067 chore: Remove async_trait from matrix-sdk-common 2022-04-29 17:13:22 +02:00
Benjamin Kampmann a70d05cb63 Merge branch 'main' into ben-ci-fixup 2022-04-29 15:15:46 +02:00
Benjamin Kampmann 5682b3bc09 ci(xtask): Adding fixup to xtask 2022-04-29 15:13:43 +02:00
Benjamin Kampmann 29674213e8 style: Cleanup styles with pre-commit 2022-04-29 14:52:41 +02:00
Benjamin Kampmann 9b6fe94bc8 ci(tooling): Improved Style Checking
- separate Styles from ci.yaml into its own for clarity
- extend pre-commit config with other useful defaults
- move clippy, tests and typos into a push-based pre-commit
2022-04-29 14:50:12 +02:00
Jonas Platte c0c30438ab chore: Upgrade Ruma to 0.6.1 2022-04-29 13:17:51 +02:00
Jonas Platte 814e415374 chore: Use new Ruma helper methods for some events 2022-04-29 13:03:50 +02:00
Jonas Platte dfd193e3b0 chore: Change TOML inline tables to be single-line consistently 2022-04-29 13:03:50 +02:00
Jonas Platte 82164b098a chore: Sort dependencies
Mostly automated (cargo sort --workspace).
2022-04-29 13:03:50 +02:00
Jonas Platte 4b1c77ec5a chore: Use js Date.now() support from Ruma 2022-04-29 13:03:49 +02:00
Benjamin Kampmann d9d143eba7 fix(sled-store): Seperate stripped and non-stripped buckets 2022-04-29 12:42:36 +02:00
Jonas Platte 097cb99ae5 chore: Make target-specific dependency formatting more consistent
* Put target-specific dependencies last
* Put cfg(wasm) before cfg(not(wasm))
* Use long table names only where lines get too long otherwise
2022-04-29 11:30:31 +02:00
Jonas Platte aae8989f99 chore(sdk): Merge local import with file-level imports 2022-04-29 11:09:14 +02:00
Jonas Platte 70174e1fea Upgrade Ruma to 0.6.0 2022-04-29 11:07:17 +02:00
Benjamin Kampmann 301cf3561f chore(indexeddb): Fix merge leftover 2022-04-29 10:41:14 +02:00
Benjamin Kampmann 18864d9722 chore: Merge remote-tracking branch 'origin/main' into gnunicorn/issue133 2022-04-29 10:27:33 +02:00
Benjamin Kampmann 9c6bc066f2 chore(CI): Add Wasm-Pack to CI
Merge pull request #619 from matrix-org/gnunicorn/issue617
2022-04-28 17:50:39 +02:00
Benjamin Kampmann 83b5d8f20e style: cargo fmt 2022-04-28 17:32:54 +02:00
Benjamin Kampmann ebd85ebaa2 feat(indexeddb): Add support for key backup v1 2022-04-28 17:31:09 +02:00
Denis Kasak 1962e7ec1d Merge pull request #621 from matrix-org/dkasak/doc-improvements2
Document `OlmDecryptionInfo` and make it `pub(crate)`.
2022-04-28 14:35:32 +00:00
Denis Kasak 73bd3a0598 fix(crypto): Make OlmDecryptionInfo and decrypt_to_device_event pub(crate). 2022-04-28 16:21:39 +02:00
Denis Kasak 698ab5328f docs(crypto): Document OlmDecryptionInfo and fix some errors. 2022-04-28 16:08:07 +02:00
Benjamin Kampmann 87ae677fc3 fix(ci): fixing it right this time 2022-04-28 13:15:27 +02:00
Benjamin Kampmann 5d3c14f309 fix(ci): fixing the wasm ci command 2022-04-28 13:12:06 +02:00
cutecutecat 33425a43d0 chore: Replace lazy_static with once_cell 2022-04-28 11:10:34 +00:00
Benjamin Kampmann 608eca6166 test(indexeddb): activate indexeddb tests for CI 2022-04-28 12:43:07 +02:00
Benjamin Kampmann a49dfa8aa2 Merge branch 'main' into gnunicorn/issue133 2022-04-28 12:36:36 +02:00
Benjamin Kampmann 3caed26f93 test(base): fix wasm tests 2022-04-28 12:00:19 +02:00
Benjamin Kampmann 7aeb8cf482 style: cargo fmt 2022-04-28 11:24:59 +02:00
Benjamin Kampmann 16ec5fe9ff chore: Merge remote-tracking branch 'origin/main' into gnunicorn/issue617 2022-04-28 11:23:32 +02:00
Benjamin Kampmann aff106f0d6 style: cargo fmt 2022-04-28 11:08:27 +02:00
Benjamin Kampmann 4b575d3d2b style: newline 2022-04-28 11:08:03 +02:00
Benjamin Kampmann 0f2424d140 test(crypto): fix wasm tests 2022-04-28 11:06:35 +02:00
Benjamin Kampmann 9c80774140 feat(common-utils): helper for modified MilliSecondsSinceUnixEpoch 2022-04-28 11:06:35 +02:00
Benjamin Kampmann d46b5ab0b6 tests: add js to get-random on matrix-sdk to allow compilation 2022-04-28 11:06:35 +02:00
Benjamin Kampmann 5b13cf4e92 Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-04-28 10:25:03 +02:00
Damir Jelić 649aff2c92 fix(crypto-ffi): Rename the error message field for MigrationError
The field is called message which clashes with the field of the same
name in the Kotlin Exception class.
2022-04-27 18:56:30 +02:00
Damir Jelić 5d8c485a51 chore: Bump most of our deps 2022-04-27 17:30:53 +02:00
Damir Jelić d8ff18322e feat(crypto-ffi): Allow unencrypted verification events to be handled 2022-04-27 17:30:41 +02:00
Damir Jelić 4780c560e1 feat(base): Pass unencrypted verification events to the olm machine 2022-04-27 17:30:41 +02:00
Damir Jelić d94f415db4 feat(crypto): Allow unencrypted verification events to be handled 2022-04-27 17:30:41 +02:00
Benjamin Kampmann 4b6ed22476 chore(ci): install wasm-pack 2022-04-27 17:20:14 +02:00
Benjamin Kampmann 868afffc4d formatting 2022-04-27 17:05:50 +02:00
Benjamin Kampmann 6a81ec226e chore: enable wasm-pack tests in ci 2022-04-27 16:58:42 +02:00
Benjamin Kampmann c0fc7c9f7e chore: Adding ci-subcommand to xtask for testing 2022-04-27 16:50:27 +02:00
Benjamin Kampmann 1bf1147d18 fixing style 2022-04-27 16:22:47 +02:00
Benjamin Kampmann 2bdd44ce1d Merge branch 'main' into gnunicorn/issue133 2022-04-27 15:45:39 +02:00
Julian Sparber 910bf531fe feat(sdk): Add method to set whether a room is DM and store all targets
This ensures also that we use, for user verification, only a DM room with
no members other then ourself and the user to be verified.
2022-04-27 12:53:51 +02:00
Benjamin Kampmann 66fcc1e486 forgot two instances in rename 2022-04-27 12:36:19 +02:00
Benjamin Kampmann 628de09938 rename Full -> Original 2022-04-27 12:22:19 +02:00
Benjamin Kampmann 703a95c486 grumbles 2022-04-27 12:21:06 +02:00
Benjamin Kampmann 48cb625f19 fixing lints 2022-04-27 12:06:42 +02:00
Benjamin Kampmann 266d7c6da7 fixing last broken display_name tests 2022-04-27 12:06:15 +02:00
Benjamin Kampmann b5ab076546 tests(matrix-sdk-base): allowing enable debugging logs for tests 2022-04-27 12:02:56 +02:00
Jonas Platte e5c2ba4bd8 fix(sdk): Export RumaApiError 2022-04-26 19:16:36 +02:00
Kévin Commaille d62cb9650f Fix typo 2022-04-26 18:59:51 +02:00
Kévin Commaille dfdaea786b docs: Document RumaApiError variants 2022-04-26 18:49:21 +02:00
Damir Jelić 6e89ecfbf0 fix(indexeddb): Don't derive a StoreCipher twice if we're reusing the db 2022-04-26 18:46:55 +02:00
Damir Jelić 742c1944eb fix(sled): Put the StoreCipher behind the Arc, not the Option 2022-04-26 18:46:55 +02:00
Damir Jelić e1baa25713 fix(sled): Don't derive a StoreCipher twice if we're reusing the db 2022-04-26 18:46:55 +02:00
Kévin Commaille 189ae93e90 fix(sdk): Export RumaApiError 2022-04-26 18:17:04 +02:00
Benjamin Kampmann 4431a2d48a fix(room name): check for proper type 2022-04-26 17:40:04 +02:00
Benjamin Kampmann 3cdee30fc1 fixing docs 2022-04-26 17:33:17 +02:00
Benjamin Kampmann 592a9338eb style, and other fixes 2022-04-26 17:27:18 +02:00
Benjamin Kampmann 55b7fd617c fix(indexeddb-store): implement merge room members 2022-04-26 17:04:46 +02:00
Benjamin Kampmann ca2f598d9e fix(sled-store): implement merge room members 2022-04-26 16:23:22 +02:00
Benjamin Kampmann 8cdfd43863 test(store): additional intergration test for stripped members 2022-04-26 15:38:58 +02:00
Benjamin Kampmann e9e21c1b25 rename computed -> calculated 2022-04-26 15:34:49 +02:00
Benjamin Kampmann 61ea1c9003 Merge remote-tracking branch 'origin/main' into gnunicorn/issue133 2022-04-26 15:24:13 +02:00
Damir Jelić 39ef1d550d chore(crypto): Improve a log line 2022-04-26 14:46:07 +02:00
Damir Jelić a425ddf97f fix(crypto): Don't try to encrypt a room key for our own device 2022-04-26 14:46:07 +02:00
Damir Jelić d38995b3f9 fix(crypto): Add our own device to the store when we create a new account 2022-04-26 14:46:07 +02:00
Damir Jelić 3490a9f726 chore(crypto): Remove a useless compile_error! call 2022-04-26 13:56:45 +02:00
Damir Jelić 610e3ffc5f fix(crypto): Be more restrictive around Megolm session rotation periods 2022-04-26 13:56:45 +02:00
Benjamin Kampmann cfeda54fc6 fix(store): combine stripped and regular membership and allow fetching that 2022-04-26 13:35:06 +02:00
Jonas Platte 2a11df01c7 chore(indexeddb): Remove unneeded matrix-sdk-common dependency 2022-04-26 11:40:54 +02:00
Jonas Platte 08fd85ea09 chore: Upgrade Ruma 2022-04-26 11:40:54 +02:00
Jonas Platte 32d1997dfc feat(crypto): Accept borrowed identifiers in some public functions 2022-04-26 11:40:54 +02:00
Jonas Platte 00249ab96e fix: Fix a typo 2022-04-26 11:40:54 +02:00
Damir Jelić 7710b0b14f Merge branch 'poljar/encrypted-reactions-fix' 2022-04-26 11:22:39 +02:00
Damir Jelić cc6e5b868e chore(sdk): Use the % sigil to record room ids 2022-04-26 09:58:25 +02:00
Damir Jelić 5f83184512 fix(sdk): Don't encrypt reactions 2022-04-26 09:41:50 +02:00
Jonas Platte 16a35081ed feat(sdk): Merge HttpError::{Api, ClientApi} 2022-04-25 19:55:56 +02:00
Jonas Platte ddb6d6af90 chore: Fix typos 2022-04-25 19:42:06 +02:00
Damir Jelić 1f8f7c853b docs(crypto-ffi): Slight docs improvements
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-04-25 14:22:01 +02:00
Damir Jelić a25a88bd25 refactor(crypto-ffi): Use the anyhow Result type for the migration function 2022-04-25 14:22:01 +02:00
Damir Jelić 94832d1a8b fix(crypto-ffi): Allow the machine to be opened with a passphrase 2022-04-25 14:22:01 +02:00
Damir Jelić 2552c0f393 docs(crypto-ffi): Add docs to the migrate method 2022-04-25 14:22:01 +02:00
Damir Jelić 797fbb2fda feat(crypto-ffi): Add a progress listener to the migrate method 2022-04-25 14:22:01 +02:00
Damir Jelić 35d4749ba7 feat(crypto-ffi): Add support to migrate from a libolm based setup 2022-04-25 14:22:01 +02:00
Damir Jelić c5ddca3bc4 feat(sled): Add a method to save tracked users in a batched way 2022-04-25 14:22:01 +02:00
Damir Jelić a6b7c98002 feat(crypto): Add a public method to import private cross signing keys 2022-04-25 14:22:01 +02:00
Benjamin Kampmann 84b721abb0 Merge pull request #599 from zecakeh/pr-cov
ci: Run code coverage for pull requests
2022-04-25 14:07:27 +02:00
Benjamin Kampmann 7ea6cb3e95 rename Calculated -> Computed 2022-04-25 13:31:45 +02:00
Benjamin Kampmann 15e76b90b1 adding display name integration tests for DM invite 2022-04-25 13:29:59 +02:00
Kévin Commaille 5c41b992b7 ci: Add newline at end of codecov.yaml
Co-authored-by: Benjamin Kampmann <ben.kampmann@gmail.com>
2022-04-25 12:53:42 +02:00
Kévin Commaille 5ce6c07d9c ci: Update codecov github action to v3 2022-04-25 12:44:33 +02:00
Kévin Commaille 8090220963 ci: Add codecov config file
Be tolerant for coverage of new PRs
2022-04-25 12:43:22 +02:00
Kévin Commaille 314a9dec6c ci: Run code coverage for pull requests 2022-04-25 12:08:58 +02:00
Benjamin Kampmann 48fc26a35b tests for broken room name 2022-04-22 17:45:27 +02:00
Benjamin Kampmann b420d7022a typed display name for i18n 2022-04-22 15:35:38 +02:00
Benjamin Kampmann 79e543eceb fix(state-stores): ensure counter consistency 2022-04-21 16:20:24 +02:00
Benjamin Kampmann 375e976289 formatting 2022-04-21 13:02:55 +02:00
Benjamin Kampmann 071d440567 fix(indexeddb-store): always pad counter with u64 padding size to ensure order consistency 2022-04-21 12:56:32 +02:00
Benjamin Kampmann d4053e2c54 fix(sled-store): save index as i64 to ensure portability 2022-04-21 12:53:10 +02:00
Benjamin Kampmann a0ba610e0b fixing wasm example 2022-04-20 16:35:55 +02:00
Benjamin Kampmann c995331f57 fixing typo 2022-04-20 16:22:32 +02:00
Benjamin Kampmann 577b45f8ce activate encryption on base if crypto-store is activated, handle non_exhaustive errors raised 2022-04-20 16:19:55 +02:00
Jonas Platte 0c7e0167c7 Merge pull request #592 from zecakeh/login-sso 2022-04-20 15:45:43 +02:00
Benjamin Kampmann 9761934bf5 fixing features in ci jobs 2022-04-20 15:43:57 +02:00
Kévin Commaille 04d62bbe1e Apply suggestions to docs
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-04-20 15:35:54 +02:00
Benjamin Kampmann 115300fa5e Addressing review comments 2022-04-20 15:27:41 +02:00
Benjamin Kampmann ae8943e050 fixing style 2022-04-20 15:25:56 +02:00
Kévin Commaille 11292b5e5a fix(sdk): Don't convert SSO login URL parse error to IoError. 2022-04-20 15:21:23 +02:00
Kévin Commaille 559fe35e1b fix(sdk): Bind SSO login server to 127.0.0.1 instead of localhost
Avoid name resolution failure in some devices
2022-04-20 15:21:23 +02:00
Kévin Commaille 32b5e5d48b feat(sdk): Improve docs for SSO login server's random ports 2022-04-20 15:21:14 +02:00
Benjamin Kampmann 3de9c54552 more feature related fixups 2022-04-20 14:39:42 +02:00
Benjamin Kampmann b29a50bed5 moving make_store_config features back to sled, fxies #562 2022-04-20 14:36:11 +02:00
Benjamin Kampmann d36220ed7c e2e-encrypted weak feature dependency 2022-04-20 14:26:54 +02:00
Benjamin Kampmann 117fd1612b explain in readme 2022-04-20 14:10:24 +02:00
Benjamin Kampmann 2c506717c8 setting rust-version 2022-04-20 14:08:27 +02:00
Damir Jelić e57721be09 Merge branch 'poljar/session-timestamp-improvements' 2022-04-20 12:11:53 +02:00
Damir Jelić 954bba6fdf fix(crypto): Don't put the session timestamps behind an Arc 2022-04-20 10:49:32 +02:00
Damir Jelić edbf831a0f fix(crypto): Make sure to sort the sessions by timestamp before encrypting
This ensures that we're using the correct Session even if our store
doesn't provide those in the correct order. The set is small anyways, so
this shouldn't have any performance impact.
2022-04-20 10:49:22 +02:00
Damir Jelić c0172c4858 fix(crypto): Fix an error message 2022-04-20 10:49:22 +02:00
Benjamin Kampmann 06f5b67b23 feat(state_store): Store keys and values encrypted, too
Merge pull request #586 from matrix-org/ben-remove-store-key

This removes the store_key and replaces it with the new key cipher for both sled and indexeddb state stores. If they are given a passphrase, we are now encrypted/hashing all keys and values stored in the store, no leaking of metadata in any key or value anymore.
2022-04-19 16:46:11 +02:00
Benjamin Kampmann 07c5f625d4 fixing encryption examples 2022-04-19 16:30:20 +02:00
Benjamin Kampmann 805044ed41 Merge branch 'ben-remove-store-key' of github.com:matrix-org/matrix-rust-sdk into ben-remove-store-key 2022-04-19 16:23:29 +02:00
Benjamin Kampmann 4da7d31770 fixing unnecessary lifetimes 2022-04-19 16:22:25 +02:00
Benjamin Kampmann cdab735ce5 Apply suggestions from code review
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-04-19 16:19:30 +02:00
Benjamin Kampmann e989b9aff7 merge sledstore's EncodeKey and SecureEncodeKey into one 2022-04-19 16:01:18 +02:00
Damir Jelić a8466f5069 refactor(crypto): Use the ruma time types for group sessions as well 2022-04-19 14:07:44 +02:00
Damir Jelić 95a3fe136d refactor(crypto): Use the ruma time types for the Session timestamps 2022-04-19 14:03:31 +02:00
Benjamin Kampmann 88d1aa615c remove unnecessary reference making 2022-04-19 12:42:39 +02:00
Benjamin Kampmann ac8500759c newline 2022-04-19 12:27:11 +02:00
Benjamin Kampmann 07f01eb985 typos 2022-04-19 12:26:27 +02:00
Benjamin Kampmann 953d759238 sort and typo 2022-04-19 12:21:26 +02:00
Benjamin Kampmann 9d09401ede .into instead of ::from 2022-04-19 12:20:41 +02:00
Benjamin Kampmann 872f32a7e0 sorting line order 2022-04-19 12:08:26 +02:00
Benjamin Kampmann 05b3077a7a fixing lints again 2022-04-19 11:00:13 +02:00
Benjamin Kampmann 8fdd8648c7 Merge remote-tracking branch 'origin/main' into ben-remove-store-key 2022-04-19 10:41:40 +02:00
Benjamin Kampmann 4e8383ea4f fixing clippy lints 2022-04-19 09:26:28 +02:00
Benjamin Kampmann 80791860fe fixing style and typos 2022-04-19 09:23:29 +02:00
Benjamin Kampmann 9698a50ad8 fixing timeline for encrypted indexeddb store 2022-04-13 15:52:57 +02:00
Benjamin Kampmann a390c3b40b more explicit naming 2022-04-13 15:52:10 +02:00
Benjamin Kampmann 70a5517c5c make room timeline test more debuggable 2022-04-13 15:23:50 +02:00
Benjamin Kampmann 262bee51b1 also implement room timeline in encrypted fashion on sled store 2022-04-13 15:23:14 +02:00
Benjamin Kampmann 897bb5aed2 new db for every encrypted test 2022-04-12 20:00:11 +02:00
Benjamin Kampmann 24266fe254 fixing ranges 2022-04-12 19:59:55 +02:00
Benjamin Kampmann 5d6c4852b1 fix media content test 2022-04-12 19:37:43 +02:00
Benjamin Kampmann 64e0356756 implementing encrypted keys 2022-04-12 19:17:49 +02:00
Benjamin Kampmann b611aa2503 remove store key feature and references 2022-04-12 16:58:56 +02:00
Benjamin Kampmann 1cdde23bc4 replace storeky with storecipher in wasm 2022-04-12 16:50:58 +02:00
Benjamin Kampmann b3c8f80b6e expose internal functionality for wasm-based storage 2022-04-12 16:50:44 +02:00
Jonas Platte 35f598a095 fix(sdk): Change the default guest_access state to Forbidden 2022-04-12 14:39:30 +02:00
Jonas Platte ad538f3f28 Upgrade Ruma 2022-04-12 14:39:30 +02:00
Jonas Platte 073d9db29f chore(crypto): Remove redundant match arms 2022-04-12 14:39:30 +02:00
Benjamin Kampmann cebe7bee92 adding encrypted tests for indexeddb store 2022-04-12 13:11:59 +02:00
Damir Jelić 7bd0f2c50c chore(sled): Fix a clippy warning 2022-04-12 13:06:17 +02:00
Benjamin Kampmann fb8f123616 fixing remaining key lookup 2022-04-12 12:44:34 +02:00
Damir Jelić 87632e7ead chore(crypto): Update vodozemac 2022-04-12 12:37:56 +02:00
Benjamin Kampmann 88be0ee9c1 fix user id streams 2022-04-12 12:24:11 +02:00
Benjamin Kampmann 000be73e80 making tests more explicit 2022-04-11 23:47:20 +02:00
Benjamin Kampmann 551711261d integration tests for encrypted version 2022-04-11 22:49:09 +02:00
Benjamin Kampmann 918d95a672 first batch of data for testing encrypted sled store 2022-04-11 22:11:14 +02:00
Benjamin Kampmann f79e6b87e2 use result 2022-04-11 20:42:35 +02:00
Benjamin Kampmann 529d1e0117 removing store key from sled store - for values 2022-04-11 13:52:08 +02:00
Jonas Platte 0dafd8cd65 chore: Update all unit test module names to the conventional 'tests' 2022-04-08 12:35:54 +00:00
Jonas Platte 1dbb0226ad feat(sdk): Check server versions after creating the Client 2022-04-08 14:16:55 +02:00
Damir Jelić 05826de639 fix(crypto): Box the RecoveryKey array so moves don't copy the key 2022-04-06 10:02:00 +02:00
Damir Jelić 4e05fe9f4a refactor(crypto): Simplify the Signing struct 2022-04-06 09:24:57 +02:00
Damir Jelić 26172ded49 ci: Test the WASM example in the CI run 2022-04-05 14:57:13 +02:00
Damir Jelić 814d4dcb8b chore(xtask): Check the wasm example when running the wasm tests 2022-04-05 14:47:24 +02:00
Damir Jelić b9f415e81e chore(sdk): Fix some clippy lints in the wasm example 2022-04-05 14:47:01 +02:00
Damir Jelić 124efe6f67 ci(wasm): Emscripten isn't needed anymore 2022-04-05 14:02:07 +02:00
Damir Jelić f2e2976496 fix(sdk): Make the wasm_command_bot example compile and work
This patch does a couple of things:

1. Fix the compilation of the example, Message -> MessageLike
2. Update Webpack and friends for the example
3. Remove futures-timer's Delay method and use equivalent methods from
   Tokio and wasm-timers.

The last point was needed because futures-timer would end up triggering
this error:
    ReferenceError: can't access lexical declaration '__wbg_clearTimeout_d8b36ad8fa330187' before initialization
2022-04-05 14:02:07 +02:00
Benjamin Kampmann 44be0cf12a chore(base): Make fields of RoomInfo and BaseRoomInfo private
Merge pull request #569 from matrix-org/jplatte/room-info-privacy
2022-04-05 11:20:12 +02:00
Benjamin Kampmann 64d9a1f633 docs: Add example to print the room history
Merge pull request #566 from jsparber/add_timeline_example
2022-04-04 17:21:14 +02:00
Jonas Platte 6f9664c9f4 chore(base): Make fields of RoomInfo and BaseRoomInfo private 2022-04-04 16:35:07 +02:00
Julian Sparber f1c1b3d319 example: Require sled-state-store for timeline example 2022-04-04 15:33:04 +02:00
Damir Jelić 6007aa7056 fix(crypto): Add some missing zeroization calls in the key export logic 2022-04-04 13:34:13 +02:00
Kévin Commaille acd8ecbd22 feat(sdk): Retrieve account data from room::Common 2022-04-04 12:15:12 +02:00
Jonas Platte eab68131e7 chore: Split auxiliary tools into separate crates 2022-03-31 14:37:52 +02:00
Julian Sparber 8807a2abaf Add example to print the room history 2022-03-31 14:37:38 +02:00
Jonas Platte e2aab504fb Move sled state inspector into a separate crate 2022-03-31 14:26:32 +02:00
Jonas Platte 9567f8f28f Move the crypto benchmarks into a separate crate
Avoids issues from circular dev-dependency.
2022-03-31 14:26:32 +02:00
Damir Jelić 1e09577a8a chore: Make the Verification and OpenStoreError enums non exhaustive 2022-03-30 13:47:56 +02:00
Damir Jelić 155abb262b chore(crypto-ffi): Add a wildcard pattern to the store opening
This is only useful in our workspace, the workspace enables the
state-store in the matrix-sdk-sled crate, which turns an additional enum
variant on.
2022-03-30 13:47:56 +02:00
Damir Jelić 8782e0068f chore(sdk): Add a wildcard match for the verifcation enum conversion
This is needed because we now have multiple consumers of the
matrix-sdk-crypto crate in the workspace. The different consumers
might enable different feature sets.

Compilation of the workspace might fail if the qrcode feature is enabled
on the `matrix-sdk-crypto` crate but disabled on the `matrix-sdk` crate.

This patch adds a wildcard pattern to the Verification enum so we handle
the case where the matrix-sdk qrcode feature remains disabled.
2022-03-30 13:47:56 +02:00
Damir Jelić 66e4ea979c refactor(crypto-ffi): Use a type alias for the encrypted event type 2022-03-30 13:47:56 +02:00
Damir Jelić a957a02d5d refactor(crypto-ffi): Use the parse methods to parse identifiers 2022-03-30 11:10:46 +02:00
Damir Jelić 8079da7b0a chore(crypto-ffi): Use the the latest matrix-sdk-crypto crate. 2022-03-30 10:44:39 +02:00
Damir Jelić 8793efebc7 chore(crypto): Expose the types module publicly 2022-03-30 10:44:39 +02:00
Damir Jelić f5d2ea0efa fix(sdk): Use a consistent naming scheme for our features 2022-03-30 10:26:38 +02:00
Damir Jelić e720b4d5e3 chore(sdk): Fix a clippy warning for the sso_login feature 2022-03-30 10:26:38 +02:00
Damir Jelić d3f4db258f chore(crypto): Remove some dead code mentioning the sled_cryptostore feature 2022-03-30 10:26:38 +02:00
Damir Jelić 13d1048d7e fix(sled): Allow the crypto-store to be used without the state-store 2022-03-30 10:26:38 +02:00
Jonas Platte d9001409a2 chore(sdk): Remove qrcode from default features
Breaking change: If you need QR code support, you now need to enable the
qrcode feature on the matrix-sdk crate.
2022-03-30 10:03:29 +02:00
Jonas Platte 890c191884 Clean up toml formatting 2022-03-30 10:03:29 +02:00
Jonas Platte 8d3441b51b Deduplicate / clean up EncodeKey trait 2022-03-30 10:03:29 +02:00
Jonas Platte 1912a63f17 chore(indexeddb): Implement SafeEncode for RoomAccountDataEventType 2022-03-30 10:03:29 +02:00
Jonas Platte e4c6040de4 Generalize SafeEncode tuple implementations 2022-03-30 10:03:29 +02:00
Jonas Platte b8c7ab9867 fix(indexeddb): Add missing as_encoded_string call 2022-03-30 10:03:29 +02:00
Jonas Platte d56d50e96f Use field shorthands in tracing macros
Automated using search `\b(\w+) = \?\1` => replace `?$1`.
2022-03-30 10:03:29 +02:00
Jonas Platte f375d8c141 Move ? in tracing macros away from =
To make it obvious that it's more like a modifier to the field value,
rather than a single `=?` operator.
2022-03-30 10:03:29 +02:00
Jonas Platte 7f9e1c8799 Remove unnecessary uses of event content enums 2022-03-30 10:03:29 +02:00
Jonas Platte ed52cfc43c fix(base): Propagate push rules deserialization errors
… from BaseClient::get_push_rules.
2022-03-30 10:03:29 +02:00
Jonas Platte 09893651a4 Remove unnecessary allocations 2022-03-30 10:03:29 +02:00
Benjamin Kampmann 7e48034cc8 Merge pull request #555 from jsparber/fix_timeline
store: Make sure that event position in store is contiguous
2022-03-29 12:26:27 +02:00
Jonas Platte 8815e77576 chore: Upgrade Ruma 2022-03-28 18:21:32 +02:00
Jonas Platte db9b3febd3 Upgrade Ruma 2022-03-28 17:54:06 +02:00
Damir Jelić 36d1ba34a9 chore(crypto): Rename the Other key enum variant into Unknown 2022-03-28 17:05:00 +02:00
Damir Jelić 105961a78d chore(crypto): Change the expect message for device key serialization
Co-authored-by: Benjamin Kampmann <ben.kampmann@gmail.com>
2022-03-28 17:05:00 +02:00
Damir Jelić 23040a1bf7 refactor(crypto): Use vodozemac types for the cross signing and device keys 2022-03-28 17:05:00 +02:00
Julian Sparber 07066e1c1f store: Make sure that event position in store is contiguous
This fixes the breaking gap in the timeline when reading the events from
store.
2022-03-28 15:50:48 +02:00
Damir Jelić 4b58017951 chore(crypto): Add umlauts to a copyright holder
Co-authored-by: Jonas Platte <jplatte@element.io>
2022-03-28 14:24:38 +02:00
Damir Jelić 5db5341974 chore(crypto): Use a specialized CrossSigning type 2022-03-28 13:53:01 +02:00
Damir Jelić 9a3d097331 chore(crypto): Use a specialized DeviceKeys type 2022-03-28 13:53:01 +02:00
Damir Jelić c50b369d72 fix(crypto): Remove some unwraps when creating inbound sessions 2022-03-28 13:48:18 +02:00
Julian Sparber 28893ec388 fix(store): Fix sync message order 2022-03-25 14:47:55 +01:00
Damir Jelić 6968edd704 feat(crypto): Start uploading fallback keys to the server 2022-03-25 13:11:53 +01:00
Damir Jelić f4010b597f feat(crypto): Use a specialized SignedKey type instead of the Ruma type 2022-03-25 13:11:53 +01:00
Damir Jelić 2bacbf1b53 feat(crypto): Add a store error variant for breaking database format changes 2022-03-25 11:15:29 +01:00
Damir Jelić 0ce74b956c fix(sled): Throw an error if we can't upgrade our database 2022-03-25 11:15:29 +01:00
Damir Jelić e2725483e4 refactor(crypto): Make it clear that olm decryption failures are normal 2022-03-25 11:15:29 +01:00
Damir Jelić 03990ab19e test(crypto): Improve the device saving test
The test didn't check if we can actually save/restore multiple devices,
this patch fixes this.
2022-03-25 11:15:29 +01:00
Damir Jelić 8b89023aff feat(indxeddb): Use the new store-cipher to encrypt our values 2022-03-25 11:15:29 +01:00
Damir Jelić 75de41bb2e feat(sled): Use the new store cipher to encrypt our keys and values 2022-03-25 11:15:29 +01:00
Damir Jelić 54e555f295 refactor(crypto): Don't use getrandom directly, we already use the rand crate 2022-03-25 11:15:29 +01:00
Damir Jelić dbb500c4b8 feat(crypto): Switch to vodozemac for the olm/megolm support 2022-03-25 11:15:29 +01:00
Damir Jelić 61ca5c7aab fix(base): Make room invitations for previously-left rooms work 2022-03-24 12:35:08 +01:00
Jonas Platte ae3b4f6640 Add a failing test for room invitations putting a left room back into invited 2022-03-24 12:21:21 +01:00
Jonas Platte 9ff6c1bc16 chore(base): Simplify BaseRoomInfo::handle_state_event 2022-03-23 14:25:14 +01:00
Jonas Platte 68a6655cb4 chore(base): Get rid of confusing double-as_ref 2022-03-23 14:25:14 +01:00
Alexandra ec97c354e2 feat(sdk): Detect invalid .well-known endpoint response 2022-03-23 11:57:13 +01:00
Jonas Platte db079065e4 refactor(sdk): Some cleanup of the HTTP code 2022-03-23 11:29:12 +01:00
Jonas Platte cbebf8c4fe Don't import reqwest::Client
… to avoid confusion with the SDKs Client type.
2022-03-23 11:04:28 +01:00
Jonas Platte 92a532a4ba Inline single-use method HttpClient::send_request 2022-03-23 10:50:15 +01:00
Jonas Platte 4601b43651 Remove unnecessary specialized send-request method from HttpClient 2022-03-23 10:43:14 +01:00
Benjamin Kampmann 9ebabf818d Chore: Add tracing span to request sending 2022-03-21 20:45:22 +01:00
Jonas Platte 68385f0ff7 Add tracing span to request sending 2022-03-18 14:40:26 +01:00
Jonas Platte 3b1400b6f8 Merge pull request #539 from matrix-org/jplatte/cleanup 2022-03-17 14:44:30 +01:00
Jonas Platte 5b5e13fe2c Remove request field from Client::keys_upload tracing span
It results in a lot of log noise for initial syncs.
2022-03-17 14:26:28 +01:00
Jonas Platte 7b8568f5c8 Simplify get_or_upload_filter example 2022-03-17 14:24:50 +01:00
Jonas Platte ea3ca1a8ca Remove unnecessary semicolons after if-let expressions 2022-03-17 14:23:55 +01:00
Jonas Platte baa869552f Implement Default for SyncSettings in terms of SyncSettings::new
… rather than the other way around.
2022-03-17 14:23:11 +01:00
Jonas Platte c9c31fa1c2 Simplify SyncSettings::default() 2022-03-17 14:22:40 +01:00
Jonas Platte 5ff38eff00 Activate tracing-subscriber's env-filter feature
This allows the log level of examples to be controlled using the
RUST_LOG environment variable.
2022-03-17 14:22:12 +01:00
Jonas Platte f9420acdfd Remove unhelpful Client self fields from tracing spans
Client's Debug implementation just returns "Client".
2022-03-17 14:21:41 +01:00
Jonas Platte c83f8f2a45 feat(sdk): Add convenience methods for getting state events of statically-known type 2022-03-16 14:26:18 +01:00
Damir Jelić 4741df627d feat(sdk): Add a method to check if the other side has scanned a qr verification 2022-03-16 14:23:35 +01:00
Julian Sparber 04e5434c9a QrVerification: Use consistent name for re-exported method 2022-03-16 14:06:26 +01:00
Julian Sparber adf463a4be QrVerification: expose whether the QrCode was scanned by the other device 2022-03-16 13:05:15 +01:00
Damir Jelić a455f23520 docs(store-cipher): Make the docs about the way the StoreCipher works clearer
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-03-16 12:48:16 +01:00
Damir Jelić 3af08059da fix(store-cipher): Use the MacKeySeed type alias in more places
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-03-16 12:48:16 +01:00
Damir Jelić bf3d2ebea3 chore(store-cipher): Rename the store-key crate and it's main type 2022-03-16 12:48:16 +01:00
Damir Jelić 8ab7bfd5fa fix(store-key): Zeroize the derived MacKeys
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-03-16 12:48:16 +01:00
Damir Jelić d03eefc49a docs(store-key): Improve the docs a bit
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
2022-03-16 12:48:16 +01:00
Damir Jelić 5766b65eeb feat(store-key): Add a feature flag to enable WASM support 2022-03-16 12:48:16 +01:00
Damir Jelić 11d27007fc fix(store-key): Add some missing zeroize calls 2022-03-16 12:48:16 +01:00
Damir Jelić 4ed06be10d chore(store-key): Add more crate metadata
Co-authored-by: Benjamin Kampmann <ben.kampmann@gmail.com>
2022-03-16 12:48:16 +01:00
Damir Jelić 6a0bda47ae chore(store-key): Rename the crate
Co-authored-by: Benjamin Kampmann <ben.kampmann@gmail.com>
2022-03-16 12:48:16 +01:00
Damir Jelić 41466eae66 feat(store-key): Add a dedicated store key crate
This crate can be used to add at-rest encryption support for a
matrix-sdk state store or crypto store.
2022-03-16 12:48:16 +01:00
Damir Jelić 440b49ce5c feat(sdk): Add store specific errors to the ClientBuildError
This makes it easier to handle store specific errors while building a
Client as long as the user is using one of our main stores.
2022-03-16 12:29:10 +01:00
Kévin Commaille 7b8c52b043 indexeddb: Move attribute below docs 2022-03-16 10:30:56 +01:00
Kévin Commaille 3a94c2115f sdk: Add store opening errors to ClientBuildError 2022-03-15 14:43:02 +01:00
Kévin Commaille 6785c07793 indexeddb: Make store opening error more specific 2022-03-15 14:43:02 +01:00
Kévin Commaille e23b22857f sled: Make store opening error more specific 2022-03-15 14:42:54 +01:00
Jonas Platte 3bf5388da0 feat(sdk): Fetch supported matrix versions from server in initialization 2022-03-14 15:23:13 +01:00
Jonas Platte 15df8fef95 Fix broken tests 2022-03-14 15:08:54 +01:00
Jonas Platte 8df7e1cc8b Fix hanging tests 2022-03-14 15:08:48 +01:00
Jonas Platte 7b2dfa39cf Remove Client::get_supported_versions
This is now always done as part of constructing the Client, unless the
user actively opted out.
2022-03-14 12:57:58 +01:00
Jonas Platte fdc8f79728 Merge branch 'main' into jplatte/server-versions 2022-03-14 12:56:57 +01:00
Benjamin Kampmann f76bcda64f feat(client): Replacing ClientConfig with a ClientBuilder to configure how the client will be set up
Merge pull request #533 from matrix-org/jplatte/client-builder
2022-03-14 12:43:38 +01:00
Jonas Platte 718fa18e7f Merge branch 'main' into jplatte/client-builder 2022-03-14 11:26:45 +01:00
Damir Jelić b8b61ce214 refactor(sdk): Scope the encryption specific Client methods behind a struct 2022-03-14 10:16:19 +01:00
Jonas Platte a2ad774112 Add ClientBuilder::server_name 2022-03-14 10:02:31 +01:00
Jonas Platte d94ba8c64f Remove Client::for_user_id 2022-03-14 10:02:31 +01:00
Jonas Platte 81d07d886c Rename Client::{new_from_user_id => for_user_id} 2022-03-13 19:56:26 +01:00
Jonas Platte 147e948fe6 Replace ClientConfig with ClientBuilder
This includes a few not-strictly-related changes that made sense to do at the
same time:

* Check for a functioning homeserver via get_supported_versions regardless of
  whether a homeserver URL or user ID was supplied
* Rename use_discovery_response to respect_login_well_known
* Small appservice documentation improvement because those docs had to be
  touched anyways
* Some test refactorings in tests that had to be touched anyways
2022-03-13 19:56:26 +01:00
Kévin Commaille d8c7fbd9dc sdk: Create Encryption struct
Lower the API surface of Client
2022-03-12 13:30:55 +01:00
Jonas Platte bd7fbea155 Fix intra-doc link 2022-03-11 18:04:32 +01:00
Jonas Platte 628e2fb716 Allow configuring assert_identity on the client level only
Completely removing it from RequestConfig is left up to a future refactoring.
2022-03-11 15:31:11 +01:00
Jonas Platte 503f4d73a0 Merge pull request #532 from matrix-org/jplatte/ctors 2022-03-11 13:05:20 +01:00
Jonas Platte 8a927df2b3 Rename PrivateCrossSigningIdentity::{new_with_account => with_account} 2022-03-11 12:48:30 +01:00
Jonas Platte 14ddcfb06e Remove new_ prefix from ToDeviceRequest ctors 2022-03-11 12:48:30 +01:00
Jonas Platte 932ef6270b Remove new_ prefix from OlmMachine ctors 2022-03-11 12:48:30 +01:00
Jonas Platte 1be68f57a5 Merge BaseClient impl blocks 2022-03-11 12:36:08 +01:00
Jonas Platte cfdf4a032e Rename BaseClient::{new_with_store_config => with_store_config} 2022-03-11 12:36:08 +01:00
Jonas Platte f5a7a1bcf0 Rename AppService::{new_with_config => with_config} 2022-03-11 12:36:08 +01:00
Jonas Platte e60b07336d Rename Client::{new_with_config => with_config} 2022-03-11 12:36:08 +01:00
Jonas Platte 48660c482f Use regular builder pattern for ClientConfig::store_config 2022-03-11 12:36:00 +01:00
Jonas Platte 27ee7c32ca Remove new_with_* constructors for StoreConfig
The regular builder pattern works just fine for the stores.
2022-03-11 11:49:01 +01:00
Benjamin Kampmann 88f1552a70 feat(stores): Improve Store initialisation to allow for reusing the same instance
Merge pull request #523 from zecakeh/stores
2022-03-11 11:40:12 +01:00
Kévin Commaille faa5cf54eb indexeddb: Make make_store_config public 2022-03-10 17:42:37 +01:00
Kévin Commaille 2bdc754140 ci: Lint matrix-sdk-crypto with a separate command 2022-03-10 17:29:20 +01:00
Kévin Commaille 597999acba sdk-base: Add constructors with stores for StoreConfig 2022-03-10 17:29:19 +01:00
Kévin Commaille 81605b731d sdk-base: Fix wording on StoreConfig docs 2022-03-10 17:29:19 +01:00
Kévin Commaille d7673257b4 stores: Rename make_config to make_store_config 2022-03-10 17:29:19 +01:00
Kévin Commaille 54c8b4f8bb sdk-base: Remove BaseClientConfig 2022-03-10 17:29:15 +01:00
Kévin Commaille ad31540b10 sdk: Don't enable store encryption by default 2022-03-10 17:28:34 +01:00
Kévin Commaille 8c7bbb0e07 sdk: Update store setup instructions for encryption. 2022-03-10 17:22:36 +01:00
Kévin Commaille 0f60dfcfc5 sdk: Re-export stores and store config 2022-03-10 17:15:18 +01:00
Kévin Commaille 0327b4f8fc indexeddb: Add methods to create a StoreConfig 2022-03-10 17:15:18 +01:00
Kévin Commaille 4b7f05e913 sled: Add a method to create a StoreConfig 2022-03-10 17:15:18 +01:00
Kévin Commaille 0ea12b3b4a base: Separate store config from the client config 2022-03-10 17:15:18 +01:00
Kévin Commaille 28a83da421 sdk: Remove default store constructors 2022-03-10 17:15:14 +01:00
Kévin Commaille 4d41f94199 sled: Add helper to open stores for encryption 2022-03-10 17:14:01 +01:00
Kévin Commaille 692f95da79 sled: Add method to create CryptoStore from StateStore
Allow to use the same database for both stores
2022-03-10 17:14:00 +01:00
Jonas Platte 872c35efd2 Fix a typo 2022-03-10 16:52:01 +01:00
Jonas Platte 65e7688a3f Don't require discovery to be mocked in tests 2022-03-10 16:05:51 +01:00
Jonas Platte b1f2adf9c0 Ensure random request with Request: Send gets a Send future as well 2022-03-10 15:01:10 +01:00
Jonas Platte 81cea84a37 Fetch supported matrix versions from server in initialization 2022-03-10 15:00:40 +01:00
Jonas Platte 5f8d3dec82 Merge pull request #529 from matrix-org/jplatte/event-type
Use fine-grained *EventType types
2022-03-10 14:49:31 +01:00
poljar e5359826e1 Merge pull request #528 from matrix-org/backup-fix
Fix the room key backup support in the crypto crate
2022-03-10 14:10:18 +01:00
Jonas Platte 1dec224210 Use fine-grained *EventType types 2022-03-10 13:54:00 +01:00
Damir Jelić 691ea2d138 ci(crypto): Test the crypto crate features when we run the CI 2022-03-10 13:52:31 +01:00
Damir Jelić 4af4faacef feat(xtask): Add a task to check the crypto crate features 2022-03-10 13:52:31 +01:00
Damir Jelić 54a253c0bf fix(crypto): Make our backup feature compile again 2022-03-10 13:50:29 +01:00
Jonas Platte 89ff804333 Remove extraneous newline 2022-03-10 13:49:40 +01:00
Jonas Platte 4d16370dba Merge pull request #527 from matrix-org/jplatte/wasm-ci 2022-03-10 13:49:16 +01:00
Jonas Platte 30b3bd1c3d Delete complicated and partially broken wasm tests 2022-03-10 13:18:59 +01:00
Jonas Platte ff15ccaf28 Merge pull request #525 from matrix-org/jplatte/refactor 2022-03-10 12:56:05 +01:00
Jonas Platte 6af9285874 Don't use Raw::from_json where it's not needed 2022-03-10 11:59:31 +01:00
Jonas Platte 9154e93089 Allow other tests to continue when indexeddb test fails 2022-03-10 11:41:01 +01:00
Jonas Platte ea2c9a2986 ci: Use clippy instead of check for wasm checks 2022-03-10 11:28:55 +01:00
Jonas Platte c01475701d Move some wasm CI logic into xtask 2022-03-10 11:02:16 +01:00
Jonas Platte 0721c7ddb2 Add missing ci subcommand description 2022-03-10 10:30:56 +01:00
Jonas Platte 36e4836c06 Merge pull request #522 from matrix-org/jplatte/send-req-refactor 2022-03-10 10:25:50 +01:00
Jonas Platte b777617515 Replace matches! with == 2022-03-10 10:12:53 +01:00
Jonas Platte 8a60154882 Use only #[warn], not #[deny] for lints
CI passes `-D warnings` to clippy, so there it will be an error either way.
For local development it is nice not to block compilation of dependent
crates on lints though.
2022-03-09 18:13:04 +01:00
Jonas Platte d2e70c16b4 Deduplicate lint configuration 2022-03-09 18:09:02 +01:00
Jonas Platte e6d20265bf Allow rustfmt to format the encryption module again 2022-03-09 18:01:48 +01:00
Jonas Platte 5602deb226 Move encryption module docs into a separate markdown file 2022-03-09 18:00:57 +01:00
Jonas Platte e4289405f5 Stop importing Result as StdResult
The SDK's Result aliases can optionally take the error parameter, so
there is no need to disambiguate this way.
2022-03-09 17:56:26 +01:00
Jonas Platte 76973fdc30 Improve consistency across sending requests with/out identity assertion 2022-03-09 16:48:28 +01:00
Jonas Platte d5d6b80e08 Inline single-callsite request serialization functions 2022-03-09 15:13:06 +01:00
Jonas Platte 1ed2b8841d Simplify HTTP request serialization logic
… the removed AuthenticationRequired branch was not necessary, Ruma's
`try_into_http_request` will take care of reporting the error.
2022-03-09 15:13:06 +01:00
Jonas Platte a33898847b Reduce duration of holding session lock
… by cloning the access token out.
2022-03-09 15:13:06 +01:00
Jonas Platte bc1eb9a792 Merge pull request #521 from matrix-org/jplatte/appservice-refactor 2022-03-09 13:15:59 +01:00
Jonas Platte 3b3fede756 Merge pull request #520 from matrix-org/jplatte/clippy 2022-03-09 12:55:27 +01:00
Jonas Platte 9f72eb9490 Enable more default-off clippy lints 2022-03-09 12:41:57 +01:00
Jonas Platte 2c181bca4f Consistently use .to_owned() instead of .to_string() for &str => String 2022-03-09 12:41:57 +01:00
Jonas Platte b67c51c267 Remove unnecessary double reference 2022-03-09 12:41:57 +01:00
Jonas Platte 7fee5b59e8 crypto: Use Box<UserId> instead of String in SignatureError
… to make the field's meaning more obvious.
2022-03-09 12:41:56 +01:00
Jonas Platte 5d6f66be54 appservice: Make warp a regular dependency
It was optional but always required to be activated.
2022-03-09 10:35:39 +01:00
Jonas Platte 5075c2730c Move appservice CI logic into xtask 2022-03-09 10:35:11 +01:00
Jonas Platte 1d5ba87b72 ci: Simplify test command by using -p instead of --manifest-path 2022-03-09 10:35:11 +01:00
Damir Jelić 4fa44f90bb Merge branch 'appservice/fix-user-room-query' 2022-03-09 09:08:04 +01:00
Johannes Becker a86da98cc2 fix(appservice): urldecode ids for user/room queries 2022-03-07 16:51:06 +01:00
Damir Jelić 6dff06579c fix(sdk): Ensure that our login_with_sso() Client method is Send 2022-03-07 14:43:42 +01:00
Julian Sparber 38cbf24e8e Add back homeserver logging for sso login
We can't use `.await` inside `info!()` because of
https://github.com/rust-lang/rust/issues/93274
2022-03-07 14:12:00 +01:00
Julian Sparber 642c4f5cfc Ensure Client::login_with_sso() to be send
This removes the `info!()` log because of
https://github.com/rust-lang/rust/issues/93274
2022-03-07 13:11:52 +01:00
Damir Jelić 89e4d47ee1 chore: Bump the dashmap version across our crates 2022-03-07 09:58:00 +01:00
Jonas Platte 896d451c47 Merge pull request #515 from matrix-org/jplatte/ci 2022-03-04 12:10:47 +01:00
Jonas Platte abe0bf0a29 Enable some useful non-default rustc lints 2022-03-04 11:35:24 +01:00
Jonas Platte 804c8e6c43 ci: Add test and test-features xtask commands 2022-03-04 10:59:17 +01:00
Jonas Platte b64d855b25 ci: Fix inconsistent formatting 2022-03-04 10:59:17 +01:00
Jonas Platte beb4ecb581 ci: Remove mentions of non-existant matrix variables 2022-03-04 10:59:17 +01:00
Jonas Platte ed7667dc8d ci: Remove unnecessary ${{ }} 2022-03-04 10:59:17 +01:00
Jonas Platte e136199bfd ci: Don't run check / build before test
It is redundant.
2022-03-04 10:59:17 +01:00
Damir Jelić 95665c8bc0 Merge branch 'poljar/matrix-crypto-ffi' 2022-03-04 10:27:12 +01:00
Damir Jelić 6bb8fd7853 feat: Import the Uniffi based matrix-sdk-crypto bindings 2022-03-04 09:45:50 +01:00
Benjamin Kampmann b3038545f5 feat(stores): Splitting Sled and Indexeddb Store into separate crates
More details in pull request #498 .
2022-03-03 16:32:31 +01:00
Benjamin Kampmann 44fe3a62a1 remove unneeded helper function 2022-03-03 15:38:22 +01:00
Benjamin Kampmann ba1b3e0c7c fix the indexeddb tests, that clippy tried to fix 2022-03-03 15:27:21 +01:00
Benjamin Kampmann 6435ea655b fix testing function wrongly exposed 2022-03-03 13:47:25 +01:00
Benjamin Kampmann 193a5ed3c9 fixing if syntax 2022-03-03 13:07:09 +01:00
Benjamin Kampmann 4e6b80d7df fix docs 2022-03-03 13:05:32 +01:00
Benjamin Kampmann e7fb512ae6 adding another encryption wasm tests 2022-03-03 12:59:23 +01:00
Benjamin Kampmann ab57fb329f Addressing review remark 2022-03-03 12:57:15 +01:00
Benjamin Kampmann fd6f4385d4 Merge remote-tracking branch 'origin/main' into ben-splitting-out-store-impls 2022-03-03 12:57:00 +01:00
Jonas Platte e03ee913f8 Merge pull request #513 from matrix-org/jplatte/xtask 2022-03-03 12:10:02 +01:00
Benjamin Kampmann 8aed72a085 Update crates/matrix-sdk-crypto/src/olm/account.rs
Co-authored-by: poljar <poljar@termina.org.uk>
2022-03-03 11:35:02 +01:00
Jonas Platte 2182ebdd16 ci: Fix toolchain installation job name inconsistencies 2022-03-03 11:10:30 +01:00
Jonas Platte e575c27601 ci: Use uppercase for docs workflow / job name 2022-03-03 11:10:29 +01:00
Jonas Platte 439081e1db ci: Move wasm and appservice into separate workflows
… to reduce the size of `ci.yml` and to allow more fine-grained retries.
2022-03-03 11:10:29 +01:00
Jonas Platte 1968ae60aa ci: Fix inconsistencies in workflow yml formatting 2022-03-03 11:10:29 +01:00
Jonas Platte b7a4ca4cff Create an xtask crate for workspace task automation
Initially covering:

* Building docs
* Nightly CI jobs
2022-03-03 11:10:28 +01:00
Jonas Platte b276087969 ci: Fail if rustdoc raises warnings 2022-03-03 11:10:13 +01:00
Jonas Platte 6e091dd5b8 ci: Use Swatinem/rust-cache@v1 instead of actions/cache@v2
Simplifies the cache configuration and could also improve build times by
disabling incremental compilation and potentially caching fewer things
or using a better cache key.
2022-03-03 11:04:07 +01:00
Jonas Platte ea5478c61c Merge pull request #510 from matrix-org/jplatte/up-ruma 2022-03-03 09:29:26 +01:00
Jonas Platte 1f2fd380b2 Upgrade Ruma to 0.5.0 2022-03-03 08:59:44 +01:00
Jonas Platte 012954e7f4 ci: Remove --all flag from cargo fmt arguments
It is only relevant for non-workspace path dependencies.
2022-03-02 14:34:22 +01:00
Jonas Platte bc0c8d529e Simplify Cargo workspace configuration 2022-03-02 14:34:22 +01:00
Jonas Platte ba3ccc7d3d Remove explicit 'static lifetimes from constants 2022-03-02 14:34:22 +01:00
Jonas Platte b3f6d1cf63 Fix inconsistent indentation 2022-03-02 14:32:37 +01:00
Jonas Platte af0375ca99 Remove unnecessary serialize / deserialize roundtrips 2022-03-02 14:26:49 +01:00
Jonas Platte a1a0ae62ba base: Use Option::get_or_insert_with to get rid of an unwrap() call 2022-03-02 14:26:48 +01:00
Damir Jelić dec4772740 Merge branch 'gnunicorn-limited-ci-runs' 2022-03-02 14:21:54 +01:00
Benjamin Kampmann 85dd7a03e2 fix(MemoryStore): undeadlock timeline saving
Merge pull request #509 from matrix-org/gnunicorn/issue508
2022-03-02 13:44:47 +01:00
Benjamin Kampmann cf674b6a46 Update crates/matrix-sdk-base/src/store/memory_store.rs 2022-03-02 13:14:38 +01:00
Benjamin Kampmann 102f960d25 chore(ci): limit CI to pull-requests & push main
Running CI on every push means running it twice for any PR as well as commit on branches that aren't PRs. This limits the CI run to pull-requests against main and pushes to main directly, removing unnecessary workload for the CI and making PRs CI faster.
2022-03-02 13:01:18 +01:00
Benjamin Kampmann 7e2e43c51c Addressing review
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
2022-03-02 12:34:04 +01:00
Benjamin Kampmann 161d79eaa1 fixing typo 2022-03-02 12:22:47 +01:00
Benjamin Kampmann eacffb5126 creating better tests, ensure sled and memory store act consistently 2022-03-02 12:13:07 +01:00
Benjamin Kampmann 40fa17f5b7 fixing timeline test 2022-03-02 08:36:10 +01:00
Benjamin Kampmann 9eee50da66 fixing clippy warnings 2022-03-01 15:32:23 +01:00
Benjamin Kampmann 2b9bb422cf fix(MemoryStore): undeadlock timeline saving 2022-03-01 14:39:27 +01:00
Benjamin Kampmann ca18fca20b make Sled store benchmarks use SledStore again 2022-03-01 11:52:52 +01:00
Benjamin Kampmann 33be17d5d0 review requests 2022-03-01 11:52:38 +01:00
Benjamin Kampmann c2bb1b9ad1 remove unneded braces in ci 2022-03-01 11:20:04 +01:00
Damir Jelić 70490277eb fix(sdk): Use a short request retry for login/register/get_version methods 2022-02-28 15:26:30 +01:00
Damir Jelić 48fff04ffd Merge branch 'enable_ruma_unstable_pre_spec' 2022-02-28 14:20:52 +01:00
Manuel Schmidbauer 6bf7b212cf Changed register to really use short_retry() 2022-02-26 15:19:38 +01:00
Manuel Schmidbauer 01e080842a Implemented short_retry for intial methods
Implemented RequestConfig::short_retry()
Changed few client methods to use it
Adjusted and added tests for it
2022-02-26 15:13:04 +01:00
Benjamin Kampmann 25e98db5aa missing .to_string 2022-02-25 17:24:50 +01:00
Benjamin Kampmann fce78ea84e fixing style 2022-02-25 17:16:19 +01:00
Benjamin Kampmann e414c88347 fixing integration test example 2022-02-25 17:14:45 +01:00
Benjamin Kampmann 56b3b2cec6 minor fix in ci 2022-02-25 16:11:32 +01:00
Benjamin Kampmann 13c39dbeab fixing crypto bench 2022-02-25 15:53:36 +01:00
Benjamin Kampmann 5e05411036 fixing typos 2022-02-25 15:40:35 +01:00
Benjamin Kampmann a6514b0cff indexeddb formatting 2022-02-25 15:32:59 +01:00
Benjamin Kampmann 2e9ca5642a more clippy for indexeddb 2022-02-25 15:31:39 +01:00
Benjamin Kampmann 06c9b1abe3 fixing proepr cargo build call 2022-02-25 15:23:04 +01:00
Benjamin Kampmann c97f7e9ed0 clippy 2022-02-25 15:19:57 +01:00
Benjamin Kampmann e1f898e6a5 fixing clippy and docs for base and crypto 2022-02-25 13:05:48 +01:00
Benjamin Kampmann 75953d6022 fixing machine doc builds 2022-02-24 17:29:08 +01:00
Benjamin Kampmann 6c90af1bd7 fixing indexeddb test 2022-02-24 17:16:10 +01:00
Benjamin Kampmann 8706ab68f8 fixing formatting 2022-02-24 16:57:39 +01:00
Benjamin Kampmann 9386e9df51 fixing name path 2022-02-24 16:56:14 +01:00
Benjamin Kampmann 418fac8574 fixing missing import for tests 2022-02-24 16:56:06 +01:00
Benjamin Kampmann 4c1e3ac03a fix missing import 2022-02-24 16:50:57 +01:00
Benjamin Kampmann 4d6d13b9c8 fixing some clippies and wrong package naming 2022-02-24 15:40:24 +01:00
Benjamin Kampmann cccad6104c fixing formatting 2022-02-24 15:18:16 +01:00
Benjamin Kampmann 259ba3b794 refactor CI tests 2022-02-24 15:14:54 +01:00
Benjamin Kampmann 9c5cb08ac0 fixing crypto testing problems 2022-02-24 15:14:42 +01:00
Benjamin Kampmann d7f30167a0 moving safe encode, making regular build work again 2022-02-24 13:02:35 +01:00
Benjamin Kampmann e20bdfa2b5 cleaning up more cryptocrate 2022-02-23 21:33:31 +01:00
Benjamin Kampmann 12cf187e51 indexeddb store and passphrase opening 2022-02-23 21:07:39 +01:00
Benjamin Kampmann ed0974eba3 re-integrate sled and indexeddb stores into base 2022-02-23 19:38:35 +01:00
Benjamin Kampmann 692f9d893a chore(CI): also skip docs making on draft PRs 2022-02-23 16:07:16 +01:00
Benjamin Kampmann 21887877da chore(CI): limit CI runs to non-draft PRs and manual dispatching 2022-02-23 16:04:05 +01:00
Julian Sparber 0dd623970b Enable 'unstable-pre-spec' ruma feature 2022-02-23 15:52:19 +01:00
Benjamin Kampmann 73227623e6 one more fmt 2022-02-23 15:46:44 +01:00
Benjamin Kampmann eeea757719 clippy and formatting 2022-02-23 15:44:36 +01:00
Benjamin Kampmann f6a3c765e9 Merge remote-tracking branch 'origin/main' into ben-splitting-out-store-impls 2022-02-23 15:33:38 +01:00
Benjamin Kampmann 8414718371 feat(StateStore): Adding forward and backwards streams for room timelines
Merge pull request #486 from jsparber/timeline_stream
2022-02-23 14:38:14 +01:00
Benjamin Kampmann 78af96dab3 Clippy and Cargo fmt 2022-02-23 12:50:57 +01:00
Benjamin Kampmann 2598001c8f room version simplification 2022-02-23 12:40:37 +01:00
Benjamin Kampmann c22b4fcfb2 minor refactor for simplicity 2022-02-23 12:37:10 +01:00
Damir Jelić 2b20055eb5 Merge branch 'test-refactor' 2022-02-23 10:30:23 +01:00
Damir Jelić e846fedc3f feat(sdk): Support logging in using SSO with an identity provider 2022-02-23 10:27:07 +01:00
Julian Sparber 980076fd73 Merge remote-tracking branch 'origin/main' into timeline_stream 2022-02-22 17:30:51 +01:00
Julian Sparber 3378d18ca8 store: Add comment why we can ignore unexpected TimelineSlices 2022-02-22 16:49:42 +01:00
Julian Sparber 70e826ff25 Fix style issue 2022-02-22 15:48:56 +01:00
Julian Sparber 890a8675c9 store: Use BoxStream type without explicit lifetime 2022-02-22 15:43:26 +01:00
Julian Sparber 7627c142c4 Add method to optain timeline stream in one direction 2022-02-22 15:42:39 +01:00
Julian Sparber 84c46affa3 Fix example for Room::Common::timeline() 2022-02-22 12:51:44 +01:00
Benjamin Kampmann 5b1746e451 Merge pull request #503 from ShadowJonathan/labs-folder
Add `labs/` folder
2022-02-22 12:01:47 +01:00
Julian Sparber d7592cce29 Merge remote-tracking branch 'origin/main' into timeline_stream 2022-02-22 11:47:17 +01:00
Julian Sparber 088086715f store: Save timeline to IndexedDbStore 2022-02-22 11:43:12 +01:00
Jonathan de Jong 7c9d139031 Apply suggestions from code review
Co-authored-by: Benjamin Kampmann <ben.kampmann@gmail.com>
2022-02-21 22:08:41 +01:00
Jonathan de Jong 28ac6f9f52 add labs folder 2022-02-21 21:37:56 +01:00
Jonas Platte b39a72ceac matrix-sdk-test: Stop relying on event enum Serialize impls
In the latest version of Ruma, the event enums no longer implement
`Serialize` because it was somewhat of a footgun when custom /
unrecognized events were involved.
2022-02-21 14:50:41 +01:00
Benjamin Kampmann 6aeb382706 move state inspector for sled store into corresponding crate 2022-02-21 12:08:45 +01:00
Benjamin Kampmann 87cd9a3afc clean up base 2022-02-18 20:41:42 +01:00
Benjamin Kampmann 95384f0f33 make encryption in new crates optional 2022-02-18 18:50:35 +01:00
Benjamin Kampmann 00ea5d9cad moving sled cryptostore, too 2022-02-18 18:46:59 +01:00
Benjamin Kampmann 1563ecdf1a Merge pull request #499 from matrix-org/ben-docs-for-custom-http-client
Minor improvements on ClientConfig
2022-02-17 20:37:47 +01:00
Benjamin Kampmann 7ab8872dd5 fix(Version): removing (crate only) VERSION const 2022-02-17 19:25:09 +01:00
Benjamin Kampmann 5d812d4aa7 fixing style 2022-02-17 19:09:10 +01:00
Benjamin Kampmann 0ca6ec1377 moving sled state store into separate crate 2022-02-17 19:02:17 +01:00
Benjamin Kampmann 1d0d32858b fix(ClientConfig): Do not expose crate version in user agent anymore 2022-02-17 18:53:32 +01:00
Julian Sparber 8e80e02a78 Add test for matrix_sdk::room::Common::timeline()
The test is only run when the `sled_state_store` feature is enabled.
This also changes the test_json::MORE_SYNC and test_json::MORE_SYNC_2 to
not responsed with a limited timeline.
2022-02-17 18:32:44 +01:00
Julian Sparber 9e7bee89c8 Add test for timeline cache 2022-02-17 18:32:44 +01:00
Julian Sparber fb3edeb206 store: Save timeline to MemoryStore 2022-02-17 18:32:36 +01:00
Julian Sparber 516aa26589 store: Save timeline to SledStore
This writes slices from StateChanges::timeline to the SledStore.
The cache is removed when ever a limited sync response is received or
when an event already known to the store is received.

Stored events are redacted when a redaction event is received.
2022-02-17 16:15:17 +01:00
Julian Sparber 7d19e9aa34 test: Add mocked responses need for timeline storage 2022-02-17 16:15:17 +01:00
Julian Sparber 64c49cd137 Add stream to obtain the timeline of a room 2022-02-17 16:15:17 +01:00
Julian Sparber c5950ac929 common: add TimelineSlice
The TimelineSlice is a slice of the timeline of a room and contains the
start and end of the slice.
2022-02-17 16:13:04 +01:00
Benjamin Kampmann ea92bc676c Merge remote-tracking branch 'origin/main' into ben-splitting-out-store-impls 2022-02-17 16:03:07 +01:00
Benjamin Kampmann 839136118f fixing style 2022-02-17 13:06:44 +01:00
Benjamin Kampmann 6751413673 Merge remote-tracking branch 'origin/main' into ben-docs-for-custom-http-client 2022-02-17 13:01:57 +01:00
Benjamin Kampmann 094fb176b6 chore: remove unused lifetime found by clippy 2022-02-17 12:13:56 +01:00
Benjamin Kampmann 75f45c8df6 chore: Update clippy, removes deprecations to make clippy happy 2022-02-17 12:12:19 +01:00
Benjamin Kampmann e9e0ba216b chore: fixing formatting 2022-02-17 11:49:49 +01:00
Benjamin Kampmann bbc92d912f docs(ClientConfig): Add example for customn reqwest::ClientBuilder 2022-02-17 11:43:20 +01:00
Benjamin Kampmann 81e90c5699 chore(ClientConfig): Simplify user agent storing 2022-02-17 11:40:59 +01:00
Benjamin Kampmann 54303a03bf feat(sdk): Move Account related functions from Client into a new separated Account struct
Create Account struct
2022-02-16 19:51:16 +01:00
Benjamin Kampmann 78ea330d3a Merge remote-tracking branch 'origin/main' into pr/zecakeh/487 2022-02-16 18:30:24 +01:00
Benjamin Kampmann 93c46280ab feat(sdk): Add method to get homeserver capabilities
Merge pull request #495 from zecakeh/capabilities
2022-02-16 18:27:04 +01:00
JCWasmx86 c119d71d8b Added support for logging in with specific SSO-Provider 2022-02-16 16:46:08 +01:00
Pass Automated Testing Suite 1e0a240701 feat(sdk): Support to autogenerate thumbnails for image attachments 2022-02-16 16:04:46 +01:00
Kévin Commaille 2f7d271c16 fix(sdk): Add license to attachment.rs 2022-02-15 19:15:06 +01:00
Kévin Commaille 9e545c34ba fix(sdk): Fix clippy warning 2022-02-15 19:00:39 +01:00
Kévin Commaille 69b0b04e70 fix(sdk): Add ruma feature for blurhash support 2022-02-15 18:43:56 +01:00
Kévin Commaille de8aa7b4f7 fix(sdk): Simplify code in room::Joined::send_attachment 2022-02-15 18:15:59 +01:00
Kévin Commaille ebd913f50f fix(sdk): Fix dead links in AttachmentConfig docs 2022-02-15 18:15:59 +01:00
Kévin Commaille 409afc6684 feat(sdk): Create AttachmentConfig struct 2022-02-15 18:15:59 +01:00
Kévin Commaille c2c9d5ecc0 fix(sdk): Enable image_proc with image_rayon 2022-02-15 18:15:59 +01:00
Kévin Commaille e926d7e928 chore: Update image dependency 2022-02-15 18:15:59 +01:00
Kévin Commaille 78489391d2 feat(sdk): Add method to send attachments with generated thumbnails 2022-02-15 18:15:59 +01:00
Kévin Commaille 5dc7dfd4c8 feat(sdk): Add method to generate thumbnails from images 2022-02-15 18:15:58 +01:00
Kévin Commaille 0436780292 feat(sdk): Allow to add info and thumbnail to attachments 2022-02-15 18:15:58 +01:00
Kévin Commaille 6389749931 fix(sdk): Return whole responses in Account 2022-02-15 18:15:05 +01:00
Kévin Commaille abed1e2986 fix(sdk): Fix Account docs
Add a license and fix the dead links.
2022-02-15 18:15:05 +01:00
Kévin Commaille 9449b3ef23 feat(sdk): Add more methods to Account
- get_profile
- change_password
- deactivate
- get_3pids
- request_3pid_email_token
- request_3pid_msisdn_token
- add_3pid
- delete_3pid
2022-02-15 18:15:05 +01:00
Kévin Commaille 30d3cafa0c feat(sdk): Make upload_avatar return an MXC URI 2022-02-15 18:15:05 +01:00
Kévin Commaille 467005b603 feat(sdk): Move account-related methods to Account struct
Methods moved from Client to Account:
- display_name renamed to get_display_name
- set_display_name
- avatar_url renamed to get_avatar_url
- set_avatar_url
- avatar renamed to get_avatar
- upload_avatar
2022-02-15 18:15:05 +01:00
Kévin Commaille c67d5afaf4 feat(sdk): Add method to get homeserver capabilities 2022-02-15 17:42:12 +01:00
Benjamin Kampmann 393cfb1851 move indexeddb cryptostore into new crate 2022-02-15 15:09:31 +01:00
Damir Jelić a4ccbf0386 Merge branch 'up-ruma' 2022-02-15 14:46:18 +01:00
Damir Jelić f220f2e743 fix(crypto): Remove an unused lifetime 2022-02-15 12:32:53 +01:00
Benjamin Kampmann 5cae4e08af making tests pass again 2022-02-14 17:38:58 +01:00
Benjamin Kampmann e928d02c6f Move indexeddb out into a separate crate 2022-02-14 17:00:55 +01:00
Benjamin Kampmann 95e06ec732 Merge pull request #492 from zecakeh/fix-docs
fix(doc): Build nightly docs with correct features
2022-02-14 12:03:21 +01:00
Kévin Commaille 0570cd9439 fix(doc): Build nightly docs with correct features 2022-02-13 10:22:05 +01:00
Jonas Platte c3d9c73d00 Make identifier parsing easier to read
… by using `Id::parse` instead of `Box::<Id>::try_from`.
2022-02-12 04:20:37 +01:00
Jonas Platte a7dcd26588 Remove unused variable from test 2022-02-12 04:15:50 +01:00
Jonas Platte 735d9e5894 Use user_id! macro in more tests 2022-02-12 04:15:48 +01:00
Jonas Platte 8e41bccf8b Upgrade Ruma 2022-02-11 20:45:22 +01:00
Daniel García Moreno 4b5aae1123 Do not fail when no session if force_auth
It looks like the force_auth is working correctly when restoring the
session, but it's not working with the call to client.login, so it
cannot be used.

The access_token is not available in the login query, so if the option
force_auth is set, this call will fail always. This patch just ignores
the force_auth if there's no session, so any query will work when
force_auth is true.

Fix https://github.com/matrix-org/matrix-rust-sdk/issues/488
2022-02-11 15:22:39 +01:00
Benjamin Kampmann 8538bdcce2 fix[state store]: Persist stripped rooms in the right bucket
fixes #467 as well as persistence problems with the indexeddb store
2022-02-07 11:53:31 +01:00
Benjamin Kampmann 7aa99448c3 fix style 2022-02-04 18:02:00 +01:00
Benjamin Kampmann 29c851f463 fixing indexeddb store 2022-02-04 18:01:37 +01:00
Benjamin Kampmann d20abe05ed lookup sync-token in proper bucket 2022-02-04 17:47:01 +01:00
Benjamin Kampmann 560ef86747 fixing style 2022-02-04 14:20:51 +01:00
Benjamin Kampmann e68c75451e fixing failing test and naming convention 2022-02-04 14:18:26 +01:00
Benjamin Kampmann 355bb0a091 fixing style 2022-02-04 12:21:31 +01:00
Benjamin Kampmann 2a8c6dabaf Re-add population test 2022-02-04 12:20:10 +01:00
Benjamin Kampmann 772a585b80 stick to naming convention, clarify name 2022-02-04 12:10:53 +01:00
Benjamin Kampmann 51bf07fc34 fixing #467 2022-02-04 12:10:22 +01:00
Erik Johnston 59d21d9683 Replace uses of Vec::drain(..) with into_iter
`drain` is designed to be used when you want to reuse the `Vec` or only
move out a subset range. Using `.into_iter()` is more efficient and
idiomatic, and can be dropped entirely when used in `for` loops.
2022-02-03 14:43:14 +00:00
Benjamin Kampmann 1286357bcf Merge pull request #414 from gnunicorn/ben-wasm-store
IndexedDB support for wasm/browser environments
2022-02-03 09:14:54 +01:00
Benjamin Kampmann fa60881e2d disable broken test 2022-02-02 20:34:52 +01:00
Benjamin Kampmann 990b897e94 switch tokio:test to async_test 2022-02-02 15:10:24 +01:00
Benjamin Kampmann 64709f1d6b fixing style 2022-02-02 14:54:29 +01:00
Benjamin Kampmann b8d93d0179 implementing room removal for indexeddb 2022-02-02 14:53:21 +01:00
Benjamin Kampmann 666bec48bc fixing indexeddb types merge 2022-02-02 14:25:34 +01:00
Benjamin Kampmann 7e008d00e4 fixing linux tests 2022-02-02 14:10:04 +01:00
Benjamin Kampmann c07c284c5e fixing docs for await 2022-02-02 14:03:07 +01:00
Benjamin Kampmann b4d5ad95cf fixing style 2022-02-02 13:15:54 +01:00
Benjamin Kampmann ea959a17e2 Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2022-02-02 13:05:52 +01:00
Benjamin Kampmann e2c6dc33fb Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2022-02-02 12:16:49 +01:00
Damir Jelić 261772c4e2 chore: Upgrade our deps 2022-02-02 10:27:03 +01:00
Damir Jelić 27eed9d9bd refactor(matrix-sdk): Use the ruma cancel code for mismatched sas 2022-02-01 16:10:06 +01:00
Jonas Platte 8a97936228 Fix one more clippy warning 2022-02-01 15:44:22 +01:00
Jonas Platte 0df1f6007b Silence invalid clippy warnings 2022-02-01 15:44:16 +01:00
Benjamin Kampmann 8270304485 Fix build warnings and clippy lints 2022-02-01 15:30:09 +01:00
Benjamin Kampmann 93c75c1e4d fixing build warnings and clippy lints 2022-02-01 15:09:58 +01:00
Jonas Platte 2f67b62509 Unbreak wasm_command_bot compilation 2022-02-01 15:08:02 +01:00
Jonas Platte 74172dac32 Activate ruma's rand feature unconditionally in matrix-sdk, matrix-sdk-crypto
… because it is required for `TransactionId::new()`.
2022-02-01 15:08:02 +01:00
Jonas Platte 96d9fd80eb Silence new clippy lint occurrence 2022-02-01 15:08:02 +01:00
Jonas Platte 8dec390258 Upgrade Ruma 2022-02-01 15:08:01 +01:00
Jonas Platte 6baffc4b0b Refactor EncodeKey implementations 2022-02-01 15:05:10 +01:00
Jonas Platte c6594edc92 Use faster sorting algorithm
… because Clippy complained.
2022-02-01 15:05:10 +01:00
Jonas Platte 80e8d4fbd5 Remove unnecessary copying 2022-02-01 15:05:10 +01:00
Jonas Platte aa4a31d81b crypto: Refactor some test code 2022-02-01 15:05:10 +01:00
Jonas Platte df93cfde8b Remove unnecessary Result from private function return type 2022-02-01 15:05:10 +01:00
Jonas Platte f56f27a2e1 Remove unnecessary parentheses 2022-02-01 15:05:10 +01:00
Jonas Platte 3e496dba50 Remove unnecessary .iter() calls 2022-02-01 15:05:10 +01:00
Damir Jelić b55362a35b Merge branch 'forget' 2022-02-01 14:36:23 +01:00
Damir Jelić 88b64950dc Merge branch 'not_match_sas' 2022-02-01 14:05:54 +01:00
Benjamin Kampmann a0f2e38b89 Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2022-02-01 14:04:26 +01:00
Damir Jelić fe2323cd33 Merge branch 'doc-store-path-feature' 2022-02-01 13:53:31 +01:00
Damir Jelić d09792e402 docs(matrix-sdk): Clarify that an in-memory store will be used 2022-02-01 13:47:16 +01:00
Damir Jelić ac7f2c94fb Merge branch 'fix-verification-done-wait' 2022-02-01 13:43:58 +01:00
Damir Jelić 906dcfe423 Merge branch 'messages-param' 2022-02-01 12:34:40 +01:00
Damir Jelić b5ce7e7bd0 Merge branch 'tags' 2022-02-01 12:01:17 +01:00
Damir Jelić c9c03fd9b1 Merge branch 'encrypt-custom-events' 2022-02-01 11:48:31 +01:00
Julian Sparber 960c90cdff Add method to mismatch SAS verifications
The method sets the proper CancelCode for the case when SAS doesn't
match on both devices.
2022-01-13 10:26:53 +01:00
Kévin Commaille e1d78c01f0 test(base): Add store test for room removal 2022-01-12 18:41:26 +01:00
Kévin Commaille 76d1b6e4d2 test(base): Add test to populate a store 2022-01-12 18:40:57 +01:00
Kévin Commaille 94e5ee71c7 fix(sdk): Remove a room from the store on forget 2022-01-12 16:53:47 +01:00
Kévin Commaille d455b0d318 test(base): Use common data for store tests 2022-01-12 16:42:04 +01:00
Kévin Commaille 535d1ec30f feat(sdk): Use TagName in set/remove tag methods 2022-01-11 12:25:27 +01:00
Kévin Commaille 52deff1db2 fix(sdk): Move set/remove tag methods to room::Common 2022-01-11 12:24:46 +01:00
Jonas Platte 4603ee136d Remove unnecessary string copies 2022-01-10 16:30:45 +01:00
Jonas Platte da657b8643 Allow custom events in OlmMachine::encrypt 2022-01-10 16:29:49 +01:00
Jonas Platte c2888e56a4 Use a custom options type for room::Common::messages
With the previous API, one would have to supply the room's ID manually,
despite the method already being called on a room.
2022-01-09 01:54:38 +01:00
Benjamin Kampmann 92044cedb9 fixing style again 2022-01-07 12:03:19 +01:00
Benjamin Kampmann fb81ebf301 fixing style again 2022-01-07 12:00:12 +01:00
Benjamin Kampmann 278d934973 fix broken merge 2022-01-07 11:49:51 +01:00
Benjamin Kampmann 0937c2e6f6 [fix ci] remove unused import 2022-01-07 10:46:46 +01:00
Benjamin Kampmann e1ad8fe8e0 Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2022-01-07 10:42:52 +01:00
Antoine Martin 27f2cd3db0 docs(sdk): document features needed for store_path
If default features `sled_state_store` and `sled_cryptostore` aren't
enabled, then passing a store path to the Client does nothing.
2022-01-06 16:09:24 +01:00
Amanda Graven 038adea6d7 appservice: Examples for query handler registry fns
Add examples for functions for registering handlers for room and user
queries. Also remove a needless mut requirement for these functions.
2022-01-05 14:33:46 +01:00
ftilde b1501fcb1d Add test for verification started from a request 2022-01-04 21:27:06 +01:00
ftilde b877d15616 Do not send Done message after receiving a Done
Done messages are supposed to indicate that the verification was
successful and _can be_ finalized. The correct time to send Done events
is after the user has confirmed the verification (after checking the
emoji or similar) and after receiving and checking a mac from the other
party (whatever happens later). Waiting for the other side to send Done
before sending it ourselves does not make sense.
2022-01-04 21:27:06 +01:00
ftilde 1c72472706 Send Done message when confirming in MacReceived state
Being in MacReceived state means that the other party has confirmed that
emojis/numbers match and the sent mac messages has been successfully
checked. When now confirming ourselves this means that the verification
was successful and thus the Done message can be sent to the other party.
2022-01-04 21:27:06 +01:00
ftilde 0e4057f3a3 Do not drop requests after receiving mac if sas is not complete
When during verification we are the first party to complete the
verification workflow and then receive a (correct) MAC from the other
party, we need to send out the Done message even if we have not received
the Done message from the other party ourselves and are thus still
"WaitingForDone".
2022-01-04 21:27:06 +01:00
Damir Jelić c79e62d80e Merge branch 'fix-verification-double-start' 2022-01-04 14:59:52 +01:00
ftilde f4249c591a Return RoomEvents from decryption methods
Previously, these methods returned `SyncRoomEvent`s instead, even though
the decrypted events are required to contain a room_id field (in order
for the server to not to be able to change these). As a side effect,
glue code which adds a room_id to the `SyncRoomEvent` to convert it to a
`RoomEvent` is be removed in some places.

When a `SyncRoomEvent` is required (such as in code handling sync
responses), the `From` implementation of `SyncRoomEvent` can be used.
2022-01-03 22:48:51 +01:00
ftilde 37cadc7c29 Add From<RoomEvent> for SyncRoomEvent
Since SyncRoomEvents are just RoomEvents without a room_id, it is safe
to just discard the information that this field exists in the underlying
json.
2022-01-03 22:48:30 +01:00
ftilde a1cf8b613d Drop start requests from lower precedence parties if sas has already been started.
According to the guide for implementing verification started from
a verification request, both parties should (or at least allowed to)
send a start request when the verification is ready. However, only the
start request from the party with lexicographically smaller user id (or
device id, for device verification, and thus equal user id) is supposed
to be accepted, and the other one ignored.
2022-01-03 21:04:07 +01:00
ftilde 798464b68e Verification: Handle Accept after Start on both sides
Previously, when a sas-workflow was started by the other party (e.g.
from a verification request), but the own start request was answered with
an "accept" this accept would be ignored. However, this is incorrect
since the official guide on implementing verification actually states
that both parties are expected to send start-requests, where of those
only one request is actually accepted (depending on user id and possibly
the device id).
2022-01-03 21:02:53 +01:00
ftilde 87de0b5883 Return broken messages unchanged from messages()
Without this change, a batch with a message that cannot be deserialized
(for whatever reason) means that the batch cannot be processed at all by
the caller. Now, those messages are returned unchanged in the batch so
that the caller can handle them.
2022-01-03 19:49:19 +01:00
Damir Jelić 5003ed1493 docs: Enable all features for some of our crates when building docs 2022-01-03 13:14:36 +01:00
Damir Jelić f12f03b8da docs: Switch to the doc_auto_cfg feature 2022-01-03 12:33:24 +01:00
Damir Jelić 9856270e75 fix(crypto): Don't enable the backup feature by default 2022-01-03 12:27:03 +01:00
Damir Jelić c22fa4e3fd fix(base): Fix a new clippy warning 2022-01-03 10:23:38 +01:00
Julien Merzoug f7f30f1636 docs(sdk): Fix a typo 2022-01-03 13:05:35 +08:00
Damir Jelić ae9a554808 Merge branch 'supported-versions' 2021-12-31 14:00:11 +01:00
Kévin Commaille 5ecd74b2e4 feat(sdk): Make get_supported_versions public 2021-12-31 13:02:15 +01:00
Damir Jelić dd29e2087c Merge branch 'common-fixes' 2021-12-31 12:54:49 +01:00
Jonas Platte 99ce9419aa Fix futures-util dependency
Turn on alloc feature that is required for `future::join_all`.
2021-12-31 11:00:51 +01:00
Kévin Commaille 0d771565f9 feat(sdk): Simplify the API of Common::event 2021-12-31 02:34:16 +01:00
Kévin Commaille c35f8c55ac fix(sdk): Fix docs of Common::active_members_no_sync 2021-12-31 02:16:20 +01:00
ftilde 703e965172 Decrypt messages from room::Common::messages()
Due to additional error possibilities and encryption info for messages,
the return type of the method was changed accordingly and a wrapper
struct `Messages` was introduced.
2021-12-29 15:26:45 +01:00
ftilde 046bfa9dad Fix typo in comment 2021-12-29 15:26:39 +01:00
Damir Jelić 035d319122 Merge branch 'travis/misc' 2021-12-28 11:52:23 +01:00
Damir Jelić 81b730d8c3 Merge branch 'request-config-expose-force_auth' 2021-12-28 11:31:08 +01:00
Damir Jelić 6170be95e1 Merge branch 'membership' 2021-12-28 10:59:34 +01:00
Benjamin Kampmann 34687733e5 create sync token store 2021-12-27 23:54:51 +01:00
Benjamin Kampmann 8ce622d11e fixin style 2021-12-27 23:37:45 +01:00
Benjamin Kampmann 9ff4609f3d testing emcc versions 2021-12-27 23:35:21 +01:00
Benjamin Kampmann 15cdaead50 fix broken now call 2021-12-27 23:27:11 +01:00
Benjamin Kampmann 3cde28a438 trying older emscripten 2021-12-27 21:37:37 +01:00
Jonas Platte d92d7771d9 Add must_use attribute to config constructors and methods
These all don't have side effects so discarding the result wouldn't make
sense.
2021-12-27 17:21:21 +01:00
Jonas Platte f6d7933601 Simplify filter closure 2021-12-27 14:56:31 +01:00
Jonas Platte abf525390e Fix clippy warning (remove unnecessary clone) 2021-12-27 14:56:19 +01:00
Jonas Platte fea80843eb Remove redundant calls to .into_iter() 2021-12-27 14:21:46 +01:00
Jonas Platte 1a7baf631e Avoid enormous type name in GroupSessionManager::encrypt_session_for 2021-12-27 14:20:16 +01:00
Benjamin Kampmann cbd4aa0a37 disable test failing on macosx 2021-12-22 13:58:54 +01:00
Benjamin Kampmann 98beff4455 resolve clippy complaints 2021-12-22 12:36:07 +01:00
Benjamin Kampmann 574893368b refine wasm tests 2021-12-22 12:32:59 +01:00
Benjamin Kampmann 1f5a084ccf don't fail fast 2021-12-22 11:38:52 +01:00
Benjamin Kampmann 8dda7ea8fa please consider all includes 2021-12-22 11:19:39 +01:00
Benjamin Kampmann e619cc1eb7 don't combine 2021-12-22 10:59:17 +01:00
Benjamin Kampmann 1a206ff36c let them all run out 2021-12-16 18:46:00 +01:00
Benjamin Kampmann afe7d055a1 [ci] fix syntax 2021-12-16 18:24:31 +01:00
Benjamin Kampmann 9d4d8667ff latest and node 2021-12-16 17:14:03 +01:00
Benjamin Kampmann 8feab722f8 [CI] dynamic node version 2021-12-16 11:35:24 +01:00
Benjamin Kampmann 7ad5bc7dee version listing 2021-12-16 11:15:10 +01:00
Benjamin Kampmann 71bc043d19 extended testing for wasm example 2021-12-16 10:52:15 +01:00
Travis Ralston 171c334cb1 Add .idea directory to gitignore 2021-12-14 18:59:23 -07:00
Benjamin Kampmann 4f93e739f5 fixing typo 2021-12-13 23:25:26 +01:00
Benjamin Kampmann fa00cba8bb fixing style 2021-12-13 22:37:12 +01:00
Benjamin Kampmann 678527e1e6 libolm is fixed, so should our code be 2021-12-13 22:35:56 +01:00
Benjamin Kampmann 7fc040d86c Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2021-12-13 22:34:33 +01:00
Marc 'risson' Schmitt ba05dd5b8c feat(RequestConfig): expose force_auth setting
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2021-12-13 20:45:51 +01:00
Kévin Commaille b697bcb4fd feat(base): Add RoomMember::membership accessor 2021-12-13 16:20:46 +01:00
Benjamin Kampmann 2982741dd1 minor style fix 2021-12-10 16:32:09 +01:00
Benjamin Kampmann 3f9b5511d1 activate IdbKeyRange feature on web-sys dependency 2021-12-10 14:02:02 +01:00
Benjamin Kampmann 35f2a004e1 style and docs fixes 2021-12-10 13:58:02 +01:00
Benjamin Kampmann e02407ef37 Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2021-12-10 13:30:46 +01:00
Benjamin Kampmann bf9ad7a5c0 fix typo 2021-12-10 13:28:28 +01:00
Benjamin Kampmann 186bd975c1 reuse SafeEncode for indexeddb_cryptostore 2021-12-10 13:28:16 +01:00
Benjamin Kampmann 007b7e2403 outsource SafeEncode helper 2021-12-10 12:53:57 +01:00
Benjamin Kampmann a6dbd6bcbb escaped characters for indexeddb keys 2021-12-10 11:47:35 +01:00
Damir Jelić 009ead2eea chore: Bump Ruma. 2021-12-08 16:50:25 +01:00
Benjamin Kampmann 3de6f60f90 remove unneccessary imports and compiler flags 2021-12-08 13:42:44 +01:00
Benjamin Kampmann 2ccb1d2813 don't pickle 2021-12-08 12:39:50 +01:00
Benjamin Kampmann 89523241fd fixing main sdk wasm testing 2021-12-02 14:37:59 +01:00
Benjamin Kampmann 5734afc7ab [CI] fixing test syntax 2021-12-02 12:45:29 +01:00
Benjamin Kampmann 4e18286c1c remove another dependency 2021-12-01 23:53:07 +01:00
Benjamin Kampmann 10e27536ba fix CI format 2021-12-01 23:51:22 +01:00
Benjamin Kampmann 9883ca0d84 [CI] parallel and the correct crates 2021-12-01 23:46:05 +01:00
Benjamin Kampmann aab1fd2147 fixing ci job 2021-12-01 21:03:26 +01:00
Benjamin Kampmann 652ef6e160 sled store needs tokio 2021-12-01 20:48:27 +01:00
Benjamin Kampmann 53ad5810ef typo fixes 2021-12-01 20:36:44 +01:00
Benjamin Kampmann d0838d6784 fixing style 2021-12-01 20:34:27 +01:00
Benjamin Kampmann 1bbe38e376 compiling matrix-sdk for wasm 2021-12-01 20:32:26 +01:00
Benjamin Kampmann d155f9a020 can work on wasm32 2021-12-01 20:06:25 +01:00
Benjamin Kampmann 7e6ac4222f cleaning up store 2021-12-01 20:03:47 +01:00
Benjamin Kampmann d0395906ab activate available tests for wasm32 2021-12-01 19:32:34 +01:00
Benjamin Kampmann ac2771b997 add docs 2021-12-01 19:00:06 +01:00
Benjamin Kampmann 470c81b8ad be specific with dead_code 2021-12-01 18:58:22 +01:00
Benjamin Kampmann f5485088a0 limit test execution to platforms that support it 2021-12-01 18:55:34 +01:00
Benjamin Kampmann 2ee7a95fc4 (now really) ensure Instant::now is working properly 2021-12-01 18:03:43 +01:00
Benjamin Kampmann 6b3f008b32 ensure Instant::now is working properly 2021-12-01 18:01:00 +01:00
Benjamin Kampmann 8ab5df490a remove appservice, as it won't support wasm for a while 2021-12-01 15:39:41 +01:00
Benjamin Kampmann 787f8265d3 fixing CI 2021-12-01 15:15:26 +01:00
Benjamin Kampmann 293700ce69 checking all crates for wasm32 2021-12-01 14:53:21 +01:00
Damir Jelić f97aed0e41 Merge branch 'MTRNord-wasm-fix' 2021-12-01 14:51:28 +01:00
Benjamin Kampmann afaeae8e6b unify indexeddb-features and improve example build 2021-12-01 12:57:09 +01:00
Benjamin Kampmann b150dea329 fix style 2021-12-01 11:58:22 +01:00
Benjamin Kampmann 4b12260af3 move store implementations into files 2021-12-01 11:56:33 +01:00
Benjamin Kampmann 9d5c1fc14c move store tests into separate reusable macro, too 2021-12-01 11:52:29 +01:00
Benjamin Kampmann c7a9fc6c8e syntax fix 2021-12-01 11:48:30 +01:00
Benjamin Kampmann a1b62a1f4b allow helper to be unused 2021-11-30 19:21:16 +01:00
Benjamin Kampmann 1a20e62de7 remove trouble causing unnecessary ref-clone 2021-11-30 18:54:12 +01:00
Benjamin Kampmann 4fdada55b8 fixing typo 2021-11-30 18:50:50 +01:00
Benjamin Kampmann c5e7ca0c5e undo my olm-sys-hack 2021-11-30 18:45:40 +01:00
Benjamin Kampmann 97d675f216 fix formatting 2021-11-30 18:45:00 +01:00
Benjamin Kampmann 9a0cf2b507 Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2021-11-30 18:43:20 +01:00
Benjamin Kampmann 9b7c1d7c4d Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2021-11-30 18:40:14 +01:00
Benjamin Kampmann 968f80cc1b minor fix 2021-11-30 18:00:20 +01:00
Benjamin Kampmann f185aa2eae reuse cryptostore for sled 2021-11-30 17:58:14 +01:00
Jonas Platte 6519aaff4d crypto: Fix docs for SledStore 2021-11-30 17:48:49 +01:00
Benjamin Kampmann 9f0fe18dfc fix async_test for non-wasm32 envs 2021-11-30 17:46:50 +01:00
Benjamin Kampmann 954cce463e make cryptostore tests reusable 2021-11-30 16:01:42 +01:00
Benjamin Kampmann e3c62825b6 test and impl for outbound 2021-11-30 14:49:00 +01:00
Benjamin Kampmann 1e654acc29 backup and reset for inbound_groups 2021-11-30 13:20:49 +01:00
Benjamin Kampmann 59e3baf819 cover more inbound_group_session functions 2021-11-30 13:01:49 +01:00
Damir Jelić 8494f10583 Merge branch 'up-ruma' 2021-11-30 09:56:01 +01:00
Benjamin Kampmann d509eaa959 implement tracked user 2021-11-29 21:23:01 +01:00
Benjamin Kampmann 85dde94dd5 implement sessions 2021-11-29 20:57:30 +01:00
Benjamin Kampmann c9a10353f2 implement olm_hashes 2021-11-29 20:47:18 +01:00
Benjamin Kampmann 41faa59121 implement keyrequests 2021-11-29 19:43:20 +01:00
Benjamin Kampmann 833802677b implement devices saving and deleting 2021-11-29 15:04:20 +01:00
Jonas Platte 5824cb649e Update tests 2021-11-29 14:30:45 +01:00
Benjamin Kampmann fe257effce properly open encrypted state db 2021-11-29 14:05:48 +01:00
Benjamin Kampmann 47168ca3da implement saving user 2021-11-29 14:05:22 +01:00
Jonas Platte dfd59f42a9 Fix warp build error 2021-11-29 13:36:05 +01:00
Jonas Platte 557e038869 Minimal style improvements 2021-11-29 13:27:38 +01:00
Damir Jelić a628e84b63 fix(crypto): Fix a copy paste error preventing us from verifying users 2021-11-29 09:31:05 +01:00
Jonas Platte 36db5e47dd Upgrade Ruma 2021-11-26 19:22:54 +01:00
Damir Jelić 56d80b91c9 fix(sdk): Send the crypto requests out before a sync as well 2021-11-26 16:52:32 +01:00
Damir Jelić b0f48c9660 fix(crypto): Let users fetch our own device out of the store 2021-11-26 16:52:31 +01:00
Damir Jelić 68a2020516 fix(crypto): Check if the device we get from the server matches our own 2021-11-26 16:26:40 +01:00
Damir Jelić 13db642143 fix(cyrpto): Log database upgrades using the debug log level 2021-11-26 16:26:40 +01:00
Damir Jelić f2c344b39a fix(crypto): Use the DeviceKeys as the inner type for a ReadOnlyDevice 2021-11-26 16:26:40 +01:00
Benjamin Kampmann b42b04e887 account loading and saving 2021-11-26 14:36:14 +01:00
Benjamin Kampmann 229a81bfd6 Implement saving 2021-11-26 12:37:57 +01:00
Benjamin Kampmann 6d9920c239 various minor cleanups of unused imports 2021-11-25 16:44:20 +01:00
Damir Jelić 7b6132b71e feat(crypto): Return the list of room keys we imported
Clients might want to retry decryption after they import room keys, for
this to be efficient they'll need to know which room keys got imported.

This patch extends the return value of the room key import result to
include the map of room keys that got imported.
2021-11-25 16:41:28 +01:00
Benjamin Kampmann 47dff21eda update trait impl of indexeddb 2021-11-25 15:52:57 +01:00
Benjamin Kampmann 32a8ec7782 minor wasm32 fixes 2021-11-25 15:52:27 +01:00
Benjamin Kampmann 4c60db94a2 Implement helper for wasm32 MilliSecondsSinceUnixEpoch 2021-11-25 15:52:03 +01:00
Benjamin Kampmann 42680164ea fix up CI test 2021-11-25 15:49:20 +01:00
Benjamin Kampmann 5cf56adce7 Adding result-signature support for wasm32 async-test-macro 2021-11-25 15:46:17 +01:00
Damir Jelić 10173b990d fix(sdk): Degrade some logs that show user ids to the debug log level 2021-11-25 14:49:07 +01:00
Damir Jelić fc74526699 fix(crypto): Add the ability to mark room keys as backed up when importing 2021-11-25 11:18:09 +01:00
Damir Jelić 55973b5bf1 fix(crypto): Make ExportedRoomKey deserialization laxer
Some clients might have skipped the serialization of an empty
sender_claimed_keys and the forwarding_curve25519_key_chain, while these
fields are required there's really no upside in requiring them if they
are empty.

So create defaults if they are missing.
2021-11-25 10:20:09 +01:00
Marcel 406aaa0b50 Make sure to also include the uuid create serde feature with wasm 2021-11-24 20:50:36 +01:00
Damir Jelić 33b198d505 fix(crypto): Make sure we remove the unsigned object before signing 2021-11-24 15:56:32 +01:00
Damir Jelić be70d38e2a fix(crypto): Use the from constructor for some maps with known values 2021-11-24 15:56:05 +01:00
Damir Jelić 1e70b4f804 fix(crypto): Automatically track your own user if the caller doesn't do so
Users of the crypto crate should mark all members that are part of an
E2EE room for tracking, this will of course mark your own user for
tracking.

If the crypto crate user doesn't have any E2EE rooms he may not add any
members to be tracked. The user might still want to inspect their own
E2EE devices and identities. This patch makes sure that our member is
tracked.
2021-11-24 15:21:50 +01:00
Benjamin Kampmann 4c0bbebb07 Merge remote-tracking branch 'upstream/main' into ben-wasm-store 2021-11-24 11:48:45 +01:00
Benjamin Kampmann 9835c4ad92 Update to webpack5 2021-11-24 11:00:52 +01:00
Damir Jelić a49a7fe1f9 fix(crypto): Clear the master key signatures when we verify our own user 2021-11-22 18:00:52 +01:00
Damir Jelić fa42373cf8 Merge branch 'client-arc' 2021-11-22 16:27:27 +01:00
Damir Jelić a8c36b4041 Merge branch 'fix-session-doc-example' 2021-11-22 16:24:31 +01:00
Damir Jelić b91773a276 Merge branch 'store-upgrade-fix' 2021-11-22 16:23:53 +01:00
Damir Jelić fbc01f015d fix(sdk): Use the correct restore method in an example 2021-11-22 15:44:35 +01:00
Damir Jelić 5d26e36e1f fix(crypto): Make sure we store the store version using the right key 2021-11-22 15:28:21 +01:00
Damir Jelić c4f60dd163 fix(crypto): Only upload our own signature when verifying user identities 2021-11-22 12:33:18 +01:00
Jonas Platte b4220bd824 Reduce the size of Client
… by moving all of its fields into an inner reference-counted type
rather than using reference counting for all fields individually.
Some fields are still refcounted individually and thus go through an
extra layer of indirection, but the size and clone simplification should
still make this change worthwhile.
2021-11-20 02:01:07 +01:00
Jonas Platte 73c5bfed28 Switch from futures-locks to async-lock 2021-11-20 02:01:07 +01:00
Jonas Platte 2456beaf88 Make Result alias more flexible 2021-11-20 00:00:08 +01:00
Jonas Platte cc6f97bee9 Fix missing word 2021-11-20 00:00:08 +01:00
Jonas Platte 8f47e6ffe9 Remove copy-pasted module documentation
It doesn't seem right that both room and room_member have  the same
description. Also room_member is private and doesn't usually show up in
docs.
2021-11-20 00:00:08 +01:00
Jonas Platte 544b24b0ef Move some code out of client.rs
It is by far the biggest module of the matrix-sdk crate.
2021-11-20 00:00:08 +01:00
Benjamin Kampmann 94d3ffa18d infrastructure for indexeddb cryptostore 2021-11-19 21:26:33 +01:00
Jonas Platte 1e13e06e34 Make event-handling related Client fields private 2021-11-19 20:48:27 +01:00
Benjamin Kampmann 9e83bcb6ce fixing browser test 2021-11-19 14:52:11 +01:00
Benjamin Kampmann 917e9016cd clean up API and corresponding docs 2021-11-19 13:52:03 +01:00
Damir Jelić 5a4aa71f6a feat(base): Add a From login response implementation for the Session 2021-11-19 09:41:48 +01:00
Damir Jelić 6606703001 docs(base): Remove anyhow from an example since it isn't used 2021-11-19 09:12:51 +01:00
Andy Balaam 0c35d8890d Improve Session docs example 2021-11-18 17:14:34 +00:00
Benjamin Kampmann 76454e6b8b style fix 2021-11-18 17:40:56 +01:00
Andy Balaam 7d7bd97812 Document how to create a Session 2021-11-18 14:18:16 +00:00
Benjamin Kampmann 10d4fe53f2 clarify API 2021-11-18 15:01:07 +01:00
Benjamin Kampmann 3fcfe98de2 minor clippy fixes 2021-11-18 13:54:24 +01:00
Benjamin Kampmann b16c660258 fixing typo 2021-11-18 13:48:56 +01:00
Benjamin Kampmann 7df36e3d49 first attempt at creating a CI job for wasm tests 2021-11-18 13:37:11 +01:00
Benjamin Kampmann 3e11e0dbb4 fixing style 2021-11-18 13:36:45 +01:00
Benjamin Kampmann a2b80f03d3 move and unify usage of store_key 2021-11-18 12:58:17 +01:00
Benjamin Kampmann e60349604d implement custom value 2021-11-18 12:40:45 +01:00
Andy Balaam f5ba9a5eea Update BackupMachine documentaton to refer to enable_backup_v1 2021-11-18 10:28:03 +00:00
Benjamin Kampmann e7ec86140b generic tests passing' 2021-11-17 21:30:12 +01:00
Benjamin Kampmann 5bba24ce77 activating browser tests 2021-11-17 18:18:20 +01:00
Benjamin Kampmann b8af613aef big batch 2021-11-17 13:08:58 +01:00
Damir Jelić 2e4d5f25cb feat(crypto): Add a method to get the algorithm of the public backup key 2021-11-17 13:02:23 +01:00
Damir Jelić 534e50da57 fix(crypto): Rename the enable_backup method so we can add a v2 one 2021-11-17 13:02:23 +01:00
Damir Jelić 1ffa06884a fix(crypto): Rename the decrypt method on the RecoveryKey struct
The new backup algorithm reuses the same key but uses a different
construct to encrypt/decrypt room keys. This reflects that our decrypt
method uses the v1 algorithm.
2021-11-17 13:02:23 +01:00
Damir Jelić 670e212d9b docs(crypto): Fill out the docs for the backup related types 2021-11-17 13:02:23 +01:00
Damir Jelić 6fc703b4a3 fix(crypto): Fix a bunch of clippy warnings 2021-11-17 13:02:23 +01:00
Damir Jelić 33b7062515 fix(crypto): Fix a bunch of typos 2021-11-17 13:01:58 +01:00
Damir Jelić a7bbeb7ef5 improvement(crypto): Add tests for the recovery key 2021-11-17 13:01:58 +01:00
Damir Jelić 34ec4ac3c9 improvement(crypto): Add tests for the backup machine 2021-11-17 13:01:58 +01:00
Damir Jelić 3f227de023 fix(crypto): Fix the backed up room key count in the memory store 2021-11-17 13:01:58 +01:00
Damir Jelić a417aa23fa fix(crypto): Load the recovery key from the sled store 2021-11-17 13:01:58 +01:00
Damir Jelić f8fdfd1613 fix(crypto): Add a proper exception when creating the Pk decryption object 2021-11-17 13:01:58 +01:00
Damir Jelić 1fdd560ff0 fix(crypto): Remove a unneeded clippy attribute 2021-11-17 13:01:58 +01:00
Damir Jelić 878969a5c4 docs(crypto): Add some docs for the backup related types 2021-11-17 13:01:58 +01:00
Damir Jelić c6d073ebd7 fix(crypto): Remove some dead code 2021-11-17 13:01:58 +01:00
Damir Jelić 2b5ae869cd feat(crypto): Gossip the backup recovery key if requested 2021-11-17 13:01:58 +01:00
Damir Jelić 2db52eed7c feat(crypto): Request the recovery key when we request secrets 2021-11-17 13:01:58 +01:00
Damir Jelić 656edce75a improvement(crypto): Make the backup logging prettier 2021-11-17 13:01:58 +01:00
Damir Jelić 4c021dea5e fix(crypto): Correctly reset the backup state of room keys 2021-11-17 13:01:58 +01:00
Damir Jelić bbd76dafa0 fix(crypto): Fix a bunch of clippy warnings 2021-11-17 13:01:58 +01:00
Damir Jelić 4f2c91d848 feat(crypto): Add a method to decrypt messages using the recovery key 2021-11-17 13:01:58 +01:00
Damir Jelić 6f5b6900d6 fix(crypto): Flush when we ugprade the DB 2021-11-17 13:01:58 +01:00
Damir Jelić eddc7bd6af feat(crypto): Add a method to check the signature of a backup version 2021-11-17 13:01:58 +01:00
Damir Jelić dfef6370b6 feat(crypto): Add a method to verify uploaded backups 2021-11-17 13:01:58 +01:00
Damir Jelić b5babdb6c4 fix(crypto): Don't load all room keys when backing up 2021-11-17 13:01:58 +01:00
Damir Jelić df53eb00ab fix(crypto): Fix a deadlock when generating the backup request 2021-11-17 13:01:58 +01:00
Damir Jelić 63915171fc feat(crypto): Add a method to check if backups are enabled 2021-11-17 13:01:58 +01:00
Damir Jelić 4873914d4d feat(crypto): Initial support for server-side backups of room keys 2021-11-17 13:01:44 +01:00
Benjamin Kampmann 8a2732ab5d first steps 2021-11-15 20:05:43 +01:00
Damir Jelić f069387d58 docs(sdk): Add an example to the restore_login method 2021-11-15 16:15:05 +01:00
ftilde 8815c05108 Refactor Joined::send_attachment
Instead of manually modifying *EventContent structs, the ruma
constructors *::encrypted and *::plain are used now depending on whether
encryption should be used for the attachment or not.
2021-11-13 01:39:00 +01:00
ftilde dfc2ed7a33 Prefer MediaType::Encrypted if url and file are present
Some clients (including those using matrix-rust-sdk currently) may add
encrypted file info as well as the url to the encrypted blob to the
*EventContent. Interpreting the presence of an url as an indicator of
unencrypted message (like was done before) would result in access to the
encrypted blob in `get_media_content`.

Fixes #406.
2021-11-13 01:39:00 +01:00
Jonas Platte 38a8253aa8 Turn register_event_handler(_context)? examples into proper doctests
Previously, they didn't actually run the methods they were showing the
use of.
2021-11-12 12:39:07 +01:00
Jonas Platte 5fed5cdeed Allow adding custom event handler context 2021-11-12 12:39:07 +01:00
Jonas Platte df50d59de2 Update signature of AppService::register_event_handler
It no longer requires a mutable `AppService` and can also be chained,
like `Client::register_event_handler`.
2021-11-11 19:28:40 +01:00
Damir Jelić 1651952903 docs(sdk): Remove a bunch of unwraps from some doc examples 2021-11-11 16:58:43 +01:00
Damir Jelić 33a43af20e improvement(crypto): Use a type for the result of the room key import method 2021-11-11 16:57:31 +01:00
Damir Jelić 6a66a67454 fix(crypto): Fix the importing of exported room keys 2021-11-11 16:05:14 +01:00
Jonas Platte 83b908754e Remove unused dependencies
Found by cargo-udeps.
2021-11-10 21:43:56 +01:00
Jonas Platte 02b0ed2b42 Reduce dependencies on futures-* crates 2021-11-10 20:39:35 +01:00
Jonas Platte c124cf5b62 Remove unnecessary use of future::ready 2021-11-10 20:39:03 +01:00
Jonas Platte dfdf794199 Remove unnecessary use of TryFutureExt 2021-11-10 20:12:56 +01:00
Damir Jelić df2c0bd6e9 docs(sdk): Fix a typo in the enable_encryption method 2021-11-09 19:52:46 +01:00
Damir Jelić 2e04a3753d Merge branch 'one-time-key-generationf-fix' 2021-11-09 13:50:08 +01:00
Damir Jelić e1e864c606 fix(crypto): Save the account if we created a new key upload request 2021-11-09 12:30:48 +01:00
Damir Jelić 7f3067553b fix(crypto): Don't generate new one-time keys unless the existing ones are uploaded
This is helpful if the caller doesn't have propper request retrying.
Calling the outgoing_requests() method without actually uploading
all the requests would end up generating too many one-time keys and
removing some one-time keys that weren't used yet.

This would manifest itself down the line as undecryptable to-device
messages.
2021-11-09 11:45:20 +01:00
Julian Sparber 253d6c9af8 matrix-qrcode: Use GenericImage and GenericImageView trait
This changes `QrVerificationData::from_luma()` to accept any struct that
implements GenericImage and GenericImageView.
This way we don't force a specific container for the ImageBufffer, hence
the developer doesn't necessarily need to copy the image data into a
Vec<u8>.
2021-11-09 11:33:38 +01:00
Damir Jelić 1f1ae0059e docs: Remove the now unneeded doc cfg attributes 2021-11-09 10:43:42 +01:00
Damir Jelić 05a190ee5a docs(sdk): Add an example that prints out the SAS emojis 2021-11-08 17:17:42 +01:00
Damir Jelić ed561f7b9e improvement(crypto): Use a struct for the SAS emoji/description pairs 2021-11-08 17:17:14 +01:00
Damir Jelić fba12b3926 docs(sdk): Explain how room keys work in the encryption module 2021-11-08 15:32:51 +01:00
Damir Jelić 1b2ef50ded docs(sdk): Explain why it may be problematic to manually verify devices 2021-11-08 15:32:51 +01:00
Damir Jelić c79481c6fa docs(sdk): Clarify what it means for a device to be verified 2021-11-08 15:32:51 +01:00
Damir Jelić f5b98a62ab docs(sdk): Describe the ways we can restore a client 2021-11-08 15:32:51 +01:00
Damir Jelić f5a6972feb improvement(crypto): Rename the EncryptionInfo struct for attachments 2021-11-08 15:32:51 +01:00
Damir Jelić 1faaba39c7 docs(sdk): Explain how cross signing helps a bit better 2021-11-08 15:32:51 +01:00
Damir Jelić e58eb70924 chore: Switch to the 2021 edition 2021-11-08 15:32:51 +01:00
Damir Jelić 4bfc1041cc docs(sdk): Improve an entry in the e2ee failure table 2021-11-08 15:32:51 +01:00
Damir Jelić b6f7e85964 feat(sdk): Add a method to enable encryption for a room 2021-11-08 15:32:51 +01:00
Damir Jelić b9b02ff167 docs(sdk): Add another entry to the failure table 2021-11-08 15:32:51 +01:00
Damir Jelić 1aba90cd0b docs(sdk): Consistent headings 2021-11-08 15:32:51 +01:00
Damir Jelić 3f689e9c74 docs(sdk): Introduce a failure table for the encryption module 2021-11-08 15:32:51 +01:00
Damir Jelić d744948a27 docs(sdk): Fix a typo 2021-11-08 15:32:51 +01:00
Damir Jelić ccc3a005cb docs(sdk): A couple small clarifications 2021-11-08 15:32:51 +01:00
Damir Jelić 605c3b056f docs(sdk): Use a table to describe our features 2021-11-08 15:32:51 +01:00
Damir Jelić 387d25c438 docs(sdk): Explain a bit more how devices are backed by device keys 2021-11-08 15:32:51 +01:00
Damir Jelić 050f62baa7 docs(sdk): Clarify the manual verification a bit more 2021-11-08 15:32:51 +01:00
Damir Jelić afe4f628c3 docs(sdk): Improve the UserIdentity docs 2021-11-08 15:32:51 +01:00
Damir Jelić 3964eea2e2 docs(sdk): Add some more E2EE related docs 2021-11-08 15:32:51 +01:00
Damir Jelić 687ebabca9 Merge branch 'reciprocate_qr_scanning' 2021-11-05 19:35:57 +01:00
Julian Sparber 635ee5f130 matrix-sdk: Send reciprocate to other side when scanning a Qr Code
We need to tell the other side that we scanned there Qr Code.
2021-11-05 19:05:43 +01:00
Jonas Platte b27795c0d1 Upgrade ruma 2021-11-05 16:05:25 +01:00
Jonas Platte f21faa9e2e Remove unused imports in doctests 2021-11-05 15:39:02 +01:00
Jonas Platte 77de8383fe Fix clippy warning 2021-11-05 15:25:16 +01:00
Jonas Platte cdfd5f9f0c Remove unnecessary use of Ruma event content enums 2021-11-05 15:16:17 +01:00
Kévin Commaille 5eb7029568 matrix-sdk: Allow to reconfigure client with login response discovery info
Fixes #219
2021-11-02 16:45:03 +01:00
Kévin Commaille 52910d50b4 matrix-sdk: Remove unecessary mut for client
Client does not need to be mutable to set the homeserver
2021-11-02 11:59:44 +01:00
Julian Sparber 8dcfd1176f matrix-sdk-crypto: Drop MutexGuard in VerificationRequest::scan_qr_code()
We can't move MutexGuards across threads and therefore we need to drop
it before awaitng on a future since a task may be moved between threads.
2021-10-29 16:33:25 +02:00
Damir Jelić a85f29d904 feat(sdk): Expose the method and types to scan QR codes 2021-10-28 11:54:28 +02:00
Damir Jelić 292425fd80 fix(crypto): Make sure we don't treat our own device as a new one every time 2021-10-28 11:24:02 +02:00
Damir Jelić 19266f643c improvement(crypto): Improve the logs for the keys/query handling 2021-10-28 11:24:02 +02:00
Damir Jelić 3853d0c9d7 improvement(crypto): Log the mismatched user/key if checking fails 2021-10-27 16:23:34 +02:00
Damir Jelić 3c59e186d9 improvement(crypto): Improve the logging when we decrypt room events 2021-10-27 15:00:04 +02:00
Damir Jelić e448a76484 improvement(crypto): Improve the to-device decryption logs 2021-10-27 14:57:07 +02:00
Damir Jelić 0ee8d2733a fix(crypto): Improve the log lines for the room key encryption flow 2021-10-27 14:44:27 +02:00
Damir Jelić 38ae79ba3c Merge branch 'room-is-space' 2021-10-27 11:08:33 +02:00
Amanda Graven d06371d458 Add convenience function to check if a room is a space 2021-10-27 10:39:19 +02:00
Damir Jelić 8b200c8200 Merge branch 'appservice-user-store' 2021-10-26 12:00:27 +02:00
Damir Jelić 2a285de1b0 Merge branch 'appservice-event-handler' 2021-10-26 11:30:30 +02:00
Amanda Graven 093588d5a3 Event handlers for room and user queries
Add a member to AppService which can store closures that will be invoked
when the homeserver invokes query endpoints.
2021-10-26 10:50:23 +02:00
Amanda Graven a9e990142a appservice: Store which users have been registered 2021-10-26 09:51:51 +02:00
Damir Jelić 42bec97b68 Merge branch 'blocking' 2021-10-25 14:25:59 +02:00
Damir Jelić bc8641666c fix(sdk): Only import the crypto store type if encryption is enabled 2021-10-25 13:30:33 +02:00
Damir Jelić 74342a8775 Merge branch 'event-handling' 2021-10-25 13:02:27 +02:00
Damir Jelić bc92c02772 Merge branch 'erikj/add_crypto_store_setting' 2021-10-25 13:00:55 +02:00
Damir Jelić f434b4d970 Merge branch 'erikj/export_gossip_request' 2021-10-25 13:00:07 +02:00
Damir Jelić 86657736e8 chore: Fix some new clippy warnings. 2021-10-25 12:40:34 +02:00
Erik Johnston a037e6b1a7 Add Config::crypto_store
This allows setting of the crypto store in the high level client, in the
same way you can in the base client.
2021-10-25 10:38:28 +01:00
Jonas Platte 4570d7194e Add SyncEvent impls for SyncRedactionEvent 2021-10-22 22:11:01 +02:00
Erik Johnston a7c97e731d Document types correctly 2021-10-22 11:57:21 +01:00
Erik Johnston c093b68078 Also export SecretInfo 2021-10-22 11:33:34 +01:00
Erik Johnston c824278565 Export GossipRequest
The `matrix-sdk-store::CryptoStore` uses the type in its definition,
so we export it to allow third party implementations.
2021-10-22 11:29:15 +01:00
Julian Sparber 8ee3b6f909 sled_store: Run read operations on blocking thread 2021-10-21 14:59:33 +02:00
Denis Kasak 9e1024f4b5 refactor: Use structured logging field for room_id. 2021-10-14 12:22:13 +02:00
Denis Kasak 8cab5b811f docs: Doc tweaks. 2021-10-14 10:22:25 +02:00
Denis Kasak 1c36e62e2c fix: Unbreak encryption.
And add some docs and logging statements.

cb8a42a529 broke encryption because it
elided the call to `send_raw` from `send` and instead did a direct HTTP
request. Since event encryption is only called from `send_raw`, this
made all events cleartext.
2021-10-14 10:22:25 +02:00
Julian Sparber 0a92f7161a client: make sync_stream() return an infallible stream
This way the developer can decide what to do on an error
2021-10-11 18:33:06 +02:00
Damir Jelić 8af768bf30 chore(base): Remove the non-exhaustive patterns lint
The lint is only available on nightly, but requires to be enabled via a
feature, which is only available for nightly.
2021-10-11 11:06:32 +02:00
Damir Jelić 61375a6245 chore: Add a github action to check for typos 2021-10-11 09:49:27 +02:00
Damir Jelić 3c08b5cf09 chore: Fix a bunch of typos 2021-10-11 09:49:25 +02:00
Damir Jelić 498d7b4666 Merge branch 'dkasak/doc-improvements' 2021-10-11 09:47:21 +02:00
Damir Jelić 7cfa9dbf58 Merge branch 'dkasak/key-sharing-algorithm-rendering' 2021-10-11 09:46:43 +02:00
Damir Jelić 5aa6aeac16 Merge branch 'flow_id' 2021-10-05 20:47:33 +02:00
Jonas Platte b6261d014c Add custom event examples for Joined::{send,send_state_event} 2021-10-05 18:42:21 +02:00
Jonas Platte 8455164a69 Simplify command_bot example 2021-10-05 18:20:07 +02:00
Jonas Platte b959d4be29 Use new event type aliases 2021-10-05 18:20:07 +02:00
Jonas Platte 39d6ebdd53 Don't panic if serialization of user-provided events fails 2021-10-05 18:20:07 +02:00
Jonas Platte 0f52cd8039 Stop relying on enum deserialization for adding room_id 2021-10-05 18:20:07 +02:00
Jonas Platte 4a50561867 crypto: Simplify Account::parse_decrypted_to_device_event 2021-10-05 18:20:07 +02:00
Jonas Platte cb8a42a529 Upgrade to latest Ruma git main 2021-10-05 18:20:07 +02:00
Jonas Platte d16d21c54f crypto: Refactor ToDeviceRequest construction 2021-10-05 18:20:07 +02:00
Jonas Platte 339dfefb53 Replace qualified path with use (style consistency) 2021-10-05 18:20:07 +02:00
Jonas Platte b8e8cfd149 Fix clippy warnings 2021-10-05 18:20:07 +02:00
Jonas Platte a40cf26aa7 Fix formatting 2021-10-05 17:40:50 +02:00
Damir Jelić fe8ecbbeb8 Merge branch 'fix_lock_on_await' 2021-10-05 10:36:02 +02:00
Damir Jelić 2686e987a6 Merge branch 'dkasak/share-all-indices-with-own-trusted-devices' 2021-10-05 10:13:49 +02:00
Julian Sparber a3f078cb96 encryption: Expose FlowId on VerificationRequest
Fixes: https://github.com/matrix-org/matrix-rust-sdk/issues/367
2021-10-04 22:42:39 +02:00
Julian Sparber 82659142c5 crypto: Fix VerificationRequest::generate_qr_code()
We can't keep a lock on the `inner` therefore clone it. It's not pretty
but we do the same in `start_sas()`.
2021-10-04 17:04:09 +02:00
Denis Kasak 3c03c64778 docs(crypto): Reword.
- Bring the wording in line with the wording on the matrix_sdk crate.
- Style fixes.
- Formatting.
2021-10-04 14:53:30 +02:00
Denis Kasak fdbed7fbf8 docs(crypto): Add room key sharing decision tree to the docs. 2021-10-04 14:48:12 +02:00
Denis Kasak 759bc76f04 docs: More typo/style fixes. 2021-10-04 14:36:37 +02:00
Denis Kasak ab1657b811 docs: Flesh out intro section a bit.
- Mention subcrates.
- Point out `Client` as the central component.
2021-10-04 14:34:18 +02:00
Denis Kasak b219a347f6 Reword opening paragraph. 2021-10-04 13:15:22 +02:00
Denis Kasak bd82738630 Fix typo. 2021-10-04 13:06:50 +02:00
Amanda Graven 9829b45ce8 Specifiy edition in rustfmt.toml 2021-10-04 12:56:49 +02:00
Denis Kasak f2c0abeb58 Add decision tree rendering of the algorithm. 2021-10-04 12:51:16 +02:00
Denis Kasak 55731922e8 Add decision tree model of the key sharing algorithm.
And a tool to render it.

Signed-off-by: Denis Kasak <dkasak@termina.org.uk>
2021-10-04 12:49:16 +02:00
Denis Kasak 671efb2313 Await result. 2021-10-04 11:13:02 +02:00
Denis Kasak da052ed9aa clippy fix 2021-10-04 11:12:46 +02:00
Denis Kasak 49e722ffbf cargo fmt 2021-10-04 10:57:11 +02:00
Denis Kasak de2e2539b7 Write a test.
Signed-off-by: Denis Kasak <dkasak@termina.org.uk>
2021-10-04 10:51:31 +02:00
Denis Kasak 5f87ccdcd9 Explain return value in the docstring.
Signed-off-by: Denis Kasak <dkasak@termina.org.uk>
2021-10-04 10:51:31 +02:00
Denis Kasak bf2195b999 crypto: Share all indices with own trusted devices.
This fixes an edge case in the key sharing decision algorithm in which
your own trusted devices could be getting a limited session upon a
reshare. It also simplifies the algorithm a bit by bringing the check
for an own and trusted device to the start.

If the requesting device is a trusted/verified device of our own, we
share the session in full, regardless of whether we've previously shared
with that device and at which index. Otherwise, we do the "have we
shared previously" check via the outbound session and only share from
the index it was originally shared at, as before.

Signed-off-by: Denis Kasak <dkasak@termina.org.uk>
2021-10-04 10:45:25 +02:00
Damir Jelić 3042209cf6 crypto: Check that the event was encrypted for the right room 2021-09-21 17:27:31 +02:00
Damir Jelić 87728268e2 crypto: Don't borrow the plaintext to later clone it 2021-09-21 16:48:42 +02:00
Jonas Platte bbbd5648e0 Fix comment typos 2021-09-21 15:36:04 +02:00
Jonas Platte b813735dd2 Remove unused dev-dependency 2021-09-21 15:24:55 +02:00
Jonas Platte 871a245702 crypto: Avoid unnecessary event serialization 2021-09-21 15:20:02 +02:00
Jonas Platte f783fb9830 Fix typo: Missmatched => Mismatched 2021-09-21 15:19:21 +02:00
Damir Jelić fa5aea2ca1 Merge branch 'fix-anyhow-feature' 2021-09-21 14:54:40 +02:00
Jonas Platte 2128d0bfcc CI: Use Nightly Clippy 2021-09-21 13:12:46 +02:00
Jonas Platte 42061c9bf5 CI: Run clippy on more (Cargo) targets 2021-09-21 13:12:34 +02:00
Jonas Platte d0851c8a9e Fix new (Nightly) Clippy warnings 2021-09-21 13:11:53 +02:00
Jonas Platte 0817bc490e Add missing required-features for examples 2021-09-21 13:11:31 +02:00
Jonas Platte 3621b62418 Fix Client::register future not being Send under warp feature
Caused by https://github.com/tokio-rs/tracing/issues/1487.
2021-09-21 13:07:40 +02:00
Jonas Platte cbc0739041 Re-export anyhow and eyre features from matrix-sdk-appservice 2021-09-21 11:59:47 +02:00
Jonas Platte f752bded4b Add eyre feature to matrix-sdk 2021-09-21 11:59:47 +02:00
Jonas Platte 6cbb07bc2d Fix broken anyhow feature 2021-09-21 11:59:15 +02:00
Damir Jelić 4d048934e6 Merge branch 'master-rename' 2021-09-20 11:18:17 +02:00
Damir Jelić 544a66fa34 chore: Rename the master branch 2021-09-20 10:09:40 +02:00
Jonas Platte 533c86d285 Run event / notification handler callbacks in order 2021-09-17 20:46:32 +02:00
Damir Jelić 15e9d03c2c fix(sdk): Don't retry requests in the tests
Since now sync_once() sends out E2EE requests after the sync and our
tests only set up the `/sync` endpoint using mockito we're going to be
stuck in a retry loop trying to send out the mentioned requests.

It's fine to disable request retrying and let those requests fail.
2021-09-17 20:19:13 +02:00
Damir Jelić ef3f827769 docs(sdk): Fix a typo 2021-09-17 20:18:42 +02:00
Damir Jelić d34b83851f feat(sdk): Add a getter for the Session 2021-09-17 20:18:17 +02:00
Damir Jelić 61eefbbadd docs(sdk): Fix some doc links. 2021-09-17 11:10:18 +02:00
Damir Jelić 544d15c574 docs(sdk): Improve a bunch of Client docs 2021-09-17 11:10:18 +02:00
Damir Jelić 8ed06883f6 fix(sdk): Don't take ownership of the user id when logging in using SSO 2021-09-17 11:10:18 +02:00
Damir Jelić 39edd32072 feat(sdk): Add a method to sync as an async stream 2021-09-17 10:54:20 +02:00
Damir Jelić 051d935b28 docs(sdk): Add better docs and examples to the sync methods 2021-09-17 10:54:20 +02:00
Damir Jelić 37904007bb feat(sdk): Send the outgoing E2EE requests out concurrently 2021-09-16 15:43:50 +02:00
Damir Jelić 3dc9f78051 fix(sdk): Move the crypto plumbing in the sync to the sync_once method
This would allow people to avoid the `sync()` method and let them drive
their own syncs.

Until now using `sync()` only would mean that the crypto requests would
never have been sent out.
2021-09-16 14:36:16 +02:00
Damir Jelić 729a29352b chore(sdk): Move the crypto plumbing of the sync into a separate method 2021-09-16 14:14:37 +02:00
Damir Jelić 626f4b92b5 chore(sdk): Remove some unwraps 2021-09-16 14:06:44 +02:00
Damir Jelić fa6230a08a fix(sdk): Use a better variable name for the file when uploading 2021-09-15 22:08:45 +02:00
Damir Jelić 866ab33c45 chore: Remove some unneeded clippy silences 2021-09-15 20:48:15 +02:00
Damir Jelić 7764f01b59 fix(crypto): Only send cancellations if there were multiple request recipients 2021-09-15 20:28:16 +02:00
Damir Jelić ff9bb94ab4 docs(sdk): Simplify the event sending examples 2021-09-15 20:27:36 +02:00
Damir Jelić 28412344d5 docs(sdk): Fix the link to the examples dir 2021-09-15 14:20:14 +02:00
Damir Jelić bae6b33497 feat(sdk): Add the ability to send out custom message events 2021-09-15 14:20:14 +02:00
Damir Jelić 7a21bdd573 docs(sdk): Fix a small typo 2021-09-15 10:36:58 +02:00
Damir Jelić 43011261a8 fix(sdk): Remove the room_send method from the Client
This method is a bit dangerous if the room is encrypted, e.g. people can
send events before the room state has been fetched and thus accidentally
send out unencrypted events in an encrypted room.
2021-09-15 10:36:58 +02:00
Damir Jelić d8b60dfe55 feat(sdk): Add support to send out custom state events 2021-09-14 23:36:09 +02:00
Damir Jelić 70ab0f446d chore: Sort the deps in our Cargo.toml files 2021-09-14 16:38:33 +02:00
Damir Jelić af74988a83 chore: Rename the crate folders to use dashes instead of underscores 2021-09-14 16:38:33 +02:00
Damir Jelić 31b7063e68 docs(sdk): Remove unwraps from the joined room doc examples 2021-09-14 16:38:33 +02:00
Damir Jelić f42883eaad docs(sdk): Remove some unwraps from the encryption doc examples 2021-09-14 16:38:33 +02:00
Damir Jelić 7de782d3a2 chore(sdk): Move the various config structs into its own module 2021-09-14 16:38:33 +02:00
Damir Jelić cf26557cc2 chore(sdk): Move the sso related imports into the sso login method 2021-09-14 13:20:03 +02:00
Damir Jelić 29d11db73a chore(sdk): Move the e2ee related client methods to the encryption module 2021-09-14 13:10:22 +02:00
Damir Jelić e8c5b0766e chore(sdk): Move all the crypto related module under an encryption module 2021-09-14 12:32:59 +02:00
Damir Jelić 041ef66c01 chore: Move the crates into a subfolder 2021-09-14 11:59:21 +02:00
Damir Jelić b3bbcd1729 chore: Set a rust version in our crates 2021-09-14 10:25:04 +02:00
605 changed files with 168231 additions and 37586 deletions
+53
View File
@@ -1,2 +1,55 @@
# Pass the rustflags specified to host dependencies (build scripts, proc-macros)
# when a `--target` is passed to Cargo. Historically this was not the case, and
# because of that, cross-compilation would not set the rustflags configured
# below in `target.'cfg(...)'` for them, resulting in cache invalidation.
#
# Since this is an unstable feature (enabled at the bottom of the file), this
# setting is unfortunately ignored on stable toolchains, but it's still better
# to have it apply on nightly than using the old behavior for all toolchains.
target-applies-to-host = false
[alias]
xtask = "run --package xtask --"
uniffi-bindgen = "run --package uniffi-bindgen --"
[doc.extern-map.registries]
crates-io = "https://docs.rs/"
# Exclude tarpaulin, android and ios from extra lints since on stable, without
# the nightly-only target-applies-to-host setting at the top, cross compilation
# and otherwise changing cfg's can be very bad for caching. These should never
# be the default either and don't have much target-specific code that would
# benefit from the extra lints.
[target.'cfg(not(any(tarpaulin, target_os = "android", target_os = "ios")))']
rustflags = [
"-Wrust_2018_idioms",
"-Wsemicolon_in_expressions_from_macros",
"-Wunused_extern_crates",
"-Wunused_import_braces",
"-Wunused_qualifications",
"-Wtrivial_casts",
"-Wtrivial_numeric_casts",
"-Wclippy::cloned_instead_of_copied",
"-Wclippy::dbg_macro",
"-Wclippy::inefficient_to_string",
"-Wclippy::macro_use_imports",
"-Wclippy::mut_mut",
"-Wclippy::needless_borrow",
"-Wclippy::nonstandard_macro_braces",
"-Wclippy::str_to_string",
"-Wclippy::todo",
]
[target.'cfg(target_arch = "wasm32")']
rustflags = [
# We have some types that are !Send and/or !Sync only on wasm, it would be
# slightly more efficient, but also pretty annoying, to wrap them in Rc
# where we would use Arc on other platforms.
"-Aclippy::arc_with_non_send_sync",
]
# activate the target-applies-to-host feature.
# Required for `target-applies-to-host` at the top to take effect.
[unstable]
rustdoc-map = true
target-applies-to-host = true
+4
View File
@@ -0,0 +1,4 @@
[profile.default]
retries = { backoff = "exponential", count = 3, delay = "1s", jitter = true }
# kill the slow tests if they still aren't up after 180s
slow-timeout = { period = "60s", terminate-after = 3 }
+6
View File
@@ -0,0 +1,6 @@
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
+1
View File
@@ -0,0 +1 @@
* @matrix-org/rust
+7
View File
@@ -0,0 +1,7 @@
<!-- description of the changes in this PR -->
- [ ] Public API changes documented in changelogs (optional)
<!-- Sign-off, if not part of the commits -->
<!-- See CONTRIBUTING.md if you don't know what this is -->
Signed-off-by:
+13
View File
@@ -0,0 +1,13 @@
name: Security audit
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
+54
View File
@@ -0,0 +1,54 @@
name: Benchmarks
on:
workflow_dispatch:
jobs:
benchmarks:
name: Run Benchmarks
runs-on: ubuntu-latest
environment: matrix-rust-bot
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2023-11-08
components: rustfmt
- name: Run Benchmarks
run: cargo bench | tee benchmark-output.txt
- name: Check benchmark result for PR
if: github.event_name == 'pull_request'
uses: benchmark-action/github-action-benchmark@v1
with:
name: Rust Benchmark
tool: 'cargo'
output-file-path: benchmark-output.txt
auto-push: false
# comment to alert the user this has gone bad
github-token: ${{ secrets.MRB_ACCESS_TOKEN }}
alert-threshold: '120%'
comment-on-alert: true
fail-threshold: '150%'
fail-on-alert: true
- name: Store benchmark result
if: github.event_name != 'pull_request'
uses: benchmark-action/github-action-benchmark@v1
with:
name: Rust Benchmark
tool: 'cargo'
output-file-path: benchmark-output.txt
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
# Show alert with commit comment on detecting possible performance regression
alert-threshold: '150%'
comment-on-alert: true
fail-on-alert: true
alert-comment-cc-users: '@gnunicornBen,@jplatte,@poljar'
+111
View File
@@ -0,0 +1,111 @@
name: Bindings tests
on:
workflow_dispatch:
push:
branches: [main]
pull_request:
branches: [main]
types:
- opened
- reopened
- synchronize
- ready_for_review
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
xtask:
uses: ./.github/workflows/xtask.yml
test-uniffi-codegen:
name: Test UniFFI bindings generation
needs: xtask
if: github.event_name == 'push' || !github.event.pull_request.draft
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install protoc
uses: taiki-e/install-action@v2
with:
tool: protoc@3.20.3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
# Cargo config can screw with caching and is only used for alias config
# and extra lints, which we don't care about here
- name: Delete cargo config
run: rm .cargo/config.toml
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-linux }}"
fail-on-cache-miss: true
- name: Build library & generate bindings
run: target/debug/xtask ci bindings
test-apple:
name: matrix-rust-components-swift
needs: xtask
runs-on: macos-12
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout
uses: actions/checkout@v3
# install protoc in case we end up rebuilding opentelemetry-proto
- name: Install protoc
uses: taiki-e/install-action@v2
with:
tool: protoc@3.20.3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install aarch64-apple-ios target
run: rustup target install aarch64-apple-ios
# Cargo config can screw with caching and is only used for alias config
# and extra lints, which we don't care about here
- name: Delete cargo config
run: rm .cargo/config.toml
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-macos }}"
fail-on-cache-miss: true
- name: Build library & bindings
run: target/debug/xtask swift build-library
- name: Run XCTests
working-directory: bindings/apple
run: swift test
- name: Build Framework
run: target/debug/xtask swift build-framework --only-target=aarch64-apple-ios
+376 -215
View File
@@ -1,249 +1,410 @@
name: CI
name: Rust tests
on:
workflow_dispatch:
push:
branches: [main]
pull_request:
branches: [ master ]
branches: [main]
types:
- opened
- reopened
- synchronize
- ready_for_review
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
style:
name: Check style
xtask:
uses: ./.github/workflows/xtask.yml
test-matrix-sdk-features:
name: 🐧 [m], ${{ matrix.name }}
needs: xtask
if: github.event_name == 'push' || !github.event.pull_request.draft
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
name:
- no-encryption
- no-sqlite
- no-encryption-and-sqlite
- sqlite-cryptostore
- rustls-tls
- markdown
- socks
- sso-login
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v3
- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
components: rustfmt
profile: minimal
override: true
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cargo fmt
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
# use a separate cache for each job to work around
# https://github.com/Swatinem/rust-cache/issues/124
key: "${{ matrix.name }}"
# ... but only save the cache on the main branch
# cf https://github.com/Swatinem/rust-cache/issues/95
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install nextest
uses: taiki-e/install-action@nextest
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-linux }}"
fail-on-cache-miss: true
- name: Test
run: |
target/debug/xtask ci test-features ${{ matrix.name }}
test-matrix-sdk-examples:
name: 🐧 [m]-examples
needs: xtask
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install nextest
uses: taiki-e/install-action@nextest
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-linux }}"
fail-on-cache-miss: true
- name: Test
run: |
target/debug/xtask ci examples
test-matrix-sdk-crypto:
name: 🐧 [m]-crypto
needs: xtask
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install nextest
uses: taiki-e/install-action@nextest
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-linux }}"
fail-on-cache-miss: true
- name: Test
run: |
target/debug/xtask ci test-crypto
test-all-crates:
name: ${{ matrix.name }}
if: github.event_name == 'push' || !github.event.pull_request.draft
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
include:
- name: 🐧 all crates, 🦀 stable
rust: stable
os: ubuntu-latest
- name: 🐧 all crates, 🦀 beta
rust: beta
os: ubuntu-latest
- name: 🍏 all crates, 🦀 stable
rust: stable
os: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install protoc
uses: taiki-e/install-action@v2
with:
tool: protoc@3.20.3
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install nextest
uses: taiki-e/install-action@nextest
- name: Test
run: |
cargo nextest run --workspace \
--exclude matrix-sdk-integration-testing --features testing
- name: Test documentation
run: |
cargo test --doc --features docsrs
test-wasm:
name: 🕸️ ${{ matrix.name }}
needs: xtask
if: github.event_name == 'push' || !github.event.pull_request.draft
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
- name: '[m]-qrcode'
cmd: matrix-sdk-qrcode
- name: '[m]-base'
cmd: matrix-sdk-base
- name: '[m]-common'
cmd: matrix-sdk-common
- name: '[m]-indexeddb, no crypto'
cmd: indexeddb-no-crypto
- name: '[m]-indexeddb, with crypto'
cmd: indexeddb-with-crypto
- name: '[m], no-default, wasm-flags'
cmd: matrix-sdk-no-default
- name: '[m], indexeddb stores'
cmd: matrix-sdk-indexeddb-stores
- name: '[m], indexeddb stores, no crypto'
cmd: matrix-sdk-indexeddb-stores-no-crypto
steps:
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
components: clippy
- name: Install wasm-pack
uses: jetli/wasm-pack-action@v0.4.0
with:
version: v0.10.3
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
# use a separate cache for each job to work around
# https://github.com/Swatinem/rust-cache/issues/124
key: "${{ matrix.cmd }}"
# ... but only save the cache on the main branch
# cf https://github.com/Swatinem/rust-cache/issues/95
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install nextest
uses: taiki-e/install-action@nextest
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-linux }}"
fail-on-cache-miss: true
- name: Rust Check
run: |
target/debug/xtask ci wasm ${{ matrix.cmd }}
- name: Wasm-Pack test
run: |
target/debug/xtask ci wasm-pack ${{ matrix.cmd }}
formatting:
name: Check Formatting
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2023-11-08
components: rustfmt
- name: Cargo fmt
run: |
cargo fmt -- --check
typos:
name: Spell Check with Typos
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout Actions Repository
uses: actions/checkout@v3
- name: Check the spelling of the files in our repo
uses: crate-ci/typos@v1.17.0
clippy:
name: Run clippy
needs: [style]
needs: xtask
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: clippy
profile: minimal
override: true
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all-targets -- -D warnings
- name: Clippy without default features
uses: actions-rs/cargo@v1
with:
command: clippy
# TODO: add `--all-targets` once all warnings in examples are resolved
args: --no-default-features --features native-tls,warp -- -D warnings
check-wasm:
name: linux / WASM
needs: [clippy]
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
profile: minimal
override: true
- name: Install emscripten
uses: mymindstorm/setup-emsdk@v7
- name: Check
run: |
cd matrix_sdk/examples/wasm_command_bot
cargo check --target wasm32-unknown-unknown
test-appservice:
name: ${{ matrix.name }}
needs: [clippy]
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
strategy:
matrix:
name:
- linux / appservice / stable / warp
- macOS / appservice / stable / warp
include:
- name: linux / appservice / stable / warp
cargo_args: --features warp
- name: macOS / appservice / stable / warp
os: macOS-latest
cargo_args: --features warp
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install rust
uses: actions-rs/toolchain@v1
- name: Install protoc
uses: taiki-e/install-action@v2
with:
toolchain: ${{ matrix.rust || 'stable' }}
target: ${{ matrix.target }}
profile: minimal
override: true
tool: protoc@3.20.3
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2023-11-08
components: clippy
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Get xtask
uses: actions/cache/restore@v3
with:
path: target/debug/xtask
key: "${{ needs.xtask.outputs.cachekey-linux }}"
fail-on-cache-miss: true
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path matrix_sdk_appservice/Cargo.toml ${{ matrix.cargo_args }} -- -D warnings
run: |
target/debug/xtask ci clippy
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path matrix_sdk_appservice/Cargo.toml ${{ matrix.cargo_args }}
integration-tests:
name: Integration test
if: github.event_name == 'push' || !github.event.pull_request.draft
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path matrix_sdk_appservice/Cargo.toml ${{ matrix.cargo_args }}
runs-on: ubuntu-latest
test-features:
name: ${{ matrix.name }}
needs: [clippy]
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
strategy:
matrix:
name:
- linux / features-no-encryption
- linux / features-no-sled
- linux / features-no-encryption-and-sled
- linux / features-sled_cryptostore
- linux / features-rustls-tls
- linux / features-markdown
- linux / features-socks
- linux / features-sso_login
- linux / features-require_auth_for_profile_requests
include:
- name: linux / features-no-encryption
cargo_args: --no-default-features --features "sled_state_store, native-tls"
- name: linux / features-no-sled
cargo_args: --no-default-features --features "encryption, native-tls"
- name: linux / features-no-encryption-and-sled
cargo_args: --no-default-features --features "native-tls"
- name: linux / features-sled_cryptostore
cargo_args: --no-default-features --features "encryption, sled_cryptostore, native-tls"
- name: linux / features-rustls-tls
cargo_args: --no-default-features --features rustls-tls
- name: linux / features-require_auth_for_profile_requests
cargo_args: --no-default-features --features "require_auth_for_profile_requests, native-tls"
- name: linux / features-markdown
cargo_args: --features markdown
- name: linux / features-socks
cargo_args: --features socks
- name: linux / features-sso_login
cargo_args: --features sso_login
# run several docker containers with the same networking stack so the hostname 'postgres'
# maps to the postgres container, etc.
services:
# sliding sync needs a postgres container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: syncv3
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432
# run sliding sync and point it at the postgres container and synapse container.
# the postgres container needs to be above this to make sure it has started prior to this service.
slidingsync:
image: "ghcr.io/matrix-org/sliding-sync:v0.99.11" # keep in sync with ./coverage.yml
env:
SYNCV3_SERVER: "http://synapse:8008"
SYNCV3_SECRET: "SUPER_CI_SECRET"
SYNCV3_BINDADDR: ":8118"
SYNCV3_DB: "user=postgres password=postgres dbname=syncv3 sslmode=disable host=postgres"
ports:
- 8118:8118
# tests need a synapse: this is a service and not michaelkaye/setup-matrix-synapse@main as the
# latter does not provide networking for services to communicate with it.
synapse:
image: ghcr.io/matrix-org/synapse-service:v1.94.0 # keep in sync with ./coverage.yml
env:
SYNAPSE_COMPLEMENT_DATABASE: sqlite
SERVER_NAME: synapse
ports:
- 8008:8008
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Checkout the repo
uses: actions/checkout@v3
- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust || 'stable' }}
target: ${{ matrix.target }}
profile: minimal
override: true
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Check
uses: actions-rs/cargo@v1
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
command: check
args: --manifest-path matrix_sdk/Cargo.toml ${{ matrix.cargo_args }}
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install nextest
uses: taiki-e/install-action@nextest
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path matrix_sdk/Cargo.toml ${{ matrix.cargo_args }}
test:
name: ${{ matrix.name }}
needs: [clippy]
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
strategy:
matrix:
name:
- linux / stable
- linux / beta
- macOS / stable
include:
- name: linux / stable
- name: linux / beta
rust: beta
- name: macOS / stable
os: macOS-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust || 'stable' }}
target: ${{ matrix.target }}
profile: minimal
override: true
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
env:
RUST_LOG: "hyper=trace"
HOMESERVER_URL: "http://localhost:8008"
HOMESERVER_DOMAIN: "synapse"
SLIDING_SYNC_PROXY_URL: "http://localhost:8118"
run: |
cargo nextest run -p matrix-sdk-integration-testing
+103 -21
View File
@@ -2,38 +2,120 @@ name: Code coverage
on:
push:
branches: [ master ]
branches: [main]
pull_request:
branches: [main]
types:
- opened
- reopened
- synchronize
- ready_for_review
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
# without matrix_sdk=trace, expressions in `trace!` fields are not evaluated
# when the `trace!` statement is hit, and thus not covered
RUST_LOG: info,matrix_sdk=trace
jobs:
code_coverage:
name: Code Coverage
runs-on: "ubuntu-latest"
if: github.event_name == 'push' || !github.event.pull_request.draft
# run several docker containers with the same networking stack so the hostname 'postgres'
# maps to the postgres container, etc.
services:
# sliding sync needs a postgres container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: syncv3
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432
# run sliding sync and point it at the postgres container and synapse container.
# the postgres container needs to be above this to make sure it has started prior to this service.
slidingsync:
image: "ghcr.io/matrix-org/sliding-sync:v0.99.11" # keep in sync with ./ci.yml
env:
SYNCV3_SERVER: "http://synapse:8008"
SYNCV3_SECRET: "SUPER_CI_SECRET"
SYNCV3_BINDADDR: ":8118"
SYNCV3_DB: "user=postgres password=postgres dbname=syncv3 sslmode=disable host=postgres"
ports:
- 8118:8118
# tests need a synapse: this is a service and not michaelkaye/setup-matrix-synapse@main as the
# latter does not provide networking for services to communicate with it.
synapse:
image: ghcr.io/matrix-org/synapse-service:v1.94.0 # keep in sync with ./ci.yml
env:
SYNAPSE_COMPLEMENT_DATABASE: sqlite
SERVER_NAME: synapse
ports:
- 8008:8008
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install tarpaulin
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-tarpaulin -f
# Cargo config can screw with caching and is only used for alias config
# and extra lints, which we don't care about here
- name: Delete cargo config
run: rm .cargo/config.toml
- name: Run tarpaulin
uses: actions-rs/cargo@v1
with:
command: tarpaulin
args: --ignore-config --exclude-files "matrix_sdk/examples/*,matrix_sdk_common,matrix_sdk_test" --out Xml
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Upload to codecov.io
uses: codecov/codecov-action@v1
- name: Install tarpaulin
uses: taiki-e/install-action@v2
with:
tool: cargo-tarpaulin
# set up backend for integration tests
- uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Run tarpaulin
run: |
rustup run stable cargo tarpaulin \
--skip-clean --profile cov --out xml \
--features experimental-widgets,testing
env:
CARGO_PROFILE_COV_INHERITS: 'dev'
CARGO_PROFILE_COV_DEBUG: 'false'
HOMESERVER_URL: "http://localhost:8008"
HOMESERVER_DOMAIN: "synapse"
SLIDING_SYNC_PROXY_URL: "http://localhost:8118"
- name: Upload to codecov.io
uses: codecov/codecov-action@v3
with:
# Work around frequent upload errors, for runs inside the main repo (not PRs from forks).
# Otherwise not required for public repos.
token: ${{ secrets.CODECOV_UPLOAD_TOKEN }}
# The upload sometimes fails due to https://github.com/codecov/codecov-action/issues/837.
# To make sure that the failure gets flagged clearly in the UI, fail the action.
fail_ci_if_error: true
-37
View File
@@ -1,37 +0,0 @@
name: docs
on:
push:
branches: [master]
pull_request:
jobs:
docs:
name: docs
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
- name: Build docs
uses: actions-rs/cargo@v1
env:
RUSTDOCFLAGS: "--enable-index-page -Zunstable-options"
with:
command: doc
args: --no-deps --workspace --features docs -Zrustdoc-map
- name: Deploy docs
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./target/doc/
+70
View File
@@ -0,0 +1,70 @@
name: Documentation
on:
push:
branches: [main]
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
pages: write
id-token: write
jobs:
docs:
name: All crates
runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install protoc
uses: taiki-e/install-action@v2
with:
tool: protoc@3.20.3
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2023-11-08
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 20
- name: Load cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
# Keep in sync with xtask docs
- name: Build documentation
env:
# Work around https://github.com/rust-lang/cargo/issues/10744
CARGO_TARGET_APPLIES_TO_HOST: "true"
RUSTDOCFLAGS: "--enable-index-page -Zunstable-options --cfg docsrs -Dwarnings"
run:
cargo doc --no-deps --workspace --features docsrs
- name: Upload artifact
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v1
with:
path: './target/doc/'
- name: Deploy to GitHub Pages
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
id: deployment
uses: actions/deploy-pages@v2
+76
View File
@@ -0,0 +1,76 @@
# A reusable github actions workflow that will build xtask, if it is not
# already cached.
#
# It will create a pair of GHA cache entries, if they do not already exist.
# The cache keys take the form `xtask-{os}-{hash}`, where "{os}" is "linux"
# or "macos", and "{hash}" is the hash of the xtask# directory.
#
# The cache keys are written to output variables named "cachekey-{os}".
#
name: Build xtask if necessary
on:
workflow_call:
outputs:
cachekey-linux:
description: "The cache key for the linux build artifact"
value: "${{ jobs.xtask.outputs.cachekey-linux }}"
cachekey-macos:
description: "The cache key for the macos build artifact"
value: "${{ jobs.xtask.outputs.cachekey-macos }}"
env:
CARGO_TERM_COLOR: always
jobs:
xtask:
name: "xtask-${{ matrix.os-name }}"
strategy:
fail-fast: true
matrix:
include:
- os: ubuntu-latest
os-name: 🐧
cachekey-id: linux
- os: macos-12
os-name: 🍏
cachekey-id: macos
runs-on: "${{ matrix.os }}"
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Calculate cache key
id: cachekey
# set a step output variable "cachekey-{os}" that can be referenced in
# the job outputs below.
run: |
echo "cachekey-${{ matrix.cachekey-id }}=xtask-${{ matrix.cachekey-id }}-${{ hashFiles('Cargo.toml', 'xtask/**') }}" >> $GITHUB_OUTPUT
- name: Check xtask cache
uses: actions/cache@v3
id: xtask-cache
with:
path: target/debug/xtask
# use the cache key calculated in the step above. Bit of an awkard
# syntax
key: |
${{ steps.cachekey.outputs[format('cachekey-{0}', matrix.cachekey-id)] }}
- name: Install Rust stable toolchain
if: steps.xtask-cache.outputs.cache-hit != 'true'
uses: dtolnay/rust-toolchain@stable
- name: Build
if: steps.xtask-cache.outputs.cache-hit != 'true'
run: |
cargo build -p xtask
outputs:
"cachekey-linux": "${{ steps.cachekey.outputs.cachekey-linux }}"
"cachekey-macos": "${{ steps.cachekey.outputs.cachekey-macos }}"
+19 -2
View File
@@ -1,4 +1,21 @@
Cargo.lock
target
generated
master.zip
emsdk-*
emsdk-*
.idea/
.env
.build
.swiftpm
/Package.swift
## User settings
xcuserdata/
.vscode/
## OS garbage
.DS_Store
## Kotlin bindings generated files
bindings/kotlin/.gradle/
bindings/kotlin/buildSrc/build/
bindings/kotlin/buildSrc/.gradle/
-29
View File
@@ -1,29 +0,0 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.3
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: local
hooks:
- id: fmt
name: fmt
language: system
types: [file, rust]
entry: cargo fmt -- --check
- id: clippy
name: clippy
language: system
types: [file, rust]
entry: cargo clippy --all-targets --all
pass_filenames: false
- id: test
name: test
language: system
files: '\.rs$'
entry: cargo test --lib
pass_filenames: false
+4
View File
@@ -4,3 +4,7 @@ wrap_comments = true
imports_granularity = "Crate"
use_small_heuristics = "Max"
group_imports = "StdExternalCrate"
format_code_in_doc_comments = true
doc_comment_code_block_width = 80
# Workaround for https://github.com/rust-lang/rust.vim/issues/464
edition = "2021"
+33
View File
@@ -0,0 +1,33 @@
[default]
extend-ignore-re = [
# base 58 strings with spaces every four chars.
# this would also match regular sentence parts with eight or more words of
# exactly four characters in row, but that doesn't really happen.
"[1-9A-Za-z]{4}( [1-9A-Za-z]{4}){7,}",
# some heuristics for base64 strings with no false matches found at the
# time of writing.
"[A-Za-z0-9+=]{72,}",
"([A-Za-z0-9+=]|\\\\\\s\\*){72,}",
"[0-9+][A-Za-z0-9+]{30,}[a-z0-9+]",
"\\$[A-Z0-9+][A-Za-z0-9+]{6,}[a-z0-9+]",
"\\b[a-z0-9+/=][A-Za-z0-9+/=]{7,}[a-z0-9+/=][A-Z]\\b",
]
[default.extend-identifiers]
WeeChat = "WeeChat"
# all of these are valid words, but should never appear in this repo
[default.extend-words]
sing = "sign"
singed = "signed"
singing = "signing"
Nd = "Nd"
[files]
# Our json files contain a bunch of base64 encoded ed25519 keys which aren't
# automatically ignored, we ignore them here.
extend-exclude = [
"*.json",
# We are using some fuzzy match patterns that can be understood as typos confusingly.
"crates/matrix-sdk-ui/tests/integration/room_list_service.rs",
]
+102
View File
@@ -0,0 +1,102 @@
# Contributing to matrix-rust-sdk
## Chat rooms
In addition to our [main Matrix room], we have a development room at
[#matrix-rust-sdk-dev:flipdot.org]. Please use it to discuss potential changes,
the overall direction of development and related topics.
[main Matrix room]: https://matrix.to/#/#matrix-rust-sdk:matrix.org
[#matrix-rust-sdk-dev:flipdot.org]: https://matrix.to/#/#matrix-rust-sdk-dev:flipdot.org
## Testing
You can run most of the tests that also happen in CI also using
`cargo xtask ci`. This needs a few dependencies to be installed, as it also runs
automatic WASM tests:
```bash
rustup component add clippy
cargo install cargo-nextest typos-cli wasm-pack
```
If you want to execute only one part of CI, there are a few sub-commands (see
`cargo xtask ci --help`).
Some tests are not automatically run in `cargo xtask ci`, for example the
integration tests that need a running synapse instance. These tests reside in
`./testing/matrix-sdk-integration-testing`. See its
[README](./testing/matrix-sdk-integration-testing/README.md) to easily set up a
synapse for testing purposes.
## Sign off
In order to have a concrete record that your contribution is intentional
and you agree to license it under the same terms as the project's license, we've
adopted the same lightweight approach that the Linux Kernel
(https://www.kernel.org/doc/Documentation/SubmittingPatches), Docker
(https://github.com/docker/docker/blob/master/CONTRIBUTING.md), and many other
projects use: the DCO (Developer Certificate of Origin:
http://developercertificate.org/). This is a simple declaration that you wrote
the contribution or otherwise have the right to contribute it to Matrix:
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
If you agree to this for your contribution, then all that's needed is to
include the line in your commit or pull request comment:
```
Signed-off-by: Your Name <your@email.example.org>
```
We accept contributions under a legally identifiable name, such as your name on
government documentation or common-law names (names claimed by legitimate usage
or repute). Unfortunately, we cannot accept anonymous contributions at this
time.
Git allows you to add this signoff automatically when using the `-s` flag to
`git commit`, which uses the name and email set in your `user.name` and
`user.email` git configs.
If you forgot to sign off your commits before making your pull request and are
on Git 2.17+ you can mass signoff using rebase:
```
git rebase --signoff origin/main
```
Generated
+6818
View File
File diff suppressed because it is too large Load Diff
+94 -8
View File
@@ -1,11 +1,97 @@
[workspace]
members = [
"matrix_sdk",
"matrix_qrcode",
"matrix_sdk_base",
"matrix_sdk_test",
"matrix_sdk_test_macros",
"matrix_sdk_crypto",
"matrix_sdk_common",
"matrix_sdk_appservice"
"benchmarks",
"bindings/matrix-sdk-crypto-ffi",
"bindings/matrix-sdk-ffi",
"crates/*",
"testing/*",
"examples/*",
"uniffi-bindgen",
"xtask",
]
# xtask, testing and the bindings should only be built when invoked explicitly.
default-members = ["benchmarks", "crates/*"]
resolver = "2"
[workspace.package]
rust-version = "1.70"
[workspace.dependencies]
anyhow = "1.0.68"
assert-json-diff = "2"
assert_matches = "1.5.0"
assert_matches2 = "0.1.1"
async-rx = "0.1.3"
async-stream = "0.3.3"
async-trait = "0.1.60"
as_variant = "1.2.0"
base64 = "0.21.0"
byteorder = "1.4.3"
eyeball = { version = "0.8.7", features = ["tracing"] }
eyeball-im = { version = "0.4.1", features = ["tracing"] }
eyeball-im-util = "0.5.1"
futures-core = "0.3.28"
futures-executor = "0.3.21"
futures-util = { version = "0.3.26", default-features = false, features = ["alloc"] }
http = "0.2.6"
itertools = "0.12.0"
ruma = { version = "0.9.3", features = ["client-api-c", "compat-upload-signatures", "compat-user-id", "compat-arbitrary-length-ids", "unstable-msc3401"] }
ruma-common = "0.12.0"
once_cell = "1.16.0"
rand = "0.8.5"
serde = "1.0.151"
serde_html_form = "0.2.0"
serde_json = "1.0.91"
sha2 = "0.10.8"
stream_assert = "0.1.1"
thiserror = "1.0.38"
tokio = { version = "1.30.0", default-features = false, features = ["sync"] }
tokio-stream = "0.1.14"
tracing = { version = "0.1.40", default-features = false, features = ["std"] }
tracing-core = "0.1.32"
uniffi = { version = "0.25.3", git = "https://github.com/mozilla/uniffi-rs", rev = "0d58c94cbd2ef63554f3388d03d55984be76bb1f" }
uniffi_bindgen = { version = "0.25.3", git = "https://github.com/mozilla/uniffi-rs", rev = "0d58c94cbd2ef63554f3388d03d55984be76bb1f" }
vodozemac = { version = "0.7.0" }
zeroize = "1.6.0"
matrix-sdk = { path = "crates/matrix-sdk", version = "0.7.0", default-features = false }
matrix-sdk-base = { path = "crates/matrix-sdk-base", version = "0.7.0" }
matrix-sdk-common = { path = "crates/matrix-sdk-common", version = "0.7.0" }
matrix-sdk-crypto = { path = "crates/matrix-sdk-crypto", version = "0.7.0" }
matrix-sdk-indexeddb = { path = "crates/matrix-sdk-indexeddb", version = "0.7.0", default-features = false }
matrix-sdk-qrcode = { path = "crates/matrix-sdk-qrcode", version = "0.7.0" }
matrix-sdk-sqlite = { path = "crates/matrix-sdk-sqlite", version = "0.7.0", default-features = false }
matrix-sdk-store-encryption = { path = "crates/matrix-sdk-store-encryption", version = "0.7.0" }
matrix-sdk-test = { path = "testing/matrix-sdk-test", version = "0.7.0" }
matrix-sdk-ui = { path = "crates/matrix-sdk-ui", version = "0.7.0", default-features = false }
# Default release profile, select with `--release`
[profile.release]
lto = true
# Default development profile; default for most Cargo commands, otherwise
# selected with `--debug`
[profile.dev]
# Saves a lot of disk space. If symbols are needed, use the dbg profile.
debug = 0
[profile.dev.package]
# Optimize quote even in debug mode. Speeds up proc-macros enough to account
# for the extra time of optimizing it for a clean build of matrix-sdk-ffi.
quote = { opt-level = 2 }
sha2 = { opt-level = 2 }
# Custom profile with full debugging info, use `--profile dbg` to select
[profile.dbg]
inherits = "dev"
debug = 2
# Custom profile for use in (debug) builds of the binding crates, use
# `--profile reldbg` to select
[profile.reldbg]
inherits = "dbg"
opt-level = 3
[patch.crates-io]
async-compat = { git = "https://github.com/jplatte/async-compat", rev = "16dc8597ec09a6102d58d4e7b67714a35dd0ecb8" }
const_panic = { git = "https://github.com/jplatte/const_panic", rev = "9024a4cb3eac45c1d2d980f17aaee287b17be498" }
-17
View File
@@ -1,17 +0,0 @@
all: build
build:
cargo build
test:
cargo test
coverage:
cargo tarpaulin -v
clean:
cargo clean
format:
cargo fmt
.PHONY: clean test coverage
+13 -3
View File
@@ -1,8 +1,8 @@
![Build Status](https://img.shields.io/github/workflow/status/matrix-org/matrix-rust-sdk/CI?style=flat-square)
[![codecov](https://img.shields.io/codecov/c/github/matrix-org/matrix-rust-sdk/master.svg?style=flat-square)](https://codecov.io/gh/matrix-org/matrix-rust-sdk)
![Build Status](https://img.shields.io/github/actions/workflow/status/matrix-org/matrix-rust-sdk/ci.yml?style=flat-square)
[![codecov](https://img.shields.io/codecov/c/github/matrix-org/matrix-rust-sdk/main.svg?style=flat-square)](https://codecov.io/gh/matrix-org/matrix-rust-sdk)
[![License](https://img.shields.io/badge/License-Apache%202.0-yellowgreen.svg?style=flat-square)](https://opensource.org/licenses/Apache-2.0)
[![#matrix-rust-sdk](https://img.shields.io/badge/matrix-%23matrix--rust--sdk-blue?style=flat-square)](https://matrix.to/#/#matrix-rust-sdk:matrix.org)
[![Docs - Master](https://img.shields.io/badge/docs-master-blue.svg?style=flat-square)](https://matrix-org.github.io/matrix-rust-sdk/)
[![Docs - Main](https://img.shields.io/badge/docs-main-blue.svg?style=flat-square)](https://matrix-org.github.io/matrix-rust-sdk/matrix_sdk/)
[![Docs - Stable](https://img.shields.io/crates/v/matrix-sdk?color=blue&label=docs&style=flat-square)](https://docs.rs/matrix-sdk)
# matrix-rust-sdk
@@ -24,6 +24,10 @@ The rust-sdk consists of multiple crates that can be picked at your convenience:
- **matrix-sdk-crypto** - No (network) IO encryption state machine that can be
used to add Matrix E2EE support to your client or client library.
## Minimum Supported Rust Version (MSRV)
These crates are built with the Rust language version 2021 and require a minimum compiler version of `1.70`.
## Status
The library is in an alpha state, things that are implemented generally work but
@@ -32,6 +36,12 @@ the API will change in breaking ways.
If you are interested in using the matrix-sdk now is the time to try it out and
provide feedback.
## Bindings
Some crates of the **matrix-rust-sdk** can be embedded inside other
environments, like Swift, Kotlin, JavaScript, Node.js etc. Please,
explore the [`bindings/`](./bindings/) directory to learn more.
## License
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)
+121
View File
@@ -0,0 +1,121 @@
# Upgrades 0.5 ➜ 0.6
This is a rough migration guide to help you upgrade your code using matrix-sdk 0.5 to the newly released matrix-sdk 0.6 . While it won't cover all edge cases and problems, we are trying to get the most common issues covered. If you experience any other difficulties in upgrade or need support with using the matrix-sdk in general, please approach us in our [matrix-sdk channel on matrix.org][matrix-channel].
## Minimum Supported Rust Version Update: `1.60`
We have updated the minimal rust version you need in order to build `matrix-sdk`, as we require some new dependency resolving features from it:
> These crates are built with the Rust language version 2021 and require a minimum compiler version of 1.60
## Dependencies
Many dependencies have been upgraded. Most notably, we are using `ruma` at version `0.7.0` now. It has seen some renamings and restructurings since our last release, so you might find that some Types have new names now.
## Repo Structure Updates
If you are looking at the repository itself, you will find we've rearranged the code quite a bit: we have split out any bindings-specific and testing related crates (and other things) into respective folders, and we've moved all `examples` into its own top-level-folder with each example as their own crate (rendering them easier to find and copy as starting points), all in all slimming down the `crates` folder to the core aspects.
## Architecture Changes / API overall
### Builder Pattern
We are moving to the [builder pattern][] (familiar from e.g. `std::io:process:Command`) as the main configurable path for many aspects of the API, including to construct Matrix-Requests and workflows. This has been and is an on-going effort, and this release sees a lot of APIs transitioning to this pattern, you should already be familiar with from the `matrix_sdk::Client::builder()` in `0.5`. This pattern been extended onto:
- the [login configuration][login builder] and [login with sso][ssologin builder],
- [`SledStore` configuratiion][sled-store builder]
- [`Indexeddb` configuration][indexeddb builder]
Most have fallback (though maybe with deprecation warning) support for an existing code path, but these are likely to be removed in upcoming releases.
### Splitting of concerns: Media
In an effort to declutter the `Client` API dedicated types have been created dealing with specific concerns in one place. In `0.5` we introduced `client.account()`, and `client.encryption()`, we are doing the same with `client.media()` to manage media and attachments in one place with the [`media::Media` type][media typ] now.
The signatures of media uploads, have also changed slightly: rather than expecting a reader `R: Read + Seek`, it now is a simple `&[u8]`. Which also means no more unnecessary `seek(0)` to reset the cursor, as we are just taking an immutable reference now.
### Event Handling & sync updaes
If you are using the `client.register_event_handler` function to receive updates on incoming sync events, you'll find yourself with a deprecation warning now. That is because we've refactored and redesigned the event handler logic to allowing `removing` of event handlers on the fly, too. For that the new `add_event_handler()` (and `add_room_event_handler`) will hand you an `EventHandlerHandle` (pardon the pun), which you can pass to `remove_event_handler`, or by using the convenient `client.event_handler_drop_guard` to create a `DropGuard` that will remove the handler when the guard is dropped. While the code still works, we recommend you switch to the new one, as we will be removing the `register_event_handler` and `register_event_handler_context` in a coming release.
Secondly, you will find a new [`sync_with_result_callback` sync function][sync with result]. Other than the previous sync functions, this will pass the entire `Result` to your callback, allowing you to handle errors or even raise some yourself to stop the loop. Further more, it will propagate any unhandled errors (it still handles retries as before) to the outer caller, allowing the higher level to decide how to handle that (e.g. in case of a network failure). This result-returning-behavior also punshes through the existing `sync` and `sync_with_callback`-API, allowing you to handle them on a higher level now (rather than the futures just resolving). If you find that warning, just adding a `?` to the `.await` of the call is probably the quickest way to move forward.
### Refresh Tokens
This release now [supports `refresh_token`s][refresh tokens PR] as part of the [`Session`][session]. It is implemented with a default-flag in serde so deserializing a previously serialized Session (e.g. in a store) will work as before. As part of `refresh_token` support, you can now configure the client via `ClientBuilder.request_refresh_token()` to refresh the access token automagically on certain failures or do it manually by calling `client.refresh_access_token()` yourself. Auto-refresh is _off_ by default.
You can stay informed about updates on the access token by listening to `client.session_tokens_signal()`.
### Further changes
- [`MessageOptions`][message options] has been updated to Matrix 1.3 by making the `from` parameter optional (and function signatures have been updated, too). You can now request the server sends you messages from the first one you are allowed to have received.
- `client.user_id()` is not a `future` anymore. Remove any `.await` you had behind it.
- `verified()`, `blacklisted()` and `deleted()` on `matrix_sdk::encryption::identities::Device` have been renamed with a `is_` prefix.
- `verified()` on `matrix_sdk::encryption::identities::UserIdentity`, too has been prefixed with `is_` and thus is now called `is_verified()`.
- The top-level crypto and state-store types of Indexeddb and Sled have been renamed to unique types>
- `state_store` and `crypto_store` do not need to be boxed anymore when passed to the [`StoreConfig`][store config]
- Indexeddb's `SerializationError` is now `IndexedDBStoreError`
- Javascript specific features are now behind the `js` feature-gate
- The new experimental next generation of sync ("sliding sync"), with a totally revamped api, can be found behind the optional `sliding-sync`-feature-gate
## Quick Troubleshooting
You find yourself focused with any of these, here are the steps to follow to upgrade your code accordingly:
### warning: use of deprecated associated function `matrix_sdk::Client::register_event_handler`: Use [`Client::add_event_handler`](#method.add_event_handler) instead
As it says on the tin: we have deprecated this function in favor of the newer removable handler approach (see above). You can still continue to use this `fn` for now, but it will be removed in a future release.
### warning: use of deprecated associated function `matrix_sdk::Client::login`: Replaced by [`Client::login_username`](#method.login_username)
We have replaced the login facilities with a `LoginBuilder` and recommend you use that from now on. This isn't an error yet, but the function will be removed in a future release.
### expected slice `[u8]`, found struct ...
We've updated the `send_attachment` and `Media` signatures to use `&[u8]` rather than `reader: Read + Seek` as it is more convenient and common place for most architectures anyways. If you are using `File::open(path)?` to get that handler, you can just replace that with `std::fs::read(path)?`
### no method named `verified` found for struct `matrix_sdk::encryption::identities::Device` in the current scope
Boolean flags like `verified`, `deleted`, `blacklisted`, etc have been renamed with a `is_` prefix. So, just follow the cargo suggestion:
```
|
69 | device.verified()
| ^^^^^^^^ help: there is an associated function with a similar name: `is_verified`
```
### unresolved import `matrix_sdk::ruma::events::AnySyncRoomEvent`
Ruma has been updated to `0.7.0`, you will find some ruma Events names have changed, most notably, the `AnySyncRoomEvent` is now named `AnySyncTimelineEvent` (and not `AnySyncStateEvent`, which cargo wrongly suggests). Just rename the import and usage of it.
### `std::option::Option<&matrix_sdk::ruma::UserId>` is not a future
You are seeing something along the lines of:
```
19 | if room_member.state_key != client.user_id().await.unwrap() {
| ^^^^^^ `std::option::Option<&matrix_sdk::ruma::UserId>` is not a future
|
= help: the trait `Future` is not implemented for `std::option::Option<&matrix_sdk::ruma::UserId>`
= note: std::option::Option<&matrix_sdk::ruma::UserId> must be a future or must implement `IntoFuture` to be awaited
= note: required because of the requirements on the impl of `IntoFuture` for `std::option::Option<&matrix_sdk::ruma::UserId>`
help: remove the `.await`
|
19 - if room_member.state_key != client.user_id().await.unwrap() {
19 + if room_member.state_key != client.user_id().unwrap() {
```
You are using `client.user_id().await` but `user_id()` is no longer `async`. Just follow the cargo suggestion and remove the `.await`, it is not necessary any longer.
[matrix-channel]: https://matrix.to/#/#matrix-rust-sdk:matrix.org
[builder pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
[login builder]: https://docs.rs/matrix-sdk/latest/matrix_sdk/struct.LoginBuilder.html
[ssologin builder]: https://docs.rs/matrix-sdk/latest/matrix_sdk/struct.SsoLoginBuilder.html
[sled-store builder]: https://docs.rs/matrix-sdk-sled/latest/matrix_sdk_sled/struct.SledStateStoreBuilder.html
[indexeddb builder]: https://docs.rs/matrix-sdk-indexeddb/latest/matrix_sdk_indexeddb/struct.IndexeddbStateStoreBuilder.html
[media type]: https://docs.rs/matrix-sdk/latest/matrix_sdk//media/struct.Media.html
[sync with result]: https://docs.rs/matrix-sdk/latest/matrix_sdk/struct.Client.html#method.sync_with_result_callback
[session]: https://docs.rs/matrix-sdk/latest/matrix_sdk/struct.Session.html
[refresh tokens PR]: https://github.com/matrix-org/matrix-rust-sdk/pull/892
[store config]: https://docs.rs/matrix-sdk-base/latest/matrix_sdk_base/store/struct.StoreConfig.html
[message options]: https://docs.rs/matrix-sdk/latest/matrix_sdk/room/struct.MessagesOptions.html
+31
View File
@@ -0,0 +1,31 @@
[package]
name = "benchmarks"
description = "Matrix SDK benchmarks"
edition = "2021"
license = "Apache-2.0"
rust-version = { workspace = true }
version = "1.0.0"
publish = false
[dependencies]
criterion = { version = "0.5.1", features = ["async", "async_tokio", "html_reports"] }
matrix-sdk-base = { workspace = true }
matrix-sdk-crypto = { workspace = true }
matrix-sdk-sqlite = { workspace = true, features = ["crypto-store"] }
matrix-sdk-test = { workspace = true }
matrix-sdk = { workspace = true }
ruma = { workspace = true }
serde_json = { workspace = true }
tempfile = "3.3.0"
tokio = { version = "1.24.2", default-features = false, features = ["rt-multi-thread"] }
[target.'cfg(target_os = "linux")'.dependencies]
pprof = { version = "0.13.0", features = ["flamegraph", "criterion"] }
[[bench]]
name = "crypto_bench"
harness = false
[[bench]]
name = "store_bench"
harness = false
@@ -57,7 +57,7 @@ $ cargo bench --bench crypto_bench -- --baseline libolm
The benchmarks support profiling and generating [Flame Graphs] while they run in
profiling mode using [pprof].
Profiling usually requieres root permissions, to avoid the need for root
Profiling usually requires root permissions, to avoid the need for root
permissions you can adjust the value of `perf_event_paranoid`, e.g. the most
permisive value is `-1`:
+306
View File
@@ -0,0 +1,306 @@
use std::{ops::Deref, sync::Arc};
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput};
use matrix_sdk_crypto::{EncryptionSettings, OlmMachine};
use matrix_sdk_sqlite::SqliteCryptoStore;
use matrix_sdk_test::response_from_file;
use ruma::{
api::{
client::{
keys::{claim_keys, get_keys},
to_device::send_event_to_device::v3::Response as ToDeviceResponse,
},
IncomingResponse,
},
device_id, room_id, user_id, DeviceId, OwnedUserId, TransactionId, UserId,
};
use serde_json::Value;
use tokio::runtime::Builder;
fn alice_id() -> &'static UserId {
user_id!("@alice:example.org")
}
fn alice_device_id() -> &'static DeviceId {
device_id!("JLAFKJWSCS")
}
fn keys_query_response() -> get_keys::v3::Response {
let data = include_bytes!("crypto_bench/keys_query.json");
let data: Value = serde_json::from_slice(data).unwrap();
let data = response_from_file(&data);
get_keys::v3::Response::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
fn keys_claim_response() -> claim_keys::v3::Response {
let data = include_bytes!("crypto_bench/keys_claim.json");
let data: Value = serde_json::from_slice(data).unwrap();
let data = response_from_file(&data);
claim_keys::v3::Response::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
fn huge_keys_query_response() -> get_keys::v3::Response {
let data = include_bytes!("crypto_bench/keys_query_2000_members.json");
let data: Value = serde_json::from_slice(data).unwrap();
let data = response_from_file(&data);
get_keys::v3::Response::try_from_http_response(data)
.expect("Can't parse the `/keys/query` response")
}
pub fn keys_query(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
let machine = runtime.block_on(OlmMachine::new(alice_id(), alice_device_id()));
let response = keys_query_response();
let txn_id = TransactionId::new();
let count = response.device_keys.values().fold(0, |acc, d| acc + d.len())
+ response.master_keys.len()
+ response.self_signing_keys.len()
+ response.user_signing_keys.len();
let mut group = c.benchmark_group("Keys querying");
group.throughput(Throughput::Elements(count as u64));
let name = format!("{count} device and cross signing keys");
// Benchmark memory store.
group.bench_with_input(BenchmarkId::new("memory store", &name), &response, |b, response| {
b.to_async(&runtime)
.iter(|| async { machine.mark_request_as_sent(&txn_id, response).await.unwrap() })
});
// Benchmark sqlite store.
let dir = tempfile::tempdir().unwrap();
let store = Arc::new(runtime.block_on(SqliteCryptoStore::open(dir.path(), None)).unwrap());
let machine =
runtime.block_on(OlmMachine::with_store(alice_id(), alice_device_id(), store)).unwrap();
group.bench_with_input(BenchmarkId::new("sqlite store", &name), &response, |b, response| {
b.to_async(&runtime)
.iter(|| async { machine.mark_request_as_sent(&txn_id, response).await.unwrap() })
});
{
let _guard = runtime.enter();
drop(machine);
}
group.finish()
}
pub fn keys_claiming(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
let keys_query_response = keys_query_response();
let txn_id = TransactionId::new();
let response = keys_claim_response();
let count = response.one_time_keys.values().fold(0, |acc, d| acc + d.len());
let mut group = c.benchmark_group("Olm session creation");
group.throughput(Throughput::Elements(count as u64));
let name = format!("{count} one-time keys");
group.bench_with_input(BenchmarkId::new("memory store", &name), &response, |b, response| {
b.iter_batched(
|| {
let machine = runtime.block_on(OlmMachine::new(alice_id(), alice_device_id()));
runtime
.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response))
.unwrap();
(machine, &runtime, &txn_id)
},
move |(machine, runtime, txn_id)| {
runtime.block_on(async {
machine.mark_request_as_sent(txn_id, response).await.unwrap();
drop(machine);
})
},
BatchSize::SmallInput,
)
});
group.bench_with_input(BenchmarkId::new("sqlite store", &name), &response, |b, response| {
b.iter_batched(
|| {
let dir = tempfile::tempdir().unwrap();
let store =
Arc::new(runtime.block_on(SqliteCryptoStore::open(dir.path(), None)).unwrap());
let machine = runtime
.block_on(OlmMachine::with_store(alice_id(), alice_device_id(), store))
.unwrap();
runtime
.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response))
.unwrap();
(machine, &runtime, &txn_id)
},
move |(machine, runtime, txn_id)| {
runtime.block_on(async {
machine.mark_request_as_sent(txn_id, response).await.unwrap();
drop(machine)
})
},
BatchSize::SmallInput,
)
});
group.finish()
}
pub fn room_key_sharing(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
let keys_query_response = keys_query_response();
let txn_id = TransactionId::new();
let response = keys_claim_response();
let room_id = room_id!("!test:localhost");
let to_device_response = ToDeviceResponse::new();
let users: Vec<OwnedUserId> = keys_query_response.device_keys.keys().cloned().collect();
let count = response.one_time_keys.values().fold(0, |acc, d| acc + d.len());
let machine = runtime.block_on(OlmMachine::new(alice_id(), alice_device_id()));
runtime.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response)).unwrap();
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
let mut group = c.benchmark_group("Room key sharing");
group.throughput(Throughput::Elements(count as u64));
let name = format!("{count} devices");
// Benchmark memory store.
group.bench_function(BenchmarkId::new("memory store", &name), |b| {
b.to_async(&runtime).iter(|| async {
let requests = machine
.share_room_key(
room_id,
users.iter().map(Deref::deref),
EncryptionSettings::default(),
)
.await
.unwrap();
assert!(!requests.is_empty());
for request in requests {
machine.mark_request_as_sent(&request.txn_id, &to_device_response).await.unwrap();
}
machine.invalidate_group_session(room_id).await.unwrap();
})
});
// Benchmark sqlite store.
let dir = tempfile::tempdir().unwrap();
let store = Arc::new(runtime.block_on(SqliteCryptoStore::open(dir.path(), None)).unwrap());
let machine =
runtime.block_on(OlmMachine::with_store(alice_id(), alice_device_id(), store)).unwrap();
runtime.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response)).unwrap();
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
group.bench_function(BenchmarkId::new("sqlite store", &name), |b| {
b.to_async(&runtime).iter(|| async {
let requests = machine
.share_room_key(
room_id,
users.iter().map(Deref::deref),
EncryptionSettings::default(),
)
.await
.unwrap();
assert!(!requests.is_empty());
for request in requests {
machine.mark_request_as_sent(&request.txn_id, &to_device_response).await.unwrap();
}
machine.invalidate_group_session(room_id).await.unwrap();
})
});
{
let _guard = runtime.enter();
drop(machine);
}
group.finish()
}
pub fn devices_missing_sessions_collecting(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
let machine = runtime.block_on(OlmMachine::new(alice_id(), alice_device_id()));
let response = huge_keys_query_response();
let txn_id = TransactionId::new();
let users: Vec<OwnedUserId> = response.device_keys.keys().cloned().collect();
let count = response.device_keys.values().fold(0, |acc, d| acc + d.len());
let mut group = c.benchmark_group("Devices missing sessions collecting");
group.throughput(Throughput::Elements(count as u64));
let name = format!("{count} devices");
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
// Benchmark memory store.
group.bench_function(BenchmarkId::new("memory store", &name), |b| {
b.to_async(&runtime).iter_with_large_drop(|| async {
machine.get_missing_sessions(users.iter().map(Deref::deref)).await.unwrap()
})
});
// Benchmark sqlite store.
let dir = tempfile::tempdir().unwrap();
let store = Arc::new(runtime.block_on(SqliteCryptoStore::open(dir.path(), None)).unwrap());
let machine =
runtime.block_on(OlmMachine::with_store(alice_id(), alice_device_id(), store)).unwrap();
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
group.bench_function(BenchmarkId::new("sqlite store", &name), |b| {
b.to_async(&runtime).iter(|| async {
machine.get_missing_sessions(users.iter().map(Deref::deref)).await.unwrap()
})
});
{
let _guard = runtime.enter();
drop(machine);
}
group.finish()
}
fn criterion() -> Criterion {
#[cfg(target_os = "linux")]
let criterion = Criterion::default().with_profiler(pprof::criterion::PProfProfiler::new(
100,
pprof::criterion::Output::Flamegraph(None),
));
#[cfg(not(target_os = "linux"))]
let criterion = Criterion::default();
criterion
}
criterion_group! {
name = benches;
config = criterion();
targets = keys_query, keys_claiming, room_key_sharing, devices_missing_sessions_collecting,
}
criterion_main!(benches);
+125
View File
@@ -0,0 +1,125 @@
use std::sync::Arc;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use matrix_sdk::{
config::StoreConfig,
matrix_auth::{MatrixSession, MatrixSessionTokens},
Client, RoomInfo, RoomState, StateChanges,
};
use matrix_sdk_base::{store::MemoryStore, SessionMeta, StateStore as _};
use matrix_sdk_sqlite::SqliteStateStore;
use ruma::{device_id, user_id, RoomId};
use tokio::runtime::Builder;
fn criterion() -> Criterion {
#[cfg(target_os = "linux")]
let criterion = Criterion::default().with_profiler(pprof::criterion::PProfProfiler::new(
100,
pprof::criterion::Output::Flamegraph(None),
));
#[cfg(not(target_os = "linux"))]
let criterion = Criterion::default();
criterion
}
/// Number of joined rooms in the benchmark.
const NUM_JOINED_ROOMS: usize = 10000;
/// Number of stripped rooms in the benchmark.
const NUM_STRIPPED_JOINED_ROOMS: usize = 10000;
pub fn restore_session(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
// Create a fake list of changes, and a session to recover from.
let mut changes = StateChanges::default();
for i in 0..NUM_JOINED_ROOMS {
let room_id = RoomId::parse(format!("!room{i}:example.com")).unwrap().to_owned();
changes.add_room(RoomInfo::new(&room_id, RoomState::Joined));
}
for i in 0..NUM_STRIPPED_JOINED_ROOMS {
let room_id = RoomId::parse(format!("!strippedroom{i}:example.com")).unwrap().to_owned();
changes.add_room(RoomInfo::new(&room_id, RoomState::Invited));
}
let session = MatrixSession {
meta: SessionMeta {
user_id: user_id!("@somebody:example.com").to_owned(),
device_id: device_id!("DEVICE_ID").to_owned(),
},
tokens: MatrixSessionTokens { access_token: "OHEY".to_owned(), refresh_token: None },
};
// Start the benchmark.
let mut group = c.benchmark_group("Client reload");
group.throughput(Throughput::Elements(100));
const NAME: &str = "restore a session";
// Memory
let mem_store = Arc::new(MemoryStore::new());
runtime.block_on(mem_store.save_changes(&changes)).expect("initial filling of mem failed");
group.bench_with_input(BenchmarkId::new("memory store", NAME), &mem_store, |b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client.restore_session(session.clone()).await.expect("couldn't restore session");
})
});
for encryption_password in [None, Some("hunter2")] {
let encrypted_suffix = if encryption_password.is_some() { "encrypted" } else { "clear" };
// Sqlite
let sqlite_dir = tempfile::tempdir().unwrap();
let sqlite_store = runtime
.block_on(SqliteStateStore::open(sqlite_dir.path(), encryption_password))
.unwrap();
runtime
.block_on(sqlite_store.save_changes(&changes))
.expect("initial filling of sqlite failed");
group.bench_with_input(
BenchmarkId::new(format!("sqlite store {encrypted_suffix}"), NAME),
&sqlite_store,
|b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client
.restore_session(session.clone())
.await
.expect("couldn't restore session");
})
},
);
{
let _guard = runtime.enter();
drop(sqlite_store);
}
}
group.finish()
}
criterion_group! {
name = benches;
config = criterion();
targets = restore_session
}
criterion_main!(benches);
+41
View File
@@ -0,0 +1,41 @@
## Introduction
**matrix-rust-sdk** leverages [UniFFI](https://mozilla.github.io/uniffi-rs/) to generate bindings for host languages (eg. Swift and Kotlin).
Rust code related with bindings live in the [matrix-rust-sdk/bindings](https://github.com/matrix-org/matrix-rust-sdk/tree/main/bindings) folder.
Developers can expose Rust code to UniFFI using two different approaches:
- Using an `.udl` file. When a crate has one, you find it under the `src` folder (an example is [here](https://github.com/matrix-org/matrix-rust-sdk/blob/main/bindings/matrix-sdk-ffi/src/api.udl)).
- Add UniFFI directivies as Rust attributes. In this case Rust source files (`.rs`) contain attributes related to UniFFI (e.g. `#[uniffi::export]`). Attributes are preferred, where applicable.
## Expose Rust definitions to UniFFI
### Check if the API is already on UniFFI
First of all check if the Rust definition you are looking for exists on UniFFI already. Most of exposed matrix definitions are collected in the crate [matrix-sdk-ffi](https://github.com/matrix-org/matrix-rust-sdk/tree/main/bindings/matrix-sdk-ffi).
This crate contains mainly small Rust wrappers around the actual Rust SDK (e.g. the crate [matrix-sdk](https://github.com/matrix-org/matrix-rust-sdk/tree/main/crates/matrix-sdk))
If the Rust definition is on UniFFI already, you either:
- find it in a `.udl` file like [matrix-sdk-ffi/src/api.udl](https://github.com/matrix-org/matrix-rust-sdk/blob/main/bindings/matrix-sdk-ffi/src/api.udl)
- see it marked with a proper UniFFI Rust attribute like this `#[uniffi::export]`
### Adding a missing matrix API
1. Unless you want to contribute on the crypto side, you probably need to add some code in the [matrix-sdk-ffi](https://github.com/matrix-org/matrix-rust-sdk/tree/main/bindings/matrix-sdk-ffi) crate. After you find the crate you need to understand which file is best to contain the new Rust definition. When exposing new matrix API often (but not always) you need to touch the file [client.rs](https://github.com/matrix-org/matrix-rust-sdk/blob/main/bindings/matrix-sdk-ffi/src/client.rs)
2. Identify the API to expose in the target Rust crate (typically in [matrix-sdk](https://github.com/matrix-org/matrix-rust-sdk/tree/main/crates/matrix-sdk). If you cant find it, you probably need to touch the actual Rust SDK as well. In this case you typically just need to write some code around [ruma](https://github.com/ruma/ruma) (a Rust SDKs dependency) which already implements most of the matrix protocol
3. After you got (by finding or writing) the required Rust code, you need to expose to UniFFI. To do that just write a small Rust wrapper in the related UniFFI crate (most of the time is **matrix-sdk-ffi**) you found on step 1.
4. When your new (wrapping) Rust definition is ready, remember to expose it to UniFFI.
Its best to do it using UniFFI Rust attributes (e.g. `#[uniffi::export]`). Otherwise add the new definition in the crates `.udl` file. For the **matrix-sdk-ffi** crate the definition file is [api.udl](https://github.com/matrix-org/matrix-rust-sdk/blob/main/bindings/matrix-sdk-ffi/src/api.udl). **Remember**: the language inside a `.udl` file isnt Rust. To learn more about how map Rust into UDL read [here](https://mozilla.github.io/uniffi-rs/udl_file_spec.html)
## FAQ
**Q**: I wrote my Rust code and exposed it to UniFFI. How can I check if the compiler is happy?\
**A**: Run `cargo build` in the crate you touched (e.g. matrix-sdk-ffi). The compiler will complain if the Rust code and/or the `.udl` is wrong.
**Q**: The compiler is happy with my code but the CI is failing on GitHub. How can I fix it?\
**A**: The CI may fail for different reasons, you need to have a look on the failing GitHub workflow. One common reason though is that the linter ([Clippy](https://github.com/rust-lang/rust-clippy)) isnt happy with your code. If this is the case, you can run `cargo clippy` in the crate you touched to see whats wrong and fix it accordingly.
+30
View File
@@ -0,0 +1,30 @@
# Matrix Rust SDK bindings
In this directory, one can find bindings to the Rust SDK that are
maintained by the owners of the Matrix Rust SDK project.
* [`apple`] or `matrix-rust-components-swift`, Swift bindings of the
[`matrix-sdk`] crate via [`matrix-sdk-ffi`],
* [`matrix-sdk-crypto-ffi`], UniFFI (Kotlin, Swift, Python, Ruby) bindings of the [`matrix-sdk-crypto`]
crate,
* [`matrix-sdk-ffi`], UniFFI bindings of the [`matrix-sdk`] crate.
There are also external bindings in other repositories:
* [`matrix-sdk-crypto-js`], JavaScript bindings of the
[`matrix-sdk-crypto`] crate,
* [`matrix-sdk-crypto-nodejs`], Node.js bindings of the
[`matrix-sdk-crypto`] crate
[`apple`]: ./apple
[`matrix-sdk-crypto-ffi`]: ./matrix-sdk-crypto-ffi
[`matrix-sdk-crypto`]: ../crates/matrix-sdk-crypto
[`matrix-sdk-ffi`]: ./matrix-sdk-ffi
[`matrix-sdk`]: ../crates/matrix-sdk
[`matrix-sdk-crypto-js`]: https://github.com/matrix-org/matrix-rust-sdk-crypto-web
[`matrix-sdk-crypto-nodejs`]: https://github.com/matrix-org/matrix-rust-sdk-crypto-nodejs
## Contributing
To contribute read this [guide](./CONTRIBUTING.md).
+8
View File
@@ -0,0 +1,8 @@
// swift-tools-version:5.6
// A package manifest for local development. This file will be copied
// into the root of the repo when generating an XCFramework.
import PackageDescription
let package = Package()
+24
View File
@@ -0,0 +1,24 @@
// swift-tools-version:5.6
// A package manifest for local development. This file will be copied
// into the root of the repo when generating an XCFramework.
import PackageDescription
let package = Package(
name: "MatrixRustSDK",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(name: "MatrixRustSDK",
targets: ["MatrixRustSDK"]),
],
targets: [
.binaryTarget(name: "MatrixSDKFFI", path: "bindings/apple/generated/MatrixSDKFFI.xcframework"),
.target(name: "MatrixRustSDK",
dependencies: [.target(name: "MatrixSDKFFI")],
path: "bindings/apple/generated/swift")
]
)
@@ -0,0 +1,21 @@
# Podspec file for local-development only, which points to local version of generated framework instead of github release
# To use this, the file needs to be copied to the root of `matrix-rust-sdk` in order to have access to the source files.`
Pod::Spec.new do |s|
s.name = "MatrixSDKCrypto"
s.version = "0.0.1"
s.summary = "Uniffi based bindings for the Rust SDK crypto crate."
s.homepage = "https://github.com/matrix-org/matrix-rust-sdk"
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" }
s.author = { "matrix.org" => "support@matrix.org" }
s.ios.deployment_target = "11.0"
s.osx.deployment_target = "10.10"
s.swift_versions = ['5.1', '5.2']
s.source = { :git => "Not Published", :tag => "Cocoapods/#{s.name}/#{s.version}" }
s.vendored_frameworks = "generated/MatrixSDKCryptoFFI.xcframework"
s.source_files = "generated/Sources/**/*.{swift}"
s.resources = ["bindings/matrix-sdk-crypto-ffi/src/**/*.rs", "crates/matrix-sdk-crypto/src/**/*.rs"]
end
+19
View File
@@ -0,0 +1,19 @@
Pod::Spec.new do |s|
s.name = "MatrixSDKCrypto"
s.version = "0.0.1" # Version is only incremented manually and locally before pushing to CocoaPods
s.summary = "Uniffi based bindings for the Rust SDK crypto crate."
s.homepage = "https://github.com/matrix-org/matrix-rust-sdk"
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" }
s.author = { "matrix.org" => "support@matrix.org" }
s.ios.deployment_target = "11.0"
s.osx.deployment_target = "10.10"
s.swift_versions = ['5.0']
s.source = { :http => "https://github.com/matrix-org/matrix-rust-sdk/releases/download/matrix-sdk-crypto-ffi-#{s.version}/MatrixSDKCryptoFFI.zip" }
s.vendored_frameworks = "MatrixSDKCryptoFFI.xcframework"
s.source_files = "Sources/**/*.{swift}"
end
+33
View File
@@ -0,0 +1,33 @@
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "MatrixRustSDK",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(name: "MatrixRustSDK",
targets: ["MatrixRustSDK"]),
],
targets: [
.target(name: "MatrixRustSDK",
path: "generated/swift",
swiftSettings: [
.unsafeFlags(["-I", "./generated/matrix_sdk_ffi"])
]),
.testTarget(name: "MatrixRustSDKTests",
dependencies: ["MatrixRustSDK"],
swiftSettings: [
.unsafeFlags(["-I", "./generated/matrix_sdk_ffi"])
],
linkerSettings: [
.linkedLibrary("matrix_sdk_ffi", .when(platforms: [.macOS])),
.linkedLibrary("matrix_sdk_ffiFFI", .when(platforms: [.linux])),
.unsafeFlags(["-L./generated/matrix_sdk_ffi"])
])
]
)
+73
View File
@@ -0,0 +1,73 @@
# Apple platforms support
This project and build script demonstrate how to create an XCFramework that can be imported into an Xcode project and run on Apple platforms. It can compile and bundle an [entire SDK](#Building-the-SDK), or only a smaller [Crypto module](#Building-only-the-Crypto-SDK) that provides end-to-end encryption for clients that already depend on an SDK (e.g. [Matrix iOS SDK](https://github.com/matrix-org/matrix-ios-sdk))
## Building
### Prerequisites for building universal frameworks
- the Rust toolchain
- Apple targets (e.g. `rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios aarch64-apple-darwin x86_64-apple-darwin`)
- `xcodebuild` command line tool from [Apple](https://developer.apple.com/library/archive/technotes/tn2339/_index.html)
- `lipo` for creating the fat static libs
### Building the SDK
```
cargo xtask swift build-framework
```
The `build-framework` task will go through all the steps required to generate a fully usable `.xcframework`:
1. compile `matrix-sdk-ffi` libraries for iOS, the iOS simulator and macOS under `/target`. Some targets are not part of the standard library and they will be built using the nightly toolchain.
2. `lipo` together the libraries for the same platform under `/generated`
3. run `uniffi` and generate the C header, module map and swift files
4. `xcodebuild` an `xcframework` from the fat static libs and the original iOS one, and add the header and module map to it under `generated/MatrixSDKFFI.xcframework`
5. cleanup and delete the generated files except the .xcframework and the swift sources (that aren't part of the framework)
For development purposes, it will additionally generate a `Package.swift` file in the root of the repo that can be used to add the framework to your project and enable debugging through the use of [rust-xcode-plugin](https://github.com/BrainiumLLC/rust-xcode-plugin) (make sure to run the task with the argument `--profile=reldbg`).
When building the SDK for release you should pass the `--release` argument to the task, which will strip away any symbols and optimise the created binary.
### Building only the Crypto SDK
```
build_crypto_xcframework.sh
```
The `build_crypto_xcframework.sh` script will go through all the steps required to generate a fully usable `.xcframework`:
1. compile `matrix-sdk-crypto-ffi` libraries for iOS and the iOS simulator under `/target`
2. `lipo` together the libraries for the same platform under `/generated`
3. run `uniffi` and generate the C header, module map and swift files
4. `xcodebuild` an `xcframework` from the fat static libs and the original iOS one, and add the header and module map to it under `generated/MatrixSDKCryptoFFI.xcframework`
5. cleanup and delete the generated files except the .xcframework and the swift sources (that aren't part of the framework)
### Building & testing the Swift package
The `Package.swift` file in this directory provides a simple example on how to integrate everything together but also a place to run unit and integration tests from.
It's pre-configured to link to the generated static lib and .swift files so successfully running `cargo xtask swift build-library` first is necessary for it to compile. Afterwards you can execute the tests with `swift test`. Note that for the moment this only works on macOS but we're planning to add Linux support in the future.
## Distribution
The generated framework and Swift code can be distributed and integrated directly but in order to make things simpler we bundle them together as a [Swift package](https://github.com/matrix-org/matrix-rust-components-swift/) in the case of SDK, and as a CocoaPods podspec in the case of Crypto SDK.
### Publishing MatrixSDKCrypto
1. Navigate into `bindings/apple` and run [`build_crypto_xcframework.sh`](#building-only-the-crypto-sdk) script which generates a .zip file with the framework in `./generated` folder
Note that whilst you can run this command from any git branch, if you want to make a public release, ensure you are building from latest `main`
2. Tag the commit you just used to build the release and push the tag to GitHub
Use `matrix-sdk-crypto-ffi-<major>.<minor>.<patch>` tag name
3. Create a new [GitHub release](https://github.com/matrix-org/matrix-rust-sdk/releases) using this tag (see [example](https://github.com/matrix-org/matrix-rust-sdk/releases/tag/matrix-sdk-crypto-ffi-0.3.4))
4. Upload the previously generated .zip file to this release
5. Increment the version in [`MatrixSDKCrypto.podspec`](./MatrixSDKCrypto.podspec)
Note that this is not automated and is a local-only change. To determine the most recent published version, run `pod repo update && pod search MatrixSDKCrypto`
or check git tags via `git tag | grep matrix-sdk-crypto-ffi`
6. Push new Podspec version to Cocoapods via `pod trunk push MatrixSDKCrypto.podspec --allow-warnings`
@@ -0,0 +1,61 @@
import XCTest
@testable import MatrixRustSDK
final class ClientTests: XCTestCase {
func testBuildingWithHomeserverURL() {
do {
_ = try ClientBuilder()
.homeserverUrl(url: "https://localhost:8008")
.build()
} catch {
XCTFail("The client should build successfully when given a homeserver.")
}
}
func testBuildingWithHomeserverURLAndUserAgent() {
do {
_ = try ClientBuilder()
.homeserverUrl(url: "https://localhost:8008")
.userAgent(userAgent: "golden-eye/007")
.build()
} catch {
XCTFail("The client should build successfully when given a homeserver and user agent.")
}
}
func testBuildingWithUsername() {
do {
_ = try ClientBuilder()
.username(username: "@test:matrix.org")
.build()
} catch {
XCTFail("The client should build successfully when given a username.")
}
}
func testBuildingWithInvalidUsername() {
do {
_ = try ClientBuilder()
.username(username: "@test:invalid")
.build()
XCTFail("The client should not build when given an invalid username.")
} catch ClientError.Generic(let message) {
XCTAssertTrue(message.contains(".well-known"), "The client should fail to do the well-known lookup.")
} catch {
XCTFail("Not expecting any other kind of exception")
}
}
// MARK: - Private
static private var basePath: String {
guard let url = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else {
fatalError("Should always be able to retrieve the caches directory")
}
try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: false, attributes: nil)
return url.path
}
}
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/env bash
set -eEu
cd "$(dirname "$0")"
# Path to the repo root
SRC_ROOT=../..
TARGET_DIR="${SRC_ROOT}/target"
GENERATED_DIR="${SRC_ROOT}/generated"
if [ -d "${GENERATED_DIR}" ]; then rm -rf "${GENERATED_DIR}"; fi
mkdir -p ${GENERATED_DIR}/{macos,simulator}
REL_FLAG="--release"
REL_TYPE_DIR="release"
TARGET_CRATE=matrix-sdk-crypto-ffi
# Build static libs for all the different architectures
# Required by olm-sys crate
export IOS_SDK_PATH=`xcrun --show-sdk-path --sdk iphoneos`
# iOS
echo -e "Building for iOS [1/5]"
cargo build -p ${TARGET_CRATE} ${REL_FLAG} --target "aarch64-apple-ios"
# MacOS
echo -e "\nBuilding for macOS (Apple Silicon) [2/5]"
cargo build -p ${TARGET_CRATE} ${REL_FLAG} --target "aarch64-apple-darwin"
echo -e "\nBuilding for macOS (Intel) [3/5]"
cargo build -p ${TARGET_CRATE} ${REL_FLAG} --target "x86_64-apple-darwin"
# iOS Simulator
echo -e "\nBuilding for iOS Simulator (Apple Silicon) [4/5]"
cargo build -p ${TARGET_CRATE} ${REL_FLAG} --target "aarch64-apple-ios-sim"
echo -e "\nBuilding for iOS Simulator (Intel) [5/5]"
cargo build -p ${TARGET_CRATE} ${REL_FLAG} --target "x86_64-apple-ios"
echo -e "\nCreating XCFramework"
# Lipo together the libraries for the same platform
# MacOS
lipo -create \
"${TARGET_DIR}/x86_64-apple-darwin/${REL_TYPE_DIR}/libmatrix_sdk_crypto_ffi.a" \
"${TARGET_DIR}/aarch64-apple-darwin/${REL_TYPE_DIR}/libmatrix_sdk_crypto_ffi.a" \
-output "${GENERATED_DIR}/macos/libmatrix_sdk_crypto_ffi.a"
# iOS Simulator
lipo -create \
"${TARGET_DIR}/x86_64-apple-ios/${REL_TYPE_DIR}/libmatrix_sdk_crypto_ffi.a" \
"${TARGET_DIR}/aarch64-apple-ios-sim/${REL_TYPE_DIR}/libmatrix_sdk_crypto_ffi.a" \
-output "${GENERATED_DIR}/simulator/libmatrix_sdk_crypto_ffi.a"
# Generate uniffi files
cargo uniffi-bindgen generate \
--language swift \
--lib-file "${TARGET_DIR}/aarch64-apple-ios-sim/${REL_TYPE_DIR}/libmatrix_sdk_crypto_ffi.a" \
--config "${SRC_ROOT}/bindings/${TARGET_CRATE}/uniffi.toml" \
--out-dir ${GENERATED_DIR} \
"${SRC_ROOT}/bindings/${TARGET_CRATE}/src/olm.udl"
# Move headers to the right place
HEADERS_DIR=${GENERATED_DIR}/headers
mkdir -p ${HEADERS_DIR}
mv ${GENERATED_DIR}/*.h ${HEADERS_DIR}
# Rename and move modulemap to the right place
mv ${GENERATED_DIR}/*.modulemap ${HEADERS_DIR}/module.modulemap
# Move source files to the right place
SWIFT_DIR="${GENERATED_DIR}/Sources"
mkdir -p ${SWIFT_DIR}
mv ${GENERATED_DIR}/*.swift ${SWIFT_DIR}
# Build the xcframework
if [ -d "${GENERATED_DIR}/MatrixSDKCryptoFFI.xcframework" ]; then rm -rf "${GENERATED_DIR}/MatrixSDKCryptoFFI.xcframework"; fi
xcodebuild -create-xcframework \
-library "${TARGET_DIR}/aarch64-apple-ios/${REL_TYPE_DIR}/libmatrix_sdk_crypto_ffi.a" \
-headers ${HEADERS_DIR} \
-library "${GENERATED_DIR}/macos/libmatrix_sdk_crypto_ffi.a" \
-headers ${HEADERS_DIR} \
-library "${GENERATED_DIR}/simulator/libmatrix_sdk_crypto_ffi.a" \
-headers ${HEADERS_DIR} \
-output "${GENERATED_DIR}/MatrixSDKCryptoFFI.xcframework"
# Cleanup
if [ -d "${GENERATED_DIR}/macos" ]; then rm -rf "${GENERATED_DIR}/macos"; fi
if [ -d "${GENERATED_DIR}/simulator" ]; then rm -rf "${GENERATED_DIR}/simulator"; fi
if [ -d ${HEADERS_DIR} ]; then rm -rf ${HEADERS_DIR}; fi
# Zip up framework, sources and LICENSE, ready to be uploaded to GitHub Releases and used by MatrixSDKCrypto.podspec
cp ${SRC_ROOT}/LICENSE $GENERATED_DIR
cd $GENERATED_DIR
zip -r MatrixSDKCryptoFFI.zip MatrixSDKCryptoFFI.xcframework Sources LICENSE
rm LICENSE
echo "XCFramework is ready 🚀"
+61
View File
@@ -0,0 +1,61 @@
[package]
name = "matrix-sdk-crypto-ffi"
version = "0.1.0"
authors = ["Damir Jelić <poljar@termina.org.uk>"]
edition = "2021"
rust-version = { workspace = true }
description = "Uniffi based bindings for the Rust SDK crypto crate"
repository = "https://github.com/matrix-org/matrix-rust-sdk"
license = "Apache-2.0"
publish = false
[lib]
crate-type = ["cdylib", "staticlib"]
[features]
default = ["bundled-sqlite"]
bundled-sqlite = ["matrix-sdk-sqlite/bundled"]
[dependencies]
anyhow = { workspace = true }
futures-util = "0.3.28"
hmac = "0.12.1"
http = { workspace = true }
matrix-sdk-common = { workspace = true }
pbkdf2 = "0.12.2"
rand = { workspace = true }
ruma = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
thiserror = { workspace = true }
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
# keep in sync with uniffi dependency in matrix-sdk-ffi, and uniffi_bindgen in ffi CI job
uniffi = { workspace = true }
vodozemac = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] }
[dependencies.js_int]
version = "0.2.2"
features = ["lax_deserialize"]
[dependencies.matrix-sdk-crypto]
workspace = true
features = ["qrcode", "automatic-room-key-forwarding"]
[dependencies.matrix-sdk-sqlite]
workspace = true
features = ["crypto-store"]
[dependencies.tokio]
version = "1.33.0"
default_features = false
features = ["rt-multi-thread"]
[build-dependencies]
uniffi = { workspace = true, features = ["build"] }
vergen = { version = "8.2.5", features = ["build", "git", "gitcl"] }
[dev-dependencies]
tempfile = "3.8.0"
assert_matches2 = { workspace = true }
+86
View File
@@ -0,0 +1,86 @@
# Uniffi based bindings for the Rust SDK crypto crate.
This crate contains Uniffi based bindings for the `matrix-sdk-crypto` crate. The
README mainly describes how to build and integrate the bindings into a Kotlin
based Android project, but the Android specific bits can be skipped if you are
targeting an x86 Linux project.
To build and distribute bindings for iOS projects, see a [dedicated page](../apple/README.md)
## Prerequisites
### Rust
To build the bindings [Rust] will be needed it can be either installed using an
OS specific package manager or directly with the provided [installer](https://rustup.rs/).
### Android NDK
The Android NDK will be required as well, it can be installed either through
Android Studio or directly using an [installer](https://developer.android.com/ndk/downloads).
### Configuring Rust for cross compilation
First we'll need to install the Rust target for our desired Android architecture,
for example:
```
# rustup target add aarch64-linux-android
```
This will add support to cross-compile for the aarch64-linux-android target,
Rust supports many different [targets], you'll have to make sure to pick the
right one for your device or emulator.
After this is done, we'll have to configure [Cargo] to use the correct linker
for our target. Cargo is configured using a TOML file that will be found in
`%USERPROFILE%\.cargo\config.toml` on Windows or `$HOME/.cargo/config` on Unix
platforms. More details and configuration options for Cargo can be found in the
official docs over [here](https://doc.rust-lang.org/cargo/reference/config.html).
```
[target.aarch64-linux-android]
ar = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ar"
linker = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang"
```
## Building
To enable cross compilation for `olm-sys` which builds our `libolm` C library
we'll need to set the `ANDROID_NDK` environment variable to the location of our
Android NDK installation.
```
$ export ANDROID_NDK=$HOME/Android/Sdk/ndk/22.0.7026061/
```
### Building for a target
The bindings can built for the `aarch64` target with:
```
$ cargo build --target aarch64-linux-android
```
After that, a dynamic library can be found in the `target/aarch64-linux-android/debug` directory.
The library will be called `libmatrix_crypto.so` and needs to be renamed and
copied into the `jniLibs` directory of your Android project, for Element Android:
```
$ cp ../../target/aarch64-linux-android/debug/libmatrix_crypto.so \
/home/example/matrix-sdk-android/src/main/jniLibs/aarch64/libuniffi_olm.so
```
## Minimum Supported Rust Version (MSRV)
These crates are built with the Rust language version 2021 and require a minimum compiler version of `1.62`.
## License
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)
[Rust]: https://www.rust-lang.org/
[installer]: https://rustup.rs/
[targets]: https://doc.rust-lang.org/nightly/rustc/platform-support.html
[Cargo]: https://doc.rust-lang.org/cargo/
[uniffi]: https://github.com/mozilla/uniffi-rs/
+39
View File
@@ -0,0 +1,39 @@
use std::{env, error::Error};
use vergen::EmitBuilder;
/// Adds a temporary workaround for an issue with the Rust compiler and Android
/// in x86_64 devices: https://github.com/rust-lang/rust/issues/109717.
/// The workaround comes from: https://github.com/mozilla/application-services/pull/5442
fn setup_x86_64_android_workaround() {
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
if target_arch == "x86_64" && target_os == "android" {
let android_ndk_home = env::var("ANDROID_NDK_HOME").expect("ANDROID_NDK_HOME not set");
let build_os = match env::consts::OS {
"linux" => "linux",
"macos" => "darwin",
"windows" => "windows",
_ => panic!(
"Unsupported OS. You must use either Linux, MacOS or Windows to build the crate."
),
};
const DEFAULT_CLANG_VERSION: &str = "14.0.7";
let clang_version =
env::var("NDK_CLANG_VERSION").unwrap_or_else(|_| DEFAULT_CLANG_VERSION.to_owned());
let linux_x86_64_lib_dir = format!(
"toolchains/llvm/prebuilt/{build_os}-x86_64/lib64/clang/{clang_version}/lib/linux/"
);
println!("cargo:rustc-link-search={android_ndk_home}/{linux_x86_64_lib_dir}");
println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
}
}
fn main() -> Result<(), Box<dyn Error>> {
setup_x86_64_android_workaround();
uniffi::generate_scaffolding("./src/olm.udl")?;
EmitBuilder::builder().git_sha(true).git_describe(true, false, None).emit()?;
Ok(())
}
@@ -0,0 +1,233 @@
use std::{collections::HashMap, iter, ops::DerefMut, sync::Arc};
use hmac::Hmac;
use matrix_sdk_crypto::{
backups::DecryptionError,
store::{BackupDecryptionKey, CryptoStoreError as InnerStoreError},
};
use pbkdf2::pbkdf2;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use sha2::Sha512;
use thiserror::Error;
use zeroize::Zeroize;
/// The private part of the backup key, the one used for recovery.
#[derive(uniffi::Object)]
pub struct BackupRecoveryKey {
pub(crate) inner: BackupDecryptionKey,
pub(crate) passphrase_info: Option<PassphraseInfo>,
}
/// Error type for the decryption of backed up room keys.
#[derive(Debug, Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum PkDecryptionError {
/// An internal libolm error happened during decryption.
#[error("Error decryption a PkMessage {0}")]
Olm(#[from] DecryptionError),
}
/// Error type for the decoding and storing of the backup key.
#[derive(Debug, Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum DecodeError {
/// An error happened while decoding the recovery key.
#[error(transparent)]
Decode(#[from] matrix_sdk_crypto::backups::DecodeError),
/// An error happened in the storage layer while trying to save the
/// decoded recovery key.
#[error(transparent)]
CryptoStore(#[from] InnerStoreError),
}
/// Struct containing info about the way the backup key got derived from a
/// passphrase.
#[derive(Debug, Clone, uniffi::Record)]
pub struct PassphraseInfo {
/// The salt that was used during key derivation.
pub private_key_salt: String,
/// The number of PBKDF rounds that were used for key derivation.
pub private_key_iterations: i32,
}
/// The public part of the backup key.
#[derive(uniffi::Record)]
pub struct MegolmV1BackupKey {
/// The actual base64 encoded public key.
pub public_key: String,
/// Signatures that have signed our backup key.
pub signatures: HashMap<String, HashMap<String, String>>,
/// The passphrase info, if the key was derived from one.
pub passphrase_info: Option<PassphraseInfo>,
/// Get the full name of the backup algorithm this backup key supports.
pub backup_algorithm: String,
}
impl BackupRecoveryKey {
const KEY_SIZE: usize = 32;
const SALT_SIZE: usize = 32;
const PBKDF_ROUNDS: i32 = 500_000;
}
#[uniffi::export]
impl BackupRecoveryKey {
/// Create a new random [`BackupRecoveryKey`].
#[allow(clippy::new_without_default)]
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
Arc::new(Self {
inner: BackupDecryptionKey::new()
.expect("Can't gather enough randomness to create a recovery key"),
passphrase_info: None,
})
}
/// Try to create a [`BackupRecoveryKey`] from a base 64 encoded string.
#[uniffi::constructor]
pub fn from_base64(key: String) -> Result<Arc<Self>, DecodeError> {
Ok(Arc::new(Self { inner: BackupDecryptionKey::from_base64(&key)?, passphrase_info: None }))
}
/// Try to create a [`BackupRecoveryKey`] from a base 58 encoded string.
#[uniffi::constructor]
pub fn from_base58(key: String) -> Result<Arc<Self>, DecodeError> {
Ok(Arc::new(Self { inner: BackupDecryptionKey::from_base58(&key)?, passphrase_info: None }))
}
/// Create a new [`BackupRecoveryKey`] from the given passphrase.
#[uniffi::constructor]
pub fn new_from_passphrase(passphrase: String) -> Arc<Self> {
let mut rng = thread_rng();
let salt: String = iter::repeat(())
.map(|()| rng.sample(Alphanumeric))
.map(char::from)
.take(Self::SALT_SIZE)
.collect();
Self::from_passphrase(passphrase, salt, Self::PBKDF_ROUNDS)
}
/// Restore a [`BackupRecoveryKey`] from the given passphrase.
#[uniffi::constructor]
pub fn from_passphrase(passphrase: String, salt: String, rounds: i32) -> Arc<Self> {
let mut key = Box::new([0u8; Self::KEY_SIZE]);
let rounds = rounds as u32;
pbkdf2::<Hmac<Sha512>>(passphrase.as_bytes(), salt.as_bytes(), rounds, key.deref_mut())
.expect(
"We should be able to expand a passphrase of any length due to \
HMAC being able to be initialized with any input size",
);
let backup_decryption_key = BackupDecryptionKey::from_bytes(&key);
key.zeroize();
Arc::new(Self {
inner: backup_decryption_key,
passphrase_info: Some(PassphraseInfo {
private_key_salt: salt,
private_key_iterations: rounds as i32,
}),
})
}
/// Convert the recovery key to a base 58 encoded string.
pub fn to_base58(&self) -> String {
self.inner.to_base58()
}
/// Convert the recovery key to a base 64 encoded string.
pub fn to_base64(&self) -> String {
self.inner.to_base64()
}
/// Get the public part of the backup key.
pub fn megolm_v1_public_key(&self) -> MegolmV1BackupKey {
let public_key = self.inner.megolm_v1_public_key();
let signatures: HashMap<String, HashMap<String, String>> = public_key
.signatures()
.into_iter()
.map(|(k, v)| {
(
k.to_string(),
v.into_iter()
.map(|(k, v)| {
(
k.to_string(),
match v {
Ok(s) => s.to_base64(),
Err(s) => s.source,
},
)
})
.collect(),
)
})
.collect();
MegolmV1BackupKey {
public_key: public_key.to_base64(),
signatures,
passphrase_info: self.passphrase_info.clone(),
backup_algorithm: public_key.backup_algorithm().to_owned(),
}
}
/// Try to decrypt a message that was encrypted using the public part of the
/// backup key.
pub fn decrypt_v1(
&self,
ephemeral_key: String,
mac: String,
ciphertext: String,
) -> Result<String, PkDecryptionError> {
self.inner.decrypt_v1(&ephemeral_key, &mac, &ciphertext).map_err(|e| e.into())
}
}
#[cfg(test)]
mod tests {
use ruma::api::client::backup::KeyBackupData;
use serde_json::json;
use super::BackupRecoveryKey;
#[test]
fn test_decrypt_key() {
let recovery_key = BackupRecoveryKey::from_base64(
"Ha9cklU/9NqFo9WKdVfGzmqUL/9wlkdxfEitbSIPVXw".to_owned(),
)
.unwrap();
let data = json!({
"first_message_index": 0,
"forwarded_count": 0,
"is_verified": false,
"session_data": {
"ephemeral": "HlLi76oV6wxHz3PCqE/bxJi6yF1HnYz5Dq3T+d/KpRw",
"ciphertext": "MuM8E3Yc6TSAvhVGb77rQ++jE6p9dRepx63/3YPD2wACKAppkZHeFrnTH6wJ/HSyrmzo\
7HfwqVl6tKNpfooSTHqUf6x1LHz+h4B/Id5ITO1WYt16AaI40LOnZqTkJZCfSPuE2oxa\
lwEHnCS3biWybutcnrBFPR3LMtaeHvvkb+k3ny9l5ZpsU9G7vCm3XoeYkWfLekWXvDhb\
qWrylXD0+CNUuaQJ/S527TzLd4XKctqVjjO/cCH7q+9utt9WJAfK8LGaWT/mZ3AeWjf5\
kiqOpKKf5Cn4n5SSil5p/pvGYmjnURvZSEeQIzHgvunIBEPtzK/MYEPOXe/P5achNGlC\
x+5N19Ftyp9TFaTFlTWCTi0mpD7ePfCNISrwpozAz9HZc0OhA8+1aSc7rhYFIeAYXFU3\
26NuFIFHI5pvpSxjzPQlOA+mavIKmiRAtjlLw11IVKTxgrdT4N8lXeMr4ndCSmvIkAzF\
Mo1uZA4fzjiAdQJE4/2WeXFNNpvdfoYmX8Zl9CAYjpSO5HvpwkAbk4/iLEH3hDfCVUwD\
fMh05PdGLnxeRpiEFWSMSsJNp+OWAA+5JsF41BoRGrxoXXT+VKqlUDONd+O296Psu8Q+\
d8/S618",
"mac": "GtMrurhDTwo"
}
});
let key_backup_data: KeyBackupData = serde_json::from_value(data).unwrap();
let ephemeral = key_backup_data.session_data.ephemeral.encode();
let ciphertext = key_backup_data.session_data.ciphertext.encode();
let mac = key_backup_data.session_data.mac.encode();
let _ = recovery_key
.decrypt_v1(ephemeral, mac, ciphertext)
.expect("The backed up key should be decrypted successfully");
}
}
@@ -0,0 +1,191 @@
use std::{mem::ManuallyDrop, sync::Arc};
use matrix_sdk_crypto::dehydrated_devices::{
DehydratedDevice as InnerDehydratedDevice, DehydratedDevices as InnerDehydratedDevices,
RehydratedDevice as InnerRehydratedDevice,
};
use ruma::{api::client::dehydrated_device, events::AnyToDeviceEvent, serde::Raw, OwnedDeviceId};
use serde_json::json;
use tokio::runtime::Handle;
use zeroize::Zeroize;
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum DehydrationError {
#[error(transparent)]
Pickle(#[from] matrix_sdk_crypto::vodozemac::LibolmPickleError),
#[error(transparent)]
MissingSigningKey(#[from] matrix_sdk_crypto::SignatureError),
#[error(transparent)]
Json(#[from] serde_json::Error),
#[error(transparent)]
Store(#[from] matrix_sdk_crypto::CryptoStoreError),
#[error("The pickle key has an invalid length, expected 32 bytes, got {0}")]
PickleKeyLength(usize),
}
impl From<matrix_sdk_crypto::dehydrated_devices::DehydrationError> for DehydrationError {
fn from(value: matrix_sdk_crypto::dehydrated_devices::DehydrationError) -> Self {
match value {
matrix_sdk_crypto::dehydrated_devices::DehydrationError::Json(e) => Self::Json(e),
matrix_sdk_crypto::dehydrated_devices::DehydrationError::Pickle(e) => Self::Pickle(e),
matrix_sdk_crypto::dehydrated_devices::DehydrationError::MissingSigningKey(e) => {
Self::MissingSigningKey(e)
}
matrix_sdk_crypto::dehydrated_devices::DehydrationError::Store(e) => Self::Store(e),
}
}
}
#[derive(uniffi::Object)]
pub struct DehydratedDevices {
pub(crate) runtime: Handle,
pub(crate) inner: ManuallyDrop<InnerDehydratedDevices>,
}
impl Drop for DehydratedDevices {
fn drop(&mut self) {
// See the drop implementation for the `crate::OlmMachine` for an explanation.
let _guard = self.runtime.enter();
unsafe {
ManuallyDrop::drop(&mut self.inner);
}
}
}
#[uniffi::export]
impl DehydratedDevices {
pub fn create(&self) -> Result<Arc<DehydratedDevice>, DehydrationError> {
let inner = self.runtime.block_on(self.inner.create())?;
Ok(Arc::new(DehydratedDevice {
inner: ManuallyDrop::new(inner),
runtime: self.runtime.to_owned(),
}))
}
pub fn rehydrate(
&self,
pickle_key: Vec<u8>,
device_id: String,
device_data: String,
) -> Result<Arc<RehydratedDevice>, DehydrationError> {
let device_data: Raw<_> = serde_json::from_str(&device_data)?;
let device_id: OwnedDeviceId = device_id.into();
let mut key = get_pickle_key(&pickle_key)?;
let ret = RehydratedDevice {
runtime: self.runtime.to_owned(),
inner: ManuallyDrop::new(self.runtime.block_on(self.inner.rehydrate(
&key,
&device_id,
device_data,
))?),
}
.into();
key.zeroize();
Ok(ret)
}
}
#[derive(uniffi::Object)]
pub struct RehydratedDevice {
inner: ManuallyDrop<InnerRehydratedDevice>,
runtime: Handle,
}
impl Drop for RehydratedDevice {
fn drop(&mut self) {
// See the drop implementation for the `crate::OlmMachine` for an explanation.
let _guard = self.runtime.enter();
unsafe {
ManuallyDrop::drop(&mut self.inner);
}
}
}
#[uniffi::export]
impl RehydratedDevice {
pub fn receive_events(&self, events: String) -> Result<(), crate::CryptoStoreError> {
let events: Vec<Raw<AnyToDeviceEvent>> = serde_json::from_str(&events)?;
self.runtime.block_on(self.inner.receive_events(events))?;
Ok(())
}
}
#[derive(uniffi::Object)]
pub struct DehydratedDevice {
pub(crate) runtime: Handle,
pub(crate) inner: ManuallyDrop<InnerDehydratedDevice>,
}
impl Drop for DehydratedDevice {
fn drop(&mut self) {
// See the drop implementation for the `crate::OlmMachine` for an explanation.
let _guard = self.runtime.enter();
unsafe {
ManuallyDrop::drop(&mut self.inner);
}
}
}
#[uniffi::export]
impl DehydratedDevice {
pub fn keys_for_upload(
&self,
device_display_name: String,
pickle_key: Vec<u8>,
) -> Result<UploadDehydratedDeviceRequest, DehydrationError> {
let mut key = get_pickle_key(&pickle_key)?;
let request =
self.runtime.block_on(self.inner.keys_for_upload(device_display_name, &key))?;
key.zeroize();
Ok(request.into())
}
}
#[derive(Debug, uniffi::Record)]
pub struct UploadDehydratedDeviceRequest {
/// The serialized JSON body of the request.
body: String,
}
impl From<dehydrated_device::put_dehydrated_device::unstable::Request>
for UploadDehydratedDeviceRequest
{
fn from(value: dehydrated_device::put_dehydrated_device::unstable::Request) -> Self {
let body = json!({
"device_id": value.device_id,
"device_data": value.device_data,
"initial_device_display_name": value.initial_device_display_name,
"device_keys": value.device_keys,
"one_time_keys": value.one_time_keys,
"fallback_keys": value.fallback_keys,
});
let body = serde_json::to_string(&body)
.expect("We should be able to serialize the PUT dehydrated devices request body");
Self { body }
}
}
fn get_pickle_key(pickle_key: &[u8]) -> Result<Box<[u8; 32]>, DehydrationError> {
let pickle_key_length = pickle_key.len();
if pickle_key_length == 32 {
let mut key = Box::new([0u8; 32]);
key.copy_from_slice(pickle_key);
Ok(key)
} else {
Err(DehydrationError::PickleKeyLength(pickle_key_length))
}
}
@@ -0,0 +1,47 @@
use std::collections::HashMap;
use matrix_sdk_crypto::Device as InnerDevice;
/// An E2EE capable Matrix device.
#[derive(uniffi::Record)]
pub struct Device {
/// The device owner.
pub user_id: String,
/// The unique ID of the device.
pub device_id: String,
/// The published public identity keys of the devices
///
/// A map from the key type (e.g. curve25519) to the base64 encoded key.
pub keys: HashMap<String, String>,
/// The supported algorithms of the device.
pub algorithms: Vec<String>,
/// The human readable name of the device.
pub display_name: Option<String>,
/// A flag indicating if the device has been blocked, blocked devices don't
/// receive any room keys from us.
pub is_blocked: bool,
/// Is the device locally trusted
pub locally_trusted: bool,
/// Is our cross signing identity trusted and does the identity trust the
/// device.
pub cross_signing_trusted: bool,
/// The first time this device was seen in local timestamp, seconds since
/// epoch.
pub first_time_seen_ts: u64,
}
impl From<InnerDevice> for Device {
fn from(d: InnerDevice) -> Self {
Device {
user_id: d.user_id().to_string(),
device_id: d.device_id().to_string(),
keys: d.keys().iter().map(|(k, v)| (k.to_string(), v.to_base64())).collect(),
algorithms: d.algorithms().iter().map(|a| a.to_string()).collect(),
display_name: d.display_name().map(|d| d.to_owned()),
is_blocked: d.is_blacklisted(),
locally_trusted: d.is_locally_trusted(),
cross_signing_trusted: d.is_cross_signing_trusted(),
first_time_seen_ts: d.first_time_seen_ts().0.into(),
}
}
}
+126
View File
@@ -0,0 +1,126 @@
#![allow(missing_docs)]
use matrix_sdk_crypto::{
store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError,
SecretImportError as RustSecretImportError, SignatureError as InnerSignatureError,
};
use matrix_sdk_sqlite::OpenStoreError;
use ruma::{IdParseError, OwnedUserId};
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum KeyImportError {
#[error(transparent)]
Export(#[from] KeyExportError),
#[error(transparent)]
CryptoStore(#[from] InnerStoreError),
#[error(transparent)]
Json(#[from] serde_json::Error),
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum SecretImportError {
#[error(transparent)]
CryptoStore(#[from] InnerStoreError),
#[error(transparent)]
Import(#[from] RustSecretImportError),
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum SignatureError {
#[error(transparent)]
Signature(#[from] InnerSignatureError),
#[error(transparent)]
Identifier(#[from] IdParseError),
#[error(transparent)]
CryptoStore(#[from] InnerStoreError),
#[error("Unknown device {0} {1}")]
UnknownDevice(OwnedUserId, String),
#[error("Unknown user identity {0}")]
UnknownUserIdentity(String),
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum CryptoStoreError {
#[error("Failed to open the store")]
OpenStore(#[from] OpenStoreError),
#[error(transparent)]
CryptoStore(#[from] InnerStoreError),
#[error(transparent)]
OlmError(#[from] OlmError),
#[error(transparent)]
Serialization(#[from] serde_json::Error),
#[error("The given string is not a valid user ID: source {0}, error {1}")]
InvalidUserId(String, IdParseError),
#[error(transparent)]
Identifier(#[from] IdParseError),
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
pub enum DecryptionError {
#[error("serialization error: {error}")]
Serialization { error: String },
#[error("identifier parsing error: {error}")]
Identifier { error: String },
#[error("megolm error: {error}")]
Megolm { error: String },
#[error("missing room key: {error}")]
MissingRoomKey { error: String, withheld_code: Option<String> },
#[error("store error: {error}")]
Store { error: String },
}
impl From<MegolmError> for DecryptionError {
fn from(value: MegolmError) -> Self {
match value {
MegolmError::MissingRoomKey(withheld_code) => Self::MissingRoomKey {
error: "Withheld Inbound group session".to_owned(),
withheld_code: withheld_code.map(|w| w.as_str().to_owned()),
},
_ => Self::Megolm { error: value.to_string() },
}
}
}
impl From<serde_json::Error> for DecryptionError {
fn from(err: serde_json::Error) -> Self {
Self::Serialization { error: err.to_string() }
}
}
impl From<IdParseError> for DecryptionError {
fn from(err: IdParseError) -> Self {
Self::Identifier { error: err.to_string() }
}
}
impl From<InnerStoreError> for DecryptionError {
fn from(err: InnerStoreError) -> Self {
Self::Store { error: err.to_string() }
}
}
#[cfg(test)]
mod tests {
use assert_matches2::assert_let;
use matrix_sdk_crypto::MegolmError;
use super::DecryptionError;
#[test]
fn test_withheld_error_mapping() {
use matrix_sdk_crypto::types::events::room_key_withheld::WithheldCode;
let inner_error = MegolmError::MissingRoomKey(Some(WithheldCode::Unverified));
let binding_error: DecryptionError = inner_error.into();
assert_let!(
DecryptionError::MissingRoomKey { error: _, withheld_code: Some(code) } = binding_error
);
assert_eq!("m.unverified", code)
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
use std::{
io::{Result, Write},
sync::{Arc, Mutex},
};
use tracing_subscriber::{fmt::MakeWriter, EnvFilter};
/// Trait that can be used to forward Rust logs over FFI to a language specific
/// logger.
#[uniffi::export(callback_interface)]
pub trait Logger: Send {
/// Called every time the Rust side wants to post a log line.
fn log(&self, log_line: String);
// TODO add support for different log levels, do this by adding more methods
// to the trait.
}
impl Write for LoggerWrapper {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let data = String::from_utf8_lossy(buf).to_string();
self.inner.lock().unwrap().log(data);
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl MakeWriter<'_> for LoggerWrapper {
type Writer = LoggerWrapper;
fn make_writer(&self) -> Self::Writer {
self.clone()
}
}
#[derive(Clone)]
pub struct LoggerWrapper {
inner: Arc<Mutex<Box<dyn Logger>>>,
}
/// Set the logger that should be used to forward Rust logs over FFI.
#[uniffi::export]
pub fn set_logger(logger: Box<dyn Logger>) {
let logger = LoggerWrapper { inner: Arc::new(Mutex::new(logger)) };
let filter = EnvFilter::from_default_env()
.add_directive(
"matrix_sdk_crypto=trace".parse().expect("Can't parse logging filter directive"),
)
.add_directive(
"matrix_sdk_sqlite=debug".parse().expect("Can't parse logging filter directive"),
);
let _ = tracing_subscriber::fmt()
.with_writer(logger)
.with_env_filter(filter)
.with_ansi(false)
.without_time()
.try_init();
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
namespace matrix_sdk_crypto_ffi {};
enum LocalTrust {
"Verified",
"BlackListed",
"Ignored",
"Unset",
};
enum SignatureState {
"Missing",
"Invalid",
"ValidButNotTrusted",
"ValidAndTrusted",
};
@@ -0,0 +1,354 @@
#![allow(missing_docs)]
use std::collections::HashMap;
use http::Response;
use matrix_sdk_crypto::{
CrossSigningBootstrapRequests, IncomingResponse, KeysBackupRequest, OutgoingRequest,
OutgoingVerificationRequest as SdkVerificationRequest, RoomMessageRequest, ToDeviceRequest,
UploadSigningKeysRequest as RustUploadSigningKeysRequest,
};
use ruma::{
api::client::{
backup::add_backup_keys::v3::Response as KeysBackupResponse,
keys::{
claim_keys::v3::{Request as KeysClaimRequest, Response as KeysClaimResponse},
get_keys::v3::Response as KeysQueryResponse,
upload_keys::v3::Response as KeysUploadResponse,
upload_signatures::v3::{
Request as RustSignatureUploadRequest, Response as SignatureUploadResponse,
},
},
message::send_message_event::v3::Response as RoomMessageResponse,
sync::sync_events::DeviceLists as RumaDeviceLists,
to_device::send_event_to_device::v3::Response as ToDeviceResponse,
},
assign,
events::EventContent,
OwnedTransactionId, UserId,
};
use serde_json::json;
#[derive(uniffi::Record)]
pub struct SignatureUploadRequest {
pub body: String,
}
impl From<RustSignatureUploadRequest> for SignatureUploadRequest {
fn from(r: RustSignatureUploadRequest) -> Self {
Self {
body: serde_json::to_string(&r.signed_keys)
.expect("Can't serialize signature upload request"),
}
}
}
#[derive(uniffi::Record)]
pub struct UploadSigningKeysRequest {
pub master_key: String,
pub self_signing_key: String,
pub user_signing_key: String,
}
impl From<RustUploadSigningKeysRequest> for UploadSigningKeysRequest {
fn from(r: RustUploadSigningKeysRequest) -> Self {
Self {
master_key: serde_json::to_string(
&r.master_key.expect("Request didn't contain a master key"),
)
.expect("Can't serialize cross signing master key"),
self_signing_key: serde_json::to_string(
&r.self_signing_key.expect("Request didn't contain a self-signing key"),
)
.expect("Can't serialize cross signing self-signing key"),
user_signing_key: serde_json::to_string(
&r.user_signing_key.expect("Request didn't contain a user-signing key"),
)
.expect("Can't serialize cross signing user-signing key"),
}
}
}
#[derive(uniffi::Record)]
pub struct BootstrapCrossSigningResult {
/// Optional request to upload some device keys alongside.
///
/// Must be sent first if present, and marked with `mark_request_as_sent`.
pub upload_keys_request: Option<Request>,
/// Request to upload the signing keys. Must be sent second.
pub upload_signing_keys_request: UploadSigningKeysRequest,
/// Request to upload the keys signatures, including for the signing keys
/// and optionally for the device keys. Must be sent last.
pub upload_signature_request: SignatureUploadRequest,
}
impl From<CrossSigningBootstrapRequests> for BootstrapCrossSigningResult {
fn from(requests: CrossSigningBootstrapRequests) -> Self {
Self {
upload_signing_keys_request: requests.upload_signing_keys_req.into(),
upload_keys_request: requests.upload_keys_req.map(Request::from),
upload_signature_request: requests.upload_signatures_req.into(),
}
}
}
#[derive(uniffi::Enum)]
pub enum OutgoingVerificationRequest {
ToDevice { request_id: String, event_type: String, body: String },
InRoom { request_id: String, room_id: String, event_type: String, content: String },
}
impl From<SdkVerificationRequest> for OutgoingVerificationRequest {
fn from(r: SdkVerificationRequest) -> Self {
match r {
SdkVerificationRequest::ToDevice(r) => r.into(),
SdkVerificationRequest::InRoom(r) => Self::InRoom {
request_id: r.txn_id.to_string(),
room_id: r.room_id.to_string(),
content: serde_json::to_string(&r.content)
.expect("Can't serialize message content"),
event_type: r.content.event_type().to_string(),
},
}
}
}
impl From<ToDeviceRequest> for OutgoingVerificationRequest {
fn from(r: ToDeviceRequest) -> Self {
Self::ToDevice {
request_id: r.txn_id.to_string(),
event_type: r.event_type.to_string(),
body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
}
}
}
#[derive(Debug, uniffi::Enum)]
pub enum Request {
ToDevice { request_id: String, event_type: String, body: String },
KeysUpload { request_id: String, body: String },
KeysQuery { request_id: String, users: Vec<String> },
KeysClaim { request_id: String, one_time_keys: HashMap<String, HashMap<String, String>> },
KeysBackup { request_id: String, version: String, rooms: String },
RoomMessage { request_id: String, room_id: String, event_type: String, content: String },
SignatureUpload { request_id: String, body: String },
}
impl From<OutgoingRequest> for Request {
fn from(r: OutgoingRequest) -> Self {
use matrix_sdk_crypto::OutgoingRequests::*;
match r.request() {
KeysUpload(u) => {
let body = json!({
"device_keys": u.device_keys,
"one_time_keys": u.one_time_keys,
"fallback_keys": u.fallback_keys,
});
Request::KeysUpload {
request_id: r.request_id().to_string(),
body: serde_json::to_string(&body)
.expect("Can't serialize `/keys/upload` request"),
}
}
KeysQuery(k) => {
let users: Vec<String> = k.device_keys.keys().map(|u| u.to_string()).collect();
Request::KeysQuery { request_id: r.request_id().to_string(), users }
}
ToDeviceRequest(t) => Request::from(t),
SignatureUpload(t) => Request::SignatureUpload {
request_id: r.request_id().to_string(),
body: serde_json::to_string(&t.signed_keys)
.expect("Can't serialize signature upload request"),
},
RoomMessage(r) => Request::from(r),
KeysClaim(c) => (r.request_id().to_owned(), c.clone()).into(),
KeysBackup(b) => (r.request_id().to_owned(), b.clone()).into(),
}
}
}
impl From<ToDeviceRequest> for Request {
fn from(r: ToDeviceRequest) -> Self {
Request::ToDevice {
request_id: r.txn_id.to_string(),
event_type: r.event_type.to_string(),
body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
}
}
}
impl From<(OwnedTransactionId, KeysClaimRequest)> for Request {
fn from(request_tuple: (OwnedTransactionId, KeysClaimRequest)) -> Self {
let (request_id, request) = request_tuple;
Request::KeysClaim {
request_id: request_id.to_string(),
one_time_keys: request
.one_time_keys
.into_iter()
.map(|(u, d)| {
(
u.to_string(),
d.into_iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(),
)
})
.collect(),
}
}
}
impl From<(OwnedTransactionId, KeysBackupRequest)> for Request {
fn from(request_tuple: (OwnedTransactionId, KeysBackupRequest)) -> Self {
let (request_id, request) = request_tuple;
Request::KeysBackup {
request_id: request_id.to_string(),
version: request.version.to_owned(),
rooms: serde_json::to_string(&request.rooms)
.expect("Can't serialize keys backup request"),
}
}
}
impl From<&ToDeviceRequest> for Request {
fn from(r: &ToDeviceRequest) -> Self {
Request::ToDevice {
request_id: r.txn_id.to_string(),
event_type: r.event_type.to_string(),
body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
}
}
}
impl From<&RoomMessageRequest> for Request {
fn from(r: &RoomMessageRequest) -> Self {
Self::RoomMessage {
request_id: r.txn_id.to_string(),
room_id: r.room_id.to_string(),
event_type: r.content.event_type().to_string(),
content: serde_json::to_string(&r.content).expect("Can't serialize message content"),
}
}
}
pub(crate) fn response_from_string(body: &str) -> Response<Vec<u8>> {
Response::builder()
.status(200)
.body(body.as_bytes().to_vec())
.expect("Can't create HTTP response")
}
#[derive(uniffi::Enum)]
pub enum RequestType {
KeysQuery,
KeysClaim,
KeysUpload,
ToDevice,
SignatureUpload,
KeysBackup,
RoomMessage,
}
#[derive(uniffi::Record)]
pub struct DeviceLists {
pub changed: Vec<String>,
pub left: Vec<String>,
}
impl From<DeviceLists> for RumaDeviceLists {
fn from(d: DeviceLists) -> Self {
assign!(RumaDeviceLists::new(), {
changed: d
.changed
.into_iter()
.filter_map(|u| UserId::parse(u).ok())
.collect(),
left: d
.left
.into_iter()
.filter_map(|u| UserId::parse(u).ok())
.collect(),
})
}
}
#[derive(uniffi::Record)]
pub struct KeysImportResult {
/// The number of room keys that were imported.
pub imported: i64,
/// The total number of room keys that were found in the export.
pub total: i64,
/// The map of keys that were imported.
///
/// It's a map from room id to a map of the sender key to a list of session
/// ids.
pub keys: HashMap<String, HashMap<String, Vec<String>>>,
}
pub(crate) enum OwnedResponse {
KeysClaim(KeysClaimResponse),
KeysUpload(KeysUploadResponse),
KeysQuery(KeysQueryResponse),
ToDevice(ToDeviceResponse),
SignatureUpload(SignatureUploadResponse),
KeysBackup(KeysBackupResponse),
RoomMessage(RoomMessageResponse),
}
impl From<KeysClaimResponse> for OwnedResponse {
fn from(response: KeysClaimResponse) -> Self {
OwnedResponse::KeysClaim(response)
}
}
impl From<KeysQueryResponse> for OwnedResponse {
fn from(response: KeysQueryResponse) -> Self {
OwnedResponse::KeysQuery(response)
}
}
impl From<KeysUploadResponse> for OwnedResponse {
fn from(response: KeysUploadResponse) -> Self {
OwnedResponse::KeysUpload(response)
}
}
impl From<ToDeviceResponse> for OwnedResponse {
fn from(response: ToDeviceResponse) -> Self {
OwnedResponse::ToDevice(response)
}
}
impl From<SignatureUploadResponse> for OwnedResponse {
fn from(response: SignatureUploadResponse) -> Self {
Self::SignatureUpload(response)
}
}
impl From<KeysBackupResponse> for OwnedResponse {
fn from(r: KeysBackupResponse) -> Self {
Self::KeysBackup(r)
}
}
impl From<RoomMessageResponse> for OwnedResponse {
fn from(response: RoomMessageResponse) -> Self {
OwnedResponse::RoomMessage(response)
}
}
impl<'a> From<&'a OwnedResponse> for IncomingResponse<'a> {
fn from(r: &'a OwnedResponse) -> Self {
match r {
OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r),
OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r),
OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r),
OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r),
OwnedResponse::SignatureUpload(r) => IncomingResponse::SignatureUpload(r),
OwnedResponse::KeysBackup(r) => IncomingResponse::KeysBackup(r),
OwnedResponse::RoomMessage(r) => IncomingResponse::RoomMessage(r),
}
}
}
@@ -0,0 +1,61 @@
use matrix_sdk_crypto::{types::CrossSigningKey, UserIdentities};
use crate::CryptoStoreError;
/// Enum representing cross signing identities of our own user or some other
/// user.
#[derive(uniffi::Enum)]
pub enum UserIdentity {
/// Our own user identity.
Own {
/// The unique id of our own user.
user_id: String,
/// Does our own user identity trust our own device.
trusts_our_own_device: bool,
/// The public master key of our identity.
master_key: String,
/// The public user-signing key of our identity.
user_signing_key: String,
/// The public self-signing key of our identity.
self_signing_key: String,
},
/// The user identity of other users.
Other {
/// The unique id of the user.
user_id: String,
/// The public master key of the identity.
master_key: String,
/// The public self-signing key of our identity.
self_signing_key: String,
},
}
impl UserIdentity {
pub(crate) async fn from_rust(i: UserIdentities) -> Result<Self, CryptoStoreError> {
Ok(match i {
UserIdentities::Own(i) => {
let master: CrossSigningKey = i.master_key().as_ref().to_owned();
let user_signing: CrossSigningKey = i.user_signing_key().as_ref().to_owned();
let self_signing: CrossSigningKey = i.self_signing_key().as_ref().to_owned();
UserIdentity::Own {
user_id: i.user_id().to_string(),
trusts_our_own_device: i.trusts_our_own_device().await?,
master_key: serde_json::to_string(&master)?,
user_signing_key: serde_json::to_string(&user_signing)?,
self_signing_key: serde_json::to_string(&self_signing)?,
}
}
UserIdentities::Other(i) => {
let master: CrossSigningKey = i.master_key().as_ref().to_owned();
let self_signing: CrossSigningKey = i.self_signing_key().as_ref().to_owned();
UserIdentity::Other {
user_id: i.user_id().to_string(),
master_key: serde_json::to_string(&master)?,
self_signing_key: serde_json::to_string(&self_signing)?,
}
}
})
}
}
@@ -0,0 +1,803 @@
use std::sync::Arc;
use futures_util::{Stream, StreamExt};
use matrix_sdk_crypto::{
matrix_sdk_qrcode::QrVerificationData, CancelInfo as RustCancelInfo, QrVerification as InnerQr,
QrVerificationState, Sas as InnerSas, SasState as RustSasState,
Verification as InnerVerification, VerificationRequest as InnerVerificationRequest,
VerificationRequestState as RustVerificationRequestState,
};
use ruma::events::key::verification::VerificationMethod;
use tokio::runtime::Handle;
use vodozemac::{base64_decode, base64_encode};
use crate::{CryptoStoreError, OutgoingVerificationRequest, SignatureUploadRequest};
/// Listener that will be passed over the FFI to report changes to a SAS
/// verification.
#[uniffi::export(callback_interface)]
pub trait SasListener: Send {
/// The callback that should be called on the Rust side
///
/// # Arguments
///
/// * `state` - The current state of the SAS verification.
fn on_change(&self, state: SasState);
}
/// An Enum describing the state the SAS verification is in.
#[derive(uniffi::Enum)]
pub enum SasState {
/// The verification has been started, the protocols that should be used
/// have been proposed and can be accepted.
Started,
/// The verification has been accepted and both sides agreed to a set of
/// protocols that will be used for the verification process.
Accepted,
/// The public keys have been exchanged and the short auth string can be
/// presented to the user.
KeysExchanged {
/// The emojis that represent the short auth string, will be `None` if
/// the emoji SAS method wasn't one of accepted protocols.
emojis: Option<Vec<i32>>,
/// The list of decimals that represent the short auth string.
decimals: Vec<i32>,
},
/// The verification process has been confirmed from our side, we're waiting
/// for the other side to confirm as well.
Confirmed,
/// The verification process has been successfully concluded.
Done,
/// The verification process has been cancelled.
Cancelled {
/// Information about the reason of the cancellation.
cancel_info: CancelInfo,
},
}
impl From<RustSasState> for SasState {
fn from(s: RustSasState) -> Self {
match s {
RustSasState::Started { .. } => Self::Started,
RustSasState::Accepted { .. } => Self::Accepted,
RustSasState::KeysExchanged { emojis, decimals } => Self::KeysExchanged {
emojis: emojis.map(|e| e.indices.map(|i| i as i32).to_vec()),
decimals: [decimals.0.into(), decimals.1.into(), decimals.2.into()].to_vec(),
},
RustSasState::Confirmed => Self::Confirmed,
RustSasState::Done { .. } => Self::Done,
RustSasState::Cancelled(c) => Self::Cancelled { cancel_info: c.into() },
}
}
}
/// Enum representing the different verification flows we support.
#[derive(uniffi::Object)]
pub struct Verification {
pub(crate) inner: InnerVerification,
pub(crate) runtime: Handle,
}
#[uniffi::export]
impl Verification {
/// Try to represent the `Verification` as an `Sas` verification object,
/// returns `None` if the verification is not a `Sas` verification.
pub fn as_sas(&self) -> Option<Arc<Sas>> {
if let InnerVerification::SasV1(sas) = &self.inner {
Some(Sas { inner: sas.to_owned(), runtime: self.runtime.to_owned() }.into())
} else {
None
}
}
/// Try to represent the `Verification` as an `QrCode` verification object,
/// returns `None` if the verification is not a `QrCode` verification.
pub fn as_qr(&self) -> Option<Arc<QrCode>> {
if let InnerVerification::QrV1(qr) = &self.inner {
Some(QrCode { inner: qr.to_owned(), runtime: self.runtime.to_owned() }.into())
} else {
None
}
}
}
/// The `m.sas.v1` verification flow.
#[derive(uniffi::Object)]
pub struct Sas {
pub(crate) inner: InnerSas,
pub(crate) runtime: Handle,
}
#[uniffi::export]
impl Sas {
/// Get the user id of the other side.
pub fn other_user_id(&self) -> String {
self.inner.other_user_id().to_string()
}
/// Get the device ID of the other side.
pub fn other_device_id(&self) -> String {
self.inner.other_device_id().to_string()
}
/// Get the unique ID that identifies this SAS verification flow.
pub fn flow_id(&self) -> String {
self.inner.flow_id().as_str().to_owned()
}
/// Get the room id if the verification is happening inside a room.
pub fn room_id(&self) -> Option<String> {
self.inner.room_id().map(|r| r.to_string())
}
/// Is the SAS flow done.
pub fn is_done(&self) -> bool {
self.inner.is_done()
}
/// Did we initiate the verification flow.
pub fn we_started(&self) -> bool {
self.inner.we_started()
}
/// Accept that we're going forward with the short auth string verification.
pub fn accept(&self) -> Option<OutgoingVerificationRequest> {
self.inner.accept().map(|r| r.into())
}
/// Confirm a verification was successful.
///
/// This method should be called if a short auth string should be confirmed
/// as matching.
pub fn confirm(&self) -> Result<Option<ConfirmVerificationResult>, CryptoStoreError> {
let (requests, signature_request) = self.runtime.block_on(self.inner.confirm())?;
let requests = requests.into_iter().map(|r| r.into()).collect();
Ok(Some(ConfirmVerificationResult {
requests,
signature_request: signature_request.map(|s| s.into()),
}))
}
/// Cancel the SAS verification using the given cancel code.
///
/// # Arguments
///
/// * `cancel_code` - The error code for why the verification was cancelled,
/// manual cancellatio usually happens with `m.user` cancel code. The full
/// list of cancel codes can be found in the [spec]
///
/// [spec]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationcancel
pub fn cancel(&self, cancel_code: String) -> Option<OutgoingVerificationRequest> {
self.inner.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
/// Get a list of emoji indices of the emoji representation of the short
/// auth string.
///
/// *Note*: A SAS verification needs to be started and in the presentable
/// state for this to return the list of emoji indices, otherwise returns
/// `None`.
pub fn get_emoji_indices(&self) -> Option<Vec<i32>> {
self.inner.emoji_index().map(|v| v.iter().map(|i| (*i).into()).collect())
}
/// Get the decimal representation of the short auth string.
///
/// *Note*: A SAS verification needs to be started and in the presentable
/// state for this to return the list of decimals, otherwise returns
/// `None`.
pub fn get_decimals(&self) -> Option<Vec<i32>> {
self.inner.decimals().map(|v| [v.0.into(), v.1.into(), v.2.into()].to_vec())
}
/// Set a listener for changes in the SAS verification process.
///
/// The given callback will be called whenever the state changes.
///
/// This method can be used to react to changes in the state of the
/// verification process, or rather the method can be used to handle
/// each step of the verification process.
///
/// This method will spawn a tokio task on the Rust side, once we reach the
/// Done or Cancelled state, the task will stop listening for changes.
///
/// # Flowchart
///
/// The flow of the verification process is pictured bellow. Please note
/// that the process can be cancelled at each step of the process.
/// Either side can cancel the process.
///
/// ```text
/// ┌───────┐
/// │Started│
/// └───┬───┘
/// │
/// ┌────⌄───┐
/// │Accepted│
/// └────┬───┘
/// │
/// ┌───────⌄──────┐
/// │Keys Exchanged│
/// └───────┬──────┘
/// │
/// ________⌄________
/// ╲ ┌─────────┐
/// Does the short ╲______│Cancelled│
/// ╲ auth string match no └─────────┘
/// ╲_________________
/// │yes
/// │
/// ┌────⌄────┐
/// │Confirmed│
/// └────┬────┘
/// │
/// ┌───⌄───┐
/// │ Done │
/// └───────┘
/// ```
pub fn set_changes_listener(&self, listener: Box<dyn SasListener>) {
let stream = self.inner.changes();
self.runtime.spawn(Self::changes_listener(stream, listener));
}
/// Get the current state of the SAS verification process.
pub fn state(&self) -> SasState {
self.inner.state().into()
}
}
impl Sas {
async fn changes_listener(
mut stream: impl Stream<Item = RustSasState> + std::marker::Unpin,
listener: Box<dyn SasListener>,
) {
while let Some(state) = stream.next().await {
// If we receive a done or a cancelled state we're at the end of our road, we
// break out of the loop to deallocate the stream and finish the
// task.
let should_break =
matches!(state, RustSasState::Done { .. } | RustSasState::Cancelled { .. });
listener.on_change(state.into());
if should_break {
break;
}
}
}
}
/// Listener that will be passed over the FFI to report changes to a QrCode
/// verification.
#[uniffi::export(callback_interface)]
pub trait QrCodeListener: Send {
/// The callback that should be called on the Rust side
///
/// # Arguments
///
/// * `state` - The current state of the QrCode verification.
fn on_change(&self, state: QrCodeState);
}
/// An Enum describing the state the QrCode verification is in.
#[derive(uniffi::Enum)]
pub enum QrCodeState {
/// The QR verification has been started.
Started,
/// The QR verification has been scanned by the other side.
Scanned,
/// The scanning of the QR code has been confirmed by us.
Confirmed,
/// We have successfully scanned the QR code and are able to send a
/// reciprocation event.
Reciprocated,
/// The verification process has been successfully concluded.
Done,
/// The verification process has been cancelled.
Cancelled {
/// Information about the reason of the cancellation.
cancel_info: CancelInfo,
},
}
impl From<QrVerificationState> for QrCodeState {
fn from(value: QrVerificationState) -> Self {
match value {
QrVerificationState::Started => Self::Started,
QrVerificationState::Scanned => Self::Scanned,
QrVerificationState::Confirmed => Self::Confirmed,
QrVerificationState::Reciprocated => Self::Reciprocated,
QrVerificationState::Done { .. } => Self::Done,
QrVerificationState::Cancelled(c) => Self::Cancelled { cancel_info: c.into() },
}
}
}
/// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1`
/// verification flow.
#[derive(uniffi::Object)]
pub struct QrCode {
pub(crate) inner: InnerQr,
pub(crate) runtime: Handle,
}
#[uniffi::export]
impl QrCode {
/// Get the user id of the other side.
pub fn other_user_id(&self) -> String {
self.inner.other_user_id().to_string()
}
/// Get the device ID of the other side.
pub fn other_device_id(&self) -> String {
self.inner.other_device_id().to_string()
}
/// Get the unique ID that identifies this QR code verification flow.
pub fn flow_id(&self) -> String {
self.inner.flow_id().as_str().to_owned()
}
/// Get the room id if the verification is happening inside a room.
pub fn room_id(&self) -> Option<String> {
self.inner.room_id().map(|r| r.to_string())
}
/// Is the QR code verification done.
pub fn is_done(&self) -> bool {
self.inner.is_done()
}
/// Has the verification flow been cancelled.
pub fn is_cancelled(&self) -> bool {
self.inner.is_cancelled()
}
/// Did we initiate the verification flow.
pub fn we_started(&self) -> bool {
self.inner.we_started()
}
/// Get the CancelInfo of this QR code verification object.
///
/// Will be `None` if the flow has not been cancelled.
pub fn cancel_info(&self) -> Option<CancelInfo> {
self.inner.cancel_info().map(|c| c.into())
}
/// Has the QR verification been scanned by the other side.
///
/// When the verification object is in this state it's required that the
/// user confirms that the other side has scanned the QR code.
pub fn has_been_scanned(&self) -> bool {
self.inner.has_been_scanned()
}
/// Have we successfully scanned the QR code and are able to send a
/// reciprocation event.
pub fn reciprocated(&self) -> bool {
self.inner.reciprocated()
}
/// Cancel the QR code verification using the given cancel code.
///
/// # Arguments
///
/// * `cancel_code` - The error code for why the verification was cancelled,
/// manual cancellatio usually happens with `m.user` cancel code. The full
/// list of cancel codes can be found in the [spec]
///
/// [spec]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationcancel
pub fn cancel(&self, cancel_code: String) -> Option<OutgoingVerificationRequest> {
self.inner.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
/// Confirm a verification was successful.
///
/// This method should be called if we want to confirm that the other side
/// has scanned our QR code.
pub fn confirm(&self) -> Option<ConfirmVerificationResult> {
self.inner.confirm_scanning().map(|r| ConfirmVerificationResult {
requests: vec![r.into()],
signature_request: None,
})
}
/// Generate data that should be encoded as a QR code.
///
/// This method should be called right before a QR code should be displayed,
/// the returned data is base64 encoded (without padding) and needs to be
/// decoded on the other side before it can be put through a QR code
/// generator.
pub fn generate_qr_code(&self) -> Option<String> {
self.inner.to_bytes().map(base64_encode).ok()
}
/// Set a listener for changes in the QrCode verification process.
///
/// The given callback will be called whenever the state changes.
pub fn set_changes_listener(&self, listener: Box<dyn QrCodeListener>) {
let stream = self.inner.changes();
self.runtime.spawn(Self::changes_listener(stream, listener));
}
/// Get the current state of the QrCode verification process.
pub fn state(&self) -> QrCodeState {
self.inner.state().into()
}
}
impl QrCode {
async fn changes_listener(
mut stream: impl Stream<Item = QrVerificationState> + std::marker::Unpin,
listener: Box<dyn QrCodeListener>,
) {
while let Some(state) = stream.next().await {
// If we receive a done or a cancelled state we're at the end of our road, we
// break out of the loop to deallocate the stream and finish the
// task.
let should_break = matches!(
state,
QrVerificationState::Done { .. } | QrVerificationState::Cancelled { .. }
);
listener.on_change(state.into());
if should_break {
break;
}
}
}
}
/// Information on why a verification flow has been cancelled and by whom.
#[derive(uniffi::Record)]
pub struct CancelInfo {
/// The textual representation of the cancel reason
pub reason: String,
/// The code describing the cancel reason
pub cancel_code: String,
/// Was the verification flow cancelled by us
pub cancelled_by_us: bool,
}
impl From<RustCancelInfo> for CancelInfo {
fn from(c: RustCancelInfo) -> Self {
Self {
reason: c.reason().to_owned(),
cancel_code: c.cancel_code().to_string(),
cancelled_by_us: c.cancelled_by_us(),
}
}
}
/// A result type for starting SAS verifications.
#[derive(uniffi::Record)]
pub struct StartSasResult {
/// The SAS verification object that got created.
pub sas: Arc<Sas>,
/// The request that needs to be sent out to notify the other side that a
/// SAS verification should start.
pub request: OutgoingVerificationRequest,
}
/// A result type for scanning QR codes.
#[derive(uniffi::Record)]
pub struct ScanResult {
/// The QR code verification object that got created.
pub qr: Arc<QrCode>,
/// The request that needs to be sent out to notify the other side that a
/// QR code verification should start.
pub request: OutgoingVerificationRequest,
}
/// A result type for requesting verifications.
#[derive(uniffi::Record)]
pub struct RequestVerificationResult {
/// The verification request object that got created.
pub verification: Arc<VerificationRequest>,
/// The request that needs to be sent out to notify the other side that
/// we're requesting verification to begin.
pub request: OutgoingVerificationRequest,
}
/// A result type for confirming verifications.
#[derive(uniffi::Record)]
pub struct ConfirmVerificationResult {
/// The requests that needs to be sent out to notify the other side that we
/// confirmed the verification.
pub requests: Vec<OutgoingVerificationRequest>,
/// A request that will upload signatures of the verified device or user, if
/// the verification is completed and we're able to sign devices or users
pub signature_request: Option<SignatureUploadRequest>,
}
/// Listener that will be passed over the FFI to report changes to a
/// verification request.
#[uniffi::export(callback_interface)]
pub trait VerificationRequestListener: Send {
/// The callback that should be called on the Rust side
///
/// # Arguments
///
/// * `state` - The current state of the verification request.
fn on_change(&self, state: VerificationRequestState);
}
/// An Enum describing the state the QrCode verification is in.
#[derive(uniffi::Enum)]
pub enum VerificationRequestState {
/// The verification request was sent
Requested,
/// The verification request is ready to start a verification flow.
Ready {
/// The verification methods supported by the other side.
their_methods: Vec<String>,
/// The verification methods supported by the us.
our_methods: Vec<String>,
},
/// The verification flow that was started with this request has finished.
Done,
/// The verification process has been cancelled.
Cancelled {
/// Information about the reason of the cancellation.
cancel_info: CancelInfo,
},
}
/// The verificatoin request object which then can transition into some concrete
/// verification method
#[derive(uniffi::Object)]
pub struct VerificationRequest {
pub(crate) inner: InnerVerificationRequest,
pub(crate) runtime: Handle,
}
#[uniffi::export]
impl VerificationRequest {
/// The id of the other user that is participating in this verification
/// request.
pub fn other_user_id(&self) -> String {
self.inner.other_user().to_string()
}
/// The id of the other device that is participating in this verification.
pub fn other_device_id(&self) -> Option<String> {
self.inner.other_device_id().map(|d| d.to_string())
}
/// Get the unique ID of this verification request
pub fn flow_id(&self) -> String {
self.inner.flow_id().as_str().to_owned()
}
/// Get the room id if the verification is happening inside a room.
pub fn room_id(&self) -> Option<String> {
self.inner.room_id().map(|r| r.to_string())
}
/// Has the verification flow that was started with this request finished.
pub fn is_done(&self) -> bool {
self.inner.is_done()
}
/// Is the verification request ready to start a verification flow.
pub fn is_ready(&self) -> bool {
self.inner.is_ready()
}
/// Did we initiate the verification request
pub fn we_started(&self) -> bool {
self.inner.we_started()
}
/// Has the verification request been answered by another device.
pub fn is_passive(&self) -> bool {
self.inner.is_passive()
}
/// Has the verification flow that been cancelled.
pub fn is_cancelled(&self) -> bool {
self.inner.is_cancelled()
}
/// Get info about the cancellation if the verification request has been
/// cancelled.
pub fn cancel_info(&self) -> Option<CancelInfo> {
self.inner.cancel_info().map(|v| v.into())
}
/// Get the supported verification methods of the other side.
///
/// Will be present only if the other side requested the verification or if
/// we're in the ready state.
pub fn their_supported_methods(&self) -> Option<Vec<String>> {
self.inner.their_supported_methods().map(|m| m.iter().map(|m| m.to_string()).collect())
}
/// Get our own supported verification methods that we advertised.
///
/// Will be present only we requested the verification or if we're in the
/// ready state.
pub fn our_supported_methods(&self) -> Option<Vec<String>> {
self.inner.our_supported_methods().map(|m| m.iter().map(|m| m.to_string()).collect())
}
/// Accept a verification requests that we share with the given user with
/// the given flow id.
///
/// This will move the verification request into the ready state.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to accept the
/// verification requests.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
///
/// * `methods` - A list of verification methods that we want to advertise
/// as supported.
pub fn accept(&self, methods: Vec<String>) -> Option<OutgoingVerificationRequest> {
let methods = methods.into_iter().map(VerificationMethod::from).collect();
self.inner.accept_with_methods(methods).map(|r| r.into())
}
/// Cancel a verification for the given user with the given flow id using
/// the given cancel code.
pub fn cancel(&self) -> Option<OutgoingVerificationRequest> {
self.inner.cancel().map(|r| r.into())
}
/// Transition from a verification request into short auth string based
/// verification.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to start the
/// SAS verification.
///
/// * `flow_id` - The ID of the verification request that initiated the
/// verification flow.
pub fn start_sas_verification(&self) -> Result<Option<StartSasResult>, CryptoStoreError> {
Ok(self.runtime.block_on(self.inner.start_sas())?.map(|(sas, r)| StartSasResult {
sas: Arc::new(Sas { inner: sas, runtime: self.runtime.clone() }),
request: r.into(),
}))
}
/// Transition from a verification request into QR code verification.
///
/// This method should be called when one wants to display a QR code so the
/// other side can scan it and move the QR code verification forward.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to start the
/// QR code verification.
///
/// * `flow_id` - The ID of the verification request that initiated the
/// verification flow.
pub fn start_qr_verification(&self) -> Result<Option<Arc<QrCode>>, CryptoStoreError> {
Ok(self
.runtime
.block_on(self.inner.generate_qr_code())?
.map(|qr| QrCode { inner: qr, runtime: self.runtime.clone() }.into()))
}
/// Pass data from a scanned QR code to an active verification request and
/// transition into QR code verification.
///
/// This requires an active `VerificationRequest` to succeed, returns `None`
/// if no `VerificationRequest` is found or if the QR code data is invalid.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to start the
/// QR code verification.
///
/// * `flow_id` - The ID of the verification request that initiated the
/// verification flow.
///
/// * `data` - The data that was extracted from the scanned QR code as an
/// base64 encoded string, without padding.
pub fn scan_qr_code(&self, data: String) -> Option<ScanResult> {
let data = base64_decode(data).ok()?;
let data = QrVerificationData::from_bytes(data).ok()?;
if let Some(qr) = self.runtime.block_on(self.inner.scan_qr_code(data)).ok()? {
let request = qr.reciprocate()?;
Some(ScanResult {
qr: QrCode { inner: qr, runtime: self.runtime.clone() }.into(),
request: request.into(),
})
} else {
None
}
}
/// Set a listener for changes in the verification request
///
/// The given callback will be called whenever the state changes.
pub fn set_changes_listener(&self, listener: Box<dyn VerificationRequestListener>) {
let stream = self.inner.changes();
self.runtime.spawn(Self::changes_listener(self.inner.to_owned(), stream, listener));
}
/// Get the current state of the verification request.
pub fn state(&self) -> VerificationRequestState {
Self::convert_verification_request(&self.inner, self.inner.state())
}
}
impl VerificationRequest {
fn convert_verification_request(
request: &InnerVerificationRequest,
value: RustVerificationRequestState,
) -> VerificationRequestState {
match value {
// The clients do not need to distinguish `Created` and `Requested` state
RustVerificationRequestState::Created { .. } => VerificationRequestState::Requested,
RustVerificationRequestState::Requested { .. } => VerificationRequestState::Requested,
RustVerificationRequestState::Ready {
their_methods,
our_methods,
other_device_id: _,
} => VerificationRequestState::Ready {
their_methods: their_methods.iter().map(|m| m.to_string()).collect(),
our_methods: our_methods.iter().map(|m| m.to_string()).collect(),
},
RustVerificationRequestState::Done => VerificationRequestState::Done,
RustVerificationRequestState::Transitioned { .. } => {
let their_methods = request
.their_supported_methods()
.expect("The transitioned state should know the other side's methods")
.into_iter()
.map(|m| m.to_string())
.collect();
let our_methods = request
.our_supported_methods()
.expect("The transitioned state should know our own supported methods")
.iter()
.map(|m| m.to_string())
.collect();
VerificationRequestState::Ready { their_methods, our_methods }
}
RustVerificationRequestState::Cancelled(c) => {
VerificationRequestState::Cancelled { cancel_info: c.into() }
}
}
}
async fn changes_listener(
request: InnerVerificationRequest,
mut stream: impl Stream<Item = RustVerificationRequestState> + std::marker::Unpin,
listener: Box<dyn VerificationRequestListener>,
) {
while let Some(state) = stream.next().await {
// If we receive a done or a cancelled state we're at the end of our road, we
// break out of the loop to deallocate the stream and finish the
// task.
let should_break = matches!(
state,
RustVerificationRequestState::Done { .. }
| RustVerificationRequestState::Cancelled { .. }
);
let state = Self::convert_verification_request(&request, state);
listener.on_change(state);
if should_break {
break;
}
}
}
}
@@ -0,0 +1,6 @@
[bindings.kotlin]
package_name = "org.matrix.rustcomponents.sdk.crypto"
cdylib_name = "matrix_sdk_crypto_ffi"
[bindings.swift]
module_name = "MatrixSDKCrypto"
+86
View File
@@ -0,0 +1,86 @@
[package]
name = "matrix-sdk-ffi"
version = "0.2.0"
edition = "2021"
homepage = "https://github.com/matrix-org/matrix-rust-sdk"
keywords = ["matrix", "chat", "messaging", "ffi"]
license = "Apache-2.0"
readme = "README.md"
rust-version = { workspace = true }
repository = "https://github.com/matrix-org/matrix-rust-sdk"
[lib]
crate-type = ["cdylib", "staticlib"]
[features]
default = ["bundled-sqlite"]
bundled-sqlite = ["matrix-sdk/bundled-sqlite"]
[build-dependencies]
uniffi = { workspace = true, features = ["build"] }
vergen = { version = "8.1.3", features = ["build", "git", "gitcl"] }
[dependencies]
anyhow = { workspace = true }
as_variant = { workspace = true }
async-compat = "0.2.1"
base64 = "0.21"
eyeball-im = { workspace = true }
extension-trait = "1.0.1"
futures-core = { workspace = true }
futures-util = { workspace = true }
matrix-sdk-ui = { workspace = true, features = ["e2e-encryption", "uniffi"] }
mime = "0.3.16"
once_cell = { workspace = true }
opentelemetry = "0.21.0"
opentelemetry_sdk = { version = "0.21.0", features = ["rt-tokio"] }
opentelemetry-otlp = { version = "0.14.0", features = ["tokio", "reqwest-client", "http-proto"] }
ruma = { workspace = true, features = ["html", "unstable-unspecified", "unstable-msc3488", "compat-unset-avatar", "unstable-msc3245-v1-compat"] }
sanitize-filename-reader-friendly = "2.2.1"
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
tracing-core = { workspace = true }
tracing-opentelemetry = "0.22.0"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-appender = { version = "0.2.2" }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
tokio-stream = { workspace = true, features = ["time"] }
uniffi = { workspace = true, features = ["tokio"] }
url = "2.2.2"
zeroize = { workspace = true }
uuid = { version = "1.4.1", features = ["v4"] }
language-tags = "0.3.2"
[target.'cfg(target_os = "android")'.dependencies]
log-panics = { version = "2", features = ["with-backtrace"] }
paranoid-android = "0.2.1"
[target.'cfg(target_os = "android")'.dependencies.matrix-sdk]
workspace = true
features = [
"anyhow",
"e2e-encryption",
"experimental-oidc",
"experimental-sliding-sync",
"experimental-widgets",
"markdown",
"rustls-tls", # note: differ from block below
"socks",
"sqlite",
]
[target.'cfg(not(target_os = "android"))'.dependencies.matrix-sdk]
workspace = true
features = [
"anyhow",
"e2e-encryption",
"experimental-oidc",
"experimental-sliding-sync",
"experimental-widgets",
"markdown",
"native-tls", # note: differ from block above
"socks",
"sqlite",
]
+21
View File
@@ -0,0 +1,21 @@
# FFI bindings for the rust matrix SDK
This uses [`uniffi`](https://mozilla.github.io/uniffi-rs/Overview.html) to build the matrix bindings for native support and wasm-bindgen for web-browser assembly support. Please refer to the specific section to figure out how to build and use the bindings for your platform.
# OpenTelemetry support
The bindings have support for OpenTelemetry, allowing for the upload of traces to
any OpenTelemetry collector. This support is provided through the
[`opentelemetry`](https://docs.rs/opentelemetry/latest/opentelemetry/)
crate, which requires the [`protoc`] binary to be installed during the build
process.
## Platforms
### Swift/iOS sync
### Swift/iOS async
TBD
+37
View File
@@ -0,0 +1,37 @@
use std::{env, error::Error};
use vergen::EmitBuilder;
/// Adds a temporary workaround for an issue with the Rust compiler and Android
/// in x86_64 devices: https://github.com/rust-lang/rust/issues/109717.
/// The workaround comes from: https://github.com/mozilla/application-services/pull/5442
fn setup_x86_64_android_workaround() {
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
if target_arch == "x86_64" && target_os == "android" {
let android_ndk_home = env::var("ANDROID_NDK_HOME").expect("ANDROID_NDK_HOME not set");
let build_os = match env::consts::OS {
"linux" => "linux",
"macos" => "darwin",
"windows" => "windows",
_ => panic!(
"Unsupported OS. You must use either Linux, MacOS or Windows to build the crate."
),
};
const DEFAULT_CLANG_VERSION: &str = "14.0.7";
let clang_version =
env::var("NDK_CLANG_VERSION").unwrap_or_else(|_| DEFAULT_CLANG_VERSION.to_owned());
let linux_x86_64_lib_dir = format!(
"toolchains/llvm/prebuilt/{build_os}-x86_64/lib64/clang/{clang_version}/lib/linux/"
);
println!("cargo:rustc-link-search={android_ndk_home}/{linux_x86_64_lib_dir}");
println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
}
}
fn main() -> Result<(), Box<dyn Error>> {
setup_x86_64_android_workaround();
uniffi::generate_scaffolding("./src/api.udl").expect("Building the UDL file failed");
EmitBuilder::builder().git_sha(true).emit()?;
Ok(())
}
+22
View File
@@ -0,0 +1,22 @@
namespace matrix_sdk_ffi {};
dictionary Mentions {
sequence<string> user_ids;
boolean room;
};
interface RoomMessageEventContentWithoutRelation {
RoomMessageEventContentWithoutRelation with_mentions(Mentions mentions);
};
[Error]
interface ClientError {
Generic(string msg);
};
interface MediaSource {
[Name=from_json, Throws=ClientError]
constructor(string json);
string to_json();
string url();
};
@@ -0,0 +1,615 @@
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use matrix_sdk::{
oidc::{
types::{
client_credentials::ClientCredentials,
errors::ClientErrorCode::AccessDenied,
iana::oauth::OAuthClientAuthenticationMethod,
oidc::ApplicationType,
registration::{ClientMetadata, Localized, VerifiedClientMetadata},
requests::{GrantType, Prompt},
},
AuthorizationResponse, Oidc, OidcError,
},
AuthSession,
};
use matrix_sdk_ui::authentication::oidc::{ClientId, OidcRegistrations, OidcRegistrationsError};
use ruma::{
api::client::discovery::discover_homeserver::AuthenticationServerInfo, IdParseError,
OwnedUserId,
};
use url::Url;
use zeroize::Zeroize;
use super::{client::Client, client_builder::ClientBuilder, RUNTIME};
use crate::{client::ClientSessionDelegate, client_builder::UrlScheme, error::ClientError};
#[derive(uniffi::Object)]
pub struct AuthenticationService {
base_path: String,
passphrase: Option<String>,
user_agent: Option<String>,
client: RwLock<Option<Arc<Client>>>,
homeserver_details: RwLock<Option<Arc<HomeserverLoginDetails>>>,
oidc_configuration: Option<OidcConfiguration>,
custom_sliding_sync_proxy: RwLock<Option<String>>,
cross_process_refresh_lock_id: Option<String>,
session_delegate: Option<Arc<dyn ClientSessionDelegate>>,
}
impl Drop for AuthenticationService {
fn drop(&mut self) {
self.passphrase.zeroize();
}
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum AuthenticationError {
#[error("A successful call to configure_homeserver must be made first.")]
ClientMissing,
#[error("{message}")]
InvalidServerName { message: String },
#[error("The homeserver doesn't provide a trusted sliding sync proxy in its well-known configuration.")]
SlidingSyncNotAvailable,
#[error("Login was successful but is missing a valid Session to configure the file store.")]
SessionMissing,
#[error("Failed to use the supplied base path.")]
InvalidBasePath,
#[error(
"The homeserver doesn't provide an authentication issuer in its well-known configuration."
)]
OidcNotSupported,
#[error("Unable to use OIDC as no client metadata has been supplied.")]
OidcMetadataMissing,
#[error("Unable to use OIDC as the supplied client metadata is invalid.")]
OidcMetadataInvalid,
#[error("The supplied callback URL used to complete OIDC is invalid.")]
OidcCallbackUrlInvalid,
#[error("The OIDC login was cancelled by the user.")]
OidcCancelled,
#[error("An error occurred with OIDC: {message}")]
OidcError { message: String },
#[error("An error occurred: {message}")]
Generic { message: String },
}
impl From<anyhow::Error> for AuthenticationError {
fn from(e: anyhow::Error) -> AuthenticationError {
AuthenticationError::Generic { message: e.to_string() }
}
}
impl From<IdParseError> for AuthenticationError {
fn from(e: IdParseError) -> AuthenticationError {
AuthenticationError::InvalidServerName { message: e.to_string() }
}
}
impl From<OidcRegistrationsError> for AuthenticationError {
fn from(e: OidcRegistrationsError) -> AuthenticationError {
match e {
OidcRegistrationsError::InvalidBasePath => AuthenticationError::InvalidBasePath,
_ => AuthenticationError::OidcError { message: e.to_string() },
}
}
}
impl From<OidcError> for AuthenticationError {
fn from(e: OidcError) -> AuthenticationError {
AuthenticationError::OidcError { message: e.to_string() }
}
}
/// The configuration to use when authenticating with OIDC.
#[derive(uniffi::Record)]
pub struct OidcConfiguration {
/// The name of the client that will be shown during OIDC authentication.
pub client_name: Option<String>,
/// The redirect URI that will be used when OIDC authentication is
/// successful.
pub redirect_uri: String,
/// A URI that contains information about the client.
pub client_uri: Option<String>,
/// A URI that contains the client's logo.
pub logo_uri: Option<String>,
/// A URI that contains the client's terms of service.
pub tos_uri: Option<String>,
/// A URI that contains the client's privacy policy.
pub policy_uri: Option<String>,
/// An array of e-mail addresses of people responsible for this client.
pub contacts: Option<Vec<String>>,
/// Pre-configured registrations for use with issuers that don't support
/// dynamic client registration.
pub static_registrations: HashMap<String, String>,
}
/// The data required to authenticate against an OIDC server.
#[derive(uniffi::Object)]
pub struct OidcAuthenticationData {
/// The underlying URL for authentication.
url: Url,
/// A unique identifier for the request, used to ensure the response
/// originated from the authentication issuer.
state: String,
}
#[uniffi::export]
impl OidcAuthenticationData {
/// The login URL to use for authentication.
pub fn login_url(&self) -> String {
self.url.to_string()
}
}
#[derive(uniffi::Object)]
pub struct HomeserverLoginDetails {
url: String,
supports_oidc_login: bool,
supports_password_login: bool,
}
#[uniffi::export]
impl HomeserverLoginDetails {
/// The URL of the currently configured homeserver.
pub fn url(&self) -> String {
self.url.clone()
}
/// Whether the current homeserver supports login using OIDC.
pub fn supports_oidc_login(&self) -> bool {
self.supports_oidc_login
}
/// Whether the current homeserver supports the password login flow.
pub fn supports_password_login(&self) -> bool {
self.supports_password_login
}
}
#[uniffi::export]
impl AuthenticationService {
/// Creates a new service to authenticate a user with.
#[uniffi::constructor]
pub fn new(
base_path: String,
passphrase: Option<String>,
user_agent: Option<String>,
oidc_configuration: Option<OidcConfiguration>,
custom_sliding_sync_proxy: Option<String>,
session_delegate: Option<Box<dyn ClientSessionDelegate>>,
cross_process_refresh_lock_id: Option<String>,
) -> Arc<Self> {
Arc::new(AuthenticationService {
base_path,
passphrase,
user_agent,
client: RwLock::new(None),
homeserver_details: RwLock::new(None),
oidc_configuration,
custom_sliding_sync_proxy: RwLock::new(custom_sliding_sync_proxy),
session_delegate: session_delegate.map(Into::into),
cross_process_refresh_lock_id,
})
}
pub fn homeserver_details(&self) -> Option<Arc<HomeserverLoginDetails>> {
self.homeserver_details.read().unwrap().clone()
}
/// Updates the service to authenticate with the homeserver for the
/// specified address.
pub fn configure_homeserver(
&self,
server_name_or_homeserver_url: String,
) -> Result<(), AuthenticationError> {
let mut builder = self.new_client_builder();
// Attempt discovery as a server name first.
let result = matrix_sdk::sanitize_server_name(&server_name_or_homeserver_url);
match result {
Ok(server_name) => {
let protocol = if server_name_or_homeserver_url.starts_with("http://") {
UrlScheme::Http
} else {
UrlScheme::Https
};
builder = builder.server_name_with_protocol(server_name.to_string(), protocol);
}
Err(e) => {
// When the input isn't a valid server name check it is a URL.
// If this is the case, build the client with a homeserver URL.
if Url::parse(&server_name_or_homeserver_url).is_ok() {
builder = builder.homeserver_url(server_name_or_homeserver_url.clone());
} else {
return Err(e.into());
}
}
}
let client = builder.build_inner().or_else(|e| {
if !server_name_or_homeserver_url.starts_with("http://")
&& !server_name_or_homeserver_url.starts_with("https://")
{
return Err(e);
}
// When discovery fails, fallback to the homeserver URL if supplied.
let mut builder = self.new_client_builder();
builder = builder.homeserver_url(server_name_or_homeserver_url);
builder.build_inner()
})?;
let details = RUNTIME.block_on(self.details_from_client(&client))?;
// Now we've verified that it's a valid homeserver, make sure
// there's a sliding sync proxy available one way or another.
if self.custom_sliding_sync_proxy.read().unwrap().is_none()
&& client.discovered_sliding_sync_proxy().is_none()
{
return Err(AuthenticationError::SlidingSyncNotAvailable);
}
*self.client.write().unwrap() = Some(client);
*self.homeserver_details.write().unwrap() = Some(Arc::new(details));
Ok(())
}
/// Performs a password login using the current homeserver.
pub fn login(
&self,
username: String,
password: String,
initial_device_name: Option<String>,
device_id: Option<String>,
) -> Result<Arc<Client>, AuthenticationError> {
let Some(client) = self.client.read().unwrap().clone() else {
return Err(AuthenticationError::ClientMissing);
};
// Login and ask the server for the full user ID as this could be different from
// the username that was entered.
client.login(username, password, initial_device_name, device_id).map_err(|e| match e {
ClientError::Generic { msg } => AuthenticationError::Generic { message: msg },
})?;
let whoami = client.whoami()?;
let session =
client.inner.matrix_auth().session().ok_or(AuthenticationError::SessionMissing)?;
self.finalize_client(client, session, whoami.user_id)
}
/// Requests the URL needed for login in a web view using OIDC. Once the web
/// view has succeeded, call `login_with_oidc_callback` with the callback it
/// returns.
pub fn url_for_oidc_login(&self) -> Result<Arc<OidcAuthenticationData>, AuthenticationError> {
let Some(client) = self.client.read().unwrap().clone() else {
return Err(AuthenticationError::ClientMissing);
};
let Some(authentication_server) = client.discovered_authentication_server() else {
return Err(AuthenticationError::OidcNotSupported);
};
let Some(oidc_configuration) = &self.oidc_configuration else {
return Err(AuthenticationError::OidcMetadataMissing);
};
let redirect_url = Url::parse(&oidc_configuration.redirect_uri)
.map_err(|_e| AuthenticationError::OidcMetadataInvalid)?;
let oidc = client.inner.oidc();
RUNTIME.block_on(async {
self.configure_oidc(&oidc, authentication_server, oidc_configuration).await?;
let mut data_builder = oidc.login(redirect_url, None)?;
// TODO: Add a check for the Consent prompt when MAS is updated.
data_builder = data_builder.prompt(vec![Prompt::Consent]);
let data = data_builder.build().await?;
Ok(Arc::new(OidcAuthenticationData { url: data.url, state: data.state }))
})
}
/// Completes the OIDC login process.
pub fn login_with_oidc_callback(
&self,
authentication_data: Arc<OidcAuthenticationData>,
callback_url: String,
) -> Result<Arc<Client>, AuthenticationError> {
let Some(client) = self.client.read().unwrap().clone() else {
return Err(AuthenticationError::ClientMissing);
};
let oidc = client.inner.oidc();
let url =
Url::parse(&callback_url).map_err(|_| AuthenticationError::OidcCallbackUrlInvalid)?;
let response = AuthorizationResponse::parse_uri(&url)
.map_err(|_| AuthenticationError::OidcCallbackUrlInvalid)?;
let code = match response {
AuthorizationResponse::Success(code) => code,
AuthorizationResponse::Error(err) => {
if err.error.error == AccessDenied {
// The user cancelled the login in the web view.
return Err(AuthenticationError::OidcCancelled);
}
return Err(AuthenticationError::OidcError {
message: err.error.error.to_string(),
});
}
};
if code.state != authentication_data.state {
return Err(AuthenticationError::OidcCallbackUrlInvalid);
};
RUNTIME.block_on(async move {
oidc.finish_authorization(code).await?;
oidc.finish_login()
.await
.map_err(|e| AuthenticationError::OidcError { message: e.to_string() })
})?;
let user_id = client.inner.user_id().unwrap().to_owned();
let session =
client.inner.oidc().full_session().ok_or(AuthenticationError::SessionMissing)?;
self.finalize_client(client, session, user_id)
}
}
impl AuthenticationService {
/// A new client builder pre-configured with the service's base path and
/// user agent if specified
fn new_client_builder(&self) -> Arc<ClientBuilder> {
let mut builder = ClientBuilder::new().base_path(self.base_path.clone());
if let Some(user_agent) = self.user_agent.clone() {
builder = builder.user_agent(user_agent);
}
builder
}
/// Get the homeserver login details from a client.
async fn details_from_client(
&self,
client: &Arc<Client>,
) -> Result<HomeserverLoginDetails, AuthenticationError> {
let supports_oidc_login = client.discovered_authentication_server().is_some();
let supports_password_login = client.supports_password_login().await.ok().unwrap_or(false);
let url = client.homeserver();
Ok(HomeserverLoginDetails { url, supports_oidc_login, supports_password_login })
}
/// Handle any necessary configuration in order for login via OIDC to
/// succeed. This includes performing dynamic client registration against
/// the homeserver's issuer or restoring a previous registration if one has
/// been stored.
async fn configure_oidc(
&self,
oidc: &Oidc,
authentication_server: AuthenticationServerInfo,
configuration: &OidcConfiguration,
) -> Result<(), AuthenticationError> {
if oidc.client_credentials().is_some() {
tracing::info!("OIDC is already configured.");
return Ok(());
};
let oidc_metadata = self.oidc_metadata(configuration)?;
if self.load_client_registration(oidc, &authentication_server, oidc_metadata.clone()).await
{
tracing::info!("OIDC configuration loaded from disk.");
return Ok(());
}
tracing::info!("Registering this client for OIDC.");
let registration_response = oidc
.register_client(&authentication_server.issuer, oidc_metadata.clone(), None)
.await?;
// The format of the credentials changes according to the client metadata that
// was sent. Public clients only get a client ID.
let credentials =
ClientCredentials::None { client_id: registration_response.client_id.clone() };
oidc.restore_registered_client(authentication_server, oidc_metadata, credentials);
tracing::info!("Persisting OIDC registration data.");
self.store_client_registration(oidc).await?;
Ok(())
}
/// Stores the current OIDC dynamic client registration so it can be re-used
/// if we ever log in via the same issuer again.
async fn store_client_registration(&self, oidc: &Oidc) -> Result<(), AuthenticationError> {
let issuer = Url::parse(oidc.issuer().ok_or(AuthenticationError::OidcNotSupported)?)
.map_err(|_| AuthenticationError::OidcError {
message: String::from("Failed to parse issuer URL."),
})?;
let client_id = oidc
.client_credentials()
.ok_or(AuthenticationError::OidcError {
message: String::from("Missing client registration."),
})?
.client_id()
.to_owned();
let metadata = oidc.client_metadata().ok_or(AuthenticationError::OidcError {
message: String::from("Missing client metadata."),
})?;
let registrations = OidcRegistrations::new(
&self.base_path,
metadata.clone(),
self.oidc_static_registrations(),
)?;
registrations.set_and_write_client_id(ClientId(client_id), issuer)?;
Ok(())
}
/// Attempts to load an existing OIDC dynamic client registration for the
/// currently configured issuer.
async fn load_client_registration(
&self,
oidc: &Oidc,
authentication_server: &AuthenticationServerInfo,
oidc_metadata: VerifiedClientMetadata,
) -> bool {
let Ok(issuer) = Url::parse(&authentication_server.issuer) else {
tracing::error!("Failed to parse {:?}", authentication_server.issuer);
return false;
};
let Some(registrations) = OidcRegistrations::new(
&self.base_path,
oidc_metadata.clone(),
self.oidc_static_registrations(),
)
.ok() else {
return false;
};
let Some(client_id) = registrations.client_id(&issuer) else {
return false;
};
oidc.restore_registered_client(
authentication_server.clone(),
oidc_metadata,
ClientCredentials::None { client_id: client_id.0 },
);
true
}
/// Creates and verifies OIDC client metadata for the supplied OIDC
/// configuration.
fn oidc_metadata(
&self,
configuration: &OidcConfiguration,
) -> Result<VerifiedClientMetadata, AuthenticationError> {
let redirect_uri = Url::parse(&configuration.redirect_uri)
.map_err(|_| AuthenticationError::OidcCallbackUrlInvalid)?;
let client_name =
configuration.client_name.as_ref().map(|n| Localized::new(n.to_owned(), []));
let client_uri = configuration.client_uri.localized_url()?;
let logo_uri = configuration.logo_uri.localized_url()?;
let policy_uri = configuration.policy_uri.localized_url()?;
let tos_uri = configuration.tos_uri.localized_url()?;
let contacts = configuration.contacts.clone();
ClientMetadata {
application_type: Some(ApplicationType::Native),
redirect_uris: Some(vec![redirect_uri]),
grant_types: Some(vec![GrantType::RefreshToken, GrantType::AuthorizationCode]),
// A native client shouldn't use authentication as the credentials could be intercepted.
token_endpoint_auth_method: Some(OAuthClientAuthenticationMethod::None),
// The server should display the following fields when getting the user's consent.
client_name,
contacts,
client_uri,
logo_uri,
policy_uri,
tos_uri,
..Default::default()
}
.validate()
.map_err(|_| AuthenticationError::OidcMetadataInvalid)
}
fn oidc_static_registrations(&self) -> HashMap<Url, ClientId> {
let registrations = self
.oidc_configuration
.as_ref()
.map(|c| c.static_registrations.clone())
.unwrap_or_default();
registrations
.iter()
.filter_map(|(issuer, client_id)| {
let Ok(issuer) = Url::parse(issuer) else {
tracing::error!("Failed to parse {:?}", issuer);
return None;
};
Some((issuer, ClientId(client_id.clone())))
})
.collect()
}
/// Creates a new client to setup the store path now the user ID is known.
fn finalize_client(
&self,
client: Arc<Client>,
session: impl Into<AuthSession>,
user_id: OwnedUserId,
) -> Result<Arc<Client>, AuthenticationError> {
let homeserver_url = client.homeserver();
let sliding_sync_proxy: Option<String>;
if let Some(custom_proxy) = self.custom_sliding_sync_proxy.read().unwrap().clone() {
sliding_sync_proxy = Some(custom_proxy);
} else if let Some(discovered_proxy) = client.discovered_sliding_sync_proxy() {
sliding_sync_proxy = Some(discovered_proxy.to_string());
} else {
sliding_sync_proxy = None;
}
let mut client = self
.new_client_builder()
.passphrase(self.passphrase.clone())
.homeserver_url(homeserver_url)
.sliding_sync_proxy(sliding_sync_proxy)
.username(user_id.to_string());
if let Some(id) = &self.cross_process_refresh_lock_id {
let Some(ref session_delegate) = self.session_delegate else {
return Err(AuthenticationError::OidcError {
message: "cross-process refresh lock requires session delegate".to_owned(),
});
};
client = client
.enable_cross_process_refresh_lock_inner(id.clone(), session_delegate.clone());
} else if let Some(ref session_delegate) = self.session_delegate {
client = client.set_session_delegate_inner(session_delegate.clone());
}
let client = client.build_inner()?;
// Restore the client using the session from the login request.
client.restore_session_inner(session)?;
Ok(client)
}
}
trait OptionExt {
/// Convenience method to convert a string to a URL and returns it as a
/// Localized URL. No localization is actually performed.
fn localized_url(&self) -> Result<Option<Localized<Url>>, AuthenticationError>;
}
impl OptionExt for Option<String> {
fn localized_url(&self) -> Result<Option<Localized<Url>>, AuthenticationError> {
self.as_deref()
.map(|uri| -> Result<Localized<Url>, AuthenticationError> {
Ok(Localized::new(
Url::parse(uri).map_err(|_| AuthenticationError::OidcMetadataInvalid)?,
[],
))
})
.transpose()
}
}
@@ -0,0 +1,66 @@
//! A generic `ChunkIterator` that operates over a `Vec`.
//!
//! This type is not designed to work over FFI, but it can be embedded inside an
//! `uniffi::Object` for example.
use std::{cmp, mem, sync::RwLock};
pub struct ChunkIterator<T> {
items: RwLock<Vec<T>>,
}
impl<T> ChunkIterator<T> {
pub fn new(items: Vec<T>) -> Self {
Self { items: RwLock::new(items) }
}
pub fn len(&self) -> u32 {
self.items.read().unwrap().len().try_into().unwrap()
}
pub fn next(&self, chunk_size: u32) -> Option<Vec<T>> {
if self.items.read().unwrap().is_empty() {
None
} else if chunk_size == 0 {
Some(Vec::new())
} else {
let mut items = self.items.write().unwrap();
// Compute the `chunk_size`.
let chunk_size = cmp::min(items.len(), chunk_size.try_into().unwrap());
// Split the items vector.
let mut tail = items.split_off(chunk_size);
// `Vec::split_off` returns the tail, and `items` contains the head. Let's
// swap them.
mem::swap(&mut tail, &mut items);
// Finally, let's rename `tail` to `head`.
let head = tail;
Some(head)
}
}
}
#[cfg(test)]
mod tests {
use super::ChunkIterator;
#[test]
fn test_len() {
assert_eq!(ChunkIterator::<u8>::new(vec![1, 2, 3]).len(), 3);
assert_eq!(ChunkIterator::<u8>::new(vec![]).len(), 0);
}
#[test]
fn test_next() {
let iterator = ChunkIterator::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
assert_eq!(iterator.next(3), Some(vec![1, 2, 3]));
assert_eq!(iterator.next(5), Some(vec![4, 5, 6, 7, 8]));
assert_eq!(iterator.next(0), Some(vec![]));
assert_eq!(iterator.next(1), Some(vec![9]));
assert_eq!(iterator.next(3), Some(vec![10, 11]));
assert_eq!(iterator.next(2), None);
assert_eq!(iterator.next(2), None);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,277 @@
use std::{fs, path::PathBuf, sync::Arc};
use matrix_sdk::{
encryption::{BackupDownloadStrategy, EncryptionSettings},
ruma::{
api::{error::UnknownVersionError, MatrixVersion},
ServerName, UserId,
},
Client as MatrixClient, ClientBuilder as MatrixClientBuilder,
};
use sanitize_filename_reader_friendly::sanitize;
use url::Url;
use zeroize::Zeroizing;
use super::{client::Client, RUNTIME};
use crate::{client::ClientSessionDelegate, error::ClientError, helpers::unwrap_or_clone_arc};
#[derive(Clone)]
pub(crate) enum UrlScheme {
Http,
Https,
}
#[derive(Clone, uniffi::Object)]
pub struct ClientBuilder {
base_path: Option<String>,
username: Option<String>,
server_name: Option<(String, UrlScheme)>,
homeserver_url: Option<String>,
server_versions: Option<Vec<String>>,
passphrase: Zeroizing<Option<String>>,
user_agent: Option<String>,
sliding_sync_proxy: Option<String>,
proxy: Option<String>,
disable_ssl_verification: bool,
disable_automatic_token_refresh: bool,
inner: MatrixClientBuilder,
cross_process_refresh_lock_id: Option<String>,
session_delegate: Option<Arc<dyn ClientSessionDelegate>>,
}
#[uniffi::export]
impl ClientBuilder {
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
Arc::new(Self::default())
}
pub fn enable_cross_process_refresh_lock(
self: Arc<Self>,
process_id: String,
session_delegate: Box<dyn ClientSessionDelegate>,
) -> Arc<Self> {
self.enable_cross_process_refresh_lock_inner(process_id, session_delegate.into())
}
pub fn set_session_delegate(
self: Arc<Self>,
session_delegate: Box<dyn ClientSessionDelegate>,
) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.session_delegate = Some(session_delegate.into());
Arc::new(builder)
}
pub fn base_path(self: Arc<Self>, path: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.base_path = Some(path);
Arc::new(builder)
}
pub fn username(self: Arc<Self>, username: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.username = Some(username);
Arc::new(builder)
}
pub fn server_versions(self: Arc<Self>, versions: Vec<String>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.server_versions = Some(versions);
Arc::new(builder)
}
pub fn server_name(self: Arc<Self>, server_name: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
// Assume HTTPS if no protocol is provided.
builder.server_name = Some((server_name, UrlScheme::Https));
Arc::new(builder)
}
pub fn homeserver_url(self: Arc<Self>, url: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.homeserver_url = Some(url);
Arc::new(builder)
}
pub fn passphrase(self: Arc<Self>, passphrase: Option<String>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.passphrase = Zeroizing::new(passphrase);
Arc::new(builder)
}
pub fn user_agent(self: Arc<Self>, user_agent: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.user_agent = Some(user_agent);
Arc::new(builder)
}
pub fn sliding_sync_proxy(self: Arc<Self>, sliding_sync_proxy: Option<String>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.sliding_sync_proxy = sliding_sync_proxy;
Arc::new(builder)
}
pub fn proxy(self: Arc<Self>, url: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.proxy = Some(url);
Arc::new(builder)
}
pub fn disable_ssl_verification(self: Arc<Self>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.disable_ssl_verification = true;
Arc::new(builder)
}
pub fn disable_automatic_token_refresh(self: Arc<Self>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.disable_automatic_token_refresh = true;
Arc::new(builder)
}
pub fn build(self: Arc<Self>) -> Result<Arc<Client>, ClientError> {
Ok(self.build_inner()?)
}
}
impl ClientBuilder {
pub(crate) fn enable_cross_process_refresh_lock_inner(
self: Arc<Self>,
process_id: String,
session_delegate: Arc<dyn ClientSessionDelegate>,
) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.cross_process_refresh_lock_id = Some(process_id);
builder.session_delegate = Some(session_delegate);
Arc::new(builder)
}
pub(crate) fn set_session_delegate_inner(
self: Arc<Self>,
session_delegate: Arc<dyn ClientSessionDelegate>,
) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.session_delegate = Some(session_delegate);
Arc::new(builder)
}
pub(crate) fn server_name_with_protocol(
self: Arc<Self>,
server_name: String,
protocol: UrlScheme,
) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.server_name = Some((server_name, protocol));
Arc::new(builder)
}
pub(crate) fn build_inner(self: Arc<Self>) -> anyhow::Result<Arc<Client>> {
let builder = unwrap_or_clone_arc(self);
let mut inner_builder = builder.inner;
if let (Some(base_path), Some(username)) = (builder.base_path, &builder.username) {
// Determine store path
let data_path = PathBuf::from(base_path).join(sanitize(username));
fs::create_dir_all(&data_path)?;
inner_builder = inner_builder.sqlite_store(&data_path, builder.passphrase.as_deref());
}
// Determine server either from URL, server name or user ID.
if let Some(homeserver_url) = builder.homeserver_url {
inner_builder = inner_builder.homeserver_url(homeserver_url);
} else if let Some((server_name, protocol)) = builder.server_name {
let server_name = ServerName::parse(server_name)?;
inner_builder = match protocol {
UrlScheme::Http => inner_builder.insecure_server_name_no_tls(&server_name),
UrlScheme::Https => inner_builder.server_name(&server_name),
};
} else if let Some(username) = builder.username {
let user = UserId::parse(username)?;
inner_builder = inner_builder.server_name(user.server_name());
} else {
anyhow::bail!(
"Failed to build: One of homeserver_url, server_name or username must be called."
);
}
if let Some(proxy) = builder.proxy {
inner_builder = inner_builder.proxy(proxy);
}
if builder.disable_ssl_verification {
inner_builder = inner_builder.disable_ssl_verification();
}
if !builder.disable_automatic_token_refresh {
inner_builder = inner_builder.handle_refresh_tokens();
}
if let Some(user_agent) = builder.user_agent {
inner_builder = inner_builder.user_agent(user_agent);
}
if let Some(server_versions) = builder.server_versions {
inner_builder = inner_builder.server_versions(
server_versions
.iter()
.map(|s| MatrixVersion::try_from(s.as_str()))
.collect::<Result<Vec<MatrixVersion>, UnknownVersionError>>()?,
);
}
let sdk_client = RUNTIME.block_on(async move { inner_builder.build().await })?;
// At this point, `sdk_client` might contain a `sliding_sync_proxy` that has
// been configured by the homeserver (if it's a `ServerName` and the
// `.well-known` file is filled as expected).
//
// If `builder.sliding_sync_proxy` contains `Some(_)`, it means one wants to
// overwrite this value. It would be an error to call
// `sdk_client.set_sliding_sync_proxy()` with `None`, as it would erase the
// `sliding_sync_proxy` if any, and it's not the intended behavior.
//
// So let's call `sdk_client.set_sliding_sync_proxy()` if and only if there is
// `Some(_)` value in `builder.sliding_sync_proxy`. That's really important: It
// might not break an existing app session, but it is likely to break a new
// session, which not immediate to detect if there is no test.
if let Some(sliding_sync_proxy) = builder.sliding_sync_proxy {
sdk_client.set_sliding_sync_proxy(Some(Url::parse(&sliding_sync_proxy)?));
}
Ok(Client::new(
sdk_client,
builder.cross_process_refresh_lock_id,
builder.session_delegate,
)?)
}
}
impl Default for ClientBuilder {
fn default() -> Self {
let encryption_settings = EncryptionSettings {
auto_enable_cross_signing: true,
auto_enable_backups: true,
backup_download_strategy: BackupDownloadStrategy::AfterDecryptionFailure,
};
let inner = MatrixClient::builder().with_encryption_settings(encryption_settings);
Self {
base_path: None,
username: None,
server_name: None,
homeserver_url: None,
server_versions: None,
passphrase: Zeroizing::new(None),
user_agent: None,
sliding_sync_proxy: None,
proxy: None,
disable_ssl_verification: false,
disable_automatic_token_refresh: false,
inner,
cross_process_refresh_lock_id: None,
session_delegate: None,
}
}
}
+329
View File
@@ -0,0 +1,329 @@
use std::sync::Arc;
use futures_util::StreamExt;
use matrix_sdk::encryption::{backups, recovery};
use thiserror::Error;
use zeroize::Zeroize;
use super::RUNTIME;
use crate::{error::ClientError, task_handle::TaskHandle};
#[derive(uniffi::Object)]
pub struct Encryption {
inner: matrix_sdk::encryption::Encryption,
}
impl From<matrix_sdk::encryption::Encryption> for Encryption {
fn from(value: matrix_sdk::encryption::Encryption) -> Self {
Self { inner: value }
}
}
#[uniffi::export(callback_interface)]
pub trait BackupStateListener: Sync + Send {
fn on_update(&self, status: BackupState);
}
#[uniffi::export(callback_interface)]
pub trait BackupSteadyStateListener: Sync + Send {
fn on_update(&self, status: BackupUploadState);
}
#[uniffi::export(callback_interface)]
pub trait RecoveryStateListener: Sync + Send {
fn on_update(&self, status: RecoveryState);
}
#[derive(uniffi::Enum)]
pub enum BackupUploadState {
Waiting,
Uploading { backed_up_count: u32, total_count: u32 },
Error,
Done,
}
#[derive(Debug, Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum SteadyStateError {
#[error("The backup got disabled while waiting for the room keys to be uploaded.")]
BackupDisabled,
#[error("There was a connection error.")]
Connection,
#[error("We couldn't read status updates from the upload task quickly enough.")]
Lagged,
}
#[derive(Debug, Error, uniffi::Error)]
pub enum RecoveryError {
/// A backup already exists on the homeserver, the recovery subsystem does
/// not allow backups to be overwritten, disable recovery first.
#[error(
"A backup already exists on the homeserver and the method does not allow to overwrite it"
)]
BackupExistsOnServer,
/// A typical SDK error.
#[error(transparent)]
Client { source: crate::ClientError },
/// Error in the secret storage subsystem.
#[error("Error in the secret-storage subsystem: {error_message}")]
SecretStorage { error_message: String },
}
impl From<matrix_sdk::encryption::recovery::RecoveryError> for RecoveryError {
fn from(value: matrix_sdk::encryption::recovery::RecoveryError) -> Self {
match value {
recovery::RecoveryError::BackupExistsOnServer => Self::BackupExistsOnServer,
recovery::RecoveryError::Sdk(e) => Self::Client { source: ClientError::from(e) },
recovery::RecoveryError::SecretStorage(e) => {
Self::SecretStorage { error_message: e.to_string() }
}
}
}
}
pub type Result<A, E = RecoveryError> = std::result::Result<A, E>;
impl From<matrix_sdk::encryption::backups::futures::SteadyStateError> for SteadyStateError {
fn from(value: matrix_sdk::encryption::backups::futures::SteadyStateError) -> Self {
match value {
backups::futures::SteadyStateError::BackupDisabled => Self::BackupDisabled,
backups::futures::SteadyStateError::Connection => Self::Connection,
backups::futures::SteadyStateError::Lagged => Self::Lagged,
}
}
}
#[derive(uniffi::Enum)]
pub enum BackupState {
Unknown,
Creating,
Enabling,
Resuming,
Enabled,
Downloading,
Disabling,
}
impl From<backups::BackupState> for BackupState {
fn from(value: backups::BackupState) -> Self {
match value {
backups::BackupState::Unknown => Self::Unknown,
backups::BackupState::Creating => Self::Creating,
backups::BackupState::Enabling => Self::Enabling,
backups::BackupState::Resuming => Self::Resuming,
backups::BackupState::Enabled => Self::Enabled,
backups::BackupState::Downloading => Self::Downloading,
backups::BackupState::Disabling => Self::Disabling,
}
}
}
impl From<backups::UploadState> for BackupUploadState {
fn from(value: backups::UploadState) -> Self {
match value {
backups::UploadState::Idle => Self::Waiting,
backups::UploadState::Uploading(count) => Self::Uploading {
backed_up_count: count.backed_up.try_into().unwrap_or(u32::MAX),
total_count: count.total.try_into().unwrap_or(u32::MAX),
},
backups::UploadState::Error => Self::Error,
backups::UploadState::Done => Self::Done,
}
}
}
#[derive(uniffi::Enum)]
pub enum RecoveryState {
Unknown,
Enabled,
Disabled,
Incomplete,
}
impl From<recovery::RecoveryState> for RecoveryState {
fn from(value: recovery::RecoveryState) -> Self {
match value {
recovery::RecoveryState::Unknown => Self::Unknown,
recovery::RecoveryState::Enabled => Self::Enabled,
recovery::RecoveryState::Disabled => Self::Disabled,
recovery::RecoveryState::Incomplete => Self::Incomplete,
}
}
}
#[uniffi::export(callback_interface)]
pub trait EnableRecoveryProgressListener: Sync + Send {
fn on_update(&self, status: EnableRecoveryProgress);
}
#[derive(uniffi::Enum)]
pub enum EnableRecoveryProgress {
Starting,
CreatingBackup,
CreatingRecoveryKey,
BackingUp { backed_up_count: u32, total_count: u32 },
RoomKeyUploadError,
Done { recovery_key: String },
}
impl From<recovery::EnableProgress> for EnableRecoveryProgress {
fn from(value: recovery::EnableProgress) -> Self {
match &value {
recovery::EnableProgress::Starting => Self::Starting,
recovery::EnableProgress::CreatingBackup => Self::CreatingBackup,
recovery::EnableProgress::CreatingRecoveryKey => Self::CreatingRecoveryKey,
recovery::EnableProgress::BackingUp(counts) => Self::BackingUp {
backed_up_count: counts.backed_up.try_into().unwrap_or(u32::MAX),
total_count: counts.backed_up.try_into().unwrap_or(u32::MAX),
},
recovery::EnableProgress::RoomKeyUploadError => Self::RoomKeyUploadError,
recovery::EnableProgress::Done { recovery_key } => {
Self::Done { recovery_key: recovery_key.to_owned() }
}
}
}
}
#[uniffi::export(async_runtime = "tokio")]
impl Encryption {
pub fn backup_state_listener(&self, listener: Box<dyn BackupStateListener>) -> Arc<TaskHandle> {
let mut stream = self.inner.backups().state_stream();
let stream_task = TaskHandle::new(RUNTIME.spawn(async move {
while let Some(state) = stream.next().await {
let Ok(state) = state else { continue };
listener.on_update(state.into());
}
}));
stream_task.into()
}
pub fn backup_state(&self) -> BackupState {
self.inner.backups().state().into()
}
/// Does a backup exist on the server?
///
/// Because the homeserver doesn't notify us about changes to the backup
/// version, the [`BackupState`] and its listener are a bit crippled.
/// The `BackupState::Unknown` state might mean there is no backup at all or
/// a backup exists but we don't have access to it.
///
/// Therefore it is necessary to poll the server for an answer every time
/// you want to differentiate between those two states.
pub async fn backup_exists_on_server(&self) -> Result<bool, ClientError> {
Ok(self.inner.backups().exists_on_server().await?)
}
pub fn recovery_state(&self) -> RecoveryState {
self.inner.recovery().state().into()
}
pub fn recovery_state_listener(
&self,
listener: Box<dyn RecoveryStateListener>,
) -> Arc<TaskHandle> {
let mut stream = self.inner.recovery().state_stream();
let stream_task = TaskHandle::new(RUNTIME.spawn(async move {
while let Some(state) = stream.next().await {
listener.on_update(state.into());
}
}));
stream_task.into()
}
pub async fn enable_backups(&self) -> Result<()> {
Ok(self.inner.recovery().enable_backup().await?)
}
pub async fn is_last_device(&self) -> Result<bool> {
Ok(self.inner.recovery().are_we_the_last_man_standing().await?)
}
pub async fn wait_for_backup_upload_steady_state(
&self,
progress_listener: Option<Box<dyn BackupSteadyStateListener>>,
) -> Result<(), SteadyStateError> {
let backups = self.inner.backups();
let wait_for_steady_state = backups.wait_for_steady_state();
let task = if let Some(listener) = progress_listener {
let mut progress_stream = wait_for_steady_state.subscribe_to_progress();
Some(RUNTIME.spawn(async move {
while let Some(progress) = progress_stream.next().await {
let Ok(progress) = progress else { continue };
listener.on_update(progress.into());
}
}))
} else {
None
};
let result = wait_for_steady_state.await;
if let Some(task) = task {
task.abort();
}
Ok(result?)
}
pub async fn enable_recovery(
&self,
wait_for_backups_to_upload: bool,
progress_listener: Box<dyn EnableRecoveryProgressListener>,
) -> Result<String> {
let recovery = self.inner.recovery();
let enable = if wait_for_backups_to_upload {
recovery.enable().wait_for_backups_to_upload()
} else {
recovery.enable()
};
let mut progress_stream = enable.subscribe_to_progress();
let task = RUNTIME.spawn(async move {
while let Some(progress) = progress_stream.next().await {
let Ok(progress) = progress else { continue };
progress_listener.on_update(progress.into());
}
});
let ret = enable.await?;
task.abort();
Ok(ret)
}
pub async fn disable_recovery(&self) -> Result<()> {
Ok(self.inner.recovery().disable().await?)
}
pub async fn reset_recovery_key(&self) -> Result<String> {
Ok(self.inner.recovery().reset_key().await?)
}
pub async fn recover_and_reset(&self, mut old_recovery_key: String) -> Result<String> {
let result = self.inner.recovery().recover_and_reset(&old_recovery_key).await;
old_recovery_key.zeroize();
Ok(result?)
}
pub async fn recover(&self, mut recovery_key: String) -> Result<()> {
let result = self.inner.recovery().recover(&recovery_key).await;
recovery_key.zeroize();
Ok(result?)
}
}
+188
View File
@@ -0,0 +1,188 @@
use std::fmt::Display;
use matrix_sdk::{
self, encryption::CryptoStoreError, oidc::OidcError, HttpError, IdParseError,
NotificationSettingsError as SdkNotificationSettingsError, StoreError,
};
use matrix_sdk_ui::{encryption_sync_service, notification_client, sync_service, timeline};
use uniffi::UnexpectedUniFFICallbackError;
#[derive(Debug, thiserror::Error)]
pub enum ClientError {
#[error("client error: {msg}")]
Generic { msg: String },
}
impl ClientError {
fn new<E: Display>(error: E) -> Self {
Self::Generic { msg: error.to_string() }
}
}
impl From<anyhow::Error> for ClientError {
fn from(e: anyhow::Error) -> ClientError {
ClientError::Generic { msg: format!("{e:#}") }
}
}
impl From<UnexpectedUniFFICallbackError> for ClientError {
fn from(e: UnexpectedUniFFICallbackError) -> Self {
Self::new(e)
}
}
impl From<matrix_sdk::Error> for ClientError {
fn from(e: matrix_sdk::Error) -> Self {
Self::new(e)
}
}
impl From<StoreError> for ClientError {
fn from(e: StoreError) -> Self {
Self::new(e)
}
}
impl From<CryptoStoreError> for ClientError {
fn from(e: CryptoStoreError) -> Self {
Self::new(e)
}
}
impl From<HttpError> for ClientError {
fn from(e: HttpError) -> Self {
Self::new(e)
}
}
impl From<IdParseError> for ClientError {
fn from(e: IdParseError) -> Self {
Self::new(e)
}
}
impl From<serde_json::Error> for ClientError {
fn from(e: serde_json::Error) -> Self {
Self::new(e)
}
}
impl From<url::ParseError> for ClientError {
fn from(e: url::ParseError) -> Self {
Self::new(e)
}
}
impl From<mime::FromStrError> for ClientError {
fn from(e: mime::FromStrError) -> Self {
Self::new(e)
}
}
impl From<encryption_sync_service::Error> for ClientError {
fn from(e: encryption_sync_service::Error) -> Self {
Self::new(e)
}
}
impl From<timeline::Error> for ClientError {
fn from(e: timeline::Error) -> Self {
Self::new(e)
}
}
impl From<notification_client::Error> for ClientError {
fn from(e: notification_client::Error) -> Self {
Self::new(e)
}
}
impl From<sync_service::Error> for ClientError {
fn from(e: sync_service::Error) -> Self {
Self::new(e)
}
}
impl From<OidcError> for ClientError {
fn from(e: OidcError) -> Self {
Self::new(e)
}
}
impl From<RoomError> for ClientError {
fn from(e: RoomError) -> Self {
Self::new(e)
}
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum RoomError {
#[error("Invalid attachment data")]
InvalidAttachmentData,
#[error("Invalid attachment mime type")]
InvalidAttachmentMimeType,
#[error("Invalid media info")]
InvalidMediaInfo,
#[error("Timeline unavailable")]
TimelineUnavailable,
#[error("Invalid thumbnail data")]
InvalidThumbnailData,
#[error("Failed sending attachment")]
FailedSendingAttachment,
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum MediaInfoError {
#[error("Required value missing from the media info")]
MissingField,
#[error("Media info field invalid")]
InvalidField,
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
pub enum NotificationSettingsError {
#[error("client error: {msg}")]
Generic { msg: String },
/// Invalid parameter.
#[error("Invalid parameter: {msg}")]
InvalidParameter { msg: String },
/// Invalid room id.
#[error("Invalid room ID {room_id}")]
InvalidRoomId { room_id: String },
/// Rule not found
#[error("Rule not found: {rule_id}")]
RuleNotFound { rule_id: String },
/// Unable to add push rule.
#[error("Unable to add push rule")]
UnableToAddPushRule,
/// Unable to remove push rule.
#[error("Unable to remove push rule")]
UnableToRemovePushRule,
/// Unable to save the push rules
#[error("Unable to save push rules")]
UnableToSavePushRules,
/// Unable to update push rule.
#[error("Unable to update push rule")]
UnableToUpdatePushRule,
}
impl From<SdkNotificationSettingsError> for NotificationSettingsError {
fn from(value: SdkNotificationSettingsError) -> Self {
match value {
SdkNotificationSettingsError::RuleNotFound(rule_id) => Self::RuleNotFound { rule_id },
SdkNotificationSettingsError::UnableToAddPushRule => Self::UnableToAddPushRule,
SdkNotificationSettingsError::UnableToRemovePushRule => Self::UnableToRemovePushRule,
SdkNotificationSettingsError::UnableToSavePushRules => Self::UnableToSavePushRules,
SdkNotificationSettingsError::InvalidParameter(msg) => Self::InvalidParameter { msg },
SdkNotificationSettingsError::UnableToUpdatePushRule => Self::UnableToUpdatePushRule,
}
}
}
impl From<matrix_sdk::Error> for NotificationSettingsError {
fn from(e: matrix_sdk::Error) -> Self {
Self::Generic { msg: e.to_string() }
}
}
+218
View File
@@ -0,0 +1,218 @@
use anyhow::{bail, Context};
use ruma::events::{
room::message::Relation, AnySyncMessageLikeEvent, AnySyncStateEvent, AnySyncTimelineEvent,
AnyTimelineEvent, MessageLikeEventContent as RumaMessageLikeEventContent, RedactContent,
RedactedStateEventContent, StaticStateEventContent, SyncMessageLikeEvent, SyncStateEvent,
};
use crate::{room_member::MembershipState, ruma::MessageType, ClientError};
#[derive(uniffi::Object)]
pub struct TimelineEvent(pub(crate) AnySyncTimelineEvent);
#[uniffi::export]
impl TimelineEvent {
pub fn event_id(&self) -> String {
self.0.event_id().to_string()
}
pub fn sender_id(&self) -> String {
self.0.sender().to_string()
}
pub fn timestamp(&self) -> u64 {
self.0.origin_server_ts().0.into()
}
pub fn event_type(&self) -> Result<TimelineEventType, ClientError> {
let event_type = match &self.0 {
AnySyncTimelineEvent::MessageLike(event) => {
TimelineEventType::MessageLike { content: event.clone().try_into()? }
}
AnySyncTimelineEvent::State(event) => {
TimelineEventType::State { content: event.clone().try_into()? }
}
};
Ok(event_type)
}
}
impl From<AnyTimelineEvent> for TimelineEvent {
fn from(event: AnyTimelineEvent) -> Self {
Self(event.into())
}
}
#[derive(uniffi::Enum)]
pub enum TimelineEventType {
MessageLike { content: MessageLikeEventContent },
State { content: StateEventContent },
}
#[derive(uniffi::Enum)]
pub enum StateEventContent {
PolicyRuleRoom,
PolicyRuleServer,
PolicyRuleUser,
RoomAliases,
RoomAvatar,
RoomCanonicalAlias,
RoomCreate,
RoomEncryption,
RoomGuestAccess,
RoomHistoryVisibility,
RoomJoinRules,
RoomMemberContent { user_id: String, membership_state: MembershipState },
RoomName,
RoomPinnedEvents,
RoomPowerLevels,
RoomServerAcl,
RoomThirdPartyInvite,
RoomTombstone,
RoomTopic,
SpaceChild,
SpaceParent,
}
impl TryFrom<AnySyncStateEvent> for StateEventContent {
type Error = anyhow::Error;
fn try_from(value: AnySyncStateEvent) -> anyhow::Result<Self> {
let event = match value {
AnySyncStateEvent::PolicyRuleRoom(_) => StateEventContent::PolicyRuleRoom,
AnySyncStateEvent::PolicyRuleServer(_) => StateEventContent::PolicyRuleServer,
AnySyncStateEvent::PolicyRuleUser(_) => StateEventContent::PolicyRuleUser,
AnySyncStateEvent::RoomAliases(_) => StateEventContent::RoomAliases,
AnySyncStateEvent::RoomAvatar(_) => StateEventContent::RoomAvatar,
AnySyncStateEvent::RoomCanonicalAlias(_) => StateEventContent::RoomCanonicalAlias,
AnySyncStateEvent::RoomCreate(_) => StateEventContent::RoomCreate,
AnySyncStateEvent::RoomEncryption(_) => StateEventContent::RoomEncryption,
AnySyncStateEvent::RoomGuestAccess(_) => StateEventContent::RoomGuestAccess,
AnySyncStateEvent::RoomHistoryVisibility(_) => StateEventContent::RoomHistoryVisibility,
AnySyncStateEvent::RoomJoinRules(_) => StateEventContent::RoomJoinRules,
AnySyncStateEvent::RoomMember(content) => {
let state_key = content.state_key().to_string();
let original_content = get_state_event_original_content(content)?;
StateEventContent::RoomMemberContent {
user_id: state_key,
membership_state: original_content.membership.into(),
}
}
AnySyncStateEvent::RoomName(_) => StateEventContent::RoomName,
AnySyncStateEvent::RoomPinnedEvents(_) => StateEventContent::RoomPinnedEvents,
AnySyncStateEvent::RoomPowerLevels(_) => StateEventContent::RoomPowerLevels,
AnySyncStateEvent::RoomServerAcl(_) => StateEventContent::RoomServerAcl,
AnySyncStateEvent::RoomThirdPartyInvite(_) => StateEventContent::RoomThirdPartyInvite,
AnySyncStateEvent::RoomTombstone(_) => StateEventContent::RoomTombstone,
AnySyncStateEvent::RoomTopic(_) => StateEventContent::RoomTopic,
AnySyncStateEvent::SpaceChild(_) => StateEventContent::SpaceChild,
AnySyncStateEvent::SpaceParent(_) => StateEventContent::SpaceParent,
_ => bail!("Unsupported state event"),
};
Ok(event)
}
}
#[derive(uniffi::Enum)]
pub enum MessageLikeEventContent {
CallAnswer,
CallInvite,
CallHangup,
CallCandidates,
KeyVerificationReady,
KeyVerificationStart,
KeyVerificationCancel,
KeyVerificationAccept,
KeyVerificationKey,
KeyVerificationMac,
KeyVerificationDone,
Poll { question: String },
ReactionContent { related_event_id: String },
RoomEncrypted,
RoomMessage { message_type: MessageType, in_reply_to_event_id: Option<String> },
RoomRedaction,
Sticker,
}
impl TryFrom<AnySyncMessageLikeEvent> for MessageLikeEventContent {
type Error = anyhow::Error;
fn try_from(value: AnySyncMessageLikeEvent) -> anyhow::Result<Self> {
let content = match value {
AnySyncMessageLikeEvent::CallAnswer(_) => MessageLikeEventContent::CallAnswer,
AnySyncMessageLikeEvent::CallInvite(_) => MessageLikeEventContent::CallInvite,
AnySyncMessageLikeEvent::CallHangup(_) => MessageLikeEventContent::CallHangup,
AnySyncMessageLikeEvent::CallCandidates(_) => MessageLikeEventContent::CallCandidates,
AnySyncMessageLikeEvent::KeyVerificationReady(_) => {
MessageLikeEventContent::KeyVerificationReady
}
AnySyncMessageLikeEvent::KeyVerificationStart(_) => {
MessageLikeEventContent::KeyVerificationStart
}
AnySyncMessageLikeEvent::KeyVerificationCancel(_) => {
MessageLikeEventContent::KeyVerificationCancel
}
AnySyncMessageLikeEvent::KeyVerificationAccept(_) => {
MessageLikeEventContent::KeyVerificationAccept
}
AnySyncMessageLikeEvent::KeyVerificationKey(_) => {
MessageLikeEventContent::KeyVerificationKey
}
AnySyncMessageLikeEvent::KeyVerificationMac(_) => {
MessageLikeEventContent::KeyVerificationMac
}
AnySyncMessageLikeEvent::KeyVerificationDone(_) => {
MessageLikeEventContent::KeyVerificationDone
}
AnySyncMessageLikeEvent::UnstablePollStart(content) => {
let original_content = get_message_like_event_original_content(content)?;
MessageLikeEventContent::Poll {
question: original_content.poll_start().question.text.clone(),
}
}
AnySyncMessageLikeEvent::Reaction(content) => {
let original_content = get_message_like_event_original_content(content)?;
MessageLikeEventContent::ReactionContent {
related_event_id: original_content.relates_to.event_id.to_string(),
}
}
AnySyncMessageLikeEvent::RoomEncrypted(_) => MessageLikeEventContent::RoomEncrypted,
AnySyncMessageLikeEvent::RoomMessage(content) => {
let original_content = get_message_like_event_original_content(content)?;
let in_reply_to_event_id =
original_content.relates_to.and_then(|relation| match relation {
Relation::Reply { in_reply_to } => Some(in_reply_to.event_id.to_string()),
_ => None,
});
MessageLikeEventContent::RoomMessage {
message_type: original_content.msgtype.into(),
in_reply_to_event_id,
}
}
AnySyncMessageLikeEvent::RoomRedaction(_) => MessageLikeEventContent::RoomRedaction,
AnySyncMessageLikeEvent::Sticker(_) => MessageLikeEventContent::Sticker,
_ => bail!("Unsupported Event Type"),
};
Ok(content)
}
}
fn get_state_event_original_content<C>(event: SyncStateEvent<C>) -> anyhow::Result<C>
where
C: StaticStateEventContent + RedactContent + Clone,
<C as RedactContent>::Redacted: RedactedStateEventContent<StateKey = C::StateKey>,
{
let original_content =
event.as_original().context("Failed to get original content")?.content.clone();
Ok(original_content)
}
fn get_message_like_event_original_content<C>(event: SyncMessageLikeEvent<C>) -> anyhow::Result<C>
where
C: RumaMessageLikeEventContent + RedactContent + Clone,
<C as ruma::events::RedactContent>::Redacted: ruma::events::RedactedMessageLikeEventContent,
{
let original_content =
event.as_original().context("Failed to get original content")?.content.clone();
Ok(original_content)
}
+5
View File
@@ -0,0 +1,5 @@
use std::sync::Arc;
pub(crate) fn unwrap_or_clone_arc<T: Clone>(arc: Arc<T>) -> T {
Arc::try_unwrap(arc).unwrap_or_else(|x| (*x).clone())
}
+63
View File
@@ -0,0 +1,63 @@
// TODO: target-os conditional would be good.
#![allow(unused_qualifications, clippy::new_without_default)]
macro_rules! unwrap_or_clone_arc_into_variant {
(
$arc:ident $(, .$field:tt)?, $pat:pat => $body:expr
) => {
#[allow(unused_variables)]
match &(*$arc)$(.$field)? {
$pat => {
#[warn(unused_variables)]
match crate::helpers::unwrap_or_clone_arc($arc)$(.$field)? {
$pat => Some($body),
_ => unreachable!(),
}
},
_ => None,
}
};
}
mod authentication_service;
mod chunk_iterator;
mod client;
mod client_builder;
mod encryption;
mod error;
mod event;
mod helpers;
mod notification;
mod notification_settings;
mod platform;
mod room;
mod room_info;
mod room_list;
mod room_member;
mod ruma;
mod session_verification;
mod sync_service;
mod task_handle;
mod timeline;
mod tracing;
mod utils;
mod widget;
use async_compat::TOKIO1 as RUNTIME;
use matrix_sdk::ruma::events::room::{
message::RoomMessageEventContentWithoutRelation, MediaSource,
};
use self::{
error::ClientError,
ruma::{MediaSourceExt, Mentions, RoomMessageEventContentWithoutRelationExt},
task_handle::TaskHandle,
};
uniffi::include_scaffolding!("api");
#[uniffi::export]
fn sdk_git_sha() -> String {
env!("VERGEN_GIT_SHA").to_owned()
}
+151
View File
@@ -0,0 +1,151 @@
use std::sync::Arc;
use matrix_sdk_ui::notification_client::{
NotificationClient as MatrixNotificationClient,
NotificationClientBuilder as MatrixNotificationClientBuilder,
NotificationItem as MatrixNotificationItem, NotificationProcessSetup,
};
use ruma::{EventId, RoomId};
use crate::{
client::Client, error::ClientError, event::TimelineEvent, helpers::unwrap_or_clone_arc, RUNTIME,
};
#[derive(uniffi::Enum)]
pub enum NotificationEvent {
Timeline { event: Arc<TimelineEvent> },
Invite { sender: String },
}
#[derive(uniffi::Record)]
pub struct NotificationSenderInfo {
pub display_name: Option<String>,
pub avatar_url: Option<String>,
}
#[derive(uniffi::Record)]
pub struct NotificationRoomInfo {
pub display_name: String,
pub avatar_url: Option<String>,
pub canonical_alias: Option<String>,
pub joined_members_count: u64,
pub is_encrypted: Option<bool>,
pub is_direct: bool,
}
#[derive(uniffi::Record)]
pub struct NotificationItem {
pub event: NotificationEvent,
pub sender_info: NotificationSenderInfo,
pub room_info: NotificationRoomInfo,
/// Is the notification supposed to be at the "noisy" level?
/// Can be `None` if we couldn't determine this, because we lacked
/// information to create a push context.
pub is_noisy: Option<bool>,
pub has_mention: Option<bool>,
}
impl NotificationItem {
fn from_inner(item: MatrixNotificationItem) -> Self {
let event = match item.event {
matrix_sdk_ui::notification_client::NotificationEvent::Timeline(event) => {
NotificationEvent::Timeline { event: Arc::new(TimelineEvent(event)) }
}
matrix_sdk_ui::notification_client::NotificationEvent::Invite(event) => {
NotificationEvent::Invite { sender: event.sender.to_string() }
}
};
Self {
event,
sender_info: NotificationSenderInfo {
display_name: item.sender_display_name,
avatar_url: item.sender_avatar_url,
},
room_info: NotificationRoomInfo {
display_name: item.room_display_name,
avatar_url: item.room_avatar_url,
canonical_alias: item.room_canonical_alias,
joined_members_count: item.joined_members_count,
is_encrypted: item.is_room_encrypted,
is_direct: item.is_direct_message_room,
},
is_noisy: item.is_noisy,
has_mention: item.has_mention,
}
}
}
#[derive(Clone, uniffi::Object)]
pub struct NotificationClientBuilder {
client: Arc<Client>,
builder: MatrixNotificationClientBuilder,
}
impl NotificationClientBuilder {
pub(crate) fn new(
client: Arc<Client>,
process_setup: NotificationProcessSetup,
) -> Result<Arc<Self>, ClientError> {
let builder = RUNTIME.block_on(async {
MatrixNotificationClient::builder((*client.inner).clone(), process_setup).await
})?;
Ok(Arc::new(Self { builder, client }))
}
}
#[uniffi::export]
impl NotificationClientBuilder {
/// Filter out the notification event according to the push rules present in
/// the event.
pub fn filter_by_push_rules(self: Arc<Self>) -> Arc<Self> {
let this = unwrap_or_clone_arc(self);
let builder = this.builder.filter_by_push_rules();
Arc::new(Self { builder, client: this.client })
}
pub fn finish(self: Arc<Self>) -> Arc<NotificationClient> {
let this = unwrap_or_clone_arc(self);
Arc::new(NotificationClient { inner: this.builder.build(), _client: this.client })
}
}
#[derive(uniffi::Object)]
pub struct NotificationClient {
inner: MatrixNotificationClient,
/// A reference to the FFI client.
///
/// Note: we do this to make it so that the FFI `NotificationClient` keeps
/// the FFI `Client` and thus the SDK `Client` alive. Otherwise, we
/// would need to repeat the hack done in the FFI `Client::drop` method.
_client: Arc<Client>,
}
#[uniffi::export]
impl NotificationClient {
/// See also documentation of
/// `MatrixNotificationClient::get_notification`.
pub fn get_notification(
&self,
room_id: String,
event_id: String,
) -> Result<Option<NotificationItem>, ClientError> {
let room_id = RoomId::parse(room_id)?;
let event_id = EventId::parse(event_id)?;
RUNTIME.block_on(async move {
let item = self
.inner
.get_notification(&room_id, &event_id)
.await
.map_err(ClientError::from)?;
if let Some(item) = item {
Ok(Some(NotificationItem::from_inner(item)))
} else {
Ok(None)
}
})
}
}
@@ -0,0 +1,406 @@
use std::sync::Arc;
use matrix_sdk::{
event_handler::EventHandlerHandle,
notification_settings::{
NotificationSettings as SdkNotificationSettings,
RoomNotificationMode as SdkRoomNotificationMode,
},
ruma::events::push_rules::PushRulesEvent,
Client as MatrixClient,
};
use ruma::{
push::{PredefinedOverrideRuleId, PredefinedUnderrideRuleId, RuleKind},
RoomId,
};
use tokio::sync::RwLock;
use super::RUNTIME;
use crate::error::NotificationSettingsError;
/// Enum representing the push notification modes for a room.
#[derive(Clone, uniffi::Enum)]
pub enum RoomNotificationMode {
/// Receive notifications for all messages.
AllMessages,
/// Receive notifications for mentions and keywords only.
MentionsAndKeywordsOnly,
/// Do not receive any notifications.
Mute,
}
impl From<SdkRoomNotificationMode> for RoomNotificationMode {
fn from(value: SdkRoomNotificationMode) -> Self {
match value {
SdkRoomNotificationMode::AllMessages => Self::AllMessages,
SdkRoomNotificationMode::MentionsAndKeywordsOnly => Self::MentionsAndKeywordsOnly,
SdkRoomNotificationMode::Mute => Self::Mute,
}
}
}
impl From<RoomNotificationMode> for SdkRoomNotificationMode {
fn from(value: RoomNotificationMode) -> Self {
match value {
RoomNotificationMode::AllMessages => Self::AllMessages,
RoomNotificationMode::MentionsAndKeywordsOnly => Self::MentionsAndKeywordsOnly,
RoomNotificationMode::Mute => Self::Mute,
}
}
}
/// Delegate to notify of changes in push rules
#[uniffi::export(callback_interface)]
pub trait NotificationSettingsDelegate: Sync + Send {
fn settings_did_change(&self);
}
/// `RoomNotificationSettings` represents the current settings for a `Room`
#[derive(Clone, uniffi::Record)]
pub struct RoomNotificationSettings {
/// The room notification mode
mode: RoomNotificationMode,
/// Whether the mode is the default one
is_default: bool,
}
impl RoomNotificationSettings {
fn new(mode: RoomNotificationMode, is_default: bool) -> Self {
RoomNotificationSettings { mode, is_default }
}
}
#[derive(Clone, uniffi::Object)]
pub struct NotificationSettings {
sdk_client: MatrixClient,
sdk_notification_settings: Arc<RwLock<SdkNotificationSettings>>,
pushrules_event_handler: Arc<RwLock<Option<EventHandlerHandle>>>,
}
impl NotificationSettings {
pub(crate) fn new(
sdk_client: MatrixClient,
sdk_notification_settings: SdkNotificationSettings,
) -> Self {
let sdk_notification_settings = Arc::new(RwLock::new(sdk_notification_settings));
Self {
sdk_client,
sdk_notification_settings,
pushrules_event_handler: Arc::new(RwLock::new(None)),
}
}
}
impl Drop for NotificationSettings {
fn drop(&mut self) {
// Remove the event handler on the sdk_client.
RUNTIME.block_on(async move {
if let Some(event_handler) = self.pushrules_event_handler.read().await.as_ref() {
self.sdk_client.remove_event_handler(event_handler.clone());
}
});
}
}
#[uniffi::export(async_runtime = "tokio")]
impl NotificationSettings {
pub fn set_delegate(&self, delegate: Option<Box<dyn NotificationSettingsDelegate>>) {
if let Some(delegate) = delegate {
let delegate: Arc<dyn NotificationSettingsDelegate> = Arc::from(delegate);
// Add an event handler to listen to `PushRulesEvent`
let event_handler =
self.sdk_client.add_event_handler(move |_: PushRulesEvent| async move {
delegate.settings_did_change();
});
RUNTIME.block_on(async move {
*self.pushrules_event_handler.write().await = Some(event_handler);
});
} else {
// Remove the event handler if there is no delegate
RUNTIME.block_on(async move {
let event_handler = &mut *self.pushrules_event_handler.write().await;
if let Some(event_handler) = event_handler {
self.sdk_client.remove_event_handler(event_handler.clone());
}
*event_handler = None;
});
}
}
/// Get the notification settings for a room.
///
/// # Arguments
///
/// * `room_id` - the room ID
/// * `is_encrypted` - whether the room is encrypted
/// * `is_one_to_one` - whether the room is a direct chat involving two
/// people
pub async fn get_room_notification_settings(
&self,
room_id: String,
is_encrypted: bool,
is_one_to_one: bool,
) -> Result<RoomNotificationSettings, NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let parsed_room_id = RoomId::parse(&room_id)
.map_err(|_e| NotificationSettingsError::InvalidRoomId { room_id })?;
// Get the current user defined mode for this room
if let Some(mode) =
notification_settings.get_user_defined_room_notification_mode(&parsed_room_id).await
{
return Ok(RoomNotificationSettings::new(mode.into(), false));
}
// If the user has not defined a notification mode, return the default one for
// this room
let mode = notification_settings
.get_default_room_notification_mode(is_encrypted.into(), is_one_to_one.into())
.await;
Ok(RoomNotificationSettings::new(mode.into(), true))
}
/// Set the notification mode for a room.
pub async fn set_room_notification_mode(
&self,
room_id: String,
mode: RoomNotificationMode,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let parsed_room_id = RoomId::parse(&room_id)
.map_err(|_e| NotificationSettingsError::InvalidRoomId { room_id })?;
notification_settings.set_room_notification_mode(&parsed_room_id, mode.into()).await?;
Ok(())
}
/// Get the user defined room notification mode
pub async fn get_user_defined_room_notification_mode(
&self,
room_id: String,
) -> Result<Option<RoomNotificationMode>, NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let parsed_room_id = RoomId::parse(&room_id)
.map_err(|_e| NotificationSettingsError::InvalidRoomId { room_id })?;
// Get the current user defined mode for this room
if let Some(mode) =
notification_settings.get_user_defined_room_notification_mode(&parsed_room_id).await
{
Ok(Some(mode.into()))
} else {
Ok(None)
}
}
/// Get the default room notification mode
///
/// The mode will depend on the associated `PushRule` based on whether the
/// room is encrypted or not, and on the number of members.
///
/// # Arguments
///
/// * `is_encrypted` - whether the room is encrypted
/// * `is_one_to_one` - whether the room is a direct chats involving two
/// people
pub async fn get_default_room_notification_mode(
&self,
is_encrypted: bool,
is_one_to_one: bool,
) -> RoomNotificationMode {
let notification_settings = self.sdk_notification_settings.read().await;
let mode = notification_settings
.get_default_room_notification_mode(is_encrypted.into(), is_one_to_one.into())
.await;
mode.into()
}
/// Set the default room notification mode
///
/// # Arguments
///
/// * `is_encrypted` - whether the mode is for encrypted rooms
/// * `is_one_to_one` - whether the mode is for direct chats involving two
/// people
/// * `mode` - the new default mode
pub async fn set_default_room_notification_mode(
&self,
is_encrypted: bool,
is_one_to_one: bool,
mode: RoomNotificationMode,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings
.set_default_room_notification_mode(
is_encrypted.into(),
is_one_to_one.into(),
mode.into(),
)
.await?;
Ok(())
}
/// Restore the default notification mode for a room
pub async fn restore_default_room_notification_mode(
&self,
room_id: String,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let parsed_room_id = RoomId::parse(&room_id)
.map_err(|_e| NotificationSettingsError::InvalidRoomId { room_id })?;
notification_settings.delete_user_defined_room_rules(&parsed_room_id).await?;
Ok(())
}
/// Get all room IDs for which a user-defined rule exists.
pub async fn get_rooms_with_user_defined_rules(&self, enabled: Option<bool>) -> Vec<String> {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings.get_rooms_with_user_defined_rules(enabled).await
}
/// Get whether some enabled keyword rules exist.
pub async fn contains_keywords_rules(&self) -> bool {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings.contains_keyword_rules().await
}
/// Get whether room mentions are enabled.
pub async fn is_room_mention_enabled(&self) -> Result<bool, NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let enabled = notification_settings
.is_push_rule_enabled(RuleKind::Override, PredefinedOverrideRuleId::IsRoomMention)
.await?;
Ok(enabled)
}
/// Set whether room mentions are enabled.
pub async fn set_room_mention_enabled(
&self,
enabled: bool,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings
.set_push_rule_enabled(
RuleKind::Override,
PredefinedOverrideRuleId::IsRoomMention,
enabled,
)
.await?;
Ok(())
}
/// Get whether user mentions are enabled.
pub async fn is_user_mention_enabled(&self) -> Result<bool, NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let enabled = notification_settings
.is_push_rule_enabled(RuleKind::Override, PredefinedOverrideRuleId::IsUserMention)
.await?;
Ok(enabled)
}
/// Check if [MSC 4028 push rule][rule] is enabled.
///
/// [rule]: https://github.com/matrix-org/matrix-spec-proposals/blob/giomfo/push_encrypted_events/proposals/4028-push-all-encrypted-events-except-for-muted-rooms.md
pub async fn can_homeserver_push_encrypted_event_to_device(&self) -> bool {
let notification_settings = self.sdk_notification_settings.read().await;
// Check stable identifier
if let Ok(enabled) = notification_settings
.is_push_rule_enabled(RuleKind::Override, ".m.rule.encrypted_event")
.await
{
enabled
// Check unstable identifier
} else if let Ok(enabled) = notification_settings
.is_push_rule_enabled(RuleKind::Override, ".org.matrix.msc4028.encrypted_event")
.await
{
enabled
} else {
false
}
}
/// Set whether user mentions are enabled.
pub async fn set_user_mention_enabled(
&self,
enabled: bool,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings
.set_push_rule_enabled(
RuleKind::Override,
PredefinedOverrideRuleId::IsUserMention,
enabled,
)
.await?;
Ok(())
}
/// Get whether the `.m.rule.call` push rule is enabled
pub async fn is_call_enabled(&self) -> Result<bool, NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let enabled = notification_settings
.is_push_rule_enabled(RuleKind::Underride, PredefinedUnderrideRuleId::Call)
.await?;
Ok(enabled)
}
/// Set whether the `.m.rule.call` push rule is enabled
pub async fn set_call_enabled(&self, enabled: bool) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings
.set_push_rule_enabled(RuleKind::Underride, PredefinedUnderrideRuleId::Call, enabled)
.await?;
Ok(())
}
/// Get whether the `.m.rule.invite_for_me` push rule is enabled
pub async fn is_invite_for_me_enabled(&self) -> Result<bool, NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let enabled = notification_settings
.is_push_rule_enabled(
RuleKind::Override,
PredefinedOverrideRuleId::InviteForMe.as_str(),
)
.await?;
Ok(enabled)
}
/// Set whether the `.m.rule.invite_for_me` push rule is enabled
pub async fn set_invite_for_me_enabled(
&self,
enabled: bool,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
notification_settings
.set_push_rule_enabled(
RuleKind::Override,
PredefinedOverrideRuleId::InviteForMe.as_str(),
enabled,
)
.await?;
Ok(())
}
/// Unmute a room.
///
/// # Arguments
///
/// * `room_id` - the room to unmute
/// * `is_encrypted` - whether the room is encrypted
/// * `is_one_to_one` - whether the room is a direct chat involving two
/// people
pub async fn unmute_room(
&self,
room_id: String,
is_encrypted: bool,
is_one_to_one: bool,
) -> Result<(), NotificationSettingsError> {
let notification_settings = self.sdk_notification_settings.read().await;
let parsed_room_id = RoomId::parse(&room_id)
.map_err(|_e| NotificationSettingsError::InvalidRoomId { room_id })?;
notification_settings
.unmute_room(&parsed_room_id, is_encrypted.into(), is_one_to_one.into())
.await?;
Ok(())
}
}
+294
View File
@@ -0,0 +1,294 @@
use std::{collections::HashMap, fmt::Debug, pin::Pin};
use base64::{engine::general_purpose::STANDARD, Engine};
use futures_core::future::BoxFuture;
use opentelemetry::KeyValue;
use opentelemetry_otlp::{Protocol, WithExportConfig};
use opentelemetry_sdk::{runtime::RuntimeChannel, trace::Tracer, Resource};
use tokio::runtime::Handle;
use tracing_core::Subscriber;
use tracing_subscriber::{
fmt::{self, time::FormatTime, FormatEvent, FormatFields, FormattedFields},
layer::SubscriberExt,
registry::LookupSpan,
util::SubscriberInitExt,
EnvFilter, Layer,
};
use crate::RUNTIME;
#[derive(Clone, Debug)]
struct TokioRuntime {
runtime: Handle,
}
impl opentelemetry_sdk::runtime::Runtime for TokioRuntime {
type Interval = tokio_stream::wrappers::IntervalStream;
type Delay = Pin<Box<tokio::time::Sleep>>;
fn interval(&self, period: std::time::Duration) -> Self::Interval {
let _guard = self.runtime.enter();
tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(period))
}
fn spawn(&self, future: BoxFuture<'static, ()>) {
#[allow(clippy::let_underscore_future)]
let _ = self.runtime.spawn(future);
}
fn delay(&self, duration: std::time::Duration) -> Self::Delay {
let _guard = self.runtime.enter();
Box::pin(tokio::time::sleep(duration))
}
}
impl RuntimeChannel for TokioRuntime {
type Receiver<T: Debug + Send> = tokio_stream::wrappers::ReceiverStream<T>;
type Sender<T: Debug + Send> = tokio::sync::mpsc::Sender<T>;
fn batch_message_channel<T: Debug + Send>(
&self,
capacity: usize,
) -> (Self::Sender<T>, Self::Receiver<T>) {
let (sender, receiver) = tokio::sync::mpsc::channel(capacity);
(sender, tokio_stream::wrappers::ReceiverStream::new(receiver))
}
}
pub fn create_otlp_tracer(
user: String,
password: String,
otlp_endpoint: String,
client_name: String,
) -> anyhow::Result<Tracer> {
let runtime = RUNTIME.handle().to_owned();
let auth = STANDARD.encode(format!("{user}:{password}"));
let headers = HashMap::from([("Authorization".to_owned(), format!("Basic {auth}"))]);
let http_client = matrix_sdk::reqwest::ClientBuilder::new().build()?;
let exporter = opentelemetry_otlp::new_exporter()
.http()
.with_http_client(http_client)
.with_protocol(Protocol::HttpBinary)
.with_endpoint(otlp_endpoint)
.with_headers(headers);
let tracer_runtime = TokioRuntime { runtime: runtime.to_owned() };
let _guard = runtime.enter();
let tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_exporter(exporter)
.with_trace_config(
opentelemetry_sdk::trace::config()
.with_resource(Resource::new(vec![KeyValue::new("service.name", client_name)])),
)
.install_batch(tracer_runtime)?;
Ok(tracer)
}
#[cfg(target_os = "android")]
pub fn log_panics() {
std::env::set_var("RUST_BACKTRACE", "1");
log_panics::init();
}
fn text_layers<S>(config: TracingConfiguration) -> impl Layer<S>
where
S: Subscriber + for<'a> LookupSpan<'a>,
{
// Adjusted version of tracing_subscriber::fmt::Format
struct EventFormatter {
display_timestamp: bool,
display_level: bool,
}
impl EventFormatter {
fn new() -> Self {
Self { display_timestamp: true, display_level: true }
}
#[cfg(target_os = "android")]
fn for_logcat() -> Self {
// Level and time are already captured by logcat separately
Self { display_timestamp: false, display_level: false }
}
fn format_timestamp(&self, writer: &mut fmt::format::Writer<'_>) -> std::fmt::Result {
if fmt::time::SystemTime.format_time(writer).is_err() {
writer.write_str("<unknown time>")?;
}
Ok(())
}
fn write_filename(
&self,
writer: &mut fmt::format::Writer<'_>,
filename: &str,
) -> std::fmt::Result {
const CRATES_IO_PATH_MATCHER: &str = ".cargo/registry/src/index.crates.io";
let crates_io_filename = filename
.split_once(CRATES_IO_PATH_MATCHER)
.and_then(|(_, rest)| rest.split_once('/').map(|(_, rest)| rest));
if let Some(filename) = crates_io_filename {
writer.write_str("<crates.io>/")?;
writer.write_str(filename)
} else {
writer.write_str(filename)
}
}
}
impl<S, N> FormatEvent<S, N> for EventFormatter
where
S: Subscriber + for<'a> LookupSpan<'a>,
N: for<'a> FormatFields<'a> + 'static,
{
fn format_event(
&self,
ctx: &fmt::FmtContext<'_, S, N>,
mut writer: fmt::format::Writer<'_>,
event: &tracing_core::Event<'_>,
) -> std::fmt::Result {
let meta = event.metadata();
if self.display_timestamp {
self.format_timestamp(&mut writer)?;
writer.write_char(' ')?;
}
if self.display_level {
// For info and warn, add a padding space to the left
write!(writer, "{:>5} ", meta.level())?;
}
write!(writer, "{}: ", meta.target())?;
ctx.format_fields(writer.by_ref(), event)?;
if let Some(filename) = meta.file() {
writer.write_str(" | ")?;
self.write_filename(&mut writer, filename)?;
if let Some(line_number) = meta.line() {
write!(writer, ":{line_number}")?;
}
}
if let Some(scope) = ctx.event_scope() {
writer.write_str(" | spans: ")?;
let mut first = true;
for span in scope.from_root() {
if !first {
writer.write_str(" > ")?;
}
first = false;
write!(writer, "{}", span.metadata().name())?;
let ext = span.extensions();
if let Some(fields) = &ext.get::<FormattedFields<N>>() {
if !fields.is_empty() {
write!(writer, "{{{fields}}}")?;
}
}
}
}
writeln!(writer)
}
}
let file_layer = config.write_to_files.map(|c| {
fmt::layer()
.event_format(EventFormatter::new())
// EventFormatter doesn't support ANSI colors anyways, but the
// default field formatter does, which is unhelpful for iOS +
// Android logs, but enabled by default.
.with_ansi(false)
.with_writer(tracing_appender::rolling::hourly(c.path, c.file_prefix))
});
Layer::and_then(
file_layer,
config.write_to_stdout_or_system.then(|| {
#[cfg(not(target_os = "android"))]
return fmt::layer()
.event_format(EventFormatter::new())
// See comment above.
.with_ansi(false)
.with_writer(std::io::stderr);
#[cfg(target_os = "android")]
return fmt::layer()
.event_format(EventFormatter::for_logcat())
// See comment above.
.with_ansi(false)
.with_writer(paranoid_android::AndroidLogMakeWriter::new(
"org.matrix.rust.sdk".to_owned(),
));
}),
)
}
#[derive(uniffi::Record)]
pub struct TracingFileConfiguration {
path: String,
file_prefix: String,
}
#[derive(uniffi::Record)]
pub struct TracingConfiguration {
filter: String,
/// Controls whether to print to stdout or, equivalent, the system logs on
/// Android.
write_to_stdout_or_system: bool,
write_to_files: Option<TracingFileConfiguration>,
}
#[uniffi::export]
pub fn setup_tracing(config: TracingConfiguration) {
#[cfg(target_os = "android")]
log_panics();
tracing_subscriber::registry()
.with(EnvFilter::new(&config.filter))
.with(text_layers(config))
.init();
}
#[derive(uniffi::Record)]
pub struct OtlpTracingConfiguration {
client_name: String,
user: String,
password: String,
otlp_endpoint: String,
filter: String,
/// Controls whether to print to stdout or, equivalent, the system logs on
/// Android.
write_to_stdout_or_system: bool,
write_to_files: Option<TracingFileConfiguration>,
}
#[uniffi::export]
pub fn setup_otlp_tracing(config: OtlpTracingConfiguration) {
#[cfg(target_os = "android")]
log_panics();
let otlp_tracer =
create_otlp_tracer(config.user, config.password, config.otlp_endpoint, config.client_name)
.expect("Couldn't configure the OpenTelemetry tracer");
let otlp_layer = tracing_opentelemetry::layer().with_tracer(otlp_tracer);
tracing_subscriber::registry()
.with(EnvFilter::new(&config.filter))
.with(text_layers(TracingConfiguration {
filter: config.filter,
write_to_stdout_or_system: config.write_to_stdout_or_system,
write_to_files: config.write_to_files,
}))
.with(otlp_layer)
.init();
}
+551
View File
@@ -0,0 +1,551 @@
use std::{convert::TryFrom, sync::Arc};
use anyhow::{Context, Result};
use matrix_sdk::{room::Room as SdkRoom, RoomMemberships, RoomState};
use matrix_sdk_ui::timeline::RoomExt;
use mime::Mime;
use ruma::{
api::client::room::report_content,
assign,
events::room::{avatar::ImageInfo as RumaAvatarImageInfo, MediaSource},
EventId, UserId,
};
use tokio::sync::RwLock;
use tracing::error;
use super::RUNTIME;
use crate::{
chunk_iterator::ChunkIterator,
error::{ClientError, MediaInfoError, RoomError},
room_info::RoomInfo,
room_member::{MessageLikeEventType, RoomMember, StateEventType},
ruma::ImageInfo,
timeline::{EventTimelineItem, Timeline},
utils::u64_to_uint,
TaskHandle,
};
#[derive(uniffi::Enum)]
pub enum Membership {
Invited,
Joined,
Left,
}
impl From<RoomState> for Membership {
fn from(value: RoomState) -> Self {
match value {
RoomState::Invited => Membership::Invited,
RoomState::Joined => Membership::Joined,
RoomState::Left => Membership::Left,
}
}
}
pub(crate) type TimelineLock = Arc<RwLock<Option<Arc<Timeline>>>>;
#[derive(uniffi::Object)]
pub struct Room {
pub(super) inner: SdkRoom,
timeline: TimelineLock,
}
impl Room {
pub(crate) fn new(inner: SdkRoom) -> Self {
Room { inner, timeline: Default::default() }
}
pub(crate) fn with_timeline(inner: SdkRoom, timeline: TimelineLock) -> Self {
Room { inner, timeline }
}
}
#[uniffi::export(async_runtime = "tokio")]
impl Room {
pub fn id(&self) -> String {
self.inner.room_id().to_string()
}
pub fn name(&self) -> Option<String> {
self.inner.name()
}
pub fn topic(&self) -> Option<String> {
self.inner.topic()
}
pub fn avatar_url(&self) -> Option<String> {
self.inner.avatar_url().map(|m| m.to_string())
}
pub fn is_direct(&self) -> bool {
RUNTIME.block_on(async move { self.inner.is_direct().await.unwrap_or(false) })
}
pub fn is_public(&self) -> bool {
self.inner.is_public()
}
pub fn is_space(&self) -> bool {
self.inner.is_space()
}
pub fn is_tombstoned(&self) -> bool {
self.inner.is_tombstoned()
}
pub fn canonical_alias(&self) -> Option<String> {
self.inner.canonical_alias().map(|a| a.to_string())
}
pub fn alternative_aliases(&self) -> Vec<String> {
self.inner.alt_aliases().iter().map(|a| a.to_string()).collect()
}
pub fn membership(&self) -> Membership {
self.inner.state().into()
}
/// Is there a non expired membership with application "m.call" and scope
/// "m.room" in this room.
pub fn has_active_room_call(&self) -> bool {
self.inner.has_active_room_call()
}
/// Returns a Vec of userId's that participate in the room call.
///
/// matrix_rtc memberships with application "m.call" and scope "m.room" are
/// considered. A user can occur twice if they join with two devices.
/// convert to a set depending if the different users are required or the
/// amount of sessions.
///
/// The vector is ordered by oldest membership user to newest.
pub fn active_room_call_participants(&self) -> Vec<String> {
self.inner.active_room_call_participants().iter().map(|u| u.to_string()).collect()
}
pub fn inviter(&self) -> Option<Arc<RoomMember>> {
if self.inner.state() == RoomState::Invited {
RUNTIME.block_on(async move {
self.inner
.invite_details()
.await
.ok()
.and_then(|a| a.inviter)
.map(|m| Arc::new(RoomMember::new(m)))
})
} else {
None
}
}
pub async fn timeline(&self) -> Arc<Timeline> {
let mut write_guard = self.timeline.write().await;
if let Some(timeline) = &*write_guard {
timeline.clone()
} else {
let timeline = Timeline::new(self.inner.timeline().await);
*write_guard = Some(timeline.clone());
timeline
}
}
pub async fn poll_history(&self) -> Arc<Timeline> {
Timeline::new(self.inner.poll_history().await)
}
pub fn display_name(&self) -> Result<String, ClientError> {
let r = self.inner.clone();
RUNTIME.block_on(async move { Ok(r.display_name().await?.to_string()) })
}
pub fn is_encrypted(&self) -> Result<bool, ClientError> {
let room = self.inner.clone();
RUNTIME.block_on(async move {
let is_encrypted = room.is_encrypted().await?;
Ok(is_encrypted)
})
}
pub async fn members(&self) -> Result<Arc<RoomMembersIterator>, ClientError> {
Ok(Arc::new(RoomMembersIterator::new(self.inner.members(RoomMemberships::empty()).await?)))
}
pub async fn member(&self, user_id: String) -> Result<Arc<RoomMember>, ClientError> {
let user_id = UserId::parse(&*user_id).context("Invalid user id.")?;
let member = self.inner.get_member(&user_id).await?.context("No user found")?;
Ok(Arc::new(RoomMember::new(member)))
}
pub fn member_avatar_url(&self, user_id: String) -> Result<Option<String>, ClientError> {
let room = self.inner.clone();
RUNTIME.block_on(async move {
let user_id = UserId::parse(&*user_id).context("Invalid user id.")?;
let member = room.get_member(&user_id).await?.context("No user found")?;
let avatar_url_string = member.avatar_url().map(|m| m.to_string());
Ok(avatar_url_string)
})
}
pub fn member_display_name(&self, user_id: String) -> Result<Option<String>, ClientError> {
let room = self.inner.clone();
RUNTIME.block_on(async move {
let user_id = UserId::parse(&*user_id).context("Invalid user id.")?;
let member = room.get_member(&user_id).await?.context("No user found")?;
let avatar_url_string = member.display_name().map(|m| m.to_owned());
Ok(avatar_url_string)
})
}
pub async fn room_info(&self) -> Result<RoomInfo, ClientError> {
let avatar_url = self.inner.avatar_url();
// Look for a local event in the `Timeline`.
//
// First off, let's see if a `Timeline` exists…
if let Some(timeline) = self.timeline.read().await.clone() {
// If it contains a `latest_event`…
if let Some(timeline_last_event) = timeline.inner.latest_event().await {
// If it's a local echo…
if timeline_last_event.is_local_echo() {
return Ok(RoomInfo::new(
&self.inner,
avatar_url,
Some(Arc::new(EventTimelineItem(timeline_last_event))),
)
.await?);
}
}
}
// Otherwise, fallback to the classical path.
let latest_event = match self.inner.latest_event() {
Some(latest_event) => matrix_sdk_ui::timeline::EventTimelineItem::from_latest_event(
self.inner.client(),
self.inner.room_id(),
latest_event,
)
.await
.map(EventTimelineItem)
.map(Arc::new),
None => None,
};
Ok(RoomInfo::new(&self.inner, avatar_url, latest_event).await?)
}
pub fn subscribe_to_room_info_updates(
self: Arc<Self>,
listener: Box<dyn RoomInfoListener>,
) -> Arc<TaskHandle> {
let mut subscriber = self.inner.subscribe_info();
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
while subscriber.next().await.is_some() {
match self.room_info().await {
Ok(room_info) => listener.call(room_info),
Err(e) => {
error!("Failed to compute new RoomInfo: {e}");
}
}
}
})))
}
/// Redacts an event from the room.
///
/// # Arguments
///
/// * `event_id` - The ID of the event to redact
///
/// * `reason` - The reason for the event being redacted (optional).
/// its transaction ID (optional). If not given one is created.
pub fn redact(&self, event_id: String, reason: Option<String>) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
let event_id = EventId::parse(event_id)?;
self.inner.redact(&event_id, reason.as_deref(), None).await?;
Ok(())
})
}
pub fn active_members_count(&self) -> u64 {
self.inner.active_members_count()
}
pub fn invited_members_count(&self) -> u64 {
self.inner.invited_members_count()
}
pub fn joined_members_count(&self) -> u64 {
self.inner.joined_members_count()
}
/// Reports an event from the room.
///
/// # Arguments
///
/// * `event_id` - The ID of the event to report
///
/// * `reason` - The reason for the event being reported (optional).
///
/// * `score` - The score to rate this content as where -100 is most
/// offensive and 0 is inoffensive (optional).
pub fn report_content(
&self,
event_id: String,
score: Option<i32>,
reason: Option<String>,
) -> Result<(), ClientError> {
let int_score = score.map(|value| value.into());
RUNTIME.block_on(async move {
let event_id = EventId::parse(event_id)?;
self.inner
.client()
.send(
report_content::v3::Request::new(
self.inner.room_id().into(),
event_id,
int_score,
reason,
),
None,
)
.await?;
Ok(())
})
}
/// Ignores a user.
///
/// # Arguments
///
/// * `event_id` - The ID of the user to ignore.
pub fn ignore_user(&self, user_id: String) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
let user_id = UserId::parse(user_id)?;
self.inner.client().account().ignore_user(&user_id).await?;
Ok(())
})
}
/// Leave this room.
///
/// Only invited and joined rooms can be left.
pub fn leave(&self) -> Result<(), ClientError> {
RUNTIME.block_on(async {
self.inner.leave().await?;
Ok(())
})
}
/// Join this room.
///
/// Only invited and left rooms can be joined via this method.
pub fn join(&self) -> Result<(), ClientError> {
RUNTIME.block_on(async {
self.inner.join().await?;
Ok(())
})
}
/// Sets a new name to the room.
pub fn set_name(&self, name: String) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
self.inner.set_name(name).await?;
Ok(())
})
}
/// Sets a new topic in the room.
pub fn set_topic(&self, topic: String) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
self.inner.set_room_topic(&topic).await?;
Ok(())
})
}
/// Upload and set the room's avatar.
///
/// This will upload the data produced by the reader to the homeserver's
/// content repository, and set the room's avatar to the MXC URI for the
/// uploaded file.
///
/// # Arguments
///
/// * `mime_type` - The mime description of the avatar, for example
/// image/jpeg
/// * `data` - The raw data that will be uploaded to the homeserver's
/// content repository
/// * `media_info` - The media info used as avatar image info.
pub fn upload_avatar(
&self,
mime_type: String,
data: Vec<u8>,
media_info: Option<ImageInfo>,
) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
let mime: Mime = mime_type.parse()?;
self.inner
.upload_avatar(
&mime,
data,
media_info
.map(TryInto::try_into)
.transpose()
.map_err(|_| RoomError::InvalidMediaInfo)?,
)
.await?;
Ok(())
})
}
/// Removes the current room avatar
pub fn remove_avatar(&self) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
self.inner.remove_avatar().await?;
Ok(())
})
}
pub fn invite_user_by_id(&self, user_id: String) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
let user = <&UserId>::try_from(user_id.as_str())
.context("Could not create user from string")?;
self.inner.invite_user_by_id(user).await?;
Ok(())
})
}
pub async fn can_user_redact(&self, user_id: String) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_redact(&user_id).await?)
}
pub async fn can_user_ban(&self, user_id: String) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_ban(&user_id).await?)
}
pub async fn ban_user(
&self,
user_id: String,
reason: Option<String>,
) -> Result<(), ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.ban_user(&user_id, reason.as_deref()).await?)
}
pub async fn unban_user(
&self,
user_id: String,
reason: Option<String>,
) -> Result<(), ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.unban_user(&user_id, reason.as_deref()).await?)
}
pub async fn can_user_invite(&self, user_id: String) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_invite(&user_id).await?)
}
pub async fn can_user_kick(&self, user_id: String) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_kick(&user_id).await?)
}
pub async fn kick_user(
&self,
user_id: String,
reason: Option<String>,
) -> Result<(), ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.kick_user(&user_id, reason.as_deref()).await?)
}
pub async fn can_user_send_state(
&self,
user_id: String,
state_event: StateEventType,
) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_send_state(&user_id, state_event.into()).await?)
}
pub async fn can_user_send_message(
&self,
user_id: String,
message: MessageLikeEventType,
) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_send_message(&user_id, message.into()).await?)
}
pub async fn can_user_trigger_room_notification(
&self,
user_id: String,
) -> Result<bool, ClientError> {
let user_id = UserId::parse(&user_id)?;
Ok(self.inner.can_user_trigger_room_notification(&user_id).await?)
}
pub fn own_user_id(&self) -> String {
self.inner.own_user_id().to_string()
}
pub async fn typing_notice(&self, is_typing: bool) -> Result<(), ClientError> {
Ok(self.inner.typing_notice(is_typing).await?)
}
}
#[uniffi::export(callback_interface)]
pub trait RoomInfoListener: Sync + Send {
fn call(&self, room_info: RoomInfo);
}
#[derive(uniffi::Object)]
pub struct RoomMembersIterator {
chunk_iterator: ChunkIterator<matrix_sdk::room::RoomMember>,
}
impl RoomMembersIterator {
fn new(members: Vec<matrix_sdk::room::RoomMember>) -> Self {
Self { chunk_iterator: ChunkIterator::new(members) }
}
}
#[uniffi::export]
impl RoomMembersIterator {
fn len(&self) -> u32 {
self.chunk_iterator.len()
}
fn next_chunk(&self, chunk_size: u32) -> Option<Vec<Arc<RoomMember>>> {
self.chunk_iterator
.next(chunk_size)
.map(|members| members.into_iter().map(RoomMember::new).map(Arc::new).collect())
}
}
impl TryFrom<ImageInfo> for RumaAvatarImageInfo {
type Error = MediaInfoError;
fn try_from(value: ImageInfo) -> Result<Self, MediaInfoError> {
let thumbnail_url = if let Some(media_source) = value.thumbnail_source {
match media_source.as_ref() {
MediaSource::Plain(mxc_uri) => Some(mxc_uri.clone()),
MediaSource::Encrypted(_) => return Err(MediaInfoError::InvalidField),
}
} else {
None
};
Ok(assign!(RumaAvatarImageInfo::new(), {
height: value.height.map(u64_to_uint),
width: value.width.map(u64_to_uint),
mimetype: value.mimetype,
size: value.size.map(u64_to_uint),
thumbnail_info: value.thumbnail_info.map(Into::into).map(Box::new),
thumbnail_url: thumbnail_url,
blurhash: value.blurhash,
}))
}
}
+92
View File
@@ -0,0 +1,92 @@
use std::sync::Arc;
use matrix_sdk::RoomState;
use ruma::OwnedMxcUri;
use crate::{
notification_settings::RoomNotificationMode, room::Membership, room_member::RoomMember,
timeline::EventTimelineItem,
};
#[derive(uniffi::Record)]
pub struct RoomInfo {
id: String,
name: Option<String>,
topic: Option<String>,
avatar_url: Option<String>,
is_direct: bool,
is_public: bool,
is_space: bool,
is_tombstoned: bool,
canonical_alias: Option<String>,
alternative_aliases: Vec<String>,
membership: Membership,
latest_event: Option<Arc<EventTimelineItem>>,
inviter: Option<Arc<RoomMember>>,
active_members_count: u64,
invited_members_count: u64,
joined_members_count: u64,
highlight_count: u64,
notification_count: u64,
user_defined_notification_mode: Option<RoomNotificationMode>,
has_room_call: bool,
active_room_call_participants: Vec<String>,
/// "Interesting" messages received in that room, independently of the
/// notification settings.
num_unread_messages: u64,
/// Events that will notify the user, according to their
/// notification settings.
num_unread_notifications: u64,
/// Events causing mentions/highlights for the user, according to their
/// notification settings.
num_unread_mentions: u64,
}
impl RoomInfo {
pub(crate) async fn new(
room: &matrix_sdk::Room,
avatar_url: Option<OwnedMxcUri>,
latest_event: Option<Arc<EventTimelineItem>>,
) -> matrix_sdk::Result<Self> {
let unread_notification_counts = room.unread_notification_counts();
Ok(Self {
id: room.room_id().to_string(),
name: room.name(),
topic: room.topic(),
avatar_url: avatar_url.map(Into::into),
is_direct: room.is_direct().await?,
is_public: room.is_public(),
is_space: room.is_space(),
is_tombstoned: room.is_tombstoned(),
canonical_alias: room.canonical_alias().map(Into::into),
alternative_aliases: room.alt_aliases().into_iter().map(Into::into).collect(),
membership: room.state().into(),
latest_event,
inviter: match room.state() {
RoomState::Invited => {
room.invite_details().await?.inviter.map(|inner| Arc::new(RoomMember { inner }))
}
_ => None,
},
active_members_count: room.active_members_count(),
invited_members_count: room.invited_members_count(),
joined_members_count: room.joined_members_count(),
highlight_count: unread_notification_counts.highlight_count,
notification_count: unread_notification_counts.notification_count,
user_defined_notification_mode: room
.user_defined_notification_mode()
.await
.map(Into::into),
has_room_call: room.has_active_room_call(),
active_room_call_participants: room
.active_room_call_participants()
.iter()
.map(|u| u.to_string())
.collect(),
num_unread_messages: room.num_unread_messages(),
num_unread_notifications: room.num_unread_notifications(),
num_unread_mentions: room.num_unread_mentions(),
})
}
}
+563
View File
@@ -0,0 +1,563 @@
use std::{fmt::Debug, sync::Arc, time::Duration};
use eyeball_im::VectorDiff;
use futures_util::{pin_mut, StreamExt};
use matrix_sdk::{
ruma::{
api::client::sync::sync_events::{
v4::RoomSubscription as RumaRoomSubscription,
UnreadNotificationsCount as RumaUnreadNotificationsCount,
},
assign, RoomId,
},
RoomListEntry as MatrixRoomListEntry,
};
use matrix_sdk_ui::room_list_service::filters::{
new_filter_all, new_filter_all_non_left, new_filter_fuzzy_match_room_name, new_filter_none,
new_filter_normalized_match_room_name,
};
use tokio::sync::RwLock;
use crate::{
error::ClientError,
room::Room,
room_info::RoomInfo,
timeline::{EventTimelineItem, Timeline},
TaskHandle, RUNTIME,
};
#[derive(Debug, thiserror::Error, uniffi::Error)]
pub enum RoomListError {
#[error("sliding sync error: {error}")]
SlidingSync { error: String },
#[error("unknown list `{list_name}`")]
UnknownList { list_name: String },
#[error("input cannot be applied")]
InputCannotBeApplied,
#[error("room `{room_name}` not found")]
RoomNotFound { room_name: String },
#[error("invalid room ID: {error}")]
InvalidRoomId { error: String },
}
impl From<matrix_sdk_ui::room_list_service::Error> for RoomListError {
fn from(value: matrix_sdk_ui::room_list_service::Error) -> Self {
use matrix_sdk_ui::room_list_service::Error::*;
match value {
SlidingSync(error) => Self::SlidingSync { error: error.to_string() },
UnknownList(list_name) => Self::UnknownList { list_name },
InputCannotBeApplied(_) => Self::InputCannotBeApplied,
RoomNotFound(room_id) => Self::RoomNotFound { room_name: room_id.to_string() },
}
}
}
impl From<ruma::IdParseError> for RoomListError {
fn from(value: ruma::IdParseError) -> Self {
Self::InvalidRoomId { error: value.to_string() }
}
}
#[derive(uniffi::Record)]
pub struct RoomListRange {
pub start: u32,
pub end_inclusive: u32,
}
#[derive(uniffi::Enum)]
pub enum RoomListInput {
Viewport { ranges: Vec<RoomListRange> },
}
impl From<RoomListInput> for matrix_sdk_ui::room_list_service::Input {
fn from(value: RoomListInput) -> Self {
match value {
RoomListInput::Viewport { ranges } => Self::Viewport(
ranges.iter().map(|range| range.start..=range.end_inclusive).collect(),
),
}
}
}
#[derive(uniffi::Object)]
pub struct RoomListService {
pub(crate) inner: Arc<matrix_sdk_ui::RoomListService>,
}
#[uniffi::export(async_runtime = "tokio")]
impl RoomListService {
fn state(&self, listener: Box<dyn RoomListServiceStateListener>) -> Arc<TaskHandle> {
let state_stream = self.inner.state();
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(state_stream);
while let Some(state) = state_stream.next().await {
listener.on_update(state.into());
}
})))
}
fn room(&self, room_id: String) -> Result<Arc<RoomListItem>, RoomListError> {
let room_id = <&RoomId>::try_from(room_id.as_str()).map_err(RoomListError::from)?;
Ok(Arc::new(RoomListItem {
inner: Arc::new(RUNTIME.block_on(async { self.inner.room(room_id).await })?),
}))
}
async fn all_rooms(self: Arc<Self>) -> Result<Arc<RoomList>, RoomListError> {
Ok(Arc::new(RoomList {
room_list_service: self.clone(),
inner: Arc::new(self.inner.all_rooms().await.map_err(RoomListError::from)?),
}))
}
async fn invites(self: Arc<Self>) -> Result<Arc<RoomList>, RoomListError> {
Ok(Arc::new(RoomList {
room_list_service: self.clone(),
inner: Arc::new(self.inner.invites().await.map_err(RoomListError::from)?),
}))
}
async fn apply_input(&self, input: RoomListInput) -> Result<(), RoomListError> {
self.inner.apply_input(input.into()).await.map(|_| ()).map_err(Into::into)
}
fn sync_indicator(
&self,
delay_before_showing_in_ms: u32,
delay_before_hiding_in_ms: u32,
listener: Box<dyn RoomListServiceSyncIndicatorListener>,
) -> Arc<TaskHandle> {
let sync_indicator_stream = self.inner.sync_indicator(
Duration::from_millis(delay_before_showing_in_ms.into()),
Duration::from_millis(delay_before_hiding_in_ms.into()),
);
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(sync_indicator_stream);
while let Some(sync_indicator) = sync_indicator_stream.next().await {
listener.on_update(sync_indicator.into());
}
})))
}
}
#[derive(uniffi::Object)]
pub struct RoomList {
room_list_service: Arc<RoomListService>,
inner: Arc<matrix_sdk_ui::room_list_service::RoomList>,
}
#[uniffi::export]
impl RoomList {
fn loading_state(
&self,
listener: Box<dyn RoomListLoadingStateListener>,
) -> Result<RoomListLoadingStateResult, RoomListError> {
let loading_state = self.inner.loading_state();
Ok(RoomListLoadingStateResult {
state: loading_state.get().into(),
state_stream: Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(loading_state);
while let Some(loading_state) = loading_state.next().await {
listener.on_update(loading_state.into());
}
}))),
})
}
fn entries(&self, listener: Box<dyn RoomListEntriesListener>) -> RoomListEntriesResult {
let (entries, entries_stream) = self.inner.entries();
RoomListEntriesResult {
entries: entries.into_iter().map(Into::into).collect(),
entries_stream: Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(entries_stream);
while let Some(diff) = entries_stream.next().await {
listener.on_update(diff.into_iter().map(Into::into).collect());
}
}))),
}
}
fn entries_with_dynamic_adapters(
&self,
page_size: u32,
listener: Box<dyn RoomListEntriesListener>,
) -> RoomListEntriesWithDynamicAdaptersResult {
let (entries_stream, dynamic_entries_controller) =
self.inner.entries_with_dynamic_adapters(page_size.try_into().unwrap());
RoomListEntriesWithDynamicAdaptersResult {
controller: Arc::new(RoomListDynamicEntriesController::new(
dynamic_entries_controller,
self.room_list_service.inner.client(),
)),
entries_stream: Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(entries_stream);
while let Some(diff) = entries_stream.next().await {
listener.on_update(diff.into_iter().map(Into::into).collect());
}
}))),
}
}
fn room(&self, room_id: String) -> Result<Arc<RoomListItem>, RoomListError> {
self.room_list_service.room(room_id)
}
}
#[derive(uniffi::Record)]
pub struct RoomListEntriesResult {
pub entries: Vec<RoomListEntry>,
pub entries_stream: Arc<TaskHandle>,
}
#[derive(uniffi::Record)]
pub struct RoomListEntriesWithDynamicAdaptersResult {
pub controller: Arc<RoomListDynamicEntriesController>,
pub entries_stream: Arc<TaskHandle>,
}
#[derive(uniffi::Record)]
pub struct RoomListLoadingStateResult {
pub state: RoomListLoadingState,
pub state_stream: Arc<TaskHandle>,
}
#[derive(uniffi::Enum)]
pub enum RoomListServiceState {
// Name it `Initial` instead of `Init`, otherwise it creates a keyword conflict in Swift
// as of 2023-08-21.
Initial,
SettingUp,
Recovering,
Running,
Error,
Terminated,
}
impl From<matrix_sdk_ui::room_list_service::State> for RoomListServiceState {
fn from(value: matrix_sdk_ui::room_list_service::State) -> Self {
use matrix_sdk_ui::room_list_service::State as S;
match value {
S::Init => Self::Initial,
S::SettingUp => Self::SettingUp,
S::Recovering => Self::Recovering,
S::Running => Self::Running,
S::Error { .. } => Self::Error,
S::Terminated { .. } => Self::Terminated,
}
}
}
#[derive(uniffi::Enum)]
pub enum RoomListServiceSyncIndicator {
Show,
Hide,
}
impl From<matrix_sdk_ui::room_list_service::SyncIndicator> for RoomListServiceSyncIndicator {
fn from(value: matrix_sdk_ui::room_list_service::SyncIndicator) -> Self {
use matrix_sdk_ui::room_list_service::SyncIndicator as SI;
match value {
SI::Show => Self::Show,
SI::Hide => Self::Hide,
}
}
}
#[derive(uniffi::Enum)]
pub enum RoomListLoadingState {
NotLoaded,
Loaded { maximum_number_of_rooms: Option<u32> },
}
impl From<matrix_sdk_ui::room_list_service::RoomListLoadingState> for RoomListLoadingState {
fn from(value: matrix_sdk_ui::room_list_service::RoomListLoadingState) -> Self {
use matrix_sdk_ui::room_list_service::RoomListLoadingState as LS;
match value {
LS::NotLoaded => Self::NotLoaded,
LS::Loaded { maximum_number_of_rooms } => Self::Loaded { maximum_number_of_rooms },
}
}
}
#[uniffi::export(callback_interface)]
pub trait RoomListServiceStateListener: Send + Sync + Debug {
fn on_update(&self, state: RoomListServiceState);
}
#[uniffi::export(callback_interface)]
pub trait RoomListLoadingStateListener: Send + Sync + Debug {
fn on_update(&self, state: RoomListLoadingState);
}
#[uniffi::export(callback_interface)]
pub trait RoomListServiceSyncIndicatorListener: Send + Sync + Debug {
fn on_update(&self, sync_indicator: RoomListServiceSyncIndicator);
}
#[derive(uniffi::Enum)]
pub enum RoomListEntriesUpdate {
Append { values: Vec<RoomListEntry> },
Clear,
PushFront { value: RoomListEntry },
PushBack { value: RoomListEntry },
PopFront,
PopBack,
Insert { index: u32, value: RoomListEntry },
Set { index: u32, value: RoomListEntry },
Remove { index: u32 },
Truncate { length: u32 },
Reset { values: Vec<RoomListEntry> },
}
impl From<VectorDiff<matrix_sdk::RoomListEntry>> for RoomListEntriesUpdate {
fn from(other: VectorDiff<matrix_sdk::RoomListEntry>) -> Self {
match other {
VectorDiff::Append { values } => {
Self::Append { values: values.into_iter().map(Into::into).collect() }
}
VectorDiff::Clear => Self::Clear,
VectorDiff::PushFront { value } => Self::PushFront { value: value.into() },
VectorDiff::PushBack { value } => Self::PushBack { value: value.into() },
VectorDiff::PopFront => Self::PopFront,
VectorDiff::PopBack => Self::PopBack,
VectorDiff::Insert { index, value } => {
Self::Insert { index: u32::try_from(index).unwrap(), value: value.into() }
}
VectorDiff::Set { index, value } => {
Self::Set { index: u32::try_from(index).unwrap(), value: value.into() }
}
VectorDiff::Remove { index } => Self::Remove { index: u32::try_from(index).unwrap() },
VectorDiff::Truncate { length } => {
Self::Truncate { length: u32::try_from(length).unwrap() }
}
VectorDiff::Reset { values } => {
Self::Reset { values: values.into_iter().map(Into::into).collect() }
}
}
}
}
#[uniffi::export(callback_interface)]
pub trait RoomListEntriesListener: Send + Sync + Debug {
fn on_update(&self, room_entries_update: Vec<RoomListEntriesUpdate>);
}
#[derive(uniffi::Object)]
pub struct RoomListDynamicEntriesController {
inner: matrix_sdk_ui::room_list_service::RoomListDynamicEntriesController,
client: matrix_sdk::Client,
}
impl RoomListDynamicEntriesController {
fn new(
dynamic_entries_controller: matrix_sdk_ui::room_list_service::RoomListDynamicEntriesController,
client: &matrix_sdk::Client,
) -> Self {
Self { inner: dynamic_entries_controller, client: client.clone() }
}
}
#[uniffi::export]
impl RoomListDynamicEntriesController {
fn set_filter(&self, kind: RoomListEntriesDynamicFilterKind) -> bool {
use RoomListEntriesDynamicFilterKind as Kind;
match kind {
Kind::All => self.inner.set_filter(new_filter_all()),
Kind::AllNonLeft => self.inner.set_filter(new_filter_all_non_left(&self.client)),
Kind::None => self.inner.set_filter(new_filter_none()),
Kind::NormalizedMatchRoomName { pattern } => {
self.inner.set_filter(new_filter_normalized_match_room_name(&self.client, &pattern))
}
Kind::FuzzyMatchRoomName { pattern } => {
self.inner.set_filter(new_filter_fuzzy_match_room_name(&self.client, &pattern))
}
}
}
fn add_one_page(&self) {
self.inner.add_one_page();
}
fn reset_to_one_page(&self) {
self.inner.reset_to_one_page();
}
}
#[derive(uniffi::Enum)]
pub enum RoomListEntriesDynamicFilterKind {
All,
AllNonLeft,
None,
NormalizedMatchRoomName { pattern: String },
FuzzyMatchRoomName { pattern: String },
}
#[derive(uniffi::Object)]
pub struct RoomListItem {
inner: Arc<matrix_sdk_ui::room_list_service::Room>,
}
#[uniffi::export(async_runtime = "tokio")]
impl RoomListItem {
fn id(&self) -> String {
self.inner.id().to_string()
}
fn name(&self) -> Option<String> {
RUNTIME.block_on(async { self.inner.name().await })
}
fn avatar_url(&self) -> Option<String> {
self.inner.avatar_url().map(|uri| uri.to_string())
}
fn is_direct(&self) -> bool {
RUNTIME.block_on(async { self.inner.inner_room().is_direct().await.unwrap_or(false) })
}
fn canonical_alias(&self) -> Option<String> {
self.inner.inner_room().canonical_alias().map(|alias| alias.to_string())
}
pub async fn room_info(&self) -> Result<RoomInfo, ClientError> {
let avatar_url = self.inner.avatar_url();
let latest_event = self.inner.latest_event().await.map(EventTimelineItem).map(Arc::new);
Ok(RoomInfo::new(self.inner.inner_room(), avatar_url, latest_event).await?)
}
/// Building a `Room`.
///
/// Be careful that building a `Room` builds its entire `Timeline` at the
/// same time.
async fn full_room(&self) -> Arc<Room> {
Arc::new(Room::with_timeline(
self.inner.inner_room().clone(),
Arc::new(RwLock::new(Some(Timeline::from_arc(self.inner.timeline().await)))),
))
}
// Temporary workaround for coroutine leaks on Kotlin.
fn full_room_blocking(&self) -> Arc<Room> {
RUNTIME.block_on(async move { self.full_room().await })
}
fn subscribe(&self, settings: Option<RoomSubscription>) {
self.inner.subscribe(settings.map(Into::into));
}
fn unsubscribe(&self) {
self.inner.unsubscribe();
}
async fn latest_event(&self) -> Option<Arc<EventTimelineItem>> {
self.inner.latest_event().await.map(EventTimelineItem).map(Arc::new)
}
fn has_unread_notifications(&self) -> bool {
self.inner.has_unread_notifications()
}
fn unread_notifications(&self) -> Arc<UnreadNotificationsCount> {
Arc::new(self.inner.unread_notifications().into())
}
}
#[derive(Clone, Debug, uniffi::Enum)]
pub enum RoomListEntry {
Empty,
Invalidated { room_id: String },
Filled { room_id: String },
}
impl From<MatrixRoomListEntry> for RoomListEntry {
fn from(value: MatrixRoomListEntry) -> Self {
(&value).into()
}
}
impl From<&MatrixRoomListEntry> for RoomListEntry {
fn from(value: &MatrixRoomListEntry) -> Self {
match value {
MatrixRoomListEntry::Empty => Self::Empty,
MatrixRoomListEntry::Filled(room_id) => Self::Filled { room_id: room_id.to_string() },
MatrixRoomListEntry::Invalidated(room_id) => {
Self::Invalidated { room_id: room_id.to_string() }
}
}
}
}
#[derive(uniffi::Record)]
pub struct RequiredState {
pub key: String,
pub value: String,
}
#[derive(uniffi::Record)]
pub struct RoomSubscription {
pub required_state: Option<Vec<RequiredState>>,
pub timeline_limit: Option<u32>,
}
impl From<RoomSubscription> for RumaRoomSubscription {
fn from(val: RoomSubscription) -> Self {
assign!(RumaRoomSubscription::default(), {
required_state: val.required_state.map(|r|
r.into_iter().map(|s| (s.key.into(), s.value)).collect()
).unwrap_or_default(),
timeline_limit: val.timeline_limit.map(|u| u.into())
})
}
}
#[derive(uniffi::Object)]
pub struct UnreadNotificationsCount {
highlight_count: u32,
notification_count: u32,
}
#[uniffi::export]
impl UnreadNotificationsCount {
fn highlight_count(&self) -> u32 {
self.highlight_count
}
fn notification_count(&self) -> u32 {
self.notification_count
}
fn has_notifications(&self) -> bool {
self.notification_count != 0 || self.highlight_count != 0
}
}
impl From<RumaUnreadNotificationsCount> for UnreadNotificationsCount {
fn from(inner: RumaUnreadNotificationsCount) -> Self {
UnreadNotificationsCount {
highlight_count: inner
.highlight_count
.and_then(|x| x.try_into().ok())
.unwrap_or_default(),
notification_count: inner
.notification_count
.and_then(|x| x.try_into().ok())
.unwrap_or_default(),
}
}
}
+237
View File
@@ -0,0 +1,237 @@
use matrix_sdk::room::RoomMember as SdkRoomMember;
use super::RUNTIME;
use crate::ClientError;
#[derive(Clone, uniffi::Enum)]
pub enum MembershipState {
/// The user is banned.
Ban,
/// The user has been invited.
Invite,
/// The user has joined.
Join,
/// The user has requested to join.
Knock,
/// The user has left.
Leave,
}
impl From<matrix_sdk::ruma::events::room::member::MembershipState> for MembershipState {
fn from(m: matrix_sdk::ruma::events::room::member::MembershipState) -> Self {
match m {
matrix_sdk::ruma::events::room::member::MembershipState::Ban => MembershipState::Ban,
matrix_sdk::ruma::events::room::member::MembershipState::Invite => {
MembershipState::Invite
}
matrix_sdk::ruma::events::room::member::MembershipState::Join => MembershipState::Join,
matrix_sdk::ruma::events::room::member::MembershipState::Knock => {
MembershipState::Knock
}
matrix_sdk::ruma::events::room::member::MembershipState::Leave => {
MembershipState::Leave
}
_ => todo!(
"Handle Custom case: https://github.com/matrix-org/matrix-rust-sdk/issues/1254"
),
}
}
}
#[derive(uniffi::Object)]
pub struct RoomMember {
pub(crate) inner: SdkRoomMember,
}
#[uniffi::export]
impl RoomMember {
pub fn user_id(&self) -> String {
self.inner.user_id().to_string()
}
pub fn display_name(&self) -> Option<String> {
self.inner.display_name().map(|d| d.to_owned())
}
pub fn avatar_url(&self) -> Option<String> {
self.inner.avatar_url().map(ToString::to_string)
}
pub fn membership(&self) -> MembershipState {
self.inner.membership().to_owned().into()
}
pub fn is_name_ambiguous(&self) -> bool {
self.inner.name_ambiguous()
}
pub fn power_level(&self) -> i64 {
self.inner.power_level()
}
pub fn normalized_power_level(&self) -> i64 {
self.inner.normalized_power_level()
}
pub fn is_ignored(&self) -> bool {
self.inner.is_ignored()
}
pub fn is_account_user(&self) -> bool {
self.inner.is_account_user()
}
/// Adds the room member to the current account data's ignore list
/// which will ignore the user across all rooms.
pub fn ignore(&self) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
self.inner.ignore().await?;
Ok(())
})
}
/// Removes the room member from the current account data's ignore list
/// which will unignore the user across all rooms.
pub fn unignore(&self) -> Result<(), ClientError> {
RUNTIME.block_on(async move {
self.inner.unignore().await?;
Ok(())
})
}
pub fn can_ban(&self) -> bool {
self.inner.can_ban()
}
pub fn can_invite(&self) -> bool {
self.inner.can_invite()
}
pub fn can_kick(&self) -> bool {
self.inner.can_kick()
}
pub fn can_redact(&self) -> bool {
self.inner.can_redact()
}
pub fn can_send_state(&self, state_event: StateEventType) -> bool {
self.inner.can_send_state(state_event.into())
}
pub fn can_send_message(&self, event: MessageLikeEventType) -> bool {
self.inner.can_send_message(event.into())
}
pub fn can_trigger_room_notification(&self) -> bool {
self.inner.can_trigger_room_notification()
}
}
impl RoomMember {
pub fn new(room_member: SdkRoomMember) -> Self {
RoomMember { inner: room_member }
}
}
#[derive(Clone, uniffi::Enum)]
pub enum StateEventType {
CallMember,
PolicyRuleRoom,
PolicyRuleServer,
PolicyRuleUser,
RoomAliases,
RoomAvatar,
RoomCanonicalAlias,
RoomCreate,
RoomEncryption,
RoomGuestAccess,
RoomHistoryVisibility,
RoomJoinRules,
RoomMemberEvent,
RoomName,
RoomPinnedEvents,
RoomPowerLevels,
RoomServerAcl,
RoomThirdPartyInvite,
RoomTombstone,
RoomTopic,
SpaceChild,
SpaceParent,
}
impl From<StateEventType> for ruma::events::StateEventType {
fn from(val: StateEventType) -> Self {
match val {
StateEventType::CallMember => Self::CallMember,
StateEventType::PolicyRuleRoom => Self::PolicyRuleRoom,
StateEventType::PolicyRuleServer => Self::PolicyRuleServer,
StateEventType::PolicyRuleUser => Self::PolicyRuleUser,
StateEventType::RoomAliases => Self::RoomAliases,
StateEventType::RoomAvatar => Self::RoomAvatar,
StateEventType::RoomCanonicalAlias => Self::RoomCanonicalAlias,
StateEventType::RoomCreate => Self::RoomCreate,
StateEventType::RoomEncryption => Self::RoomEncryption,
StateEventType::RoomGuestAccess => Self::RoomGuestAccess,
StateEventType::RoomHistoryVisibility => Self::RoomHistoryVisibility,
StateEventType::RoomJoinRules => Self::RoomJoinRules,
StateEventType::RoomMemberEvent => Self::RoomMember,
StateEventType::RoomName => Self::RoomName,
StateEventType::RoomPinnedEvents => Self::RoomPinnedEvents,
StateEventType::RoomPowerLevels => Self::RoomPowerLevels,
StateEventType::RoomServerAcl => Self::RoomServerAcl,
StateEventType::RoomThirdPartyInvite => Self::RoomThirdPartyInvite,
StateEventType::RoomTombstone => Self::RoomTombstone,
StateEventType::RoomTopic => Self::RoomTopic,
StateEventType::SpaceChild => Self::SpaceChild,
StateEventType::SpaceParent => Self::SpaceParent,
}
}
}
#[derive(Clone, uniffi::Enum)]
pub enum MessageLikeEventType {
CallAnswer,
CallInvite,
CallHangup,
CallCandidates,
KeyVerificationReady,
KeyVerificationStart,
KeyVerificationCancel,
KeyVerificationAccept,
KeyVerificationKey,
KeyVerificationMac,
KeyVerificationDone,
ReactionSent,
RoomEncrypted,
RoomMessage,
RoomRedaction,
Sticker,
}
impl From<MessageLikeEventType> for ruma::events::MessageLikeEventType {
fn from(val: MessageLikeEventType) -> Self {
match val {
MessageLikeEventType::CallAnswer => Self::CallAnswer,
MessageLikeEventType::CallInvite => Self::CallInvite,
MessageLikeEventType::CallHangup => Self::CallHangup,
MessageLikeEventType::CallCandidates => Self::CallCandidates,
MessageLikeEventType::KeyVerificationReady => Self::KeyVerificationReady,
MessageLikeEventType::KeyVerificationStart => Self::KeyVerificationStart,
MessageLikeEventType::KeyVerificationCancel => Self::KeyVerificationCancel,
MessageLikeEventType::KeyVerificationAccept => Self::KeyVerificationAccept,
MessageLikeEventType::KeyVerificationKey => Self::KeyVerificationKey,
MessageLikeEventType::KeyVerificationMac => Self::KeyVerificationMac,
MessageLikeEventType::KeyVerificationDone => Self::KeyVerificationDone,
MessageLikeEventType::ReactionSent => Self::Reaction,
MessageLikeEventType::RoomEncrypted => Self::RoomEncrypted,
MessageLikeEventType::RoomMessage => Self::RoomMessage,
MessageLikeEventType::RoomRedaction => Self::RoomRedaction,
MessageLikeEventType::Sticker => Self::Sticker,
}
}
}
+712
View File
@@ -0,0 +1,712 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{collections::BTreeSet, sync::Arc, time::Duration};
use extension_trait::extension_trait;
use matrix_sdk::attachment::{
BaseAudioInfo, BaseFileInfo, BaseImageInfo, BaseThumbnailInfo, BaseVideoInfo,
};
use ruma::{
assign,
events::{
location::AssetType as RumaAssetType,
poll::start::PollKind as RumaPollKind,
room::{
message::{
AudioInfo as RumaAudioInfo,
AudioMessageEventContent as RumaAudioMessageEventContent,
EmoteMessageEventContent as RumaEmoteMessageEventContent, FileInfo as RumaFileInfo,
FileMessageEventContent as RumaFileMessageEventContent,
FormattedBody as RumaFormattedBody,
ImageMessageEventContent as RumaImageMessageEventContent,
LocationMessageEventContent as RumaLocationMessageEventContent,
MessageType as RumaMessageType,
NoticeMessageEventContent as RumaNoticeMessageEventContent,
RoomMessageEventContentWithoutRelation,
TextMessageEventContent as RumaTextMessageEventContent,
UnstableAudioDetailsContentBlock as RumaUnstableAudioDetailsContentBlock,
UnstableVoiceContentBlock as RumaUnstableVoiceContentBlock,
VideoInfo as RumaVideoInfo,
VideoMessageEventContent as RumaVideoMessageEventContent,
},
ImageInfo as RumaImageInfo, MediaSource, ThumbnailInfo as RumaThumbnailInfo,
},
},
serde::JsonObject,
OwnedUserId, UInt, UserId,
};
use tracing::info;
use crate::{
error::{ClientError, MediaInfoError},
helpers::unwrap_or_clone_arc,
utils::u64_to_uint,
};
#[uniffi::export]
pub fn media_source_from_url(url: String) -> Arc<MediaSource> {
Arc::new(MediaSource::Plain(url.into()))
}
#[uniffi::export]
pub fn message_event_content_new(
msgtype: MessageType,
) -> Result<Arc<RoomMessageEventContentWithoutRelation>, ClientError> {
Ok(Arc::new(RoomMessageEventContentWithoutRelation::new(msgtype.try_into()?)))
}
#[uniffi::export]
pub fn message_event_content_from_markdown(
md: String,
) -> Arc<RoomMessageEventContentWithoutRelation> {
Arc::new(RoomMessageEventContentWithoutRelation::new(RumaMessageType::text_markdown(md)))
}
#[uniffi::export]
pub fn message_event_content_from_markdown_as_emote(
md: String,
) -> Arc<RoomMessageEventContentWithoutRelation> {
Arc::new(RoomMessageEventContentWithoutRelation::new(RumaMessageType::emote_markdown(md)))
}
#[uniffi::export]
pub fn message_event_content_from_html(
body: String,
html_body: String,
) -> Arc<RoomMessageEventContentWithoutRelation> {
Arc::new(RoomMessageEventContentWithoutRelation::new(RumaMessageType::text_html(
body, html_body,
)))
}
#[uniffi::export]
pub fn message_event_content_from_html_as_emote(
body: String,
html_body: String,
) -> Arc<RoomMessageEventContentWithoutRelation> {
Arc::new(RoomMessageEventContentWithoutRelation::new(RumaMessageType::emote_html(
body, html_body,
)))
}
#[extension_trait]
pub impl MediaSourceExt for MediaSource {
fn from_json(json: String) -> Result<MediaSource, ClientError> {
let res = serde_json::from_str(&json)?;
Ok(res)
}
fn to_json(&self) -> String {
serde_json::to_string(self).expect("Media source should always be serializable ")
}
fn url(&self) -> String {
match self {
MediaSource::Plain(url) => url.to_string(),
MediaSource::Encrypted(file) => file.url.to_string(),
}
}
}
#[extension_trait]
pub impl RoomMessageEventContentWithoutRelationExt for RoomMessageEventContentWithoutRelation {
fn with_mentions(self: Arc<Self>, mentions: Mentions) -> Arc<Self> {
let mut content = unwrap_or_clone_arc(self);
content.mentions = Some(mentions.into());
Arc::new(content)
}
}
pub struct Mentions {
pub user_ids: Vec<String>,
pub room: bool,
}
impl From<Mentions> for ruma::events::Mentions {
fn from(value: Mentions) -> Self {
let mut user_ids = BTreeSet::<OwnedUserId>::new();
for user_id in value.user_ids {
if let Ok(user_id) = UserId::parse(user_id) {
user_ids.insert(user_id);
}
}
let mut result = Self::default();
result.user_ids = user_ids;
result.room = value.room;
result
}
}
#[derive(Clone, uniffi::Enum)]
pub enum MessageType {
Emote { content: EmoteMessageContent },
Image { content: ImageMessageContent },
Audio { content: AudioMessageContent },
Video { content: VideoMessageContent },
File { content: FileMessageContent },
Notice { content: NoticeMessageContent },
Text { content: TextMessageContent },
Location { content: LocationContent },
Other { msgtype: String, body: String },
}
impl TryFrom<MessageType> for RumaMessageType {
type Error = serde_json::Error;
fn try_from(value: MessageType) -> Result<Self, Self::Error> {
Ok(match value {
MessageType::Emote { content } => {
Self::Emote(assign!(RumaEmoteMessageEventContent::plain(content.body), {
formatted: content.formatted.map(Into::into),
}))
}
MessageType::Image { content } => Self::Image(
RumaImageMessageEventContent::new(content.body, (*content.source).clone())
.info(content.info.map(Into::into).map(Box::new)),
),
MessageType::Audio { content } => Self::Audio(
RumaAudioMessageEventContent::new(content.body, (*content.source).clone())
.info(content.info.map(Into::into).map(Box::new)),
),
MessageType::Video { content } => Self::Video(
RumaVideoMessageEventContent::new(content.body, (*content.source).clone())
.info(content.info.map(Into::into).map(Box::new)),
),
MessageType::File { content } => Self::File(
RumaFileMessageEventContent::new(content.body, (*content.source).clone())
.filename(content.filename)
.info(content.info.map(Into::into).map(Box::new)),
),
MessageType::Notice { content } => {
Self::Notice(assign!(RumaNoticeMessageEventContent::plain(content.body), {
formatted: content.formatted.map(Into::into),
}))
}
MessageType::Text { content } => {
Self::Text(assign!(RumaTextMessageEventContent::plain(content.body), {
formatted: content.formatted.map(Into::into),
}))
}
MessageType::Location { content } => {
Self::Location(RumaLocationMessageEventContent::new(content.body, content.geo_uri))
}
MessageType::Other { msgtype, body } => {
Self::new(&msgtype, body, JsonObject::default())?
}
})
}
}
impl From<RumaMessageType> for MessageType {
fn from(value: RumaMessageType) -> Self {
match value {
RumaMessageType::Emote(c) => MessageType::Emote {
content: EmoteMessageContent {
body: c.body.clone(),
formatted: c.formatted.as_ref().map(Into::into),
},
},
RumaMessageType::Image(c) => MessageType::Image {
content: ImageMessageContent {
body: c.body.clone(),
source: Arc::new(c.source.clone()),
info: c.info.as_deref().map(Into::into),
},
},
RumaMessageType::Audio(c) => MessageType::Audio {
content: AudioMessageContent {
body: c.body.clone(),
source: Arc::new(c.source.clone()),
info: c.info.as_deref().map(Into::into),
audio: c.audio.map(Into::into),
voice: c.voice.map(Into::into),
},
},
RumaMessageType::Video(c) => MessageType::Video {
content: VideoMessageContent {
body: c.body.clone(),
source: Arc::new(c.source.clone()),
info: c.info.as_deref().map(Into::into),
},
},
RumaMessageType::File(c) => MessageType::File {
content: FileMessageContent {
body: c.body.clone(),
filename: c.filename.clone(),
source: Arc::new(c.source.clone()),
info: c.info.as_deref().map(Into::into),
},
},
RumaMessageType::Notice(c) => MessageType::Notice {
content: NoticeMessageContent {
body: c.body.clone(),
formatted: c.formatted.as_ref().map(Into::into),
},
},
RumaMessageType::Text(c) => MessageType::Text {
content: TextMessageContent {
body: c.body.clone(),
formatted: c.formatted.as_ref().map(Into::into),
},
},
RumaMessageType::Location(c) => {
let (description, zoom_level) =
c.location.map(|loc| (loc.description, loc.zoom_level)).unwrap_or((None, None));
MessageType::Location {
content: LocationContent {
body: c.body,
geo_uri: c.geo_uri,
description,
zoom_level: zoom_level.and_then(|z| z.get().try_into().ok()),
asset: c.asset.and_then(|a| match a.type_ {
RumaAssetType::Self_ => Some(AssetType::Sender),
RumaAssetType::Pin => Some(AssetType::Pin),
_ => None,
}),
},
}
}
_ => MessageType::Other {
msgtype: value.msgtype().to_owned(),
body: value.body().to_owned(),
},
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct EmoteMessageContent {
pub body: String,
pub formatted: Option<FormattedBody>,
}
#[derive(Clone, uniffi::Record)]
pub struct ImageMessageContent {
pub body: String,
pub source: Arc<MediaSource>,
pub info: Option<ImageInfo>,
}
#[derive(Clone, uniffi::Record)]
pub struct AudioMessageContent {
pub body: String,
pub source: Arc<MediaSource>,
pub info: Option<AudioInfo>,
pub audio: Option<UnstableAudioDetailsContent>,
pub voice: Option<UnstableVoiceContent>,
}
#[derive(Clone, uniffi::Record)]
pub struct VideoMessageContent {
pub body: String,
pub source: Arc<MediaSource>,
pub info: Option<VideoInfo>,
}
#[derive(Clone, uniffi::Record)]
pub struct FileMessageContent {
pub body: String,
pub filename: Option<String>,
pub source: Arc<MediaSource>,
pub info: Option<FileInfo>,
}
#[derive(Clone, uniffi::Record)]
pub struct ImageInfo {
pub height: Option<u64>,
pub width: Option<u64>,
pub mimetype: Option<String>,
pub size: Option<u64>,
pub thumbnail_info: Option<ThumbnailInfo>,
pub thumbnail_source: Option<Arc<MediaSource>>,
pub blurhash: Option<String>,
}
impl From<ImageInfo> for RumaImageInfo {
fn from(value: ImageInfo) -> Self {
assign!(RumaImageInfo::new(), {
height: value.height.map(u64_to_uint),
width: value.width.map(u64_to_uint),
mimetype: value.mimetype,
size: value.size.map(u64_to_uint),
thumbnail_info: value.thumbnail_info.map(Into::into).map(Box::new),
thumbnail_source: value.thumbnail_source.map(|source| (*source).clone()),
blurhash: value.blurhash,
})
}
}
impl TryFrom<&ImageInfo> for BaseImageInfo {
type Error = MediaInfoError;
fn try_from(value: &ImageInfo) -> Result<Self, MediaInfoError> {
let height = UInt::try_from(value.height.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let width = UInt::try_from(value.width.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let size = UInt::try_from(value.size.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let blurhash = value.blurhash.clone().ok_or(MediaInfoError::MissingField)?;
Ok(BaseImageInfo {
height: Some(height),
width: Some(width),
size: Some(size),
blurhash: Some(blurhash),
})
}
}
#[derive(Clone, uniffi::Record)]
pub struct AudioInfo {
pub duration: Option<Duration>,
pub size: Option<u64>,
pub mimetype: Option<String>,
}
impl From<AudioInfo> for RumaAudioInfo {
fn from(value: AudioInfo) -> Self {
assign!(RumaAudioInfo::new(), {
duration: value.duration,
size: value.size.map(u64_to_uint),
mimetype: value.mimetype,
})
}
}
impl TryFrom<&AudioInfo> for BaseAudioInfo {
type Error = MediaInfoError;
fn try_from(value: &AudioInfo) -> Result<Self, MediaInfoError> {
let duration = value.duration.ok_or(MediaInfoError::MissingField)?;
let size = UInt::try_from(value.size.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
Ok(BaseAudioInfo { duration: Some(duration), size: Some(size) })
}
}
#[derive(Clone, uniffi::Record)]
pub struct UnstableAudioDetailsContent {
pub duration: Duration,
pub waveform: Vec<u16>,
}
impl From<RumaUnstableAudioDetailsContentBlock> for UnstableAudioDetailsContent {
fn from(details: RumaUnstableAudioDetailsContentBlock) -> Self {
Self {
duration: details.duration,
waveform: details
.waveform
.iter()
.map(|x| u16::try_from(x.get()).unwrap_or(0))
.collect(),
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct UnstableVoiceContent {}
impl From<RumaUnstableVoiceContentBlock> for UnstableVoiceContent {
fn from(_details: RumaUnstableVoiceContentBlock) -> Self {
Self {}
}
}
#[derive(Clone, uniffi::Record)]
pub struct VideoInfo {
pub duration: Option<Duration>,
pub height: Option<u64>,
pub width: Option<u64>,
pub mimetype: Option<String>,
pub size: Option<u64>,
pub thumbnail_info: Option<ThumbnailInfo>,
pub thumbnail_source: Option<Arc<MediaSource>>,
pub blurhash: Option<String>,
}
impl From<VideoInfo> for RumaVideoInfo {
fn from(value: VideoInfo) -> Self {
assign!(RumaVideoInfo::new(), {
duration: value.duration,
height: value.height.map(u64_to_uint),
width: value.width.map(u64_to_uint),
mimetype: value.mimetype,
size: value.size.map(u64_to_uint),
thumbnail_info: value.thumbnail_info.map(Into::into).map(Box::new),
thumbnail_source: value.thumbnail_source.map(|source| (*source).clone()),
blurhash: value.blurhash,
})
}
}
impl TryFrom<&VideoInfo> for BaseVideoInfo {
type Error = MediaInfoError;
fn try_from(value: &VideoInfo) -> Result<Self, MediaInfoError> {
let duration = value.duration.ok_or(MediaInfoError::MissingField)?;
let height = UInt::try_from(value.height.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let width = UInt::try_from(value.width.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let size = UInt::try_from(value.size.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let blurhash = value.blurhash.clone().ok_or(MediaInfoError::MissingField)?;
Ok(BaseVideoInfo {
duration: Some(duration),
height: Some(height),
width: Some(width),
size: Some(size),
blurhash: Some(blurhash),
})
}
}
#[derive(Clone, uniffi::Record)]
pub struct FileInfo {
pub mimetype: Option<String>,
pub size: Option<u64>,
pub thumbnail_info: Option<ThumbnailInfo>,
pub thumbnail_source: Option<Arc<MediaSource>>,
}
impl From<FileInfo> for RumaFileInfo {
fn from(value: FileInfo) -> Self {
assign!(RumaFileInfo::new(), {
mimetype: value.mimetype,
size: value.size.map(u64_to_uint),
thumbnail_info: value.thumbnail_info.map(Into::into).map(Box::new),
thumbnail_source: value.thumbnail_source.map(|source| (*source).clone()),
})
}
}
impl TryFrom<&FileInfo> for BaseFileInfo {
type Error = MediaInfoError;
fn try_from(value: &FileInfo) -> Result<Self, MediaInfoError> {
let size = UInt::try_from(value.size.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
Ok(BaseFileInfo { size: Some(size) })
}
}
#[derive(Clone, uniffi::Record)]
pub struct ThumbnailInfo {
pub height: Option<u64>,
pub width: Option<u64>,
pub mimetype: Option<String>,
pub size: Option<u64>,
}
impl From<ThumbnailInfo> for RumaThumbnailInfo {
fn from(value: ThumbnailInfo) -> Self {
assign!(RumaThumbnailInfo::new(), {
height: value.height.map(u64_to_uint),
width: value.width.map(u64_to_uint),
mimetype: value.mimetype,
size: value.size.map(u64_to_uint),
})
}
}
impl TryFrom<&ThumbnailInfo> for BaseThumbnailInfo {
type Error = MediaInfoError;
fn try_from(value: &ThumbnailInfo) -> Result<Self, MediaInfoError> {
let height = UInt::try_from(value.height.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let width = UInt::try_from(value.width.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
let size = UInt::try_from(value.size.ok_or(MediaInfoError::MissingField)?)
.map_err(|_| MediaInfoError::InvalidField)?;
Ok(BaseThumbnailInfo { height: Some(height), width: Some(width), size: Some(size) })
}
}
#[derive(Clone, uniffi::Record)]
pub struct NoticeMessageContent {
pub body: String,
pub formatted: Option<FormattedBody>,
}
#[derive(Clone, uniffi::Record)]
pub struct TextMessageContent {
pub body: String,
pub formatted: Option<FormattedBody>,
}
#[derive(Clone, uniffi::Record)]
pub struct LocationContent {
pub body: String,
pub geo_uri: String,
pub description: Option<String>,
pub zoom_level: Option<u8>,
pub asset: Option<AssetType>,
}
#[derive(Clone, uniffi::Enum)]
pub enum AssetType {
Sender,
Pin,
}
impl From<AssetType> for RumaAssetType {
fn from(value: AssetType) -> Self {
match value {
AssetType::Sender => Self::Self_,
AssetType::Pin => Self::Pin,
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct FormattedBody {
pub format: MessageFormat,
pub body: String,
}
impl From<FormattedBody> for RumaFormattedBody {
fn from(f: FormattedBody) -> Self {
Self {
format: match f.format {
MessageFormat::Html => matrix_sdk::ruma::events::room::message::MessageFormat::Html,
MessageFormat::Unknown { format } => format.into(),
},
body: f.body,
}
}
}
impl From<&RumaFormattedBody> for FormattedBody {
fn from(f: &RumaFormattedBody) -> Self {
Self {
format: match &f.format {
matrix_sdk::ruma::events::room::message::MessageFormat::Html => MessageFormat::Html,
_ => MessageFormat::Unknown { format: f.format.to_string() },
},
body: f.body.clone(),
}
}
}
#[derive(Clone, uniffi::Enum)]
pub enum MessageFormat {
Html,
Unknown { format: String },
}
impl From<&matrix_sdk::ruma::events::room::ImageInfo> for ImageInfo {
fn from(info: &matrix_sdk::ruma::events::room::ImageInfo) -> Self {
let thumbnail_info = info.thumbnail_info.as_ref().map(|info| ThumbnailInfo {
height: info.height.map(Into::into),
width: info.width.map(Into::into),
mimetype: info.mimetype.clone(),
size: info.size.map(Into::into),
});
Self {
height: info.height.map(Into::into),
width: info.width.map(Into::into),
mimetype: info.mimetype.clone(),
size: info.size.map(Into::into),
thumbnail_info,
thumbnail_source: info.thumbnail_source.clone().map(Arc::new),
blurhash: info.blurhash.clone(),
}
}
}
impl From<&RumaAudioInfo> for AudioInfo {
fn from(info: &RumaAudioInfo) -> Self {
Self {
duration: info.duration,
size: info.size.map(Into::into),
mimetype: info.mimetype.clone(),
}
}
}
impl From<&RumaVideoInfo> for VideoInfo {
fn from(info: &RumaVideoInfo) -> Self {
let thumbnail_info = info.thumbnail_info.as_ref().map(|info| ThumbnailInfo {
height: info.height.map(Into::into),
width: info.width.map(Into::into),
mimetype: info.mimetype.clone(),
size: info.size.map(Into::into),
});
Self {
duration: info.duration,
height: info.height.map(Into::into),
width: info.width.map(Into::into),
mimetype: info.mimetype.clone(),
size: info.size.map(Into::into),
thumbnail_info,
thumbnail_source: info.thumbnail_source.clone().map(Arc::new),
blurhash: info.blurhash.clone(),
}
}
}
impl From<&RumaFileInfo> for FileInfo {
fn from(info: &RumaFileInfo) -> Self {
let thumbnail_info = info.thumbnail_info.as_ref().map(|info| ThumbnailInfo {
height: info.height.map(Into::into),
width: info.width.map(Into::into),
mimetype: info.mimetype.clone(),
size: info.size.map(Into::into),
});
Self {
mimetype: info.mimetype.clone(),
size: info.size.map(Into::into),
thumbnail_info,
thumbnail_source: info.thumbnail_source.clone().map(Arc::new),
}
}
}
#[derive(uniffi::Enum)]
pub enum PollKind {
Disclosed,
Undisclosed,
}
impl From<PollKind> for RumaPollKind {
fn from(value: PollKind) -> Self {
match value {
PollKind::Disclosed => Self::Disclosed,
PollKind::Undisclosed => Self::Undisclosed,
}
}
}
impl From<RumaPollKind> for PollKind {
fn from(value: RumaPollKind) -> Self {
match value {
RumaPollKind::Disclosed => Self::Disclosed,
RumaPollKind::Undisclosed => Self::Undisclosed,
_ => {
info!("Unknown poll kind, defaulting to undisclosed");
Self::Undisclosed
}
}
}
}
@@ -0,0 +1,253 @@
use std::sync::{Arc, RwLock};
use anyhow::Context as _;
use futures_util::StreamExt;
use matrix_sdk::{
encryption::{
identities::UserIdentity,
verification::{SasState, SasVerification, VerificationRequest},
Encryption,
},
ruma::events::{key::verification::VerificationMethod, AnyToDeviceEvent},
};
use super::RUNTIME;
use crate::error::ClientError;
#[derive(uniffi::Object)]
pub struct SessionVerificationEmoji {
symbol: String,
description: String,
}
#[uniffi::export]
impl SessionVerificationEmoji {
pub fn symbol(&self) -> String {
self.symbol.clone()
}
pub fn description(&self) -> String {
self.description.clone()
}
}
#[derive(uniffi::Enum)]
pub enum SessionVerificationData {
Emojis { emojis: Vec<Arc<SessionVerificationEmoji>>, indices: Vec<u8> },
Decimals { values: Vec<u16> },
}
#[uniffi::export(callback_interface)]
pub trait SessionVerificationControllerDelegate: Sync + Send {
fn did_accept_verification_request(&self);
fn did_start_sas_verification(&self);
fn did_receive_verification_data(&self, data: SessionVerificationData);
fn did_fail(&self);
fn did_cancel(&self);
fn did_finish(&self);
}
pub type Delegate = Arc<RwLock<Option<Box<dyn SessionVerificationControllerDelegate>>>>;
#[derive(Clone, uniffi::Object)]
pub struct SessionVerificationController {
encryption: Encryption,
user_identity: UserIdentity,
delegate: Delegate,
verification_request: Arc<RwLock<Option<VerificationRequest>>>,
sas_verification: Arc<RwLock<Option<SasVerification>>>,
}
#[uniffi::export(async_runtime = "tokio")]
impl SessionVerificationController {
pub async fn is_verified(&self) -> Result<bool, ClientError> {
let device =
self.encryption.get_own_device().await?.context("Our own device is missing")?;
Ok(device.is_cross_signed_by_owner())
}
pub fn set_delegate(&self, delegate: Option<Box<dyn SessionVerificationControllerDelegate>>) {
*self.delegate.write().unwrap() = delegate;
}
pub async fn request_verification(&self) -> Result<(), ClientError> {
let methods = vec![VerificationMethod::SasV1];
let verification_request = self
.user_identity
.request_verification_with_methods(methods)
.await
.map_err(anyhow::Error::from)?;
*self.verification_request.write().unwrap() = Some(verification_request);
Ok(())
}
pub async fn start_sas_verification(&self) -> Result<(), ClientError> {
let verification_request = self.verification_request.read().unwrap().clone();
if let Some(verification) = verification_request {
match verification.start_sas().await {
Ok(Some(verification)) => {
*self.sas_verification.write().unwrap() = Some(verification.clone());
if let Some(delegate) = &*self.delegate.read().unwrap() {
delegate.did_start_sas_verification()
}
let delegate = self.delegate.clone();
RUNTIME.spawn(Self::listen_to_changes(delegate, verification));
}
_ => {
if let Some(delegate) = &*self.delegate.read().unwrap() {
delegate.did_fail()
}
}
}
}
Ok(())
}
pub async fn approve_verification(&self) -> Result<(), ClientError> {
let sas_verification = self.sas_verification.read().unwrap().clone();
if let Some(sas_verification) = sas_verification {
sas_verification.confirm().await?;
}
Ok(())
}
pub async fn decline_verification(&self) -> Result<(), ClientError> {
let sas_verification = self.sas_verification.read().unwrap().clone();
if let Some(sas_verification) = sas_verification {
sas_verification.mismatch().await?;
}
Ok(())
}
pub async fn cancel_verification(&self) -> Result<(), ClientError> {
let verification_request = self.verification_request.read().unwrap().clone();
if let Some(verification) = verification_request {
verification.cancel().await?;
}
Ok(())
}
}
impl SessionVerificationController {
pub(crate) fn new(encryption: Encryption, user_identity: UserIdentity) -> Self {
SessionVerificationController {
encryption,
user_identity,
delegate: Arc::new(RwLock::new(None)),
verification_request: Arc::new(RwLock::new(None)),
sas_verification: Arc::new(RwLock::new(None)),
}
}
pub(crate) async fn process_to_device_message(&self, event: AnyToDeviceEvent) {
match event {
// TODO: Use the changes stream for this as well once we expose
// VerificationRequest::changes() in the main crate.
AnyToDeviceEvent::KeyVerificationStart(event) => {
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
return;
}
if let Some(verification) = self
.encryption
.get_verification(
self.user_identity.user_id(),
event.content.transaction_id.as_str(),
)
.await
{
if let Some(sas_verification) = verification.sas() {
*self.sas_verification.write().unwrap() = Some(sas_verification.clone());
if sas_verification.accept().await.is_ok() {
if let Some(delegate) = &*self.delegate.read().unwrap() {
delegate.did_start_sas_verification()
}
let delegate = self.delegate.clone();
RUNTIME.spawn(Self::listen_to_changes(delegate, sas_verification));
} else if let Some(delegate) = &*self.delegate.read().unwrap() {
delegate.did_fail()
}
}
}
}
AnyToDeviceEvent::KeyVerificationReady(event) => {
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
return;
}
if let Some(delegate) = &*self.delegate.read().unwrap() {
delegate.did_accept_verification_request()
}
}
_ => (),
}
}
fn is_transaction_id_valid(&self, transaction_id: String) -> bool {
match &*self.verification_request.read().unwrap() {
Some(verification) => verification.flow_id() == transaction_id,
None => false,
}
}
async fn listen_to_changes(delegate: Delegate, sas: SasVerification) {
let mut stream = sas.changes();
while let Some(state) = stream.next().await {
match state {
SasState::KeysExchanged { emojis, decimals } => {
if let Some(delegate) = &*delegate.read().unwrap() {
if let Some(emojis) = emojis {
delegate.did_receive_verification_data(
SessionVerificationData::Emojis {
emojis: emojis
.emojis
.into_iter()
.map(|emoji| {
Arc::new(SessionVerificationEmoji {
symbol: emoji.symbol.to_owned(),
description: emoji.description.to_owned(),
})
})
.collect(),
indices: emojis.indices.to_vec(),
},
);
} else {
delegate.did_receive_verification_data(
SessionVerificationData::Decimals {
values: vec![decimals.0, decimals.1, decimals.2],
},
)
}
}
}
SasState::Done { .. } => {
if let Some(delegate) = &*delegate.read().unwrap() {
delegate.did_finish()
}
break;
}
SasState::Cancelled(_cancel_info) => {
// TODO: The cancel_info is usable, we should tell the user why we were
// cancelled.
if let Some(delegate) = &*delegate.read().unwrap() {
delegate.did_cancel()
}
break;
}
SasState::Started { .. } | SasState::Accepted { .. } | SasState::Confirmed => (),
}
}
}
}
+108
View File
@@ -0,0 +1,108 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for that specific language governing permissions and
// limitations under the License.
use std::{fmt::Debug, sync::Arc};
use futures_util::pin_mut;
use matrix_sdk::Client;
use matrix_sdk_ui::sync_service::{
State as MatrixSyncServiceState, SyncService as MatrixSyncService,
SyncServiceBuilder as MatrixSyncServiceBuilder,
};
use crate::{
error::ClientError, helpers::unwrap_or_clone_arc, room_list::RoomListService, TaskHandle,
RUNTIME,
};
#[derive(uniffi::Enum)]
pub enum SyncServiceState {
Idle,
Running,
Terminated,
Error,
}
impl From<MatrixSyncServiceState> for SyncServiceState {
fn from(value: MatrixSyncServiceState) -> Self {
match value {
MatrixSyncServiceState::Idle => Self::Idle,
MatrixSyncServiceState::Running => Self::Running,
MatrixSyncServiceState::Terminated => Self::Terminated,
MatrixSyncServiceState::Error => Self::Error,
}
}
}
#[uniffi::export(callback_interface)]
pub trait SyncServiceStateObserver: Send + Sync + Debug {
fn on_update(&self, state: SyncServiceState);
}
#[derive(uniffi::Object)]
pub struct SyncService {
pub(crate) inner: Arc<MatrixSyncService>,
}
#[uniffi::export(async_runtime = "tokio")]
impl SyncService {
pub fn room_list_service(&self) -> Arc<RoomListService> {
Arc::new(RoomListService { inner: self.inner.room_list_service() })
}
pub async fn start(&self) {
self.inner.start().await;
}
pub async fn stop(&self) -> Result<(), ClientError> {
Ok(self.inner.stop().await?)
}
pub fn state(&self, listener: Box<dyn SyncServiceStateObserver>) -> Arc<TaskHandle> {
let state_stream = self.inner.state();
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(state_stream);
while let Some(state) = state_stream.next().await {
listener.on_update(state.into());
}
})))
}
}
#[derive(Clone, uniffi::Object)]
pub struct SyncServiceBuilder {
builder: MatrixSyncServiceBuilder,
}
impl SyncServiceBuilder {
pub(crate) fn new(client: Client) -> Arc<Self> {
Arc::new(Self { builder: MatrixSyncService::builder(client) })
}
}
#[uniffi::export(async_runtime = "tokio")]
impl SyncServiceBuilder {
pub fn with_cross_process_lock(self: Arc<Self>, app_identifier: Option<String>) -> Arc<Self> {
let this = unwrap_or_clone_arc(self);
let builder = this.builder.with_cross_process_lock(app_identifier);
Arc::new(Self { builder })
}
pub async fn finish(self: Arc<Self>) -> Result<Arc<SyncService>, ClientError> {
let this = unwrap_or_clone_arc(self);
Ok(Arc::new(SyncService { inner: Arc::new(this.builder.build().await?) }))
}
}
@@ -0,0 +1,39 @@
use tokio::task::JoinHandle;
use tracing::debug;
/// A task handle is a way to keep the handle a task running by itself in
/// detached mode.
///
/// It's a thin wrapper around [`JoinHandle`].
#[derive(uniffi::Object)]
pub struct TaskHandle {
handle: JoinHandle<()>,
}
impl TaskHandle {
// Create a new task handle.
pub fn new(handle: JoinHandle<()>) -> Self {
Self { handle }
}
}
#[uniffi::export]
impl TaskHandle {
// Cancel a task handle.
pub fn cancel(&self) {
debug!("Cancelling the task handle");
self.handle.abort();
}
/// Check whether the handle is finished.
pub fn is_finished(&self) -> bool {
self.handle.is_finished()
}
}
impl Drop for TaskHandle {
fn drop(&mut self) {
self.cancel();
}
}
@@ -0,0 +1,399 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{collections::HashMap, sync::Arc};
use matrix_sdk_ui::timeline::{PollResult, TimelineDetails};
use tracing::warn;
use super::ProfileDetails;
use crate::ruma::{ImageInfo, MessageType, PollKind};
#[derive(Clone, uniffi::Object)]
pub struct TimelineItemContent(pub(crate) matrix_sdk_ui::timeline::TimelineItemContent);
#[uniffi::export]
impl TimelineItemContent {
pub fn kind(&self) -> TimelineItemContentKind {
use matrix_sdk_ui::timeline::TimelineItemContent as Content;
match &self.0 {
Content::Message(_) => TimelineItemContentKind::Message,
Content::RedactedMessage => TimelineItemContentKind::RedactedMessage,
Content::Sticker(sticker) => {
let content = sticker.content();
TimelineItemContentKind::Sticker {
body: content.body.clone(),
info: (&content.info).into(),
url: content.url.to_string(),
}
}
Content::Poll(poll_state) => TimelineItemContentKind::from(poll_state.results()),
Content::UnableToDecrypt(msg) => {
TimelineItemContentKind::UnableToDecrypt { msg: EncryptedMessage::new(msg) }
}
Content::MembershipChange(membership) => TimelineItemContentKind::RoomMembership {
user_id: membership.user_id().to_string(),
change: membership.change().map(Into::into),
},
Content::ProfileChange(profile) => {
let (display_name, prev_display_name) = profile
.displayname_change()
.map(|change| (change.new.clone(), change.old.clone()))
.unzip();
let (avatar_url, prev_avatar_url) = profile
.avatar_url_change()
.map(|change| {
(
change.new.as_ref().map(ToString::to_string),
change.old.as_ref().map(ToString::to_string),
)
})
.unzip();
TimelineItemContentKind::ProfileChange {
display_name: display_name.flatten(),
prev_display_name: prev_display_name.flatten(),
avatar_url: avatar_url.flatten(),
prev_avatar_url: prev_avatar_url.flatten(),
}
}
Content::OtherState(state) => TimelineItemContentKind::State {
state_key: state.state_key().to_owned(),
content: state.content().into(),
},
Content::FailedToParseMessageLike { event_type, error } => {
TimelineItemContentKind::FailedToParseMessageLike {
event_type: event_type.to_string(),
error: error.to_string(),
}
}
Content::FailedToParseState { event_type, state_key, error } => {
TimelineItemContentKind::FailedToParseState {
event_type: event_type.to_string(),
state_key: state_key.to_string(),
error: error.to_string(),
}
}
}
}
pub fn as_message(self: Arc<Self>) -> Option<Arc<Message>> {
use matrix_sdk_ui::timeline::TimelineItemContent as Content;
unwrap_or_clone_arc_into_variant!(self, .0, Content::Message(msg) => Arc::new(Message(msg)))
}
}
#[derive(uniffi::Enum)]
pub enum TimelineItemContentKind {
Message,
RedactedMessage,
Sticker {
body: String,
info: ImageInfo,
url: String,
},
Poll {
question: String,
kind: PollKind,
max_selections: u64,
answers: Vec<PollAnswer>,
votes: HashMap<String, Vec<String>>,
end_time: Option<u64>,
has_been_edited: bool,
},
UnableToDecrypt {
msg: EncryptedMessage,
},
RoomMembership {
user_id: String,
change: Option<MembershipChange>,
},
ProfileChange {
display_name: Option<String>,
prev_display_name: Option<String>,
avatar_url: Option<String>,
prev_avatar_url: Option<String>,
},
State {
state_key: String,
content: OtherState,
},
FailedToParseMessageLike {
event_type: String,
error: String,
},
FailedToParseState {
event_type: String,
state_key: String,
error: String,
},
}
#[derive(Clone, uniffi::Object)]
pub struct Message(matrix_sdk_ui::timeline::Message);
#[uniffi::export]
impl Message {
pub fn msgtype(&self) -> MessageType {
self.0.msgtype().clone().into()
}
pub fn body(&self) -> String {
self.0.msgtype().body().to_owned()
}
pub fn in_reply_to(&self) -> Option<InReplyToDetails> {
self.0.in_reply_to().map(InReplyToDetails::from)
}
pub fn is_threaded(&self) -> bool {
self.0.is_threaded()
}
pub fn is_edited(&self) -> bool {
self.0.is_edited()
}
}
#[derive(uniffi::Record)]
pub struct InReplyToDetails {
event_id: String,
event: RepliedToEventDetails,
}
impl From<&matrix_sdk_ui::timeline::InReplyToDetails> for InReplyToDetails {
fn from(inner: &matrix_sdk_ui::timeline::InReplyToDetails) -> Self {
let event_id = inner.event_id.to_string();
let event = match &inner.event {
TimelineDetails::Unavailable => RepliedToEventDetails::Unavailable,
TimelineDetails::Pending => RepliedToEventDetails::Pending,
TimelineDetails::Ready(event) => RepliedToEventDetails::Ready {
content: Arc::new(TimelineItemContent(event.content().to_owned())),
sender: event.sender().to_string(),
sender_profile: event.sender_profile().into(),
},
TimelineDetails::Error(err) => {
RepliedToEventDetails::Error { message: err.to_string() }
}
};
Self { event_id, event }
}
}
#[derive(uniffi::Enum)]
pub enum RepliedToEventDetails {
Unavailable,
Pending,
Ready { content: Arc<TimelineItemContent>, sender: String, sender_profile: ProfileDetails },
Error { message: String },
}
#[derive(Clone, uniffi::Enum)]
pub enum EncryptedMessage {
OlmV1Curve25519AesSha2 {
/// The Curve25519 key of the sender.
sender_key: String,
},
// Other fields not included because UniFFI doesn't have the concept of
// deprecated fields right now.
MegolmV1AesSha2 {
/// The ID of the session used to encrypt the message.
session_id: String,
},
Unknown,
}
impl EncryptedMessage {
fn new(msg: &matrix_sdk_ui::timeline::EncryptedMessage) -> Self {
use matrix_sdk_ui::timeline::EncryptedMessage as Message;
match msg {
Message::OlmV1Curve25519AesSha2 { sender_key } => {
let sender_key = sender_key.clone();
Self::OlmV1Curve25519AesSha2 { sender_key }
}
Message::MegolmV1AesSha2 { session_id, .. } => {
let session_id = session_id.clone();
Self::MegolmV1AesSha2 { session_id }
}
Message::Unknown => Self::Unknown,
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct Reaction {
pub key: String,
pub count: u64,
pub senders: Vec<ReactionSenderData>,
}
#[derive(Clone, uniffi::Record)]
pub struct ReactionSenderData {
pub sender_id: String,
pub timestamp: u64,
}
#[derive(Clone, uniffi::Enum)]
pub enum MembershipChange {
None,
Error,
Joined,
Left,
Banned,
Unbanned,
Kicked,
Invited,
KickedAndBanned,
InvitationAccepted,
InvitationRejected,
InvitationRevoked,
Knocked,
KnockAccepted,
KnockRetracted,
KnockDenied,
NotImplemented,
}
impl From<matrix_sdk_ui::timeline::MembershipChange> for MembershipChange {
fn from(membership_change: matrix_sdk_ui::timeline::MembershipChange) -> Self {
use matrix_sdk_ui::timeline::MembershipChange as Change;
match membership_change {
Change::None => Self::None,
Change::Error => Self::Error,
Change::Joined => Self::Joined,
Change::Left => Self::Left,
Change::Banned => Self::Banned,
Change::Unbanned => Self::Unbanned,
Change::Kicked => Self::Kicked,
Change::Invited => Self::Invited,
Change::KickedAndBanned => Self::KickedAndBanned,
Change::InvitationAccepted => Self::InvitationAccepted,
Change::InvitationRejected => Self::InvitationRejected,
Change::InvitationRevoked => Self::InvitationRevoked,
Change::Knocked => Self::Knocked,
Change::KnockAccepted => Self::KnockAccepted,
Change::KnockRetracted => Self::KnockRetracted,
Change::KnockDenied => Self::KnockDenied,
Change::NotImplemented => Self::NotImplemented,
}
}
}
#[derive(Clone, uniffi::Enum)]
pub enum OtherState {
PolicyRuleRoom,
PolicyRuleServer,
PolicyRuleUser,
RoomAliases,
RoomAvatar { url: Option<String> },
RoomCanonicalAlias,
RoomCreate,
RoomEncryption,
RoomGuestAccess,
RoomHistoryVisibility,
RoomJoinRules,
RoomName { name: Option<String> },
RoomPinnedEvents,
RoomPowerLevels,
RoomServerAcl,
RoomThirdPartyInvite { display_name: Option<String> },
RoomTombstone,
RoomTopic { topic: Option<String> },
SpaceChild,
SpaceParent,
Custom { event_type: String },
}
impl From<&matrix_sdk_ui::timeline::AnyOtherFullStateEventContent> for OtherState {
fn from(content: &matrix_sdk_ui::timeline::AnyOtherFullStateEventContent) -> Self {
use matrix_sdk::ruma::events::FullStateEventContent as FullContent;
use matrix_sdk_ui::timeline::AnyOtherFullStateEventContent as Content;
match content {
Content::PolicyRuleRoom(_) => Self::PolicyRuleRoom,
Content::PolicyRuleServer(_) => Self::PolicyRuleServer,
Content::PolicyRuleUser(_) => Self::PolicyRuleUser,
Content::RoomAliases(_) => Self::RoomAliases,
Content::RoomAvatar(c) => {
let url = match c {
FullContent::Original { content, .. } => {
content.url.as_ref().map(ToString::to_string)
}
FullContent::Redacted(_) => None,
};
Self::RoomAvatar { url }
}
Content::RoomCanonicalAlias(_) => Self::RoomCanonicalAlias,
Content::RoomCreate(_) => Self::RoomCreate,
Content::RoomEncryption(_) => Self::RoomEncryption,
Content::RoomGuestAccess(_) => Self::RoomGuestAccess,
Content::RoomHistoryVisibility(_) => Self::RoomHistoryVisibility,
Content::RoomJoinRules(_) => Self::RoomJoinRules,
Content::RoomName(c) => {
let name = match c {
FullContent::Original { content, .. } => Some(content.name.clone()),
FullContent::Redacted(_) => None,
};
Self::RoomName { name }
}
Content::RoomPinnedEvents(_) => Self::RoomPinnedEvents,
Content::RoomPowerLevels(_) => Self::RoomPowerLevels,
Content::RoomServerAcl(_) => Self::RoomServerAcl,
Content::RoomThirdPartyInvite(c) => {
let display_name = match c {
FullContent::Original { content, .. } => Some(content.display_name.clone()),
FullContent::Redacted(_) => None,
};
Self::RoomThirdPartyInvite { display_name }
}
Content::RoomTombstone(_) => Self::RoomTombstone,
Content::RoomTopic(c) => {
let topic = match c {
FullContent::Original { content, .. } => Some(content.topic.clone()),
FullContent::Redacted(_) => None,
};
Self::RoomTopic { topic }
}
Content::SpaceChild(_) => Self::SpaceChild,
Content::SpaceParent(_) => Self::SpaceParent,
Content::_Custom { event_type, .. } => Self::Custom { event_type: event_type.clone() },
}
}
}
#[derive(uniffi::Record)]
pub struct PollAnswer {
pub id: String,
pub text: String,
}
impl From<PollResult> for TimelineItemContentKind {
fn from(value: PollResult) -> Self {
TimelineItemContentKind::Poll {
question: value.question,
kind: PollKind::from(value.kind),
max_selections: value.max_selections,
answers: value
.answers
.into_iter()
.map(|i| PollAnswer { id: i.id, text: i.text })
.collect(),
votes: value.votes,
end_time: value.end_time,
has_been_edited: value.has_been_edited,
}
}
}
+998
View File
@@ -0,0 +1,998 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{collections::HashMap, fmt::Write as _, fs, sync::Arc};
use anyhow::{Context, Result};
use as_variant::as_variant;
use eyeball_im::VectorDiff;
use futures_util::{pin_mut, StreamExt};
use matrix_sdk::attachment::{
AttachmentConfig, AttachmentInfo, BaseAudioInfo, BaseFileInfo, BaseImageInfo,
BaseThumbnailInfo, BaseVideoInfo, Thumbnail,
};
use matrix_sdk_ui::timeline::{BackPaginationStatus, EventItemOrigin, Profile, TimelineDetails};
use mime::Mime;
use ruma::{
events::{
location::{AssetType as RumaAssetType, LocationContent, ZoomLevel},
poll::{
unstable_end::UnstablePollEndEventContent,
unstable_response::UnstablePollResponseEventContent,
unstable_start::{
NewUnstablePollStartEventContent, UnstablePollAnswer, UnstablePollAnswers,
UnstablePollStartContentBlock,
},
},
receipt::ReceiptThread,
relation::Annotation,
room::message::{
ForwardThread, LocationMessageEventContent, MessageType,
RoomMessageEventContentWithoutRelation,
},
AnyMessageLikeEventContent,
},
EventId,
};
use tokio::{
sync::Mutex,
task::{AbortHandle, JoinHandle},
};
use tracing::{error, info, warn};
use uuid::Uuid;
use crate::{
client::ProgressWatcher,
error::{ClientError, RoomError},
helpers::unwrap_or_clone_arc,
ruma::{AssetType, AudioInfo, FileInfo, ImageInfo, PollKind, ThumbnailInfo, VideoInfo},
task_handle::TaskHandle,
RUNTIME,
};
mod content;
pub use self::content::{Reaction, ReactionSenderData, TimelineItemContent};
#[derive(uniffi::Object)]
#[repr(transparent)]
pub struct Timeline {
pub(crate) inner: matrix_sdk_ui::timeline::Timeline,
}
impl Timeline {
pub(crate) fn new(inner: matrix_sdk_ui::timeline::Timeline) -> Arc<Self> {
Arc::new(Self { inner })
}
pub(crate) fn from_arc(inner: Arc<matrix_sdk_ui::timeline::Timeline>) -> Arc<Self> {
// SAFETY: repr(transparent) means transmuting the arc this way is allowed
unsafe { Arc::from_raw(Arc::into_raw(inner) as _) }
}
fn build_thumbnail_info(
&self,
thumbnail_url: String,
thumbnail_info: ThumbnailInfo,
) -> Result<Thumbnail, RoomError> {
let thumbnail_data =
fs::read(thumbnail_url).map_err(|_| RoomError::InvalidThumbnailData)?;
let base_thumbnail_info = BaseThumbnailInfo::try_from(&thumbnail_info)
.map_err(|_| RoomError::InvalidAttachmentData)?;
let mime_str =
thumbnail_info.mimetype.as_ref().ok_or(RoomError::InvalidAttachmentMimeType)?;
let mime_type =
mime_str.parse::<Mime>().map_err(|_| RoomError::InvalidAttachmentMimeType)?;
Ok(Thumbnail {
data: thumbnail_data,
content_type: mime_type,
info: Some(base_thumbnail_info),
})
}
async fn send_attachment(
&self,
url: String,
mime_type: Mime,
attachment_config: AttachmentConfig,
progress_watcher: Option<Box<dyn ProgressWatcher>>,
) -> Result<(), RoomError> {
let request = self.inner.send_attachment(url, mime_type, attachment_config);
if let Some(progress_watcher) = progress_watcher {
let mut subscriber = request.subscribe_to_send_progress();
RUNTIME.spawn(async move {
while let Some(progress) = subscriber.next().await {
progress_watcher.transmission_progress(progress.into());
}
});
}
request.await.map_err(|_| RoomError::FailedSendingAttachment)?;
Ok(())
}
}
#[uniffi::export(async_runtime = "tokio")]
impl Timeline {
pub async fn add_listener(
&self,
listener: Box<dyn TimelineListener>,
) -> RoomTimelineListenerResult {
let (timeline_items, timeline_stream) = self.inner.subscribe_batched().await;
let timeline_stream = TaskHandle::new(RUNTIME.spawn(async move {
pin_mut!(timeline_stream);
while let Some(diffs) = timeline_stream.next().await {
listener
.on_update(diffs.into_iter().map(|d| Arc::new(TimelineDiff::new(d))).collect());
}
}));
RoomTimelineListenerResult {
items: timeline_items.into_iter().map(TimelineItem::from_arc).collect(),
items_stream: Arc::new(timeline_stream),
}
}
pub fn retry_decryption(self: Arc<Self>, session_ids: Vec<String>) {
RUNTIME.spawn(async move {
self.inner.retry_decryption(&session_ids).await;
});
}
pub async fn fetch_members(&self) {
self.inner.fetch_members().await
}
pub fn subscribe_to_back_pagination_status(
&self,
listener: Box<dyn BackPaginationStatusListener>,
) -> Result<Arc<TaskHandle>, ClientError> {
let mut subscriber = self.inner.back_pagination_status();
Ok(Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
// Send the current state even if it hasn't changed right away.
listener.on_update(subscriber.next_now());
while let Some(status) = subscriber.next().await {
listener.on_update(status);
}
}))))
}
/// Loads older messages into the timeline.
///
/// Raises an exception if there are no timeline listeners.
pub fn paginate_backwards(&self, opts: PaginationOptions) -> Result<(), ClientError> {
RUNTIME.block_on(async { Ok(self.inner.paginate_backwards(opts.into()).await?) })
}
pub fn send_read_receipt(
&self,
receipt_type: ReceiptType,
event_id: String,
) -> Result<(), ClientError> {
let event_id = EventId::parse(event_id)?;
RUNTIME.block_on(async {
self.inner
.send_single_receipt(receipt_type.into(), ReceiptThread::Unthreaded, event_id)
.await?;
Ok(())
})
}
pub fn send(self: Arc<Self>, msg: Arc<RoomMessageEventContentWithoutRelation>) {
RUNTIME.spawn(async move {
self.inner.send((*msg).to_owned().with_relation(None).into()).await;
});
}
pub fn send_image(
self: Arc<Self>,
url: String,
thumbnail_url: Option<String>,
image_info: ImageInfo,
progress_watcher: Option<Box<dyn ProgressWatcher>>,
) -> Arc<SendAttachmentJoinHandle> {
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
let mime_str =
image_info.mimetype.as_ref().ok_or(RoomError::InvalidAttachmentMimeType)?;
let mime_type =
mime_str.parse::<Mime>().map_err(|_| RoomError::InvalidAttachmentMimeType)?;
let base_image_info = BaseImageInfo::try_from(&image_info)
.map_err(|_| RoomError::InvalidAttachmentData)?;
let attachment_info = AttachmentInfo::Image(base_image_info);
let attachment_config = match (thumbnail_url, image_info.thumbnail_info) {
(Some(thumbnail_url), Some(thumbnail_image_info)) => {
let thumbnail =
self.build_thumbnail_info(thumbnail_url, thumbnail_image_info)?;
AttachmentConfig::with_thumbnail(thumbnail).info(attachment_info)
}
_ => AttachmentConfig::new().info(attachment_info),
};
self.send_attachment(url, mime_type, attachment_config, progress_watcher).await
}))
}
pub fn send_video(
self: Arc<Self>,
url: String,
thumbnail_url: Option<String>,
video_info: VideoInfo,
progress_watcher: Option<Box<dyn ProgressWatcher>>,
) -> Arc<SendAttachmentJoinHandle> {
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
let mime_str =
video_info.mimetype.as_ref().ok_or(RoomError::InvalidAttachmentMimeType)?;
let mime_type =
mime_str.parse::<Mime>().map_err(|_| RoomError::InvalidAttachmentMimeType)?;
let base_video_info: BaseVideoInfo = BaseVideoInfo::try_from(&video_info)
.map_err(|_| RoomError::InvalidAttachmentData)?;
let attachment_info = AttachmentInfo::Video(base_video_info);
let attachment_config = match (thumbnail_url, video_info.thumbnail_info) {
(Some(thumbnail_url), Some(thumbnail_image_info)) => {
let thumbnail =
self.build_thumbnail_info(thumbnail_url, thumbnail_image_info)?;
AttachmentConfig::with_thumbnail(thumbnail).info(attachment_info)
}
_ => AttachmentConfig::new().info(attachment_info),
};
self.send_attachment(url, mime_type, attachment_config, progress_watcher).await
}))
}
pub fn send_audio(
self: Arc<Self>,
url: String,
audio_info: AudioInfo,
progress_watcher: Option<Box<dyn ProgressWatcher>>,
) -> Arc<SendAttachmentJoinHandle> {
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
let mime_str =
audio_info.mimetype.as_ref().ok_or(RoomError::InvalidAttachmentMimeType)?;
let mime_type =
mime_str.parse::<Mime>().map_err(|_| RoomError::InvalidAttachmentMimeType)?;
let base_audio_info: BaseAudioInfo = BaseAudioInfo::try_from(&audio_info)
.map_err(|_| RoomError::InvalidAttachmentData)?;
let attachment_info = AttachmentInfo::Audio(base_audio_info);
let attachment_config = AttachmentConfig::new().info(attachment_info);
self.send_attachment(url, mime_type, attachment_config, progress_watcher).await
}))
}
pub fn send_voice_message(
self: Arc<Self>,
url: String,
audio_info: AudioInfo,
waveform: Vec<u16>,
progress_watcher: Option<Box<dyn ProgressWatcher>>,
) -> Arc<SendAttachmentJoinHandle> {
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
let mime_str =
audio_info.mimetype.as_ref().ok_or(RoomError::InvalidAttachmentMimeType)?;
let mime_type =
mime_str.parse::<Mime>().map_err(|_| RoomError::InvalidAttachmentMimeType)?;
let base_audio_info: BaseAudioInfo = BaseAudioInfo::try_from(&audio_info)
.map_err(|_| RoomError::InvalidAttachmentData)?;
let attachment_info =
AttachmentInfo::Voice { audio_info: base_audio_info, waveform: Some(waveform) };
let attachment_config = AttachmentConfig::new().info(attachment_info);
self.send_attachment(url, mime_type, attachment_config, progress_watcher).await
}))
}
pub fn send_file(
self: Arc<Self>,
url: String,
file_info: FileInfo,
progress_watcher: Option<Box<dyn ProgressWatcher>>,
) -> Arc<SendAttachmentJoinHandle> {
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
let mime_str =
file_info.mimetype.as_ref().ok_or(RoomError::InvalidAttachmentMimeType)?;
let mime_type =
mime_str.parse::<Mime>().map_err(|_| RoomError::InvalidAttachmentMimeType)?;
let base_file_info: BaseFileInfo =
BaseFileInfo::try_from(&file_info).map_err(|_| RoomError::InvalidAttachmentData)?;
let attachment_info = AttachmentInfo::File(base_file_info);
let attachment_config = AttachmentConfig::new().info(attachment_info);
self.send_attachment(url, mime_type, attachment_config, progress_watcher).await
}))
}
pub fn create_poll(
self: Arc<Self>,
question: String,
answers: Vec<String>,
max_selections: u8,
poll_kind: PollKind,
) -> Result<(), ClientError> {
let poll_data = PollData { question, answers, max_selections, poll_kind };
let poll_start_event_content = NewUnstablePollStartEventContent::plain_text(
poll_data.fallback_text(),
poll_data.try_into()?,
);
let event_content =
AnyMessageLikeEventContent::UnstablePollStart(poll_start_event_content.into());
RUNTIME.spawn(async move {
self.inner.send(event_content).await;
});
Ok(())
}
pub fn send_poll_response(
self: Arc<Self>,
poll_start_id: String,
answers: Vec<String>,
) -> Result<(), ClientError> {
let poll_start_event_id =
EventId::parse(poll_start_id).context("Failed to parse EventId")?;
let poll_response_event_content =
UnstablePollResponseEventContent::new(answers, poll_start_event_id);
let event_content =
AnyMessageLikeEventContent::UnstablePollResponse(poll_response_event_content);
RUNTIME.spawn(async move {
self.inner.send(event_content).await;
});
Ok(())
}
pub fn end_poll(
self: Arc<Self>,
poll_start_id: String,
text: String,
) -> Result<(), ClientError> {
let poll_start_event_id =
EventId::parse(poll_start_id).context("Failed to parse EventId")?;
let poll_end_event_content = UnstablePollEndEventContent::new(text, poll_start_event_id);
let event_content = AnyMessageLikeEventContent::UnstablePollEnd(poll_end_event_content);
RUNTIME.spawn(async move {
self.inner.send(event_content).await;
});
Ok(())
}
pub fn send_reply(
&self,
msg: Arc<RoomMessageEventContentWithoutRelation>,
reply_item: Arc<EventTimelineItem>,
) -> Result<(), ClientError> {
RUNTIME.block_on(async {
self.inner.send_reply((*msg).clone(), &reply_item.0, ForwardThread::Yes).await?;
anyhow::Ok(())
})?;
Ok(())
}
pub fn edit(
&self,
new_content: Arc<RoomMessageEventContentWithoutRelation>,
edit_item: Arc<EventTimelineItem>,
) -> Result<(), ClientError> {
RUNTIME.block_on(async {
self.inner.edit((*new_content).clone().with_relation(None), &edit_item.0).await?;
anyhow::Ok(())
})?;
Ok(())
}
pub async fn edit_poll(
&self,
question: String,
answers: Vec<String>,
max_selections: u8,
poll_kind: PollKind,
edit_item: Arc<EventTimelineItem>,
) -> Result<(), ClientError> {
let poll_data = PollData { question, answers, max_selections, poll_kind };
RUNTIME.block_on(async {
self.inner
.edit_poll(poll_data.fallback_text(), poll_data.try_into()?, &edit_item.0)
.await?;
anyhow::Ok(())
})?;
Ok(())
}
pub fn send_location(
self: Arc<Self>,
body: String,
geo_uri: String,
description: Option<String>,
zoom_level: Option<u8>,
asset_type: Option<AssetType>,
) {
let mut location_event_message_content =
LocationMessageEventContent::new(body, geo_uri.clone());
if let Some(asset_type) = asset_type {
location_event_message_content =
location_event_message_content.with_asset_type(RumaAssetType::from(asset_type));
}
let mut location_content = LocationContent::new(geo_uri);
location_content.description = description;
location_content.zoom_level = zoom_level.and_then(ZoomLevel::new);
location_event_message_content.location = Some(location_content);
let room_message_event_content = RoomMessageEventContentWithoutRelation::new(
MessageType::Location(location_event_message_content),
);
self.send(Arc::new(room_message_event_content))
}
pub fn toggle_reaction(&self, event_id: String, key: String) -> Result<(), ClientError> {
let event_id = EventId::parse(event_id)?;
RUNTIME.block_on(async {
self.inner.toggle_reaction(&Annotation::new(event_id, key)).await?;
Ok(())
})
}
pub fn fetch_details_for_event(&self, event_id: String) -> Result<(), ClientError> {
let event_id = <&EventId>::try_from(event_id.as_str())?;
RUNTIME.block_on(async {
self.inner.fetch_details_for_event(event_id).await.context("Fetching event details")?;
Ok(())
})
}
pub fn retry_send(self: Arc<Self>, txn_id: String) {
RUNTIME.spawn(async move {
if let Err(e) = self.inner.retry_send(txn_id.as_str().into()).await {
error!(txn_id, "Failed to retry sending: {e}");
}
});
}
pub fn cancel_send(self: Arc<Self>, txn_id: String) {
RUNTIME.spawn(async move {
if !self.inner.cancel_send(txn_id.as_str().into()).await {
info!(txn_id, "Failed to discard local echo: Not found");
}
});
}
pub fn get_event_timeline_item_by_event_id(
&self,
event_id: String,
) -> Result<Arc<EventTimelineItem>, ClientError> {
let event_id = EventId::parse(event_id)?;
RUNTIME.block_on(async {
let item = self
.inner
.item_by_event_id(&event_id)
.await
.context("Item with given event ID not found")?;
Ok(Arc::new(EventTimelineItem(item)))
})
}
pub fn get_timeline_event_content_by_event_id(
&self,
event_id: String,
) -> Result<Arc<RoomMessageEventContentWithoutRelation>, ClientError> {
let event_id = EventId::parse(event_id)?;
RUNTIME.block_on(async {
let item = self
.inner
.item_by_event_id(&event_id)
.await
.context("Item with given event ID not found")?;
let msgtype = item
.content()
.as_message()
.context("Item with given event ID is not a message")?
.msgtype()
.to_owned();
Ok(Arc::new(RoomMessageEventContentWithoutRelation::new(msgtype)))
})
}
}
#[derive(uniffi::Record)]
pub struct RoomTimelineListenerResult {
pub items: Vec<Arc<TimelineItem>>,
pub items_stream: Arc<TaskHandle>,
}
#[uniffi::export(callback_interface)]
pub trait TimelineListener: Sync + Send {
fn on_update(&self, diff: Vec<Arc<TimelineDiff>>);
}
#[uniffi::export(callback_interface)]
pub trait BackPaginationStatusListener: Sync + Send {
fn on_update(&self, status: BackPaginationStatus);
}
#[derive(Clone, uniffi::Object)]
pub enum TimelineDiff {
Append { values: Vec<Arc<TimelineItem>> },
Clear,
PushFront { value: Arc<TimelineItem> },
PushBack { value: Arc<TimelineItem> },
PopFront,
PopBack,
Insert { index: usize, value: Arc<TimelineItem> },
Set { index: usize, value: Arc<TimelineItem> },
Remove { index: usize },
Truncate { length: usize },
Reset { values: Vec<Arc<TimelineItem>> },
}
impl TimelineDiff {
pub(crate) fn new(inner: VectorDiff<Arc<matrix_sdk_ui::timeline::TimelineItem>>) -> Self {
match inner {
VectorDiff::Append { values } => {
Self::Append { values: values.into_iter().map(TimelineItem::from_arc).collect() }
}
VectorDiff::Clear => Self::Clear,
VectorDiff::Insert { index, value } => {
Self::Insert { index, value: TimelineItem::from_arc(value) }
}
VectorDiff::Set { index, value } => {
Self::Set { index, value: TimelineItem::from_arc(value) }
}
VectorDiff::Truncate { length } => Self::Truncate { length },
VectorDiff::Remove { index } => Self::Remove { index },
VectorDiff::PushBack { value } => {
Self::PushBack { value: TimelineItem::from_arc(value) }
}
VectorDiff::PushFront { value } => {
Self::PushFront { value: TimelineItem::from_arc(value) }
}
VectorDiff::PopBack => Self::PopBack,
VectorDiff::PopFront => Self::PopFront,
VectorDiff::Reset { values } => {
warn!("Timeline subscriber lagged behind and was reset");
Self::Reset { values: values.into_iter().map(TimelineItem::from_arc).collect() }
}
}
}
}
#[uniffi::export]
impl TimelineDiff {
pub fn change(&self) -> TimelineChange {
match self {
Self::Append { .. } => TimelineChange::Append,
Self::Insert { .. } => TimelineChange::Insert,
Self::Set { .. } => TimelineChange::Set,
Self::Remove { .. } => TimelineChange::Remove,
Self::PushBack { .. } => TimelineChange::PushBack,
Self::PushFront { .. } => TimelineChange::PushFront,
Self::PopBack => TimelineChange::PopBack,
Self::PopFront => TimelineChange::PopFront,
Self::Clear => TimelineChange::Clear,
Self::Truncate { .. } => TimelineChange::Truncate,
Self::Reset { .. } => TimelineChange::Reset,
}
}
pub fn append(self: Arc<Self>) -> Option<Vec<Arc<TimelineItem>>> {
let this = unwrap_or_clone_arc(self);
as_variant!(this, Self::Append { values } => values)
}
pub fn insert(self: Arc<Self>) -> Option<InsertData> {
let this = unwrap_or_clone_arc(self);
as_variant!(this, Self::Insert { index, value } => {
InsertData { index: index.try_into().unwrap(), item: value }
})
}
pub fn set(self: Arc<Self>) -> Option<SetData> {
let this = unwrap_or_clone_arc(self);
as_variant!(this, Self::Set { index, value } => {
SetData { index: index.try_into().unwrap(), item: value }
})
}
pub fn remove(&self) -> Option<u32> {
as_variant!(self, Self::Remove { index } => (*index).try_into().unwrap())
}
pub fn push_back(self: Arc<Self>) -> Option<Arc<TimelineItem>> {
let this = unwrap_or_clone_arc(self);
as_variant!(this, Self::PushBack { value } => value)
}
pub fn push_front(self: Arc<Self>) -> Option<Arc<TimelineItem>> {
let this = unwrap_or_clone_arc(self);
as_variant!(this, Self::PushFront { value } => value)
}
pub fn reset(self: Arc<Self>) -> Option<Vec<Arc<TimelineItem>>> {
let this = unwrap_or_clone_arc(self);
as_variant!(this, Self::Reset { values } => values)
}
}
#[derive(uniffi::Record)]
pub struct InsertData {
pub index: u32,
pub item: Arc<TimelineItem>,
}
#[derive(uniffi::Record)]
pub struct SetData {
pub index: u32,
pub item: Arc<TimelineItem>,
}
#[derive(Clone, Copy, uniffi::Enum)]
pub enum TimelineChange {
Append,
Clear,
Insert,
Set,
Remove,
PushBack,
PushFront,
PopBack,
PopFront,
Truncate,
Reset,
}
#[repr(transparent)]
#[derive(Clone, uniffi::Object)]
pub struct TimelineItem(pub(crate) matrix_sdk_ui::timeline::TimelineItem);
impl TimelineItem {
pub(crate) fn from_arc(arc: Arc<matrix_sdk_ui::timeline::TimelineItem>) -> Arc<Self> {
// SAFETY: This is valid because Self is a repr(transparent) wrapper
// around the other Timeline type.
unsafe { Arc::from_raw(Arc::into_raw(arc) as _) }
}
}
#[uniffi::export]
impl TimelineItem {
pub fn as_event(self: Arc<Self>) -> Option<Arc<EventTimelineItem>> {
let event_item = self.0.as_event()?;
Some(Arc::new(EventTimelineItem(event_item.clone())))
}
pub fn as_virtual(self: Arc<Self>) -> Option<VirtualTimelineItem> {
use matrix_sdk_ui::timeline::VirtualTimelineItem as VItem;
match self.0.as_virtual()? {
VItem::DayDivider(ts) => Some(VirtualTimelineItem::DayDivider { ts: ts.0.into() }),
VItem::ReadMarker => Some(VirtualTimelineItem::ReadMarker),
}
}
pub fn unique_id(&self) -> u64 {
self.0.unique_id()
}
pub fn fmt_debug(&self) -> String {
format!("{:#?}", self.0)
}
}
/// This type represents the “send state” of a local event timeline item.
#[derive(Clone, uniffi::Enum)]
pub enum EventSendState {
/// The local event has not been sent yet.
NotSentYet,
/// The local event has been sent to the server, but unsuccessfully: The
/// sending has failed.
SendingFailed { error: String },
/// Sending has been cancelled because an earlier event in the
/// message-sending queue failed.
Cancelled,
/// The local event has been sent successfully to the server.
Sent { event_id: String },
}
impl From<&matrix_sdk_ui::timeline::EventSendState> for EventSendState {
fn from(value: &matrix_sdk_ui::timeline::EventSendState) -> Self {
use matrix_sdk_ui::timeline::EventSendState::*;
match value {
NotSentYet => Self::NotSentYet,
SendingFailed { error } => Self::SendingFailed { error: error.to_string() },
Cancelled => Self::Cancelled,
Sent { event_id } => Self::Sent { event_id: event_id.to_string() },
}
}
}
#[derive(uniffi::Object)]
pub struct EventTimelineItem(pub(crate) matrix_sdk_ui::timeline::EventTimelineItem);
#[uniffi::export]
impl EventTimelineItem {
pub fn is_local(&self) -> bool {
self.0.is_local_echo()
}
pub fn is_remote(&self) -> bool {
!self.0.is_local_echo()
}
pub fn transaction_id(&self) -> Option<String> {
self.0.transaction_id().map(ToString::to_string)
}
pub fn event_id(&self) -> Option<String> {
self.0.event_id().map(ToString::to_string)
}
pub fn sender(&self) -> String {
self.0.sender().to_string()
}
pub fn sender_profile(&self) -> ProfileDetails {
self.0.sender_profile().into()
}
pub fn is_own(&self) -> bool {
self.0.is_own()
}
pub fn is_editable(&self) -> bool {
self.0.is_editable()
}
pub fn content(&self) -> Arc<TimelineItemContent> {
Arc::new(TimelineItemContent(self.0.content().clone()))
}
pub fn timestamp(&self) -> u64 {
self.0.timestamp().0.into()
}
pub fn reactions(&self) -> Vec<Reaction> {
self.0
.reactions()
.iter()
.map(|(k, v)| Reaction {
key: k.to_owned(),
count: v.len().try_into().unwrap(),
senders: v
.senders()
.map(|v| ReactionSenderData {
sender_id: v.sender_id.to_string(),
timestamp: v.timestamp.0.into(),
})
.collect(),
})
.collect()
}
pub fn debug_info(&self) -> EventTimelineItemDebugInfo {
EventTimelineItemDebugInfo {
model: format!("{:#?}", self.0),
original_json: self.0.original_json().map(|raw| raw.json().get().to_owned()),
latest_edit_json: self.0.latest_edit_json().map(|raw| raw.json().get().to_owned()),
}
}
pub fn local_send_state(&self) -> Option<EventSendState> {
self.0.send_state().map(Into::into)
}
pub fn read_receipts(&self) -> HashMap<String, Receipt> {
self.0.read_receipts().iter().map(|(k, v)| (k.to_string(), v.clone().into())).collect()
}
pub fn origin(&self) -> Option<EventItemOrigin> {
self.0.origin()
}
pub fn can_be_replied_to(&self) -> bool {
self.0.can_be_replied_to()
}
}
#[derive(uniffi::Record)]
pub struct Receipt {
pub timestamp: Option<u64>,
}
impl From<ruma::events::receipt::Receipt> for Receipt {
fn from(value: ruma::events::receipt::Receipt) -> Self {
Receipt { timestamp: value.ts.map(|ts| ts.0.into()) }
}
}
#[derive(uniffi::Record)]
pub struct EventTimelineItemDebugInfo {
model: String,
original_json: Option<String>,
latest_edit_json: Option<String>,
}
#[derive(uniffi::Enum)]
pub enum ProfileDetails {
Unavailable,
Pending,
Ready { display_name: Option<String>, display_name_ambiguous: bool, avatar_url: Option<String> },
Error { message: String },
}
impl From<&TimelineDetails<Profile>> for ProfileDetails {
fn from(details: &TimelineDetails<Profile>) -> Self {
match details {
TimelineDetails::Unavailable => Self::Unavailable,
TimelineDetails::Pending => Self::Pending,
TimelineDetails::Ready(profile) => Self::Ready {
display_name: profile.display_name.clone(),
display_name_ambiguous: profile.display_name_ambiguous,
avatar_url: profile.avatar_url.as_ref().map(ToString::to_string),
},
TimelineDetails::Error(e) => Self::Error { message: e.to_string() },
}
}
}
struct PollData {
question: String,
answers: Vec<String>,
max_selections: u8,
poll_kind: PollKind,
}
impl PollData {
fn fallback_text(&self) -> String {
self.answers.iter().enumerate().fold(self.question.clone(), |mut acc, (index, answer)| {
write!(&mut acc, "\n{}. {answer}", index + 1).unwrap();
acc
})
}
}
impl TryFrom<PollData> for UnstablePollStartContentBlock {
type Error = ClientError;
fn try_from(value: PollData) -> Result<Self, Self::Error> {
let poll_answers_vec: Vec<UnstablePollAnswer> = value
.answers
.iter()
.map(|answer| UnstablePollAnswer::new(Uuid::new_v4().to_string(), answer))
.collect();
let poll_answers = UnstablePollAnswers::try_from(poll_answers_vec)
.context("Failed to create poll answers")?;
let mut poll_content_block =
UnstablePollStartContentBlock::new(value.question.clone(), poll_answers);
poll_content_block.kind = value.poll_kind.into();
poll_content_block.max_selections = value.max_selections.into();
Ok(poll_content_block)
}
}
#[derive(uniffi::Object)]
pub struct SendAttachmentJoinHandle {
join_hdl: Arc<Mutex<JoinHandle<Result<(), RoomError>>>>,
abort_hdl: AbortHandle,
}
impl SendAttachmentJoinHandle {
fn new(join_hdl: JoinHandle<Result<(), RoomError>>) -> Arc<Self> {
let abort_hdl = join_hdl.abort_handle();
let join_hdl = Arc::new(Mutex::new(join_hdl));
Arc::new(Self { join_hdl, abort_hdl })
}
}
#[uniffi::export(async_runtime = "tokio")]
impl SendAttachmentJoinHandle {
pub async fn join(&self) -> Result<(), RoomError> {
let join_hdl = self.join_hdl.clone();
RUNTIME.spawn(async move { (&mut *join_hdl.lock().await).await.unwrap() }).await.unwrap()
}
pub fn cancel(&self) {
self.abort_hdl.abort();
}
}
#[derive(uniffi::Enum)]
pub enum PaginationOptions {
SimpleRequest { event_limit: u16, wait_for_token: bool },
UntilNumItems { event_limit: u16, items: u16, wait_for_token: bool },
}
impl From<PaginationOptions> for matrix_sdk_ui::timeline::PaginationOptions<'static> {
fn from(value: PaginationOptions) -> Self {
use matrix_sdk_ui::timeline::PaginationOptions as Opts;
let (wait_for_token, mut opts) = match value {
PaginationOptions::SimpleRequest { event_limit, wait_for_token } => {
(wait_for_token, Opts::simple_request(event_limit))
}
PaginationOptions::UntilNumItems { event_limit, items, wait_for_token } => {
(wait_for_token, Opts::until_num_items(event_limit, items))
}
};
if wait_for_token {
opts = opts.wait_for_token();
}
opts
}
}
/// A [`TimelineItem`](super::TimelineItem) that doesn't correspond to an event.
#[derive(uniffi::Enum)]
pub enum VirtualTimelineItem {
/// A divider between messages of two days.
DayDivider {
/// A timestamp in milliseconds since Unix Epoch on that day in local
/// time.
ts: u64,
},
/// The user's own read marker.
ReadMarker,
}
/// A [`TimelineItem`](super::TimelineItem) that doesn't correspond to an event.
#[derive(uniffi::Enum)]
pub enum ReceiptType {
Read,
ReadPrivate,
FullyRead,
}
impl From<ReceiptType> for ruma::api::client::receipt::create_receipt::v3::ReceiptType {
fn from(value: ReceiptType) -> Self {
match value {
ReceiptType::Read => Self::Read,
ReceiptType::ReadPrivate => Self::Read,
ReceiptType::FullyRead => Self::FullyRead,
}
}
}
+212
View File
@@ -0,0 +1,212 @@
use std::{
collections::BTreeMap,
sync::{Arc, Mutex},
};
use once_cell::sync::OnceCell;
use tracing::{callsite::DefaultCallsite, field::FieldSet, Callsite};
use tracing_core::{identify_callsite, metadata::Kind as MetadataKind};
/// Log an event.
///
/// The target should be something like a module path, and can be referenced in
/// the filter string given to `setup_tracing`. `level` and `target` for a
/// callsite are fixed at the first `log_event` call for that callsite and can
/// not be changed afterwards, i.e. the level and target passed for second and
/// following `log_event`s with the same callsite will be ignored.
///
/// This function leaks a little bit of memory for each unique (file + line +
/// level + target) it is called with. Please make sure that the number of
/// different combinations of those parameters this can be called with is
/// constant in the final executable.
#[uniffi::export]
fn log_event(file: String, line: Option<u32>, level: LogLevel, target: String, message: String) {
static CALLSITES: Mutex<BTreeMap<MetadataId, &'static DefaultCallsite>> =
Mutex::new(BTreeMap::new());
let id = MetadataId { file, line, level, target, name: None };
let callsite = get_or_init_metadata(&CALLSITES, id, &["message"], MetadataKind::EVENT);
if span_or_event_enabled(callsite) {
let metadata = callsite.metadata();
let fields = metadata.fields();
let message_field = fields.field("message").unwrap();
#[allow(trivial_casts)] // The compiler is lying, it can't infer this cast
let values = [(&message_field, Some(&message as &dyn tracing::Value))];
// This function is hidden from docs, but we have to use it
// because there is no other way of obtaining a `ValueSet`.
// It's not entirely clear why it is private. See this issue:
// https://github.com/tokio-rs/tracing/issues/2363
let values = fields.value_set(&values);
tracing::Event::dispatch(metadata, &values);
}
}
type FieldNames = &'static [&'static str];
fn get_or_init_metadata(
mutex: &Mutex<BTreeMap<MetadataId, &'static DefaultCallsite>>,
id: MetadataId,
field_names: FieldNames,
meta_kind: MetadataKind,
) -> &'static DefaultCallsite {
mutex.lock().unwrap().entry(id).or_insert_with_key(|id| {
let callsite = Box::leak(Box::new(LateInitCallsite(OnceCell::new())));
let metadata = Box::leak(Box::new(tracing::Metadata::new(
Box::leak(
id.name
.clone()
.unwrap_or_else(|| match id.line {
Some(line) => format!("event {}:{line}", id.file),
None => format!("event {}", id.file),
})
.into_boxed_str(),
),
Box::leak(id.target.as_str().into()),
id.level.to_tracing_level(),
Some(Box::leak(Box::from(id.file.as_str()))),
id.line,
None, // module path
FieldSet::new(field_names, identify_callsite!(callsite)),
meta_kind,
)));
callsite.0.try_insert(DefaultCallsite::new(metadata)).expect("callsite was not set before")
})
}
fn span_or_event_enabled(callsite: &'static DefaultCallsite) -> bool {
use tracing::{
dispatcher,
level_filters::{LevelFilter, STATIC_MAX_LEVEL},
};
let meta = callsite.metadata();
let level = *meta.level();
if level > STATIC_MAX_LEVEL || level > LevelFilter::current() {
false
} else {
let interest = callsite.interest();
interest.is_always()
|| !interest.is_never() && dispatcher::get_default(|default| default.enabled(meta))
}
}
#[derive(uniffi::Object)]
pub struct Span(tracing::Span);
#[uniffi::export]
impl Span {
/// Create a span originating at the given callsite (file, line and column).
///
/// The target should be something like a module path, and can be referenced
/// in the filter string given to `setup_tracing`. `level` and `target`
/// for a callsite are fixed at the first creation of a span for that
/// callsite and can not be changed afterwards, i.e. the level and
/// target passed for second and following creation of a span with the same
/// callsite will be ignored.
///
/// This function leaks a little bit of memory for each unique (file + line
/// + level + target + name) it is called with. Please make sure that the
/// number of different combinations of those parameters this can be called
/// with is constant in the final executable.
///
/// For a span to have an effect, you must `.enter()` it at the start of a
/// logical unit of work and `.exit()` it at the end of the same (including
/// on failure). Entering registers the span in thread-local storage, so
/// future calls to `log_event` on the same thread are able to attach the
/// events they create to the span, exiting unregisters it. For this to
/// work, exiting a span must be done on the same thread where it was
/// entered. It is possible to enter a span on multiple threads, in which
/// case it should also be exited on all of them individually; that is,
/// unless you *want* the span to be attached to all further events created
/// on that thread.
#[uniffi::constructor]
pub fn new(
file: String,
line: Option<u32>,
level: LogLevel,
target: String,
name: String,
) -> Arc<Self> {
static CALLSITES: Mutex<BTreeMap<MetadataId, &'static DefaultCallsite>> =
Mutex::new(BTreeMap::new());
let loc = MetadataId { file, line, level, target, name: Some(name) };
let callsite = get_or_init_metadata(&CALLSITES, loc, &[], MetadataKind::SPAN);
let metadata = callsite.metadata();
let span = if span_or_event_enabled(callsite) {
// This function is hidden from docs, but we have to use it (see above).
let values = metadata.fields().value_set(&[]);
tracing::Span::new(metadata, &values)
} else {
tracing::Span::none()
};
Arc::new(Self(span))
}
#[uniffi::constructor]
pub fn current() -> Arc<Self> {
Arc::new(Self(tracing::Span::current()))
}
fn enter(&self) {
self.0.with_subscriber(|(id, dispatch)| dispatch.enter(id));
}
fn exit(&self) {
self.0.with_subscriber(|(id, dispatch)| dispatch.exit(id));
}
fn is_none(&self) -> bool {
self.0.is_none()
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, uniffi::Enum)]
pub enum LogLevel {
Error,
Warn,
Info,
Debug,
Trace,
}
impl LogLevel {
fn to_tracing_level(&self) -> tracing::Level {
match self {
LogLevel::Error => tracing::Level::ERROR,
LogLevel::Warn => tracing::Level::WARN,
LogLevel::Info => tracing::Level::INFO,
LogLevel::Debug => tracing::Level::DEBUG,
LogLevel::Trace => tracing::Level::TRACE,
}
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct MetadataId {
file: String,
line: Option<u32>,
level: LogLevel,
target: String,
name: Option<String>,
}
struct LateInitCallsite(OnceCell<DefaultCallsite>);
impl Callsite for LateInitCallsite {
fn set_interest(&self, interest: tracing_core::Interest) {
self.0
.get()
.expect("Callsite impl must not be used before initialization")
.set_interest(interest)
}
fn metadata(&self) -> &tracing::Metadata<'_> {
self.0.get().expect("Callsite impl must not be used before initialization").metadata()
}
}
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ruma::UInt;
use tracing::warn;
pub(crate) fn u64_to_uint(u: u64) -> UInt {
UInt::new(u).unwrap_or_else(|| {
warn!("u64 -> UInt conversion overflowed, falling back to UInt::MAX");
UInt::MAX
})
}
+493
View File
@@ -0,0 +1,493 @@
use std::sync::{Arc, Mutex};
use language_tags::LanguageTag;
use matrix_sdk::{
async_trait,
widget::{MessageLikeEventFilter, StateEventFilter},
};
use tracing::error;
use crate::{room::Room, RUNTIME};
#[derive(uniffi::Record)]
pub struct WidgetDriverAndHandle {
pub driver: Arc<WidgetDriver>,
pub handle: Arc<WidgetDriverHandle>,
}
#[uniffi::export]
pub fn make_widget_driver(settings: WidgetSettings) -> Result<WidgetDriverAndHandle, ParseError> {
let (driver, handle) = matrix_sdk::widget::WidgetDriver::new(settings.try_into()?);
Ok(WidgetDriverAndHandle {
driver: Arc::new(WidgetDriver(Mutex::new(Some(driver)))),
handle: Arc::new(WidgetDriverHandle(handle)),
})
}
/// An object that handles all interactions of a widget living inside a webview
/// or IFrame with the Matrix world.
#[derive(uniffi::Object)]
pub struct WidgetDriver(Mutex<Option<matrix_sdk::widget::WidgetDriver>>);
#[uniffi::export(async_runtime = "tokio")]
impl WidgetDriver {
pub async fn run(
&self,
room: Arc<Room>,
capabilities_provider: Box<dyn WidgetCapabilitiesProvider>,
) {
let Some(driver) = self.0.lock().unwrap().take() else {
error!("Can't call run multiple times on a WidgetDriver");
return;
};
let capabilities_provider = CapabilitiesProviderWrap(capabilities_provider.into());
if let Err(()) = driver.run(room.inner.clone(), capabilities_provider).await {
// TODO
}
}
}
/// Information about a widget.
#[derive(uniffi::Record, Clone)]
pub struct WidgetSettings {
/// Widget's unique identifier.
pub widget_id: String,
/// Whether or not the widget should be initialized on load message
/// (`ContentLoad` message), or upon creation/attaching of the widget to
/// the SDK's state machine that drives the API.
pub init_after_content_load: bool,
/// This contains the url from the widget state event.
/// In this url placeholders can be used to pass information from the client
/// to the widget. Possible values are: `$widgetId`, `$parentUrl`,
/// `$userId`, `$lang`, `$fontScale`, `$analyticsID`.
///
/// # Examples
///
/// e.g `http://widget.domain?username=$userId`
/// will become: `http://widget.domain?username=@user_matrix_id:server.domain`.
raw_url: String,
}
impl TryFrom<WidgetSettings> for matrix_sdk::widget::WidgetSettings {
type Error = ParseError;
fn try_from(value: WidgetSettings) -> Result<Self, Self::Error> {
let WidgetSettings { widget_id, init_after_content_load, raw_url } = value;
Ok(matrix_sdk::widget::WidgetSettings::new(widget_id, init_after_content_load, &raw_url)?)
}
}
impl From<matrix_sdk::widget::WidgetSettings> for WidgetSettings {
fn from(value: matrix_sdk::widget::WidgetSettings) -> Self {
WidgetSettings {
widget_id: value.widget_id().to_owned(),
init_after_content_load: value.init_on_content_load(),
raw_url: value.raw_url().to_string(),
}
}
}
/// Create the actual url that can be used to setup the WebView or IFrame
/// that contains the widget.
///
/// # Arguments
/// * `widget_settings` - The widget settings to generate the url for.
/// * `room` - A matrix room which is used to query the logged in username
/// * `props` - Properties from the client that can be used by a widget to adapt
/// to the client. e.g. language, font-scale...
#[uniffi::export(async_runtime = "tokio")]
pub async fn generate_webview_url(
widget_settings: WidgetSettings,
room: Arc<Room>,
props: ClientProperties,
) -> Result<String, ParseError> {
Ok(matrix_sdk::widget::WidgetSettings::generate_webview_url(
&widget_settings.clone().try_into()?,
&room.inner,
props.into(),
)
.await
.map(|url| url.to_string())?)
}
/// Defines if a call is encrypted and which encryption system should be used.
///
/// This controls the url parameters: `perParticipantE2EE`, `password`.
#[derive(uniffi::Enum, Clone)]
pub enum EncryptionSystem {
/// Equivalent to the element call url parameter: `enableE2EE=false`
Unencrypted,
/// Equivalent to the element call url parameter:
/// `perParticipantE2EE=true`
PerParticipantKeys,
/// Equivalent to the element call url parameter:
/// `password={secret}`
SharedSecret {
/// The secret/password which is used in the url.
secret: String,
},
}
impl From<EncryptionSystem> for matrix_sdk::widget::EncryptionSystem {
fn from(value: EncryptionSystem) -> Self {
match value {
EncryptionSystem::Unencrypted => Self::Unencrypted,
EncryptionSystem::PerParticipantKeys => Self::PerParticipantKeys,
EncryptionSystem::SharedSecret { secret } => Self::SharedSecret { secret },
}
}
}
/// Properties to create a new virtual Element Call widget.
#[derive(uniffi::Record, Clone)]
pub struct VirtualElementCallWidgetOptions {
/// The url to the app.
///
/// E.g. <https://call.element.io>, <https://call.element.dev>
pub element_call_url: String,
/// The widget id.
pub widget_id: String,
/// The url that is used as the target for the PostMessages sent
/// by the widget (to the client).
///
/// For a web app client this is the client url. In case of using other
/// platforms the client most likely is setup up to listen to
/// postmessages in the same webview the widget is hosted. In this case
/// the `parent_url` is set to the url of the webview with the widget. Be
/// aware that this means that the widget will receive its own postmessage
/// messages. The `matrix-widget-api` (js) ignores those so this works but
/// it might break custom implementations.
///
/// Defaults to `element_call_url` for the non-iframe (dedicated webview)
/// usecase.
pub parent_url: Option<String>,
/// Whether the branding header of Element call should be hidden.
///
/// Default: `true`
pub hide_header: Option<bool>,
/// If set, the lobby will be skipped and the widget will join the
/// call on the `io.element.join` action.
///
/// Default: `false`
pub preload: Option<bool>,
/// The font scale which will be used inside element call.
///
/// Default: `1`
pub font_scale: Option<f64>,
/// Whether element call should prompt the user to open in the browser or
/// the app.
///
/// Default: `false`
pub app_prompt: Option<bool>,
/// Don't show the lobby and join the call immediately.
///
/// Default: `false`
pub skip_lobby: Option<bool>,
/// Make it not possible to get to the calls list in the webview.
///
/// Default: `true`
pub confine_to_room: Option<bool>,
/// The font to use, to adapt to the system font.
pub font: Option<String>,
/// Can be used to pass a PostHog id to element call.
pub analytics_id: Option<String>,
/// The encryption system to use.
///
/// Use `EncryptionSystem::Unencrypted` to disable encryption.
pub encryption: EncryptionSystem,
}
impl From<VirtualElementCallWidgetOptions> for matrix_sdk::widget::VirtualElementCallWidgetOptions {
fn from(value: VirtualElementCallWidgetOptions) -> Self {
Self {
element_call_url: value.element_call_url,
widget_id: value.widget_id,
parent_url: value.parent_url,
hide_header: value.hide_header,
preload: value.preload,
font_scale: value.font_scale,
app_prompt: value.app_prompt,
skip_lobby: value.skip_lobby,
confine_to_room: value.confine_to_room,
font: value.font,
analytics_id: value.analytics_id,
encryption: value.encryption.into(),
}
}
}
/// `WidgetSettings` are usually created from a state event.
/// (currently unimplemented)
///
/// In some cases the client wants to create custom `WidgetSettings`
/// for specific rooms based on other conditions.
/// This function returns a `WidgetSettings` object which can be used
/// to setup a widget using `run_client_widget_api`
/// and to generate the correct url for the widget.
/// # Arguments
/// * - `props` A struct containing the configuration parameters for a element
/// call widget.
#[uniffi::export]
pub fn new_virtual_element_call_widget(
props: VirtualElementCallWidgetOptions,
) -> Result<WidgetSettings, ParseError> {
Ok(matrix_sdk::widget::WidgetSettings::new_virtual_element_call_widget(props.into())
.map(|w| w.into())?)
}
/// The Capabilities required to run a element call widget.
///
/// This is intended to be used in combination with: `acquire_capabilities` of
/// the `CapabilitiesProvider`.
///
/// `acquire_capabilities` can simply return the `WidgetCapabilities` from this
/// function. Even if there are non intersecting permissions to what the widget
/// requested.
///
/// Editing and extending the capabilities from this function is also possible,
/// but should only be done as temporal workarounds until this function is
/// adjusted
#[uniffi::export]
pub fn get_element_call_required_permissions() -> WidgetCapabilities {
use ruma::events::StateEventType;
WidgetCapabilities {
read: vec![
WidgetEventFilter::StateWithType { event_type: StateEventType::CallMember.to_string() },
WidgetEventFilter::StateWithType { event_type: StateEventType::RoomMember.to_string() },
WidgetEventFilter::MessageLikeWithType {
event_type: "org.matrix.rageshake_request".to_owned(),
},
WidgetEventFilter::MessageLikeWithType {
event_type: "io.element.call.encryption_keys".to_owned(),
},
],
send: vec![
WidgetEventFilter::StateWithType { event_type: StateEventType::CallMember.to_string() },
WidgetEventFilter::StateWithType {
event_type: "org.matrix.rageshake_request".to_owned(),
},
WidgetEventFilter::StateWithType {
event_type: "io.element.call.encryption_keys".to_owned(),
},
],
requires_client: true,
}
}
#[derive(uniffi::Record)]
pub struct ClientProperties {
/// The client_id provides the widget with the option to behave differently
/// for different clients. e.g org.example.ios.
client_id: String,
/// The language tag the client is set to e.g. en-us. (Undefined and invalid
/// becomes: `en-US`)
language_tag: Option<String>,
/// A string describing the theme (dark, light) or org.example.dark.
/// (default: `light`)
theme: Option<String>,
}
impl From<ClientProperties> for matrix_sdk::widget::ClientProperties {
fn from(value: ClientProperties) -> Self {
let ClientProperties { client_id, language_tag, theme } = value;
let language_tag = language_tag.and_then(|l| LanguageTag::parse(&l).ok());
Self::new(&client_id, language_tag, theme)
}
}
/// A handle that encapsulates the communication between a widget driver and the
/// corresponding widget (inside a webview or IFrame).
#[derive(uniffi::Object)]
pub struct WidgetDriverHandle(matrix_sdk::widget::WidgetDriverHandle);
#[uniffi::export(async_runtime = "tokio")]
impl WidgetDriverHandle {
/// Receive a message from the widget driver.
///
/// The message must be passed on to the widget.
///
/// Returns `None` if the widget driver is no longer running.
pub async fn recv(&self) -> Option<String> {
self.0.recv().await
}
//// Send a message from the widget to the widget driver.
///
/// Returns `false` if the widget driver is no longer running.
pub async fn send(&self, msg: String) -> bool {
self.0.send(msg).await
}
}
/// Capabilities that a widget can request from a client.
#[derive(uniffi::Record)]
pub struct WidgetCapabilities {
/// Types of the messages that a widget wants to be able to fetch.
pub read: Vec<WidgetEventFilter>,
/// Types of the messages that a widget wants to be able to send.
pub send: Vec<WidgetEventFilter>,
/// If this capability is requested by the widget, it can not operate
/// separately from the matrix client.
///
/// This means clients should not offer to open the widget in a separate
/// browser/tab/webview that is not connected to the postmessage widget-api.
pub requires_client: bool,
}
impl From<WidgetCapabilities> for matrix_sdk::widget::Capabilities {
fn from(value: WidgetCapabilities) -> Self {
Self {
read: value.read.into_iter().map(Into::into).collect(),
send: value.send.into_iter().map(Into::into).collect(),
requires_client: value.requires_client,
}
}
}
impl From<matrix_sdk::widget::Capabilities> for WidgetCapabilities {
fn from(value: matrix_sdk::widget::Capabilities) -> Self {
Self {
read: value.read.into_iter().map(Into::into).collect(),
send: value.send.into_iter().map(Into::into).collect(),
requires_client: value.requires_client,
}
}
}
/// Different kinds of filters that could be applied to the timeline events.
#[derive(uniffi::Enum)]
pub enum WidgetEventFilter {
/// Matches message-like events with the given `type`.
MessageLikeWithType { event_type: String },
/// Matches `m.room.message` events with the given `msgtype`.
RoomMessageWithMsgtype { msgtype: String },
/// Matches state events with the given `type`, regardless of `state_key`.
StateWithType { event_type: String },
/// Matches state events with the given `type` and `state_key`.
StateWithTypeAndStateKey { event_type: String, state_key: String },
}
impl From<WidgetEventFilter> for matrix_sdk::widget::EventFilter {
fn from(value: WidgetEventFilter) -> Self {
match value {
WidgetEventFilter::MessageLikeWithType { event_type } => {
Self::MessageLike(MessageLikeEventFilter::WithType(event_type.into()))
}
WidgetEventFilter::RoomMessageWithMsgtype { msgtype } => {
Self::MessageLike(MessageLikeEventFilter::RoomMessageWithMsgtype(msgtype))
}
WidgetEventFilter::StateWithType { event_type } => {
Self::State(StateEventFilter::WithType(event_type.into()))
}
WidgetEventFilter::StateWithTypeAndStateKey { event_type, state_key } => {
Self::State(StateEventFilter::WithTypeAndStateKey(event_type.into(), state_key))
}
}
}
}
impl From<matrix_sdk::widget::EventFilter> for WidgetEventFilter {
fn from(value: matrix_sdk::widget::EventFilter) -> Self {
use matrix_sdk::widget::EventFilter as F;
match value {
F::MessageLike(MessageLikeEventFilter::WithType(event_type)) => {
Self::MessageLikeWithType { event_type: event_type.to_string() }
}
F::MessageLike(MessageLikeEventFilter::RoomMessageWithMsgtype(msgtype)) => {
Self::RoomMessageWithMsgtype { msgtype }
}
F::State(StateEventFilter::WithType(event_type)) => {
Self::StateWithType { event_type: event_type.to_string() }
}
F::State(StateEventFilter::WithTypeAndStateKey(event_type, state_key)) => {
Self::StateWithTypeAndStateKey { event_type: event_type.to_string(), state_key }
}
}
}
}
#[uniffi::export(callback_interface)]
pub trait WidgetCapabilitiesProvider: Send + Sync {
fn acquire_capabilities(&self, capabilities: WidgetCapabilities) -> WidgetCapabilities;
}
struct CapabilitiesProviderWrap(Arc<dyn WidgetCapabilitiesProvider>);
#[async_trait]
impl matrix_sdk::widget::CapabilitiesProvider for CapabilitiesProviderWrap {
async fn acquire_capabilities(
&self,
capabilities: matrix_sdk::widget::Capabilities,
) -> matrix_sdk::widget::Capabilities {
let this = self.0.clone();
// This could require a prompt to the user. Ideally the callback
// interface would just be async, but that's not supported yet so use
// one of tokio's blocking task threads instead.
RUNTIME
.spawn_blocking(move || this.acquire_capabilities(capabilities.into()).into())
.await
// propagate panics from the blocking task
.unwrap()
}
}
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[uniffi(flat_error)]
pub enum ParseError {
#[error("empty host")]
EmptyHost,
#[error("invalid international domain name")]
IdnaError,
#[error("invalid port number")]
InvalidPort,
#[error("invalid IPv4 address")]
InvalidIpv4Address,
#[error("invalid IPv6 address")]
InvalidIpv6Address,
#[error("invalid domain character")]
InvalidDomainCharacter,
#[error("relative URL without a base")]
RelativeUrlWithoutBase,
#[error("relative URL with a cannot-be-a-base base")]
RelativeUrlWithCannotBeABaseBase,
#[error("a cannot-be-a-base URL doesnt have a host to set")]
SetHostOnCannotBeABaseUrl,
#[error("URLs more than 4 GB are not supported")]
Overflow,
#[error("unknown URL parsing error")]
Other,
}
impl From<url::ParseError> for ParseError {
fn from(value: url::ParseError) -> Self {
match value {
url::ParseError::EmptyHost => Self::EmptyHost,
url::ParseError::IdnaError => Self::IdnaError,
url::ParseError::InvalidPort => Self::InvalidPort,
url::ParseError::InvalidIpv4Address => Self::InvalidIpv4Address,
url::ParseError::InvalidIpv6Address => Self::InvalidIpv6Address,
url::ParseError::InvalidDomainCharacter => Self::InvalidDomainCharacter,
url::ParseError::RelativeUrlWithoutBase => Self::RelativeUrlWithoutBase,
url::ParseError::RelativeUrlWithCannotBeABaseBase => {
Self::RelativeUrlWithCannotBeABaseBase
}
url::ParseError::SetHostOnCannotBeABaseUrl => Self::SetHostOnCannotBeABaseUrl,
url::ParseError::Overflow => Self::Overflow,
_ => Self::Other,
}
}
}
+3
View File
@@ -0,0 +1,3 @@
[bindings.kotlin]
package_name = "org.matrix.rustcomponents.sdk"
cdylib_name = "matrix_sdk_ffi"
+32
View File
@@ -0,0 +1,32 @@
coverage:
status:
project:
default:
# by default, we only care about test coverage of the main
# rust crates
target: auto
threshold: 1%
paths:
- "crates/matrix-sdk/"
- "crates/matrix-sdk-base/"
- "crates/matrix-sdk-common/"
- "crates/matrix-sdk-crypto/"
- "crates/matrix-sdk-qrcode/"
- "crates/matrix-sdk-sqlite/"
- "crates/matrix-sdk-store-encryption/"
# Coverage of wasm tests isn't supported at the moment,
# see rustwasm/wasm-bindgen#2276
# - "crates/matrix-sdk-indexeddb"
bindings:
# Coverage of binding tests is recorded but for informational
# purposes only
informational: true
paths:
- "bindings/"
patch: off
ignore:
- "bindings/matrix-sdk-crypto-ffi"
- "bindings/matrix-sdk-ffi"
- "crates/matrix-sdk-indexeddb"
- "testing"
- "xtask"
+4
View File
@@ -0,0 +1,4 @@
{
"rust-analyzer.checkOnSave.command": "clippy",
"rust-analyzer.rustfmt.extraArgs": ["+nightly"]
}
+15
View File
@@ -0,0 +1,15 @@
.PHONY: default clean png pdf
default: model.png model.pdf
clean:
rm -f model.png model.pdf
pdf: model.pdf
png: model.png
model.pdf: model.dot
./setdotlabelwidth 45 <model.dot | dot -Tpdf -o model.pdf
model.png: model.dot
./setdotlabelwidth 45 <model.dot | dot -Tpng -o model.png
+11
View File
@@ -0,0 +1,11 @@
This models the room key sharing algorithm as a decision tree and provides
tooling to render it as a PDF or PNG.
# Usage
make # Render the decision tree both as a PDF and PNG
make pdf # Renders the decision tree as a PDF
make png # Renders the decision tree as a PNG
make clean # Remove rendered artifacts
+45
View File
@@ -0,0 +1,45 @@
digraph {
label="Matrix room key sharing algorithm"
fontname="Fira Sans"
ratio=0.5
node [shape=box, colorscheme=paired6, style=filled, fillcolor=white, fontname="Fira Sans"]
edge [fontname="Fira Sans"]
/* Non-end states, additional checks needed. */
verified_device_check [label="START\n\nIs this our own, verified device?", labelfontname="Fira Sans"]
outbound_session_check [label="Outbound session exists?"]
outbound_exists [label="Session previously previously_shared with this user ID/device ID pair?"]
previously_shared [label="Requesting device sender (Curve25519) key matches the key we originally shared with?"]
own_device_check [label="Is this our own device?"]
/* End states */
allow_verified [label="Share the entire session from the earliest known index.\n\nOk(None)", color=4, fillcolor=3]
allow_limited [label="Share a limited session starting from index i, which is the index we previously shared at.\n\nOk(Some(i))", color=4, fillcolor=3]
refuse_device_key_changed [label="Sender key changed, refuse to share.\n\nErr(KeyForwardDecision::ChangedSenderKey)", color=6, fillcolor=5]
refuse_not_shared [label="Session was never shared with this device, refuse to share.\n\nErr(KeyForwardDecision::OutboundSessionNotShared)", color=6, fillcolor=5]
refuse_untrusted_own_device [label="Our own device, but it is untrusted and we haven't previously shared with it. Refuse to share.\n\nErr(KeyForwardDecision::UntrustedDevice)", color=6, fillcolor=5]
refuse_missing_outbound_session [label="Not our device and haven't previously shared with it. Refuse to share.\n\nErr(KeyForwardDecision::MissingOutboundSession)", color=6, fillcolor=5]
/* Checks */
/* Is this our own verified device? */
verified_device_check -> allow_verified [label="Yes"]
verified_device_check -> outbound_session_check [label="No"]
/* Does the outbound session exist? */
outbound_session_check -> outbound_exists [label="Yes"]
outbound_session_check -> own_device_check [label="No"]
/* Previously shared? */
outbound_exists -> previously_shared [label="Yes"]
outbound_exists -> refuse_not_shared [label="No"]
/* Requesting device sender key matches key it was shared with? */
previously_shared -> allow_limited [label="Yes"]
previously_shared -> refuse_device_key_changed [label="No"]
/* Is this our own device? */
own_device_check -> refuse_untrusted_own_device [label="Yes"]
own_device_check -> refuse_missing_outbound_session [label="No"]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/perl
#
# Adapted from https://stackoverflow.com/a/68057031
use strict;
my $usage = "setdotlabelwidth [char-width] < [dotfile]";
my $width = shift() or die("Usage: $usage $!");
while(<STDIN>)
{
if (m/label="(.*?)"/)
{
my $labeltext = $1;
my @words = split(/ +|(?=\\n)/, $labeltext);
my @newtext = ();
my $newline = "";
foreach my $word(@words)
{
if (length($newline) > 0 and
length($newline) + length($word) > $width)
{
push(@newtext, $newline);
$newline = "";
}
$newline .= " " if (length($newline) > 0);
$newline .= $word;
}
push(@newtext, $newline) if (length($newline) > 0);
my $newlabel = join("\\n", @newtext);
s/label=".*?"/label="$newlabel"/;
}
print;
}
+3 -3
View File
@@ -30,13 +30,13 @@ def timeout(flow):
# hold a tuple containing a function that may or may not create a failure and
# the probability weight at which rate this failure should be triggered.
#
# The method should return an http.HTTPResponse if it should modify the
# The method should return an http.Response if it should modify the
# response or None if the response should be passed as is.
FAILURES = {
"Success": (lambda x: None, 50),
"Gateway error":
(lambda _: http.HTTPResponse.make(500, b"Gateway error"), 20),
"Limit exeeded": (lambda _: http.HTTPResponse.make(
(lambda _: http.Response.make(500, b"Gateway error"), 20),
"Limit exceeded": (lambda _: http.Response.make(
429,
json.dumps({
"errcode": "M_LIMIT_EXCEEDED",
+39
View File
@@ -0,0 +1,39 @@
# 0.7.0
- Rename `RoomType` to `RoomState`
- Add `RoomInfo::state` accessor
- Remove `members` and `stripped_members` fields in `StateChanges`. Room member events are now with
other state events in `state` and `stripped_state`.
- `StateStore::get_user_ids` takes a `RoomMemberships` to be able to filter the results by any
membership state.
- `StateStore::get_joined_user_ids` and `StateStore::get_invited_user_ids` are deprecated.
- `Room::members` takes a `RoomMemberships` to be able to filter the results by any membership
state.
- `Room::active_members` and `Room::joined_members` are deprecated.
- `RoomMember` has new methods:
- `can_ban`
- `can_invite`
- `can_kick`
- `can_redact`
- `can_send_message`
- `can_send_state`
- `can_trigger_room_notification`
- Move `StateStore::get_member_event` to `StateStoreExt`
- `StateStore::get_stripped_room_infos` is deprecated. All room infos should now be returned by
`get_room_infos`.
- `BaseClient::get_stripped_rooms` is deprecated. Use `get_rooms_filtered` with
`RoomStateFilter::INVITED` instead.
- Add methods to `StateStore` to be able to retrieve data in batch
- `get_state_events_for_keys`
- `get_profiles`
- `get_presence_events`
- `get_users_with_display_names`
- Move `Session`, `SessionTokens` and associated methods to the `matrix-sdk` crate.
- Add `Room::subscribe_info`
# 0.5.1
## Bug Fixes
- #664: Fix regression with push rules being applied to the own user_id only instead of all but the own user_id
# 0.5.0
+71
View File
@@ -0,0 +1,71 @@
[package]
authors = ["Damir Jelić <poljar@termina.org.uk>"]
description = "The base component to build a Matrix client library."
edition = "2021"
homepage = "https://github.com/matrix-org/matrix-rust-sdk"
keywords = ["matrix", "chat", "messaging", "ruma", "nio"]
license = "Apache-2.0"
name = "matrix-sdk-base"
readme = "README.md"
repository = "https://github.com/matrix-org/matrix-rust-sdk"
rust-version = { workspace = true }
version = "0.7.0"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = []
e2e-encryption = ["dep:matrix-sdk-crypto"]
js = ["matrix-sdk-common/js", "matrix-sdk-crypto?/js", "ruma/js", "matrix-sdk-store-encryption/js"]
qrcode = ["matrix-sdk-crypto?/qrcode"]
automatic-room-key-forwarding = ["matrix-sdk-crypto?/automatic-room-key-forwarding"]
message-ids = ["matrix-sdk-crypto?/message-ids"]
experimental-sliding-sync = ["ruma/unstable-msc3575"]
# helpers for testing features build upon this
testing = [
"dep:assert_matches",
"dep:assert_matches2",
"dep:http",
"dep:matrix-sdk-test",
"matrix-sdk-crypto?/testing",
]
[dependencies]
as_variant = { workspace = true }
assert_matches = { workspace = true, optional = true }
assert_matches2 = { workspace = true, optional = true }
async-trait = { workspace = true }
bitflags = "2.1.0"
eyeball = { workspace = true }
eyeball-im = { workspace = true }
futures-util = { workspace = true }
http = { workspace = true, optional = true }
matrix-sdk-common = { workspace = true }
matrix-sdk-crypto = { workspace = true, optional = true }
matrix-sdk-store-encryption = { workspace = true }
matrix-sdk-test = { workspace = true, optional = true }
once_cell = { workspace = true }
ruma = { workspace = true, features = ["canonical-json", "unstable-msc3381"] }
serde = { workspace = true, features = ["rc"] }
serde_json = { workspace = true }
tokio = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
[dev-dependencies]
assert_matches = { workspace = true }
assert_matches2 = { workspace = true }
assign = "1.1.1"
futures-executor = { workspace = true }
http = { workspace = true }
matrix-sdk-test = { workspace = true }
stream_assert = { workspace = true }
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3.33"
+10
View File
@@ -0,0 +1,10 @@
This crate implements the base to build a [Matrix](https://matrix.org/) client
library.
## Crate Feature Flags
The following crate feature flags are available:
* `encryption`: Enables end-to-end encryption support in the library.
* `qrcode`: Enables QRcode generation and reading code.
* `testing`: Provides facilities and functions for tests, in particular for integration testing store implementations. ATTENTION: do not ever use outside of tests, we do not provide any stability warantees on these, these are merely helpers. If you find you _need_ any function provided here outside of tests, please open a Github Issue and inform us about your use case for us to consider.
File diff suppressed because it is too large Load Diff
+103
View File
@@ -0,0 +1,103 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Helpers for creating `std::fmt::Debug` implementations.
use std::{collections::BTreeMap, fmt};
pub use matrix_sdk_common::debug::*;
use ruma::{
api::client::{push::get_notifications::v3::Notification, sync::sync_events::v3::InvitedRoom},
serde::Raw,
OwnedRoomId,
};
/// A wrapper around a slice of `Raw` events that implements `Debug` in a way
/// that only prints the event type of each item.
pub struct DebugListOfRawEventsNoId<'a, T>(pub &'a [Raw<T>]);
#[cfg(not(tarpaulin_include))]
impl<'a, T> fmt::Debug for DebugListOfRawEventsNoId<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut list = f.debug_list();
list.entries(self.0.iter().map(DebugRawEventNoId));
list.finish()
}
}
/// A wrapper around a notification map as found in `/sync` responses that
/// implements `Debug` in a way that only prints the event ID and event type
/// for the raw events contained in each notification.
pub struct DebugNotificationMap<'a>(pub &'a BTreeMap<OwnedRoomId, Vec<Notification>>);
#[cfg(not(tarpaulin_include))]
impl<'a> fmt::Debug for DebugNotificationMap<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut map = f.debug_map();
map.entries(self.0.iter().map(|(room_id, raw)| (room_id, DebugNotificationList(raw))));
map.finish()
}
}
struct DebugNotificationList<'a>(&'a [Notification]);
#[cfg(not(tarpaulin_include))]
impl<'a> fmt::Debug for DebugNotificationList<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut list = f.debug_list();
list.entries(self.0.iter().map(DebugNotification));
list.finish()
}
}
struct DebugNotification<'a>(&'a Notification);
#[cfg(not(tarpaulin_include))]
impl<'a> fmt::Debug for DebugNotification<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Notification")
.field("actions", &self.0.actions)
.field("event", &DebugRawEvent(&self.0.event))
.field("profile_tag", &self.0.profile_tag)
.field("read", &self.0.read)
.field("room_id", &self.0.room_id)
.field("ts", &self.0.ts)
.finish()
}
}
/// A wrapper around an invited room as found in `/sync` responses that
/// implements `Debug` in a way that only prints the event ID and event type for
/// the raw events contained in `invite_state`.
pub struct DebugInvitedRoom<'a>(pub &'a InvitedRoom);
#[cfg(not(tarpaulin_include))]
impl<'a> fmt::Debug for DebugInvitedRoom<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InvitedRoom")
.field("invite_state", &DebugListOfRawEvents(&self.0.invite_state.events))
.finish()
}
}
pub(crate) struct DebugListOfRawEvents<'a, T>(pub &'a [Raw<T>]);
#[cfg(not(tarpaulin_include))]
impl<'a, T> fmt::Debug for DebugListOfRawEvents<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut list = f.debug_list();
list.entries(self.0.iter().map(DebugRawEvent));
list.finish()
}
}
@@ -0,0 +1,290 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! SDK-specific variations of response types from Ruma.
use std::{collections::BTreeMap, fmt};
pub use matrix_sdk_common::deserialized_responses::*;
use ruma::{
events::{
room::{
member::{MembershipState, RoomMemberEvent, RoomMemberEventContent},
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
},
AnyStrippedStateEvent, AnySyncStateEvent, EventContentFromType,
PossiblyRedactedStateEventContent, RedactContent, RedactedStateEventContent,
StateEventContent, StaticStateEventContent, StrippedStateEvent, SyncStateEvent,
},
serde::Raw,
EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, UserId,
};
use serde::Serialize;
/// A change in ambiguity of room members that an `m.room.member` event
/// triggers.
#[derive(Clone, Debug, Default)]
#[non_exhaustive]
pub struct AmbiguityChange {
/// Is the member that is contained in the state key of the `m.room.member`
/// event itself ambiguous because of the event.
pub member_ambiguous: bool,
/// Has another user been disambiguated because of this event.
pub disambiguated_member: Option<OwnedUserId>,
/// Has another user become ambiguous because of this event.
pub ambiguated_member: Option<OwnedUserId>,
}
/// Collection of ambiguity changes that room member events trigger.
#[derive(Clone, Debug, Default)]
#[non_exhaustive]
pub struct AmbiguityChanges {
/// A map from room id to a map of an event id to the `AmbiguityChange` that
/// the event with the given id caused.
pub changes: BTreeMap<OwnedRoomId, BTreeMap<OwnedEventId, AmbiguityChange>>,
}
/// A deserialized response for the rooms members API call.
///
/// [`GET /_matrix/client/r0/rooms/{roomId}/members`](https://spec.matrix.org/v1.5/client-server-api/#get_matrixclientv3roomsroomidmembers)
#[derive(Clone, Debug, Default)]
pub struct MembersResponse {
/// The list of members events.
pub chunk: Vec<RoomMemberEvent>,
/// Collection of ambiguity changes that room member events trigger.
pub ambiguity_changes: AmbiguityChanges,
}
/// Wrapper around both versions of any raw state event.
#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
pub enum RawAnySyncOrStrippedState {
/// An event from a room in joined or left state.
Sync(Raw<AnySyncStateEvent>),
/// An event from a room in invited state.
Stripped(Raw<AnyStrippedStateEvent>),
}
impl RawAnySyncOrStrippedState {
/// Try to deserialize the inner JSON as the expected type.
pub fn deserialize(&self) -> serde_json::Result<AnySyncOrStrippedState> {
match self {
Self::Sync(raw) => Ok(AnySyncOrStrippedState::Sync(raw.deserialize()?)),
Self::Stripped(raw) => Ok(AnySyncOrStrippedState::Stripped(raw.deserialize()?)),
}
}
/// Turns this `RawAnySyncOrStrippedState` into `RawSyncOrStrippedState<C>`
/// without changing the underlying JSON.
pub fn cast<C>(self) -> RawSyncOrStrippedState<C>
where
C: StaticStateEventContent + RedactContent,
C::Redacted: RedactedStateEventContent,
{
match self {
Self::Sync(raw) => RawSyncOrStrippedState::Sync(raw.cast()),
Self::Stripped(raw) => RawSyncOrStrippedState::Stripped(raw.cast()),
}
}
}
/// Wrapper around both versions of any state event.
#[derive(Clone, Debug)]
pub enum AnySyncOrStrippedState {
/// An event from a room in joined or left state.
Sync(AnySyncStateEvent),
/// An event from a room in invited state.
Stripped(AnyStrippedStateEvent),
}
impl AnySyncOrStrippedState {
/// If this is an `AnySyncStateEvent`, return a reference to the inner
/// event.
pub fn as_sync(&self) -> Option<&AnySyncStateEvent> {
match self {
Self::Sync(ev) => Some(ev),
Self::Stripped(_) => None,
}
}
/// If this is an `AnyStrippedStateEvent`, return a reference to the inner
/// event.
pub fn as_stripped(&self) -> Option<&AnyStrippedStateEvent> {
match self {
Self::Sync(_) => None,
Self::Stripped(ev) => Some(ev),
}
}
}
/// Wrapper around both versions of a raw state event.
#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
pub enum RawSyncOrStrippedState<C>
where
C: StaticStateEventContent + RedactContent,
C::Redacted: RedactedStateEventContent,
{
/// An event from a room in joined or left state.
Sync(Raw<SyncStateEvent<C>>),
/// An event from a room in invited state.
Stripped(Raw<StrippedStateEvent<C::PossiblyRedacted>>),
}
impl<C> RawSyncOrStrippedState<C>
where
C: StaticStateEventContent + RedactContent,
C::Redacted: RedactedStateEventContent + fmt::Debug + Clone,
{
/// Try to deserialize the inner JSON as the expected type.
pub fn deserialize(&self) -> serde_json::Result<SyncOrStrippedState<C>>
where
C: StaticStateEventContent + EventContentFromType + RedactContent,
C::Redacted: RedactedStateEventContent<StateKey = C::StateKey> + EventContentFromType,
C::PossiblyRedacted: PossiblyRedactedStateEventContent + EventContentFromType,
{
match self {
Self::Sync(ev) => Ok(SyncOrStrippedState::Sync(ev.deserialize()?)),
Self::Stripped(ev) => Ok(SyncOrStrippedState::Stripped(ev.deserialize()?)),
}
}
}
/// Raw version of [`MemberEvent`].
pub type RawMemberEvent = RawSyncOrStrippedState<RoomMemberEventContent>;
/// Wrapper around both versions of a state event.
#[derive(Clone, Debug)]
pub enum SyncOrStrippedState<C>
where
C: StaticStateEventContent + RedactContent,
C::Redacted: RedactedStateEventContent + fmt::Debug + Clone,
{
/// An event from a room in joined or left state.
Sync(SyncStateEvent<C>),
/// An event from a room in invited state.
Stripped(StrippedStateEvent<C::PossiblyRedacted>),
}
impl<C> SyncOrStrippedState<C>
where
C: StaticStateEventContent + RedactContent,
C::Redacted: RedactedStateEventContent<StateKey = C::StateKey> + fmt::Debug + Clone,
C::PossiblyRedacted: PossiblyRedactedStateEventContent<StateKey = C::StateKey>,
{
/// If this is a `SyncStateEvent`, return a reference to the inner event.
pub fn as_sync(&self) -> Option<&SyncStateEvent<C>> {
match self {
Self::Sync(ev) => Some(ev),
Self::Stripped(_) => None,
}
}
/// If this is a `StrippedStateEvent`, return a reference to the inner
/// event.
pub fn as_stripped(&self) -> Option<&StrippedStateEvent<C::PossiblyRedacted>> {
match self {
Self::Sync(_) => None,
Self::Stripped(ev) => Some(ev),
}
}
/// The sender of this event.
pub fn sender(&self) -> &UserId {
match self {
Self::Sync(e) => e.sender(),
Self::Stripped(e) => &e.sender,
}
}
/// The ID of this event.
pub fn event_id(&self) -> Option<&EventId> {
match self {
Self::Sync(e) => Some(e.event_id()),
Self::Stripped(_) => None,
}
}
/// The server timestamp of this event.
pub fn origin_server_ts(&self) -> Option<MilliSecondsSinceUnixEpoch> {
match self {
Self::Sync(e) => Some(e.origin_server_ts()),
Self::Stripped(_) => None,
}
}
/// The state key associated to this state event.
pub fn state_key(&self) -> &C::StateKey {
match self {
Self::Sync(e) => e.state_key(),
Self::Stripped(e) => &e.state_key,
}
}
}
impl<C> SyncOrStrippedState<C>
where
C: StaticStateEventContent<PossiblyRedacted = C>
+ RedactContent
+ PossiblyRedactedStateEventContent,
C::Redacted: RedactedStateEventContent<StateKey = <C as StateEventContent>::StateKey>
+ fmt::Debug
+ Clone,
{
/// The inner content of the wrapped event.
pub fn original_content(&self) -> Option<&C> {
match self {
Self::Sync(e) => e.as_original().map(|e| &e.content),
Self::Stripped(e) => Some(&e.content),
}
}
}
/// Wrapper around both MemberEvent-Types
pub type MemberEvent = SyncOrStrippedState<RoomMemberEventContent>;
impl MemberEvent {
/// The membership state of the user.
pub fn membership(&self) -> &MembershipState {
match self {
MemberEvent::Sync(e) => e.membership(),
MemberEvent::Stripped(e) => &e.content.membership,
}
}
/// The user id associated to this member event.
pub fn user_id(&self) -> &UserId {
self.state_key()
}
/// The name that should be displayed for this member event.
///
/// It there is no `displayname` in the event's content, the localpart or
/// the user ID is returned.
pub fn display_name(&self) -> &str {
self.original_content()
.and_then(|c| c.displayname.as_deref())
.unwrap_or_else(|| self.user_id().localpart())
}
}
impl SyncOrStrippedState<RoomPowerLevelsEventContent> {
/// The power levels of the event.
pub fn power_levels(&self) -> RoomPowerLevels {
match self {
Self::Sync(e) => e.power_levels(),
Self::Stripped(e) => e.power_levels(),
}
}
}

Some files were not shown because too many files have changed in this diff Show More