1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-29 16:43:09 +03:00

Support Olm with WebAssembly

wasm Olm has a new interface: it now has an init method that needs
to be called and the promise it returns waited on before the Olm
module is used. Support that, and allow Crypto etc to be imported
whether Olm is enabled or not. Change whether olm is enabled to
be async since now it will be unavailable if the async module init
fails. Don't call getOlmVersion() until the Olm.init() is done.
This commit is contained in:
David Baker
2018-09-25 17:49:54 +01:00
parent 184c3dce15
commit c556ca40b1
5 changed files with 40 additions and 41 deletions

View File

@@ -1,20 +1,23 @@
"use strict";
import 'source-map-support/register';
import Crypto from '../../lib/crypto';
import expect from 'expect';
const sdk = require("../..");
let Crypto;
if (sdk.CRYPTO_ENABLED) {
Crypto = require("../../lib/crypto");
}
import expect from 'expect';
describe("Crypto", function() {
if (!sdk.CRYPTO_ENABLED) {
return;
}
beforeEach(function(done) {
Olm.init().then(done);
});
it("Crypto exposes the correct olm library version", function() {
console.log(Crypto);
expect(Crypto.getOlmVersion()[0]).toEqual(2);
});
});

View File

@@ -13,14 +13,8 @@ import WebStorageSessionStore from '../../../../lib/store/session/webstorage';
import MemoryCryptoStore from '../../../../lib/crypto/store/memory-crypto-store.js';
import MockStorageApi from '../../../MockStorageApi';
import testUtils from '../../../test-utils';
// Crypto and OlmDevice won't import unless we have global.Olm
let OlmDevice;
let Crypto;
if (global.Olm) {
OlmDevice = require('../../../../lib/crypto/OlmDevice');
Crypto = require('../../../../lib/crypto');
}
import OlmDevice from '../../../../lib/crypto/OlmDevice';
import Crypto from '../../../../lib/crypto';
const MatrixEvent = sdk.MatrixEvent;
const MegolmDecryption = algorithms.DECRYPTION_CLASSES['m.megolm.v1.aes-sha2'];
@@ -69,7 +63,8 @@ describe("MegolmDecryption", function() {
describe('receives some keys:', function() {
let groupSession;
beforeEach(function() {
beforeEach(async function() {
await Olm.init();
groupSession = new global.Olm.OutboundGroupSession();
groupSession.create();
@@ -98,7 +93,7 @@ describe("MegolmDecryption", function() {
},
};
return event.attemptDecryption(mockCrypto).then(() => {
await event.attemptDecryption(mockCrypto).then(() => {
megolmDecryption.onRoomKeyEvent(event);
});
});

View File

@@ -45,6 +45,8 @@ const ContentHelpers = require("./content-helpers");
import ReEmitter from './ReEmitter';
import RoomList from './crypto/RoomList';
import Crypto from './crypto';
import { isCryptoAvailable } from './crypto';
const LAZY_LOADING_MESSAGES_FILTER = {
lazy_load_members: true,
@@ -58,14 +60,7 @@ const LAZY_LOADING_SYNC_FILTER = {
const SCROLLBACK_DELAY_MS = 3000;
let CRYPTO_ENABLED = false;
try {
var Crypto = require("./crypto");
CRYPTO_ENABLED = true;
} catch (e) {
console.warn("Unable to load crypto module: crypto will be disabled: " + e);
}
let CRYPTO_ENABLED = isCryptoAvailable();
/**
* Construct a Matrix Client. Only directly construct this if you want to use
@@ -140,6 +135,8 @@ function MatrixClient(opts) {
MatrixBaseApis.call(this, opts);
this.olmVersion = null; // Populated after initCrypto is done
this.reEmitter = new ReEmitter(this);
this.store = opts.store || new StubStore();
@@ -192,10 +189,6 @@ function MatrixClient(opts) {
this._forceTURN = opts.forceTURN || false;
if (CRYPTO_ENABLED) {
this.olmVersion = Crypto.getOlmVersion();
}
// List of which rooms have encryption enabled: separate from crypto because
// we still want to know which rooms are encrypted even if crypto is disabled:
// we don't want to start sending unencrypted events to them.
@@ -385,6 +378,14 @@ MatrixClient.prototype.setNotifTimelineSet = function(notifTimelineSet) {
* successfully initialised.
*/
MatrixClient.prototype.initCrypto = async function() {
if (!isCryptoAvailable()) {
throw new Error(
`End-to-end encryption not supported in this js-sdk build: did ` +
`you remember to load the olm library?`,
);
return;
}
if (this._crypto) {
console.warn("Attempt to re-initialise e2e encryption on MatrixClient");
return;
@@ -402,13 +403,6 @@ MatrixClient.prototype.initCrypto = async function() {
// initialise the list of encrypted rooms (whether or not crypto is enabled)
await this._roomList.init();
if (!CRYPTO_ENABLED) {
throw new Error(
`End-to-end encryption not supported in this js-sdk build: did ` +
`you remember to load the olm library?`,
);
}
const userId = this.getUserId();
if (userId === null) {
throw new Error(
@@ -440,6 +434,9 @@ MatrixClient.prototype.initCrypto = async function() {
await crypto.init();
this.olmVersion = Crypto.getOlmVersion();
// if crypto initialisation was successful, tell it to attach its event
// handlers.
crypto.registerEventHandlers(this);

View File

@@ -23,9 +23,6 @@ import IndexedDBCryptoStore from './store/indexeddb-crypto-store';
* @module crypto/OlmDevice
*/
const Olm = global.Olm;
if (!Olm) {
throw new Error("global.Olm is not defined");
}
// The maximum size of an event is 65K, and we base64 the content, so this is a

View File

@@ -36,6 +36,12 @@ const DeviceList = require('./DeviceList').default;
import OutgoingRoomKeyRequestManager from './OutgoingRoomKeyRequestManager';
import IndexedDBCryptoStore from './store/indexeddb-crypto-store';
const Olm = global.Olm;
export function isCryptoAvailable() {
return Boolean(Olm);
}
/**
* Cryptography bits
*
@@ -62,7 +68,7 @@ import IndexedDBCryptoStore from './store/indexeddb-crypto-store';
*
* @param {RoomList} roomList An initialised RoomList object
*/
function Crypto(baseApis, sessionStore, userId, deviceId,
export default function Crypto(baseApis, sessionStore, userId, deviceId,
clientStore, cryptoStore, roomList) {
this._baseApis = baseApis;
this._sessionStore = sessionStore;
@@ -124,6 +130,10 @@ utils.inherits(Crypto, EventEmitter);
* Returns a promise which resolves once the crypto module is ready for use.
*/
Crypto.prototype.init = async function() {
// Olm is just an object with a .then, not a fully-fledged promise, so
// pass it into bluebird to make it a proper promise.
await Olm.init();
const sessionStoreHasAccount = Boolean(this._sessionStore.getEndToEndAccount());
let cryptoStoreHasAccount;
await this._cryptoStore.doTxn(
@@ -1518,6 +1528,3 @@ class IncomingRoomKeyRequestCancellation {
* @event module:client~MatrixClient#"crypto.warning"
* @param {string} type One of the strings listed above
*/
/** */
module.exports = Crypto;