Skip to content

feat(crypto-nodejs) Implement missing APIs #721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8a0e0a7
feat(crypto-nodejs): Start implementing `OlmMachine` API.
Hywan May 30, 2022
e2ecba7
feat(crypto-nodejs): Implement `OlmMachine.update_tracked_users`.
Hywan May 30, 2022
1ecf90b
feat(crypto-nodejs): Implement `OlmMachine.receive_sync_changes`.
Hywan May 30, 2022
7c85fda
doc(crypto-js): Update documentation.
Hywan May 30, 2022
2e22f6b
feat(crypto-nodejs): Implement `OlmMachine.outgoing_requests`.
Hywan May 31, 2022
8d909cc
feat(crypto-nodejs): Implement `OlmMachine.mark_request_as_sent`.
Hywan May 31, 2022
02e63ab
chore(crypto-js): Remove a useless import.
Hywan May 31, 2022
a7697fb
feat(crypto-nodejs): Implement `OlmMachine.get_missing_sessions`.
Hywan May 31, 2022
a8b44f2
feat(crypto-nodejs): Implement `OlmMachine.share_room_key`.
Hywan May 31, 2022
475fffb
feat(crypto-nodejs): Implement `OlmMachine.encrypt_room_event`.
Hywan May 31, 2022
888ffb0
chore(crypto-node): Use `Either5` + `Either3` instead of `Either`.
Hywan May 31, 2022
5d4b3a0
feat(crypto-nodejs): Implement `OlmMachine.decrypt_room_event`.
Hywan May 31, 2022
dc7f038
chore(crypto-node): Document and add `napi(getter)` when necessary.
Hywan May 31, 2022
7bb96e0
chore(crypto-node): Use `Either7` (new pending feature).
Hywan Jun 1, 2022
6a996c7
doc(crypto-nodejs): Write missing documentation and clean up the code.
Hywan Jun 2, 2022
c573985
chore(crypto-nodejs): Add a `.gitignore` for artifacts.
Hywan Jun 2, 2022
8e120eb
doc(crypto-nodejs): Write missing documentation.
Hywan Jun 2, 2022
6d10d61
test(crypto-nodejs): Add some test suites.
Hywan Jun 2, 2022
1a6adc6
chore(crypto-nodejs): Ignore `package-lock.json` for now.
Hywan Jun 2, 2022
02802e9
feat(crypto-nodejs): `EncryptionSettings.rotation_period` and `.…_per…
Hywan Jun 2, 2022
0d66480
fix(crypto-nodejs): `OlmMachine.new` effectively raises an error.
Hywan Jun 2, 2022
9ebc61a
test(crypto-nodejs): Adding more test suites.
Hywan Jun 2, 2022
a75ae16
test(crypto-nodejs): Add more test suites.
Hywan Jun 2, 2022
407e27d
feat(crypto-nodejs): Make `changed` and `left` optional in `DeviceLis…
Hywan Jun 6, 2022
35d7cab
feat(crypto-nodejs): Rename requests `request_id` to `id` + add `type`.
Hywan Jun 6, 2022
0ed74d8
test(crypto-nodejs): Test `OlmMachine.receiveSyncChanges`, `.outgoing…
Hywan Jun 6, 2022
07fed7f
test(crypto-nodejs): Continue to test `OlmMachine` and add tracing su…
Hywan Jun 6, 2022
12c53bb
test(crypto-nodejs): Add more test cases.
Hywan Jun 7, 2022
520758b
test(crypto-nodejs): Finish the `OlmMachine` test suite.
Hywan Jun 7, 2022
1e7d509
chore(crypto-nodejs): Clean up.
Hywan Jun 7, 2022
ec7724f
doc(crypto-nodejs): Improve the `README.md`.
Hywan Jun 7, 2022
15af364
Merge branch 'main' into feat-crypto-nodejs-next
Hywan Jun 7, 2022
2a76d17
doc(crypto-nodejs): Generate JavaScript/TypeScript documentation.
Hywan Jun 7, 2022
99dcf84
chore(crypto-nodejs): Use `napi::Result` when possible.
Hywan Jun 7, 2022
530c268
doc(crypto-nodejs): Include the `README.md` in the generated document…
Hywan Jun 7, 2022
8c95b1c
chore(crypto-nodejs): Fix a typo.
Hywan Jun 7, 2022
75571c2
fix(crypto-js): Fix missing symbol.
Hywan Jun 7, 2022
0762045
chore(crypto-node): Make Clippy happy.
Hywan Jun 7, 2022
6d8c54d
chore(crypto-nodejs): Add missing newline.
Hywan Jun 7, 2022
1b2c644
test(crypto-nodejs): Set up CI to run the test suites.
Hywan Jun 9, 2022
506f57a
feat(crypto-nodejs): Enable traace filtering and change the env var t…
Hywan Jun 9, 2022
8a332ca
chore(crypto-nodejs): Implement feedbacks / polish.
Hywan Jun 9, 2022
fe4ddfd
chore(crypto-nodejs): Remove `clone` calls when possible.
Hywan Jun 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,48 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test

test-nodejs:
name: linux / node.js (${{ matrix.node-version }})
if: github.event_name == 'push' || !github.event.pull_request.draft

runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
node-version: [12.17, 14.0, 15.0, 16.0]
include:
- node-version: 16.0
build-doc: true

steps:
- name: Checkout the repo
uses: actions/checkout@v2

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true

- name: Load cache
uses: Swatinem/rust-cache@v1

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Install NPM dependencies
run: cd crates/matrix-sdk-crypto-nodejs && npm install

- name: Build the Node.js binding
run: cd crates/matrix-sdk-crypto-nodejs && npm run build

- name: Test the Node.js binding
run: cd crates/matrix-sdk-crypto-nodejs && npm run test

- if: ${{ matrix.build-doc }}
name: Build the documentation
run: cd crates/matrix-sdk-crypto-nodejs && npm run doc
5 changes: 1 addition & 4 deletions crates/matrix-sdk-crypto-js/src/sync_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ pub struct DeviceLists {
impl DeviceLists {
/// Create an empty `DeviceLists`.
///
/// `changed` and `left` must be an array of strings representing
/// a user ID. Ideally, we should pass a `UserId` object instance,
/// but it's a limitation of `wasm-bindgen` (a workaround is
/// possible but it will slow down performance).
/// `changed` and `left` must be an array of `UserId`.
#[wasm_bindgen(constructor)]
pub fn new(changed: Array, left: Array) -> Result<DeviceLists, JsError> {
let mut inner = ruma::api::client::sync::sync_events::v3::DeviceLists::default();
Expand Down
6 changes: 6 additions & 0 deletions crates/matrix-sdk-crypto-nodejs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/node_modules
/package-lock.json
/index.js
/index.d.ts
/matrix-sdk-crypto.*.node
/docs/*
13 changes: 9 additions & 4 deletions crates/matrix-sdk-crypto-nodejs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@ crate-type = ["cdylib"]
default = []
qrcode = ["matrix-sdk-crypto/qrcode"]
docsrs = []
tracing = ["tracing-subscriber"]

[dependencies]
matrix-sdk-crypto = { version = "0.5.0", path = "../matrix-sdk-crypto" }
matrix-sdk-common = { version = "0.5.0", path = "../matrix-sdk-common" }
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"] }
napi-derive = "2.4.1"
vodozemac = { git = "https://github.com/matrix-org/vodozemac/", rev = "d0e744287a14319c2a9148fef3747548c740fc36" }
napi = { git = "https://github.com/Hywan/napi-rs", branch = "feat-either-n-up-to-26", default-features = false, features = ["napi6", "tokio_rt"] }
napi-derive = { git = "https://github.com/Hywan/napi-rs", branch = "feat-either-n-up-to-26" }
serde_json = "1.0.79"
http = "0.2.6"
tracing-subscriber = { version = "0.3", default-features = false, features = ["tracing-log", "time", "smallvec", "fmt", "env-filter"], optional = true }

[build-dependencies]
napi-build = "2.0.0"
napi-build = "2.0.0"
130 changes: 130 additions & 0 deletions crates/matrix-sdk-crypto-nodejs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# `matrix-sdk-crypto-nodejs`

Welcome to the [Node.js] binding for the Rust [`matrix-sdk-crypto`]
library! This binding is part of the [`matrix-rust-sdk`] project,
which is a library implementation of a [Matrix] client-server.

`matrix-sdk-crypto-nodejs` is a no-network-IO implementation of a
state machine, named `OlmMachine`, that handles E2EE ([End-to-End
Encryption](https://en.wikipedia.org/wiki/End-to-end_encryption)) for
[Matrix] clients.

## Usage

This Node.js binding is written in [Rust]. To build this binding, you
need to install the Rust compiler, see [the Install Rust
Page](https://www.rust-lang.org/tools/install). Then, the workflow is
pretty classical by using [npm], see [the Downloading and installing
Node.js and npm
Page](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).

The binding is using NAPI 6 (Node API version 6), which means that is
compatible with Node.js versions 12.17.0, 14.0.0, 15.0.0 and 16.0.0
(see [the full Node API version
matrix](https://nodejs.org/api/n-api.html#node-api-version-matrix))
(we do not support the version 10.20).

Once the Rust compiler, Node.js and npm are installed, you can run the
following commands:

```sh
$ npm install
$ npm run build
$ npm run test
```

An `index.js`, `index.d.ts` and a `*.node` files should be
generated. At the same level of those files, you can edit a file and
try this:

```javascript
const { OlmMachine } = require('./index.js');

