Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76c675cd09 | |||
| 85a4a594c5 | |||
| f70746c50f | |||
| ae85c209ab | |||
| 2306caa62f | |||
| 3222b11346 | |||
| fc9d6a6d47 | |||
| b233ab87bb | |||
| 73c3a709de | |||
| 6ce7b30b72 | |||
| 980d55a2f3 | |||
| 988be62804 | |||
| 23efd0850d | |||
| c6ea976d7f | |||
| 5f24915300 | |||
| fbe174fb64 | |||
| 977d5331c0 | |||
| d40d7e18f5 | |||
| 11be68ad49 | |||
| b0d0782a72 | |||
| dbb6d8ac71 | |||
| 2774bd238b | |||
| fed67192bc | |||
| 16db970558 | |||
| c9a79bf32e | |||
| eafba9c7ef | |||
| 610923af89 | |||
| 23dfeb13df | |||
| f4abd7d027 | |||
| b716e71784 | |||
| 094598196a | |||
| db1d1c49a0 | |||
| ff4125c11e | |||
| a0d51803ed | |||
| 3aabd63975 | |||
| 394e37f9ea | |||
| 369b88d6f8 | |||
| ec8b3ae515 | |||
| c94382b46c | |||
| e89879d8a6 | |||
| 62b2c07be2 | |||
| 2fb29ae8fd | |||
| b57e858ad1 | |||
| 054aac17aa | |||
| 68b65dd357 | |||
| f2881126cd | |||
| 11968a5888 | |||
| ad279dc566 | |||
| 604af1ac8c | |||
| 68c6393eb2 | |||
| 4cbf9c7f47 | |||
| 8bb3b75b1d | |||
| a76f0c7cb4 | |||
| 01e31afcbd | |||
| 64b83b3245 | |||
| e69f7dbc5f | |||
| 4d0f6df89a | |||
| 6b184363a1 | |||
| b519069634 | |||
| 1bd44a7427 | |||
| 568ff5a3f5 | |||
| 88b39f4b67 | |||
| 870e96a1df | |||
| 59070c2af6 | |||
| cec8936728 | |||
| 14071b0d31 | |||
| 57173e4385 | |||
| 997caad985 | |||
| 2b752c0c02 | |||
| 2cccb8b450 | |||
| 0c540ac8de | |||
| 6033b7b886 | |||
| b67f8d1389 | |||
| ae645ad9f0 | |||
| 5b72509dac | |||
| 3ce42a096b | |||
| 8331c2f267 | |||
| b3c9570b0f | |||
| 9d5c877df9 | |||
| a8e2727473 | |||
| 4b9c6e6bd2 | |||
| d29ac088c0 | |||
| 3a316de9ef | |||
| 84b91d4575 | |||
| f5832423f4 | |||
| 73dd07aadf | |||
| 0f39a45734 | |||
| f41060c39a | |||
| bbb8e12bac | |||
| d0e1471c91 | |||
| 47cb97bc60 | |||
| 8d35bea830 | |||
| d8bcc4e3f1 | |||
| 1061026f96 | |||
| e638c49160 | |||
| 5d84db9fb7 | |||
| b9e198c172 | |||
| 5873db7331 | |||
| 35d584c67b | |||
| 9504cbcc4f | |||
| 6790699279 | |||
| fbca7951fc | |||
| 33ad65a105 | |||
| 63cc3fd890 | |||
| c556ca40b1 | |||
| d28f829b1c | |||
| aec7ef6f9c | |||
| 329f09ce0a | |||
| 68c23af5ae | |||
| a54f30c02f |
@@ -1,3 +1,91 @@
|
||||
Changes in [0.14.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.14.1) (2018-11-22)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.14.0...v0.14.1)
|
||||
|
||||
* Warning when crypto DB is too new to use.
|
||||
|
||||
Changes in [0.14.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.14.0) (2018-11-19)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.14.0-rc.1...v0.14.0)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [0.14.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.14.0-rc.1) (2018-11-15)
|
||||
============================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.13.1...v0.14.0-rc.1)
|
||||
|
||||
BREAKING CHANGE
|
||||
----------------
|
||||
|
||||
* js-sdk now uses Olm 3.0. Apps using Olm must update to 3.0 to
|
||||
continue using Olm with the js-sdk. The js-sdk will call Olm's
|
||||
init() method when the client is started.
|
||||
|
||||
All Changes
|
||||
-----------
|
||||
|
||||
* Prevent messages from being sent if other messages have failed to send
|
||||
[\#781](https://github.com/matrix-org/matrix-js-sdk/pull/781)
|
||||
* A unit test for olm
|
||||
[\#777](https://github.com/matrix-org/matrix-js-sdk/pull/777)
|
||||
* Set access_token and user_id after login in with username and password.
|
||||
[\#778](https://github.com/matrix-org/matrix-js-sdk/pull/778)
|
||||
* Add function to get currently joined rooms.
|
||||
[\#779](https://github.com/matrix-org/matrix-js-sdk/pull/779)
|
||||
* Remove the request-only stuff we don't need anymore
|
||||
[\#775](https://github.com/matrix-org/matrix-js-sdk/pull/775)
|
||||
* Manually construct query strings for browser-request instances
|
||||
[\#770](https://github.com/matrix-org/matrix-js-sdk/pull/770)
|
||||
* Fix: correctly check for crypto being present
|
||||
[\#769](https://github.com/matrix-org/matrix-js-sdk/pull/769)
|
||||
* Update babel-eslint to 8.1.1
|
||||
[\#768](https://github.com/matrix-org/matrix-js-sdk/pull/768)
|
||||
* Support `request` in the browser and support supplying servers to try in
|
||||
joinRoom()
|
||||
[\#764](https://github.com/matrix-org/matrix-js-sdk/pull/764)
|
||||
* loglevel should be a normal dependency
|
||||
[\#767](https://github.com/matrix-org/matrix-js-sdk/pull/767)
|
||||
* Stop devicelist when client is stopped
|
||||
[\#766](https://github.com/matrix-org/matrix-js-sdk/pull/766)
|
||||
* Update to WebAssembly-powered Olm
|
||||
[\#743](https://github.com/matrix-org/matrix-js-sdk/pull/743)
|
||||
* Logging lib. Fixes #332
|
||||
[\#763](https://github.com/matrix-org/matrix-js-sdk/pull/763)
|
||||
* Use new stop() method on matrix-mock-request
|
||||
[\#765](https://github.com/matrix-org/matrix-js-sdk/pull/765)
|
||||
|
||||
Changes in [0.13.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.13.1) (2018-11-14)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.13.0...v0.13.1)
|
||||
|
||||
* Add function to get currently joined rooms.
|
||||
[\#779](https://github.com/matrix-org/matrix-js-sdk/pull/779)
|
||||
|
||||
Changes in [0.13.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.13.0) (2018-11-15)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.12.1...v0.13.0)
|
||||
|
||||
BREAKING CHANGE
|
||||
----------------
|
||||
* `MatrixClient::login` now sets client `access_token` and `user_id` following successful login with username and password.
|
||||
|
||||
Changes in [0.12.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.12.1) (2018-10-29)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.12.1-rc.1...v0.12.1)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [0.12.1-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.12.1-rc.1) (2018-10-24)
|
||||
============================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.12.0...v0.12.1-rc.1)
|
||||
|
||||
* Add repository type to package.json to make it valid
|
||||
[\#762](https://github.com/matrix-org/matrix-js-sdk/pull/762)
|
||||
* Add getMediaConfig()
|
||||
[\#761](https://github.com/matrix-org/matrix-js-sdk/pull/761)
|
||||
* add new examples, to be expanded into a post
|
||||
[\#739](https://github.com/matrix-org/matrix-js-sdk/pull/739)
|
||||
|
||||
Changes in [0.12.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.12.0) (2018-10-16)
|
||||
==================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.12.0-rc.1...v0.12.0)
|
||||
|
||||
@@ -30,9 +30,61 @@ In Node.js
|
||||
console.log("Public Rooms: %s", JSON.stringify(data));
|
||||
});
|
||||
```
|
||||
|
||||
See below for how to include libolm to enable end-to-end-encryption. Please check
|
||||
[the Node.js terminal app](examples/node) for a more complex example.
|
||||
|
||||
To start the client:
|
||||
|
||||
```javascript
|
||||
await client.startClient({initialSyncLimit: 10});
|
||||
```
|
||||
|
||||
You can perform a call to `/sync` to get the current state of the client:
|
||||
|
||||
```javascript
|
||||
client.once('sync', function(state, prevState, res) {
|
||||
if(state === 'PREPARED') {
|
||||
console.log("prepared");
|
||||
} else {
|
||||
console.log(state);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
To send a message:
|
||||
|
||||
```javascript
|
||||
var content = {
|
||||
"body": "message text",
|
||||
"msgtype": "m.text"
|
||||
};
|
||||
client.sendEvent("roomId", "m.room.message", content, "", (err, res) => {
|
||||
console.log(err);
|
||||
});
|
||||
```
|
||||
|
||||
To listen for message events:
|
||||
|
||||
```javascript
|
||||
client.on("Room.timeline", function(event, room, toStartOfTimeline) {
|
||||
if (event.getType() !== "m.room.message") {
|
||||
return; // only use messages
|
||||
}
|
||||
console.log(event.event.content.body);
|
||||
});
|
||||
```
|
||||
|
||||
By default, the `matrix-js-sdk` client uses the `MatrixInMemoryStore` to store events as they are received. For example to iterate through the currently stored timeline for a room:
|
||||
|
||||
```javascript
|
||||
Object.keys(client.store.rooms).forEach((roomId) => {
|
||||
client.getRoom(roomId).timeline.forEach(t => {
|
||||
console.log(t.event);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
What does this SDK do?
|
||||
----------------------
|
||||
@@ -267,13 +319,13 @@ To provide the Olm library in a browser application:
|
||||
|
||||
To provide the Olm library in a node.js application:
|
||||
|
||||
* ``npm install https://matrix.org/packages/npm/olm/olm-2.2.2.tgz``
|
||||
* ``npm install https://matrix.org/packages/npm/olm/olm-3.0.0.tgz``
|
||||
(replace the URL with the latest version you want to use from
|
||||
https://matrix.org/packages/npm/olm/)
|
||||
* ``global.Olm = require('olm');`` *before* loading ``matrix-js-sdk``.
|
||||
|
||||
If you want to package Olm as dependency for your node.js application, you
|
||||
can use ``npm install https://matrix.org/packages/npm/olm/olm-2.2.2.tgz
|
||||
can use ``npm install https://matrix.org/packages/npm/olm/olm-3.0.0.tgz
|
||||
--save-optional`` (if your application also works without e2e crypto enabled)
|
||||
or ``--save`` (if it doesn't) to do so.
|
||||
|
||||
|
||||
+13
-1
@@ -1,5 +1,17 @@
|
||||
var matrixcs = require("./lib/matrix");
|
||||
matrixcs.request(require("browser-request"));
|
||||
const request = require('browser-request');
|
||||
const queryString = require('qs');
|
||||
|
||||
matrixcs.request(function(opts, fn) {
|
||||
// We manually fix the query string for browser-request because
|
||||
// it doesn't correctly handle cases like ?via=one&via=two. Instead
|
||||
// we mimic `request`'s query string interface to make it all work
|
||||
// as expected.
|
||||
// browser-request will happily take the constructed string as the
|
||||
// query string without trying to modify it further.
|
||||
opts.qs = queryString.stringify(opts.qs || {}, opts.qsStringifyOptions);
|
||||
return request(opts, fn);
|
||||
});
|
||||
|
||||
// just *accessing* indexedDB throws an exception in firefox with
|
||||
// indexeddb disabled.
|
||||
|
||||
+9
-6
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "matrix-js-sdk",
|
||||
"version": "0.12.0",
|
||||
"version": "0.14.1",
|
||||
"description": "Matrix Client-Server SDK for Javascript",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -21,6 +21,7 @@
|
||||
"prepublish": "npm run clean && npm run build && git rev-parse HEAD > git-revision.txt"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matrix-org/matrix-js-sdk"
|
||||
},
|
||||
"keywords": [
|
||||
@@ -56,15 +57,17 @@
|
||||
"bluebird": "^3.5.0",
|
||||
"browser-request": "^0.3.3",
|
||||
"content-type": "^1.0.2",
|
||||
"request": "^2.53.0"
|
||||
"loglevel": "1.6.1",
|
||||
"qs": "^6.5.2",
|
||||
"request": "^2.88.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.18.0",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-eslint": "^8.1.1",
|
||||
"babel-plugin-transform-async-to-bluebird": "^1.1.1",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"browserify": "^14.0.0",
|
||||
"browserify": "^16.2.3",
|
||||
"browserify-shim": "^3.8.13",
|
||||
"eslint": "^3.13.1",
|
||||
"eslint-config-google": "^0.7.1",
|
||||
@@ -73,14 +76,14 @@
|
||||
"istanbul": "^0.4.5",
|
||||
"jsdoc": "^3.5.5",
|
||||
"lolex": "^1.5.2",
|
||||
"matrix-mock-request": "^1.2.0",
|
||||
"matrix-mock-request": "^1.2.2",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-jenkins-reporter": "^0.4.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"source-map-support": "^0.4.11",
|
||||
"sourceify": "^0.1.0",
|
||||
"uglify-js": "^2.8.26",
|
||||
"watchify": "^3.2.1"
|
||||
"watchify": "^3.11.0"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
|
||||
@@ -102,9 +102,11 @@ TestClient.prototype.start = function() {
|
||||
|
||||
/**
|
||||
* stop the client
|
||||
* @return {Promise} Resolves once the mock http backend has finished all pending flushes
|
||||
*/
|
||||
TestClient.prototype.stop = function() {
|
||||
this.client.stopClient();
|
||||
return this.httpBackend.stop();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,7 +97,7 @@ describe("DeviceList management:", function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
aliceTestClient.stop();
|
||||
return aliceTestClient.stop();
|
||||
});
|
||||
|
||||
it("Alice shouldn't do a second /query for non-e2e-capable devices", function() {
|
||||
|
||||
@@ -410,10 +410,10 @@ describe("MatrixClient crypto", function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
aliTestClient.stop();
|
||||
aliTestClient.httpBackend.verifyNoOutstandingExpectation();
|
||||
bobTestClient.stop();
|
||||
bobTestClient.httpBackend.verifyNoOutstandingExpectation();
|
||||
|
||||
return Promise.all([aliTestClient.stop(), bobTestClient.stop()]);
|
||||
});
|
||||
|
||||
it("Bob uploads device keys", function() {
|
||||
|
||||
@@ -30,6 +30,7 @@ describe("MatrixClient events", function() {
|
||||
afterEach(function() {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
client.stopClient();
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
describe("emissions", function() {
|
||||
|
||||
@@ -111,6 +111,7 @@ describe("getEventTimeline support", function() {
|
||||
if (client) {
|
||||
client.stopClient();
|
||||
}
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
it("timeline support must be enabled to work", function(done) {
|
||||
|
||||
@@ -41,6 +41,7 @@ describe("MatrixClient", function() {
|
||||
|
||||
afterEach(function() {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
describe("uploadContent", function() {
|
||||
|
||||
@@ -64,6 +64,7 @@ describe("MatrixClient opts", function() {
|
||||
|
||||
afterEach(function() {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
describe("without opts.store", function() {
|
||||
|
||||
@@ -36,6 +36,7 @@ describe("MatrixClient retrying", function() {
|
||||
|
||||
afterEach(function() {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
xit("should retry according to MatrixScheduler.retryFn", function() {
|
||||
|
||||
@@ -130,6 +130,7 @@ describe("MatrixClient room timelines", function() {
|
||||
afterEach(function() {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
client.stopClient();
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
describe("local echo events", function() {
|
||||
|
||||
@@ -38,6 +38,7 @@ describe("MatrixClient syncing", function() {
|
||||
afterEach(function() {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
client.stopClient();
|
||||
return httpBackend.stop();
|
||||
});
|
||||
|
||||
describe("startClient", function() {
|
||||
|
||||
@@ -296,7 +296,7 @@ describe("megolm", function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
aliceTestClient.stop();
|
||||
return aliceTestClient.stop();
|
||||
});
|
||||
|
||||
it("Alice receives a megolm message", function() {
|
||||
@@ -817,8 +817,14 @@ describe("megolm", function() {
|
||||
};
|
||||
});
|
||||
|
||||
// Grab the event that we'll need to resend
|
||||
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||
const pendingEvents = room.getPendingEvents();
|
||||
expect(pendingEvents.length).toEqual(1);
|
||||
const unsentEvent = pendingEvents[0];
|
||||
|
||||
return Promise.all([
|
||||
aliceTestClient.client.sendTextMessage(ROOM_ID, 'test'),
|
||||
aliceTestClient.client.resendEvent(unsentEvent, room),
|
||||
|
||||
// the crypto stuff can take a while, so give the requests a whole second.
|
||||
aliceTestClient.httpBackend.flushAllExpected({
|
||||
|
||||
@@ -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';
|
||||
const Olm = global.Olm;
|
||||
|
||||
describe("Crypto", function() {
|
||||
if (!sdk.CRYPTO_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
beforeEach(function(done) {
|
||||
Olm.init().then(done);
|
||||
});
|
||||
|
||||
it("Crypto exposes the correct olm library version", function() {
|
||||
expect(Crypto.getOlmVersion()[0]).toEqual(2);
|
||||
expect(Crypto.getOlmVersion()[0]).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -59,16 +59,25 @@ describe('DeviceList', function() {
|
||||
let downloadSpy;
|
||||
let sessionStore;
|
||||
let cryptoStore;
|
||||
let deviceLists = [];
|
||||
|
||||
beforeEach(function() {
|
||||
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||
|
||||
deviceLists = [];
|
||||
|
||||
downloadSpy = expect.createSpy();
|
||||
const mockStorage = new MockStorageApi();
|
||||
sessionStore = new WebStorageSessionStore(mockStorage);
|
||||
cryptoStore = new MemoryCryptoStore();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
for (const dl of deviceLists) {
|
||||
dl.stop();
|
||||
}
|
||||
});
|
||||
|
||||
function createTestDeviceList() {
|
||||
const baseApis = {
|
||||
downloadKeysForUsers: downloadSpy,
|
||||
@@ -76,7 +85,9 @@ describe('DeviceList', function() {
|
||||
const mockOlm = {
|
||||
verifySignature: function(key, message, signature) {},
|
||||
};
|
||||
return new DeviceList(baseApis, cryptoStore, sessionStore, mockOlm);
|
||||
const dl = new DeviceList(baseApis, cryptoStore, sessionStore, mockOlm);
|
||||
deviceLists.push(dl);
|
||||
return dl;
|
||||
}
|
||||
|
||||
it("should successfully download and store device keys", function() {
|
||||
|
||||
@@ -13,20 +13,16 @@ 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'];
|
||||
|
||||
const ROOM_ID = '!ROOM:ID';
|
||||
|
||||
const Olm = global.Olm;
|
||||
|
||||
describe("MegolmDecryption", function() {
|
||||
if (!global.Olm) {
|
||||
console.warn('Not running megolm unit tests: libolm not present');
|
||||
@@ -69,7 +65,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 +95,7 @@ describe("MegolmDecryption", function() {
|
||||
},
|
||||
};
|
||||
|
||||
return event.attemptDecryption(mockCrypto).then(() => {
|
||||
await event.attemptDecryption(mockCrypto).then(() => {
|
||||
megolmDecryption.onRoomKeyEvent(event);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
global.Olm = require('olm');
|
||||
} catch (e) {
|
||||
console.warn("unable to run megolm tests: libolm not available");
|
||||
}
|
||||
|
||||
import expect from 'expect';
|
||||
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';
|
||||
|
||||
import OlmDevice from '../../../../lib/crypto/OlmDevice';
|
||||
|
||||
function makeOlmDevice() {
|
||||
const mockStorage = new MockStorageApi();
|
||||
const sessionStore = new WebStorageSessionStore(mockStorage);
|
||||
const cryptoStore = new MemoryCryptoStore(mockStorage);
|
||||
const olmDevice = new OlmDevice(sessionStore, cryptoStore);
|
||||
return olmDevice;
|
||||
}
|
||||
|
||||
async function setupSession(initiator, opponent) {
|
||||
await opponent.generateOneTimeKeys(1);
|
||||
const keys = await opponent.getOneTimeKeys();
|
||||
const firstKey = Object.values(keys['curve25519'])[0];
|
||||
|
||||
const sid = await initiator.createOutboundSession(
|
||||
opponent.deviceCurve25519Key, firstKey,
|
||||
);
|
||||
return sid;
|
||||
}
|
||||
|
||||
describe("OlmDecryption", function() {
|
||||
if (!global.Olm) {
|
||||
console.warn('Not running megolm unit tests: libolm not present');
|
||||
return;
|
||||
}
|
||||
|
||||
let aliceOlmDevice;
|
||||
let bobOlmDevice;
|
||||
|
||||
beforeEach(async function() {
|
||||
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||
|
||||
await global.Olm.init();
|
||||
|
||||
aliceOlmDevice = makeOlmDevice();
|
||||
bobOlmDevice = makeOlmDevice();
|
||||
await aliceOlmDevice.init();
|
||||
await bobOlmDevice.init();
|
||||
});
|
||||
|
||||
describe('olm', function() {
|
||||
it("can decrypt messages", async function() {
|
||||
const sid = await setupSession(aliceOlmDevice, bobOlmDevice);
|
||||
|
||||
const ciphertext = await aliceOlmDevice.encryptMessage(
|
||||
bobOlmDevice.deviceCurve25519Key,
|
||||
sid,
|
||||
"The olm or proteus is an aquatic salamander in the family Proteidae",
|
||||
);
|
||||
|
||||
const result = await bobOlmDevice.createInboundSession(
|
||||
aliceOlmDevice.deviceCurve25519Key,
|
||||
ciphertext.type,
|
||||
ciphertext.body,
|
||||
);
|
||||
expect(result.payload).toEqual(
|
||||
"The olm or proteus is an aquatic salamander in the family Proteidae",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
+35
-1
@@ -262,7 +262,19 @@ MatrixBaseApis.prototype.login = function(loginType, data, callback) {
|
||||
utils.extend(login_data, data);
|
||||
|
||||
return this._http.authedRequest(
|
||||
callback, "POST", "/login", undefined, login_data,
|
||||
(error, response) => {
|
||||
if (loginType === "m.login.password" && response &&
|
||||
response.access_token && response.user_id) {
|
||||
this._http.opts.accessToken = response.access_token;
|
||||
this.credentials = {
|
||||
userId: response.user_id,
|
||||
};
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(error, response);
|
||||
}
|
||||
}, "POST", "/login", undefined, login_data,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -927,6 +939,28 @@ MatrixBaseApis.prototype.setRoomReadMarkersHttpRequest =
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {module:client.Promise} Resolves: A list of the user's current rooms
|
||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||
*/
|
||||
MatrixBaseApis.prototype.getJoinedRooms = function() {
|
||||
const path = utils.encodeUri("/joined_rooms");
|
||||
return this._http.authedRequest(undefined, "GET", path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve membership info. for a room.
|
||||
* @param {string} roomId ID of the room to get membership for
|
||||
* @return {module:client.Promise} Resolves: A list of currently joined users
|
||||
* and their profile data.
|
||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||
*/
|
||||
MatrixBaseApis.prototype.getJoinedRoomMembers = function(roomId) {
|
||||
const path = utils.encodeUri("/rooms/$roomId/joined_members", {
|
||||
$roomId: roomId,
|
||||
});
|
||||
return this._http.authedRequest(undefined, "GET", path);
|
||||
};
|
||||
|
||||
// Room Directory operations
|
||||
// =========================
|
||||
|
||||
+45
-20
@@ -45,20 +45,16 @@ const ContentHelpers = require("./content-helpers");
|
||||
import ReEmitter from './ReEmitter';
|
||||
import RoomList from './crypto/RoomList';
|
||||
|
||||
import Crypto from './crypto';
|
||||
import { isCryptoAvailable } from './crypto';
|
||||
|
||||
// Disable warnings for now: we use deprecated bluebird functions
|
||||
// and need to migrate, but they spam the console with warnings.
|
||||
Promise.config({warnings: false});
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
const CRYPTO_ENABLED = isCryptoAvailable();
|
||||
|
||||
/**
|
||||
* Construct a Matrix Client. Only directly construct this if you want to use
|
||||
@@ -133,6 +129,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();
|
||||
@@ -185,10 +183,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.
|
||||
@@ -378,6 +372,13 @@ 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?`,
|
||||
);
|
||||
}
|
||||
|
||||
if (this._crypto) {
|
||||
console.warn("Attempt to re-initialise e2e encryption on MatrixClient");
|
||||
return;
|
||||
@@ -395,13 +396,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(
|
||||
@@ -433,6 +427,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);
|
||||
@@ -764,6 +761,17 @@ MatrixClient.prototype.getGroups = function() {
|
||||
return this.store.getGroups();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the config for the media repository.
|
||||
* @param {module:client.callback} callback Optional.
|
||||
* @return {module:client.Promise} Resolves with an object containing the config.
|
||||
*/
|
||||
MatrixClient.prototype.getMediaConfig = function(callback) {
|
||||
return this._http.requestWithPrefix(
|
||||
callback, "GET", "/config", undefined, undefined, httpApi.PREFIX_MEDIA_R0,
|
||||
);
|
||||
};
|
||||
|
||||
// Room ops
|
||||
// ========
|
||||
|
||||
@@ -910,6 +918,8 @@ MatrixClient.prototype.isUserIgnored = function(userId) {
|
||||
* </strong> Default: true.
|
||||
* @param {boolean} opts.inviteSignUrl If the caller has a keypair 3pid invite,
|
||||
* the signing URL is passed in this parameter.
|
||||
* @param {string[]} opts.viaServers The server names to try and join through in
|
||||
* addition to those that are automatically chosen.
|
||||
* @param {module:client.callback} callback Optional.
|
||||
* @return {module:client.Promise} Resolves: Room object.
|
||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||
@@ -938,6 +948,13 @@ MatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) {
|
||||
);
|
||||
}
|
||||
|
||||
const queryString = {};
|
||||
if (opts.viaServers) {
|
||||
queryString["server_name"] = opts.viaServers;
|
||||
}
|
||||
|
||||
const reqOpts = {qsStringifyOptions: {arrayFormat: 'repeat'}};
|
||||
|
||||
const defer = Promise.defer();
|
||||
|
||||
const self = this;
|
||||
@@ -948,7 +965,8 @@ MatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) {
|
||||
}
|
||||
|
||||
const path = utils.encodeUri("/join/$roomid", { $roomid: roomIdOrAlias});
|
||||
return self._http.authedRequest(undefined, "POST", path, undefined, data);
|
||||
return self._http.authedRequest(
|
||||
undefined, "POST", path, queryString, data, reqOpts);
|
||||
}).then(function(res) {
|
||||
const roomId = res.room_id;
|
||||
const syncApi = new SyncApi(self, self._clientOpts);
|
||||
@@ -1168,6 +1186,13 @@ MatrixClient.prototype.sendEvent = function(roomId, eventType, content, txnId,
|
||||
room.addPendingEvent(localEvent, txnId);
|
||||
}
|
||||
|
||||
// addPendingEvent can change the state to NOT_SENT if it believes
|
||||
// that there's other events that have failed. We won't bother to
|
||||
// try sending the event if the state has changed as such.
|
||||
if (localEvent.status === EventStatus.NOT_SENT) {
|
||||
return Promise.reject(new Error("Event blocked by other events not yet sent"));
|
||||
}
|
||||
|
||||
return _sendEvent(this, room, localEvent, callback);
|
||||
};
|
||||
|
||||
|
||||
+29
-22
@@ -24,6 +24,7 @@ limitations under the License.
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import logger from '../logger';
|
||||
import DeviceInfo from './deviceinfo';
|
||||
import olmlib from './olmlib';
|
||||
import IndexedDBCryptoStore from './store/indexeddb-crypto-store';
|
||||
@@ -110,7 +111,7 @@ export default class DeviceList {
|
||||
'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {
|
||||
this._cryptoStore.getEndToEndDeviceData(txn, (deviceData) => {
|
||||
if (deviceData === null) {
|
||||
console.log("Migrating e2e device data...");
|
||||
logger.log("Migrating e2e device data...");
|
||||
this._devices = this._sessionStore.getAllEndToEndDevices() || {};
|
||||
this._deviceTrackingStatus = (
|
||||
this._sessionStore.getEndToEndDeviceTrackingStatus() || {}
|
||||
@@ -145,6 +146,12 @@ export default class DeviceList {
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
if (this._saveTimer !== null) {
|
||||
clearTimeout(this._saveTimer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the device tracking state to storage, if any changes are
|
||||
* pending other than updating the sync token
|
||||
@@ -190,7 +197,7 @@ export default class DeviceList {
|
||||
const resolveSavePromise = this._resolveSavePromise;
|
||||
this._savePromiseTime = targetTime;
|
||||
this._saveTimer = setTimeout(() => {
|
||||
console.log('Saving device tracking data at token ' + this._syncToken);
|
||||
logger.log('Saving device tracking data at token ' + this._syncToken);
|
||||
// null out savePromise now (after the delay but before the write),
|
||||
// otherwise we could return the existing promise when the save has
|
||||
// actually already happened. Likewise for the dirty flag.
|
||||
@@ -258,7 +265,7 @@ export default class DeviceList {
|
||||
if (this._keyDownloadsInProgressByUser[u]) {
|
||||
// already a key download in progress/queued for this user; its results
|
||||
// will be good enough for us.
|
||||
console.log(
|
||||
logger.log(
|
||||
`downloadKeys: already have a download in progress for ` +
|
||||
`${u}: awaiting its result`,
|
||||
);
|
||||
@@ -269,13 +276,13 @@ export default class DeviceList {
|
||||
});
|
||||
|
||||
if (usersToDownload.length != 0) {
|
||||
console.log("downloadKeys: downloading for", usersToDownload);
|
||||
logger.log("downloadKeys: downloading for", usersToDownload);
|
||||
const downloadPromise = this._doKeyDownload(usersToDownload);
|
||||
promises.push(downloadPromise);
|
||||
}
|
||||
|
||||
if (promises.length === 0) {
|
||||
console.log("downloadKeys: already have all necessary keys");
|
||||
logger.log("downloadKeys: already have all necessary keys");
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
@@ -433,7 +440,7 @@ export default class DeviceList {
|
||||
throw new Error('userId must be a string; was '+userId);
|
||||
}
|
||||
if (!this._deviceTrackingStatus[userId]) {
|
||||
console.log('Now tracking device list for ' + userId);
|
||||
logger.log('Now tracking device list for ' + userId);
|
||||
this._deviceTrackingStatus[userId] = TRACKING_STATUS_PENDING_DOWNLOAD;
|
||||
}
|
||||
// we don't yet persist the tracking status, since there may be a lot
|
||||
@@ -452,7 +459,7 @@ export default class DeviceList {
|
||||
*/
|
||||
stopTrackingDeviceList(userId) {
|
||||
if (this._deviceTrackingStatus[userId]) {
|
||||
console.log('No longer tracking device list for ' + userId);
|
||||
logger.log('No longer tracking device list for ' + userId);
|
||||
this._deviceTrackingStatus[userId] = TRACKING_STATUS_NOT_TRACKED;
|
||||
|
||||
// we don't yet persist the tracking status, since there may be a lot
|
||||
@@ -487,7 +494,7 @@ export default class DeviceList {
|
||||
*/
|
||||
invalidateUserDeviceList(userId) {
|
||||
if (this._deviceTrackingStatus[userId]) {
|
||||
console.log("Marking device list outdated for", userId);
|
||||
logger.log("Marking device list outdated for", userId);
|
||||
this._deviceTrackingStatus[userId] = TRACKING_STATUS_PENDING_DOWNLOAD;
|
||||
|
||||
// we don't yet persist the tracking status, since there may be a lot
|
||||
@@ -550,7 +557,7 @@ export default class DeviceList {
|
||||
).then(() => {
|
||||
finished(true);
|
||||
}, (e) => {
|
||||
console.error(
|
||||
logger.error(
|
||||
'Error downloading keys for ' + users + ":", e,
|
||||
);
|
||||
finished(false);
|
||||
@@ -573,7 +580,7 @@ export default class DeviceList {
|
||||
// since we started this request. If that happens, we should
|
||||
// ignore the completion of the first one.
|
||||
if (this._keyDownloadsInProgressByUser[u] !== prom) {
|
||||
console.log('Another update in the queue for', u,
|
||||
logger.log('Another update in the queue for', u,
|
||||
'- not marking up-to-date');
|
||||
return;
|
||||
}
|
||||
@@ -584,7 +591,7 @@ export default class DeviceList {
|
||||
// we didn't get any new invalidations since this download started:
|
||||
// this user's device list is now up to date.
|
||||
this._deviceTrackingStatus[u] = TRACKING_STATUS_UP_TO_DATE;
|
||||
console.log("Device list for", u, "now up to date");
|
||||
logger.log("Device list for", u, "now up to date");
|
||||
} else {
|
||||
this._deviceTrackingStatus[u] = TRACKING_STATUS_PENDING_DOWNLOAD;
|
||||
}
|
||||
@@ -659,7 +666,7 @@ class DeviceListUpdateSerialiser {
|
||||
|
||||
if (this._downloadInProgress) {
|
||||
// just queue up these users
|
||||
console.log('Queued key download for', users);
|
||||
logger.log('Queued key download for', users);
|
||||
return this._queuedQueryDeferred.promise;
|
||||
}
|
||||
|
||||
@@ -679,7 +686,7 @@ class DeviceListUpdateSerialiser {
|
||||
const deferred = this._queuedQueryDeferred;
|
||||
this._queuedQueryDeferred = null;
|
||||
|
||||
console.log('Starting key download for', downloadUsers);
|
||||
logger.log('Starting key download for', downloadUsers);
|
||||
this._downloadInProgress = true;
|
||||
|
||||
const opts = {};
|
||||
@@ -706,7 +713,7 @@ class DeviceListUpdateSerialiser {
|
||||
|
||||
return prom;
|
||||
}).done(() => {
|
||||
console.log('Completed key download for ' + downloadUsers);
|
||||
logger.log('Completed key download for ' + downloadUsers);
|
||||
|
||||
this._downloadInProgress = false;
|
||||
deferred.resolve();
|
||||
@@ -716,7 +723,7 @@ class DeviceListUpdateSerialiser {
|
||||
this._doQueuedQueries();
|
||||
}
|
||||
}, (e) => {
|
||||
console.warn('Error downloading keys for ' + downloadUsers + ':', e);
|
||||
logger.warn('Error downloading keys for ' + downloadUsers + ':', e);
|
||||
this._downloadInProgress = false;
|
||||
deferred.reject(e);
|
||||
});
|
||||
@@ -725,7 +732,7 @@ class DeviceListUpdateSerialiser {
|
||||
}
|
||||
|
||||
async _processQueryResponseForUser(userId, response) {
|
||||
console.log('got keys for ' + userId + ':', response);
|
||||
logger.log('got keys for ' + userId + ':', response);
|
||||
|
||||
// map from deviceid -> deviceinfo for this user
|
||||
const userStore = {};
|
||||
@@ -763,7 +770,7 @@ async function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,
|
||||
}
|
||||
|
||||
if (!(deviceId in userResult)) {
|
||||
console.log("Device " + userId + ":" + deviceId +
|
||||
logger.log("Device " + userId + ":" + deviceId +
|
||||
" has been removed");
|
||||
delete userStore[deviceId];
|
||||
updated = true;
|
||||
@@ -780,12 +787,12 @@ async function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,
|
||||
// check that the user_id and device_id in the response object are
|
||||
// correct
|
||||
if (deviceResult.user_id !== userId) {
|
||||
console.warn("Mismatched user_id " + deviceResult.user_id +
|
||||
logger.warn("Mismatched user_id " + deviceResult.user_id +
|
||||
" in keys from " + userId + ":" + deviceId);
|
||||
continue;
|
||||
}
|
||||
if (deviceResult.device_id !== deviceId) {
|
||||
console.warn("Mismatched device_id " + deviceResult.device_id +
|
||||
logger.warn("Mismatched device_id " + deviceResult.device_id +
|
||||
" in keys from " + userId + ":" + deviceId);
|
||||
continue;
|
||||
}
|
||||
@@ -815,7 +822,7 @@ async function _storeDeviceKeys(_olmDevice, userStore, deviceResult) {
|
||||
const signKeyId = "ed25519:" + deviceId;
|
||||
const signKey = deviceResult.keys[signKeyId];
|
||||
if (!signKey) {
|
||||
console.warn("Device " + userId + ":" + deviceId +
|
||||
logger.warn("Device " + userId + ":" + deviceId +
|
||||
" has no ed25519 key");
|
||||
return false;
|
||||
}
|
||||
@@ -825,7 +832,7 @@ async function _storeDeviceKeys(_olmDevice, userStore, deviceResult) {
|
||||
try {
|
||||
await olmlib.verifySignature(_olmDevice, deviceResult, userId, deviceId, signKey);
|
||||
} catch (e) {
|
||||
console.warn("Unable to verify signature on device " +
|
||||
logger.warn("Unable to verify signature on device " +
|
||||
userId + ":" + deviceId + ":" + e);
|
||||
return false;
|
||||
}
|
||||
@@ -842,7 +849,7 @@ async function _storeDeviceKeys(_olmDevice, userStore, deviceResult) {
|
||||
// best off sticking with the original keys.
|
||||
//
|
||||
// Should we warn the user about it somehow?
|
||||
console.warn("Ed25519 key for device " + userId + ":" +
|
||||
logger.warn("Ed25519 key for device " + userId + ":" +
|
||||
deviceId + " has changed");
|
||||
return false;
|
||||
}
|
||||
|
||||
+19
-29
@@ -15,19 +15,9 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import logger from '../logger';
|
||||
import IndexedDBCryptoStore from './store/indexeddb-crypto-store';
|
||||
|
||||
/**
|
||||
* olm.js wrapper
|
||||
*
|
||||
* @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
|
||||
// reasonable approximation to the biggest plaintext we can encrypt.
|
||||
const MAX_PLAINTEXT_LENGTH = 65536 * 3 / 4;
|
||||
@@ -127,7 +117,7 @@ OlmDevice.prototype.init = async function() {
|
||||
await this._migrateFromSessionStore();
|
||||
|
||||
let e2eKeys;
|
||||
const account = new Olm.Account();
|
||||
const account = new global.Olm.Account();
|
||||
try {
|
||||
await _initialiseAccount(
|
||||
this._sessionStore, this._cryptoStore, this._pickleKey, account,
|
||||
@@ -161,7 +151,7 @@ async function _initialiseAccount(sessionStore, cryptoStore, pickleKey, account)
|
||||
* @return {array} The version of Olm.
|
||||
*/
|
||||
OlmDevice.getOlmVersion = function() {
|
||||
return Olm.get_library_version();
|
||||
return global.Olm.get_library_version();
|
||||
};
|
||||
|
||||
OlmDevice.prototype._migrateFromSessionStore = async function() {
|
||||
@@ -173,7 +163,7 @@ OlmDevice.prototype._migrateFromSessionStore = async function() {
|
||||
// Migrate from sessionStore
|
||||
pickledAccount = this._sessionStore.getEndToEndAccount();
|
||||
if (pickledAccount !== null) {
|
||||
console.log("Migrating account from session store");
|
||||
logger.log("Migrating account from session store");
|
||||
this._cryptoStore.storeAccount(txn, pickledAccount);
|
||||
}
|
||||
}
|
||||
@@ -195,7 +185,7 @@ OlmDevice.prototype._migrateFromSessionStore = async function() {
|
||||
// has run against the same localstorage and created some spurious sessions.
|
||||
this._cryptoStore.countEndToEndSessions(txn, (count) => {
|
||||
if (count) {
|
||||
console.log("Crypto store already has sessions: not migrating");
|
||||
logger.log("Crypto store already has sessions: not migrating");
|
||||
return;
|
||||
}
|
||||
let numSessions = 0;
|
||||
@@ -207,7 +197,7 @@ OlmDevice.prototype._migrateFromSessionStore = async function() {
|
||||
);
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
logger.log(
|
||||
"Migrating " + numSessions + " sessions from session store",
|
||||
);
|
||||
});
|
||||
@@ -236,14 +226,14 @@ OlmDevice.prototype._migrateFromSessionStore = async function() {
|
||||
), txn,
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
"Failed to migrate session " + s.senderKey + "/" +
|
||||
s.sessionId + ": " + e.stack || e,
|
||||
);
|
||||
}
|
||||
++numIbSessions;
|
||||
}
|
||||
console.log(
|
||||
logger.log(
|
||||
"Migrated " + numIbSessions +
|
||||
" inbound group sessions from session store",
|
||||
);
|
||||
@@ -268,7 +258,7 @@ OlmDevice.prototype._migrateFromSessionStore = async function() {
|
||||
*/
|
||||
OlmDevice.prototype._getAccount = function(txn, func) {
|
||||
this._cryptoStore.getAccount(txn, (pickledAccount) => {
|
||||
const account = new Olm.Account();
|
||||
const account = new global.Olm.Account();
|
||||
try {
|
||||
account.unpickle(this._pickleKey, pickledAccount);
|
||||
func(account);
|
||||
@@ -321,7 +311,7 @@ OlmDevice.prototype._getSession = function(deviceKey, sessionId, txn, func) {
|
||||
* @private
|
||||
*/
|
||||
OlmDevice.prototype._unpickleSession = function(pickledSession, func) {
|
||||
const session = new Olm.Session();
|
||||
const session = new global.Olm.Session();
|
||||
try {
|
||||
session.unpickle(this._pickleKey, pickledSession);
|
||||
func(session);
|
||||
@@ -354,7 +344,7 @@ OlmDevice.prototype._saveSession = function(deviceKey, session, txn) {
|
||||
* @private
|
||||
*/
|
||||
OlmDevice.prototype._getUtility = function(func) {
|
||||
const utility = new Olm.Utility();
|
||||
const utility = new global.Olm.Utility();
|
||||
try {
|
||||
return func(utility);
|
||||
} finally {
|
||||
@@ -466,7 +456,7 @@ OlmDevice.prototype.createOutboundSession = async function(
|
||||
],
|
||||
(txn) => {
|
||||
this._getAccount(txn, (account) => {
|
||||
const session = new Olm.Session();
|
||||
const session = new global.Olm.Session();
|
||||
try {
|
||||
session.create_outbound(account, theirIdentityKey, theirOneTimeKey);
|
||||
newSessionId = session.session_id();
|
||||
@@ -510,7 +500,7 @@ OlmDevice.prototype.createInboundSession = async function(
|
||||
],
|
||||
(txn) => {
|
||||
this._getAccount(txn, (account) => {
|
||||
const session = new Olm.Session();
|
||||
const session = new global.Olm.Session();
|
||||
try {
|
||||
session.create_inbound_from(
|
||||
account, theirDeviceIdentityKey, ciphertext,
|
||||
@@ -728,7 +718,7 @@ OlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) {
|
||||
throw new Error("Unknown outbound group session " + sessionId);
|
||||
}
|
||||
|
||||
const session = new Olm.OutboundGroupSession();
|
||||
const session = new global.Olm.OutboundGroupSession();
|
||||
try {
|
||||
session.unpickle(this._pickleKey, pickled);
|
||||
return func(session);
|
||||
@@ -744,7 +734,7 @@ OlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) {
|
||||
* @return {string} sessionId for the outbound session.
|
||||
*/
|
||||
OlmDevice.prototype.createOutboundGroupSession = function() {
|
||||
const session = new Olm.OutboundGroupSession();
|
||||
const session = new global.Olm.OutboundGroupSession();
|
||||
try {
|
||||
session.create();
|
||||
this._saveOutboundGroupSession(session);
|
||||
@@ -816,7 +806,7 @@ OlmDevice.prototype.getOutboundGroupSessionKey = function(sessionId) {
|
||||
* @return {*} result of func
|
||||
*/
|
||||
OlmDevice.prototype._unpickleInboundGroupSession = function(sessionData, func) {
|
||||
const session = new Olm.InboundGroupSession();
|
||||
const session = new global.Olm.InboundGroupSession();
|
||||
try {
|
||||
session.unpickle(this._pickleKey, sessionData.session);
|
||||
return func(session);
|
||||
@@ -889,7 +879,7 @@ OlmDevice.prototype.addInboundGroupSession = async function(
|
||||
roomId, senderKey, sessionId, txn,
|
||||
(existingSession, existingSessionData) => {
|
||||
if (existingSession) {
|
||||
console.log(
|
||||
logger.log(
|
||||
"Update for megolm session " + senderKey + "/" + sessionId,
|
||||
);
|
||||
// for now we just ignore updates. TODO: implement something here
|
||||
@@ -897,7 +887,7 @@ OlmDevice.prototype.addInboundGroupSession = async function(
|
||||
}
|
||||
|
||||
// new session.
|
||||
const session = new Olm.InboundGroupSession();
|
||||
const session = new global.Olm.InboundGroupSession();
|
||||
try {
|
||||
if (exportFormat) {
|
||||
session.import_session(sessionKey);
|
||||
@@ -1034,7 +1024,7 @@ OlmDevice.prototype.hasInboundSessionKeys = async function(roomId, senderKey, se
|
||||
}
|
||||
|
||||
if (roomId !== sessionData.room_id) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`requested keys for inbound group session ${senderKey}|` +
|
||||
`${sessionId}, with incorrect room_id ` +
|
||||
`(expected ${sessionData.room_id}, ` +
|
||||
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import logger from '../logger';
|
||||
import utils from '../utils';
|
||||
|
||||
/**
|
||||
@@ -108,7 +109,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
* Called when the client is stopped. Stops any running background processes.
|
||||
*/
|
||||
stop() {
|
||||
console.log('stopping OutgoingRoomKeyRequestManager');
|
||||
logger.log('stopping OutgoingRoomKeyRequestManager');
|
||||
// stop the timer on the next run
|
||||
this._clientRunning = false;
|
||||
}
|
||||
@@ -173,7 +174,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
// may have seen it, so we still need to send a cancellation
|
||||
// in that case :/
|
||||
|
||||
console.log(
|
||||
logger.log(
|
||||
'deleting unnecessary room key request for ' +
|
||||
stringifyRequestBody(requestBody),
|
||||
);
|
||||
@@ -201,7 +202,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
// the request cancelled. There is no point in
|
||||
// sending another cancellation since the other tab
|
||||
// will do it.
|
||||
console.log(
|
||||
logger.log(
|
||||
'Tried to cancel room key request for ' +
|
||||
stringifyRequestBody(requestBody) +
|
||||
' but it was already cancelled in another tab',
|
||||
@@ -222,7 +223,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
updatedReq,
|
||||
andResend,
|
||||
).catch((e) => {
|
||||
console.error(
|
||||
logger.error(
|
||||
"Error sending room key request cancellation;"
|
||||
+ " will retry later.", e,
|
||||
);
|
||||
@@ -261,7 +262,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
}).catch((e) => {
|
||||
// this should only happen if there is an indexeddb error,
|
||||
// in which case we're a bit stuffed anyway.
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`error in OutgoingRoomKeyRequestManager: ${e}`,
|
||||
);
|
||||
}).done();
|
||||
@@ -282,7 +283,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
console.log("Looking for queued outgoing room key requests");
|
||||
logger.log("Looking for queued outgoing room key requests");
|
||||
|
||||
return this._cryptoStore.getOutgoingRoomKeyRequestByState([
|
||||
ROOM_KEY_REQUEST_STATES.CANCELLATION_PENDING,
|
||||
@@ -290,7 +291,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
ROOM_KEY_REQUEST_STATES.UNSENT,
|
||||
]).then((req) => {
|
||||
if (!req) {
|
||||
console.log("No more outgoing room key requests");
|
||||
logger.log("No more outgoing room key requests");
|
||||
this._sendOutgoingRoomKeyRequestsTimer = null;
|
||||
return;
|
||||
}
|
||||
@@ -312,7 +313,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
// go around the loop again
|
||||
return this._sendOutgoingRoomKeyRequests();
|
||||
}).catch((e) => {
|
||||
console.error("Error sending room key request; will retry later.", e);
|
||||
logger.error("Error sending room key request; will retry later.", e);
|
||||
this._sendOutgoingRoomKeyRequestsTimer = null;
|
||||
this._startTimer();
|
||||
}).done();
|
||||
@@ -321,7 +322,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
|
||||
// given a RoomKeyRequest, send it and update the request record
|
||||
_sendOutgoingRoomKeyRequest(req) {
|
||||
console.log(
|
||||
logger.log(
|
||||
`Requesting keys for ${stringifyRequestBody(req.requestBody)}` +
|
||||
` from ${stringifyRecipientList(req.recipients)}` +
|
||||
`(id ${req.requestId})`,
|
||||
@@ -347,7 +348,7 @@ export default class OutgoingRoomKeyRequestManager {
|
||||
// Given a RoomKeyRequest, cancel it and delete the request record unless
|
||||
// andResend is set, in which case transition to UNSENT.
|
||||
_sendOutgoingRoomKeyRequestCancellation(req, andResend) {
|
||||
console.log(
|
||||
logger.log(
|
||||
`Sending cancellation for key request for ` +
|
||||
`${stringifyRequestBody(req.requestBody)} to ` +
|
||||
`${stringifyRecipientList(req.recipients)} ` +
|
||||
|
||||
@@ -24,6 +24,7 @@ limitations under the License.
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
const logger = require("../../logger");
|
||||
const utils = require("../../utils");
|
||||
const olmlib = require("../olmlib");
|
||||
const base = require("./base");
|
||||
@@ -65,7 +66,7 @@ OutboundSessionInfo.prototype.needsRotation = function(
|
||||
if (this.useCount >= rotationPeriodMsgs ||
|
||||
sessionLifetime >= rotationPeriodMs
|
||||
) {
|
||||
console.log(
|
||||
logger.log(
|
||||
"Rotating megolm session after " + this.useCount +
|
||||
" messages, " + sessionLifetime + "ms",
|
||||
);
|
||||
@@ -103,7 +104,7 @@ OutboundSessionInfo.prototype.sharedWithTooManyDevices = function(
|
||||
}
|
||||
|
||||
if (!devicesInRoom.hasOwnProperty(userId)) {
|
||||
console.log("Starting new session because we shared with " + userId);
|
||||
logger.log("Starting new session because we shared with " + userId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ OutboundSessionInfo.prototype.sharedWithTooManyDevices = function(
|
||||
}
|
||||
|
||||
if (!devicesInRoom[userId].hasOwnProperty(deviceId)) {
|
||||
console.log(
|
||||
logger.log(
|
||||
"Starting new session because we shared with " +
|
||||
userId + ":" + deviceId,
|
||||
);
|
||||
@@ -182,7 +183,7 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
||||
if (session && session.needsRotation(self._sessionRotationPeriodMsgs,
|
||||
self._sessionRotationPeriodMs)
|
||||
) {
|
||||
console.log("Starting new megolm session because we need to rotate.");
|
||||
logger.log("Starting new megolm session because we need to rotate.");
|
||||
session = null;
|
||||
}
|
||||
|
||||
@@ -192,7 +193,7 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
console.log(`Starting new megolm session for room ${self._roomId}`);
|
||||
logger.log(`Starting new megolm session for room ${self._roomId}`);
|
||||
session = await self._prepareNewSession();
|
||||
}
|
||||
|
||||
@@ -319,7 +320,7 @@ MegolmEncryption.prototype._splitUserDeviceMap = function(
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(
|
||||
logger.log(
|
||||
"share keys with device " + userId + ":" + deviceId,
|
||||
);
|
||||
|
||||
@@ -441,10 +442,10 @@ MegolmEncryption.prototype._shareKeyWithDevices = async function(session, device
|
||||
await this._encryptAndSendKeysToDevices(
|
||||
session, key.chain_index, userDeviceMaps[i], payload,
|
||||
);
|
||||
console.log(`Completed megolm keyshare in ${this._roomId} `
|
||||
logger.log(`Completed megolm keyshare in ${this._roomId} `
|
||||
+ `(slice ${i + 1}/${userDeviceMaps.length})`);
|
||||
} catch (e) {
|
||||
console.log(`megolm keyshare in ${this._roomId} `
|
||||
logger.log(`megolm keyshare in ${this._roomId} `
|
||||
+ `(slice ${i + 1}/${userDeviceMaps.length}) failed`);
|
||||
|
||||
throw e;
|
||||
@@ -463,7 +464,7 @@ MegolmEncryption.prototype._shareKeyWithDevices = async function(session, device
|
||||
*/
|
||||
MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
||||
const self = this;
|
||||
console.log(`Starting to encrypt event for ${this._roomId}`);
|
||||
logger.log(`Starting to encrypt event for ${this._roomId}`);
|
||||
|
||||
return this._getDevicesInRoom(room).then(function(devicesInRoom) {
|
||||
// check if any of these devices are not yet known to the user.
|
||||
@@ -782,12 +783,12 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
||||
!sessionId ||
|
||||
!content.session_key
|
||||
) {
|
||||
console.error("key event is missing fields");
|
||||
logger.error("key event is missing fields");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!senderKey) {
|
||||
console.error("key event has no sender key (not encrypted?)");
|
||||
logger.error("key event has no sender key (not encrypted?)");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -804,13 +805,13 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
||||
|
||||
senderKey = content.sender_key;
|
||||
if (!senderKey) {
|
||||
console.error("forwarded_room_key event is missing sender_key field");
|
||||
logger.error("forwarded_room_key event is missing sender_key field");
|
||||
return;
|
||||
}
|
||||
|
||||
const ed25519Key = content.sender_claimed_ed25519_key;
|
||||
if (!ed25519Key) {
|
||||
console.error(
|
||||
logger.error(
|
||||
`forwarded_room_key_event is missing sender_claimed_ed25519_key field`,
|
||||
);
|
||||
return;
|
||||
@@ -823,7 +824,7 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
||||
keysClaimed = event.getKeysClaimed();
|
||||
}
|
||||
|
||||
console.log(`Adding key for megolm session ${senderKey}|${sessionId}`);
|
||||
logger.log(`Adding key for megolm session ${senderKey}|${sessionId}`);
|
||||
this._olmDevice.addInboundGroupSession(
|
||||
content.room_id, senderKey, forwardingKeyChain, sessionId,
|
||||
content.session_key, keysClaimed,
|
||||
@@ -840,7 +841,7 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
||||
// have another go at decrypting events sent with this session.
|
||||
this._retryDecryption(senderKey, sessionId);
|
||||
}).catch((e) => {
|
||||
console.error(`Error handling m.room_key_event: ${e}`);
|
||||
logger.error(`Error handling m.room_key_event: ${e}`);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -882,7 +883,7 @@ MegolmDecryption.prototype.shareKeysWithDevice = function(keyRequest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(
|
||||
logger.log(
|
||||
"sharing keys for session " + body.sender_key + "|"
|
||||
+ body.session_id + " with device "
|
||||
+ userId + ":" + deviceId,
|
||||
|
||||
@@ -22,6 +22,7 @@ limitations under the License.
|
||||
*/
|
||||
import Promise from 'bluebird';
|
||||
|
||||
const logger = require("../../logger");
|
||||
const utils = require("../../utils");
|
||||
const olmlib = require("../olmlib");
|
||||
const DeviceInfo = require("../deviceinfo");
|
||||
@@ -273,7 +274,7 @@ OlmDecryption.prototype._decryptMessage = async function(
|
||||
const payload = await this._olmDevice.decryptMessage(
|
||||
theirDeviceIdentityKey, sessionId, message.type, message.body,
|
||||
);
|
||||
console.log(
|
||||
logger.log(
|
||||
"Decrypted Olm message from " + theirDeviceIdentityKey +
|
||||
" with session " + sessionId,
|
||||
);
|
||||
@@ -328,7 +329,7 @@ OlmDecryption.prototype._decryptMessage = async function(
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
logger.log(
|
||||
"created new inbound Olm session ID " +
|
||||
res.session_id + " with " + theirDeviceIdentityKey,
|
||||
);
|
||||
|
||||
+34
-29
@@ -25,6 +25,7 @@ const anotherjson = require('another-json');
|
||||
import Promise from 'bluebird';
|
||||
import {EventEmitter} from 'events';
|
||||
|
||||
const logger = require("../logger");
|
||||
const utils = require("../utils");
|
||||
const OlmDevice = require("./OlmDevice");
|
||||
const olmlib = require("./olmlib");
|
||||
@@ -36,6 +37,10 @@ const DeviceList = require('./DeviceList').default;
|
||||
import OutgoingRoomKeyRequestManager from './OutgoingRoomKeyRequestManager';
|
||||
import IndexedDBCryptoStore from './store/indexeddb-crypto-store';
|
||||
|
||||
export function isCryptoAvailable() {
|
||||
return Boolean(global.Olm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cryptography bits
|
||||
*
|
||||
@@ -62,7 +67,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 +129,8 @@ utils.inherits(Crypto, EventEmitter);
|
||||
* Returns a promise which resolves once the crypto module is ready for use.
|
||||
*/
|
||||
Crypto.prototype.init = async function() {
|
||||
await global.Olm.init();
|
||||
|
||||
const sessionStoreHasAccount = Boolean(this._sessionStore.getEndToEndAccount());
|
||||
let cryptoStoreHasAccount;
|
||||
await this._cryptoStore.doTxn(
|
||||
@@ -196,7 +203,7 @@ Crypto.prototype.registerEventHandlers = function(eventEmitter) {
|
||||
try {
|
||||
crypto._onRoomMembership(event, member, oldMembership);
|
||||
} catch (e) {
|
||||
console.error("Error handling membership change:", e);
|
||||
logger.error("Error handling membership change:", e);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -214,6 +221,7 @@ Crypto.prototype.start = function() {
|
||||
/** Stop background processes related to crypto */
|
||||
Crypto.prototype.stop = function() {
|
||||
this._outgoingRoomKeyRequestManager.stop();
|
||||
this._deviceList.stop();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -381,7 +389,7 @@ function _maybeUploadOneTimeKeys(crypto) {
|
||||
// create any more keys.
|
||||
return uploadLoop(keyCount);
|
||||
}).catch((e) => {
|
||||
console.error("Error uploading one-time keys", e.stack || e);
|
||||
logger.error("Error uploading one-time keys", e.stack || e);
|
||||
}).finally(() => {
|
||||
// reset _oneTimeKeyCount to prevent start uploading based on old data.
|
||||
// it will be set again on the next /sync-response
|
||||
@@ -606,13 +614,13 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) {
|
||||
|
||||
const claimedKey = event.getClaimedEd25519Key();
|
||||
if (!claimedKey) {
|
||||
console.warn("Event " + event.getId() + " claims no ed25519 key: " +
|
||||
logger.warn("Event " + event.getId() + " claims no ed25519 key: " +
|
||||
"cannot verify sending device");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (claimedKey !== device.getFingerprint()) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
"Event " + event.getId() + " claims ed25519 key " + claimedKey +
|
||||
"but sender device has key " + device.getFingerprint());
|
||||
return null;
|
||||
@@ -658,7 +666,7 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic
|
||||
const existingConfig = this._roomList.getRoomEncryption(roomId);
|
||||
if (existingConfig) {
|
||||
if (JSON.stringify(existingConfig) != JSON.stringify(config)) {
|
||||
console.error("Ignoring m.room.encryption event which requests " +
|
||||
logger.error("Ignoring m.room.encryption event which requests " +
|
||||
"a change of config in " + roomId);
|
||||
return;
|
||||
}
|
||||
@@ -705,7 +713,7 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic
|
||||
}
|
||||
|
||||
if (!this._lazyLoadMembers) {
|
||||
console.log("Enabling encryption in " + roomId + "; " +
|
||||
logger.log("Enabling encryption in " + roomId + "; " +
|
||||
"starting to track device lists for all users therein");
|
||||
|
||||
await this.trackRoomDevices(roomId);
|
||||
@@ -717,7 +725,7 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic
|
||||
this._deviceList.refreshOutdatedDeviceLists();
|
||||
}
|
||||
} else {
|
||||
console.log("Enabling encryption in " + roomId);
|
||||
logger.log("Enabling encryption in " + roomId);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -738,7 +746,7 @@ Crypto.prototype.trackRoomDevices = function(roomId) {
|
||||
if (!room) {
|
||||
throw new Error(`Unable to start tracking devices in unknown room ${roomId}`);
|
||||
}
|
||||
console.log(`Starting to track devices for room ${roomId} ...`);
|
||||
logger.log(`Starting to track devices for room ${roomId} ...`);
|
||||
const members = await room.getEncryptionTargetMembers();
|
||||
members.forEach((m) => {
|
||||
this._deviceList.startTrackingDeviceList(m.userId);
|
||||
@@ -834,7 +842,7 @@ Crypto.prototype.importRoomKeys = function(keys) {
|
||||
return Promise.map(
|
||||
keys, (key) => {
|
||||
if (!key.room_id || !key.algorithm) {
|
||||
console.warn("ignoring room key entry with missing fields", key);
|
||||
logger.warn("ignoring room key entry with missing fields", key);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -963,7 +971,7 @@ Crypto.prototype.requestRoomKey = function(requestBody, recipients) {
|
||||
requestBody, recipients,
|
||||
).catch((e) => {
|
||||
// this normally means we couldn't talk to the store
|
||||
console.error(
|
||||
logger.error(
|
||||
'Error requesting key for event', e,
|
||||
);
|
||||
}).done();
|
||||
@@ -980,7 +988,7 @@ Crypto.prototype.requestRoomKey = function(requestBody, recipients) {
|
||||
Crypto.prototype.cancelRoomKeyRequest = function(requestBody, andResend) {
|
||||
this._outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody, andResend)
|
||||
.catch((e) => {
|
||||
console.warn("Error clearing pending room key requests", e);
|
||||
logger.warn("Error clearing pending room key requests", e);
|
||||
}).done();
|
||||
};
|
||||
|
||||
@@ -998,7 +1006,7 @@ Crypto.prototype.onCryptoEvent = async function(event) {
|
||||
// finished processing the sync, in onSyncCompleted.
|
||||
await this.setRoomEncryption(roomId, content, true);
|
||||
} catch (e) {
|
||||
console.error("Error configuring encryption in room " + roomId +
|
||||
logger.error("Error configuring encryption in room " + roomId +
|
||||
":", e);
|
||||
}
|
||||
};
|
||||
@@ -1014,7 +1022,7 @@ Crypto.prototype.onSyncWillProcess = async function(syncData) {
|
||||
// scratch, so mark everything as untracked. onCryptoEvent will
|
||||
// be called for all e2e rooms during the processing of the sync,
|
||||
// at which point we'll start tracking all the users of that room.
|
||||
console.log("Initial sync performed - resetting device tracking state");
|
||||
logger.log("Initial sync performed - resetting device tracking state");
|
||||
this._deviceList.stopTrackingAllDeviceLists();
|
||||
this._roomDeviceTrackingState = {};
|
||||
}
|
||||
@@ -1132,7 +1140,7 @@ Crypto.prototype._onToDeviceEvent = function(event) {
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error handling toDeviceEvent:", e);
|
||||
logger.error("Error handling toDeviceEvent:", e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1146,7 +1154,7 @@ Crypto.prototype._onRoomKeyEvent = function(event) {
|
||||
const content = event.getContent();
|
||||
|
||||
if (!content.room_id || !content.algorithm) {
|
||||
console.error("key event is missing fields");
|
||||
logger.error("key event is missing fields");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1184,12 +1192,12 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) {
|
||||
// by calling _trackRoomDevices
|
||||
if (this._roomDeviceTrackingState[roomId]) {
|
||||
if (member.membership == 'join') {
|
||||
console.log('Join event for ' + member.userId + ' in ' + roomId);
|
||||
logger.log('Join event for ' + member.userId + ' in ' + roomId);
|
||||
// make sure we are tracking the deviceList for this user
|
||||
this._deviceList.startTrackingDeviceList(member.userId);
|
||||
} else if (member.membership == 'invite' &&
|
||||
this._clientStore.getRoom(roomId).shouldEncryptForInvitedMembers()) {
|
||||
console.log('Invite event for ' + member.userId + ' in ' + roomId);
|
||||
logger.log('Invite event for ' + member.userId + ' in ' + roomId);
|
||||
this._deviceList.startTrackingDeviceList(member.userId);
|
||||
}
|
||||
}
|
||||
@@ -1256,7 +1264,7 @@ Crypto.prototype._processReceivedRoomKeyRequests = async function() {
|
||||
this._processReceivedRoomKeyRequestCancellation(cancellation),
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(`Error processing room key requsts: ${e}`);
|
||||
logger.error(`Error processing room key requsts: ${e}`);
|
||||
} finally {
|
||||
this._processingRoomKeyRequests = false;
|
||||
}
|
||||
@@ -1275,13 +1283,13 @@ Crypto.prototype._processReceivedRoomKeyRequest = async function(req) {
|
||||
const roomId = body.room_id;
|
||||
const alg = body.algorithm;
|
||||
|
||||
console.log(`m.room_key_request from ${userId}:${deviceId}` +
|
||||
logger.log(`m.room_key_request from ${userId}:${deviceId}` +
|
||||
` for ${roomId} / ${body.session_id} (id ${req.requestId})`);
|
||||
|
||||
if (userId !== this._userId) {
|
||||
// TODO: determine if we sent this device the keys already: in
|
||||
// which case we can do so again.
|
||||
console.log("Ignoring room key request from other user for now");
|
||||
logger.log("Ignoring room key request from other user for now");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1291,18 +1299,18 @@ Crypto.prototype._processReceivedRoomKeyRequest = async function(req) {
|
||||
// if we don't have a decryptor for this room/alg, we don't have
|
||||
// the keys for the requested events, and can drop the requests.
|
||||
if (!this._roomDecryptors[roomId]) {
|
||||
console.log(`room key request for unencrypted room ${roomId}`);
|
||||
logger.log(`room key request for unencrypted room ${roomId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const decryptor = this._roomDecryptors[roomId][alg];
|
||||
if (!decryptor) {
|
||||
console.log(`room key request for unknown alg ${alg} in room ${roomId}`);
|
||||
logger.log(`room key request for unknown alg ${alg} in room ${roomId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await decryptor.hasKeysForKeyRequest(req)) {
|
||||
console.log(
|
||||
logger.log(
|
||||
`room key request for unknown session ${roomId} / ` +
|
||||
body.session_id,
|
||||
);
|
||||
@@ -1316,7 +1324,7 @@ Crypto.prototype._processReceivedRoomKeyRequest = async function(req) {
|
||||
// if the device is is verified already, share the keys
|
||||
const device = this._deviceList.getStoredDevice(userId, deviceId);
|
||||
if (device && device.isVerified()) {
|
||||
console.log('device is already verified: sharing keys');
|
||||
logger.log('device is already verified: sharing keys');
|
||||
req.share();
|
||||
return;
|
||||
}
|
||||
@@ -1333,7 +1341,7 @@ Crypto.prototype._processReceivedRoomKeyRequest = async function(req) {
|
||||
Crypto.prototype._processReceivedRoomKeyRequestCancellation = async function(
|
||||
cancellation,
|
||||
) {
|
||||
console.log(
|
||||
logger.log(
|
||||
`m.room_key_request cancellation for ${cancellation.userId}:` +
|
||||
`${cancellation.deviceId} (id ${cancellation.requestId})`,
|
||||
);
|
||||
@@ -1518,6 +1526,3 @@ class IncomingRoomKeyRequestCancellation {
|
||||
* @event module:client~MatrixClient#"crypto.warning"
|
||||
* @param {string} type One of the strings listed above
|
||||
*/
|
||||
|
||||
/** */
|
||||
module.exports = Crypto;
|
||||
|
||||
@@ -23,6 +23,7 @@ limitations under the License.
|
||||
import Promise from 'bluebird';
|
||||
const anotherjson = require('another-json');
|
||||
|
||||
const logger = require("../logger");
|
||||
const utils = require("../utils");
|
||||
|
||||
/**
|
||||
@@ -65,7 +66,7 @@ module.exports.encryptMessageForDevice = async function(
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
logger.log(
|
||||
"Using sessionid " + sessionId + " for device " +
|
||||
recipientUserId + ":" + recipientDevice.deviceId,
|
||||
);
|
||||
@@ -190,7 +191,7 @@ module.exports.ensureOlmSessionsForDevices = async function(
|
||||
}
|
||||
|
||||
if (!oneTimeKey) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
"No one-time keys (alg=" + oneTimeKeyAlgorithm +
|
||||
") for device " + userId + ":" + deviceId,
|
||||
);
|
||||
@@ -219,7 +220,7 @@ async function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceIn
|
||||
deviceInfo.getFingerprint(),
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
logger.error(
|
||||
"Unable to verify signature on one-time key for device " +
|
||||
userId + ":" + deviceId + ":", e,
|
||||
);
|
||||
@@ -233,12 +234,12 @@ async function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceIn
|
||||
);
|
||||
} catch (e) {
|
||||
// possibly a bad key
|
||||
console.error("Error starting session with device " +
|
||||
logger.error("Error starting session with device " +
|
||||
userId + ":" + deviceId + ": " + e);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log("Started new sessionid " + sid +
|
||||
logger.log("Started new sessionid " + sid +
|
||||
" for device " + userId + ":" + deviceId);
|
||||
return sid;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import logger from '../../logger';
|
||||
import utils from '../../utils';
|
||||
|
||||
export const VERSION = 6;
|
||||
@@ -38,7 +40,7 @@ export class Backend {
|
||||
// attempts to delete the database will block (and subsequent
|
||||
// attempts to re-create it will also block).
|
||||
db.onversionchange = (ev) => {
|
||||
console.log(`versionchange for indexeddb ${this._dbName}: closing`);
|
||||
logger.log(`versionchange for indexeddb ${this._dbName}: closing`);
|
||||
db.close();
|
||||
};
|
||||
}
|
||||
@@ -64,7 +66,7 @@ export class Backend {
|
||||
this._getOutgoingRoomKeyRequest(txn, requestBody, (existing) => {
|
||||
if (existing) {
|
||||
// this entry matches the request - return it.
|
||||
console.log(
|
||||
logger.log(
|
||||
`already have key request outstanding for ` +
|
||||
`${requestBody.room_id} / ${requestBody.session_id}: ` +
|
||||
`not sending another`,
|
||||
@@ -75,7 +77,7 @@ export class Backend {
|
||||
|
||||
// we got to the end of the list without finding a match
|
||||
// - add the new request.
|
||||
console.log(
|
||||
logger.log(
|
||||
`enqueueing key request for ${requestBody.room_id} / ` +
|
||||
requestBody.session_id,
|
||||
);
|
||||
@@ -226,7 +228,7 @@ export class Backend {
|
||||
}
|
||||
const data = cursor.value;
|
||||
if (data.state != expectedState) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`Cannot update room key request from ${expectedState} ` +
|
||||
`as it was already updated to ${data.state}`,
|
||||
);
|
||||
@@ -264,7 +266,7 @@ export class Backend {
|
||||
}
|
||||
const data = cursor.value;
|
||||
if (data.state != expectedState) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`Cannot delete room key request in state ${data.state} `
|
||||
+ `(expected ${expectedState})`,
|
||||
);
|
||||
@@ -400,7 +402,7 @@ export class Backend {
|
||||
ev.stopPropagation();
|
||||
// ...and this stops it from aborting the transaction
|
||||
ev.preventDefault();
|
||||
console.log(
|
||||
logger.log(
|
||||
"Ignoring duplicate inbound group session: " +
|
||||
senderCurve25519Key + " / " + sessionId,
|
||||
);
|
||||
@@ -471,7 +473,7 @@ export class Backend {
|
||||
}
|
||||
|
||||
export function upgradeDatabase(db, oldVersion) {
|
||||
console.log(
|
||||
logger.log(
|
||||
`Upgrading IndexedDBCryptoStore from version ${oldVersion}`
|
||||
+ ` to ${VERSION}`,
|
||||
);
|
||||
|
||||
@@ -17,9 +17,11 @@ limitations under the License.
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import logger from '../../logger';
|
||||
import LocalStorageCryptoStore from './localStorage-crypto-store';
|
||||
import MemoryCryptoStore from './memory-crypto-store';
|
||||
import * as IndexedDBCryptoStoreBackend from './indexeddb-crypto-store-backend';
|
||||
import {InvalidCryptoStoreError} from '../../errors';
|
||||
|
||||
/**
|
||||
* Internal module. indexeddb storage for e2e.
|
||||
@@ -64,7 +66,7 @@ export default class IndexedDBCryptoStore {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`connecting to indexeddb ${this._dbName}`);
|
||||
logger.log(`connecting to indexeddb ${this._dbName}`);
|
||||
|
||||
const req = this._indexedDB.open(
|
||||
this._dbName, IndexedDBCryptoStoreBackend.VERSION,
|
||||
@@ -77,7 +79,7 @@ export default class IndexedDBCryptoStore {
|
||||
};
|
||||
|
||||
req.onblocked = () => {
|
||||
console.log(
|
||||
logger.log(
|
||||
`can't yet open IndexedDBCryptoStore because it is open elsewhere`,
|
||||
);
|
||||
};
|
||||
@@ -89,7 +91,7 @@ export default class IndexedDBCryptoStore {
|
||||
req.onsuccess = (r) => {
|
||||
const db = r.target.result;
|
||||
|
||||
console.log(`connected to indexeddb ${this._dbName}`);
|
||||
logger.log(`connected to indexeddb ${this._dbName}`);
|
||||
resolve(new IndexedDBCryptoStoreBackend.Backend(db));
|
||||
};
|
||||
}).then((backend) => {
|
||||
@@ -106,16 +108,25 @@ export default class IndexedDBCryptoStore {
|
||||
},
|
||||
);
|
||||
}).catch((e) => {
|
||||
console.warn(
|
||||
if (e.name === 'VersionError') {
|
||||
logger.warn("Crypto DB is too new for us to use!", e);
|
||||
// don't fall back to a different store: the user has crypto data
|
||||
// in this db so we should use it or nothing at all.
|
||||
throw new InvalidCryptoStoreError(InvalidCryptoStoreError.TOO_NEW);
|
||||
}
|
||||
logger.warn(
|
||||
`unable to connect to indexeddb ${this._dbName}` +
|
||||
`: falling back to localStorage store: ${e}`,
|
||||
);
|
||||
return new LocalStorageCryptoStore(global.localStorage);
|
||||
}).catch((e) => {
|
||||
console.warn(
|
||||
`unable to open localStorage: falling back to in-memory store: ${e}`,
|
||||
);
|
||||
return new MemoryCryptoStore();
|
||||
|
||||
try {
|
||||
return new LocalStorageCryptoStore(global.localStorage);
|
||||
} catch (e) {
|
||||
logger.warn(
|
||||
`unable to open localStorage: falling back to in-memory store: ${e}`,
|
||||
);
|
||||
return new MemoryCryptoStore();
|
||||
}
|
||||
});
|
||||
|
||||
return this._backendPromise;
|
||||
@@ -133,11 +144,11 @@ export default class IndexedDBCryptoStore {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Removing indexeddb instance: ${this._dbName}`);
|
||||
logger.log(`Removing indexeddb instance: ${this._dbName}`);
|
||||
const req = this._indexedDB.deleteDatabase(this._dbName);
|
||||
|
||||
req.onblocked = () => {
|
||||
console.log(
|
||||
logger.log(
|
||||
`can't yet delete IndexedDBCryptoStore because it is open elsewhere`,
|
||||
);
|
||||
};
|
||||
@@ -147,14 +158,14 @@ export default class IndexedDBCryptoStore {
|
||||
};
|
||||
|
||||
req.onsuccess = () => {
|
||||
console.log(`Removed indexeddb instance: ${this._dbName}`);
|
||||
logger.log(`Removed indexeddb instance: ${this._dbName}`);
|
||||
resolve();
|
||||
};
|
||||
}).catch((e) => {
|
||||
// in firefox, with indexedDB disabled, this fails with a
|
||||
// DOMError. We treat this as non-fatal, so that people can
|
||||
// still use the app.
|
||||
console.warn(`unable to delete IndexedDBCryptoStore: ${e}`);
|
||||
logger.warn(`unable to delete IndexedDBCryptoStore: ${e}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import logger from '../../logger';
|
||||
import MemoryCryptoStore from './memory-crypto-store.js';
|
||||
|
||||
/**
|
||||
@@ -199,8 +201,8 @@ function getJsonItem(store, key) {
|
||||
// JSON.parse(null) === null, so this returns null.
|
||||
return JSON.parse(store.getItem(key));
|
||||
} catch (e) {
|
||||
console.log("Error: Failed to get key %s: %s", key, e.stack || e);
|
||||
console.log(e.stack);
|
||||
logger.log("Error: Failed to get key %s: %s", key, e.stack || e);
|
||||
logger.log(e.stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import logger from '../../logger';
|
||||
import utils from '../../utils';
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,7 @@ export default class MemoryCryptoStore {
|
||||
|
||||
if (existing) {
|
||||
// this entry matches the request - return it.
|
||||
console.log(
|
||||
logger.log(
|
||||
`already have key request outstanding for ` +
|
||||
`${requestBody.room_id} / ${requestBody.session_id}: ` +
|
||||
`not sending another`,
|
||||
@@ -81,7 +82,7 @@ export default class MemoryCryptoStore {
|
||||
|
||||
// we got to the end of the list without finding a match
|
||||
// - add the new request.
|
||||
console.log(
|
||||
logger.log(
|
||||
`enqueueing key request for ${requestBody.room_id} / ` +
|
||||
requestBody.session_id,
|
||||
);
|
||||
@@ -163,7 +164,7 @@ export default class MemoryCryptoStore {
|
||||
}
|
||||
|
||||
if (req.state != expectedState) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`Cannot update room key request from ${expectedState} ` +
|
||||
`as it was already updated to ${req.state}`,
|
||||
);
|
||||
@@ -194,7 +195,7 @@ export default class MemoryCryptoStore {
|
||||
}
|
||||
|
||||
if (req.state != expectedState) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`Cannot delete room key request in state ${req.state} `
|
||||
+ `(expected ${expectedState})`,
|
||||
);
|
||||
|
||||
+23
-2
@@ -1,6 +1,6 @@
|
||||
// can't just do InvalidStoreError extends Error
|
||||
// because of http://babeljs.io/docs/usage/caveats/#classes
|
||||
function InvalidStoreError(reason, value) {
|
||||
export function InvalidStoreError(reason, value) {
|
||||
const message = `Store is invalid because ${reason}, ` +
|
||||
`please stop the client, delete all data and start the client again`;
|
||||
const instance = Reflect.construct(Error, [message]);
|
||||
@@ -22,4 +22,25 @@ InvalidStoreError.prototype = Object.create(Error.prototype, {
|
||||
});
|
||||
Reflect.setPrototypeOf(InvalidStoreError, Error);
|
||||
|
||||
module.exports.InvalidStoreError = InvalidStoreError;
|
||||
|
||||
export function InvalidCryptoStoreError(reason) {
|
||||
const message = `Crypto store is invalid because ${reason}, ` +
|
||||
`please stop the client, delete all data and start the client again`;
|
||||
const instance = Reflect.construct(Error, [message]);
|
||||
Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));
|
||||
instance.reason = reason;
|
||||
instance.name = 'InvalidCryptoStoreError';
|
||||
return instance;
|
||||
}
|
||||
|
||||
InvalidCryptoStoreError.TOO_NEW = "TOO_NEW";
|
||||
|
||||
InvalidCryptoStoreError.prototype = Object.create(Error.prototype, {
|
||||
constructor: {
|
||||
value: Error,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
},
|
||||
});
|
||||
Reflect.setPrototypeOf(InvalidCryptoStoreError, Error);
|
||||
|
||||
@@ -752,6 +752,8 @@ module.exports.MatrixHttpApi.prototype = {
|
||||
method: method,
|
||||
withCredentials: false,
|
||||
qs: queryParams,
|
||||
qsStringifyOptions: opts.qsStringifyOptions,
|
||||
useQuerystring: true,
|
||||
body: data,
|
||||
json: false,
|
||||
timeout: localTimeoutMs,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2018 André Jaenisch
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module logger
|
||||
*/
|
||||
const log = require("loglevel");
|
||||
|
||||
// This is to demonstrate, that you can use any namespace you want.
|
||||
// Namespaces allow you to turn on/off the logging for specific parts of the
|
||||
// application.
|
||||
// An idea would be to control this via an environment variable (on Node.js).
|
||||
// See https://www.npmjs.com/package/debug to see how this could be implemented
|
||||
// Part of #332 is introducing a logging library in the first place.
|
||||
const DEFAULT_NAME_SPACE = "matrix";
|
||||
const logger = log.getLogger(DEFAULT_NAME_SPACE);
|
||||
logger.setLevel(log.levels.DEBUG);
|
||||
|
||||
/**
|
||||
* Drop-in replacement for <code>console</code> using {@link https://www.npmjs.com/package/loglevel|loglevel}.
|
||||
* Can be tailored down to specific use cases if needed.
|
||||
*/
|
||||
module.exports = logger;
|
||||
@@ -999,6 +999,10 @@ Room.prototype.addPendingEvent = function(event, txnId) {
|
||||
this._txnToEvent[txnId] = event;
|
||||
|
||||
if (this._opts.pendingEventOrdering == "detached") {
|
||||
if (this._pendingEventList.some((e) => e.status === EventStatus.NOT_SENT)) {
|
||||
console.warn("Setting event as NOT_SENT due to messages in the same state");
|
||||
event.status = EventStatus.NOT_SENT;
|
||||
}
|
||||
this._pendingEventList.push(event);
|
||||
} else {
|
||||
for (let i = 0; i < this._timelineSets.length; i++) {
|
||||
|
||||
+1
-1
@@ -516,7 +516,7 @@ SyncApi.prototype.sync = function() {
|
||||
console.warn("InvalidStoreError: store is not usable: stopping sync.");
|
||||
return;
|
||||
}
|
||||
if (this.opts.lazyLoadMembers && this._crypto) {
|
||||
if (this.opts.lazyLoadMembers && this.opts.crypto) {
|
||||
this.opts.crypto.enableLazyLoading();
|
||||
}
|
||||
await this.client._storeClientOptions();
|
||||
|
||||
Reference in New Issue
Block a user