diff --git a/crates/matrix-sdk-crypto-nodejs/Cargo.toml b/crates/matrix-sdk-crypto-nodejs/Cargo.toml index a21878de1..b8b6a94ce 100644 --- a/crates/matrix-sdk-crypto-nodejs/Cargo.toml +++ b/crates/matrix-sdk-crypto-nodejs/Cargo.toml @@ -26,8 +26,8 @@ docsrs = [] [dependencies] matrix-sdk-crypto = { version = "0.5.0", path = "../matrix-sdk-crypto" } ruma = { version = "0.6.2", features = ["client-api-c", "rand", "unstable-msc2676", "unstable-msc2677"] } -vodozemac = "0.2.0" -napi = { git = "https://github.com/Hywan/napi-rs", branch = "feat-tonapivalue-u16", default-features = false, features = ["napi4"] } +vodozemac = { git = "https://github.com/matrix-org/vodozemac/", rev = "d0e744287a14319c2a9148fef3747548c740fc36" } +napi = { git = "https://github.com/Hywan/napi-rs", branch = "feat-tonapivalue-u16", default-features = false, features = ["napi4", "tokio_rt"] } napi-derive = "2.4.1" [build-dependencies] diff --git a/crates/matrix-sdk-crypto-nodejs/src/identifiers.rs b/crates/matrix-sdk-crypto-nodejs/src/identifiers.rs index 2a1f9bf8e..47c8ec448 100644 --- a/crates/matrix-sdk-crypto-nodejs/src/identifiers.rs +++ b/crates/matrix-sdk-crypto-nodejs/src/identifiers.rs @@ -14,16 +14,22 @@ pub struct UserId { pub(crate) inner: ruma::OwnedUserId, } +impl UserId { + pub(crate) fn new_with(inner: ruma::OwnedUserId) -> Self { + Self { inner } + } +} + #[napi] impl UserId { /// Parse/validate and create a new `UserId`. #[napi(constructor)] pub fn new(id: String) -> Result { - Ok(Self { - inner: ruma::UserId::parse(id.as_str()) + Ok(Self::new_with( + ruma::UserId::parse(id.as_str()) .map_err(Error::from) .map_err(Into::::into)?, - }) + )) } /// Returns the user's localpart. @@ -66,12 +72,18 @@ pub struct DeviceId { pub(crate) inner: ruma::OwnedDeviceId, } +impl DeviceId { + pub(crate) fn new_with(inner: ruma::OwnedDeviceId) -> Self { + Self { inner } + } +} + #[napi] impl DeviceId { /// Create a new `DeviceId`. #[napi(constructor)] pub fn new(id: String) -> DeviceId { - Self { inner: id.into() } + Self::new_with(id.into()) } /// Return the device ID as a string. @@ -91,16 +103,20 @@ pub struct RoomId { pub(crate) inner: ruma::OwnedRoomId, } +impl RoomId { + pub(crate) fn new_with(inner: ruma::OwnedRoomId) -> Self { + Self { inner } + } +} + #[napi] impl RoomId { /// Parse/validate and create a new `RoomId`. #[napi(constructor)] pub fn new(id: String) -> Result { - Ok(Self { - inner: ruma::RoomId::parse(id) - .map_err(Error::from) - .map_err(Into::::into)?, - }) + Ok(Self::new_with( + ruma::RoomId::parse(id).map_err(Error::from).map_err(Into::::into)?, + )) } /// Returns the user's localpart. diff --git a/crates/matrix-sdk-crypto-nodejs/src/lib.rs b/crates/matrix-sdk-crypto-nodejs/src/lib.rs index 527863a64..ad3f0a361 100644 --- a/crates/matrix-sdk-crypto-nodejs/src/lib.rs +++ b/crates/matrix-sdk-crypto-nodejs/src/lib.rs @@ -18,11 +18,7 @@ mod errors; pub mod events; -//mod future; pub mod identifiers; -//pub mod machine; -//pub mod requests; -//pub mod responses; -//pub mod sync_events; +pub mod machine; pub use crate::errors::Error; diff --git a/crates/matrix-sdk-crypto-nodejs/src/machine.rs b/crates/matrix-sdk-crypto-nodejs/src/machine.rs new file mode 100644 index 000000000..f541fb6ba --- /dev/null +++ b/crates/matrix-sdk-crypto-nodejs/src/machine.rs @@ -0,0 +1,135 @@ +//! The crypto specific Olm objects. + +use napi_derive::*; + +use crate::identifiers; + +/// State machine implementation of the Olm/Megolm encryption protocol +/// used for Matrix end to end encryption. +#[napi] +pub struct OlmMachine { + inner: matrix_sdk_crypto::OlmMachine, +} + +#[napi] +impl OlmMachine { + // napi doesn't support `#[napi(factory)]` with an `async fn`. So + // we create a normal `async fn` function, and then, we create a + // constructor that raises an error. + + #[napi] + pub async fn initialize( + user_id: &identifiers::UserId, + device_id: &identifiers::DeviceId, + ) -> Self { + let user_id = user_id.inner.clone(); + let device_id = device_id.inner.clone(); + + OlmMachine { + inner: matrix_sdk_crypto::OlmMachine::new(user_id.as_ref(), device_id.as_ref()).await, + } + } + + #[napi(constructor)] + #[allow(clippy::new_ret_no_self)] + pub fn new() -> napi::Error { + napi::Error::from_reason("To build an `OldMachine`, please use the `initialize` method") + } + + #[napi] + #[napi(js_name = "userId")] + pub fn user_id(&self) -> identifiers::UserId { + identifiers::UserId::new_with(self.inner.user_id().to_owned()) + } + + #[napi] + #[napi(js_name = "deviceId")] + pub fn device_id(&self) -> identifiers::DeviceId { + identifiers::DeviceId::new_with(self.inner.device_id().to_owned()) + } + + /* + #[napi] + #[napi(js_name = "identityKeys")] + pub fn identity_keys(&self) -> IdentityKeys { + self.inner.identity_keys().into() + } + */ +} + +/// An Ed25519 public key, used to verify digital signatures. +#[napi] +#[derive(Clone)] +pub struct Ed25519PublicKey { + inner: vodozemac::Ed25519PublicKey, +} + +#[napi] +impl Ed25519PublicKey { + /// The number of bytes an Ed25519 public key has. + #[napi(getter)] + pub fn length(&self) -> u32 { + vodozemac::Ed25519PublicKey::LENGTH as u32 + } + + /// Serialize an Ed25519 public key to an unpadded base64 + /// representation. + #[napi(js_name = "toBase64")] + pub fn to_base64(&self) -> String { + self.inner.to_base64() + } +} + +/// A Curve25519 public key. +#[napi] +#[derive(Clone)] +pub struct Curve25519PublicKey { + inner: vodozemac::Curve25519PublicKey, +} + +#[napi] +impl Curve25519PublicKey { + /// The number of bytes a Curve25519 public key has. + #[napi(getter)] + pub fn length(&self) -> u32 { + vodozemac::Curve25519PublicKey::LENGTH as u32 + } + + /// Serialize an Curve25519 public key to an unpadded base64 + /// representation. + #[napi(js_name = "toBase64")] + pub fn to_base64(&self) -> String { + self.inner.to_base64() + } +} + +#[napi] +pub struct IdentityKeys { + /// The Ed25519 public key, used for signing. + ed25519: Ed25519PublicKey, + + /// The Curve25519 public key, used for establish shared secrets. + curve25519: Curve25519PublicKey, +} + +#[napi] +impl IdentityKeys { + #[napi(getter)] + pub fn ed25519(&self) -> Ed25519PublicKey { + self.ed25519.clone() + } + + #[napi(getter)] + pub fn curve25519(&self) -> Curve25519PublicKey { + self.curve25519.clone() + } +} + +impl From for IdentityKeys { + fn from(value: matrix_sdk_crypto::olm::IdentityKeys) -> Self { + Self { + ed25519: Ed25519PublicKey { inner: value.ed25519 }, + curve25519: Curve25519PublicKey { inner: value.curve25519 }, + } + } +}