// Let's see what we can do.
```

The `OlmMachine` state machine works in a push/pull manner:

* You push state changes and events retrieved from a Matrix homeserver
`/sync` response, into the state machine,

* You pull requests that you will need to send back to the homeserver
out of the state machine.

```javascript
const { OlmMachine, UserId, DeviceId, RoomId, DeviceLists } = require('./index.js');

async function main() {
// Define a user ID.
const alice = new UserId('@alice:example.org');

// Define a device ID.
const device = new DeviceId('DEVICEID');

// Let's create the `OlmMachine` state machine.
const machine = await OlmMachine.initialize(alice, device);

// Let's pretend we have received changes and events from a
// `/sync` endpoint of a Matrix homeserver, …
const toDeviceEvents = "{}"; // JSON-encoded
const changedDevices = new DeviceLists();
const oneTimeKeyCounts = {};
const unusedFallbackKeys = [];

// … and push them into the state machine.
const decryptedToDevice = await machine.receiveSyncChanges(
toDeviceEvents,
changedDevices,
oneTimeKeyCounts,
unusedFallbackKeys,
);

// Now, let's pull requests that we need to send out to the Matrix
// homeserver.
const outgoingRequests = await machine.outgoingRequests();

// To complete the workflow, send the requests here out and call
// `machine.markRequestAsSent`.
}

