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.
This commit is contained in:
Ivan Enderlin
2022-08-23 15:00:33 +02:00
parent 9462061a5a
commit 7f07ac52ef
6 changed files with 57 additions and 7 deletions

5
Cargo.lock generated
View File

@@ -1931,8 +1931,7 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexed_db_futures"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26ac735f676c52305becf53264b91cea9866a8de61ccbf464405b377b9cbca9"
source = "git+https://github.com/Hywan/rust-indexed-db?branch=feat-factory-nodejs#5dab67890cea0ab88b967031adc09179a537d77c"
dependencies = [
"cfg-if",
"js-sys",
@@ -2365,6 +2364,7 @@ dependencies = [
"js-sys",
"matrix-sdk-common",
"matrix-sdk-crypto",
"matrix-sdk-indexeddb",
"ruma",
"serde_json",
"tracing",
@@ -2372,6 +2372,7 @@ dependencies = [
"vodozemac",
"wasm-bindgen",
"wasm-bindgen-futures",
"zeroize",
]
[[package]]

View File

@@ -28,6 +28,7 @@ tracing = []
[dependencies]
matrix-sdk-common = { version = "0.5.0", path = "../../crates/matrix-sdk-common" }
matrix-sdk-crypto = { version = "0.5.0", path = "../../crates/matrix-sdk-crypto" }
matrix-sdk-indexeddb = { version = "0.1.0", path = "../../crates/matrix-sdk-indexeddb" }
ruma = { git = "https://github.com/ruma/ruma", rev = "173eb15147c904d7dc0ee894de6114743926e33e", features = ["client-api-c", "js", "rand", "unstable-msc2676", "unstable-msc2677"] }
wasm-bindgen = "0.2.80"
wasm-bindgen-futures = "0.4.30"
@@ -38,6 +39,7 @@ http = "0.2.6"
anyhow = "1.0.58"
tracing = { version = "0.1.35", default-features = false, features = ["attributes"] }
tracing-subscriber = { version = "0.3.14", default-features = false, features = ["registry", "std"] }
zeroize = "1.3.0"
[dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"

View File

@@ -30,7 +30,8 @@
"jest": "^28.1.0",
"typedoc": "^0.22.17",
"cross-env": "^7.0.3",
"yargs-parser": "~21.0.1"
"yargs-parser": "~21.0.1",
"fake-indexeddb": "^4.0"
},
"engines": {
"node": ">= 10"

View File

@@ -1,11 +1,13 @@
//! The crypto specific Olm objects.
use std::collections::BTreeMap;
use std::sync::Arc;
use js_sys::{Array, Map, Promise, Set};
use ruma::{serde::Raw, DeviceKeyAlgorithm, OwnedTransactionId, UInt};
use serde_json::Value as JsonValue;
use wasm_bindgen::prelude::*;
use zeroize::Zeroize;
use crate::{
downcast, encryption,
@@ -36,14 +38,50 @@ impl OlmMachine {
/// that owns this machine.
#[wasm_bindgen(constructor)]
#[allow(clippy::new_ret_no_self)]
pub fn new(user_id: &identifiers::UserId, device_id: &identifiers::DeviceId) -> Promise {
pub fn new(
user_id: &identifiers::UserId,
device_id: &identifiers::DeviceId,
store_name: Option<String>,
store_passphrase: Option<String>,
) -> Promise {
let user_id = user_id.inner.clone();
let device_id = device_id.inner.clone();
future_to_promise(async move {
let store = match (store_name, store_passphrase) {
(Some(store_name), Some(mut store_passphrase)) => {
let store = Some(
matrix_sdk_indexeddb::IndexeddbCryptoStore::open_with_passphrase(
&store_name,
&store_passphrase,
)
.await
.map(Arc::new)?,
);
store_passphrase.zeroize();
store
}
_ => None,
};
Ok(OlmMachine {
inner: matrix_sdk_crypto::OlmMachine::new(user_id.as_ref(), device_id.as_ref())
.await,
inner: match store {
Some(store) => {
matrix_sdk_crypto::OlmMachine::with_store(
user_id.as_ref(),
device_id.as_ref(),
store,
)
.await?
}
None => {
matrix_sdk_crypto::OlmMachine::new(user_id.as_ref(), device_id.as_ref())
.await
}
},
})
})
}

View File

@@ -1,10 +1,18 @@
const { OlmMachine, UserId, DeviceId, RoomId, DeviceLists, RequestType, KeysUploadRequest, KeysQueryRequest, KeysClaimRequest, EncryptionSettings, DecryptedRoomEvent, VerificationState } = require('../pkg/matrix_sdk_crypto_js');
require('fake-indexeddb/auto');
describe(OlmMachine.name, () => {
test('can be instantiated with the async initializer', async () => {
expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'))).toBeInstanceOf(OlmMachine);
});
test('can be instantiated with a store', async () => {
let store_name = 'hello';
let store_passphrase = 'world';
expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine);
});
const user = new UserId('@alice:example.org');
const device = new DeviceId('foobar');
const room = new RoomId('!baz:matrix.org');

View File

@@ -26,7 +26,7 @@ base64 = "0.13.0"
dashmap = { version = "5.2.0", optional = true }
derive_builder = "0.11.2"
futures-util = { version = " 0.3.21", default-features = false, features = ["alloc"], optional = true }
indexed_db_futures = "0.2.3"
indexed_db_futures = { git = "https://github.com/Hywan/rust-indexed-db", branch = "feat-factory-nodejs" }
js-sys = { version = "0.3.58" }
matrix-sdk-base = { version = "0.5.0", path = "../matrix-sdk-base" }
matrix-sdk-crypto = { version = "0.5.0", path = "../matrix-sdk-crypto", optional = true }