From 5e848abe2f51ed999ef2bd4f524ec15608c066bd Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 6 Feb 2024 11:33:35 +0100 Subject: [PATCH 01/18] Add support for sending encrypted to_device --- CHANGELOG.md | 3 + src/device.rs | 37 +++++++++++- tests/device.test.js | 134 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 320973b..143e6a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # UNRELEASED +- Adds a new API `Device#encryptToDeviceEvent` to encrypt an event using + olm. + # matrix-sdk-crypto-wasm v4.6.0 - Update dependencies, including matrix-rust-sdk to diff --git a/src/device.rs b/src/device.rs index 52e964a..c830fcb 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,13 +1,16 @@ //! Types for a `Device`. use js_sys::{Array, Map, Promise}; +use serde_json::Value; use wasm_bindgen::prelude::*; use crate::{ encryption::EncryptionAlgorithm, future::future_to_promise, identifiers::{self, DeviceId, UserId}, - impl_from_to_inner, requests, types, verification, vodozemac, + impl_from_to_inner, + requests::{self}, + types, verification, vodozemac, }; /// A device represents a E2EE capable client of an user. @@ -51,6 +54,38 @@ impl Device { })) } + /// Encrypt an event to be sent to this device. + /// (olm encryption). + /// + /// Prior to calling this method you must ensure that an olm session is + /// available for the target device. This can be done by calling the + /// [`get_missing_sessions()`](OlmMachine::get_missing_sessions) + /// + /// The caller is responsible for sending the encrypted + /// event to the target device. If multiple messages are + /// encrypted using this method they should be sent in the same order as + /// they are encrypted. + /// + /// # Returns + /// Returns a Promise for a `json` string of the encrypted event. + /// Can be used to create the payload for a `/sendToDevice` API. + #[wasm_bindgen(js_name = "encryptToDeviceEvent")] + pub fn encrypt_to_device_event( + &self, + event_type: String, + content: JsValue, + ) -> Result { + let me = self.inner.clone(); + let content: Value = serde_wasm_bindgen::from_value(content)?; + let event_type = event_type.clone(); + + Ok(future_to_promise(async move { + let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; + + Ok(raw_encrypted.into_json().to_string()) + })) + } + /// Is this device considered to be verified. /// /// This method returns true if either the `is_locally_trusted` diff --git a/tests/device.test.js b/tests/device.test.js index fde7e96..c6506b2 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -146,6 +146,140 @@ describe(OlmMachine.name, () => { }); }); +describe("Send to device", () => { + const userId1 = new UserId("@alice:example.org"); + const deviceId1 = new DeviceId("alice_device"); + + const userId2 = new UserId("@bob:example.org"); + const deviceId2 = new DeviceId("bob_device"); + + function machine(newUser, newDevice) { + return OlmMachine.initialize(newUser || userId1, newDevice || deviceId1); + } + + it("can send a to-device message", async () => { + // Olm machine. + const m = await machine(userId1, deviceId1); + + // Make m aware of another device, and get some OTK to be able to establish a session. + { + // derived from https://github.com/matrix-org/matrix-rust-sdk/blob/7f49618d350fab66b7e1dc4eaf64ec25ceafd658/benchmarks/benches/crypto_bench/keys_query.json + const hypotheticalResponse = JSON.stringify({ + device_keys: { + "@example:localhost": { + AFGUOBTZWM: { + algorithms: ["m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"], + device_id: "AFGUOBTZWM", + keys: { + "curve25519:AFGUOBTZWM": "boYjDpaC+7NkECQEeMh5dC+I1+AfriX0VXG2UV7EUQo", + "ed25519:AFGUOBTZWM": "NayrMQ33ObqMRqz6R9GosmHdT6HQ6b/RX/3QlZ2yiec", + }, + signatures: { + "@example:localhost": { + "ed25519:AFGUOBTZWM": + "RoSWvru1jj6fs2arnTedWsyIyBmKHMdOu7r9gDi0BZ61h9SbCK2zLXzuJ9ZFLao2VvA0yEd7CASCmDHDLYpXCA", + }, + }, + user_id: "@example:localhost", + unsigned: { + device_display_name: "rust-sdk", + }, + }, + }, + }, + failures: {}, + master_keys: { + "@example:localhost": { + user_id: "@example:localhost", + usage: ["master"], + keys: { + "ed25519:n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU": + "n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU", + }, + signatures: { + "@example:localhost": { + "ed25519:TCSJXPWGVS": + "+j9G3L41I1fe0++wwusTTQvbboYW0yDtRWUEujhwZz4MAltjLSfJvY0hxhnz+wHHmuEXvQDen39XOpr1p29sAg", + }, + }, + }, + }, + self_signing_keys: { + "@example:localhost": { + user_id: "@example:localhost", + usage: ["self_signing"], + keys: { + "ed25519:kQXOuy639Yt47mvNTdrIluoC6DMvfbZLYbxAmwiDyhI": + "kQXOuy639Yt47mvNTdrIluoC6DMvfbZLYbxAmwiDyhI", + }, + signatures: { + "@example:localhost": { + "ed25519:n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU": + "q32ifix/qyRpvmegw2BEJklwoBCAJldDNkcX+fp+lBA4Rpyqtycxge6BA4hcJdxYsy3oV0IHRuugS8rJMMFyAA", + }, + }, + }, + }, + user_signing_keys: { + "@example:localhost": { + user_id: "@example:localhost", + usage: ["user_signing"], + keys: { + "ed25519:g4ED07Fnqf3GzVWNN1pZ0IFrPQVdqQf+PYoJNH4eE0s": + "g4ED07Fnqf3GzVWNN1pZ0IFrPQVdqQf+PYoJNH4eE0s", + }, + signatures: { + "@example:localhost": { + "ed25519:n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU": + "nKQu8alQKDefNbZz9luYPcNj+Z+ouQSot4fU/A23ELl1xrI06QVBku/SmDx0sIW1ytso0Cqwy1a+3PzCa1XABg", + }, + }, + }, + }, + }); + const marked = await m.markRequestAsSent("foo", RequestType.KeysQuery, hypotheticalResponse); + } + + { + // derived from https://github.com/matrix-org/matrix-rust-sdk/blob/7f49618d350fab66b7e1dc4eaf64ec25ceafd658/benchmarks/benches/crypto_bench/keys_claim.json + const hypotheticalResponse = JSON.stringify({ + one_time_keys: { + "@example:localhost": { + AFGUOBTZWM: { + "signed_curve25519:AAAABQ": { + key: "9IGouMnkB6c6HOd4xUsNv4i3Dulb4IS96TzDordzOws", + signatures: { + "@example:localhost": { + "ed25519:AFGUOBTZWM": + "2bvUbbmJegrV0eVP/vcJKuIWC3kud+V8+C0dZtg4dVovOSJdTP/iF36tQn2bh5+rb9xLlSeztXBdhy4c+LiOAg", + }, + }, + }, + }, + }, + }, + failures: {}, + }); + const marked = await m.markRequestAsSent("bar", RequestType.KeysClaim, hypotheticalResponse); + } + + // Pick the device we want to encrypt to. + const device2 = await m.getDevice(new UserId("@example:localhost"), new DeviceId("AFGUOBTZWM")); + + const content = { + body: "Hello, World!", + }; + const type = "some.custon.event.type"; + + const toDevice = await device2.encryptToDeviceEvent(type, content); + + const olmContent = JSON.parse(toDevice); + expect(olmContent.algorithm).toStrictEqual("m.olm.v1.curve25519-aes-sha2"); + expect(olmContent.ciphertext).toBeDefined(); + expect(olmContent.ciphertext["boYjDpaC+7NkECQEeMh5dC+I1+AfriX0VXG2UV7EUQo"]).toBeDefined(); + }); +}); + describe("Key Verification", () => { const userId1 = new UserId("@alice:example.org"); const deviceId1 = new DeviceId("alice_device"); From d81a6b753dcc8e8dd9f655ff19bc1a05406693e3 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:30:57 +0100 Subject: [PATCH 02/18] review: Better doc Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 143e6a4..3e9836c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # UNRELEASED -- Adds a new API `Device#encryptToDeviceEvent` to encrypt an event using - olm. +- Adds a new API `Device#encryptToDeviceEvent` to encrypt a to-device event using + Olm. # matrix-sdk-crypto-wasm v4.6.0 From dbc0893575ffb1378f89b01bc7a22116a4a2751e Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:31:40 +0100 Subject: [PATCH 03/18] Review improve comment Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- src/device.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/device.rs b/src/device.rs index c830fcb..5d25ad2 100644 --- a/src/device.rs +++ b/src/device.rs @@ -54,8 +54,7 @@ impl Device { })) } - /// Encrypt an event to be sent to this device. - /// (olm encryption). + /// Encrypt a to-device message to be sent to this device, using Olm encryption. /// /// Prior to calling this method you must ensure that an olm session is /// available for the target device. This can be done by calling the From 2b6b3014e3d1c96519f72e0dbe67defeb871ba20 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:31:53 +0100 Subject: [PATCH 04/18] review: improve comment Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- src/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index 5d25ad2..b993d3e 100644 --- a/src/device.rs +++ b/src/device.rs @@ -57,7 +57,7 @@ impl Device { /// Encrypt a to-device message to be sent to this device, using Olm encryption. /// /// Prior to calling this method you must ensure that an olm session is - /// available for the target device. This can be done by calling the + /// available for the target device. This can be done by calling /// [`get_missing_sessions()`](OlmMachine::get_missing_sessions) /// /// The caller is responsible for sending the encrypted From 6c03c26bd6da74e2440a9be9aa4efb85d04374fd Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:32:13 +0100 Subject: [PATCH 05/18] review: Improve doc Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- src/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index b993d3e..2957b87 100644 --- a/src/device.rs +++ b/src/device.rs @@ -62,7 +62,7 @@ impl Device { /// /// The caller is responsible for sending the encrypted /// event to the target device. If multiple messages are - /// encrypted using this method they should be sent in the same order as + /// encrypted for the same device using this method they should be sent in the same order as /// they are encrypted. /// /// # Returns From 18cd7e36810430da65fe858b6f6be6153dfc0b1d Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:32:50 +0100 Subject: [PATCH 06/18] Review: better test name Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- tests/device.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/device.test.js b/tests/device.test.js index c6506b2..bd9630f 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -146,7 +146,7 @@ describe(OlmMachine.name, () => { }); }); -describe("Send to device", () => { +describe("Send to-device message", () => { const userId1 = new UserId("@alice:example.org"); const deviceId1 = new DeviceId("alice_device"); From 688c41e00e005b341b73d2198d00db4301444d66 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:33:33 +0100 Subject: [PATCH 07/18] Review: better test name Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- tests/device.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/device.test.js b/tests/device.test.js index bd9630f..3d09424 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -157,7 +157,7 @@ describe("Send to-device message", () => { return OlmMachine.initialize(newUser || userId1, newDevice || deviceId1); } - it("can send a to-device message", async () => { + it("can encrypt a to-device message", async () => { // Olm machine. const m = await machine(userId1, deviceId1); From 880411dd13bcc5d253c417eec5e312681cb22418 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 4 Mar 2024 17:36:09 +0100 Subject: [PATCH 08/18] code review --- tests/device.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/device.test.js b/tests/device.test.js index 3d09424..bd22160 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -237,7 +237,7 @@ describe("Send to-device message", () => { }, }, }); - const marked = await m.markRequestAsSent("foo", RequestType.KeysQuery, hypotheticalResponse); + await m.markRequestAsSent("foo", RequestType.KeysQuery, hypotheticalResponse); } { @@ -260,7 +260,7 @@ describe("Send to-device message", () => { }, failures: {}, }); - const marked = await m.markRequestAsSent("bar", RequestType.KeysClaim, hypotheticalResponse); + await m.markRequestAsSent("bar", RequestType.KeysClaim, hypotheticalResponse); } // Pick the device we want to encrypt to. @@ -269,7 +269,7 @@ describe("Send to-device message", () => { const content = { body: "Hello, World!", }; - const type = "some.custon.event.type"; + const type = "some.custom.event.type"; const toDevice = await device2.encryptToDeviceEvent(type, content); From 85de25c9f370c8f0285485306366066a28902294 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 Mar 2024 10:37:00 +0100 Subject: [PATCH 09/18] code review --- src/device.rs | 9 ++++---- tests/device.test.js | 53 +------------------------------------------- 2 files changed, 6 insertions(+), 56 deletions(-) diff --git a/src/device.rs b/src/device.rs index 2957b87..ff93d39 100644 --- a/src/device.rs +++ b/src/device.rs @@ -54,7 +54,8 @@ impl Device { })) } - /// Encrypt a to-device message to be sent to this device, using Olm encryption. + /// Encrypt a to-device message to be sent to this device, using Olm + /// encryption. /// /// Prior to calling this method you must ensure that an olm session is /// available for the target device. This can be done by calling @@ -62,11 +63,11 @@ impl Device { /// /// The caller is responsible for sending the encrypted /// event to the target device. If multiple messages are - /// encrypted for the same device using this method they should be sent in the same order as - /// they are encrypted. + /// encrypted for the same device using this method they should be sent in + /// the same order as they are encrypted. /// /// # Returns - /// Returns a Promise for a `json` string of the encrypted event. + /// Returns a Promise for a js object of the encrypted event. /// Can be used to create the payload for a `/sendToDevice` API. #[wasm_bindgen(js_name = "encryptToDeviceEvent")] pub fn encrypt_to_device_event( diff --git a/tests/device.test.js b/tests/device.test.js index bd22160..52fa11e 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -150,11 +150,8 @@ describe("Send to-device message", () => { const userId1 = new UserId("@alice:example.org"); const deviceId1 = new DeviceId("alice_device"); - const userId2 = new UserId("@bob:example.org"); - const deviceId2 = new DeviceId("bob_device"); - function machine(newUser, newDevice) { - return OlmMachine.initialize(newUser || userId1, newDevice || deviceId1); + return OlmMachine.initialize(newUser, newDevice); } it("can encrypt a to-device message", async () => { @@ -188,54 +185,6 @@ describe("Send to-device message", () => { }, }, failures: {}, - master_keys: { - "@example:localhost": { - user_id: "@example:localhost", - usage: ["master"], - keys: { - "ed25519:n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU": - "n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU", - }, - signatures: { - "@example:localhost": { - "ed25519:TCSJXPWGVS": - "+j9G3L41I1fe0++wwusTTQvbboYW0yDtRWUEujhwZz4MAltjLSfJvY0hxhnz+wHHmuEXvQDen39XOpr1p29sAg", - }, - }, - }, - }, - self_signing_keys: { - "@example:localhost": { - user_id: "@example:localhost", - usage: ["self_signing"], - keys: { - "ed25519:kQXOuy639Yt47mvNTdrIluoC6DMvfbZLYbxAmwiDyhI": - "kQXOuy639Yt47mvNTdrIluoC6DMvfbZLYbxAmwiDyhI", - }, - signatures: { - "@example:localhost": { - "ed25519:n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU": - "q32ifix/qyRpvmegw2BEJklwoBCAJldDNkcX+fp+lBA4Rpyqtycxge6BA4hcJdxYsy3oV0IHRuugS8rJMMFyAA", - }, - }, - }, - }, - user_signing_keys: { - "@example:localhost": { - user_id: "@example:localhost", - usage: ["user_signing"], - keys: { - "ed25519:g4ED07Fnqf3GzVWNN1pZ0IFrPQVdqQf+PYoJNH4eE0s": - "g4ED07Fnqf3GzVWNN1pZ0IFrPQVdqQf+PYoJNH4eE0s", - }, - signatures: { - "@example:localhost": { - "ed25519:n2lpJGx0LiKnuNE1IucZP3QExrD4SeRP0veBHPe3XUU": - "nKQu8alQKDefNbZz9luYPcNj+Z+ouQSot4fU/A23ELl1xrI06QVBku/SmDx0sIW1ytso0Cqwy1a+3PzCa1XABg", - }, - }, - }, - }, }); await m.markRequestAsSent("foo", RequestType.KeysQuery, hypotheticalResponse); } From 1ad2eeabb8064028fe98bd968be52119cfe343bc Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 Mar 2024 10:37:37 +0100 Subject: [PATCH 10/18] encrypt_to_device_event: return a plain js object direclty --- src/device.rs | 6 +++++- tests/device.test.js | 7 +++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/device.rs b/src/device.rs index ff93d39..a1b7458 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,7 +1,9 @@ //! Types for a `Device`. use js_sys::{Array, Map, Promise}; +use serde::Serialize; use serde_json::Value; +use serde_wasm_bindgen::Serializer; use wasm_bindgen::prelude::*; use crate::{ @@ -82,7 +84,9 @@ impl Device { Ok(future_to_promise(async move { let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; - Ok(raw_encrypted.into_json().to_string()) + let to_device_encrypted = raw_encrypted.deserialize()?; + // Using json_compatible() to convert into plain object instead of Map. + Ok(to_device_encrypted.serialize(&Serializer::json_compatible()).unwrap()) })) } diff --git a/tests/device.test.js b/tests/device.test.js index 52fa11e..47184f7 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -222,10 +222,9 @@ describe("Send to-device message", () => { const toDevice = await device2.encryptToDeviceEvent(type, content); - const olmContent = JSON.parse(toDevice); - expect(olmContent.algorithm).toStrictEqual("m.olm.v1.curve25519-aes-sha2"); - expect(olmContent.ciphertext).toBeDefined(); - expect(olmContent.ciphertext["boYjDpaC+7NkECQEeMh5dC+I1+AfriX0VXG2UV7EUQo"]).toBeDefined(); + expect(toDevice.algorithm).toStrictEqual("m.olm.v1.curve25519-aes-sha2"); + expect(toDevice.ciphertext).toBeDefined(); + expect(toDevice.ciphertext["boYjDpaC+7NkECQEeMh5dC+I1+AfriX0VXG2UV7EUQo"]).toBeDefined(); }); }); From 35e703eac49bb4b2fc09a38173d7e4f5d89da3c6 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 Mar 2024 10:42:35 +0100 Subject: [PATCH 11/18] review: use proper doc link --- src/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index a1b7458..08792c0 100644 --- a/src/device.rs +++ b/src/device.rs @@ -61,7 +61,7 @@ impl Device { /// /// Prior to calling this method you must ensure that an olm session is /// available for the target device. This can be done by calling - /// [`get_missing_sessions()`](OlmMachine::get_missing_sessions) + /// {@link OlmMachine.getMissingSessions}. /// /// The caller is responsible for sending the encrypted /// event to the target device. If multiple messages are From 8665c4bd9ba64d74f091cbcd396c5aacd3b39d72 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 Mar 2024 10:47:22 +0100 Subject: [PATCH 12/18] review: test cleaning --- tests/device.test.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/device.test.js b/tests/device.test.js index 47184f7..97fb03b 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -159,9 +159,10 @@ describe("Send to-device message", () => { const m = await machine(userId1, deviceId1); // Make m aware of another device, and get some OTK to be able to establish a session. - { - // derived from https://github.com/matrix-org/matrix-rust-sdk/blob/7f49618d350fab66b7e1dc4eaf64ec25ceafd658/benchmarks/benches/crypto_bench/keys_query.json - const hypotheticalResponse = JSON.stringify({ + await m.markRequestAsSent( + "foo", + RequestType.KeysQuery, + JSON.stringify({ device_keys: { "@example:localhost": { AFGUOBTZWM: { @@ -185,13 +186,13 @@ describe("Send to-device message", () => { }, }, failures: {}, - }); - await m.markRequestAsSent("foo", RequestType.KeysQuery, hypotheticalResponse); - } + }), + ); - { - // derived from https://github.com/matrix-org/matrix-rust-sdk/blob/7f49618d350fab66b7e1dc4eaf64ec25ceafd658/benchmarks/benches/crypto_bench/keys_claim.json - const hypotheticalResponse = JSON.stringify({ + await m.markRequestAsSent( + "bar", + RequestType.KeysClaim, + JSON.stringify({ one_time_keys: { "@example:localhost": { AFGUOBTZWM: { @@ -208,9 +209,8 @@ describe("Send to-device message", () => { }, }, failures: {}, - }); - await m.markRequestAsSent("bar", RequestType.KeysClaim, hypotheticalResponse); - } + }), + ); // Pick the device we want to encrypt to. const device2 = await m.getDevice(new UserId("@example:localhost"), new DeviceId("AFGUOBTZWM")); From 45bdcfb201af20474884a6705190f46f18448474 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 22 Aug 2024 20:38:09 +0100 Subject: [PATCH 13/18] Apply suggestions from code review Co-authored-by: Ivan Enderlin --- src/device.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/device.rs b/src/device.rs index 08792c0..48c3b1f 100644 --- a/src/device.rs +++ b/src/device.rs @@ -11,7 +11,7 @@ use crate::{ future::future_to_promise, identifiers::{self, DeviceId, UserId}, impl_from_to_inner, - requests::{self}, + requests, types, verification, vodozemac, }; @@ -59,7 +59,7 @@ impl Device { /// Encrypt a to-device message to be sent to this device, using Olm /// encryption. /// - /// Prior to calling this method you must ensure that an olm session is + /// Prior to calling this method you must ensure that an Olm session is /// available for the target device. This can be done by calling /// {@link OlmMachine.getMissingSessions}. /// @@ -69,7 +69,7 @@ impl Device { /// the same order as they are encrypted. /// /// # Returns - /// Returns a Promise for a js object of the encrypted event. + /// Returns a Promise for a JS object of the encrypted event. /// Can be used to create the payload for a `/sendToDevice` API. #[wasm_bindgen(js_name = "encryptToDeviceEvent")] pub fn encrypt_to_device_event( @@ -79,7 +79,6 @@ impl Device { ) -> Result { let me = self.inner.clone(); let content: Value = serde_wasm_bindgen::from_value(content)?; - let event_type = event_type.clone(); Ok(future_to_promise(async move { let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; From 695694142a706b73431e156b1cef11d1752aa9c1 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 22 Aug 2024 21:15:49 +0100 Subject: [PATCH 14/18] Return JSON instead of an object There's not a lot of point jumping through hoops to turn the json-serialized content back into an object in the Rust layer. Might as well leave it for javascript. --- src/device.rs | 12 ++++-------- tests/device.test.js | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/device.rs b/src/device.rs index 076f7dc..c1f8f98 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,9 +1,7 @@ //! Types for a `Device`. use js_sys::{Array, Map, Promise}; -use serde::Serialize; use serde_json::Value; -use serde_wasm_bindgen::Serializer; use wasm_bindgen::prelude::*; use crate::{ @@ -66,8 +64,9 @@ impl Device { /// the same order as they are encrypted. /// /// # Returns - /// Returns a Promise for a JS object of the encrypted event. - /// Can be used to create the payload for a `/sendToDevice` API. + /// + /// Returns a promise for a JSON string containing the `content` of an encrypted event, + /// which be used to create the payload for a `/sendToDevice` API. #[wasm_bindgen(js_name = "encryptToDeviceEvent")] pub fn encrypt_to_device_event( &self, @@ -79,10 +78,7 @@ impl Device { Ok(future_to_promise(async move { let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; - - let to_device_encrypted = raw_encrypted.deserialize()?; - // Using json_compatible() to convert into plain object instead of Map. - Ok(to_device_encrypted.serialize(&Serializer::json_compatible()).unwrap()) + Ok(raw_encrypted.into_json().get().to_owned()) })) } diff --git a/tests/device.test.js b/tests/device.test.js index 584ba47..7dbf43e 100644 --- a/tests/device.test.js +++ b/tests/device.test.js @@ -220,7 +220,7 @@ describe("Send to-device message", () => { }; const type = "some.custom.event.type"; - const toDevice = await device2.encryptToDeviceEvent(type, content); + const toDevice = JSON.parse(await device2.encryptToDeviceEvent(type, content)); expect(toDevice.algorithm).toStrictEqual("m.olm.v1.curve25519-aes-sha2"); expect(toDevice.ciphertext).toBeDefined(); From 88f0cc8e0ccaf236e243d4ff9454de1dde9eea2f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 22 Aug 2024 21:25:01 +0100 Subject: [PATCH 15/18] simplify implementation --- src/device.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/device.rs b/src/device.rs index c1f8f98..6b9ab13 100644 --- a/src/device.rs +++ b/src/device.rs @@ -68,18 +68,16 @@ impl Device { /// Returns a promise for a JSON string containing the `content` of an encrypted event, /// which be used to create the payload for a `/sendToDevice` API. #[wasm_bindgen(js_name = "encryptToDeviceEvent")] - pub fn encrypt_to_device_event( + pub async fn encrypt_to_device_event( &self, event_type: String, content: JsValue, - ) -> Result { + ) -> Result { let me = self.inner.clone(); let content: Value = serde_wasm_bindgen::from_value(content)?; - Ok(future_to_promise(async move { - let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; - Ok(raw_encrypted.into_json().get().to_owned()) - })) + let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; + Ok(raw_encrypted.into_json().get().to_owned()) } /// Is this device considered to be verified. From ae3c197a4540716e57f1f7d3763aa25ef876d35c Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 22 Aug 2024 21:26:20 +0100 Subject: [PATCH 16/18] lint --- src/device.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/device.rs b/src/device.rs index 6b9ab13..16bee0d 100644 --- a/src/device.rs +++ b/src/device.rs @@ -8,9 +8,7 @@ use crate::{ encryption::EncryptionAlgorithm, future::future_to_promise, identifiers::{self, DeviceId, UserId}, - impl_from_to_inner, - requests, - types, verification, vodozemac, + impl_from_to_inner, requests, types, verification, vodozemac, }; /// A device represents a E2EE capable client of an user. @@ -65,8 +63,9 @@ impl Device { /// /// # Returns /// - /// Returns a promise for a JSON string containing the `content` of an encrypted event, - /// which be used to create the payload for a `/sendToDevice` API. + /// Returns a promise for a JSON string containing the `content` of an + /// encrypted event, which be used to create the payload for a + /// `/sendToDevice` API. #[wasm_bindgen(js_name = "encryptToDeviceEvent")] pub async fn encrypt_to_device_event( &self, From f10d768a164c9216ea70b906985fb3b38a43fb63 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 22 Aug 2024 21:36:30 +0100 Subject: [PATCH 17/18] comment --- src/device.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device.rs b/src/device.rs index 16bee0d..c0dfac2 100644 --- a/src/device.rs +++ b/src/device.rs @@ -73,6 +73,8 @@ impl Device { content: JsValue, ) -> Result { let me = self.inner.clone(); + + // JSON-serialize the payload let content: Value = serde_wasm_bindgen::from_value(content)?; let raw_encrypted = me.encrypt_event_raw(event_type.as_str(), &content).await?; From aa1edefe6842c91035cb780a3f05c996b767f15d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 22 Aug 2024 21:38:38 +0100 Subject: [PATCH 18/18] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3014670..daae636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ **Other changes** -- Add a new API `Device#encryptToDeviceEvent` to encrypt a to-device message using +- Add a new API `Device.encryptToDeviceEvent` to encrypt a to-device message using Olm. ([#101](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/101))