main();
```

### With tracing (experimental)

If you want to enable [tracing](https://tracing.rs), i.e. to get the
logs, you should re-compile the extension with the `tracing` feature
turned on:

```sh
$ npm run build -- --features tracing
```

Now, you can use the `MATRIX_LOG` environment variable to tweak the log filtering, such as:

```sh
$ MATRIX_LOG=debug npm run test
```

See
[`tracing-subscriber`](https://tracing.rs/tracing_subscriber/index.html)
to learn more about the `RUST_LOG`/`MATRIX_LOG` environment variable.

## Documentation

To generate the documentation, please run the following command:

```sh
$ npm run doc
```

The documentation is generated in the `./docs` directory.



[Node.js]: https://nodejs.org/
[`matrix-sdk-crypto`]: https://github.com/matrix-org/matrix-rust-sdk/tree/main/crates/matrix-sdk-crypto
[`matrix-rust-sdk`]: https://github.com/matrix-org/matrix-rust-sdk
[Matrix]: https://matrix.org/
[Rust]: https://www.rust-lang.org/
[npm]: https://www.npmjs.com/
9 changes: 0 additions & 9 deletions crates/matrix-sdk-crypto-nodejs/nodejs/Makefile

This file was deleted.

47 changes: 24 additions & 23 deletions crates/matrix-sdk-crypto-nodejs/package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
{
"name": "matrix-sdk-crypto",
"version": "0.5.0",
"main": "index.js",
"types": "index.d.ts",
"napi": {
"name": "matrix-sdk-crypto",
"triples": {
"additional": [
"aarch64-apple-darwin"
]
"version": "0.5.0",
"main": "index.js",
"types": "index.d.ts",
"napi": {
"name": "matrix-sdk-crypto",
"triples": {
"additional": [
"aarch64-apple-darwin"
]
}
},
"license": "MIT",
"devDependencies": {
"@napi-rs/cli": "^2.9.0",
"jest": "^28.1.0",
"typedoc": "^0.22.17"
},
"engines": {
"node": ">= 10"
},
"scripts": {
"build": "napi build --platform --release --strip",
"test": "jest --verbose",
"doc": "typedoc --tsconfig ."
}
},
"license": "MIT",
"devDependencies": {
"@napi-rs/cli": "^2.9.0",
"ava": "^4.2.0"
},
"engines": {
"node": ">= 10"
},
"scripts": {
"artifacts": "napi artifacts",
"build": "napi build --platform --release",
"test": "ava"
}
}
Loading