Skip to content

Commit 52f70d9

Browse files
authored
Return an array of ProcessedToDeviceEvent from receiveSyncChanges (#236)
Bump the dependency om matrix-rust-sdk to `59ecb1edb`, which includes matrix-org/matrix-rust-sdk#4935, which modifies `receive_sync_changes` so that it returns an list of `ProcessedToDeviceEvent` enums instead of `Raw<AnyToDeiceEvent>`s. To reflect this in javascript, we define a new wrapper struct for each variant, which can then be duck-typed. This is the same trick we use with the request objects returned by `outgoingRequests`.
1 parent 0b9ff3b commit 52f70d9

File tree

8 files changed

+279
-58
lines changed

8 files changed

+279
-58
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# UNRELEASED
22

3+
- Update matrix-rusk-sdk to `59ecb1edb`.
4+
5+
- **BREAKING**: `OlmMachine.receiveSyncChanges` now returns a list of
6+
`ProcessedToDeviceEvent` instead of a JSON-encoded list of JSON-encoded events.
7+
This allows making the difference between an event that was sent in clear and
8+
the same event successfully decrypted.
9+
([#236](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/236))
10+
311
# matrix-sdk-crypto-wasm v14.2.1
412

513
Update matrix-sdk-crypto to `0.11.1`, which includes:

Cargo.lock

Lines changed: 12 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ futures-util = "0.3.27"
6565
getrandom = { version = "0.3.0", features = ["wasm_js"] }
6666
http = "1.1.0"
6767
js-sys = "0.3.49"
68-
matrix-sdk-common = { version = "0.11.0", features = ["js"] }
69-
matrix-sdk-indexeddb = { version = "0.11.0", default-features = false, features = ["e2e-encryption"] }
70-
matrix-sdk-qrcode = { version = "0.11.0", optional = true }
68+
matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "59ecb1edb", features = ["js"] }
69+
matrix-sdk-indexeddb = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "59ecb1edb", default-features = false, features = ["e2e-encryption"] }
70+
matrix-sdk-qrcode = { git = "https://github.com/matrix-org/matrix-rust-sdk", rev = "59ecb1edb", optional = true }
7171
serde = "1.0.91"
7272
serde_json = "1.0.91"
7373
serde-wasm-bindgen = "0.6.5"
@@ -83,7 +83,8 @@ wasm-bindgen-test = "0.3.37"
8383
vergen-gitcl = { version = "1.0.0", features = ["build"] }
8484

8585
[dependencies.matrix-sdk-crypto]
86-
version = "0.11.0"
86+
git = "https://github.com/matrix-org/matrix-rust-sdk"
87+
rev = "59ecb1edb"
8788
default-features = false
8889
features = ["js", "automatic-room-key-forwarding"]
8990

index.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ declare module "./pkg/matrix_sdk_crypto_wasm.js" {
6161
| RoomMessageRequest
6262
| KeysBackupRequest;
6363

64+
/** The types returned by {@link OlmMachine.receiveSyncChanges}. */
65+
type ProcessedToDeviceEvent =
66+
| DecryptedToDeviceEvent
67+
| PlainTextToDeviceEvent
68+
| InvalidToDeviceEvent
69+
| UTDToDeviceEvent;
70+
6471
interface OlmMachine {
6572
trackedUsers(): Promise<Set<UserId>>;
6673
updateTrackedUsers(users: UserId[]): Promise<void>;
@@ -69,7 +76,7 @@ declare module "./pkg/matrix_sdk_crypto_wasm.js" {
6976
changed_devices: DeviceLists,
7077
one_time_keys_counts: Map<string, number>,
7178
unused_fallback_keys?: Set<string> | null,
72-
): Promise<string>;
79+
): Promise<Array<ProcessedToDeviceEvent>>;
7380
outgoingRequests(): Promise<Array<OutgoingRequest>>;
7481
markRequestAsSent(request_id: string, request_type: RequestType, response: string): Promise<boolean>;
7582
encryptRoomEvent(room_id: RoomId, event_type: string, content: string): Promise<string>;

src/machine.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ use crate::{
4242
store,
4343
store::{RoomKeyInfo, RoomKeyWithheldInfo, StoreHandle},
4444
sync_events,
45-
types::{self, RoomKeyImportResult, RoomSettings, SignatureVerification},
45+
types::{
46+
self, processed_to_device_event_to_js_value, RoomKeyImportResult, RoomSettings,
47+
SignatureVerification,
48+
},
4649
verification, vodozemac,
4750
};
4851

@@ -298,7 +301,11 @@ impl OlmMachine {
298301
///
299302
/// # Returns
300303
///
301-
/// A list of JSON strings, containing the decrypted to-device events.
304+
/// A list of values, each of which can be any of:
305+
/// * {@link DecryptedToDeviceEvent}
306+
/// * {@link PlainTextToDeviceEvent}
307+
/// * {@link UTDToDeviceEvent}
308+
/// * {@link InvalidToDeviceEvent}
302309
#[wasm_bindgen(js_name = "receiveSyncChanges")]
303310
pub fn receive_sync_changes(
304311
&self,
@@ -341,7 +348,7 @@ impl OlmMachine {
341348
// we discard the list of updated room keys in the result; JS applications are
342349
// expected to use register_room_key_updated_callback to receive updated room
343350
// keys.
344-
let (decrypted_to_device_events, _) = me
351+
let (processed_to_device_events, _) = me
345352
.receive_sync_changes(EncryptionSyncChanges {
346353
to_device_events,
347354
changed_devices: &changed_devices,
@@ -353,7 +360,10 @@ impl OlmMachine {
353360
})
354361
.await?;
355362

356-
Ok(serde_json::to_string(&decrypted_to_device_events)?)
363+
Ok(processed_to_device_events
364+
.into_iter()
365+
.map(processed_to_device_event_to_js_value)
366+
.collect::<Vec<_>>())
357367
}))
358368
}
359369

src/types.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,135 @@ impl From<&RoomSettings> for matrix_sdk_crypto::store::RoomSettings {
362362
}
363363
}
364364
}
365+
366+
/// The type of a {@link ProcessedToDeviceEvent}.
367+
#[wasm_bindgen]
368+
#[derive(Debug, Clone)]
369+
pub enum ProcessedToDeviceEventType {
370+
/// A successfully-decrypted encrypted to-device message.
371+
Decrypted,
372+
373+
/// An encrypted to-device message which could not be decrypted.
374+
UnableToDecrypt,
375+
376+
/// An unencrypted to-device message (sent in clear).
377+
PlainText,
378+
379+
/// An invalid to-device message that was ignored because it is missing some
380+
/// required information to be processed (like no event `type` for
381+
/// example)
382+
Invalid,
383+
}
384+
385+
/// Represents an encrypted to-device event, after it has been decrypted.
386+
#[wasm_bindgen]
387+
#[derive(Debug, Clone)]
388+
pub struct DecryptedToDeviceEvent {
389+
/// A JSON-encoded object containing the decrypted event, as if it had been
390+
/// sent in the clear.
391+
///
392+
/// Typically contains properties `type`, `sender` and `content`.
393+
///
394+
/// (For room keys or secrets, some part of the content might have been
395+
/// zeroized).
396+
#[wasm_bindgen(readonly, getter_with_clone, js_name = "decryptedRawEvent")]
397+
pub decrypted_raw_event: JsString,
398+
}
399+
400+
#[wasm_bindgen]
401+
impl DecryptedToDeviceEvent {
402+
/// The type of processed to-device event. Always {@link
403+
/// ProcessedToDeviceEventType.Decrypted} for this type.
404+
#[wasm_bindgen(getter, js_name = "type")]
405+
pub fn processed_type(&self) -> ProcessedToDeviceEventType {
406+
ProcessedToDeviceEventType::Decrypted
407+
}
408+
}
409+
410+
/// Represents a to-device event sent in the clear.
411+
#[wasm_bindgen]
412+
#[derive(Debug, Clone)]
413+
pub struct PlainTextToDeviceEvent {
414+
/// A JSON-encoded object containing the Matrix to-device message with
415+
/// `type`, `sender` and `content` fields.
416+
#[wasm_bindgen(readonly, getter_with_clone, js_name = "rawEvent")]
417+
pub raw_event: JsString,
418+
}
419+
420+
#[wasm_bindgen]
421+
impl PlainTextToDeviceEvent {
422+
/// The type of processed to-device event. Always {@link
423+
/// ProcessedToDeviceEventType.PlainText} for this type.
424+
#[wasm_bindgen(getter, js_name = "type")]
425+
pub fn processed_type(&self) -> ProcessedToDeviceEventType {
426+
ProcessedToDeviceEventType::PlainText
427+
}
428+
}
429+
430+
/// Represents an encrypted to-device event that could not be decrypted.
431+
#[wasm_bindgen]
432+
#[derive(Debug, Clone)]
433+
pub struct UTDToDeviceEvent {
434+
/// A JSON-encoded object containing the original message of type
435+
/// `m.room.encrypted` that failed to be decrypted.
436+
#[wasm_bindgen(readonly, getter_with_clone, js_name = "wireEvent")]
437+
pub wire_event: JsString,
438+
// TODO: Add some OlmError in the future
439+
}
440+
441+
#[wasm_bindgen]
442+
impl UTDToDeviceEvent {
443+
/// The type of processed to-device event. Always {@link
444+
/// ProcessedToDeviceEventType.UnableToDecrypt} for this type.
445+
#[wasm_bindgen(getter, js_name = "type")]
446+
pub fn processed_type(&self) -> ProcessedToDeviceEventType {
447+
ProcessedToDeviceEventType::UnableToDecrypt
448+
}
449+
}
450+
451+
/// Represents an invalid to-device event that was ignored (because it is
452+
/// missing some mandatory fields, for example).
453+
#[wasm_bindgen]
454+
#[derive(Debug, Clone)]
455+
pub struct InvalidToDeviceEvent {
456+
/// A JSON-encoded object containing the original message as received from
457+
/// sync.
458+
#[wasm_bindgen(readonly, getter_with_clone, js_name = "wireEvent")]
459+
pub wire_event: JsString,
460+
// TODO: Add some error information here?
461+
}
462+
463+
#[wasm_bindgen]
464+
impl InvalidToDeviceEvent {
465+
/// The type of processed to-device event. Always {@link
466+
/// ProcessedToDeviceEventType.Invalid} for this type.
467+
#[wasm_bindgen(getter, js_name = "type")]
468+
pub fn processed_type(&self) -> ProcessedToDeviceEventType {
469+
ProcessedToDeviceEventType::Invalid
470+
}
471+
}
472+
473+
/// Convert an `ProcessedToDeviceEvent` into a `JsValue`, ready to return to
474+
/// JavaScript.
475+
///
476+
/// JavaScript has no complex enums like Rust. To return structs of
477+
/// different types, we have no choice other than hiding everything behind a
478+
/// `JsValue`.
479+
pub fn processed_to_device_event_to_js_value(
480+
processed_to_device_event: matrix_sdk_crypto::types::ProcessedToDeviceEvent,
481+
) -> JsValue {
482+
match processed_to_device_event {
483+
matrix_sdk_crypto::types::ProcessedToDeviceEvent::Decrypted(raw) => {
484+
DecryptedToDeviceEvent { decrypted_raw_event: raw.json().get().into() }.into()
485+
}
486+
matrix_sdk_crypto::types::ProcessedToDeviceEvent::UnableToDecrypt(utd) => {
487+
UTDToDeviceEvent { wire_event: utd.json().get().into() }.into()
488+
}
489+
matrix_sdk_crypto::types::ProcessedToDeviceEvent::PlainText(plain) => {
490+
PlainTextToDeviceEvent { raw_event: plain.json().get().into() }.into()
491+
}
492+
matrix_sdk_crypto::types::ProcessedToDeviceEvent::Invalid(invalid) => {
493+
InvalidToDeviceEvent { wire_event: invalid.json().get().into() }.into()
494+
}
495+
}
496+
}

tests/helper.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ async function addMachineToMachine(machineToAdd, machine) {
1616
const oneTimeKeyCounts = new Map();
1717
const unusedFallbackKeys = new Set();
1818

19-
const receiveSyncChanges = JSON.parse(
20-
await machineToAdd.receiveSyncChanges(toDeviceEvents, changedDevices, oneTimeKeyCounts, unusedFallbackKeys),
19+
const receiveSyncChanges = await machineToAdd.receiveSyncChanges(
20+
toDeviceEvents,
21+
changedDevices,
22+
oneTimeKeyCounts,
23+
unusedFallbackKeys,
2124
);
22-
2325
expect(receiveSyncChanges).toEqual([]);
2426

2527
const outgoingRequests = await machineToAdd.outgoingRequests();

0 commit comments

Comments
 (0)