You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Merge branch 'develop' into kegan/indexeddb
This commit is contained in:
14
.eslintrc.js
14
.eslintrc.js
@@ -1,4 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
|
parser: "babel-eslint",
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 6,
|
ecmaVersion: 6,
|
||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
@@ -11,12 +12,20 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
extends: ["eslint:recommended", "google"],
|
extends: ["eslint:recommended", "google"],
|
||||||
rules: {
|
rules: {
|
||||||
// rules we've always adhered to
|
// rules we've always adhered to or now do
|
||||||
"max-len": ["error", {
|
"max-len": ["error", {
|
||||||
code: 90,
|
code: 90,
|
||||||
ignoreComments: true,
|
ignoreComments: true,
|
||||||
}],
|
}],
|
||||||
curly: ["error", "multi-line"],
|
curly: ["error", "multi-line"],
|
||||||
|
"prefer-const": ["error"],
|
||||||
|
"comma-dangle": ["error", {
|
||||||
|
arrays: "always-multiline",
|
||||||
|
objects: "always-multiline",
|
||||||
|
imports: "always-multiline",
|
||||||
|
exports: "always-multiline",
|
||||||
|
functions: "always-multiline",
|
||||||
|
}],
|
||||||
|
|
||||||
// loosen jsdoc requirements a little
|
// loosen jsdoc requirements a little
|
||||||
"require-jsdoc": ["error", {
|
"require-jsdoc": ["error", {
|
||||||
@@ -47,8 +56,7 @@ module.exports = {
|
|||||||
// we set these to warnings, and assert that the number
|
// we set these to warnings, and assert that the number
|
||||||
// of warnings doesn't exceed a given threshold
|
// of warnings doesn't exceed a given threshold
|
||||||
"no-var": ["warn"],
|
"no-var": ["warn"],
|
||||||
"comma-dangle": ["warn"],
|
"brace-style": ["warn", "1tbs", {"allowSingleLine": true}],
|
||||||
"brace-style": ["warn"],
|
|
||||||
"prefer-rest-params": ["warn"],
|
"prefer-rest-params": ["warn"],
|
||||||
"prefer-spread": ["warn"],
|
"prefer-spread": ["warn"],
|
||||||
"one-var": ["warn"],
|
"one-var": ["warn"],
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@ out
|
|||||||
reports
|
reports
|
||||||
/dist
|
/dist
|
||||||
/lib
|
/lib
|
||||||
|
/specbuild
|
||||||
|
|
||||||
# version file and tarball created by 'npm pack'
|
# version file and tarball created by 'npm pack'
|
||||||
/git-revision.txt
|
/git-revision.txt
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- node # Latest stable version of nodejs.
|
- node # Latest stable version of nodejs.
|
||||||
|
script:
|
||||||
|
- npm run lint
|
||||||
|
- npm run test
|
||||||
|
|||||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,3 +1,26 @@
|
|||||||
|
Changes in [0.7.4](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.4) (2017-01-16)
|
||||||
|
================================================================================================
|
||||||
|
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.4-rc.1...v0.7.4)
|
||||||
|
|
||||||
|
* Fix non-conference calling
|
||||||
|
|
||||||
|
Changes in [0.7.4-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.4-rc.1) (2017-01-13)
|
||||||
|
==========================================================================================================
|
||||||
|
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.3...v0.7.4-rc.1)
|
||||||
|
|
||||||
|
* Remove babel-polyfill
|
||||||
|
[\#321](https://github.com/matrix-org/matrix-js-sdk/pull/321)
|
||||||
|
* Update build process for ES6
|
||||||
|
[\#320](https://github.com/matrix-org/matrix-js-sdk/pull/320)
|
||||||
|
* 'babel' is not a babel package anymore
|
||||||
|
[\#319](https://github.com/matrix-org/matrix-js-sdk/pull/319)
|
||||||
|
* Add Babel for ES6 support
|
||||||
|
[\#318](https://github.com/matrix-org/matrix-js-sdk/pull/318)
|
||||||
|
* Move screen sharing check/error
|
||||||
|
[\#317](https://github.com/matrix-org/matrix-js-sdk/pull/317)
|
||||||
|
* release.sh: Bail early if there are uncommitted changes
|
||||||
|
[\#316](https://github.com/matrix-org/matrix-js-sdk/pull/316)
|
||||||
|
|
||||||
Changes in [0.7.3](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.3) (2017-01-04)
|
Changes in [0.7.3](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.7.3) (2017-01-04)
|
||||||
================================================================================================
|
================================================================================================
|
||||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.2...v0.7.3)
|
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.7.2...v0.7.3)
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#!/bin/bash -l
|
#!/bin/bash -l
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
export NVM_DIR="/home/jenkins/.nvm"
|
export NVM_DIR="/home/jenkins/.nvm"
|
||||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||||
nvm use 6
|
|
||||||
npm install
|
nvm use 6 || exit $?
|
||||||
|
npm install || exit $?
|
||||||
|
|
||||||
RC=0
|
RC=0
|
||||||
|
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "matrix-js-sdk",
|
"name": "matrix-js-sdk",
|
||||||
"version": "0.7.3",
|
"version": "0.7.4",
|
||||||
"description": "Matrix Client-Server SDK for Javascript",
|
"description": "Matrix Client-Server SDK for Javascript",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "istanbul cover --report cobertura --config .istanbul.yml -i \"lib/**/*.js\" jasmine-node -- spec --verbose --junitreport --captureExceptions",
|
"buildtest": "babel -s -d specbuild spec",
|
||||||
"check": "jasmine-node spec --verbose --junitreport --captureExceptions",
|
"test": "npm run buildtest && istanbul cover --report cobertura --config .istanbul.yml -i \"lib/**/*.js\" jasmine-node -- specbuild --verbose --junitreport --captureExceptions",
|
||||||
|
"check": "npm run buildtest && jasmine-node specbuild --verbose --junitreport --captureExceptions",
|
||||||
"gendoc": "jsdoc -r lib -P package.json -R README.md -d .jsdoc",
|
"gendoc": "jsdoc -r lib -P package.json -R README.md -d .jsdoc",
|
||||||
"start": "babel -s -w -d lib src",
|
"start": "babel -s -w -d lib src",
|
||||||
"build": "babel -s -d lib src && rimraf dist && mkdir dist && browserify --exclude olm browser-index.js -o dist/browser-matrix.js --ignore-missing && uglifyjs -c -m -o dist/browser-matrix.min.js dist/browser-matrix.js",
|
"build": "babel -s -d lib src && rimraf dist && mkdir dist && browserify --exclude olm browser-index.js -o dist/browser-matrix.js --ignore-missing && uglifyjs -c -m -o dist/browser-matrix.min.js dist/browser-matrix.js",
|
||||||
"dist": "npm run build",
|
"dist": "npm run build",
|
||||||
"watch": "watchify --exclude olm browser-index.js -o dist/browser-matrix-dev.js -v",
|
"watch": "watchify --exclude olm browser-index.js -o dist/browser-matrix-dev.js -v",
|
||||||
"lint": "eslint --max-warnings 146 src spec",
|
"lint": "eslint --max-warnings 121 src spec",
|
||||||
"prepublish": "npm run lint && npm run build && git rev-parse HEAD > git-revision.txt"
|
"prepublish": "npm run build && git rev-parse HEAD > git-revision.txt"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "https://github.com/matrix-org/matrix-js-sdk"
|
"url": "https://github.com/matrix-org/matrix-js-sdk"
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-cli": "^6.18.0",
|
"babel-cli": "^6.18.0",
|
||||||
|
"babel-eslint": "^7.1.1",
|
||||||
"babel-preset-es2015": "^6.18.0",
|
"babel-preset-es2015": "^6.18.0",
|
||||||
"eslint": "^3.13.1",
|
"eslint": "^3.13.1",
|
||||||
"eslint-config-google": "^0.7.1",
|
"eslint-config-google": "^0.7.1",
|
||||||
@@ -63,6 +65,6 @@
|
|||||||
"watchify": "^3.2.1"
|
"watchify": "^3.2.1"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"olm": "https://matrix.org/packages/npm/olm/olm-2.1.0.tgz"
|
"olm": "https://matrix.org/packages/npm/olm/olm-2.2.1.tgz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ MockStorageApi.prototype = {
|
|||||||
return this.keys[index];
|
return this.keys[index];
|
||||||
},
|
},
|
||||||
_recalc: function() {
|
_recalc: function() {
|
||||||
let keys = [];
|
const keys = [];
|
||||||
for (let k in this.data) {
|
for (const k in this.data) {
|
||||||
if (!this.data.hasOwnProperty(k)) {
|
if (!this.data.hasOwnProperty(k)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../../lib/utils");
|
const utils = require("../../lib/utils");
|
||||||
let test_utils = require("../test-utils");
|
const testUtils = require("../test-utils");
|
||||||
|
|
||||||
let aliHttpBackend;
|
let aliHttpBackend;
|
||||||
let bobHttpBackend;
|
let bobHttpBackend;
|
||||||
let aliClient;
|
let aliClient;
|
||||||
let roomId = "!room:localhost";
|
const roomId = "!room:localhost";
|
||||||
let aliUserId = "@ali:localhost";
|
const aliUserId = "@ali:localhost";
|
||||||
let aliDeviceId = "zxcvb";
|
const aliDeviceId = "zxcvb";
|
||||||
let aliAccessToken = "aseukfgwef";
|
const aliAccessToken = "aseukfgwef";
|
||||||
let bobClient;
|
let bobClient;
|
||||||
let bobUserId = "@bob:localhost";
|
const bobUserId = "@bob:localhost";
|
||||||
let bobDeviceId = "bvcxz";
|
const bobDeviceId = "bvcxz";
|
||||||
let bobAccessToken = "fewgfkuesa";
|
const bobAccessToken = "fewgfkuesa";
|
||||||
let bobOneTimeKeys;
|
let bobOneTimeKeys;
|
||||||
let aliDeviceKeys;
|
let aliDeviceKeys;
|
||||||
let bobDeviceKeys;
|
let bobDeviceKeys;
|
||||||
@@ -38,8 +38,8 @@ let bobMessages;
|
|||||||
* {one_time_keys: {}, device_keys: {}}
|
* {one_time_keys: {}, device_keys: {}}
|
||||||
*/
|
*/
|
||||||
function expectKeyUpload(deviceId, httpBackend) {
|
function expectKeyUpload(deviceId, httpBackend) {
|
||||||
let uploadPath = "/keys/upload/" + deviceId;
|
const uploadPath = "/keys/upload/" + deviceId;
|
||||||
let keys = {};
|
const keys = {};
|
||||||
|
|
||||||
httpBackend.when("POST", uploadPath).respond(200, function(path, content) {
|
httpBackend.when("POST", uploadPath).respond(200, function(path, content) {
|
||||||
expect(content.one_time_keys).not.toBeDefined();
|
expect(content.one_time_keys).not.toBeDefined();
|
||||||
@@ -53,7 +53,7 @@ function expectKeyUpload(deviceId, httpBackend) {
|
|||||||
expect(content.one_time_keys).toBeDefined();
|
expect(content.one_time_keys).toBeDefined();
|
||||||
expect(content.one_time_keys).not.toEqual({});
|
expect(content.one_time_keys).not.toEqual({});
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (let key in content.one_time_keys) {
|
for (const key in content.one_time_keys) {
|
||||||
if (content.one_time_keys.hasOwnProperty(key)) {
|
if (content.one_time_keys.hasOwnProperty(key)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ function expectBobKeyUpload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function bobUploadsKeys() {
|
function bobUploadsKeys() {
|
||||||
bobClient.uploadKeys(5).catch(test_utils.failTest);
|
bobClient.uploadKeys(5).catch(testUtils.failTest);
|
||||||
return expectBobKeyUpload();
|
return expectBobKeyUpload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,11 +119,11 @@ function expectAliQueryKeys() {
|
|||||||
// can't query keys before bob has uploaded them
|
// can't query keys before bob has uploaded them
|
||||||
expect(bobDeviceKeys).toBeDefined();
|
expect(bobDeviceKeys).toBeDefined();
|
||||||
|
|
||||||
let bobKeys = {};
|
const bobKeys = {};
|
||||||
bobKeys[bobDeviceId] = bobDeviceKeys;
|
bobKeys[bobDeviceId] = bobDeviceKeys;
|
||||||
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
||||||
expect(content.device_keys[bobUserId]).toEqual({});
|
expect(content.device_keys[bobUserId]).toEqual({});
|
||||||
let result = {};
|
const result = {};
|
||||||
result[bobUserId] = bobKeys;
|
result[bobUserId] = bobKeys;
|
||||||
return {device_keys: result};
|
return {device_keys: result};
|
||||||
});
|
});
|
||||||
@@ -139,11 +139,11 @@ function expectBobQueryKeys() {
|
|||||||
// can't query keys before ali has uploaded them
|
// can't query keys before ali has uploaded them
|
||||||
expect(aliDeviceKeys).toBeDefined();
|
expect(aliDeviceKeys).toBeDefined();
|
||||||
|
|
||||||
let aliKeys = {};
|
const aliKeys = {};
|
||||||
aliKeys[aliDeviceId] = aliDeviceKeys;
|
aliKeys[aliDeviceId] = aliDeviceKeys;
|
||||||
bobHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
bobHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
||||||
expect(content.device_keys[aliUserId]).toEqual({});
|
expect(content.device_keys[aliUserId]).toEqual({});
|
||||||
let result = {};
|
const result = {};
|
||||||
result[aliUserId] = aliKeys;
|
result[aliUserId] = aliKeys;
|
||||||
return {device_keys: result};
|
return {device_keys: result};
|
||||||
});
|
});
|
||||||
@@ -160,16 +160,17 @@ function expectAliClaimKeys() {
|
|||||||
expect(bobOneTimeKeys).toBeDefined();
|
expect(bobOneTimeKeys).toBeDefined();
|
||||||
|
|
||||||
aliHttpBackend.when("POST", "/keys/claim").respond(200, function(path, content) {
|
aliHttpBackend.when("POST", "/keys/claim").respond(200, function(path, content) {
|
||||||
let claimType = content.one_time_keys[bobUserId][bobDeviceId];
|
const claimType = content.one_time_keys[bobUserId][bobDeviceId];
|
||||||
expect(claimType).toEqual("signed_curve25519");
|
expect(claimType).toEqual("signed_curve25519");
|
||||||
for (var keyId in bobOneTimeKeys) {
|
let keyId = null;
|
||||||
|
for (keyId in bobOneTimeKeys) {
|
||||||
if (bobOneTimeKeys.hasOwnProperty(keyId)) {
|
if (bobOneTimeKeys.hasOwnProperty(keyId)) {
|
||||||
if (keyId.indexOf(claimType + ":") === 0) {
|
if (keyId.indexOf(claimType + ":") === 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = {};
|
const result = {};
|
||||||
result[bobUserId] = {};
|
result[bobUserId] = {};
|
||||||
result[bobUserId][bobDeviceId] = {};
|
result[bobUserId][bobDeviceId] = {};
|
||||||
result[bobUserId][bobDeviceId][keyId] = bobOneTimeKeys[keyId];
|
result[bobUserId][bobDeviceId][keyId] = bobOneTimeKeys[keyId];
|
||||||
@@ -184,7 +185,7 @@ function aliDownloadsKeys() {
|
|||||||
// can't query keys before bob has uploaded them
|
// can't query keys before bob has uploaded them
|
||||||
expect(bobDeviceEd25519Key).toBeDefined();
|
expect(bobDeviceEd25519Key).toBeDefined();
|
||||||
|
|
||||||
let p1 = aliClient.downloadKeys([bobUserId]).then(function() {
|
const p1 = aliClient.downloadKeys([bobUserId]).then(function() {
|
||||||
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([{
|
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([{
|
||||||
id: "bvcxz",
|
id: "bvcxz",
|
||||||
key: bobDeviceEd25519Key,
|
key: bobDeviceEd25519Key,
|
||||||
@@ -193,12 +194,12 @@ function aliDownloadsKeys() {
|
|||||||
display_name: null,
|
display_name: null,
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
let p2 = expectAliQueryKeys();
|
const p2 = expectAliQueryKeys();
|
||||||
|
|
||||||
// check that the localStorage is updated as we expect (not sure this is
|
// check that the localStorage is updated as we expect (not sure this is
|
||||||
// an integration test, but meh)
|
// an integration test, but meh)
|
||||||
return q.all([p1, p2]).then(function() {
|
return q.all([p1, p2]).then(function() {
|
||||||
let devices = aliStorage.getEndToEndDevicesForUser(bobUserId);
|
const devices = aliStorage.getEndToEndDevicesForUser(bobUserId);
|
||||||
expect(devices[bobDeviceId].keys).toEqual(bobDeviceKeys.keys);
|
expect(devices[bobDeviceId].keys).toEqual(bobDeviceKeys.keys);
|
||||||
expect(devices[bobDeviceId].verified).
|
expect(devices[bobDeviceId].verified).
|
||||||
toBe(0); // DeviceVerification.UNVERIFIED
|
toBe(0); // DeviceVerification.UNVERIFIED
|
||||||
@@ -278,7 +279,7 @@ function expectAliSendMessageRequest() {
|
|||||||
return expectSendMessageRequest(aliHttpBackend).then(function(content) {
|
return expectSendMessageRequest(aliHttpBackend).then(function(content) {
|
||||||
aliMessages.push(content);
|
aliMessages.push(content);
|
||||||
expect(utils.keys(content.ciphertext)).toEqual([bobDeviceCurve25519Key]);
|
expect(utils.keys(content.ciphertext)).toEqual([bobDeviceCurve25519Key]);
|
||||||
let ciphertext = content.ciphertext[bobDeviceCurve25519Key];
|
const ciphertext = content.ciphertext[bobDeviceCurve25519Key];
|
||||||
expect(ciphertext).toBeDefined();
|
expect(ciphertext).toBeDefined();
|
||||||
return ciphertext;
|
return ciphertext;
|
||||||
});
|
});
|
||||||
@@ -292,10 +293,10 @@ function expectAliSendMessageRequest() {
|
|||||||
function expectBobSendMessageRequest() {
|
function expectBobSendMessageRequest() {
|
||||||
return expectSendMessageRequest(bobHttpBackend).then(function(content) {
|
return expectSendMessageRequest(bobHttpBackend).then(function(content) {
|
||||||
bobMessages.push(content);
|
bobMessages.push(content);
|
||||||
let aliKeyId = "curve25519:" + aliDeviceId;
|
const aliKeyId = "curve25519:" + aliDeviceId;
|
||||||
let aliDeviceCurve25519Key = aliDeviceKeys.keys[aliKeyId];
|
const aliDeviceCurve25519Key = aliDeviceKeys.keys[aliKeyId];
|
||||||
expect(utils.keys(content.ciphertext)).toEqual([aliDeviceCurve25519Key]);
|
expect(utils.keys(content.ciphertext)).toEqual([aliDeviceCurve25519Key]);
|
||||||
let ciphertext = content.ciphertext[aliDeviceCurve25519Key];
|
const ciphertext = content.ciphertext[aliDeviceCurve25519Key];
|
||||||
expect(ciphertext).toBeDefined();
|
expect(ciphertext).toBeDefined();
|
||||||
return ciphertext;
|
return ciphertext;
|
||||||
});
|
});
|
||||||
@@ -303,12 +304,12 @@ function expectBobSendMessageRequest() {
|
|||||||
|
|
||||||
function sendMessage(client) {
|
function sendMessage(client) {
|
||||||
return client.sendMessage(
|
return client.sendMessage(
|
||||||
roomId, {msgtype: "m.text", body: "Hello, World"}
|
roomId, {msgtype: "m.text", body: "Hello, World"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectSendMessageRequest(httpBackend) {
|
function expectSendMessageRequest(httpBackend) {
|
||||||
let path = "/send/m.room.encrypted/";
|
const path = "/send/m.room.encrypted/";
|
||||||
let sent;
|
let sent;
|
||||||
httpBackend.when("PUT", path).respond(200, function(path, content) {
|
httpBackend.when("PUT", path).respond(200, function(path, content) {
|
||||||
sent = content;
|
sent = content;
|
||||||
@@ -322,17 +323,17 @@ function expectSendMessageRequest(httpBackend) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function aliRecvMessage() {
|
function aliRecvMessage() {
|
||||||
let message = bobMessages.shift();
|
const message = bobMessages.shift();
|
||||||
return recvMessage(aliHttpBackend, aliClient, bobUserId, message);
|
return recvMessage(aliHttpBackend, aliClient, bobUserId, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bobRecvMessage() {
|
function bobRecvMessage() {
|
||||||
let message = aliMessages.shift();
|
const message = aliMessages.shift();
|
||||||
return recvMessage(bobHttpBackend, bobClient, aliUserId, message);
|
return recvMessage(bobHttpBackend, bobClient, aliUserId, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function recvMessage(httpBackend, client, sender, message) {
|
function recvMessage(httpBackend, client, sender, message) {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "x",
|
next_batch: "x",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
@@ -343,7 +344,7 @@ function recvMessage(httpBackend, client, sender, message) {
|
|||||||
syncData.rooms.join[roomId] = {
|
syncData.rooms.join[roomId] = {
|
||||||
timeline: {
|
timeline: {
|
||||||
events: [
|
events: [
|
||||||
test_utils.mkEvent({
|
testUtils.mkEvent({
|
||||||
type: "m.room.encrypted",
|
type: "m.room.encrypted",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
content: message,
|
content: message,
|
||||||
@@ -353,8 +354,8 @@ function recvMessage(httpBackend, client, sender, message) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
let deferred = q.defer();
|
const deferred = q.defer();
|
||||||
let onEvent = function(event) {
|
const onEvent = function(event) {
|
||||||
console.log(client.credentials.userId + " received event",
|
console.log(client.credentials.userId + " received event",
|
||||||
event);
|
event);
|
||||||
|
|
||||||
@@ -382,12 +383,12 @@ function recvMessage(httpBackend, client, sender, message) {
|
|||||||
|
|
||||||
|
|
||||||
function aliStartClient() {
|
function aliStartClient() {
|
||||||
expectAliKeyUpload().catch(test_utils.failTest);
|
expectAliKeyUpload().catch(testUtils.failTest);
|
||||||
|
|
||||||
// ali will try to query her own keys on start
|
// ali will try to query her own keys on start
|
||||||
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
||||||
expect(content.device_keys[aliUserId]).toEqual({});
|
expect(content.device_keys[aliUserId]).toEqual({});
|
||||||
let result = {};
|
const result = {};
|
||||||
result[aliUserId] = {};
|
result[aliUserId] = {};
|
||||||
return {device_keys: result};
|
return {device_keys: result};
|
||||||
});
|
});
|
||||||
@@ -399,12 +400,12 @@ function aliStartClient() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function bobStartClient() {
|
function bobStartClient() {
|
||||||
expectBobKeyUpload().catch(test_utils.failTest);
|
expectBobKeyUpload().catch(testUtils.failTest);
|
||||||
|
|
||||||
// bob will try to query his own keys on start
|
// bob will try to query his own keys on start
|
||||||
bobHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
bobHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
||||||
expect(content.device_keys[bobUserId]).toEqual({});
|
expect(content.device_keys[bobUserId]).toEqual({});
|
||||||
let result = {};
|
const result = {};
|
||||||
result[bobUserId] = {};
|
result[bobUserId] = {};
|
||||||
return {device_keys: result};
|
return {device_keys: result};
|
||||||
});
|
});
|
||||||
@@ -428,7 +429,7 @@ function startClient(httpBackend, client) {
|
|||||||
httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
|
httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
|
||||||
|
|
||||||
// send a sync response including our test room.
|
// send a sync response including our test room.
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "x",
|
next_batch: "x",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: { },
|
join: { },
|
||||||
@@ -437,11 +438,11 @@ function startClient(httpBackend, client) {
|
|||||||
syncData.rooms.join[roomId] = {
|
syncData.rooms.join[roomId] = {
|
||||||
state: {
|
state: {
|
||||||
events: [
|
events: [
|
||||||
test_utils.mkMembership({
|
testUtils.mkMembership({
|
||||||
mship: "join",
|
mship: "join",
|
||||||
user: aliUserId,
|
user: aliUserId,
|
||||||
}),
|
}),
|
||||||
test_utils.mkMembership({
|
testUtils.mkMembership({
|
||||||
mship: "join",
|
mship: "join",
|
||||||
user: bobUserId,
|
user: bobUserId,
|
||||||
}),
|
}),
|
||||||
@@ -463,9 +464,9 @@ describe("MatrixClient crypto", function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
test_utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
|
|
||||||
aliStorage = new sdk.WebStorageSessionStore(new test_utils.MockStorageApi());
|
aliStorage = new sdk.WebStorageSessionStore(new testUtils.MockStorageApi());
|
||||||
aliHttpBackend = new HttpBackend();
|
aliHttpBackend = new HttpBackend();
|
||||||
aliClient = sdk.createClient({
|
aliClient = sdk.createClient({
|
||||||
baseUrl: "http://alis.server",
|
baseUrl: "http://alis.server",
|
||||||
@@ -476,7 +477,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
request: aliHttpBackend.requestFn,
|
request: aliHttpBackend.requestFn,
|
||||||
});
|
});
|
||||||
|
|
||||||
bobStorage = new sdk.WebStorageSessionStore(new test_utils.MockStorageApi());
|
bobStorage = new sdk.WebStorageSessionStore(new testUtils.MockStorageApi());
|
||||||
bobHttpBackend = new HttpBackend();
|
bobHttpBackend = new HttpBackend();
|
||||||
bobClient = sdk.createClient({
|
bobClient = sdk.createClient({
|
||||||
baseUrl: "http://bobs.server",
|
baseUrl: "http://bobs.server",
|
||||||
@@ -509,30 +510,30 @@ describe("MatrixClient crypto", function() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let p1 = aliClient.downloadKeys(['@bob:id']);
|
const p1 = aliClient.downloadKeys(['@bob:id']);
|
||||||
let p2 = aliHttpBackend.flush('/keys/query', 1);
|
const p2 = aliHttpBackend.flush('/keys/query', 1);
|
||||||
|
|
||||||
q.all([p1, p2]).then(function() {
|
q.all([p1, p2]).then(function() {
|
||||||
let devices = aliStorage.getEndToEndDevicesForUser('@bob:id');
|
const devices = aliStorage.getEndToEndDevicesForUser('@bob:id');
|
||||||
expect(utils.keys(devices).length).toEqual(0);
|
expect(utils.keys(devices).length).toEqual(0);
|
||||||
|
|
||||||
// request again: should be no more requests
|
// request again: should be no more requests
|
||||||
return aliClient.downloadKeys(['@bob:id']);
|
return aliClient.downloadKeys(['@bob:id']);
|
||||||
}).nodeify(done);
|
}).nodeify(done);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
it("Bob uploads without one-time keys and with one-time keys", function(done) {
|
it("Bob uploads without one-time keys and with one-time keys", function(done) {
|
||||||
q()
|
q()
|
||||||
.then(bobUploadsKeys)
|
.then(bobUploadsKeys)
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali downloads Bobs keys", function(done) {
|
it("Ali downloads Bobs keys", function(done) {
|
||||||
q()
|
q()
|
||||||
.then(bobUploadsKeys)
|
.then(bobUploadsKeys)
|
||||||
.then(aliDownloadsKeys)
|
.then(aliDownloadsKeys)
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali gets keys with an invalid signature", function(done) {
|
it("Ali gets keys with an invalid signature", function(done) {
|
||||||
@@ -550,13 +551,13 @@ describe("MatrixClient crypto", function() {
|
|||||||
// should get an empty list
|
// should get an empty list
|
||||||
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([]);
|
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([]);
|
||||||
})
|
})
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali gets keys with an incorrect userId", function(done) {
|
it("Ali gets keys with an incorrect userId", function(done) {
|
||||||
let eveUserId = "@eve:localhost";
|
const eveUserId = "@eve:localhost";
|
||||||
|
|
||||||
let bobDeviceKeys = {
|
const bobDeviceKeys = {
|
||||||
algorithms: ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
|
algorithms: ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
|
||||||
device_id: 'bvcxz',
|
device_id: 'bvcxz',
|
||||||
keys: {
|
keys: {
|
||||||
@@ -572,26 +573,26 @@ describe("MatrixClient crypto", function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let bobKeys = {};
|
const bobKeys = {};
|
||||||
bobKeys[bobDeviceId] = bobDeviceKeys;
|
bobKeys[bobDeviceId] = bobDeviceKeys;
|
||||||
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
||||||
let result = {};
|
const result = {};
|
||||||
result[bobUserId] = bobKeys;
|
result[bobUserId] = bobKeys;
|
||||||
return {device_keys: result};
|
return {device_keys: result};
|
||||||
});
|
});
|
||||||
|
|
||||||
q.all(
|
q.all(
|
||||||
aliClient.downloadKeys([bobUserId, eveUserId]),
|
aliClient.downloadKeys([bobUserId, eveUserId]),
|
||||||
aliHttpBackend.flush("/keys/query", 1)
|
aliHttpBackend.flush("/keys/query", 1),
|
||||||
).then(function() {
|
).then(function() {
|
||||||
// should get an empty list
|
// should get an empty list
|
||||||
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([]);
|
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([]);
|
||||||
expect(aliClient.listDeviceKeys(eveUserId)).toEqual([]);
|
expect(aliClient.listDeviceKeys(eveUserId)).toEqual([]);
|
||||||
}).catch(test_utils.failTest).done(done);
|
}).catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali gets keys with an incorrect deviceId", function(done) {
|
it("Ali gets keys with an incorrect deviceId", function(done) {
|
||||||
let bobDeviceKeys = {
|
const bobDeviceKeys = {
|
||||||
algorithms: ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
|
algorithms: ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
|
||||||
device_id: 'bad_device',
|
device_id: 'bad_device',
|
||||||
keys: {
|
keys: {
|
||||||
@@ -607,21 +608,21 @@ describe("MatrixClient crypto", function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let bobKeys = {};
|
const bobKeys = {};
|
||||||
bobKeys[bobDeviceId] = bobDeviceKeys;
|
bobKeys[bobDeviceId] = bobDeviceKeys;
|
||||||
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
|
||||||
let result = {};
|
const result = {};
|
||||||
result[bobUserId] = bobKeys;
|
result[bobUserId] = bobKeys;
|
||||||
return {device_keys: result};
|
return {device_keys: result};
|
||||||
});
|
});
|
||||||
|
|
||||||
q.all(
|
q.all(
|
||||||
aliClient.downloadKeys([bobUserId]),
|
aliClient.downloadKeys([bobUserId]),
|
||||||
aliHttpBackend.flush("/keys/query", 1)
|
aliHttpBackend.flush("/keys/query", 1),
|
||||||
).then(function() {
|
).then(function() {
|
||||||
// should get an empty list
|
// should get an empty list
|
||||||
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([]);
|
expect(aliClient.listDeviceKeys(bobUserId)).toEqual([]);
|
||||||
}).catch(test_utils.failTest).done(done);
|
}).catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali enables encryption", function(done) {
|
it("Ali enables encryption", function(done) {
|
||||||
@@ -629,7 +630,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(bobUploadsKeys)
|
.then(bobUploadsKeys)
|
||||||
.then(aliStartClient)
|
.then(aliStartClient)
|
||||||
.then(aliEnablesEncryption)
|
.then(aliEnablesEncryption)
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali sends a message", function(done) {
|
it("Ali sends a message", function(done) {
|
||||||
@@ -638,7 +639,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(aliStartClient)
|
.then(aliStartClient)
|
||||||
.then(aliEnablesEncryption)
|
.then(aliEnablesEncryption)
|
||||||
.then(aliSendsFirstMessage)
|
.then(aliSendsFirstMessage)
|
||||||
.catch(test_utils.failTest).nodeify(done);
|
.catch(testUtils.failTest).nodeify(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Bob receives a message", function(done) {
|
it("Bob receives a message", function(done) {
|
||||||
@@ -649,7 +650,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(aliSendsFirstMessage)
|
.then(aliSendsFirstMessage)
|
||||||
.then(bobStartClient)
|
.then(bobStartClient)
|
||||||
.then(bobRecvMessage)
|
.then(bobRecvMessage)
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Bob receives a message with a bogus sender", function(done) {
|
it("Bob receives a message with a bogus sender", function(done) {
|
||||||
@@ -660,8 +661,8 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(aliSendsFirstMessage)
|
.then(aliSendsFirstMessage)
|
||||||
.then(bobStartClient)
|
.then(bobStartClient)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
let message = aliMessages.shift();
|
const message = aliMessages.shift();
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "x",
|
next_batch: "x",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
@@ -672,7 +673,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
syncData.rooms.join[roomId] = {
|
syncData.rooms.join[roomId] = {
|
||||||
timeline: {
|
timeline: {
|
||||||
events: [
|
events: [
|
||||||
test_utils.mkEvent({
|
testUtils.mkEvent({
|
||||||
type: "m.room.encrypted",
|
type: "m.room.encrypted",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
content: message,
|
content: message,
|
||||||
@@ -683,8 +684,8 @@ describe("MatrixClient crypto", function() {
|
|||||||
};
|
};
|
||||||
bobHttpBackend.when("GET", "/sync").respond(200, syncData);
|
bobHttpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
|
|
||||||
let deferred = q.defer();
|
const deferred = q.defer();
|
||||||
let onEvent = function(event) {
|
const onEvent = function(event) {
|
||||||
console.log(bobClient.credentials.userId + " received event",
|
console.log(bobClient.credentials.userId + " received event",
|
||||||
event);
|
event);
|
||||||
|
|
||||||
@@ -706,7 +707,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
bobHttpBackend.flush();
|
bobHttpBackend.flush();
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
})
|
})
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Ali blocks Bob's device", function(done) {
|
it("Ali blocks Bob's device", function(done) {
|
||||||
@@ -717,8 +718,8 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(aliDownloadsKeys)
|
.then(aliDownloadsKeys)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
aliClient.setDeviceBlocked(bobUserId, bobDeviceId, true);
|
aliClient.setDeviceBlocked(bobUserId, bobDeviceId, true);
|
||||||
let p1 = sendMessage(aliClient);
|
const p1 = sendMessage(aliClient);
|
||||||
let p2 = expectAliQueryKeys()
|
const p2 = expectAliQueryKeys()
|
||||||
.then(expectAliClaimKeys)
|
.then(expectAliClaimKeys)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return expectSendMessageRequest(aliHttpBackend);
|
return expectSendMessageRequest(aliHttpBackend);
|
||||||
@@ -727,7 +728,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
expect(sentContent.ciphertext).toEqual({});
|
expect(sentContent.ciphertext).toEqual({});
|
||||||
});
|
});
|
||||||
return q.all([p1, p2]);
|
return q.all([p1, p2]);
|
||||||
}).catch(test_utils.failTest).nodeify(done);
|
}).catch(testUtils.failTest).nodeify(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Bob receives two pre-key messages", function(done) {
|
it("Bob receives two pre-key messages", function(done) {
|
||||||
@@ -740,7 +741,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(bobRecvMessage)
|
.then(bobRecvMessage)
|
||||||
.then(aliSendsMessage)
|
.then(aliSendsMessage)
|
||||||
.then(bobRecvMessage)
|
.then(bobRecvMessage)
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Bob replies to the message", function(done) {
|
it("Bob replies to the message", function(done) {
|
||||||
@@ -755,7 +756,7 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(bobSendsReplyMessage).then(function(ciphertext) {
|
.then(bobSendsReplyMessage).then(function(ciphertext) {
|
||||||
expect(ciphertext.type).toEqual(1);
|
expect(ciphertext.type).toEqual(1);
|
||||||
}).then(aliRecvMessage)
|
}).then(aliRecvMessage)
|
||||||
.catch(test_utils.failTest).done(done);
|
.catch(testUtils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -764,11 +765,11 @@ describe("MatrixClient crypto", function() {
|
|||||||
.then(bobUploadsKeys)
|
.then(bobUploadsKeys)
|
||||||
.then(aliStartClient)
|
.then(aliStartClient)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: '2',
|
next_batch: '2',
|
||||||
to_device: {
|
to_device: {
|
||||||
events: [
|
events: [
|
||||||
test_utils.mkEvent({
|
testUtils.mkEvent({
|
||||||
content: {
|
content: {
|
||||||
device_id: 'TEST_DEVICE',
|
device_id: 'TEST_DEVICE',
|
||||||
rooms: [],
|
rooms: [],
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("MatrixClient events", function() {
|
describe("MatrixClient events", function() {
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let client;
|
let client;
|
||||||
let httpBackend;
|
let httpBackend;
|
||||||
let selfUserId = "@alice:localhost";
|
const selfUserId = "@alice:localhost";
|
||||||
let selfAccessToken = "aseukfgwef";
|
const selfAccessToken = "aseukfgwef";
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
@@ -29,7 +29,7 @@ describe("MatrixClient events", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("emissions", function() {
|
describe("emissions", function() {
|
||||||
let SYNC_DATA = {
|
const SYNC_DATA = {
|
||||||
next_batch: "s_5_3",
|
next_batch: "s_5_3",
|
||||||
presence: {
|
presence: {
|
||||||
events: [
|
events: [
|
||||||
@@ -67,7 +67,7 @@ describe("MatrixClient events", function() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let NEXT_SYNC_DATA = {
|
const NEXT_SYNC_DATA = {
|
||||||
next_batch: "e_6_7",
|
next_batch: "e_6_7",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
@@ -108,7 +108,7 @@ describe("MatrixClient events", function() {
|
|||||||
SYNC_DATA.rooms.join["!erufh:bar"].timeline.events,
|
SYNC_DATA.rooms.join["!erufh:bar"].timeline.events,
|
||||||
SYNC_DATA.rooms.join["!erufh:bar"].state.events,
|
SYNC_DATA.rooms.join["!erufh:bar"].state.events,
|
||||||
NEXT_SYNC_DATA.rooms.join["!erufh:bar"].timeline.events,
|
NEXT_SYNC_DATA.rooms.join["!erufh:bar"].timeline.events,
|
||||||
NEXT_SYNC_DATA.rooms.join["!erufh:bar"].ephemeral.events
|
NEXT_SYNC_DATA.rooms.join["!erufh:bar"].ephemeral.events,
|
||||||
);
|
);
|
||||||
|
|
||||||
client.on("event", function(event) {
|
client.on("event", function(event) {
|
||||||
@@ -121,7 +121,7 @@ describe("MatrixClient events", function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(found).toBe(
|
expect(found).toBe(
|
||||||
true, "Unexpected 'event' emitted: " + event.getType()
|
true, "Unexpected 'event' emitted: " + event.getType(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ describe("MatrixClient events", function() {
|
|||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
expect(expectedEvents.length).toEqual(
|
expect(expectedEvents.length).toEqual(
|
||||||
0, "Failed to see all events from /sync calls"
|
0, "Failed to see all events from /sync calls",
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -149,7 +149,7 @@ describe("MatrixClient events", function() {
|
|||||||
|
|
||||||
expect(event.event).toEqual(SYNC_DATA.presence.events[0]);
|
expect(event.event).toEqual(SYNC_DATA.presence.events[0]);
|
||||||
expect(user.presence).toEqual(
|
expect(user.presence).toEqual(
|
||||||
SYNC_DATA.presence.events[0].content.presence
|
SYNC_DATA.presence.events[0].content.presence,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
client.startClient();
|
client.startClient();
|
||||||
@@ -182,13 +182,13 @@ describe("MatrixClient events", function() {
|
|||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
expect(roomInvokeCount).toEqual(
|
expect(roomInvokeCount).toEqual(
|
||||||
1, "Room fired wrong number of times."
|
1, "Room fired wrong number of times.",
|
||||||
);
|
);
|
||||||
expect(roomNameInvokeCount).toEqual(
|
expect(roomNameInvokeCount).toEqual(
|
||||||
1, "Room.name fired wrong number of times."
|
1, "Room.name fired wrong number of times.",
|
||||||
);
|
);
|
||||||
expect(timelineFireCount).toEqual(
|
expect(timelineFireCount).toEqual(
|
||||||
3, "Room.timeline fired the wrong number of times"
|
3, "Room.timeline fired the wrong number of times",
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -198,7 +198,7 @@ describe("MatrixClient events", function() {
|
|||||||
httpBackend.when("GET", "/sync").respond(200, SYNC_DATA);
|
httpBackend.when("GET", "/sync").respond(200, SYNC_DATA);
|
||||||
httpBackend.when("GET", "/sync").respond(200, NEXT_SYNC_DATA);
|
httpBackend.when("GET", "/sync").respond(200, NEXT_SYNC_DATA);
|
||||||
|
|
||||||
let roomStateEventTypes = [
|
const roomStateEventTypes = [
|
||||||
"m.room.member", "m.room.create",
|
"m.room.member", "m.room.create",
|
||||||
];
|
];
|
||||||
let eventsInvokeCount = 0;
|
let eventsInvokeCount = 0;
|
||||||
@@ -206,9 +206,9 @@ describe("MatrixClient events", function() {
|
|||||||
let newMemberInvokeCount = 0;
|
let newMemberInvokeCount = 0;
|
||||||
client.on("RoomState.events", function(event, state) {
|
client.on("RoomState.events", function(event, state) {
|
||||||
eventsInvokeCount++;
|
eventsInvokeCount++;
|
||||||
let index = roomStateEventTypes.indexOf(event.getType());
|
const index = roomStateEventTypes.indexOf(event.getType());
|
||||||
expect(index).not.toEqual(
|
expect(index).not.toEqual(
|
||||||
-1, "Unexpected room state event type: " + event.getType()
|
-1, "Unexpected room state event type: " + event.getType(),
|
||||||
);
|
);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
roomStateEventTypes.splice(index, 1);
|
roomStateEventTypes.splice(index, 1);
|
||||||
@@ -231,13 +231,13 @@ describe("MatrixClient events", function() {
|
|||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
expect(membersInvokeCount).toEqual(
|
expect(membersInvokeCount).toEqual(
|
||||||
1, "RoomState.members fired wrong number of times"
|
1, "RoomState.members fired wrong number of times",
|
||||||
);
|
);
|
||||||
expect(newMemberInvokeCount).toEqual(
|
expect(newMemberInvokeCount).toEqual(
|
||||||
1, "RoomState.newMember fired wrong number of times"
|
1, "RoomState.newMember fired wrong number of times",
|
||||||
);
|
);
|
||||||
expect(eventsInvokeCount).toEqual(
|
expect(eventsInvokeCount).toEqual(
|
||||||
2, "RoomState.events fired wrong number of times"
|
2, "RoomState.events fired wrong number of times",
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -270,16 +270,16 @@ describe("MatrixClient events", function() {
|
|||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
expect(typingInvokeCount).toEqual(
|
expect(typingInvokeCount).toEqual(
|
||||||
1, "RoomMember.typing fired wrong number of times"
|
1, "RoomMember.typing fired wrong number of times",
|
||||||
);
|
);
|
||||||
expect(powerLevelInvokeCount).toEqual(
|
expect(powerLevelInvokeCount).toEqual(
|
||||||
0, "RoomMember.powerLevel fired wrong number of times"
|
0, "RoomMember.powerLevel fired wrong number of times",
|
||||||
);
|
);
|
||||||
expect(nameInvokeCount).toEqual(
|
expect(nameInvokeCount).toEqual(
|
||||||
0, "RoomMember.name fired wrong number of times"
|
0, "RoomMember.name fired wrong number of times",
|
||||||
);
|
);
|
||||||
expect(membershipInvokeCount).toEqual(
|
expect(membershipInvokeCount).toEqual(
|
||||||
1, "RoomMember.membership fired wrong number of times"
|
1, "RoomMember.membership fired wrong number of times",
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -297,7 +297,7 @@ describe("MatrixClient events", function() {
|
|||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
expect(sessionLoggedOutCount).toEqual(
|
expect(sessionLoggedOutCount).toEqual(
|
||||||
1, "Session.logged_out fired wrong number of times"
|
1, "Session.logged_out fired wrong number of times",
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
let EventTimeline = sdk.EventTimeline;
|
const EventTimeline = sdk.EventTimeline;
|
||||||
|
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let userId = "@alice:localhost";
|
const userId = "@alice:localhost";
|
||||||
let userName = "Alice";
|
const userName = "Alice";
|
||||||
let accessToken = "aseukfgwef";
|
const accessToken = "aseukfgwef";
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let otherUserId = "@bob:localhost";
|
const otherUserId = "@bob:localhost";
|
||||||
|
|
||||||
let USER_MEMBERSHIP_EVENT = utils.mkMembership({
|
const USER_MEMBERSHIP_EVENT = utils.mkMembership({
|
||||||
room: roomId, mship: "join", user: userId, name: userName,
|
room: roomId, mship: "join", user: userId, name: userName,
|
||||||
});
|
});
|
||||||
|
|
||||||
let ROOM_NAME_EVENT = utils.mkEvent({
|
const ROOM_NAME_EVENT = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: otherUserId,
|
type: "m.room.name", room: roomId, user: otherUserId,
|
||||||
content: {
|
content: {
|
||||||
name: "Old room name",
|
name: "Old room name",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let INITIAL_SYNC_DATA = {
|
const INITIAL_SYNC_DATA = {
|
||||||
next_batch: "s_5_3",
|
next_batch: "s_5_3",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
@@ -57,7 +57,7 @@ let INITIAL_SYNC_DATA = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let EVENTS = [
|
const EVENTS = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userId, msg: "we",
|
room: roomId, user: userId, msg: "we",
|
||||||
}),
|
}),
|
||||||
@@ -81,7 +81,7 @@ function startClient(httpBackend, client) {
|
|||||||
client.startClient();
|
client.startClient();
|
||||||
|
|
||||||
// set up a promise which will resolve once the client is initialised
|
// set up a promise which will resolve once the client is initialised
|
||||||
let deferred = q.defer();
|
const deferred = q.defer();
|
||||||
client.on("sync", function(state) {
|
client.on("sync", function(state) {
|
||||||
console.log("sync", state);
|
console.log("sync", state);
|
||||||
if (state != "SYNCING") {
|
if (state != "SYNCING") {
|
||||||
@@ -118,10 +118,10 @@ describe("getEventTimeline support", function() {
|
|||||||
accessToken: accessToken,
|
accessToken: accessToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
startClient(httpBackend, client
|
startClient(httpBackend, client,
|
||||||
).then(function() {
|
).then(function() {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
expect(function() {
|
expect(function() {
|
||||||
client.getEventTimeline(timelineSet, "event");
|
client.getEventTimeline(timelineSet, "event");
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
@@ -136,10 +136,10 @@ describe("getEventTimeline support", function() {
|
|||||||
timelineSupport: true,
|
timelineSupport: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
startClient(httpBackend, client
|
startClient(httpBackend, client,
|
||||||
).then(function() {
|
).then(function() {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
expect(function() {
|
expect(function() {
|
||||||
client.getEventTimeline(timelineSet, "event");
|
client.getEventTimeline(timelineSet, "event");
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
@@ -159,7 +159,7 @@ describe("getEventTimeline support", function() {
|
|||||||
});
|
});
|
||||||
let room;
|
let room;
|
||||||
|
|
||||||
startClient(httpBackend, client
|
startClient(httpBackend, client,
|
||||||
).then(function() {
|
).then(function() {
|
||||||
room = client.getRoom(roomId);
|
room = client.getRoom(roomId);
|
||||||
|
|
||||||
@@ -220,7 +220,8 @@ describe("getEventTimeline support", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("MatrixClient event timelines", function() {
|
describe("MatrixClient event timelines", function() {
|
||||||
let client, httpBackend;
|
let client = null;
|
||||||
|
let httpBackend = null;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
@@ -245,8 +246,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
describe("getEventTimeline", function() {
|
describe("getEventTimeline", function() {
|
||||||
it("should create a new timeline for new events", function(done) {
|
it("should create a new timeline for new events", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1%3Abar")
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1%3Abar")
|
||||||
.respond(200, function() {
|
.respond(200, function() {
|
||||||
return {
|
return {
|
||||||
@@ -278,8 +279,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return existing timeline for known events", function(done) {
|
it("should return existing timeline for known events", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
httpBackend.when("GET", "/sync").respond(200, {
|
httpBackend.when("GET", "/sync").respond(200, {
|
||||||
next_batch: "s_5_4",
|
next_batch: "s_5_4",
|
||||||
rooms: {
|
rooms: {
|
||||||
@@ -310,8 +311,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should update timelines where they overlap a previous /sync", function(done) {
|
it("should update timelines where they overlap a previous /sync", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
httpBackend.when("GET", "/sync").respond(200, {
|
httpBackend.when("GET", "/sync").respond(200, {
|
||||||
next_batch: "s_5_4",
|
next_batch: "s_5_4",
|
||||||
rooms: {
|
rooms: {
|
||||||
@@ -342,7 +343,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
client.on("sync", function() {
|
client.on("sync", function() {
|
||||||
client.getEventTimeline(timelineSet, EVENTS[2].event_id
|
client.getEventTimeline(timelineSet, EVENTS[2].event_id,
|
||||||
).then(function(tl) {
|
).then(function(tl) {
|
||||||
expect(tl.getEvents().length).toEqual(4);
|
expect(tl.getEvents().length).toEqual(4);
|
||||||
expect(tl.getEvents()[0].event).toEqual(EVENTS[1]);
|
expect(tl.getEvents()[0].event).toEqual(EVENTS[1]);
|
||||||
@@ -360,8 +361,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
it("should join timelines where they overlap a previous /context",
|
it("should join timelines where they overlap a previous /context",
|
||||||
function(done) {
|
function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
|
|
||||||
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned
|
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned
|
||||||
// with context which joins them all up.
|
// with context which joins them all up.
|
||||||
@@ -417,8 +418,9 @@ describe("MatrixClient event timelines", function() {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
let tl0, tl3;
|
let tl0;
|
||||||
client.getEventTimeline(timelineSet, EVENTS[0].event_id
|
let tl3;
|
||||||
|
client.getEventTimeline(timelineSet, EVENTS[0].event_id,
|
||||||
).then(function(tl) {
|
).then(function(tl) {
|
||||||
expect(tl.getEvents().length).toEqual(1);
|
expect(tl.getEvents().length).toEqual(1);
|
||||||
tl0 = tl;
|
tl0 = tl;
|
||||||
@@ -453,8 +455,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should fail gracefully if there is no event field", function(done) {
|
it("should fail gracefully if there is no event field", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned
|
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned
|
||||||
// with context which joins them all up.
|
// with context which joins them all up.
|
||||||
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1")
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1")
|
||||||
@@ -468,7 +470,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
client.getEventTimeline(timelineSet, "event1"
|
client.getEventTimeline(timelineSet, "event1",
|
||||||
).then(function(tl) {
|
).then(function(tl) {
|
||||||
// could do with a fail()
|
// could do with a fail()
|
||||||
expect(true).toBeFalsy();
|
expect(true).toBeFalsy();
|
||||||
@@ -482,8 +484,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
describe("paginateEventTimeline", function() {
|
describe("paginateEventTimeline", function() {
|
||||||
it("should allow you to paginate backwards", function(done) {
|
it("should allow you to paginate backwards", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
|
|
||||||
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
||||||
encodeURIComponent(EVENTS[0].event_id))
|
encodeURIComponent(EVENTS[0].event_id))
|
||||||
@@ -500,7 +502,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
httpBackend.when("GET", "/rooms/!foo%3Abar/messages")
|
httpBackend.when("GET", "/rooms/!foo%3Abar/messages")
|
||||||
.check(function(req) {
|
.check(function(req) {
|
||||||
let params = req.queryParams;
|
const params = req.queryParams;
|
||||||
expect(params.dir).toEqual("b");
|
expect(params.dir).toEqual("b");
|
||||||
expect(params.from).toEqual("start_token0");
|
expect(params.from).toEqual("start_token0");
|
||||||
expect(params.limit).toEqual(30);
|
expect(params.limit).toEqual(30);
|
||||||
@@ -512,7 +514,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let tl;
|
let tl;
|
||||||
client.getEventTimeline(timelineSet, EVENTS[0].event_id
|
client.getEventTimeline(timelineSet, EVENTS[0].event_id,
|
||||||
).then(function(tl0) {
|
).then(function(tl0) {
|
||||||
tl = tl0;
|
tl = tl0;
|
||||||
return client.paginateEventTimeline(tl, {backwards: true});
|
return client.paginateEventTimeline(tl, {backwards: true});
|
||||||
@@ -533,8 +535,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
|
|
||||||
it("should allow you to paginate forwards", function(done) {
|
it("should allow you to paginate forwards", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
|
|
||||||
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
||||||
encodeURIComponent(EVENTS[0].event_id))
|
encodeURIComponent(EVENTS[0].event_id))
|
||||||
@@ -551,7 +553,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
httpBackend.when("GET", "/rooms/!foo%3Abar/messages")
|
httpBackend.when("GET", "/rooms/!foo%3Abar/messages")
|
||||||
.check(function(req) {
|
.check(function(req) {
|
||||||
let params = req.queryParams;
|
const params = req.queryParams;
|
||||||
expect(params.dir).toEqual("f");
|
expect(params.dir).toEqual("f");
|
||||||
expect(params.from).toEqual("end_token0");
|
expect(params.from).toEqual("end_token0");
|
||||||
expect(params.limit).toEqual(20);
|
expect(params.limit).toEqual(20);
|
||||||
@@ -563,7 +565,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let tl;
|
let tl;
|
||||||
client.getEventTimeline(timelineSet, EVENTS[0].event_id
|
client.getEventTimeline(timelineSet, EVENTS[0].event_id,
|
||||||
).then(function(tl0) {
|
).then(function(tl0) {
|
||||||
tl = tl0;
|
tl = tl0;
|
||||||
return client.paginateEventTimeline(
|
return client.paginateEventTimeline(
|
||||||
@@ -585,8 +587,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("event timeline for sent events", function() {
|
describe("event timeline for sent events", function() {
|
||||||
let TXN_ID = "txn1";
|
const TXN_ID = "txn1";
|
||||||
let event = utils.mkMessage({
|
const event = utils.mkMessage({
|
||||||
room: roomId, user: userId, msg: "a body",
|
room: roomId, user: userId, msg: "a body",
|
||||||
});
|
});
|
||||||
event.unsigned = {transaction_id: TXN_ID};
|
event.unsigned = {transaction_id: TXN_ID};
|
||||||
@@ -616,8 +618,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should work when /send returns before /sync", function(done) {
|
it("should work when /send returns before /sync", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
|
|
||||||
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
|
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
|
||||||
expect(res.event_id).toEqual(event.event_id);
|
expect(res.event_id).toEqual(event.event_id);
|
||||||
@@ -640,8 +642,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should work when /send returns after /sync", function(done) {
|
it("should work when /send returns after /sync", function(done) {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let timelineSet = room.getTimelineSets()[0];
|
const timelineSet = room.getTimelineSets()[0];
|
||||||
|
|
||||||
// initiate the send, and set up checks to be done when it completes
|
// initiate the send, and set up checks to be done when it completes
|
||||||
// - but note that it won't complete until after the /sync does, below.
|
// - but note that it won't complete until after the /sync does, below.
|
||||||
@@ -673,10 +675,10 @@ describe("MatrixClient event timelines", function() {
|
|||||||
// https://github.com/vector-im/vector-web/issues/1389
|
// https://github.com/vector-im/vector-web/issues/1389
|
||||||
|
|
||||||
// a state event, followed by a redaction thereof
|
// a state event, followed by a redaction thereof
|
||||||
let event = utils.mkMembership({
|
const event = utils.mkMembership({
|
||||||
room: roomId, mship: "join", user: otherUserId,
|
room: roomId, mship: "join", user: otherUserId,
|
||||||
});
|
});
|
||||||
let redaction = utils.mkEvent({
|
const redaction = utils.mkEvent({
|
||||||
type: "m.room.redaction",
|
type: "m.room.redaction",
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
sender: otherUserId,
|
sender: otherUserId,
|
||||||
@@ -684,7 +686,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
});
|
});
|
||||||
redaction.redacts = event.event_id;
|
redaction.redacts = event.event_id;
|
||||||
|
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "batch1",
|
next_batch: "batch1",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -702,12 +704,12 @@ describe("MatrixClient event timelines", function() {
|
|||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
|
|
||||||
httpBackend.flush().then(function() {
|
httpBackend.flush().then(function() {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let tl = room.getLiveTimeline();
|
const tl = room.getLiveTimeline();
|
||||||
expect(tl.getEvents().length).toEqual(3);
|
expect(tl.getEvents().length).toEqual(3);
|
||||||
expect(tl.getEvents()[1].isRedacted()).toBe(true);
|
expect(tl.getEvents()[1].isRedacted()).toBe(true);
|
||||||
|
|
||||||
let sync2 = {
|
const sync2 = {
|
||||||
next_batch: "batch2",
|
next_batch: "batch2",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -728,8 +730,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
return httpBackend.flush();
|
return httpBackend.flush();
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let tl = room.getLiveTimeline();
|
const tl = room.getLiveTimeline();
|
||||||
expect(tl.getEvents().length).toEqual(1);
|
expect(tl.getEvents().length).toEqual(1);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,28 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let publicGlobals = require("../../lib/matrix");
|
const publicGlobals = require("../../lib/matrix");
|
||||||
let Room = publicGlobals.Room;
|
const Room = publicGlobals.Room;
|
||||||
let MatrixInMemoryStore = publicGlobals.MatrixInMemoryStore;
|
const MatrixInMemoryStore = publicGlobals.MatrixInMemoryStore;
|
||||||
let Filter = publicGlobals.Filter;
|
const Filter = publicGlobals.Filter;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
let MockStorageApi = require("../MockStorageApi");
|
const MockStorageApi = require("../MockStorageApi");
|
||||||
|
|
||||||
describe("MatrixClient", function() {
|
describe("MatrixClient", function() {
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let client, httpBackend, store, sessionStore;
|
let client = null;
|
||||||
let userId = "@alice:localhost";
|
let httpBackend = null;
|
||||||
let accessToken = "aseukfgwef";
|
let store = null;
|
||||||
|
let sessionStore = null;
|
||||||
|
const userId = "@alice:localhost";
|
||||||
|
const accessToken = "aseukfgwef";
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
httpBackend = new HttpBackend();
|
httpBackend = new HttpBackend();
|
||||||
store = new MatrixInMemoryStore();
|
store = new MatrixInMemoryStore();
|
||||||
|
|
||||||
let mockStorage = new MockStorageApi();
|
const mockStorage = new MockStorageApi();
|
||||||
sessionStore = new sdk.WebStorageSessionStore(mockStorage);
|
sessionStore = new sdk.WebStorageSessionStore(mockStorage);
|
||||||
|
|
||||||
sdk.request(httpBackend.requestFn);
|
sdk.request(httpBackend.requestFn);
|
||||||
@@ -38,10 +41,10 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("uploadContent", function() {
|
describe("uploadContent", function() {
|
||||||
let buf = new Buffer('hello world');
|
const buf = new Buffer('hello world');
|
||||||
it("should upload the file", function(done) {
|
it("should upload the file", function(done) {
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"POST", "/_matrix/media/v1/upload"
|
"POST", "/_matrix/media/v1/upload",
|
||||||
).check(function(req) {
|
).check(function(req) {
|
||||||
expect(req.data).toEqual(buf);
|
expect(req.data).toEqual(buf);
|
||||||
expect(req.queryParams.filename).toEqual("hi.txt");
|
expect(req.queryParams.filename).toEqual("hi.txt");
|
||||||
@@ -51,7 +54,7 @@ describe("MatrixClient", function() {
|
|||||||
expect(req.opts.timeout).toBe(undefined);
|
expect(req.opts.timeout).toBe(undefined);
|
||||||
}).respond(200, "content");
|
}).respond(200, "content");
|
||||||
|
|
||||||
let prom = client.uploadContent({
|
const prom = client.uploadContent({
|
||||||
stream: buf,
|
stream: buf,
|
||||||
name: "hi.txt",
|
name: "hi.txt",
|
||||||
type: "text/plain",
|
type: "text/plain",
|
||||||
@@ -59,7 +62,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
expect(prom).toBeDefined();
|
expect(prom).toBeDefined();
|
||||||
|
|
||||||
let uploads = client.getCurrentUploads();
|
const uploads = client.getCurrentUploads();
|
||||||
expect(uploads.length).toEqual(1);
|
expect(uploads.length).toEqual(1);
|
||||||
expect(uploads[0].promise).toBe(prom);
|
expect(uploads[0].promise).toBe(prom);
|
||||||
expect(uploads[0].loaded).toEqual(0);
|
expect(uploads[0].loaded).toEqual(0);
|
||||||
@@ -68,7 +71,7 @@ describe("MatrixClient", function() {
|
|||||||
// for backwards compatibility, we return the raw JSON
|
// for backwards compatibility, we return the raw JSON
|
||||||
expect(response).toEqual("content");
|
expect(response).toEqual("content");
|
||||||
|
|
||||||
let uploads = client.getCurrentUploads();
|
const uploads = client.getCurrentUploads();
|
||||||
expect(uploads.length).toEqual(0);
|
expect(uploads.length).toEqual(0);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
|
|
||||||
@@ -77,7 +80,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should parse the response if rawResponse=false", function(done) {
|
it("should parse the response if rawResponse=false", function(done) {
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"POST", "/_matrix/media/v1/upload"
|
"POST", "/_matrix/media/v1/upload",
|
||||||
).check(function(req) {
|
).check(function(req) {
|
||||||
expect(req.opts.json).toBeFalsy();
|
expect(req.opts.json).toBeFalsy();
|
||||||
}).respond(200, JSON.stringify({ "content_uri": "uri" }));
|
}).respond(200, JSON.stringify({ "content_uri": "uri" }));
|
||||||
@@ -98,7 +101,7 @@ describe("MatrixClient", function() {
|
|||||||
it("should parse errors into a MatrixError", function(done) {
|
it("should parse errors into a MatrixError", function(done) {
|
||||||
// opts.json is false, so request returns unparsed json.
|
// opts.json is false, so request returns unparsed json.
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"POST", "/_matrix/media/v1/upload"
|
"POST", "/_matrix/media/v1/upload",
|
||||||
).check(function(req) {
|
).check(function(req) {
|
||||||
expect(req.data).toEqual(buf);
|
expect(req.data).toEqual(buf);
|
||||||
expect(req.opts.json).toBeFalsy();
|
expect(req.opts.json).toBeFalsy();
|
||||||
@@ -123,13 +126,13 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return a promise which can be cancelled", function(done) {
|
it("should return a promise which can be cancelled", function(done) {
|
||||||
let prom = client.uploadContent({
|
const prom = client.uploadContent({
|
||||||
stream: buf,
|
stream: buf,
|
||||||
name: "hi.txt",
|
name: "hi.txt",
|
||||||
type: "text/plain",
|
type: "text/plain",
|
||||||
});
|
});
|
||||||
|
|
||||||
let uploads = client.getCurrentUploads();
|
const uploads = client.getCurrentUploads();
|
||||||
expect(uploads.length).toEqual(1);
|
expect(uploads.length).toEqual(1);
|
||||||
expect(uploads[0].promise).toBe(prom);
|
expect(uploads[0].promise).toBe(prom);
|
||||||
expect(uploads[0].loaded).toEqual(0);
|
expect(uploads[0].loaded).toEqual(0);
|
||||||
@@ -139,19 +142,19 @@ describe("MatrixClient", function() {
|
|||||||
}, function(error) {
|
}, function(error) {
|
||||||
expect(error).toEqual("aborted");
|
expect(error).toEqual("aborted");
|
||||||
|
|
||||||
let uploads = client.getCurrentUploads();
|
const uploads = client.getCurrentUploads();
|
||||||
expect(uploads.length).toEqual(0);
|
expect(uploads.length).toEqual(0);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
|
|
||||||
let r = client.cancelUpload(prom);
|
const r = client.cancelUpload(prom);
|
||||||
expect(r).toBe(true);
|
expect(r).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("joinRoom", function() {
|
describe("joinRoom", function() {
|
||||||
it("should no-op if you've already joined a room", function() {
|
it("should no-op if you've already joined a room", function() {
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let room = new Room(roomId);
|
const room = new Room(roomId);
|
||||||
room.addLiveEvents([
|
room.addLiveEvents([
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: userId, room: roomId, mship: "join", event: true,
|
user: userId, room: roomId, mship: "join", event: true,
|
||||||
@@ -164,10 +167,10 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("getFilter", function() {
|
describe("getFilter", function() {
|
||||||
let filterId = "f1lt3r1d";
|
const filterId = "f1lt3r1d";
|
||||||
|
|
||||||
it("should return a filter from the store if allowCached", function(done) {
|
it("should return a filter from the store if allowCached", function(done) {
|
||||||
let filter = Filter.fromJson(userId, filterId, {
|
const filter = Filter.fromJson(userId, filterId, {
|
||||||
event_format: "client",
|
event_format: "client",
|
||||||
});
|
});
|
||||||
store.storeFilter(filter);
|
store.storeFilter(filter);
|
||||||
@@ -180,15 +183,15 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should do an HTTP request if !allowCached even if one exists",
|
it("should do an HTTP request if !allowCached even if one exists",
|
||||||
function(done) {
|
function(done) {
|
||||||
let httpFilterDefinition = {
|
const httpFilterDefinition = {
|
||||||
event_format: "federation",
|
event_format: "federation",
|
||||||
};
|
};
|
||||||
|
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId
|
"GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId,
|
||||||
).respond(200, httpFilterDefinition);
|
).respond(200, httpFilterDefinition);
|
||||||
|
|
||||||
let storeFilter = Filter.fromJson(userId, filterId, {
|
const storeFilter = Filter.fromJson(userId, filterId, {
|
||||||
event_format: "client",
|
event_format: "client",
|
||||||
});
|
});
|
||||||
store.storeFilter(storeFilter);
|
store.storeFilter(storeFilter);
|
||||||
@@ -202,13 +205,13 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should do an HTTP request if nothing is in the cache and then store it",
|
it("should do an HTTP request if nothing is in the cache and then store it",
|
||||||
function(done) {
|
function(done) {
|
||||||
let httpFilterDefinition = {
|
const httpFilterDefinition = {
|
||||||
event_format: "federation",
|
event_format: "federation",
|
||||||
};
|
};
|
||||||
expect(store.getFilter(userId, filterId)).toBeNull();
|
expect(store.getFilter(userId, filterId)).toBeNull();
|
||||||
|
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId
|
"GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId,
|
||||||
).respond(200, httpFilterDefinition);
|
).respond(200, httpFilterDefinition);
|
||||||
client.getFilter(userId, filterId, true).done(function(gotFilter) {
|
client.getFilter(userId, filterId, true).done(function(gotFilter) {
|
||||||
expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition);
|
expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition);
|
||||||
@@ -221,17 +224,17 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("createFilter", function() {
|
describe("createFilter", function() {
|
||||||
let filterId = "f1llllllerid";
|
const filterId = "f1llllllerid";
|
||||||
|
|
||||||
it("should do an HTTP request and then store the filter", function(done) {
|
it("should do an HTTP request and then store the filter", function(done) {
|
||||||
expect(store.getFilter(userId, filterId)).toBeNull();
|
expect(store.getFilter(userId, filterId)).toBeNull();
|
||||||
|
|
||||||
let filterDefinition = {
|
const filterDefinition = {
|
||||||
event_format: "client",
|
event_format: "client",
|
||||||
};
|
};
|
||||||
|
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"POST", "/user/" + encodeURIComponent(userId) + "/filter"
|
"POST", "/user/" + encodeURIComponent(userId) + "/filter",
|
||||||
).check(function(req) {
|
).check(function(req) {
|
||||||
expect(req.data).toEqual(filterDefinition);
|
expect(req.data).toEqual(filterDefinition);
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
@@ -249,7 +252,7 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("searching", function() {
|
describe("searching", function() {
|
||||||
let response = {
|
const response = {
|
||||||
search_categories: {
|
search_categories: {
|
||||||
room_events: {
|
room_events: {
|
||||||
count: 24,
|
count: 24,
|
||||||
@@ -294,9 +297,9 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
describe("downloadKeys", function() {
|
describe("downloadKeys", function() {
|
||||||
it("should do an HTTP request and then store the keys", function(done) {
|
it("should do an HTTP request and then store the keys", function(done) {
|
||||||
let ed25519key = "7wG2lzAqbjcyEkOP7O4gU7ItYcn+chKzh5sT/5r2l78";
|
const ed25519key = "7wG2lzAqbjcyEkOP7O4gU7ItYcn+chKzh5sT/5r2l78";
|
||||||
// ed25519key = client.getDeviceEd25519Key();
|
// ed25519key = client.getDeviceEd25519Key();
|
||||||
let borisKeys = {
|
const borisKeys = {
|
||||||
dev1: {
|
dev1: {
|
||||||
algorithms: ["1"],
|
algorithms: ["1"],
|
||||||
device_id: "dev1",
|
device_id: "dev1",
|
||||||
@@ -312,7 +315,7 @@ describe("MatrixClient", function() {
|
|||||||
user_id: "boris",
|
user_id: "boris",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let chazKeys = {
|
const chazKeys = {
|
||||||
dev2: {
|
dev2: {
|
||||||
algorithms: ["2"],
|
algorithms: ["2"],
|
||||||
device_id: "dev2",
|
device_id: "dev2",
|
||||||
@@ -373,16 +376,16 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("deleteDevice", function() {
|
describe("deleteDevice", function() {
|
||||||
let auth = {a: 1};
|
const auth = {a: 1};
|
||||||
it("should pass through an auth dict", function(done) {
|
it("should pass through an auth dict", function(done) {
|
||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"DELETE", "/_matrix/client/unstable/devices/my_device"
|
"DELETE", "/_matrix/client/unstable/devices/my_device",
|
||||||
).check(function(req) {
|
).check(function(req) {
|
||||||
expect(req.data).toEqual({auth: auth});
|
expect(req.data).toEqual({auth: auth});
|
||||||
}).respond(200);
|
}).respond(200);
|
||||||
|
|
||||||
client.deleteDevice(
|
client.deleteDevice(
|
||||||
"my_device", auth
|
"my_device", auth,
|
||||||
).catch(utils.failTest).done(done);
|
).catch(utils.failTest).done(done);
|
||||||
|
|
||||||
httpBackend.flush();
|
httpBackend.flush();
|
||||||
@@ -391,7 +394,7 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function assertObjectContains(obj, expected) {
|
function assertObjectContains(obj, expected) {
|
||||||
for (let k in expected) {
|
for (const k in expected) {
|
||||||
if (expected.hasOwnProperty(k)) {
|
if (expected.hasOwnProperty(k)) {
|
||||||
expect(obj[k]).toEqual(expected[k]);
|
expect(obj[k]).toEqual(expected[k]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let MatrixClient = sdk.MatrixClient;
|
const MatrixClient = sdk.MatrixClient;
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("MatrixClient opts", function() {
|
describe("MatrixClient opts", function() {
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let client, httpBackend;
|
let client = null;
|
||||||
let userId = "@alice:localhost";
|
let httpBackend = null;
|
||||||
let userB = "@bob:localhost";
|
const userId = "@alice:localhost";
|
||||||
let accessToken = "aseukfgwef";
|
const userB = "@bob:localhost";
|
||||||
let roomId = "!foo:bar";
|
const accessToken = "aseukfgwef";
|
||||||
let syncData = {
|
const roomId = "!foo:bar";
|
||||||
|
const syncData = {
|
||||||
next_batch: "s_5_3",
|
next_batch: "s_5_3",
|
||||||
presence: {},
|
presence: {},
|
||||||
rooms: {
|
rooms: {
|
||||||
@@ -78,7 +79,7 @@ describe("MatrixClient opts", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should be able to send messages", function(done) {
|
it("should be able to send messages", function(done) {
|
||||||
let eventId = "$flibble:wibble";
|
const eventId = "$flibble:wibble";
|
||||||
httpBackend.when("PUT", "/txn1").respond(200, {
|
httpBackend.when("PUT", "/txn1").respond(200, {
|
||||||
event_id: eventId,
|
event_id: eventId,
|
||||||
});
|
});
|
||||||
@@ -90,16 +91,16 @@ describe("MatrixClient opts", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should be able to sync / get new events", function(done) {
|
it("should be able to sync / get new events", function(done) {
|
||||||
let expectedEventTypes = [ // from /initialSync
|
const expectedEventTypes = [ // from /initialSync
|
||||||
"m.room.message", "m.room.name", "m.room.member", "m.room.member",
|
"m.room.message", "m.room.name", "m.room.member", "m.room.member",
|
||||||
"m.room.create",
|
"m.room.create",
|
||||||
];
|
];
|
||||||
client.on("event", function(event) {
|
client.on("event", function(event) {
|
||||||
expect(expectedEventTypes.indexOf(event.getType())).not.toEqual(
|
expect(expectedEventTypes.indexOf(event.getType())).not.toEqual(
|
||||||
-1, "Recv unexpected event type: " + event.getType()
|
-1, "Recv unexpected event type: " + event.getType(),
|
||||||
);
|
);
|
||||||
expectedEventTypes.splice(
|
expectedEventTypes.splice(
|
||||||
expectedEventTypes.indexOf(event.getType()), 1
|
expectedEventTypes.indexOf(event.getType()), 1,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
httpBackend.when("GET", "/pushrules").respond(200, {});
|
httpBackend.when("GET", "/pushrules").respond(200, {});
|
||||||
@@ -112,7 +113,7 @@ describe("MatrixClient opts", function() {
|
|||||||
return httpBackend.flush("/sync", 1);
|
return httpBackend.flush("/sync", 1);
|
||||||
}).done(function() {
|
}).done(function() {
|
||||||
expect(expectedEventTypes.length).toEqual(
|
expect(expectedEventTypes.length).toEqual(
|
||||||
0, "Expected to see event types: " + expectedEventTypes
|
0, "Expected to see event types: " + expectedEventTypes,
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
let EventStatus = sdk.EventStatus;
|
const EventStatus = sdk.EventStatus;
|
||||||
|
|
||||||
describe("MatrixClient retrying", function() {
|
describe("MatrixClient retrying", function() {
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let client, httpBackend;
|
let client = null;
|
||||||
|
let httpBackend = null;
|
||||||
let scheduler;
|
let scheduler;
|
||||||
let userId = "@alice:localhost";
|
const userId = "@alice:localhost";
|
||||||
let accessToken = "aseukfgwef";
|
const accessToken = "aseukfgwef";
|
||||||
let roomId = "!room:here";
|
const roomId = "!room:here";
|
||||||
let room;
|
let room;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -50,7 +51,6 @@ describe("MatrixClient retrying", function() {
|
|||||||
|
|
||||||
it("should mark events as EventStatus.CANCELLED when cancelled", function(done) {
|
it("should mark events as EventStatus.CANCELLED when cancelled", function(done) {
|
||||||
// send a couple of events; the second will be queued
|
// send a couple of events; the second will be queued
|
||||||
let ev1, ev2;
|
|
||||||
client.sendMessage(roomId, "m1").then(function(ev) {
|
client.sendMessage(roomId, "m1").then(function(ev) {
|
||||||
expect(ev).toEqual(ev1);
|
expect(ev).toEqual(ev1);
|
||||||
});
|
});
|
||||||
@@ -59,10 +59,10 @@ describe("MatrixClient retrying", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// both events should be in the timeline at this point
|
// both events should be in the timeline at this point
|
||||||
let tl = room.getLiveTimeline().getEvents();
|
const tl = room.getLiveTimeline().getEvents();
|
||||||
expect(tl.length).toEqual(2);
|
expect(tl.length).toEqual(2);
|
||||||
ev1 = tl[0];
|
const ev1 = tl[0];
|
||||||
ev2 = tl[1];
|
const ev2 = tl[1];
|
||||||
|
|
||||||
expect(ev1.status).toEqual(EventStatus.SENDING);
|
expect(ev1.status).toEqual(EventStatus.SENDING);
|
||||||
expect(ev2.status).toEqual(EventStatus.SENDING);
|
expect(ev2.status).toEqual(EventStatus.SENDING);
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let EventStatus = sdk.EventStatus;
|
const EventStatus = sdk.EventStatus;
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("MatrixClient room timelines", function() {
|
describe("MatrixClient room timelines", function() {
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let client, httpBackend;
|
let client = null;
|
||||||
let userId = "@alice:localhost";
|
let httpBackend = null;
|
||||||
let userName = "Alice";
|
const userId = "@alice:localhost";
|
||||||
let accessToken = "aseukfgwef";
|
const userName = "Alice";
|
||||||
let roomId = "!foo:bar";
|
const accessToken = "aseukfgwef";
|
||||||
let otherUserId = "@bob:localhost";
|
const roomId = "!foo:bar";
|
||||||
let USER_MEMBERSHIP_EVENT = utils.mkMembership({
|
const otherUserId = "@bob:localhost";
|
||||||
|
const USER_MEMBERSHIP_EVENT = utils.mkMembership({
|
||||||
room: roomId, mship: "join", user: userId, name: userName,
|
room: roomId, mship: "join", user: userId, name: userName,
|
||||||
});
|
});
|
||||||
let ROOM_NAME_EVENT = utils.mkEvent({
|
const ROOM_NAME_EVENT = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: otherUserId,
|
type: "m.room.name", room: roomId, user: otherUserId,
|
||||||
content: {
|
content: {
|
||||||
name: "Old room name",
|
name: "Old room name",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let NEXT_SYNC_DATA;
|
let NEXT_SYNC_DATA;
|
||||||
let SYNC_DATA = {
|
const SYNC_DATA = {
|
||||||
next_batch: "s_5_3",
|
next_batch: "s_5_3",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
@@ -81,7 +82,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (e.__prev_event === undefined) {
|
if (e.__prev_event === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"setNextSyncData needs the prev state set to '__prev_event' " +
|
"setNextSyncData needs the prev state set to '__prev_event' " +
|
||||||
"for " + e.type
|
"for " + e.type,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (e.__prev_event !== null) {
|
if (e.__prev_event !== null) {
|
||||||
@@ -134,7 +135,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
expect(room.timeline.length).toEqual(1);
|
expect(room.timeline.length).toEqual(1);
|
||||||
|
|
||||||
client.sendTextMessage(roomId, "I am a fish", "txn1");
|
client.sendTextMessage(roomId, "I am a fish", "txn1");
|
||||||
@@ -143,7 +144,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
// check status
|
// check status
|
||||||
expect(room.timeline[1].status).toEqual(EventStatus.SENDING);
|
expect(room.timeline[1].status).toEqual(EventStatus.SENDING);
|
||||||
// check member
|
// check member
|
||||||
let member = room.timeline[1].sender;
|
const member = room.timeline[1].sender;
|
||||||
expect(member.userId).toEqual(userId);
|
expect(member.userId).toEqual(userId);
|
||||||
expect(member.name).toEqual(userName);
|
expect(member.name).toEqual(userName);
|
||||||
|
|
||||||
@@ -156,12 +157,12 @@ describe("MatrixClient room timelines", function() {
|
|||||||
|
|
||||||
it("should be updated correctly when the send request finishes " +
|
it("should be updated correctly when the send request finishes " +
|
||||||
"BEFORE the event comes down the event stream", function(done) {
|
"BEFORE the event comes down the event stream", function(done) {
|
||||||
let eventId = "$foo:bar";
|
const eventId = "$foo:bar";
|
||||||
httpBackend.when("PUT", "/txn1").respond(200, {
|
httpBackend.when("PUT", "/txn1").respond(200, {
|
||||||
event_id: eventId,
|
event_id: eventId,
|
||||||
});
|
});
|
||||||
|
|
||||||
let ev = utils.mkMessage({
|
const ev = utils.mkMessage({
|
||||||
body: "I am a fish", user: userId, room: roomId,
|
body: "I am a fish", user: userId, room: roomId,
|
||||||
});
|
});
|
||||||
ev.event_id = eventId;
|
ev.event_id = eventId;
|
||||||
@@ -172,7 +173,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
client.sendTextMessage(roomId, "I am a fish", "txn1").done(
|
client.sendTextMessage(roomId, "I am a fish", "txn1").done(
|
||||||
function() {
|
function() {
|
||||||
expect(room.timeline[1].getId()).toEqual(eventId);
|
expect(room.timeline[1].getId()).toEqual(eventId);
|
||||||
@@ -188,12 +189,12 @@ describe("MatrixClient room timelines", function() {
|
|||||||
|
|
||||||
it("should be updated correctly when the send request finishes " +
|
it("should be updated correctly when the send request finishes " +
|
||||||
"AFTER the event comes down the event stream", function(done) {
|
"AFTER the event comes down the event stream", function(done) {
|
||||||
let eventId = "$foo:bar";
|
const eventId = "$foo:bar";
|
||||||
httpBackend.when("PUT", "/txn1").respond(200, {
|
httpBackend.when("PUT", "/txn1").respond(200, {
|
||||||
event_id: eventId,
|
event_id: eventId,
|
||||||
});
|
});
|
||||||
|
|
||||||
let ev = utils.mkMessage({
|
const ev = utils.mkMessage({
|
||||||
body: "I am a fish", user: userId, room: roomId,
|
body: "I am a fish", user: userId, room: roomId,
|
||||||
});
|
});
|
||||||
ev.event_id = eventId;
|
ev.event_id = eventId;
|
||||||
@@ -204,8 +205,8 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let promise = client.sendTextMessage(roomId, "I am a fish", "txn1");
|
const promise = client.sendTextMessage(roomId, "I am a fish", "txn1");
|
||||||
httpBackend.flush("/sync", 1).done(function() {
|
httpBackend.flush("/sync", 1).done(function() {
|
||||||
expect(room.timeline.length).toEqual(2);
|
expect(room.timeline.length).toEqual(2);
|
||||||
httpBackend.flush("/txn1", 1);
|
httpBackend.flush("/txn1", 1);
|
||||||
@@ -222,7 +223,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
|
|
||||||
describe("paginated events", function() {
|
describe("paginated events", function() {
|
||||||
let sbEvents;
|
let sbEvents;
|
||||||
let sbEndTok = "pagin_end";
|
const sbEndTok = "pagin_end";
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
sbEvents = [];
|
sbEvents = [];
|
||||||
@@ -241,7 +242,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
expect(room.timeline.length).toEqual(1);
|
expect(room.timeline.length).toEqual(1);
|
||||||
|
|
||||||
client.scrollback(room).done(function() {
|
client.scrollback(room).done(function() {
|
||||||
@@ -267,14 +268,14 @@ describe("MatrixClient room timelines", function() {
|
|||||||
// <Bob> hello
|
// <Bob> hello
|
||||||
|
|
||||||
// make an m.room.member event for alice's join
|
// make an m.room.member event for alice's join
|
||||||
let joinMshipEvent = utils.mkMembership({
|
const joinMshipEvent = utils.mkMembership({
|
||||||
mship: "join", user: userId, room: roomId, name: "Old Alice",
|
mship: "join", user: userId, room: roomId, name: "Old Alice",
|
||||||
url: null,
|
url: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
// make an m.room.member event with prev_content for alice's nick
|
// make an m.room.member event with prev_content for alice's nick
|
||||||
// change
|
// change
|
||||||
let oldMshipEvent = utils.mkMembership({
|
const oldMshipEvent = utils.mkMembership({
|
||||||
mship: "join", user: userId, room: roomId, name: userName,
|
mship: "join", user: userId, room: roomId, name: userName,
|
||||||
url: "mxc://some/url",
|
url: "mxc://some/url",
|
||||||
});
|
});
|
||||||
@@ -301,17 +302,17 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
// sync response
|
// sync response
|
||||||
expect(room.timeline.length).toEqual(1);
|
expect(room.timeline.length).toEqual(1);
|
||||||
|
|
||||||
client.scrollback(room).done(function() {
|
client.scrollback(room).done(function() {
|
||||||
expect(room.timeline.length).toEqual(5);
|
expect(room.timeline.length).toEqual(5);
|
||||||
let joinMsg = room.timeline[0];
|
const joinMsg = room.timeline[0];
|
||||||
expect(joinMsg.sender.name).toEqual("Old Alice");
|
expect(joinMsg.sender.name).toEqual("Old Alice");
|
||||||
let oldMsg = room.timeline[1];
|
const oldMsg = room.timeline[1];
|
||||||
expect(oldMsg.sender.name).toEqual("Old Alice");
|
expect(oldMsg.sender.name).toEqual("Old Alice");
|
||||||
let newMsg = room.timeline[3];
|
const newMsg = room.timeline[3];
|
||||||
expect(newMsg.sender.name).toEqual(userName);
|
expect(newMsg.sender.name).toEqual(userName);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -337,7 +338,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
expect(room.timeline.length).toEqual(1);
|
expect(room.timeline.length).toEqual(1);
|
||||||
|
|
||||||
client.scrollback(room).done(function() {
|
client.scrollback(room).done(function() {
|
||||||
@@ -365,7 +366,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
expect(room.oldState.paginationToken).toBeDefined();
|
expect(room.oldState.paginationToken).toBeDefined();
|
||||||
|
|
||||||
client.scrollback(room, 1).done(function() {
|
client.scrollback(room, 1).done(function() {
|
||||||
@@ -383,7 +384,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
|
|
||||||
describe("new events", function() {
|
describe("new events", function() {
|
||||||
it("should be added to the right place in the timeline", function(done) {
|
it("should be added to the right place in the timeline", function(done) {
|
||||||
let eventData = [
|
const eventData = [
|
||||||
utils.mkMessage({user: userId, room: roomId}),
|
utils.mkMessage({user: userId, room: roomId}),
|
||||||
utils.mkMessage({user: userId, room: roomId}),
|
utils.mkMessage({user: userId, room: roomId}),
|
||||||
];
|
];
|
||||||
@@ -393,7 +394,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
client.on("Room.timeline", function(event, rm, toStart) {
|
client.on("Room.timeline", function(event, rm, toStart) {
|
||||||
@@ -408,10 +409,10 @@ describe("MatrixClient room timelines", function() {
|
|||||||
expect(index).toEqual(2);
|
expect(index).toEqual(2);
|
||||||
expect(room.timeline.length).toEqual(3);
|
expect(room.timeline.length).toEqual(3);
|
||||||
expect(room.timeline[2].event).toEqual(
|
expect(room.timeline[2].event).toEqual(
|
||||||
eventData[1]
|
eventData[1],
|
||||||
);
|
);
|
||||||
expect(room.timeline[1].event).toEqual(
|
expect(room.timeline[1].event).toEqual(
|
||||||
eventData[0]
|
eventData[0],
|
||||||
);
|
);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
@@ -419,7 +420,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set the right event.sender values", function(done) {
|
it("should set the right event.sender values", function(done) {
|
||||||
let eventData = [
|
const eventData = [
|
||||||
utils.mkMessage({user: userId, room: roomId}),
|
utils.mkMessage({user: userId, room: roomId}),
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: userId, room: roomId, mship: "join", name: "New Name",
|
user: userId, room: roomId, mship: "join", name: "New Name",
|
||||||
@@ -433,10 +434,10 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
httpBackend.flush("/sync", 1).then(function() {
|
httpBackend.flush("/sync", 1).then(function() {
|
||||||
let preNameEvent = room.timeline[room.timeline.length - 3];
|
const preNameEvent = room.timeline[room.timeline.length - 3];
|
||||||
let postNameEvent = room.timeline[room.timeline.length - 1];
|
const postNameEvent = room.timeline[room.timeline.length - 1];
|
||||||
expect(preNameEvent.sender.name).toEqual(userName);
|
expect(preNameEvent.sender.name).toEqual(userName);
|
||||||
expect(postNameEvent.sender.name).toEqual("New Name");
|
expect(postNameEvent.sender.name).toEqual("New Name");
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
@@ -445,7 +446,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set the right room.name", function(done) {
|
it("should set the right room.name", function(done) {
|
||||||
let secondRoomNameEvent = utils.mkEvent({
|
const secondRoomNameEvent = utils.mkEvent({
|
||||||
user: userId, room: roomId, type: "m.room.name", content: {
|
user: userId, room: roomId, type: "m.room.name", content: {
|
||||||
name: "Room 2",
|
name: "Room 2",
|
||||||
},
|
},
|
||||||
@@ -457,7 +458,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
let nameEmitCount = 0;
|
let nameEmitCount = 0;
|
||||||
client.on("Room.name", function(rm) {
|
client.on("Room.name", function(rm) {
|
||||||
nameEmitCount += 1;
|
nameEmitCount += 1;
|
||||||
@@ -467,7 +468,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
expect(nameEmitCount).toEqual(1);
|
expect(nameEmitCount).toEqual(1);
|
||||||
expect(room.name).toEqual("Room 2");
|
expect(room.name).toEqual("Room 2");
|
||||||
// do another round
|
// do another round
|
||||||
let thirdRoomNameEvent = utils.mkEvent({
|
const thirdRoomNameEvent = utils.mkEvent({
|
||||||
user: userId, room: roomId, type: "m.room.name", content: {
|
user: userId, room: roomId, type: "m.room.name", content: {
|
||||||
name: "Room 3",
|
name: "Room 3",
|
||||||
},
|
},
|
||||||
@@ -486,9 +487,9 @@ describe("MatrixClient room timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set the right room members", function(done) {
|
it("should set the right room members", function(done) {
|
||||||
let userC = "@cee:bar";
|
const userC = "@cee:bar";
|
||||||
let userD = "@dee:bar";
|
const userD = "@dee:bar";
|
||||||
let eventData = [
|
const eventData = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: userC, room: roomId, mship: "join", name: "C",
|
user: userC, room: roomId, mship: "join", name: "C",
|
||||||
}),
|
}),
|
||||||
@@ -504,16 +505,16 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
httpBackend.flush("/sync", 1).then(function() {
|
httpBackend.flush("/sync", 1).then(function() {
|
||||||
expect(room.currentState.getMembers().length).toEqual(4);
|
expect(room.currentState.getMembers().length).toEqual(4);
|
||||||
expect(room.currentState.getMember(userC).name).toEqual("C");
|
expect(room.currentState.getMember(userC).name).toEqual("C");
|
||||||
expect(room.currentState.getMember(userC).membership).toEqual(
|
expect(room.currentState.getMember(userC).membership).toEqual(
|
||||||
"join"
|
"join",
|
||||||
);
|
);
|
||||||
expect(room.currentState.getMember(userD).name).toEqual(userD);
|
expect(room.currentState.getMember(userD).name).toEqual(userD);
|
||||||
expect(room.currentState.getMember(userD).membership).toEqual(
|
expect(room.currentState.getMember(userD).membership).toEqual(
|
||||||
"invite"
|
"invite",
|
||||||
);
|
);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
@@ -523,7 +524,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
|
|
||||||
describe("gappy sync", function() {
|
describe("gappy sync", function() {
|
||||||
it("should copy the last known state to the new timeline", function(done) {
|
it("should copy the last known state to the new timeline", function(done) {
|
||||||
let eventData = [
|
const eventData = [
|
||||||
utils.mkMessage({user: userId, room: roomId}),
|
utils.mkMessage({user: userId, room: roomId}),
|
||||||
];
|
];
|
||||||
setNextSyncData(eventData);
|
setNextSyncData(eventData);
|
||||||
@@ -533,7 +534,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
|
|
||||||
httpBackend.flush("/messages", 1);
|
httpBackend.flush("/messages", 1);
|
||||||
httpBackend.flush("/sync", 1).done(function() {
|
httpBackend.flush("/sync", 1).done(function() {
|
||||||
@@ -542,11 +543,11 @@ describe("MatrixClient room timelines", function() {
|
|||||||
expect(room.currentState.getMembers().length).toEqual(2);
|
expect(room.currentState.getMembers().length).toEqual(2);
|
||||||
expect(room.currentState.getMember(userId).name).toEqual(userName);
|
expect(room.currentState.getMember(userId).name).toEqual(userName);
|
||||||
expect(room.currentState.getMember(userId).membership).toEqual(
|
expect(room.currentState.getMember(userId).membership).toEqual(
|
||||||
"join"
|
"join",
|
||||||
);
|
);
|
||||||
expect(room.currentState.getMember(otherUserId).name).toEqual("Bob");
|
expect(room.currentState.getMember(otherUserId).name).toEqual("Bob");
|
||||||
expect(room.currentState.getMember(otherUserId).membership).toEqual(
|
expect(room.currentState.getMember(otherUserId).membership).toEqual(
|
||||||
"join"
|
"join",
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -555,7 +556,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit a 'Room.timelineReset' event", function(done) {
|
it("should emit a 'Room.timelineReset' event", function(done) {
|
||||||
let eventData = [
|
const eventData = [
|
||||||
utils.mkMessage({user: userId, room: roomId}),
|
utils.mkMessage({user: userId, room: roomId}),
|
||||||
];
|
];
|
||||||
setNextSyncData(eventData);
|
setNextSyncData(eventData);
|
||||||
@@ -565,7 +566,7 @@ describe("MatrixClient room timelines", function() {
|
|||||||
if (state !== "PREPARED") {
|
if (state !== "PREPARED") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
|
|
||||||
let emitCount = 0;
|
let emitCount = 0;
|
||||||
client.on("Room.timelineReset", function(emitRoom) {
|
client.on("Room.timelineReset", function(emitRoom) {
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let HttpBackend = require("../mock-request");
|
const HttpBackend = require("../mock-request");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
let MatrixEvent = sdk.MatrixEvent;
|
const MatrixEvent = sdk.MatrixEvent;
|
||||||
let EventTimeline = sdk.EventTimeline;
|
const EventTimeline = sdk.EventTimeline;
|
||||||
|
|
||||||
describe("MatrixClient syncing", function() {
|
describe("MatrixClient syncing", function() {
|
||||||
let baseUrl = "http://localhost.or.something";
|
const baseUrl = "http://localhost.or.something";
|
||||||
let client, httpBackend;
|
let client = null;
|
||||||
let selfUserId = "@alice:localhost";
|
let httpBackend = null;
|
||||||
let selfAccessToken = "aseukfgwef";
|
const selfUserId = "@alice:localhost";
|
||||||
let otherUserId = "@bob:localhost";
|
const selfAccessToken = "aseukfgwef";
|
||||||
let userA = "@alice:bar";
|
const otherUserId = "@bob:localhost";
|
||||||
let userB = "@bob:bar";
|
const userA = "@alice:bar";
|
||||||
let userC = "@claire:bar";
|
const userB = "@bob:bar";
|
||||||
let roomOne = "!foo:localhost";
|
const userC = "@claire:bar";
|
||||||
let roomTwo = "!bar:localhost";
|
const roomOne = "!foo:localhost";
|
||||||
|
const roomTwo = "!bar:localhost";
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
@@ -36,7 +37,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("startClient", function() {
|
describe("startClient", function() {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "batch_token",
|
next_batch: "batch_token",
|
||||||
rooms: {},
|
rooms: {},
|
||||||
presence: {},
|
presence: {},
|
||||||
@@ -68,7 +69,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("resolving invites to profile info", function() {
|
describe("resolving invites to profile info", function() {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "s_5_3",
|
next_batch: "s_5_3",
|
||||||
presence: {
|
presence: {
|
||||||
events: [],
|
events: [],
|
||||||
@@ -113,7 +114,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
syncData.rooms.join[roomOne].state.events.push(
|
syncData.rooms.join[roomOne].state.events.push(
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomOne, mship: "invite", user: userC,
|
room: roomOne, mship: "invite", user: userC,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
@@ -121,7 +122,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
200, {
|
200, {
|
||||||
avatar_url: "mxc://flibble/wibble",
|
avatar_url: "mxc://flibble/wibble",
|
||||||
displayname: "The Boss",
|
displayname: "The Boss",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
client.startClient({
|
client.startClient({
|
||||||
@@ -129,10 +130,10 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let member = client.getRoom(roomOne).getMember(userC);
|
const member = client.getRoom(roomOne).getMember(userC);
|
||||||
expect(member.name).toEqual("The Boss");
|
expect(member.name).toEqual("The Boss");
|
||||||
expect(
|
expect(
|
||||||
member.getAvatarUrl("home.server.url", null, null, null, false)
|
member.getAvatarUrl("home.server.url", null, null, null, false),
|
||||||
).toBeDefined();
|
).toBeDefined();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -147,7 +148,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
syncData.rooms.join[roomOne].state.events.push(
|
syncData.rooms.join[roomOne].state.events.push(
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomOne, mship: "invite", user: userC,
|
room: roomOne, mship: "invite", user: userC,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
@@ -157,7 +158,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let member = client.getRoom(roomOne).getMember(userC);
|
const member = client.getRoom(roomOne).getMember(userC);
|
||||||
expect(member.name).toEqual("The Ghost");
|
expect(member.name).toEqual("The Ghost");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -172,7 +173,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
syncData.rooms.join[roomOne].state.events.push(
|
syncData.rooms.join[roomOne].state.events.push(
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomOne, mship: "invite", user: userC,
|
room: roomOne, mship: "invite", user: userC,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
@@ -198,7 +199,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
syncData.rooms.join[roomOne].state.events.push(
|
syncData.rooms.join[roomOne].state.events.push(
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomOne, mship: "invite", user: userC,
|
room: roomOne, mship: "invite", user: userC,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
@@ -206,10 +207,10 @@ describe("MatrixClient syncing", function() {
|
|||||||
client.startClient();
|
client.startClient();
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let member = client.getRoom(roomOne).getMember(userC);
|
const member = client.getRoom(roomOne).getMember(userC);
|
||||||
expect(member.name).toEqual(userC);
|
expect(member.name).toEqual(userC);
|
||||||
expect(
|
expect(
|
||||||
member.getAvatarUrl("home.server.url", null, null, null, false)
|
member.getAvatarUrl("home.server.url", null, null, null, false),
|
||||||
).toBeNull();
|
).toBeNull();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -217,7 +218,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("users", function() {
|
describe("users", function() {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "nb",
|
next_batch: "nb",
|
||||||
presence: {
|
presence: {
|
||||||
events: [
|
events: [
|
||||||
@@ -246,10 +247,10 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("room state", function() {
|
describe("room state", function() {
|
||||||
let msgText = "some text here";
|
const msgText = "some text here";
|
||||||
let otherDisplayName = "Bob Smith";
|
const otherDisplayName = "Bob Smith";
|
||||||
|
|
||||||
let syncData = {
|
const syncData = {
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
|
|
||||||
@@ -314,7 +315,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let nextSyncData = {
|
const nextSyncData = {
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
|
|
||||||
@@ -358,10 +359,10 @@ describe("MatrixClient syncing", function() {
|
|||||||
client.startClient();
|
client.startClient();
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let room = client.getRoom(roomOne);
|
const room = client.getRoom(roomOne);
|
||||||
// should have clobbered the name to the one from /events
|
// should have clobbered the name to the one from /events
|
||||||
expect(room.name).toEqual(
|
expect(room.name).toEqual(
|
||||||
nextSyncData.rooms.join[roomOne].state.events[0].content.name
|
nextSyncData.rooms.join[roomOne].state.events[0].content.name,
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -374,7 +375,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
client.startClient();
|
client.startClient();
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let room = client.getRoom(roomTwo);
|
const room = client.getRoom(roomTwo);
|
||||||
// should have added the message from /events
|
// should have added the message from /events
|
||||||
expect(room.timeline.length).toEqual(2);
|
expect(room.timeline.length).toEqual(2);
|
||||||
expect(room.timeline[1].getContent().body).toEqual(msgText);
|
expect(room.timeline[1].getContent().body).toEqual(msgText);
|
||||||
@@ -388,7 +389,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
|
|
||||||
client.startClient();
|
client.startClient();
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let room = client.getRoom(roomTwo);
|
const room = client.getRoom(roomTwo);
|
||||||
// should use the display name of the other person.
|
// should use the display name of the other person.
|
||||||
expect(room.name).toEqual(otherDisplayName);
|
expect(room.name).toEqual(otherDisplayName);
|
||||||
done();
|
done();
|
||||||
@@ -402,7 +403,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
client.startClient();
|
client.startClient();
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let room = client.getRoom(roomTwo);
|
const room = client.getRoom(roomTwo);
|
||||||
let member = room.getMember(otherUserId);
|
let member = room.getMember(otherUserId);
|
||||||
expect(member).toBeDefined();
|
expect(member).toBeDefined();
|
||||||
expect(member.typing).toEqual(true);
|
expect(member.typing).toEqual(true);
|
||||||
@@ -424,7 +425,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
|
|
||||||
describe("timeline", function() {
|
describe("timeline", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "batch_token",
|
next_batch: "batch_token",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -448,7 +449,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set the back-pagination token on new rooms", function(done) {
|
it("should set the back-pagination token on new rooms", function(done) {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "batch_token",
|
next_batch: "batch_token",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -468,8 +469,8 @@ describe("MatrixClient syncing", function() {
|
|||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
|
|
||||||
httpBackend.flush().then(function() {
|
httpBackend.flush().then(function() {
|
||||||
let room = client.getRoom(roomTwo);
|
const room = client.getRoom(roomTwo);
|
||||||
let tok = room.getLiveTimeline()
|
const tok = room.getLiveTimeline()
|
||||||
.getPaginationToken(EventTimeline.BACKWARDS);
|
.getPaginationToken(EventTimeline.BACKWARDS);
|
||||||
expect(tok).toEqual("roomtwotok");
|
expect(tok).toEqual("roomtwotok");
|
||||||
done();
|
done();
|
||||||
@@ -477,7 +478,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set the back-pagination token on gappy syncs", function(done) {
|
it("should set the back-pagination token on gappy syncs", function(done) {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "batch_token",
|
next_batch: "batch_token",
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -501,15 +502,15 @@ describe("MatrixClient syncing", function() {
|
|||||||
client.on("Room.timelineReset", function(room) {
|
client.on("Room.timelineReset", function(room) {
|
||||||
resetCallCount++;
|
resetCallCount++;
|
||||||
|
|
||||||
let tl = room.getLiveTimeline();
|
const tl = room.getLiveTimeline();
|
||||||
expect(tl.getEvents().length).toEqual(0);
|
expect(tl.getEvents().length).toEqual(0);
|
||||||
let tok = tl.getPaginationToken(EventTimeline.BACKWARDS);
|
const tok = tl.getPaginationToken(EventTimeline.BACKWARDS);
|
||||||
expect(tok).toEqual("newerTok");
|
expect(tok).toEqual("newerTok");
|
||||||
});
|
});
|
||||||
|
|
||||||
httpBackend.flush().then(function() {
|
httpBackend.flush().then(function() {
|
||||||
let room = client.getRoom(roomOne);
|
const room = client.getRoom(roomOne);
|
||||||
let tl = room.getLiveTimeline();
|
const tl = room.getLiveTimeline();
|
||||||
expect(tl.getEvents().length).toEqual(1);
|
expect(tl.getEvents().length).toEqual(1);
|
||||||
expect(resetCallCount).toEqual(1);
|
expect(resetCallCount).toEqual(1);
|
||||||
done();
|
done();
|
||||||
@@ -518,7 +519,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("receipts", function() {
|
describe("receipts", function() {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {
|
join: {
|
||||||
|
|
||||||
@@ -567,8 +568,8 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should sync receipts from /sync.", function(done) {
|
it("should sync receipts from /sync.", function(done) {
|
||||||
let ackEvent = syncData.rooms.join[roomOne].timeline.events[0];
|
const ackEvent = syncData.rooms.join[roomOne].timeline.events[0];
|
||||||
let receipt = {};
|
const receipt = {};
|
||||||
receipt[ackEvent.event_id] = {
|
receipt[ackEvent.event_id] = {
|
||||||
"m.read": {},
|
"m.read": {},
|
||||||
};
|
};
|
||||||
@@ -585,7 +586,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
client.startClient();
|
client.startClient();
|
||||||
|
|
||||||
httpBackend.flush().done(function() {
|
httpBackend.flush().done(function() {
|
||||||
let room = client.getRoom(roomOne);
|
const room = client.getRoom(roomOne);
|
||||||
expect(room.getReceiptsForEvent(new MatrixEvent(ackEvent))).toEqual([{
|
expect(room.getReceiptsForEvent(new MatrixEvent(ackEvent))).toEqual([{
|
||||||
type: "m.read",
|
type: "m.read",
|
||||||
userId: userC,
|
userId: userC,
|
||||||
@@ -646,7 +647,7 @@ describe("MatrixClient syncing", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set the back-pagination token on left rooms", function(done) {
|
it("should set the back-pagination token on left rooms", function(done) {
|
||||||
let syncData = {
|
const syncData = {
|
||||||
next_batch: "batch_token",
|
next_batch: "batch_token",
|
||||||
rooms: {
|
rooms: {
|
||||||
leave: {},
|
leave: {},
|
||||||
@@ -671,8 +672,8 @@ describe("MatrixClient syncing", function() {
|
|||||||
httpBackend.when("GET", "/sync").respond(200, syncData);
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
||||||
|
|
||||||
client.syncLeftRooms().then(function() {
|
client.syncLeftRooms().then(function() {
|
||||||
let room = client.getRoom(roomTwo);
|
const room = client.getRoom(roomTwo);
|
||||||
let tok = room.getLiveTimeline().getPaginationToken(
|
const tok = room.getLiveTimeline().getPaginationToken(
|
||||||
EventTimeline.BACKWARDS);
|
EventTimeline.BACKWARDS);
|
||||||
|
|
||||||
expect(tok).toEqual("pagTok");
|
expect(tok).toEqual("pagTok");
|
||||||
|
|||||||
@@ -17,19 +17,20 @@ limitations under the License.
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
let Olm = null;
|
||||||
try {
|
try {
|
||||||
var Olm = require('olm');
|
Olm = require('olm');
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
let anotherjson = require('another-json');
|
const anotherjson = require('another-json');
|
||||||
let q = require('q');
|
const q = require('q');
|
||||||
|
|
||||||
let sdk = require('../..');
|
const sdk = require('../..');
|
||||||
let utils = require('../../lib/utils');
|
const utils = require('../../lib/utils');
|
||||||
let test_utils = require('../test-utils');
|
const testUtils = require('../test-utils');
|
||||||
let MockHttpBackend = require('../mock-request');
|
const MockHttpBackend = require('../mock-request');
|
||||||
|
|
||||||
let ROOM_ID = "!room:id";
|
const ROOM_ID = "!room:id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for a MockStorageApi, MockHttpBackend and MatrixClient
|
* Wrapper for a MockStorageApi, MockHttpBackend and MatrixClient
|
||||||
@@ -43,7 +44,7 @@ function TestClient(userId, deviceId, accessToken) {
|
|||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
|
|
||||||
this.storage = new sdk.WebStorageSessionStore(new test_utils.MockStorageApi());
|
this.storage = new sdk.WebStorageSessionStore(new testUtils.MockStorageApi());
|
||||||
this.httpBackend = new MockHttpBackend();
|
this.httpBackend = new MockHttpBackend();
|
||||||
this.client = sdk.createClient({
|
this.client = sdk.createClient({
|
||||||
baseUrl: "http://test.server",
|
baseUrl: "http://test.server",
|
||||||
@@ -66,7 +67,7 @@ function TestClient(userId, deviceId, accessToken) {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
TestClient.prototype.start = function(existingDevices) {
|
TestClient.prototype.start = function(existingDevices) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
this.httpBackend.when("GET", "/pushrules").respond(200, {});
|
this.httpBackend.when("GET", "/pushrules").respond(200, {});
|
||||||
this.httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
|
this.httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
|
||||||
@@ -114,8 +115,8 @@ TestClient.prototype.stop = function() {
|
|||||||
* @return {string} base64 device key
|
* @return {string} base64 device key
|
||||||
*/
|
*/
|
||||||
TestClient.prototype.getDeviceKey = function() {
|
TestClient.prototype.getDeviceKey = function() {
|
||||||
let key_id = 'curve25519:' + this.deviceId;
|
const keyId = 'curve25519:' + this.deviceId;
|
||||||
return this.deviceKeys.keys[key_id];
|
return this.deviceKeys.keys[keyId];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -125,8 +126,8 @@ TestClient.prototype.getDeviceKey = function() {
|
|||||||
* @return {string} base64 device key
|
* @return {string} base64 device key
|
||||||
*/
|
*/
|
||||||
TestClient.prototype.getSigningKey = function() {
|
TestClient.prototype.getSigningKey = function() {
|
||||||
let key_id = 'ed25519:' + this.deviceId;
|
const keyId = 'ed25519:' + this.deviceId;
|
||||||
return this.deviceKeys.keys[key_id];
|
return this.deviceKeys.keys[keyId];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,12 +138,12 @@ TestClient.prototype.getSigningKey = function() {
|
|||||||
* @return {Olm.Session}
|
* @return {Olm.Session}
|
||||||
*/
|
*/
|
||||||
function createOlmSession(olmAccount, recipientTestClient) {
|
function createOlmSession(olmAccount, recipientTestClient) {
|
||||||
let otk_id = utils.keys(recipientTestClient.oneTimeKeys)[0];
|
const otkId = utils.keys(recipientTestClient.oneTimeKeys)[0];
|
||||||
let otk = recipientTestClient.oneTimeKeys[otk_id];
|
const otk = recipientTestClient.oneTimeKeys[otkId];
|
||||||
|
|
||||||
let session = new Olm.Session();
|
const session = new Olm.Session();
|
||||||
session.create_outbound(
|
session.create_outbound(
|
||||||
olmAccount, recipientTestClient.getDeviceKey(), otk.key
|
olmAccount, recipientTestClient.getDeviceKey(), otk.key,
|
||||||
);
|
);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
@@ -165,7 +166,7 @@ function encryptOlmEvent(opts) {
|
|||||||
expect(opts.p2pSession).toBeDefined();
|
expect(opts.p2pSession).toBeDefined();
|
||||||
expect(opts.recipient).toBeDefined();
|
expect(opts.recipient).toBeDefined();
|
||||||
|
|
||||||
let plaintext = {
|
const plaintext = {
|
||||||
content: opts.plaincontent || {},
|
content: opts.plaincontent || {},
|
||||||
recipient: opts.recipient.userId,
|
recipient: opts.recipient.userId,
|
||||||
recipient_keys: {
|
recipient_keys: {
|
||||||
@@ -175,7 +176,7 @@ function encryptOlmEvent(opts) {
|
|||||||
type: opts.plaintype || 'm.test',
|
type: opts.plaintype || 'm.test',
|
||||||
};
|
};
|
||||||
|
|
||||||
let event = {
|
const event = {
|
||||||
content: {
|
content: {
|
||||||
algorithm: 'm.olm.v1.curve25519-aes-sha2',
|
algorithm: 'm.olm.v1.curve25519-aes-sha2',
|
||||||
ciphertext: {},
|
ciphertext: {},
|
||||||
@@ -204,7 +205,7 @@ function encryptMegolmEvent(opts) {
|
|||||||
expect(opts.senderKey).toBeDefined();
|
expect(opts.senderKey).toBeDefined();
|
||||||
expect(opts.groupSession).toBeDefined();
|
expect(opts.groupSession).toBeDefined();
|
||||||
|
|
||||||
let plaintext = opts.plaintext || {};
|
const plaintext = opts.plaintext || {};
|
||||||
if (!plaintext.content) {
|
if (!plaintext.content) {
|
||||||
plaintext.content = {
|
plaintext.content = {
|
||||||
body: '42',
|
body: '42',
|
||||||
@@ -267,10 +268,10 @@ function encryptGroupSessionKey(opts) {
|
|||||||
* @return {object} event
|
* @return {object} event
|
||||||
*/
|
*/
|
||||||
function getSyncResponse(roomMembers) {
|
function getSyncResponse(roomMembers) {
|
||||||
let roomResponse = {
|
const roomResponse = {
|
||||||
state: {
|
state: {
|
||||||
events: [
|
events: [
|
||||||
test_utils.mkEvent({
|
testUtils.mkEvent({
|
||||||
type: 'm.room.encryption',
|
type: 'm.room.encryption',
|
||||||
skey: '',
|
skey: '',
|
||||||
content: {
|
content: {
|
||||||
@@ -283,14 +284,14 @@ function getSyncResponse(roomMembers) {
|
|||||||
|
|
||||||
for (let i = 0; i < roomMembers.length; i++) {
|
for (let i = 0; i < roomMembers.length; i++) {
|
||||||
roomResponse.state.events.push(
|
roomResponse.state.events.push(
|
||||||
test_utils.mkMembership({
|
testUtils.mkMembership({
|
||||||
mship: 'join',
|
mship: 'join',
|
||||||
sender: roomMembers[i],
|
sender: roomMembers[i],
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let syncResponse = {
|
const syncResponse = {
|
||||||
next_batch: 1,
|
next_batch: 1,
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -318,8 +319,8 @@ describe("megolm", function() {
|
|||||||
* @returns {Object} The fake query response
|
* @returns {Object} The fake query response
|
||||||
*/
|
*/
|
||||||
function getTestKeysQueryResponse(userId) {
|
function getTestKeysQueryResponse(userId) {
|
||||||
let testE2eKeys = JSON.parse(testOlmAccount.identity_keys());
|
const testE2eKeys = JSON.parse(testOlmAccount.identity_keys());
|
||||||
let testDeviceKeys = {
|
const testDeviceKeys = {
|
||||||
algorithms: ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
|
algorithms: ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
|
||||||
device_id: 'DEVICE_ID',
|
device_id: 'DEVICE_ID',
|
||||||
keys: {
|
keys: {
|
||||||
@@ -328,14 +329,14 @@ describe("megolm", function() {
|
|||||||
},
|
},
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
};
|
};
|
||||||
let j = anotherjson.stringify(testDeviceKeys);
|
const j = anotherjson.stringify(testDeviceKeys);
|
||||||
let sig = testOlmAccount.sign(j);
|
const sig = testOlmAccount.sign(j);
|
||||||
testDeviceKeys.signatures = {};
|
testDeviceKeys.signatures = {};
|
||||||
testDeviceKeys.signatures[userId] = {
|
testDeviceKeys.signatures[userId] = {
|
||||||
'ed25519:DEVICE_ID': sig,
|
'ed25519:DEVICE_ID': sig,
|
||||||
};
|
};
|
||||||
|
|
||||||
let queryResponse = {
|
const queryResponse = {
|
||||||
device_keys: {},
|
device_keys: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -355,22 +356,22 @@ describe("megolm", function() {
|
|||||||
*/
|
*/
|
||||||
function getTestKeysClaimResponse(userId) {
|
function getTestKeysClaimResponse(userId) {
|
||||||
testOlmAccount.generate_one_time_keys(1);
|
testOlmAccount.generate_one_time_keys(1);
|
||||||
let testOneTimeKeys = JSON.parse(testOlmAccount.one_time_keys());
|
const testOneTimeKeys = JSON.parse(testOlmAccount.one_time_keys());
|
||||||
testOlmAccount.mark_keys_as_published();
|
testOlmAccount.mark_keys_as_published();
|
||||||
|
|
||||||
let keyId = utils.keys(testOneTimeKeys.curve25519)[0];
|
const keyId = utils.keys(testOneTimeKeys.curve25519)[0];
|
||||||
let oneTimeKey = testOneTimeKeys.curve25519[keyId];
|
const oneTimeKey = testOneTimeKeys.curve25519[keyId];
|
||||||
let keyResult = {
|
const keyResult = {
|
||||||
'key': oneTimeKey,
|
'key': oneTimeKey,
|
||||||
};
|
};
|
||||||
let j = anotherjson.stringify(keyResult);
|
const j = anotherjson.stringify(keyResult);
|
||||||
let sig = testOlmAccount.sign(j);
|
const sig = testOlmAccount.sign(j);
|
||||||
keyResult.signatures = {};
|
keyResult.signatures = {};
|
||||||
keyResult.signatures[userId] = {
|
keyResult.signatures[userId] = {
|
||||||
'ed25519:DEVICE_ID': sig,
|
'ed25519:DEVICE_ID': sig,
|
||||||
};
|
};
|
||||||
|
|
||||||
let claimResponse = {one_time_keys: {}};
|
const claimResponse = {one_time_keys: {}};
|
||||||
claimResponse.one_time_keys[userId] = {
|
claimResponse.one_time_keys[userId] = {
|
||||||
'DEVICE_ID': {},
|
'DEVICE_ID': {},
|
||||||
};
|
};
|
||||||
@@ -380,15 +381,15 @@ describe("megolm", function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
test_utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
|
|
||||||
aliceTestClient = new TestClient(
|
aliceTestClient = new TestClient(
|
||||||
"@alice:localhost", "xzcvb", "akjgkrgjs"
|
"@alice:localhost", "xzcvb", "akjgkrgjs",
|
||||||
);
|
);
|
||||||
|
|
||||||
testOlmAccount = new Olm.Account();
|
testOlmAccount = new Olm.Account();
|
||||||
testOlmAccount.create();
|
testOlmAccount.create();
|
||||||
let testE2eKeys = JSON.parse(testOlmAccount.identity_keys());
|
const testE2eKeys = JSON.parse(testOlmAccount.identity_keys());
|
||||||
testSenderKey = testE2eKeys.curve25519;
|
testSenderKey = testE2eKeys.curve25519;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -398,13 +399,13 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
it("Alice receives a megolm message", function(done) {
|
it("Alice receives a megolm message", function(done) {
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
const p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||||
|
|
||||||
let groupSession = new Olm.OutboundGroupSession();
|
const groupSession = new Olm.OutboundGroupSession();
|
||||||
groupSession.create();
|
groupSession.create();
|
||||||
|
|
||||||
// make the room_key event
|
// make the room_key event
|
||||||
let roomKeyEncrypted = encryptGroupSessionKey({
|
const roomKeyEncrypted = encryptGroupSessionKey({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -413,14 +414,14 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// encrypt a message with the group session
|
// encrypt a message with the group session
|
||||||
let messageEncrypted = encryptMegolmEvent({
|
const messageEncrypted = encryptMegolmEvent({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
groupSession: groupSession,
|
groupSession: groupSession,
|
||||||
room_id: ROOM_ID,
|
room_id: ROOM_ID,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Alice gets both the events in a single sync
|
// Alice gets both the events in a single sync
|
||||||
let syncResponse = {
|
const syncResponse = {
|
||||||
next_batch: 1,
|
next_batch: 1,
|
||||||
to_device: {
|
to_device: {
|
||||||
events: [roomKeyEncrypted],
|
events: [roomKeyEncrypted],
|
||||||
@@ -438,21 +439,21 @@ describe("megolm", function() {
|
|||||||
aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse);
|
aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse);
|
||||||
return aliceTestClient.httpBackend.flush("/sync", 1);
|
return aliceTestClient.httpBackend.flush("/sync", 1);
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
let room = aliceTestClient.client.getRoom(ROOM_ID);
|
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||||
let event = room.getLiveTimeline().getEvents()[0];
|
const event = room.getLiveTimeline().getEvents()[0];
|
||||||
expect(event.getContent().body).toEqual('42');
|
expect(event.getContent().body).toEqual('42');
|
||||||
}).nodeify(done);
|
}).nodeify(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Alice gets a second room_key message", function(done) {
|
it("Alice gets a second room_key message", function(done) {
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
const p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||||
|
|
||||||
let groupSession = new Olm.OutboundGroupSession();
|
const groupSession = new Olm.OutboundGroupSession();
|
||||||
groupSession.create();
|
groupSession.create();
|
||||||
|
|
||||||
// make the room_key event
|
// make the room_key event
|
||||||
let roomKeyEncrypted1 = encryptGroupSessionKey({
|
const roomKeyEncrypted1 = encryptGroupSessionKey({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -461,7 +462,7 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// encrypt a message with the group session
|
// encrypt a message with the group session
|
||||||
let messageEncrypted = encryptMegolmEvent({
|
const messageEncrypted = encryptMegolmEvent({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
groupSession: groupSession,
|
groupSession: groupSession,
|
||||||
room_id: ROOM_ID,
|
room_id: ROOM_ID,
|
||||||
@@ -469,7 +470,7 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
// make a second room_key event now that we have advanced the group
|
// make a second room_key event now that we have advanced the group
|
||||||
// session.
|
// session.
|
||||||
let roomKeyEncrypted2 = encryptGroupSessionKey({
|
const roomKeyEncrypted2 = encryptGroupSessionKey({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -488,7 +489,7 @@ describe("megolm", function() {
|
|||||||
// on the second sync, send the advanced room key, along with the
|
// on the second sync, send the advanced room key, along with the
|
||||||
// message. This simulates the situation where Alice has been sent a
|
// message. This simulates the situation where Alice has been sent a
|
||||||
// later copy of the room key and is reloading the client.
|
// later copy of the room key and is reloading the client.
|
||||||
let syncResponse2 = {
|
const syncResponse2 = {
|
||||||
next_batch: 2,
|
next_batch: 2,
|
||||||
to_device: {
|
to_device: {
|
||||||
events: [roomKeyEncrypted2],
|
events: [roomKeyEncrypted2],
|
||||||
@@ -506,8 +507,8 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
return aliceTestClient.httpBackend.flush("/sync", 2);
|
return aliceTestClient.httpBackend.flush("/sync", 2);
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
let room = aliceTestClient.client.getRoom(ROOM_ID);
|
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||||
let event = room.getLiveTimeline().getEvents()[0];
|
const event = room.getLiveTimeline().getEvents()[0];
|
||||||
expect(event.getContent().body).toEqual('42');
|
expect(event.getContent().body).toEqual('42');
|
||||||
}).nodeify(done);
|
}).nodeify(done);
|
||||||
});
|
});
|
||||||
@@ -516,12 +517,12 @@ describe("megolm", function() {
|
|||||||
let p2pSession;
|
let p2pSession;
|
||||||
|
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let syncResponse = getSyncResponse(['@bob:xyz']);
|
const syncResponse = getSyncResponse(['@bob:xyz']);
|
||||||
|
|
||||||
// establish an olm session with alice
|
// establish an olm session with alice
|
||||||
p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||||
|
|
||||||
let olmEvent = encryptOlmEvent({
|
const olmEvent = encryptOlmEvent({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -534,15 +535,15 @@ describe("megolm", function() {
|
|||||||
}).then(function() {
|
}).then(function() {
|
||||||
let inboundGroupSession;
|
let inboundGroupSession;
|
||||||
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
||||||
200, getTestKeysQueryResponse('@bob:xyz')
|
200, getTestKeysQueryResponse('@bob:xyz'),
|
||||||
);
|
);
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/sendToDevice/m.room.encrypted/'
|
'PUT', '/sendToDevice/m.room.encrypted/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
let m = content.messages['@bob:xyz'].DEVICE_ID;
|
const m = content.messages['@bob:xyz'].DEVICE_ID;
|
||||||
let ct = m.ciphertext[testSenderKey];
|
const ct = m.ciphertext[testSenderKey];
|
||||||
let decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
const decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
||||||
|
|
||||||
expect(decrypted.type).toEqual('m.room_key');
|
expect(decrypted.type).toEqual('m.room_key');
|
||||||
inboundGroupSession = new Olm.InboundGroupSession();
|
inboundGroupSession = new Olm.InboundGroupSession();
|
||||||
@@ -551,14 +552,14 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
let ct = content.ciphertext;
|
const ct = content.ciphertext;
|
||||||
let r = inboundGroupSession.decrypt(ct);
|
const r = inboundGroupSession.decrypt(ct);
|
||||||
console.log('Decrypted received megolm message', r);
|
console.log('Decrypted received megolm message', r);
|
||||||
|
|
||||||
expect(r.message_index).toEqual(0);
|
expect(r.message_index).toEqual(0);
|
||||||
let decrypted = JSON.parse(r.plaintext);
|
const decrypted = JSON.parse(r.plaintext);
|
||||||
expect(decrypted.type).toEqual('m.room.message');
|
expect(decrypted.type).toEqual('m.room.message');
|
||||||
expect(decrypted.content.body).toEqual('test');
|
expect(decrypted.content.body).toEqual('test');
|
||||||
|
|
||||||
@@ -576,7 +577,7 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
it("Alice shouldn't do a second /query for non-e2e-capable devices", function(done) {
|
it("Alice shouldn't do a second /query for non-e2e-capable devices", function(done) {
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let syncResponse = getSyncResponse(['@bob:xyz']);
|
const syncResponse = getSyncResponse(['@bob:xyz']);
|
||||||
aliceTestClient.httpBackend.when('GET', '/sync').respond(200, syncResponse);
|
aliceTestClient.httpBackend.when('GET', '/sync').respond(200, syncResponse);
|
||||||
|
|
||||||
return aliceTestClient.httpBackend.flush('/sync', 1);
|
return aliceTestClient.httpBackend.flush('/sync', 1);
|
||||||
@@ -597,7 +598,7 @@ describe("megolm", function() {
|
|||||||
console.log("Telling alice to send a megolm message");
|
console.log("Telling alice to send a megolm message");
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, {
|
).respond(200, {
|
||||||
event_id: '$event_id',
|
event_id: '$event_id',
|
||||||
});
|
});
|
||||||
@@ -612,12 +613,12 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
it("We shouldn't attempt to send to blocked devices", function(done) {
|
it("We shouldn't attempt to send to blocked devices", function(done) {
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let syncResponse = getSyncResponse(['@bob:xyz']);
|
const syncResponse = getSyncResponse(['@bob:xyz']);
|
||||||
|
|
||||||
// establish an olm session with alice
|
// establish an olm session with alice
|
||||||
let p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
const p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||||
|
|
||||||
let olmEvent = encryptOlmEvent({
|
const olmEvent = encryptOlmEvent({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -631,7 +632,7 @@ describe("megolm", function() {
|
|||||||
console.log('Forcing alice to download our device keys');
|
console.log('Forcing alice to download our device keys');
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
||||||
200, getTestKeysQueryResponse('@bob:xyz')
|
200, getTestKeysQueryResponse('@bob:xyz'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return q.all([
|
return q.all([
|
||||||
@@ -644,7 +645,7 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
console.log('Telling alice to send a megolm message');
|
console.log('Telling alice to send a megolm message');
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, {
|
).respond(200, {
|
||||||
event_id: '$event_id',
|
event_id: '$event_id',
|
||||||
});
|
});
|
||||||
@@ -661,12 +662,12 @@ describe("megolm", function() {
|
|||||||
let megolmSessionId;
|
let megolmSessionId;
|
||||||
|
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let syncResponse = getSyncResponse(['@bob:xyz']);
|
const syncResponse = getSyncResponse(['@bob:xyz']);
|
||||||
|
|
||||||
// establish an olm session with alice
|
// establish an olm session with alice
|
||||||
p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||||
|
|
||||||
let olmEvent = encryptOlmEvent({
|
const olmEvent = encryptOlmEvent({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -680,17 +681,17 @@ describe("megolm", function() {
|
|||||||
console.log('Telling alice to send a megolm message');
|
console.log('Telling alice to send a megolm message');
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
||||||
200, getTestKeysQueryResponse('@bob:xyz')
|
200, getTestKeysQueryResponse('@bob:xyz'),
|
||||||
);
|
);
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/sendToDevice/m.room.encrypted/'
|
'PUT', '/sendToDevice/m.room.encrypted/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
console.log('sendToDevice: ', content);
|
console.log('sendToDevice: ', content);
|
||||||
let m = content.messages['@bob:xyz'].DEVICE_ID;
|
const m = content.messages['@bob:xyz'].DEVICE_ID;
|
||||||
let ct = m.ciphertext[testSenderKey];
|
const ct = m.ciphertext[testSenderKey];
|
||||||
expect(ct.type).toEqual(1); // normal message
|
expect(ct.type).toEqual(1); // normal message
|
||||||
let decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
const decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
||||||
console.log('decrypted sendToDevice:', decrypted);
|
console.log('decrypted sendToDevice:', decrypted);
|
||||||
expect(decrypted.type).toEqual('m.room_key');
|
expect(decrypted.type).toEqual('m.room_key');
|
||||||
megolmSessionId = decrypted.content.session_id;
|
megolmSessionId = decrypted.content.session_id;
|
||||||
@@ -698,7 +699,7 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
console.log('/send:', content);
|
console.log('/send:', content);
|
||||||
expect(content.session_id).toEqual(megolmSessionId);
|
expect(content.session_id).toEqual(megolmSessionId);
|
||||||
@@ -717,7 +718,7 @@ describe("megolm", function() {
|
|||||||
|
|
||||||
console.log('Telling alice to send another megolm message');
|
console.log('Telling alice to send another megolm message');
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
console.log('/send:', content);
|
console.log('/send:', content);
|
||||||
expect(content.session_id).not.toEqual(megolmSessionId);
|
expect(content.session_id).not.toEqual(megolmSessionId);
|
||||||
@@ -743,10 +744,10 @@ describe("megolm", function() {
|
|||||||
let decrypted;
|
let decrypted;
|
||||||
|
|
||||||
return aliceTestClient.start(
|
return aliceTestClient.start(
|
||||||
getTestKeysQueryResponse(aliceTestClient.userId)
|
getTestKeysQueryResponse(aliceTestClient.userId),
|
||||||
).then(function() {
|
).then(function() {
|
||||||
// an encrypted room with just alice
|
// an encrypted room with just alice
|
||||||
let syncResponse = {
|
const syncResponse = {
|
||||||
next_batch: 1,
|
next_batch: 1,
|
||||||
rooms: {
|
rooms: {
|
||||||
join: {},
|
join: {},
|
||||||
@@ -755,14 +756,14 @@ describe("megolm", function() {
|
|||||||
syncResponse.rooms.join[ROOM_ID] = {
|
syncResponse.rooms.join[ROOM_ID] = {
|
||||||
state: {
|
state: {
|
||||||
events: [
|
events: [
|
||||||
test_utils.mkEvent({
|
testUtils.mkEvent({
|
||||||
type: 'm.room.encryption',
|
type: 'm.room.encryption',
|
||||||
skey: '',
|
skey: '',
|
||||||
content: {
|
content: {
|
||||||
algorithm: 'm.megolm.v1.aes-sha2',
|
algorithm: 'm.megolm.v1.aes-sha2',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
test_utils.mkMembership({
|
testUtils.mkMembership({
|
||||||
mship: 'join',
|
mship: 'join',
|
||||||
sender: aliceTestClient.userId,
|
sender: aliceTestClient.userId,
|
||||||
}),
|
}),
|
||||||
@@ -781,16 +782,16 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/sendToDevice/m.room.encrypted/'
|
'PUT', '/sendToDevice/m.room.encrypted/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
console.log("sendToDevice: ", content);
|
console.log("sendToDevice: ", content);
|
||||||
let m = content.messages[aliceTestClient.userId].DEVICE_ID;
|
const m = content.messages[aliceTestClient.userId].DEVICE_ID;
|
||||||
let ct = m.ciphertext[testSenderKey];
|
const ct = m.ciphertext[testSenderKey];
|
||||||
expect(ct.type).toEqual(0); // pre-key message
|
expect(ct.type).toEqual(0); // pre-key message
|
||||||
|
|
||||||
p2pSession = new Olm.Session();
|
p2pSession = new Olm.Session();
|
||||||
p2pSession.create_inbound(testOlmAccount, ct.body);
|
p2pSession.create_inbound(testOlmAccount, ct.body);
|
||||||
let decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
const decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
||||||
|
|
||||||
expect(decrypted.type).toEqual('m.room_key');
|
expect(decrypted.type).toEqual('m.room_key');
|
||||||
inboundGroupSession = new Olm.InboundGroupSession();
|
inboundGroupSession = new Olm.InboundGroupSession();
|
||||||
@@ -799,10 +800,10 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
let ct = content.ciphertext;
|
const ct = content.ciphertext;
|
||||||
let r = inboundGroupSession.decrypt(ct);
|
const r = inboundGroupSession.decrypt(ct);
|
||||||
console.log('Decrypted received megolm message', r);
|
console.log('Decrypted received megolm message', r);
|
||||||
decrypted = JSON.parse(r.plaintext);
|
decrypted = JSON.parse(r.plaintext);
|
||||||
|
|
||||||
@@ -831,11 +832,11 @@ describe("megolm", function() {
|
|||||||
let sendPromise;
|
let sendPromise;
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/sendToDevice/m.room.encrypted/'
|
'PUT', '/sendToDevice/m.room.encrypted/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
let m = content.messages['@bob:xyz'].DEVICE_ID;
|
const m = content.messages['@bob:xyz'].DEVICE_ID;
|
||||||
let ct = m.ciphertext[testSenderKey];
|
const ct = m.ciphertext[testSenderKey];
|
||||||
let decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
const decrypted = JSON.parse(p2pSession.decrypt(ct.type, ct.body));
|
||||||
|
|
||||||
expect(decrypted.type).toEqual('m.room_key');
|
expect(decrypted.type).toEqual('m.room_key');
|
||||||
inboundGroupSession = new Olm.InboundGroupSession();
|
inboundGroupSession = new Olm.InboundGroupSession();
|
||||||
@@ -844,14 +845,14 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
aliceTestClient.httpBackend.when(
|
aliceTestClient.httpBackend.when(
|
||||||
'PUT', '/send/'
|
'PUT', '/send/',
|
||||||
).respond(200, function(path, content) {
|
).respond(200, function(path, content) {
|
||||||
let ct = content.ciphertext;
|
const ct = content.ciphertext;
|
||||||
let r = inboundGroupSession.decrypt(ct);
|
const r = inboundGroupSession.decrypt(ct);
|
||||||
console.log('Decrypted received megolm message', r);
|
console.log('Decrypted received megolm message', r);
|
||||||
|
|
||||||
expect(r.message_index).toEqual(0);
|
expect(r.message_index).toEqual(0);
|
||||||
let decrypted = JSON.parse(r.plaintext);
|
const decrypted = JSON.parse(r.plaintext);
|
||||||
expect(decrypted.type).toEqual('m.room.message');
|
expect(decrypted.type).toEqual('m.room.message');
|
||||||
expect(decrypted.content.body).toEqual('test');
|
expect(decrypted.content.body).toEqual('test');
|
||||||
|
|
||||||
@@ -861,12 +862,12 @@ describe("megolm", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return aliceTestClient.start().then(function() {
|
return aliceTestClient.start().then(function() {
|
||||||
let syncResponse = getSyncResponse(['@bob:xyz']);
|
const syncResponse = getSyncResponse(['@bob:xyz']);
|
||||||
|
|
||||||
// establish an olm session with alice
|
// establish an olm session with alice
|
||||||
p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||||
|
|
||||||
let olmEvent = encryptOlmEvent({
|
const olmEvent = encryptOlmEvent({
|
||||||
senderKey: testSenderKey,
|
senderKey: testSenderKey,
|
||||||
recipient: aliceTestClient,
|
recipient: aliceTestClient,
|
||||||
p2pSession: p2pSession,
|
p2pSession: p2pSession,
|
||||||
@@ -886,7 +887,7 @@ describe("megolm", function() {
|
|||||||
sendPromise = aliceTestClient.client.sendTextMessage(ROOM_ID, 'test');
|
sendPromise = aliceTestClient.client.sendTextMessage(ROOM_ID, 'test');
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
aliceTestClient.httpBackend.when('POST', '/keys/query').respond(
|
||||||
200, getTestKeysQueryResponse('@bob:xyz')
|
200, getTestKeysQueryResponse('@bob:xyz'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return aliceTestClient.httpBackend.flush();
|
return aliceTestClient.httpBackend.flush();
|
||||||
@@ -894,4 +895,89 @@ describe("megolm", function() {
|
|||||||
return q.all([downloadPromise, sendPromise]);
|
return q.all([downloadPromise, sendPromise]);
|
||||||
}).nodeify(done);
|
}).nodeify(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("Alice exports megolm keys and imports them to a new device", function(done) {
|
||||||
|
let messageEncrypted;
|
||||||
|
|
||||||
|
return aliceTestClient.start().then(() => {
|
||||||
|
const p2pSession = createOlmSession(
|
||||||
|
testOlmAccount, aliceTestClient,
|
||||||
|
);
|
||||||
|
|
||||||
|
const groupSession = new Olm.OutboundGroupSession();
|
||||||
|
groupSession.create();
|
||||||
|
|
||||||
|
// make the room_key event
|
||||||
|
const roomKeyEncrypted = encryptGroupSessionKey({
|
||||||
|
senderKey: testSenderKey,
|
||||||
|
recipient: aliceTestClient,
|
||||||
|
p2pSession: p2pSession,
|
||||||
|
groupSession: groupSession,
|
||||||
|
room_id: ROOM_ID,
|
||||||
|
});
|
||||||
|
|
||||||
|
// encrypt a message with the group session
|
||||||
|
messageEncrypted = encryptMegolmEvent({
|
||||||
|
senderKey: testSenderKey,
|
||||||
|
groupSession: groupSession,
|
||||||
|
room_id: ROOM_ID,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Alice gets both the events in a single sync
|
||||||
|
const syncResponse = {
|
||||||
|
next_batch: 1,
|
||||||
|
to_device: {
|
||||||
|
events: [roomKeyEncrypted],
|
||||||
|
},
|
||||||
|
rooms: {
|
||||||
|
join: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
syncResponse.rooms.join[ROOM_ID] = {
|
||||||
|
timeline: {
|
||||||
|
events: [messageEncrypted],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse);
|
||||||
|
return aliceTestClient.httpBackend.flush("/sync", 1);
|
||||||
|
}).then(function() {
|
||||||
|
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||||
|
const event = room.getLiveTimeline().getEvents()[0];
|
||||||
|
expect(event.getContent().body).toEqual('42');
|
||||||
|
|
||||||
|
return aliceTestClient.client.exportRoomKeys();
|
||||||
|
}).then(function(exported) {
|
||||||
|
// start a new client
|
||||||
|
aliceTestClient.stop();
|
||||||
|
|
||||||
|
aliceTestClient = new TestClient(
|
||||||
|
"@alice:localhost", "device2", "access_token2",
|
||||||
|
);
|
||||||
|
|
||||||
|
aliceTestClient.client.importRoomKeys(exported);
|
||||||
|
|
||||||
|
return aliceTestClient.start();
|
||||||
|
}).then(function() {
|
||||||
|
const syncResponse = {
|
||||||
|
next_batch: 1,
|
||||||
|
rooms: {
|
||||||
|
join: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
syncResponse.rooms.join[ROOM_ID] = {
|
||||||
|
timeline: {
|
||||||
|
events: [messageEncrypted],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse);
|
||||||
|
return aliceTestClient.httpBackend.flush("/sync", 1);
|
||||||
|
}).then(function() {
|
||||||
|
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||||
|
const event = room.getLiveTimeline().getEvents()[0];
|
||||||
|
expect(event.getContent().body).toEqual('42');
|
||||||
|
}).nodeify(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a mock HTTP backend, heavily inspired by Angular.js.
|
* Construct a mock HTTP backend, heavily inspired by Angular.js.
|
||||||
@@ -8,15 +8,15 @@ let q = require("q");
|
|||||||
function HttpBackend() {
|
function HttpBackend() {
|
||||||
this.requests = [];
|
this.requests = [];
|
||||||
this.expectedRequests = [];
|
this.expectedRequests = [];
|
||||||
let self = this;
|
const self = this;
|
||||||
// the request function dependency that the SDK needs.
|
// the request function dependency that the SDK needs.
|
||||||
this.requestFn = function(opts, callback) {
|
this.requestFn = function(opts, callback) {
|
||||||
let req = new Request(opts, callback);
|
const req = new Request(opts, callback);
|
||||||
console.log("HTTP backend received request: %s", req);
|
console.log("HTTP backend received request: %s", req);
|
||||||
self.requests.push(req);
|
self.requests.push(req);
|
||||||
|
|
||||||
let abort = function() {
|
const abort = function() {
|
||||||
let idx = self.requests.indexOf(req);
|
const idx = self.requests.indexOf(req);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
console.log("Aborting HTTP request: %s %s", opts.method,
|
console.log("Aborting HTTP request: %s %s", opts.method,
|
||||||
opts.uri);
|
opts.uri);
|
||||||
@@ -38,18 +38,18 @@ HttpBackend.prototype = {
|
|||||||
* @return {Promise} resolved when there is nothing left to flush.
|
* @return {Promise} resolved when there is nothing left to flush.
|
||||||
*/
|
*/
|
||||||
flush: function(path, numToFlush) {
|
flush: function(path, numToFlush) {
|
||||||
let defer = q.defer();
|
const defer = q.defer();
|
||||||
let self = this;
|
const self = this;
|
||||||
let flushed = 0;
|
let flushed = 0;
|
||||||
let triedWaiting = false;
|
let triedWaiting = false;
|
||||||
console.log(
|
console.log(
|
||||||
"HTTP backend flushing... (path=%s numToFlush=%s)", path, numToFlush
|
"HTTP backend flushing... (path=%s numToFlush=%s)", path, numToFlush,
|
||||||
);
|
);
|
||||||
let tryFlush = function() {
|
const tryFlush = function() {
|
||||||
// if there's more real requests and more expected requests, flush 'em.
|
// if there's more real requests and more expected requests, flush 'em.
|
||||||
console.log(
|
console.log(
|
||||||
" trying to flush queue => reqs=%s expected=%s [%s]",
|
" trying to flush queue => reqs=%s expected=%s [%s]",
|
||||||
self.requests.length, self.expectedRequests.length, path
|
self.requests.length, self.expectedRequests.length, path,
|
||||||
);
|
);
|
||||||
if (self._takeFromQueue(path)) {
|
if (self._takeFromQueue(path)) {
|
||||||
// try again on the next tick.
|
// try again on the next tick.
|
||||||
@@ -84,8 +84,11 @@ HttpBackend.prototype = {
|
|||||||
*/
|
*/
|
||||||
_takeFromQueue: function(path) {
|
_takeFromQueue: function(path) {
|
||||||
let req = null;
|
let req = null;
|
||||||
let i, j;
|
let i;
|
||||||
let matchingReq, expectedReq, testResponse = null;
|
let j;
|
||||||
|
let matchingReq = null;
|
||||||
|
let expectedReq = null;
|
||||||
|
let testResponse = null;
|
||||||
for (i = 0; i < this.requests.length; i++) {
|
for (i = 0; i < this.requests.length; i++) {
|
||||||
req = this.requests[i];
|
req = this.requests[i];
|
||||||
for (j = 0; j < this.expectedRequests.length; j++) {
|
for (j = 0; j < this.expectedRequests.length; j++) {
|
||||||
@@ -119,7 +122,7 @@ HttpBackend.prototype = {
|
|||||||
body = body(req.path, req.data);
|
body = body(req.path, req.data);
|
||||||
}
|
}
|
||||||
req.callback(
|
req.callback(
|
||||||
testResponse.err, testResponse.response, body
|
testResponse.err, testResponse.response, body,
|
||||||
);
|
);
|
||||||
matchingReq = null;
|
matchingReq = null;
|
||||||
}
|
}
|
||||||
@@ -134,10 +137,10 @@ HttpBackend.prototype = {
|
|||||||
* Makes sure that the SDK hasn't sent any more requests to the backend.
|
* Makes sure that the SDK hasn't sent any more requests to the backend.
|
||||||
*/
|
*/
|
||||||
verifyNoOutstandingRequests: function() {
|
verifyNoOutstandingRequests: function() {
|
||||||
let firstOutstandingReq = this.requests[0] || {};
|
const firstOutstandingReq = this.requests[0] || {};
|
||||||
expect(this.requests.length).toEqual(0,
|
expect(this.requests.length).toEqual(0,
|
||||||
"Expected no more HTTP requests but received request to " +
|
"Expected no more HTTP requests but received request to " +
|
||||||
firstOutstandingReq.path
|
firstOutstandingReq.path,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -145,9 +148,9 @@ HttpBackend.prototype = {
|
|||||||
* Makes sure that the test doesn't have any unresolved requests.
|
* Makes sure that the test doesn't have any unresolved requests.
|
||||||
*/
|
*/
|
||||||
verifyNoOutstandingExpectation: function() {
|
verifyNoOutstandingExpectation: function() {
|
||||||
let firstOutstandingExpectation = this.expectedRequests[0] || {};
|
const firstOutstandingExpectation = this.expectedRequests[0] || {};
|
||||||
expect(this.expectedRequests.length).toEqual(0,
|
expect(this.expectedRequests.length).toEqual(0,
|
||||||
"Expected to see HTTP request for " + firstOutstandingExpectation.path
|
"Expected to see HTTP request for " + firstOutstandingExpectation.path,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -159,7 +162,7 @@ HttpBackend.prototype = {
|
|||||||
* @return {Request} An expected request.
|
* @return {Request} An expected request.
|
||||||
*/
|
*/
|
||||||
when: function(method, path, data) {
|
when: function(method, path, data) {
|
||||||
let pendingReq = new ExpectedRequest(method, path, data);
|
const pendingReq = new ExpectedRequest(method, path, data);
|
||||||
this.expectedRequests.push(pendingReq);
|
this.expectedRequests.push(pendingReq);
|
||||||
return pendingReq;
|
return pendingReq;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("..");
|
const sdk = require("..");
|
||||||
let MatrixEvent = sdk.MatrixEvent;
|
const MatrixEvent = sdk.MatrixEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform common actions before each test case, e.g. printing the test case
|
* Perform common actions before each test case, e.g. printing the test case
|
||||||
@@ -8,7 +8,7 @@ let MatrixEvent = sdk.MatrixEvent;
|
|||||||
* @param {TestCase} testCase The test case that is about to be run.
|
* @param {TestCase} testCase The test case that is about to be run.
|
||||||
*/
|
*/
|
||||||
module.exports.beforeEach = function(testCase) {
|
module.exports.beforeEach = function(testCase) {
|
||||||
let desc = testCase.suite.description + " : " + testCase.description;
|
const desc = testCase.suite.description + " : " + testCase.description;
|
||||||
console.log(desc);
|
console.log(desc);
|
||||||
console.log(new Array(1 + desc.length).join("="));
|
console.log(new Array(1 + desc.length).join("="));
|
||||||
};
|
};
|
||||||
@@ -22,13 +22,13 @@ module.exports.beforeEach = function(testCase) {
|
|||||||
module.exports.mock = function(constr, name) {
|
module.exports.mock = function(constr, name) {
|
||||||
// By Tim Buschtöns
|
// By Tim Buschtöns
|
||||||
// http://eclipsesource.com/blogs/2014/03/27/mocks-in-jasmine-tests/
|
// http://eclipsesource.com/blogs/2014/03/27/mocks-in-jasmine-tests/
|
||||||
let HelperConstr = new Function(); // jshint ignore:line
|
const HelperConstr = new Function(); // jshint ignore:line
|
||||||
HelperConstr.prototype = constr.prototype;
|
HelperConstr.prototype = constr.prototype;
|
||||||
let result = new HelperConstr();
|
const result = new HelperConstr();
|
||||||
result.jasmineToString = function() {
|
result.jasmineToString = function() {
|
||||||
return "mock" + (name ? " of " + name : "");
|
return "mock" + (name ? " of " + name : "");
|
||||||
};
|
};
|
||||||
for (let key in constr.prototype) { // eslint-disable-line guard-for-in
|
for (const key in constr.prototype) { // eslint-disable-line guard-for-in
|
||||||
try {
|
try {
|
||||||
if (constr.prototype[key] instanceof Function) {
|
if (constr.prototype[key] instanceof Function) {
|
||||||
result[key] = jasmine.createSpy((name || "mock") + '.' + key);
|
result[key] = jasmine.createSpy((name || "mock") + '.' + key);
|
||||||
@@ -57,7 +57,7 @@ module.exports.mkEvent = function(opts) {
|
|||||||
if (!opts.type || !opts.content) {
|
if (!opts.type || !opts.content) {
|
||||||
throw new Error("Missing .type or .content =>" + JSON.stringify(opts));
|
throw new Error("Missing .type or .content =>" + JSON.stringify(opts));
|
||||||
}
|
}
|
||||||
let event = {
|
const event = {
|
||||||
type: opts.type,
|
type: opts.type,
|
||||||
room_id: opts.room,
|
room_id: opts.room,
|
||||||
sender: opts.sender || opts.user, // opts.user for backwards-compat
|
sender: opts.sender || opts.user, // opts.user for backwards-compat
|
||||||
@@ -83,7 +83,7 @@ module.exports.mkPresence = function(opts) {
|
|||||||
if (!opts.user) {
|
if (!opts.user) {
|
||||||
throw new Error("Missing user");
|
throw new Error("Missing user");
|
||||||
}
|
}
|
||||||
let event = {
|
const event = {
|
||||||
event_id: "$" + Math.random() + "-" + Math.random(),
|
event_id: "$" + Math.random() + "-" + Math.random(),
|
||||||
type: "m.presence",
|
type: "m.presence",
|
||||||
sender: opts.sender || opts.user, // opts.user for backwards-compat
|
sender: opts.sender || opts.user, // opts.user for backwards-compat
|
||||||
@@ -193,6 +193,12 @@ module.exports.MockStorageApi = function() {
|
|||||||
this.data = {};
|
this.data = {};
|
||||||
};
|
};
|
||||||
module.exports.MockStorageApi.prototype = {
|
module.exports.MockStorageApi.prototype = {
|
||||||
|
get length() {
|
||||||
|
return Object.keys(this.data).length;
|
||||||
|
},
|
||||||
|
key: function(i) {
|
||||||
|
return Object.keys(this.data)[i];
|
||||||
|
},
|
||||||
setItem: function(k, v) {
|
setItem: function(k, v) {
|
||||||
this.data[k] = v;
|
this.data[k] = v;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let ContentRepo = require("../../lib/content-repo");
|
const ContentRepo = require("../../lib/content-repo");
|
||||||
let testUtils = require("../test-utils");
|
const testUtils = require("../test-utils");
|
||||||
|
|
||||||
describe("ContentRepo", function() {
|
describe("ContentRepo", function() {
|
||||||
let baseUrl = "https://my.home.server";
|
const baseUrl = "https://my.home.server";
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
@@ -11,24 +11,24 @@ describe("ContentRepo", function() {
|
|||||||
|
|
||||||
describe("getHttpUriForMxc", function() {
|
describe("getHttpUriForMxc", function() {
|
||||||
it("should do nothing to HTTP URLs when allowing direct links", function() {
|
it("should do nothing to HTTP URLs when allowing direct links", function() {
|
||||||
let httpUrl = "http://example.com/image.jpeg";
|
const httpUrl = "http://example.com/image.jpeg";
|
||||||
expect(
|
expect(
|
||||||
ContentRepo.getHttpUriForMxc(
|
ContentRepo.getHttpUriForMxc(
|
||||||
baseUrl, httpUrl, undefined, undefined, undefined, true
|
baseUrl, httpUrl, undefined, undefined, undefined, true,
|
||||||
)
|
),
|
||||||
).toEqual(httpUrl);
|
).toEqual(httpUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the empty string HTTP URLs by default", function() {
|
it("should return the empty string HTTP URLs by default", function() {
|
||||||
let httpUrl = "http://example.com/image.jpeg";
|
const httpUrl = "http://example.com/image.jpeg";
|
||||||
expect(ContentRepo.getHttpUriForMxc(baseUrl, httpUrl)).toEqual("");
|
expect(ContentRepo.getHttpUriForMxc(baseUrl, httpUrl)).toEqual("");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return a download URL if no width/height/resize are specified",
|
it("should return a download URL if no width/height/resize are specified",
|
||||||
function() {
|
function() {
|
||||||
let mxcUri = "mxc://server.name/resourceid";
|
const mxcUri = "mxc://server.name/resourceid";
|
||||||
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri)).toEqual(
|
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri)).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/download/server.name/resourceid"
|
baseUrl + "/_matrix/media/v1/download/server.name/resourceid",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,27 +38,27 @@ describe("ContentRepo", function() {
|
|||||||
|
|
||||||
it("should return a thumbnail URL if a width/height/resize is specified",
|
it("should return a thumbnail URL if a width/height/resize is specified",
|
||||||
function() {
|
function() {
|
||||||
let mxcUri = "mxc://server.name/resourceid";
|
const mxcUri = "mxc://server.name/resourceid";
|
||||||
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri, 32, 64, "crop")).toEqual(
|
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri, 32, 64, "crop")).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/thumbnail/server.name/resourceid" +
|
baseUrl + "/_matrix/media/v1/thumbnail/server.name/resourceid" +
|
||||||
"?width=32&height=64&method=crop"
|
"?width=32&height=64&method=crop",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should put fragments from mxc:// URIs after any query parameters",
|
it("should put fragments from mxc:// URIs after any query parameters",
|
||||||
function() {
|
function() {
|
||||||
let mxcUri = "mxc://server.name/resourceid#automade";
|
const mxcUri = "mxc://server.name/resourceid#automade";
|
||||||
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri, 32)).toEqual(
|
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri, 32)).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/thumbnail/server.name/resourceid" +
|
baseUrl + "/_matrix/media/v1/thumbnail/server.name/resourceid" +
|
||||||
"?width=32#automade"
|
"?width=32#automade",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should put fragments from mxc:// URIs at the end of the HTTP URI",
|
it("should put fragments from mxc:// URIs at the end of the HTTP URI",
|
||||||
function() {
|
function() {
|
||||||
let mxcUri = "mxc://server.name/resourceid#automade";
|
const mxcUri = "mxc://server.name/resourceid#automade";
|
||||||
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri)).toEqual(
|
expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri)).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/download/server.name/resourceid#automade"
|
baseUrl + "/_matrix/media/v1/download/server.name/resourceid#automade",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -71,21 +71,21 @@ describe("ContentRepo", function() {
|
|||||||
it("should set w/h by default to 96", function() {
|
it("should set w/h by default to 96", function() {
|
||||||
expect(ContentRepo.getIdenticonUri(baseUrl, "foobar")).toEqual(
|
expect(ContentRepo.getIdenticonUri(baseUrl, "foobar")).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/identicon/foobar" +
|
baseUrl + "/_matrix/media/v1/identicon/foobar" +
|
||||||
"?width=96&height=96"
|
"?width=96&height=96",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be able to set custom w/h", function() {
|
it("should be able to set custom w/h", function() {
|
||||||
expect(ContentRepo.getIdenticonUri(baseUrl, "foobar", 32, 64)).toEqual(
|
expect(ContentRepo.getIdenticonUri(baseUrl, "foobar", 32, 64)).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/identicon/foobar" +
|
baseUrl + "/_matrix/media/v1/identicon/foobar" +
|
||||||
"?width=32&height=64"
|
"?width=32&height=64",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should URL encode the identicon string", function() {
|
it("should URL encode the identicon string", function() {
|
||||||
expect(ContentRepo.getIdenticonUri(baseUrl, "foo#bar", 32, 64)).toEqual(
|
expect(ContentRepo.getIdenticonUri(baseUrl, "foo#bar", 32, 64)).toEqual(
|
||||||
baseUrl + "/_matrix/media/v1/identicon/foo%23bar" +
|
baseUrl + "/_matrix/media/v1/identicon/foo%23bar" +
|
||||||
"?width=32&height=64"
|
"?width=32&height=64",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
let Crypto = require("../../lib/crypto");
|
const Crypto = require("../../lib/crypto");
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
|
|
||||||
describe("Crypto", function() {
|
describe("Crypto", function() {
|
||||||
if (!sdk.CRYPTO_ENABLED) {
|
if (!sdk.CRYPTO_ENABLED) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let EventTimeline = sdk.EventTimeline;
|
const EventTimeline = sdk.EventTimeline;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
function mockRoomStates(timeline) {
|
function mockRoomStates(timeline) {
|
||||||
timeline._startState = utils.mock(sdk.RoomState, "startState");
|
timeline._startState = utils.mock(sdk.RoomState, "startState");
|
||||||
@@ -9,16 +9,16 @@ function mockRoomStates(timeline) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("EventTimeline", function() {
|
describe("EventTimeline", function() {
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let userA = "@alice:bar";
|
const userA = "@alice:bar";
|
||||||
let userB = "@bertha:bar";
|
const userB = "@bertha:bar";
|
||||||
let timeline;
|
let timeline;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
|
|
||||||
// XXX: this is a horrid hack; should use sinon or something instead to mock
|
// XXX: this is a horrid hack; should use sinon or something instead to mock
|
||||||
let timelineSet = { room: { roomId: roomId }};
|
const timelineSet = { room: { roomId: roomId }};
|
||||||
timelineSet.room.getUnfilteredTimelineSet = function() {
|
timelineSet.room.getUnfilteredTimelineSet = function() {
|
||||||
return timelineSet;
|
return timelineSet;
|
||||||
};
|
};
|
||||||
@@ -28,7 +28,7 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
describe("construction", function() {
|
describe("construction", function() {
|
||||||
it("getRoomId should get room id", function() {
|
it("getRoomId should get room id", function() {
|
||||||
let v = timeline.getRoomId();
|
const v = timeline.getRoomId();
|
||||||
expect(v).toEqual(roomId);
|
expect(v).toEqual(roomId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -39,7 +39,7 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should copy state events to start and end state", function() {
|
it("should copy state events to start and end state", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA,
|
room: roomId, mship: "invite", user: userB, skey: userA,
|
||||||
event: true,
|
event: true,
|
||||||
@@ -52,21 +52,21 @@ describe("EventTimeline", function() {
|
|||||||
];
|
];
|
||||||
timeline.initialiseState(events);
|
timeline.initialiseState(events);
|
||||||
expect(timeline._startState.setStateEvents).toHaveBeenCalledWith(
|
expect(timeline._startState.setStateEvents).toHaveBeenCalledWith(
|
||||||
events
|
events,
|
||||||
);
|
);
|
||||||
expect(timeline._endState.setStateEvents).toHaveBeenCalledWith(
|
expect(timeline._endState.setStateEvents).toHaveBeenCalledWith(
|
||||||
events
|
events,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should raise an exception if called after events are added", function() {
|
it("should raise an exception if called after events are added", function() {
|
||||||
let event =
|
const event =
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "Adam stole the plushies",
|
room: roomId, user: userA, msg: "Adam stole the plushies",
|
||||||
event: true,
|
event: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let state = [
|
const state = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA,
|
room: roomId, mship: "invite", user: userB, skey: userA,
|
||||||
event: true,
|
event: true,
|
||||||
@@ -105,8 +105,8 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("setNeighbouringTimeline should set neighbour", function() {
|
it("setNeighbouringTimeline should set neighbour", function() {
|
||||||
let prev = {a: "a"};
|
const prev = {a: "a"};
|
||||||
let next = {b: "b"};
|
const next = {b: "b"};
|
||||||
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
||||||
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
||||||
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev);
|
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev);
|
||||||
@@ -114,8 +114,8 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("setNeighbouringTimeline should throw if called twice", function() {
|
it("setNeighbouringTimeline should throw if called twice", function() {
|
||||||
let prev = {a: "a"};
|
const prev = {a: "a"};
|
||||||
let next = {b: "b"};
|
const next = {b: "b"};
|
||||||
expect(function() {
|
expect(function() {
|
||||||
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
@@ -141,7 +141,7 @@ describe("EventTimeline", function() {
|
|||||||
mockRoomStates(timeline);
|
mockRoomStates(timeline);
|
||||||
});
|
});
|
||||||
|
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "hungry hungry hungry",
|
room: roomId, user: userA, msg: "hungry hungry hungry",
|
||||||
event: true,
|
event: true,
|
||||||
@@ -154,7 +154,7 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
it("should be able to add events to the end", function() {
|
it("should be able to add events to the end", function() {
|
||||||
timeline.addEvent(events[0], false);
|
timeline.addEvent(events[0], false);
|
||||||
let initialIndex = timeline.getBaseIndex();
|
const initialIndex = timeline.getBaseIndex();
|
||||||
timeline.addEvent(events[1], false);
|
timeline.addEvent(events[1], false);
|
||||||
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
||||||
expect(timeline.getEvents().length).toEqual(2);
|
expect(timeline.getEvents().length).toEqual(2);
|
||||||
@@ -164,7 +164,7 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
it("should be able to add events to the start", function() {
|
it("should be able to add events to the start", function() {
|
||||||
timeline.addEvent(events[0], true);
|
timeline.addEvent(events[0], true);
|
||||||
let initialIndex = timeline.getBaseIndex();
|
const initialIndex = timeline.getBaseIndex();
|
||||||
timeline.addEvent(events[1], true);
|
timeline.addEvent(events[1], true);
|
||||||
expect(timeline.getBaseIndex()).toEqual(initialIndex + 1);
|
expect(timeline.getBaseIndex()).toEqual(initialIndex + 1);
|
||||||
expect(timeline.getEvents().length).toEqual(2);
|
expect(timeline.getEvents().length).toEqual(2);
|
||||||
@@ -173,12 +173,12 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set event.sender for new and old events", function() {
|
it("should set event.sender for new and old events", function() {
|
||||||
let sentinel = {
|
const sentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Alice",
|
name: "Alice",
|
||||||
};
|
};
|
||||||
let oldSentinel = {
|
const oldSentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Old Alice",
|
name: "Old Alice",
|
||||||
@@ -198,11 +198,11 @@ describe("EventTimeline", function() {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
let newEv = utils.mkEvent({
|
const newEv = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: userA, event: true,
|
type: "m.room.name", room: roomId, user: userA, event: true,
|
||||||
content: { name: "New Room Name" },
|
content: { name: "New Room Name" },
|
||||||
});
|
});
|
||||||
let oldEv = utils.mkEvent({
|
const oldEv = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: userA, event: true,
|
type: "m.room.name", room: roomId, user: userA, event: true,
|
||||||
content: { name: "Old Room Name" },
|
content: { name: "Old Room Name" },
|
||||||
});
|
});
|
||||||
@@ -215,12 +215,12 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
it("should set event.target for new and old m.room.member events",
|
it("should set event.target for new and old m.room.member events",
|
||||||
function() {
|
function() {
|
||||||
let sentinel = {
|
const sentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Alice",
|
name: "Alice",
|
||||||
};
|
};
|
||||||
let oldSentinel = {
|
const oldSentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Old Alice",
|
name: "Old Alice",
|
||||||
@@ -240,10 +240,10 @@ describe("EventTimeline", function() {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
let newEv = utils.mkMembership({
|
const newEv = utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
});
|
});
|
||||||
let oldEv = utils.mkMembership({
|
const oldEv = utils.mkMembership({
|
||||||
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
||||||
});
|
});
|
||||||
timeline.addEvent(newEv, false);
|
timeline.addEvent(newEv, false);
|
||||||
@@ -254,7 +254,7 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
it("should call setStateEvents on the right RoomState with the right " +
|
it("should call setStateEvents on the right RoomState with the right " +
|
||||||
"forwardLooking value for new events", function() {
|
"forwardLooking value for new events", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -284,7 +284,7 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
it("should call setStateEvents on the right RoomState with the right " +
|
it("should call setStateEvents on the right RoomState with the right " +
|
||||||
"forwardLooking value for old events", function() {
|
"forwardLooking value for old events", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -313,7 +313,7 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("removeEvent", function() {
|
describe("removeEvent", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "hungry hungry hungry",
|
room: roomId, user: userA, msg: "hungry hungry hungry",
|
||||||
event: true,
|
event: true,
|
||||||
@@ -365,7 +365,7 @@ describe("EventTimeline", function() {
|
|||||||
function() {
|
function() {
|
||||||
timeline.addEvent(events[0], true);
|
timeline.addEvent(events[0], true);
|
||||||
timeline.removeEvent(events[0].getId());
|
timeline.removeEvent(events[0].getId());
|
||||||
let initialIndex = timeline.getBaseIndex();
|
const initialIndex = timeline.getBaseIndex();
|
||||||
timeline.addEvent(events[1], false);
|
timeline.addEvent(events[1], false);
|
||||||
timeline.addEvent(events[2], false);
|
timeline.addEvent(events[2], false);
|
||||||
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let Filter = sdk.Filter;
|
const Filter = sdk.Filter;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("Filter", function() {
|
describe("Filter", function() {
|
||||||
let filterId = "f1lt3ring15g00d4ursoul";
|
const filterId = "f1lt3ring15g00d4ursoul";
|
||||||
let userId = "@sir_arthur_david:humming.tiger";
|
const userId = "@sir_arthur_david:humming.tiger";
|
||||||
let filter;
|
let filter;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -15,10 +15,10 @@ describe("Filter", function() {
|
|||||||
|
|
||||||
describe("fromJson", function() {
|
describe("fromJson", function() {
|
||||||
it("create a new Filter from the provided values", function() {
|
it("create a new Filter from the provided values", function() {
|
||||||
let definition = {
|
const definition = {
|
||||||
event_fields: ["type", "content"],
|
event_fields: ["type", "content"],
|
||||||
};
|
};
|
||||||
let f = Filter.fromJson(userId, filterId, definition);
|
const f = Filter.fromJson(userId, filterId, definition);
|
||||||
expect(f.getDefinition()).toEqual(definition);
|
expect(f.getDefinition()).toEqual(definition);
|
||||||
expect(f.userId).toEqual(userId);
|
expect(f.userId).toEqual(userId);
|
||||||
expect(f.filterId).toEqual(filterId);
|
expect(f.filterId).toEqual(filterId);
|
||||||
@@ -40,7 +40,7 @@ describe("Filter", function() {
|
|||||||
|
|
||||||
describe("setDefinition/getDefinition", function() {
|
describe("setDefinition/getDefinition", function() {
|
||||||
it("should set and get the filter body", function() {
|
it("should set and get the filter body", function() {
|
||||||
let definition = {
|
const definition = {
|
||||||
event_format: "client",
|
event_format: "client",
|
||||||
};
|
};
|
||||||
filter.setDefinition(definition);
|
filter.setDefinition(definition);
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
let InteractiveAuth = sdk.InteractiveAuth;
|
const InteractiveAuth = sdk.InteractiveAuth;
|
||||||
let MatrixError = sdk.MatrixError;
|
const MatrixError = sdk.MatrixError;
|
||||||
|
|
||||||
describe("InteractiveAuth", function() {
|
describe("InteractiveAuth", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -28,10 +28,10 @@ describe("InteractiveAuth", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should start an auth stage and complete it", function(done) {
|
it("should start an auth stage and complete it", function(done) {
|
||||||
let doRequest = jasmine.createSpy('doRequest');
|
const doRequest = jasmine.createSpy('doRequest');
|
||||||
let startAuthStage = jasmine.createSpy('startAuthStage');
|
const startAuthStage = jasmine.createSpy('startAuthStage');
|
||||||
|
|
||||||
let ia = new InteractiveAuth({
|
const ia = new InteractiveAuth({
|
||||||
doRequest: doRequest,
|
doRequest: doRequest,
|
||||||
startAuthStage: startAuthStage,
|
startAuthStage: startAuthStage,
|
||||||
authData: {
|
authData: {
|
||||||
@@ -60,7 +60,7 @@ describe("InteractiveAuth", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// .. which should trigger a call here
|
// .. which should trigger a call here
|
||||||
let requestRes = {"a": "b"};
|
const requestRes = {"a": "b"};
|
||||||
doRequest.andCallFake(function(authData) {
|
doRequest.andCallFake(function(authData) {
|
||||||
expect(authData).toEqual({
|
expect(authData).toEqual({
|
||||||
session: "sessionId",
|
session: "sessionId",
|
||||||
@@ -78,10 +78,10 @@ describe("InteractiveAuth", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should make a request if no authdata is provided", function(done) {
|
it("should make a request if no authdata is provided", function(done) {
|
||||||
let doRequest = jasmine.createSpy('doRequest');
|
const doRequest = jasmine.createSpy('doRequest');
|
||||||
let startAuthStage = jasmine.createSpy('startAuthStage');
|
const startAuthStage = jasmine.createSpy('startAuthStage');
|
||||||
|
|
||||||
let ia = new InteractiveAuth({
|
const ia = new InteractiveAuth({
|
||||||
doRequest: doRequest,
|
doRequest: doRequest,
|
||||||
startAuthStage: startAuthStage,
|
startAuthStage: startAuthStage,
|
||||||
});
|
});
|
||||||
@@ -93,7 +93,7 @@ describe("InteractiveAuth", function() {
|
|||||||
doRequest.andCallFake(function(authData) {
|
doRequest.andCallFake(function(authData) {
|
||||||
console.log("request1", authData);
|
console.log("request1", authData);
|
||||||
expect(authData).toBe(null);
|
expect(authData).toBe(null);
|
||||||
let err = new MatrixError({
|
const err = new MatrixError({
|
||||||
session: "sessionId",
|
session: "sessionId",
|
||||||
flows: [
|
flows: [
|
||||||
{ stages: ["logintype"] },
|
{ stages: ["logintype"] },
|
||||||
@@ -107,7 +107,7 @@ describe("InteractiveAuth", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// .. which should be followed by a call to startAuthStage
|
// .. which should be followed by a call to startAuthStage
|
||||||
let requestRes = {"a": "b"};
|
const requestRes = {"a": "b"};
|
||||||
startAuthStage.andCallFake(function(stage) {
|
startAuthStage.andCallFake(function(stage) {
|
||||||
expect(stage).toEqual("logintype");
|
expect(stage).toEqual("logintype");
|
||||||
expect(ia.getSessionId()).toEqual("sessionId");
|
expect(ia.getSessionId()).toEqual("sessionId");
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let MatrixClient = sdk.MatrixClient;
|
const MatrixClient = sdk.MatrixClient;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("MatrixClient", function() {
|
describe("MatrixClient", function() {
|
||||||
let userId = "@alice:bar";
|
const userId = "@alice:bar";
|
||||||
let identityServerUrl = "https://identity.server";
|
const identityServerUrl = "https://identity.server";
|
||||||
let identityServerDomain = "identity.server";
|
const identityServerDomain = "identity.server";
|
||||||
let client;
|
let client;
|
||||||
let store;
|
let store;
|
||||||
let scheduler;
|
let scheduler;
|
||||||
|
|
||||||
let KEEP_ALIVE_PATH = "/_matrix/client/versions";
|
const KEEP_ALIVE_PATH = "/_matrix/client/versions";
|
||||||
|
|
||||||
let PUSH_RULES_RESPONSE = {
|
const PUSH_RULES_RESPONSE = {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: "/pushrules/",
|
path: "/pushrules/",
|
||||||
data: {},
|
data: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
let FILTER_PATH = "/user/" + encodeURIComponent(userId) + "/filter";
|
const FILTER_PATH = "/user/" + encodeURIComponent(userId) + "/filter";
|
||||||
|
|
||||||
let FILTER_RESPONSE = {
|
const FILTER_RESPONSE = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
path: FILTER_PATH,
|
path: FILTER_PATH,
|
||||||
data: { filter_id: "f1lt3r" },
|
data: { filter_id: "f1lt3r" },
|
||||||
};
|
};
|
||||||
|
|
||||||
let SYNC_DATA = {
|
const SYNC_DATA = {
|
||||||
next_batch: "s_5_3",
|
next_batch: "s_5_3",
|
||||||
presence: { events: [] },
|
presence: { events: [] },
|
||||||
rooms: {},
|
rooms: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
let SYNC_RESPONSE = {
|
const SYNC_RESPONSE = {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: "/sync",
|
path: "/sync",
|
||||||
data: SYNC_DATA,
|
data: SYNC_DATA,
|
||||||
@@ -59,8 +59,8 @@ describe("MatrixClient", function() {
|
|||||||
if (path === KEEP_ALIVE_PATH && acceptKeepalives) {
|
if (path === KEEP_ALIVE_PATH && acceptKeepalives) {
|
||||||
return q();
|
return q();
|
||||||
}
|
}
|
||||||
let next = httpLookups.shift();
|
const next = httpLookups.shift();
|
||||||
let logLine = (
|
const logLine = (
|
||||||
"MatrixClient[UT] RECV " + method + " " + path + " " +
|
"MatrixClient[UT] RECV " + method + " " + path + " " +
|
||||||
"EXPECT " + (next ? next.method : next) + " " + (next ? next.path : next)
|
"EXPECT " + (next ? next.method : next) + " " + (next ? next.path : next)
|
||||||
);
|
);
|
||||||
@@ -75,7 +75,7 @@ describe("MatrixClient", function() {
|
|||||||
expect(false).toBe(
|
expect(false).toBe(
|
||||||
true, ">1 pending request. You should probably handle them. " +
|
true, ">1 pending request. You should probably handle them. " +
|
||||||
"PENDING: " + JSON.stringify(pendingLookup) + " JUST GOT: " +
|
"PENDING: " + JSON.stringify(pendingLookup) + " JUST GOT: " +
|
||||||
method + " " + path
|
method + " " + path,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pendingLookup = {
|
pendingLookup = {
|
||||||
@@ -88,7 +88,7 @@ describe("MatrixClient", function() {
|
|||||||
if (next.path === path && next.method === method) {
|
if (next.path === path && next.method === method) {
|
||||||
console.log(
|
console.log(
|
||||||
"MatrixClient[UT] Matched. Returning " +
|
"MatrixClient[UT] Matched. Returning " +
|
||||||
(next.error ? "BAD" : "GOOD") + " response"
|
(next.error ? "BAD" : "GOOD") + " response",
|
||||||
);
|
);
|
||||||
if (next.expectBody) {
|
if (next.expectBody) {
|
||||||
expect(next.expectBody).toEqual(data);
|
expect(next.expectBody).toEqual(data);
|
||||||
@@ -176,9 +176,9 @@ describe("MatrixClient", function() {
|
|||||||
httpLookups = [];
|
httpLookups = [];
|
||||||
httpLookups.push(PUSH_RULES_RESPONSE);
|
httpLookups.push(PUSH_RULES_RESPONSE);
|
||||||
httpLookups.push(SYNC_RESPONSE);
|
httpLookups.push(SYNC_RESPONSE);
|
||||||
let filterId = "ehfewf";
|
const filterId = "ehfewf";
|
||||||
store.getFilterIdByName.andReturn(filterId);
|
store.getFilterIdByName.andReturn(filterId);
|
||||||
let filter = new sdk.Filter(0, filterId);
|
const filter = new sdk.Filter(0, filterId);
|
||||||
filter.setDefinition({"room": {"timeline": {"limit": 8}}});
|
filter.setDefinition({"room": {"timeline": {"limit": 8}}});
|
||||||
store.getFilter.andReturn(filter);
|
store.getFilter.andReturn(filter);
|
||||||
client.startClient();
|
client.startClient();
|
||||||
@@ -220,7 +220,7 @@ describe("MatrixClient", function() {
|
|||||||
// and they all need to be stored!
|
// and they all need to be stored!
|
||||||
return "FILTER_SYNC_" + userId + (suffix ? "_" + suffix : "");
|
return "FILTER_SYNC_" + userId + (suffix ? "_" + suffix : "");
|
||||||
}
|
}
|
||||||
let invalidFilterId = 'invalidF1lt3r';
|
const invalidFilterId = 'invalidF1lt3r';
|
||||||
httpLookups = [];
|
httpLookups = [];
|
||||||
httpLookups.push({
|
httpLookups.push({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@@ -236,9 +236,9 @@ describe("MatrixClient", function() {
|
|||||||
httpLookups.push(FILTER_RESPONSE);
|
httpLookups.push(FILTER_RESPONSE);
|
||||||
store.getFilterIdByName.andReturn(invalidFilterId);
|
store.getFilterIdByName.andReturn(invalidFilterId);
|
||||||
|
|
||||||
let filterName = getFilterName(client.credentials.userId);
|
const filterName = getFilterName(client.credentials.userId);
|
||||||
client.store.setFilterIdByName(filterName, invalidFilterId);
|
client.store.setFilterIdByName(filterName, invalidFilterId);
|
||||||
let filter = new sdk.Filter(client.credentials.userId);
|
const filter = new sdk.Filter(client.credentials.userId);
|
||||||
|
|
||||||
client.getOrCreateFilter(filterName, filter).then(function(filterId) {
|
client.getOrCreateFilter(filterName, filter).then(function(filterId) {
|
||||||
expect(filterId).toEqual(FILTER_RESPONSE.data.filter_id);
|
expect(filterId).toEqual(FILTER_RESPONSE.data.filter_id);
|
||||||
@@ -290,7 +290,7 @@ describe("MatrixClient", function() {
|
|||||||
if (state === "ERROR" && httpLookups.length > 0) {
|
if (state === "ERROR" && httpLookups.length > 0) {
|
||||||
expect(httpLookups.length).toEqual(1);
|
expect(httpLookups.length).toEqual(1);
|
||||||
expect(client.retryImmediately()).toBe(
|
expect(client.retryImmediately()).toBe(
|
||||||
true, "retryImmediately returned false"
|
true, "retryImmediately returned false",
|
||||||
);
|
);
|
||||||
jasmine.Clock.tick(1);
|
jasmine.Clock.tick(1);
|
||||||
} else if (state === "RECONNECTING" && httpLookups.length > 0) {
|
} else if (state === "RECONNECTING" && httpLookups.length > 0) {
|
||||||
@@ -332,9 +332,9 @@ describe("MatrixClient", function() {
|
|||||||
describe("emitted sync events", function() {
|
describe("emitted sync events", function() {
|
||||||
function syncChecker(expectedStates, done) {
|
function syncChecker(expectedStates, done) {
|
||||||
return function syncListener(state, old) {
|
return function syncListener(state, old) {
|
||||||
let expected = expectedStates.shift();
|
const expected = expectedStates.shift();
|
||||||
console.log(
|
console.log(
|
||||||
"'sync' curr=%s old=%s EXPECT=%s", state, old, expected
|
"'sync' curr=%s old=%s EXPECT=%s", state, old, expected,
|
||||||
);
|
);
|
||||||
if (!expected) {
|
if (!expected) {
|
||||||
done();
|
done();
|
||||||
@@ -352,14 +352,14 @@ describe("MatrixClient", function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it("should transition null -> PREPARED after the first /sync", function(done) {
|
it("should transition null -> PREPARED after the first /sync", function(done) {
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
expectedStates.push(["PREPARED", null]);
|
expectedStates.push(["PREPARED", null]);
|
||||||
client.on("sync", syncChecker(expectedStates, done));
|
client.on("sync", syncChecker(expectedStates, done));
|
||||||
client.startClient();
|
client.startClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should transition null -> ERROR after a failed /filter", function(done) {
|
it("should transition null -> ERROR after a failed /filter", function(done) {
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
httpLookups = [];
|
httpLookups = [];
|
||||||
httpLookups.push(PUSH_RULES_RESPONSE);
|
httpLookups.push(PUSH_RULES_RESPONSE);
|
||||||
httpLookups.push({
|
httpLookups.push({
|
||||||
@@ -372,7 +372,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should transition ERROR -> PREPARED after /sync if prev failed",
|
it("should transition ERROR -> PREPARED after /sync if prev failed",
|
||||||
function(done) {
|
function(done) {
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
acceptKeepalives = false;
|
acceptKeepalives = false;
|
||||||
httpLookups = [];
|
httpLookups = [];
|
||||||
httpLookups.push(PUSH_RULES_RESPONSE);
|
httpLookups.push(PUSH_RULES_RESPONSE);
|
||||||
@@ -399,7 +399,7 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should transition PREPARED -> SYNCING after /sync", function(done) {
|
it("should transition PREPARED -> SYNCING after /sync", function(done) {
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
expectedStates.push(["PREPARED", null]);
|
expectedStates.push(["PREPARED", null]);
|
||||||
expectedStates.push(["SYNCING", "PREPARED"]);
|
expectedStates.push(["SYNCING", "PREPARED"]);
|
||||||
client.on("sync", syncChecker(expectedStates, done));
|
client.on("sync", syncChecker(expectedStates, done));
|
||||||
@@ -408,7 +408,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should transition SYNCING -> ERROR after a failed /sync", function(done) {
|
it("should transition SYNCING -> ERROR after a failed /sync", function(done) {
|
||||||
acceptKeepalives = false;
|
acceptKeepalives = false;
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
httpLookups.push({
|
httpLookups.push({
|
||||||
method: "GET", path: "/sync", error: { errcode: "NONONONONO" },
|
method: "GET", path: "/sync", error: { errcode: "NONONONONO" },
|
||||||
});
|
});
|
||||||
@@ -427,7 +427,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
xit("should transition ERROR -> SYNCING after /sync if prev failed",
|
xit("should transition ERROR -> SYNCING after /sync if prev failed",
|
||||||
function(done) {
|
function(done) {
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
httpLookups.push({
|
httpLookups.push({
|
||||||
method: "GET", path: "/sync", error: { errcode: "NONONONONO" },
|
method: "GET", path: "/sync", error: { errcode: "NONONONONO" },
|
||||||
});
|
});
|
||||||
@@ -442,7 +442,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should transition SYNCING -> SYNCING on subsequent /sync successes",
|
it("should transition SYNCING -> SYNCING on subsequent /sync successes",
|
||||||
function(done) {
|
function(done) {
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
httpLookups.push(SYNC_RESPONSE);
|
httpLookups.push(SYNC_RESPONSE);
|
||||||
httpLookups.push(SYNC_RESPONSE);
|
httpLookups.push(SYNC_RESPONSE);
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ describe("MatrixClient", function() {
|
|||||||
|
|
||||||
it("should transition ERROR -> ERROR if keepalive keeps failing", function(done) {
|
it("should transition ERROR -> ERROR if keepalive keeps failing", function(done) {
|
||||||
acceptKeepalives = false;
|
acceptKeepalives = false;
|
||||||
let expectedStates = [];
|
const expectedStates = [];
|
||||||
httpLookups.push({
|
httpLookups.push({
|
||||||
method: "GET", path: "/sync", error: { errcode: "NONONONONO" },
|
method: "GET", path: "/sync", error: { errcode: "NONONONONO" },
|
||||||
});
|
});
|
||||||
@@ -479,7 +479,7 @@ describe("MatrixClient", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("inviteByEmail", function() {
|
describe("inviteByEmail", function() {
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
|
|
||||||
it("should send an invite HTTP POST", function() {
|
it("should send an invite HTTP POST", function() {
|
||||||
httpLookups = [{
|
httpLookups = [{
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let PushProcessor = require("../../lib/pushprocessor");
|
const PushProcessor = require("../../lib/pushprocessor");
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe('NotificationService', function() {
|
describe('NotificationService', function() {
|
||||||
let testUserId = "@ali:matrix.org";
|
const testUserId = "@ali:matrix.org";
|
||||||
let testDisplayName = "Alice M";
|
const testDisplayName = "Alice M";
|
||||||
let testRoomId = "!fl1bb13:localhost";
|
const testRoomId = "!fl1bb13:localhost";
|
||||||
|
|
||||||
let testEvent;
|
let testEvent;
|
||||||
|
|
||||||
let pushProcessor;
|
let pushProcessor;
|
||||||
|
|
||||||
// These would be better if individual rules were configured in the tests themselves.
|
// These would be better if individual rules were configured in the tests themselves.
|
||||||
let matrixClient = {
|
const matrixClient = {
|
||||||
getRoom: function() {
|
getRoom: function() {
|
||||||
return {
|
return {
|
||||||
currentState: {
|
currentState: {
|
||||||
@@ -213,25 +213,25 @@ describe('NotificationService', function() {
|
|||||||
|
|
||||||
it('should bing on a user ID.', function() {
|
it('should bing on a user ID.', function() {
|
||||||
testEvent.event.content.body = "Hello @ali:matrix.org, how are you?";
|
testEvent.event.content.body = "Hello @ali:matrix.org, how are you?";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should bing on a partial user ID with an @.', function() {
|
it('should bing on a partial user ID with an @.', function() {
|
||||||
testEvent.event.content.body = "Hello @ali, how are you?";
|
testEvent.event.content.body = "Hello @ali, how are you?";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should bing on a partial user ID without @.', function() {
|
it('should bing on a partial user ID without @.', function() {
|
||||||
testEvent.event.content.body = "Hello ali, how are you?";
|
testEvent.event.content.body = "Hello ali, how are you?";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should bing on a case-insensitive user ID.', function() {
|
it('should bing on a case-insensitive user ID.', function() {
|
||||||
testEvent.event.content.body = "Hello @AlI:matrix.org, how are you?";
|
testEvent.event.content.body = "Hello @AlI:matrix.org, how are you?";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -239,13 +239,13 @@ describe('NotificationService', function() {
|
|||||||
|
|
||||||
it('should bing on a display name.', function() {
|
it('should bing on a display name.', function() {
|
||||||
testEvent.event.content.body = "Hello Alice M, how are you?";
|
testEvent.event.content.body = "Hello Alice M, how are you?";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should bing on a case-insensitive display name.', function() {
|
it('should bing on a case-insensitive display name.', function() {
|
||||||
testEvent.event.content.body = "Hello ALICE M, how are you?";
|
testEvent.event.content.body = "Hello ALICE M, how are you?";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -253,19 +253,19 @@ describe('NotificationService', function() {
|
|||||||
|
|
||||||
it('should bing on a bing word.', function() {
|
it('should bing on a bing word.', function() {
|
||||||
testEvent.event.content.body = "I really like coffee";
|
testEvent.event.content.body = "I really like coffee";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should bing on case-insensitive bing words.', function() {
|
it('should bing on case-insensitive bing words.', function() {
|
||||||
testEvent.event.content.body = "Coffee is great";
|
testEvent.event.content.body = "Coffee is great";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should bing on wildcard (.*) bing words.', function() {
|
it('should bing on wildcard (.*) bing words.', function() {
|
||||||
testEvent.event.content.body = "It was foomahbar I think.";
|
testEvent.event.content.body = "It was foomahbar I think.";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ describe('NotificationService', function() {
|
|||||||
|
|
||||||
it('should bing on character range ([a-z]) bing words.', function() {
|
it('should bing on character range ([a-z]) bing words.', function() {
|
||||||
testEvent.event.content.body = "I ate 6 pies";
|
testEvent.event.content.body = "I ate 6 pies";
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(true);
|
expect(actions.tweaks.highlight).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ describe('NotificationService', function() {
|
|||||||
|
|
||||||
it('should gracefully handle bad input.', function() {
|
it('should gracefully handle bad input.', function() {
|
||||||
testEvent.event.content.body = { "foo": "bar" };
|
testEvent.event.content.body = { "foo": "bar" };
|
||||||
let actions = pushProcessor.actionsForEvent(testEvent);
|
const actions = pushProcessor.actionsForEvent(testEvent);
|
||||||
expect(actions.tweaks.highlight).toEqual(false);
|
expect(actions.tweaks.highlight).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
let callbacks = require("../../lib/realtime-callbacks");
|
const callbacks = require("../../lib/realtime-callbacks");
|
||||||
let test_utils = require("../test-utils.js");
|
const testUtils = require("../test-utils.js");
|
||||||
|
|
||||||
describe("realtime-callbacks", function() {
|
describe("realtime-callbacks", function() {
|
||||||
let clock = jasmine.Clock;
|
const clock = jasmine.Clock;
|
||||||
let fakeDate;
|
let fakeDate;
|
||||||
|
|
||||||
function tick(millis) {
|
function tick(millis) {
|
||||||
@@ -14,7 +14,7 @@ describe("realtime-callbacks", function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
test_utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
clock.useMock();
|
clock.useMock();
|
||||||
fakeDate = Date.now();
|
fakeDate = Date.now();
|
||||||
callbacks.setNow(function() {
|
callbacks.setNow(function() {
|
||||||
@@ -28,7 +28,7 @@ describe("realtime-callbacks", function() {
|
|||||||
|
|
||||||
describe("setTimeout", function() {
|
describe("setTimeout", function() {
|
||||||
it("should call the callback after the timeout", function() {
|
it("should call the callback after the timeout", function() {
|
||||||
let callback = jasmine.createSpy();
|
const callback = jasmine.createSpy();
|
||||||
callbacks.setTimeout(callback, 100);
|
callbacks.setTimeout(callback, 100);
|
||||||
|
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
@@ -38,7 +38,7 @@ describe("realtime-callbacks", function() {
|
|||||||
|
|
||||||
|
|
||||||
it("should default to a zero timeout", function() {
|
it("should default to a zero timeout", function() {
|
||||||
let callback = jasmine.createSpy();
|
const callback = jasmine.createSpy();
|
||||||
callbacks.setTimeout(callback);
|
callbacks.setTimeout(callback);
|
||||||
|
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
@@ -47,14 +47,14 @@ describe("realtime-callbacks", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should pass any parameters to the callback", function() {
|
it("should pass any parameters to the callback", function() {
|
||||||
let callback = jasmine.createSpy();
|
const callback = jasmine.createSpy();
|
||||||
callbacks.setTimeout(callback, 0, "a", "b", "c");
|
callbacks.setTimeout(callback, 0, "a", "b", "c");
|
||||||
tick(0);
|
tick(0);
|
||||||
expect(callback).toHaveBeenCalledWith("a", "b", "c");
|
expect(callback).toHaveBeenCalledWith("a", "b", "c");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set 'this' to the global object", function() {
|
it("should set 'this' to the global object", function() {
|
||||||
let callback = jasmine.createSpy();
|
const callback = jasmine.createSpy();
|
||||||
callback.andCallFake(function() {
|
callback.andCallFake(function() {
|
||||||
expect(this).toBe(global); // eslint-disable-line no-invalid-this
|
expect(this).toBe(global); // eslint-disable-line no-invalid-this
|
||||||
expect(this.console).toBeDefined(); // eslint-disable-line no-invalid-this
|
expect(this.console).toBeDefined(); // eslint-disable-line no-invalid-this
|
||||||
@@ -65,7 +65,7 @@ describe("realtime-callbacks", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should handle timeouts of several seconds", function() {
|
it("should handle timeouts of several seconds", function() {
|
||||||
let callback = jasmine.createSpy();
|
const callback = jasmine.createSpy();
|
||||||
callbacks.setTimeout(callback, 2000);
|
callbacks.setTimeout(callback, 2000);
|
||||||
|
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
@@ -76,9 +76,9 @@ describe("realtime-callbacks", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should call multiple callbacks in the right order", function() {
|
it("should call multiple callbacks in the right order", function() {
|
||||||
let callback1 = jasmine.createSpy("callback1");
|
const callback1 = jasmine.createSpy("callback1");
|
||||||
let callback2 = jasmine.createSpy("callback2");
|
const callback2 = jasmine.createSpy("callback2");
|
||||||
let callback3 = jasmine.createSpy("callback3");
|
const callback3 = jasmine.createSpy("callback3");
|
||||||
callbacks.setTimeout(callback2, 200);
|
callbacks.setTimeout(callback2, 200);
|
||||||
callbacks.setTimeout(callback1, 100);
|
callbacks.setTimeout(callback1, 100);
|
||||||
callbacks.setTimeout(callback3, 300);
|
callbacks.setTimeout(callback3, 300);
|
||||||
@@ -101,8 +101,8 @@ describe("realtime-callbacks", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should treat -ve timeouts the same as a zero timeout", function() {
|
it("should treat -ve timeouts the same as a zero timeout", function() {
|
||||||
let callback1 = jasmine.createSpy("callback1");
|
const callback1 = jasmine.createSpy("callback1");
|
||||||
let callback2 = jasmine.createSpy("callback2");
|
const callback2 = jasmine.createSpy("callback2");
|
||||||
|
|
||||||
// check that cb1 is called before cb2
|
// check that cb1 is called before cb2
|
||||||
callback1.andCallFake(function() {
|
callback1.andCallFake(function() {
|
||||||
@@ -120,8 +120,8 @@ describe("realtime-callbacks", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should not get confused by chained calls", function() {
|
it("should not get confused by chained calls", function() {
|
||||||
let callback2 = jasmine.createSpy("callback2");
|
const callback2 = jasmine.createSpy("callback2");
|
||||||
let callback1 = jasmine.createSpy("callback1");
|
const callback1 = jasmine.createSpy("callback1");
|
||||||
callback1.andCallFake(function() {
|
callback1.andCallFake(function() {
|
||||||
callbacks.setTimeout(callback2, 0);
|
callbacks.setTimeout(callback2, 0);
|
||||||
expect(callback2).not.toHaveBeenCalled();
|
expect(callback2).not.toHaveBeenCalled();
|
||||||
@@ -136,11 +136,11 @@ describe("realtime-callbacks", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should be immune to exceptions", function() {
|
it("should be immune to exceptions", function() {
|
||||||
let callback1 = jasmine.createSpy("callback1");
|
const callback1 = jasmine.createSpy("callback1");
|
||||||
callback1.andCallFake(function() {
|
callback1.andCallFake(function() {
|
||||||
throw new Error("prepare to die");
|
throw new Error("prepare to die");
|
||||||
});
|
});
|
||||||
let callback2 = jasmine.createSpy("callback2");
|
const callback2 = jasmine.createSpy("callback2");
|
||||||
callbacks.setTimeout(callback1, 0);
|
callbacks.setTimeout(callback1, 0);
|
||||||
callbacks.setTimeout(callback2, 0);
|
callbacks.setTimeout(callback2, 0);
|
||||||
|
|
||||||
@@ -154,19 +154,19 @@ describe("realtime-callbacks", function() {
|
|||||||
|
|
||||||
describe("cancelTimeout", function() {
|
describe("cancelTimeout", function() {
|
||||||
it("should cancel a pending timeout", function() {
|
it("should cancel a pending timeout", function() {
|
||||||
let callback = jasmine.createSpy();
|
const callback = jasmine.createSpy();
|
||||||
let k = callbacks.setTimeout(callback);
|
const k = callbacks.setTimeout(callback);
|
||||||
callbacks.clearTimeout(k);
|
callbacks.clearTimeout(k);
|
||||||
tick(0);
|
tick(0);
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not affect sooner timeouts", function() {
|
it("should not affect sooner timeouts", function() {
|
||||||
let callback1 = jasmine.createSpy("callback1");
|
const callback1 = jasmine.createSpy("callback1");
|
||||||
let callback2 = jasmine.createSpy("callback2");
|
const callback2 = jasmine.createSpy("callback2");
|
||||||
|
|
||||||
callbacks.setTimeout(callback1, 100);
|
callbacks.setTimeout(callback1, 100);
|
||||||
let k = callbacks.setTimeout(callback2, 200);
|
const k = callbacks.setTimeout(callback2, 200);
|
||||||
callbacks.clearTimeout(k);
|
callbacks.clearTimeout(k);
|
||||||
|
|
||||||
tick(100);
|
tick(100);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let RoomMember = sdk.RoomMember;
|
const RoomMember = sdk.RoomMember;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("RoomMember", function() {
|
describe("RoomMember", function() {
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let userA = "@alice:bar";
|
const userA = "@alice:bar";
|
||||||
let userB = "@bertha:bar";
|
const userB = "@bertha:bar";
|
||||||
let userC = "@clarissa:bar";
|
const userC = "@clarissa:bar";
|
||||||
let member;
|
let member;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -16,7 +16,7 @@ describe("RoomMember", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("getAvatarUrl", function() {
|
describe("getAvatarUrl", function() {
|
||||||
let hsUrl = "https://my.home.server";
|
const hsUrl = "https://my.home.server";
|
||||||
|
|
||||||
it("should return the URL from m.room.member preferentially", function() {
|
it("should return the URL from m.room.member preferentially", function() {
|
||||||
member.events.member = utils.mkEvent({
|
member.events.member = utils.mkEvent({
|
||||||
@@ -30,7 +30,7 @@ describe("RoomMember", function() {
|
|||||||
avatar_url: "mxc://flibble/wibble",
|
avatar_url: "mxc://flibble/wibble",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let url = member.getAvatarUrl(hsUrl);
|
const url = member.getAvatarUrl(hsUrl);
|
||||||
// we don't care about how the mxc->http conversion is done, other
|
// we don't care about how the mxc->http conversion is done, other
|
||||||
// than it contains the mxc body.
|
// than it contains the mxc body.
|
||||||
expect(url.indexOf("flibble/wibble")).not.toEqual(-1);
|
expect(url.indexOf("flibble/wibble")).not.toEqual(-1);
|
||||||
@@ -38,20 +38,20 @@ describe("RoomMember", function() {
|
|||||||
|
|
||||||
it("should return an identicon HTTP URL if allowDefault was set and there " +
|
it("should return an identicon HTTP URL if allowDefault was set and there " +
|
||||||
"was no m.room.member event", function() {
|
"was no m.room.member event", function() {
|
||||||
let url = member.getAvatarUrl(hsUrl, 64, 64, "crop", true);
|
const url = member.getAvatarUrl(hsUrl, 64, 64, "crop", true);
|
||||||
expect(url.indexOf("http")).toEqual(0); // don't care about form
|
expect(url.indexOf("http")).toEqual(0); // don't care about form
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return nothing if there is no m.room.member and allowDefault=false",
|
it("should return nothing if there is no m.room.member and allowDefault=false",
|
||||||
function() {
|
function() {
|
||||||
let url = member.getAvatarUrl(hsUrl, 64, 64, "crop", false);
|
const url = member.getAvatarUrl(hsUrl, 64, 64, "crop", false);
|
||||||
expect(url).toEqual(null);
|
expect(url).toEqual(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("setPowerLevelEvent", function() {
|
describe("setPowerLevelEvent", function() {
|
||||||
it("should set 'powerLevel' and 'powerLevelNorm'.", function() {
|
it("should set 'powerLevel' and 'powerLevelNorm'.", function() {
|
||||||
let event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
user: userA,
|
user: userA,
|
||||||
@@ -68,7 +68,7 @@ describe("RoomMember", function() {
|
|||||||
expect(member.powerLevel).toEqual(20);
|
expect(member.powerLevel).toEqual(20);
|
||||||
expect(member.powerLevelNorm).toEqual(10);
|
expect(member.powerLevelNorm).toEqual(10);
|
||||||
|
|
||||||
let memberB = new RoomMember(roomId, userB);
|
const memberB = new RoomMember(roomId, userB);
|
||||||
memberB.setPowerLevelEvent(event);
|
memberB.setPowerLevelEvent(event);
|
||||||
expect(memberB.powerLevel).toEqual(200);
|
expect(memberB.powerLevel).toEqual(200);
|
||||||
expect(memberB.powerLevelNorm).toEqual(100);
|
expect(memberB.powerLevelNorm).toEqual(100);
|
||||||
@@ -76,7 +76,7 @@ describe("RoomMember", function() {
|
|||||||
|
|
||||||
it("should emit 'RoomMember.powerLevel' if the power level changes.",
|
it("should emit 'RoomMember.powerLevel' if the power level changes.",
|
||||||
function() {
|
function() {
|
||||||
let event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
user: userA,
|
user: userA,
|
||||||
@@ -105,7 +105,7 @@ describe("RoomMember", function() {
|
|||||||
|
|
||||||
it("should honour power levels of zero.",
|
it("should honour power levels of zero.",
|
||||||
function() {
|
function() {
|
||||||
let event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
user: userA,
|
user: userA,
|
||||||
@@ -138,12 +138,12 @@ describe("RoomMember", function() {
|
|||||||
describe("setTypingEvent", function() {
|
describe("setTypingEvent", function() {
|
||||||
it("should set 'typing'", function() {
|
it("should set 'typing'", function() {
|
||||||
member.typing = false;
|
member.typing = false;
|
||||||
let memberB = new RoomMember(roomId, userB);
|
const memberB = new RoomMember(roomId, userB);
|
||||||
memberB.typing = true;
|
memberB.typing = true;
|
||||||
let memberC = new RoomMember(roomId, userC);
|
const memberC = new RoomMember(roomId, userC);
|
||||||
memberC.typing = true;
|
memberC.typing = true;
|
||||||
|
|
||||||
let event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.typing",
|
type: "m.typing",
|
||||||
user: userA,
|
user: userA,
|
||||||
room: roomId,
|
room: roomId,
|
||||||
@@ -165,7 +165,7 @@ describe("RoomMember", function() {
|
|||||||
|
|
||||||
it("should emit 'RoomMember.typing' if the typing state changes",
|
it("should emit 'RoomMember.typing' if the typing state changes",
|
||||||
function() {
|
function() {
|
||||||
let event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.typing",
|
type: "m.typing",
|
||||||
room: roomId,
|
room: roomId,
|
||||||
content: {
|
content: {
|
||||||
@@ -190,7 +190,7 @@ describe("RoomMember", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("setMembershipEvent", function() {
|
describe("setMembershipEvent", function() {
|
||||||
let joinEvent = utils.mkMembership({
|
const joinEvent = utils.mkMembership({
|
||||||
event: true,
|
event: true,
|
||||||
mship: "join",
|
mship: "join",
|
||||||
user: userA,
|
user: userA,
|
||||||
@@ -198,7 +198,7 @@ describe("RoomMember", function() {
|
|||||||
name: "Alice",
|
name: "Alice",
|
||||||
});
|
});
|
||||||
|
|
||||||
let inviteEvent = utils.mkMembership({
|
const inviteEvent = utils.mkMembership({
|
||||||
event: true,
|
event: true,
|
||||||
mship: "invite",
|
mship: "invite",
|
||||||
user: userB,
|
user: userB,
|
||||||
@@ -218,7 +218,7 @@ describe("RoomMember", function() {
|
|||||||
|
|
||||||
it("should set 'name' based on user_id, displayname and room state",
|
it("should set 'name' based on user_id, displayname and room state",
|
||||||
function() {
|
function() {
|
||||||
let roomState = {
|
const roomState = {
|
||||||
getStateEvents: function(type) {
|
getStateEvents: function(type) {
|
||||||
if (type !== "m.room.member") {
|
if (type !== "m.room.member") {
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let RoomState = sdk.RoomState;
|
const RoomState = sdk.RoomState;
|
||||||
let RoomMember = sdk.RoomMember;
|
const RoomMember = sdk.RoomMember;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("RoomState", function() {
|
describe("RoomState", function() {
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let userA = "@alice:bar";
|
const userA = "@alice:bar";
|
||||||
let userB = "@bob:bar";
|
const userB = "@bob:bar";
|
||||||
let state;
|
let state;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -40,7 +40,7 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return a member for each m.room.member event", function() {
|
it("should return a member for each m.room.member event", function() {
|
||||||
let members = state.getMembers();
|
const members = state.getMembers();
|
||||||
expect(members.length).toEqual(2);
|
expect(members.length).toEqual(2);
|
||||||
// ordering unimportant
|
// ordering unimportant
|
||||||
expect([userA, userB].indexOf(members[0].userId)).not.toEqual(-1);
|
expect([userA, userB].indexOf(members[0].userId)).not.toEqual(-1);
|
||||||
@@ -58,7 +58,7 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return a member which changes as state changes", function() {
|
it("should return a member which changes as state changes", function() {
|
||||||
let member = state.getMember(userB);
|
const member = state.getMember(userB);
|
||||||
expect(member.membership).toEqual("join");
|
expect(member.membership).toEqual("join");
|
||||||
expect(member.name).toEqual(userB);
|
expect(member.name).toEqual(userB);
|
||||||
|
|
||||||
@@ -81,14 +81,14 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should return a member which doesn't change when the state is updated",
|
it("should return a member which doesn't change when the state is updated",
|
||||||
function() {
|
function() {
|
||||||
let preLeaveUser = state.getSentinelMember(userA);
|
const preLeaveUser = state.getSentinelMember(userA);
|
||||||
state.setStateEvents([
|
state.setStateEvents([
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, user: userA, mship: "leave", event: true,
|
room: roomId, user: userA, mship: "leave", event: true,
|
||||||
name: "AliceIsGone",
|
name: "AliceIsGone",
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
let postLeaveUser = state.getSentinelMember(userA);
|
const postLeaveUser = state.getSentinelMember(userA);
|
||||||
|
|
||||||
expect(preLeaveUser.membership).toEqual("join");
|
expect(preLeaveUser.membership).toEqual("join");
|
||||||
expect(preLeaveUser.name).toEqual(userA);
|
expect(preLeaveUser.name).toEqual(userA);
|
||||||
@@ -111,7 +111,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should return a list of matching events if no state_key was specified",
|
it("should return a list of matching events if no state_key was specified",
|
||||||
function() {
|
function() {
|
||||||
let events = state.getStateEvents("m.room.member");
|
const events = state.getStateEvents("m.room.member");
|
||||||
expect(events.length).toEqual(2);
|
expect(events.length).toEqual(2);
|
||||||
// ordering unimportant
|
// ordering unimportant
|
||||||
expect([userA, userB].indexOf(events[0].getStateKey())).not.toEqual(-1);
|
expect([userA, userB].indexOf(events[0].getStateKey())).not.toEqual(-1);
|
||||||
@@ -120,7 +120,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should return a single MatrixEvent if a state_key was specified",
|
it("should return a single MatrixEvent if a state_key was specified",
|
||||||
function() {
|
function() {
|
||||||
let event = state.getStateEvents("m.room.member", userA);
|
const event = state.getStateEvents("m.room.member", userA);
|
||||||
expect(event.getContent()).toEqual({
|
expect(event.getContent()).toEqual({
|
||||||
membership: "join",
|
membership: "join",
|
||||||
});
|
});
|
||||||
@@ -129,7 +129,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
describe("setStateEvents", function() {
|
describe("setStateEvents", function() {
|
||||||
it("should emit 'RoomState.members' for each m.room.member event", function() {
|
it("should emit 'RoomState.members' for each m.room.member event", function() {
|
||||||
let memberEvents = [
|
const memberEvents = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: "@cleo:bar", mship: "invite", room: roomId, event: true,
|
user: "@cleo:bar", mship: "invite", room: roomId, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -149,7 +149,7 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit 'RoomState.newMember' for each new member added", function() {
|
it("should emit 'RoomState.newMember' for each new member added", function() {
|
||||||
let memberEvents = [
|
const memberEvents = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: "@cleo:bar", mship: "invite", room: roomId, event: true,
|
user: "@cleo:bar", mship: "invite", room: roomId, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -168,7 +168,7 @@ describe("RoomState", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit 'RoomState.events' for each state event", function() {
|
it("should emit 'RoomState.events' for each state event", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: "@cleo:bar", mship: "invite", room: roomId, event: true,
|
user: "@cleo:bar", mship: "invite", room: roomId, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -198,7 +198,7 @@ describe("RoomState", function() {
|
|||||||
state.members[userA] = utils.mock(RoomMember);
|
state.members[userA] = utils.mock(RoomMember);
|
||||||
state.members[userB] = utils.mock(RoomMember);
|
state.members[userB] = utils.mock(RoomMember);
|
||||||
|
|
||||||
let powerLevelEvent = utils.mkEvent({
|
const powerLevelEvent = utils.mkEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
users_default: 10,
|
users_default: 10,
|
||||||
@@ -210,20 +210,20 @@ describe("RoomState", function() {
|
|||||||
state.setStateEvents([powerLevelEvent]);
|
state.setStateEvents([powerLevelEvent]);
|
||||||
|
|
||||||
expect(state.members[userA].setPowerLevelEvent).toHaveBeenCalledWith(
|
expect(state.members[userA].setPowerLevelEvent).toHaveBeenCalledWith(
|
||||||
powerLevelEvent
|
powerLevelEvent,
|
||||||
);
|
);
|
||||||
expect(state.members[userB].setPowerLevelEvent).toHaveBeenCalledWith(
|
expect(state.members[userB].setPowerLevelEvent).toHaveBeenCalledWith(
|
||||||
powerLevelEvent
|
powerLevelEvent,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should call setPowerLevelEvent on a new RoomMember if power levels exist",
|
it("should call setPowerLevelEvent on a new RoomMember if power levels exist",
|
||||||
function() {
|
function() {
|
||||||
let userC = "@cleo:bar";
|
const userC = "@cleo:bar";
|
||||||
let memberEvent = utils.mkMembership({
|
const memberEvent = utils.mkMembership({
|
||||||
mship: "join", user: userC, room: roomId, event: true,
|
mship: "join", user: userC, room: roomId, event: true,
|
||||||
});
|
});
|
||||||
let powerLevelEvent = utils.mkEvent({
|
const powerLevelEvent = utils.mkEvent({
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
users_default: 10,
|
users_default: 10,
|
||||||
@@ -247,21 +247,21 @@ describe("RoomState", function() {
|
|||||||
state.members[userA] = utils.mock(RoomMember);
|
state.members[userA] = utils.mock(RoomMember);
|
||||||
state.members[userB] = utils.mock(RoomMember);
|
state.members[userB] = utils.mock(RoomMember);
|
||||||
|
|
||||||
let memberEvent = utils.mkMembership({
|
const memberEvent = utils.mkMembership({
|
||||||
user: userB, mship: "leave", room: roomId, event: true,
|
user: userB, mship: "leave", room: roomId, event: true,
|
||||||
});
|
});
|
||||||
state.setStateEvents([memberEvent]);
|
state.setStateEvents([memberEvent]);
|
||||||
|
|
||||||
expect(state.members[userA].setMembershipEvent).not.toHaveBeenCalled();
|
expect(state.members[userA].setMembershipEvent).not.toHaveBeenCalled();
|
||||||
expect(state.members[userB].setMembershipEvent).toHaveBeenCalledWith(
|
expect(state.members[userB].setMembershipEvent).toHaveBeenCalledWith(
|
||||||
memberEvent, state
|
memberEvent, state,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("setTypingEvent", function() {
|
describe("setTypingEvent", function() {
|
||||||
it("should call setTypingEvent on each RoomMember", function() {
|
it("should call setTypingEvent on each RoomMember", function() {
|
||||||
let typingEvent = utils.mkEvent({
|
const typingEvent = utils.mkEvent({
|
||||||
type: "m.typing", room: roomId, event: true, content: {
|
type: "m.typing", room: roomId, event: true, content: {
|
||||||
user_ids: [userA],
|
user_ids: [userA],
|
||||||
},
|
},
|
||||||
@@ -272,10 +272,10 @@ describe("RoomState", function() {
|
|||||||
state.setTypingEvent(typingEvent);
|
state.setTypingEvent(typingEvent);
|
||||||
|
|
||||||
expect(state.members[userA].setTypingEvent).toHaveBeenCalledWith(
|
expect(state.members[userA].setTypingEvent).toHaveBeenCalledWith(
|
||||||
typingEvent
|
typingEvent,
|
||||||
);
|
);
|
||||||
expect(state.members[userB].setTypingEvent).toHaveBeenCalledWith(
|
expect(state.members[userB].setTypingEvent).toHaveBeenCalledWith(
|
||||||
typingEvent
|
typingEvent,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -284,7 +284,7 @@ describe("RoomState", function() {
|
|||||||
it("should say non-joined members may not send state",
|
it("should say non-joined members may not send state",
|
||||||
function() {
|
function() {
|
||||||
expect(state.maySendStateEvent(
|
expect(state.maySendStateEvent(
|
||||||
'm.room.name', "@nobody:nowhere"
|
'm.room.name', "@nobody:nowhere",
|
||||||
)).toEqual(false);
|
)).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ describe("RoomState", function() {
|
|||||||
it("should say members with power >=50 may send state with power level event " +
|
it("should say members with power >=50 may send state with power level event " +
|
||||||
"but no state default",
|
"but no state default",
|
||||||
function() {
|
function() {
|
||||||
let powerLevelEvent = {
|
const powerLevelEvent = {
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
users_default: 10,
|
users_default: 10,
|
||||||
@@ -316,7 +316,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should obey state_default",
|
it("should obey state_default",
|
||||||
function() {
|
function() {
|
||||||
let powerLevelEvent = {
|
const powerLevelEvent = {
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
users_default: 10,
|
users_default: 10,
|
||||||
@@ -337,7 +337,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should honour explicit event power levels in the power_levels event",
|
it("should honour explicit event power levels in the power_levels event",
|
||||||
function() {
|
function() {
|
||||||
let powerLevelEvent = {
|
const powerLevelEvent = {
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
events: {
|
events: {
|
||||||
@@ -367,7 +367,7 @@ describe("RoomState", function() {
|
|||||||
it("should say non-joined members may not send events",
|
it("should say non-joined members may not send events",
|
||||||
function() {
|
function() {
|
||||||
expect(state.maySendEvent(
|
expect(state.maySendEvent(
|
||||||
'm.room.message', "@nobody:nowhere"
|
'm.room.message', "@nobody:nowhere",
|
||||||
)).toEqual(false);
|
)).toEqual(false);
|
||||||
expect(state.maySendMessage("@nobody:nowhere")).toEqual(false);
|
expect(state.maySendMessage("@nobody:nowhere")).toEqual(false);
|
||||||
});
|
});
|
||||||
@@ -380,7 +380,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should obey events_default",
|
it("should obey events_default",
|
||||||
function() {
|
function() {
|
||||||
let powerLevelEvent = {
|
const powerLevelEvent = {
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
users_default: 10,
|
users_default: 10,
|
||||||
@@ -404,7 +404,7 @@ describe("RoomState", function() {
|
|||||||
|
|
||||||
it("should honour explicit event power levels in the power_levels event",
|
it("should honour explicit event power levels in the power_levels event",
|
||||||
function() {
|
function() {
|
||||||
let powerLevelEvent = {
|
const powerLevelEvent = {
|
||||||
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
type: "m.room.power_levels", room: roomId, user: userA, event: true,
|
||||||
content: {
|
content: {
|
||||||
events: {
|
events: {
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let Room = sdk.Room;
|
const Room = sdk.Room;
|
||||||
let RoomState = sdk.RoomState;
|
const RoomState = sdk.RoomState;
|
||||||
let MatrixEvent = sdk.MatrixEvent;
|
const MatrixEvent = sdk.MatrixEvent;
|
||||||
let EventStatus = sdk.EventStatus;
|
const EventStatus = sdk.EventStatus;
|
||||||
let EventTimeline = sdk.EventTimeline;
|
const EventTimeline = sdk.EventTimeline;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("Room", function() {
|
describe("Room", function() {
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let userA = "@alice:bar";
|
const userA = "@alice:bar";
|
||||||
let userB = "@bertha:bar";
|
const userB = "@bertha:bar";
|
||||||
let userC = "@clarissa:bar";
|
const userC = "@clarissa:bar";
|
||||||
let userD = "@dorothy:bar";
|
const userD = "@dorothy:bar";
|
||||||
let room;
|
let room;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -26,7 +26,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("getAvatarUrl", function() {
|
describe("getAvatarUrl", function() {
|
||||||
let hsUrl = "https://my.home.server";
|
const hsUrl = "https://my.home.server";
|
||||||
|
|
||||||
it("should return the URL from m.room.avatar preferentially", function() {
|
it("should return the URL from m.room.avatar preferentially", function() {
|
||||||
room.currentState.getStateEvents.andCallFake(function(type, key) {
|
room.currentState.getStateEvents.andCallFake(function(type, key) {
|
||||||
@@ -43,7 +43,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let url = room.getAvatarUrl(hsUrl);
|
const url = room.getAvatarUrl(hsUrl);
|
||||||
// we don't care about how the mxc->http conversion is done, other
|
// we don't care about how the mxc->http conversion is done, other
|
||||||
// than it contains the mxc body.
|
// than it contains the mxc body.
|
||||||
expect(url.indexOf("flibble/wibble")).not.toEqual(-1);
|
expect(url.indexOf("flibble/wibble")).not.toEqual(-1);
|
||||||
@@ -51,13 +51,13 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should return an identicon HTTP URL if allowDefault was set and there " +
|
it("should return an identicon HTTP URL if allowDefault was set and there " +
|
||||||
"was no m.room.avatar event", function() {
|
"was no m.room.avatar event", function() {
|
||||||
let url = room.getAvatarUrl(hsUrl, 64, 64, "crop", true);
|
const url = room.getAvatarUrl(hsUrl, 64, 64, "crop", true);
|
||||||
expect(url.indexOf("http")).toEqual(0); // don't care about form
|
expect(url.indexOf("http")).toEqual(0); // don't care about form
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return nothing if there is no m.room.avatar and allowDefault=false",
|
it("should return nothing if there is no m.room.avatar and allowDefault=false",
|
||||||
function() {
|
function() {
|
||||||
let url = room.getAvatarUrl(hsUrl, 64, 64, "crop", false);
|
const url = room.getAvatarUrl(hsUrl, 64, 64, "crop", false);
|
||||||
expect(url).toEqual(null);
|
expect(url).toEqual(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -83,7 +83,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("addLiveEvents", function() {
|
describe("addLiveEvents", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "changing room name", event: true,
|
room: roomId, user: userA, msg: "changing room name", event: true,
|
||||||
}),
|
}),
|
||||||
@@ -95,7 +95,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should call RoomState.setTypingEvent on m.typing events", function() {
|
it("should call RoomState.setTypingEvent on m.typing events", function() {
|
||||||
room.currentState = utils.mock(RoomState);
|
room.currentState = utils.mock(RoomState);
|
||||||
let typing = utils.mkEvent({
|
const typing = utils.mkEvent({
|
||||||
room: roomId, type: "m.typing", event: true, content: {
|
room: roomId, type: "m.typing", event: true, content: {
|
||||||
user_ids: [userA],
|
user_ids: [userA],
|
||||||
},
|
},
|
||||||
@@ -112,7 +112,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should replace a timeline event if dupe strategy is 'replace'", function() {
|
it("should replace a timeline event if dupe strategy is 'replace'", function() {
|
||||||
// make a duplicate
|
// make a duplicate
|
||||||
let dupe = utils.mkMessage({
|
const dupe = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "dupe", event: true,
|
room: roomId, user: userA, msg: "dupe", event: true,
|
||||||
});
|
});
|
||||||
dupe.event.event_id = events[0].getId();
|
dupe.event.event_id = events[0].getId();
|
||||||
@@ -124,7 +124,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should ignore a given dupe event if dupe strategy is 'ignore'", function() {
|
it("should ignore a given dupe event if dupe strategy is 'ignore'", function() {
|
||||||
// make a duplicate
|
// make a duplicate
|
||||||
let dupe = utils.mkMessage({
|
const dupe = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "dupe", event: true,
|
room: roomId, user: userA, msg: "dupe", event: true,
|
||||||
});
|
});
|
||||||
dupe.event.event_id = events[0].getId();
|
dupe.event.event_id = events[0].getId();
|
||||||
@@ -150,7 +150,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should call setStateEvents on the right RoomState with the right " +
|
it("should call setStateEvents on the right RoomState with the right " +
|
||||||
"forwardLooking value for new events", function() {
|
"forwardLooking value for new events", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -163,10 +163,10 @@ describe("Room", function() {
|
|||||||
];
|
];
|
||||||
room.addLiveEvents(events);
|
room.addLiveEvents(events);
|
||||||
expect(room.currentState.setStateEvents).toHaveBeenCalledWith(
|
expect(room.currentState.setStateEvents).toHaveBeenCalledWith(
|
||||||
[events[0]]
|
[events[0]],
|
||||||
);
|
);
|
||||||
expect(room.currentState.setStateEvents).toHaveBeenCalledWith(
|
expect(room.currentState.setStateEvents).toHaveBeenCalledWith(
|
||||||
[events[1]]
|
[events[1]],
|
||||||
);
|
);
|
||||||
expect(events[0].forwardLooking).toBe(true);
|
expect(events[0].forwardLooking).toBe(true);
|
||||||
expect(events[1].forwardLooking).toBe(true);
|
expect(events[1].forwardLooking).toBe(true);
|
||||||
@@ -174,7 +174,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should synthesize read receipts for the senders of events", function() {
|
it("should synthesize read receipts for the senders of events", function() {
|
||||||
let sentinel = {
|
const sentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Alice",
|
name: "Alice",
|
||||||
@@ -190,17 +190,17 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit Room.localEchoUpdated when a local echo is updated", function() {
|
it("should emit Room.localEchoUpdated when a local echo is updated", function() {
|
||||||
let localEvent = utils.mkMessage({
|
const localEvent = utils.mkMessage({
|
||||||
room: roomId, user: userA, event: true,
|
room: roomId, user: userA, event: true,
|
||||||
});
|
});
|
||||||
localEvent.status = EventStatus.SENDING;
|
localEvent.status = EventStatus.SENDING;
|
||||||
let localEventId = localEvent.getId();
|
const localEventId = localEvent.getId();
|
||||||
|
|
||||||
let remoteEvent = utils.mkMessage({
|
const remoteEvent = utils.mkMessage({
|
||||||
room: roomId, user: userA, event: true,
|
room: roomId, user: userA, event: true,
|
||||||
});
|
});
|
||||||
remoteEvent.event.unsigned = {transaction_id: "TXN_ID"};
|
remoteEvent.event.unsigned = {transaction_id: "TXN_ID"};
|
||||||
let remoteEventId = remoteEvent.getId();
|
const remoteEventId = remoteEvent.getId();
|
||||||
|
|
||||||
let callCount = 0;
|
let callCount = 0;
|
||||||
room.on("Room.localEchoUpdated",
|
room.on("Room.localEchoUpdated",
|
||||||
@@ -222,7 +222,7 @@ describe("Room", function() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
callCount += 1;
|
callCount += 1;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// first add the local echo
|
// first add the local echo
|
||||||
@@ -238,7 +238,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("addEventsToTimeline", function() {
|
describe("addEventsToTimeline", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "changing room name", event: true,
|
room: roomId, user: userA, msg: "changing room name", event: true,
|
||||||
}),
|
}),
|
||||||
@@ -278,12 +278,12 @@ describe("Room", function() {
|
|||||||
|
|
||||||
describe("event metadata handling", function() {
|
describe("event metadata handling", function() {
|
||||||
it("should set event.sender for new and old events", function() {
|
it("should set event.sender for new and old events", function() {
|
||||||
let sentinel = {
|
const sentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Alice",
|
name: "Alice",
|
||||||
};
|
};
|
||||||
let oldSentinel = {
|
const oldSentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Old Alice",
|
name: "Old Alice",
|
||||||
@@ -301,11 +301,11 @@ describe("Room", function() {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
let newEv = utils.mkEvent({
|
const newEv = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: userA, event: true,
|
type: "m.room.name", room: roomId, user: userA, event: true,
|
||||||
content: { name: "New Room Name" },
|
content: { name: "New Room Name" },
|
||||||
});
|
});
|
||||||
let oldEv = utils.mkEvent({
|
const oldEv = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: userA, event: true,
|
type: "m.room.name", room: roomId, user: userA, event: true,
|
||||||
content: { name: "Old Room Name" },
|
content: { name: "Old Room Name" },
|
||||||
});
|
});
|
||||||
@@ -317,12 +317,12 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should set event.target for new and old m.room.member events",
|
it("should set event.target for new and old m.room.member events",
|
||||||
function() {
|
function() {
|
||||||
let sentinel = {
|
const sentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Alice",
|
name: "Alice",
|
||||||
};
|
};
|
||||||
let oldSentinel = {
|
const oldSentinel = {
|
||||||
userId: userA,
|
userId: userA,
|
||||||
membership: "join",
|
membership: "join",
|
||||||
name: "Old Alice",
|
name: "Old Alice",
|
||||||
@@ -340,10 +340,10 @@ describe("Room", function() {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
let newEv = utils.mkMembership({
|
const newEv = utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
});
|
});
|
||||||
let oldEv = utils.mkMembership({
|
const oldEv = utils.mkMembership({
|
||||||
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
||||||
});
|
});
|
||||||
room.addLiveEvents([newEv]);
|
room.addLiveEvents([newEv]);
|
||||||
@@ -354,7 +354,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should call setStateEvents on the right RoomState with the right " +
|
it("should call setStateEvents on the right RoomState with the right " +
|
||||||
"forwardLooking value for old events", function() {
|
"forwardLooking value for old events", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
}),
|
}),
|
||||||
@@ -368,10 +368,10 @@ describe("Room", function() {
|
|||||||
|
|
||||||
room.addEventsToTimeline(events, true, room.getLiveTimeline());
|
room.addEventsToTimeline(events, true, room.getLiveTimeline());
|
||||||
expect(room.oldState.setStateEvents).toHaveBeenCalledWith(
|
expect(room.oldState.setStateEvents).toHaveBeenCalledWith(
|
||||||
[events[0]]
|
[events[0]],
|
||||||
);
|
);
|
||||||
expect(room.oldState.setStateEvents).toHaveBeenCalledWith(
|
expect(room.oldState.setStateEvents).toHaveBeenCalledWith(
|
||||||
[events[1]]
|
[events[1]],
|
||||||
);
|
);
|
||||||
expect(events[0].forwardLooking).toBe(false);
|
expect(events[0].forwardLooking).toBe(false);
|
||||||
expect(events[1].forwardLooking).toBe(false);
|
expect(events[1].forwardLooking).toBe(false);
|
||||||
@@ -379,8 +379,8 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let resetTimelineTests = function(timelineSupport) {
|
const resetTimelineTests = function(timelineSupport) {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "A message", event: true,
|
room: roomId, user: userA, msg: "A message", event: true,
|
||||||
}),
|
}),
|
||||||
@@ -404,8 +404,8 @@ describe("Room", function() {
|
|||||||
room.resetLiveTimeline();
|
room.resetLiveTimeline();
|
||||||
|
|
||||||
room.addLiveEvents([events[2]]);
|
room.addLiveEvents([events[2]]);
|
||||||
let oldState = room.getLiveTimeline().getState(EventTimeline.BACKWARDS);
|
const oldState = room.getLiveTimeline().getState(EventTimeline.BACKWARDS);
|
||||||
let newState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
|
const newState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
|
||||||
expect(room.getLiveTimeline().getEvents().length).toEqual(1);
|
expect(room.getLiveTimeline().getEvents().length).toEqual(1);
|
||||||
expect(oldState.getStateEvents("m.room.name", "")).toEqual(events[1]);
|
expect(oldState.getStateEvents("m.room.name", "")).toEqual(events[1]);
|
||||||
expect(newState.getStateEvents("m.room.name", "")).toEqual(events[2]);
|
expect(newState.getStateEvents("m.room.name", "")).toEqual(events[2]);
|
||||||
@@ -417,7 +417,7 @@ describe("Room", function() {
|
|||||||
room.resetLiveTimeline();
|
room.resetLiveTimeline();
|
||||||
|
|
||||||
room.addLiveEvents([events[2]]);
|
room.addLiveEvents([events[2]]);
|
||||||
let newLiveTimeline = room.getLiveTimeline();
|
const newLiveTimeline = room.getLiveTimeline();
|
||||||
expect(room.timeline).toEqual(newLiveTimeline.getEvents());
|
expect(room.timeline).toEqual(newLiveTimeline.getEvents());
|
||||||
expect(room.oldState).toEqual(
|
expect(room.oldState).toEqual(
|
||||||
newLiveTimeline.getState(EventTimeline.BACKWARDS));
|
newLiveTimeline.getState(EventTimeline.BACKWARDS));
|
||||||
@@ -434,7 +434,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
// make sure that the pagination token has been set before the
|
// make sure that the pagination token has been set before the
|
||||||
// event is emitted.
|
// event is emitted.
|
||||||
let tok = emitRoom.getLiveTimeline()
|
const tok = emitRoom.getLiveTimeline()
|
||||||
.getPaginationToken(EventTimeline.BACKWARDS);
|
.getPaginationToken(EventTimeline.BACKWARDS);
|
||||||
|
|
||||||
expect(tok).toEqual("pagToken");
|
expect(tok).toEqual("pagToken");
|
||||||
@@ -447,10 +447,10 @@ describe("Room", function() {
|
|||||||
" old timelines", function() {
|
" old timelines", function() {
|
||||||
room.addLiveEvents([events[0]]);
|
room.addLiveEvents([events[0]]);
|
||||||
expect(room.timeline.length).toEqual(1);
|
expect(room.timeline.length).toEqual(1);
|
||||||
let firstLiveTimeline = room.getLiveTimeline();
|
const firstLiveTimeline = room.getLiveTimeline();
|
||||||
room.resetLiveTimeline();
|
room.resetLiveTimeline();
|
||||||
|
|
||||||
let tl = room.getTimelineForEvent(events[0].getId());
|
const tl = room.getTimelineForEvent(events[0].getId());
|
||||||
expect(tl).toBe(timelineSupport ? firstLiveTimeline : null);
|
expect(tl).toBe(timelineSupport ? firstLiveTimeline : null);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -465,7 +465,7 @@ describe("Room", function() {
|
|||||||
room = new Room(roomId, {timelineSupport: true});
|
room = new Room(roomId, {timelineSupport: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "1111", event: true,
|
room: roomId, user: userA, msg: "1111", event: true,
|
||||||
}),
|
}),
|
||||||
@@ -492,7 +492,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should handle events in adjacent timelines", function() {
|
it("should handle events in adjacent timelines", function() {
|
||||||
let oldTimeline = room.addTimeline();
|
const oldTimeline = room.addTimeline();
|
||||||
oldTimeline.setNeighbouringTimeline(room.getLiveTimeline(), 'f');
|
oldTimeline.setNeighbouringTimeline(room.getLiveTimeline(), 'f');
|
||||||
room.getLiveTimeline().setNeighbouringTimeline(oldTimeline, 'b');
|
room.getLiveTimeline().setNeighbouringTimeline(oldTimeline, 'b');
|
||||||
|
|
||||||
@@ -508,7 +508,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return null for events in non-adjacent timelines", function() {
|
it("should return null for events in non-adjacent timelines", function() {
|
||||||
let oldTimeline = room.addTimeline();
|
const oldTimeline = room.addTimeline();
|
||||||
|
|
||||||
room.addEventsToTimeline([events[0]], false, oldTimeline);
|
room.addEventsToTimeline([events[0]], false, oldTimeline);
|
||||||
room.addLiveEvents([events[1]]);
|
room.addLiveEvents([events[1]]);
|
||||||
@@ -545,7 +545,7 @@ describe("Room", function() {
|
|||||||
{ userId: "@cleo:bar", membership: "leave" },
|
{ userId: "@cleo:bar", membership: "leave" },
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
let res = room.getJoinedMembers();
|
const res = room.getJoinedMembers();
|
||||||
expect(res.length).toEqual(1);
|
expect(res.length).toEqual(1);
|
||||||
expect(res[0].userId).toEqual("@alice:bar");
|
expect(res[0].userId).toEqual("@alice:bar");
|
||||||
});
|
});
|
||||||
@@ -556,7 +556,7 @@ describe("Room", function() {
|
|||||||
{ userId: "@bob:bar", membership: "invite" },
|
{ userId: "@bob:bar", membership: "invite" },
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
let res = room.getJoinedMembers();
|
const res = room.getJoinedMembers();
|
||||||
expect(res.length).toEqual(0);
|
expect(res.length).toEqual(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -607,14 +607,14 @@ describe("Room", function() {
|
|||||||
// event.type + "$" event.state_key : MatrixEvent
|
// event.type + "$" event.state_key : MatrixEvent
|
||||||
};
|
};
|
||||||
|
|
||||||
let setJoinRule = function(rule) {
|
const setJoinRule = function(rule) {
|
||||||
stateLookup["m.room.join_rules$"] = utils.mkEvent({
|
stateLookup["m.room.join_rules$"] = utils.mkEvent({
|
||||||
type: "m.room.join_rules", room: roomId, user: userA, content: {
|
type: "m.room.join_rules", room: roomId, user: userA, content: {
|
||||||
join_rule: rule,
|
join_rule: rule,
|
||||||
}, event: true,
|
}, event: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let setAliases = function(aliases, stateKey) {
|
const setAliases = function(aliases, stateKey) {
|
||||||
if (!stateKey) {
|
if (!stateKey) {
|
||||||
stateKey = "flibble";
|
stateKey = "flibble";
|
||||||
}
|
}
|
||||||
@@ -624,14 +624,14 @@ describe("Room", function() {
|
|||||||
}, event: true,
|
}, event: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let setRoomName = function(name) {
|
const setRoomName = function(name) {
|
||||||
stateLookup["m.room.name$"] = utils.mkEvent({
|
stateLookup["m.room.name$"] = utils.mkEvent({
|
||||||
type: "m.room.name", room: roomId, user: userA, content: {
|
type: "m.room.name", room: roomId, user: userA, content: {
|
||||||
name: name,
|
name: name,
|
||||||
}, event: true,
|
}, event: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let addMember = function(userId, state, opts) {
|
const addMember = function(userId, state, opts) {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
state = "join";
|
state = "join";
|
||||||
}
|
}
|
||||||
@@ -648,9 +648,9 @@ describe("Room", function() {
|
|||||||
stateLookup = {};
|
stateLookup = {};
|
||||||
room.currentState.getStateEvents.andCallFake(function(type, key) {
|
room.currentState.getStateEvents.andCallFake(function(type, key) {
|
||||||
if (key === undefined) {
|
if (key === undefined) {
|
||||||
let prefix = type + "$";
|
const prefix = type + "$";
|
||||||
let list = [];
|
const list = [];
|
||||||
for (let stateBlob in stateLookup) {
|
for (const stateBlob in stateLookup) {
|
||||||
if (!stateLookup.hasOwnProperty(stateBlob)) {
|
if (!stateLookup.hasOwnProperty(stateBlob)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -664,8 +664,8 @@ describe("Room", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
room.currentState.getMembers.andCallFake(function() {
|
room.currentState.getMembers.andCallFake(function() {
|
||||||
let memberEvents = room.currentState.getStateEvents("m.room.member");
|
const memberEvents = room.currentState.getStateEvents("m.room.member");
|
||||||
let members = [];
|
const members = [];
|
||||||
for (let i = 0; i < memberEvents.length; i++) {
|
for (let i = 0; i < memberEvents.length; i++) {
|
||||||
members.push({
|
members.push({
|
||||||
name: memberEvents[i].event.content &&
|
name: memberEvents[i].event.content &&
|
||||||
@@ -679,8 +679,8 @@ describe("Room", function() {
|
|||||||
return members;
|
return members;
|
||||||
});
|
});
|
||||||
room.currentState.getMember.andCallFake(function(userId) {
|
room.currentState.getMember.andCallFake(function(userId) {
|
||||||
let memberEvent = room.currentState.getStateEvents(
|
const memberEvent = room.currentState.getStateEvents(
|
||||||
"m.room.member", userId
|
"m.room.member", userId,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
name: memberEvent.event.content &&
|
name: memberEvent.event.content &&
|
||||||
@@ -696,7 +696,7 @@ describe("Room", function() {
|
|||||||
describe("Room.recalculate => Stripped State Events", function() {
|
describe("Room.recalculate => Stripped State Events", function() {
|
||||||
it("should set stripped state events as actual state events if the " +
|
it("should set stripped state events as actual state events if the " +
|
||||||
"room is an invite room", function() {
|
"room is an invite room", function() {
|
||||||
let roomName = "flibble";
|
const roomName = "flibble";
|
||||||
|
|
||||||
addMember(userA, "invite");
|
addMember(userA, "invite");
|
||||||
stateLookup["m.room.member$" + userA].event.invite_room_state = [
|
stateLookup["m.room.member$" + userA].event.invite_room_state = [
|
||||||
@@ -712,7 +712,7 @@ describe("Room", function() {
|
|||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
expect(room.currentState.setStateEvents).toHaveBeenCalled();
|
expect(room.currentState.setStateEvents).toHaveBeenCalled();
|
||||||
// first call, first arg (which is an array), first element in array
|
// first call, first arg (which is an array), first element in array
|
||||||
let fakeEvent = room.currentState.setStateEvents.calls[0].args[0][0];
|
const fakeEvent = room.currentState.setStateEvents.calls[0].args[0][0];
|
||||||
expect(fakeEvent.getContent()).toEqual({
|
expect(fakeEvent.getContent()).toEqual({
|
||||||
name: roomName,
|
name: roomName,
|
||||||
});
|
});
|
||||||
@@ -745,9 +745,9 @@ describe("Room", function() {
|
|||||||
addMember(userC);
|
addMember(userC);
|
||||||
addMember(userD);
|
addMember(userD);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
// we expect at least 1 member to be mentioned
|
// we expect at least 1 member to be mentioned
|
||||||
let others = [userB, userC, userD];
|
const others = [userB, userC, userD];
|
||||||
let found = false;
|
let found = false;
|
||||||
for (let i = 0; i < others.length; i++) {
|
for (let i = 0; i < others.length; i++) {
|
||||||
if (name.indexOf(others[i]) !== -1) {
|
if (name.indexOf(others[i]) !== -1) {
|
||||||
@@ -766,7 +766,7 @@ describe("Room", function() {
|
|||||||
addMember(userB);
|
addMember(userB);
|
||||||
addMember(userC);
|
addMember(userC);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
||||||
expect(name.indexOf(userC)).not.toEqual(-1, name);
|
expect(name.indexOf(userC)).not.toEqual(-1, name);
|
||||||
});
|
});
|
||||||
@@ -779,7 +779,7 @@ describe("Room", function() {
|
|||||||
addMember(userB);
|
addMember(userB);
|
||||||
addMember(userC);
|
addMember(userC);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
||||||
expect(name.indexOf(userC)).not.toEqual(-1, name);
|
expect(name.indexOf(userC)).not.toEqual(-1, name);
|
||||||
});
|
});
|
||||||
@@ -791,7 +791,7 @@ describe("Room", function() {
|
|||||||
addMember(userA);
|
addMember(userA);
|
||||||
addMember(userB);
|
addMember(userB);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -802,7 +802,7 @@ describe("Room", function() {
|
|||||||
addMember(userA);
|
addMember(userA);
|
||||||
addMember(userB);
|
addMember(userB);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -812,47 +812,47 @@ describe("Room", function() {
|
|||||||
addMember(userA, "invite", {user: userB});
|
addMember(userA, "invite", {user: userB});
|
||||||
addMember(userB);
|
addMember(userB);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
expect(name.indexOf(userB)).not.toEqual(-1, name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show the room alias if one exists for private " +
|
it("should show the room alias if one exists for private " +
|
||||||
"(invite join_rules) rooms if a room name doesn't exist.", function() {
|
"(invite join_rules) rooms if a room name doesn't exist.", function() {
|
||||||
let alias = "#room_alias:here";
|
const alias = "#room_alias:here";
|
||||||
setJoinRule("invite");
|
setJoinRule("invite");
|
||||||
setAliases([alias, "#another:one"]);
|
setAliases([alias, "#another:one"]);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual(alias);
|
expect(name).toEqual(alias);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show the room alias if one exists for public " +
|
it("should show the room alias if one exists for public " +
|
||||||
"(public join_rules) rooms if a room name doesn't exist.", function() {
|
"(public join_rules) rooms if a room name doesn't exist.", function() {
|
||||||
let alias = "#room_alias:here";
|
const alias = "#room_alias:here";
|
||||||
setJoinRule("public");
|
setJoinRule("public");
|
||||||
setAliases([alias, "#another:one"]);
|
setAliases([alias, "#another:one"]);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual(alias);
|
expect(name).toEqual(alias);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show the room name if one exists for private " +
|
it("should show the room name if one exists for private " +
|
||||||
"(invite join_rules) rooms.", function() {
|
"(invite join_rules) rooms.", function() {
|
||||||
let roomName = "A mighty name indeed";
|
const roomName = "A mighty name indeed";
|
||||||
setJoinRule("invite");
|
setJoinRule("invite");
|
||||||
setRoomName(roomName);
|
setRoomName(roomName);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual(roomName);
|
expect(name).toEqual(roomName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show the room name if one exists for public " +
|
it("should show the room name if one exists for public " +
|
||||||
"(public join_rules) rooms.", function() {
|
"(public join_rules) rooms.", function() {
|
||||||
let roomName = "A mighty name indeed";
|
const roomName = "A mighty name indeed";
|
||||||
setJoinRule("public");
|
setJoinRule("public");
|
||||||
setRoomName(roomName);
|
setRoomName(roomName);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual(roomName);
|
expect(name).toEqual(roomName);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -861,7 +861,7 @@ describe("Room", function() {
|
|||||||
setJoinRule("invite");
|
setJoinRule("invite");
|
||||||
addMember(userA);
|
addMember(userA);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual("Empty room");
|
expect(name).toEqual("Empty room");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -870,7 +870,7 @@ describe("Room", function() {
|
|||||||
setJoinRule("public");
|
setJoinRule("public");
|
||||||
addMember(userA);
|
addMember(userA);
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual("Empty room");
|
expect(name).toEqual("Empty room");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -878,7 +878,7 @@ describe("Room", function() {
|
|||||||
"alias or members in the room.",
|
"alias or members in the room.",
|
||||||
function() {
|
function() {
|
||||||
room.recalculate(userA);
|
room.recalculate(userA);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual("Empty room");
|
expect(name).toEqual("Empty room");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -889,7 +889,7 @@ describe("Room", function() {
|
|||||||
addMember(userA, 'join', {name: "Alice"});
|
addMember(userA, 'join', {name: "Alice"});
|
||||||
addMember(userB, "invite", {user: userA});
|
addMember(userB, "invite", {user: userA});
|
||||||
room.recalculate(userB);
|
room.recalculate(userB);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual("Invite from Alice");
|
expect(name).toEqual("Invite from Alice");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -899,20 +899,20 @@ describe("Room", function() {
|
|||||||
addMember(userA);
|
addMember(userA);
|
||||||
addMember(userB, "invite", {user: userA});
|
addMember(userB, "invite", {user: userA});
|
||||||
room.recalculate(userB);
|
room.recalculate(userB);
|
||||||
let name = room.name;
|
const name = room.name;
|
||||||
expect(name).toEqual("Invite from " + userA);
|
expect(name).toEqual("Invite from " + userA);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("receipts", function() {
|
describe("receipts", function() {
|
||||||
let eventToAck = utils.mkMessage({
|
const eventToAck = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "PLEASE ACKNOWLEDGE MY EXISTENCE",
|
room: roomId, user: userA, msg: "PLEASE ACKNOWLEDGE MY EXISTENCE",
|
||||||
event: true,
|
event: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
function mkReceipt(roomId, records) {
|
function mkReceipt(roomId, records) {
|
||||||
let content = {};
|
const content = {};
|
||||||
records.forEach(function(r) {
|
records.forEach(function(r) {
|
||||||
if (!content[r.eventId]) {
|
if (!content[r.eventId]) {
|
||||||
content[r.eventId] = {};
|
content[r.eventId] = {};
|
||||||
@@ -944,7 +944,7 @@ describe("Room", function() {
|
|||||||
describe("addReceipt", function() {
|
describe("addReceipt", function() {
|
||||||
it("should store the receipt so it can be obtained via getReceiptsForEvent",
|
it("should store the receipt so it can be obtained via getReceiptsForEvent",
|
||||||
function() {
|
function() {
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
||||||
]));
|
]));
|
||||||
@@ -959,12 +959,12 @@ describe("Room", function() {
|
|||||||
|
|
||||||
it("should emit an event when a receipt is added",
|
it("should emit an event when a receipt is added",
|
||||||
function() {
|
function() {
|
||||||
let listener = jasmine.createSpy('spy');
|
const listener = jasmine.createSpy('spy');
|
||||||
room.on("Room.receipt", listener);
|
room.on("Room.receipt", listener);
|
||||||
|
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
|
|
||||||
let receiptEvent = mkReceipt(roomId, [
|
const receiptEvent = mkReceipt(roomId, [
|
||||||
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -973,15 +973,15 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should clobber receipts based on type and user ID", function() {
|
it("should clobber receipts based on type and user ID", function() {
|
||||||
let nextEventToAck = utils.mkMessage({
|
const nextEventToAck = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "I AM HERE YOU KNOW",
|
room: roomId, user: userA, msg: "I AM HERE YOU KNOW",
|
||||||
event: true,
|
event: true,
|
||||||
});
|
});
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
||||||
]));
|
]));
|
||||||
let ts2 = 13787899999;
|
const ts2 = 13787899999;
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
mkRecord(nextEventToAck.getId(), "m.read", userB, ts2),
|
mkRecord(nextEventToAck.getId(), "m.read", userB, ts2),
|
||||||
]));
|
]));
|
||||||
@@ -996,27 +996,27 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should persist multiple receipts for a single event ID", function() {
|
it("should persist multiple receipts for a single event ID", function() {
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
||||||
mkRecord(eventToAck.getId(), "m.read", userC, ts),
|
mkRecord(eventToAck.getId(), "m.read", userC, ts),
|
||||||
mkRecord(eventToAck.getId(), "m.read", userD, ts),
|
mkRecord(eventToAck.getId(), "m.read", userD, ts),
|
||||||
]));
|
]));
|
||||||
expect(room.getUsersReadUpTo(eventToAck)).toEqual(
|
expect(room.getUsersReadUpTo(eventToAck)).toEqual(
|
||||||
[userB, userC, userD]
|
[userB, userC, userD],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should persist multiple receipts for a single receipt type", function() {
|
it("should persist multiple receipts for a single receipt type", function() {
|
||||||
let eventTwo = utils.mkMessage({
|
const eventTwo = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "2222",
|
room: roomId, user: userA, msg: "2222",
|
||||||
event: true,
|
event: true,
|
||||||
});
|
});
|
||||||
let eventThree = utils.mkMessage({
|
const eventThree = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "3333",
|
room: roomId, user: userA, msg: "3333",
|
||||||
event: true,
|
event: true,
|
||||||
});
|
});
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
||||||
mkRecord(eventTwo.getId(), "m.read", userC, ts),
|
mkRecord(eventTwo.getId(), "m.read", userC, ts),
|
||||||
@@ -1059,7 +1059,7 @@ describe("Room", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should prioritise the most recent event", function() {
|
it("should prioritise the most recent event", function() {
|
||||||
let events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "1111",
|
room: roomId, user: userA, msg: "1111",
|
||||||
event: true,
|
event: true,
|
||||||
@@ -1075,7 +1075,7 @@ describe("Room", function() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
room.addLiveEvents(events);
|
room.addLiveEvents(events);
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
|
|
||||||
// check it initialises correctly
|
// check it initialises correctly
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
@@ -1099,7 +1099,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
describe("getUsersReadUpTo", function() {
|
describe("getUsersReadUpTo", function() {
|
||||||
it("should return user IDs read up to the given event", function() {
|
it("should return user IDs read up to the given event", function() {
|
||||||
let ts = 13787898424;
|
const ts = 13787898424;
|
||||||
room.addReceipt(mkReceipt(roomId, [
|
room.addReceipt(mkReceipt(roomId, [
|
||||||
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
mkRecord(eventToAck.getId(), "m.read", userB, ts),
|
||||||
]));
|
]));
|
||||||
@@ -1110,7 +1110,7 @@ describe("Room", function() {
|
|||||||
|
|
||||||
describe("tags", function() {
|
describe("tags", function() {
|
||||||
function mkTags(roomId, tags) {
|
function mkTags(roomId, tags) {
|
||||||
let content = { "tags": tags };
|
const content = { "tags": tags };
|
||||||
return new MatrixEvent({
|
return new MatrixEvent({
|
||||||
content: content,
|
content: content,
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
@@ -1122,7 +1122,7 @@ describe("Room", function() {
|
|||||||
it("should set tags on rooms from event stream so " +
|
it("should set tags on rooms from event stream so " +
|
||||||
"they can be obtained by the tags property",
|
"they can be obtained by the tags property",
|
||||||
function() {
|
function() {
|
||||||
let tags = { "m.foo": { "order": 0.5 } };
|
const tags = { "m.foo": { "order": 0.5 } };
|
||||||
room.addTags(mkTags(roomId, tags));
|
room.addTags(mkTags(roomId, tags));
|
||||||
expect(room.tags).toEqual(tags);
|
expect(room.tags).toEqual(tags);
|
||||||
});
|
});
|
||||||
@@ -1130,11 +1130,11 @@ describe("Room", function() {
|
|||||||
it("should emit Room.tags event when new tags are " +
|
it("should emit Room.tags event when new tags are " +
|
||||||
"received on the event stream",
|
"received on the event stream",
|
||||||
function() {
|
function() {
|
||||||
let listener = jasmine.createSpy('spy');
|
const listener = jasmine.createSpy('spy');
|
||||||
room.on("Room.tags", listener);
|
room.on("Room.tags", listener);
|
||||||
|
|
||||||
let tags = { "m.foo": { "order": 0.5 } };
|
const tags = { "m.foo": { "order": 0.5 } };
|
||||||
let event = mkTags(roomId, tags);
|
const event = mkTags(roomId, tags);
|
||||||
room.addTags(event);
|
room.addTags(event);
|
||||||
expect(listener).toHaveBeenCalledWith(event, room);
|
expect(listener).toHaveBeenCalledWith(event, room);
|
||||||
});
|
});
|
||||||
@@ -1147,27 +1147,27 @@ describe("Room", function() {
|
|||||||
describe("addPendingEvent", function() {
|
describe("addPendingEvent", function() {
|
||||||
it("should add pending events to the pendingEventList if " +
|
it("should add pending events to the pendingEventList if " +
|
||||||
"pendingEventOrdering == 'detached'", function() {
|
"pendingEventOrdering == 'detached'", function() {
|
||||||
let room = new Room(roomId, {
|
const room = new Room(roomId, {
|
||||||
pendingEventOrdering: "detached",
|
pendingEventOrdering: "detached",
|
||||||
});
|
});
|
||||||
let eventA = utils.mkMessage({
|
const eventA = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "remote 1", event: true,
|
room: roomId, user: userA, msg: "remote 1", event: true,
|
||||||
});
|
});
|
||||||
let eventB = utils.mkMessage({
|
const eventB = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "local 1", event: true,
|
room: roomId, user: userA, msg: "local 1", event: true,
|
||||||
});
|
});
|
||||||
eventB.status = EventStatus.SENDING;
|
eventB.status = EventStatus.SENDING;
|
||||||
let eventC = utils.mkMessage({
|
const eventC = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "remote 2", event: true,
|
room: roomId, user: userA, msg: "remote 2", event: true,
|
||||||
});
|
});
|
||||||
room.addLiveEvents([eventA]);
|
room.addLiveEvents([eventA]);
|
||||||
room.addPendingEvent(eventB, "TXN1");
|
room.addPendingEvent(eventB, "TXN1");
|
||||||
room.addLiveEvents([eventC]);
|
room.addLiveEvents([eventC]);
|
||||||
expect(room.timeline).toEqual(
|
expect(room.timeline).toEqual(
|
||||||
[eventA, eventC]
|
[eventA, eventC],
|
||||||
);
|
);
|
||||||
expect(room.getPendingEvents()).toEqual(
|
expect(room.getPendingEvents()).toEqual(
|
||||||
[eventB]
|
[eventB],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1176,39 +1176,39 @@ describe("Room", function() {
|
|||||||
room = new Room(roomId, {
|
room = new Room(roomId, {
|
||||||
pendingEventOrdering: "chronological",
|
pendingEventOrdering: "chronological",
|
||||||
});
|
});
|
||||||
let eventA = utils.mkMessage({
|
const eventA = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "remote 1", event: true,
|
room: roomId, user: userA, msg: "remote 1", event: true,
|
||||||
});
|
});
|
||||||
let eventB = utils.mkMessage({
|
const eventB = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "local 1", event: true,
|
room: roomId, user: userA, msg: "local 1", event: true,
|
||||||
});
|
});
|
||||||
eventB.status = EventStatus.SENDING;
|
eventB.status = EventStatus.SENDING;
|
||||||
let eventC = utils.mkMessage({
|
const eventC = utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "remote 2", event: true,
|
room: roomId, user: userA, msg: "remote 2", event: true,
|
||||||
});
|
});
|
||||||
room.addLiveEvents([eventA]);
|
room.addLiveEvents([eventA]);
|
||||||
room.addPendingEvent(eventB, "TXN1");
|
room.addPendingEvent(eventB, "TXN1");
|
||||||
room.addLiveEvents([eventC]);
|
room.addLiveEvents([eventC]);
|
||||||
expect(room.timeline).toEqual(
|
expect(room.timeline).toEqual(
|
||||||
[eventA, eventB, eventC]
|
[eventA, eventB, eventC],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("updatePendingEvent", function() {
|
describe("updatePendingEvent", function() {
|
||||||
it("should remove cancelled events from the pending list", function() {
|
it("should remove cancelled events from the pending list", function() {
|
||||||
let room = new Room(roomId, {
|
const room = new Room(roomId, {
|
||||||
pendingEventOrdering: "detached",
|
pendingEventOrdering: "detached",
|
||||||
});
|
});
|
||||||
let eventA = utils.mkMessage({
|
const eventA = utils.mkMessage({
|
||||||
room: roomId, user: userA, event: true,
|
room: roomId, user: userA, event: true,
|
||||||
});
|
});
|
||||||
eventA.status = EventStatus.SENDING;
|
eventA.status = EventStatus.SENDING;
|
||||||
let eventId = eventA.getId();
|
const eventId = eventA.getId();
|
||||||
|
|
||||||
room.addPendingEvent(eventA, "TXN1");
|
room.addPendingEvent(eventA, "TXN1");
|
||||||
expect(room.getPendingEvents()).toEqual(
|
expect(room.getPendingEvents()).toEqual(
|
||||||
[eventA]
|
[eventA],
|
||||||
);
|
);
|
||||||
|
|
||||||
// the event has to have been failed or queued before it can be
|
// the event has to have been failed or queued before it can be
|
||||||
@@ -1233,16 +1233,16 @@ describe("Room", function() {
|
|||||||
|
|
||||||
|
|
||||||
it("should remove cancelled events from the timeline", function() {
|
it("should remove cancelled events from the timeline", function() {
|
||||||
let room = new Room(roomId);
|
const room = new Room(roomId);
|
||||||
let eventA = utils.mkMessage({
|
const eventA = utils.mkMessage({
|
||||||
room: roomId, user: userA, event: true,
|
room: roomId, user: userA, event: true,
|
||||||
});
|
});
|
||||||
eventA.status = EventStatus.SENDING;
|
eventA.status = EventStatus.SENDING;
|
||||||
let eventId = eventA.getId();
|
const eventId = eventA.getId();
|
||||||
|
|
||||||
room.addPendingEvent(eventA, "TXN1");
|
room.addPendingEvent(eventA, "TXN1");
|
||||||
expect(room.getLiveTimeline().getEvents()).toEqual(
|
expect(room.getLiveTimeline().getEvents()).toEqual(
|
||||||
[eventA]
|
[eventA],
|
||||||
);
|
);
|
||||||
|
|
||||||
// the event has to have been failed or queued before it can be
|
// the event has to have been failed or queued before it can be
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
// This file had a function whose name is all caps, which displeases eslint
|
// This file had a function whose name is all caps, which displeases eslint
|
||||||
/* eslint new-cap: "off" */
|
/* eslint new-cap: "off" */
|
||||||
|
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let MatrixScheduler = sdk.MatrixScheduler;
|
const MatrixScheduler = sdk.MatrixScheduler;
|
||||||
let MatrixError = sdk.MatrixError;
|
const MatrixError = sdk.MatrixError;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("MatrixScheduler", function() {
|
describe("MatrixScheduler", function() {
|
||||||
let scheduler;
|
let scheduler;
|
||||||
let retryFn, queueFn;
|
let retryFn;
|
||||||
|
let queueFn;
|
||||||
let defer;
|
let defer;
|
||||||
let roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
let eventA = utils.mkMessage({
|
const eventA = utils.mkMessage({
|
||||||
user: "@alice:bar", room: roomId, event: true,
|
user: "@alice:bar", room: roomId, event: true,
|
||||||
});
|
});
|
||||||
let eventB = utils.mkMessage({
|
const eventB = utils.mkMessage({
|
||||||
user: "@alice:bar", room: roomId, event: true,
|
user: "@alice:bar", room: roomId, event: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,8 +46,8 @@ describe("MatrixScheduler", function() {
|
|||||||
queueFn = function() {
|
queueFn = function() {
|
||||||
return "one_big_queue";
|
return "one_big_queue";
|
||||||
};
|
};
|
||||||
let deferA = q.defer();
|
const deferA = q.defer();
|
||||||
let deferB = q.defer();
|
const deferB = q.defer();
|
||||||
let resolvedA = false;
|
let resolvedA = false;
|
||||||
scheduler.setProcessFunction(function(event) {
|
scheduler.setProcessFunction(function(event) {
|
||||||
if (resolvedA) {
|
if (resolvedA) {
|
||||||
@@ -69,8 +70,8 @@ describe("MatrixScheduler", function() {
|
|||||||
|
|
||||||
it("should invoke the retryFn on failure and wait the amount of time specified",
|
it("should invoke the retryFn on failure and wait the amount of time specified",
|
||||||
function(done) {
|
function(done) {
|
||||||
let waitTimeMs = 1500;
|
const waitTimeMs = 1500;
|
||||||
let retryDefer = q.defer();
|
const retryDefer = q.defer();
|
||||||
retryFn = function() {
|
retryFn = function() {
|
||||||
retryDefer.resolve();
|
retryDefer.resolve();
|
||||||
return waitTimeMs;
|
return waitTimeMs;
|
||||||
@@ -115,8 +116,8 @@ describe("MatrixScheduler", function() {
|
|||||||
return "yep";
|
return "yep";
|
||||||
};
|
};
|
||||||
|
|
||||||
let deferA = q.defer();
|
const deferA = q.defer();
|
||||||
let deferB = q.defer();
|
const deferB = q.defer();
|
||||||
let procCount = 0;
|
let procCount = 0;
|
||||||
scheduler.setProcessFunction(function(ev) {
|
scheduler.setProcessFunction(function(ev) {
|
||||||
procCount += 1;
|
procCount += 1;
|
||||||
@@ -130,7 +131,7 @@ describe("MatrixScheduler", function() {
|
|||||||
expect(procCount).toBeLessThan(3);
|
expect(procCount).toBeLessThan(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
let globalA = scheduler.queueEvent(eventA);
|
const globalA = scheduler.queueEvent(eventA);
|
||||||
scheduler.queueEvent(eventB);
|
scheduler.queueEvent(eventB);
|
||||||
|
|
||||||
expect(procCount).toEqual(1);
|
expect(procCount).toEqual(1);
|
||||||
@@ -148,10 +149,10 @@ describe("MatrixScheduler", function() {
|
|||||||
// Expect to have processFn invoked for A&B.
|
// Expect to have processFn invoked for A&B.
|
||||||
// Resolve A.
|
// Resolve A.
|
||||||
// Expect to have processFn invoked for D.
|
// Expect to have processFn invoked for D.
|
||||||
let eventC = utils.mkMessage({user: "@a:bar", room: roomId, event: true});
|
const eventC = utils.mkMessage({user: "@a:bar", room: roomId, event: true});
|
||||||
let eventD = utils.mkMessage({user: "@b:bar", room: roomId, event: true});
|
const eventD = utils.mkMessage({user: "@b:bar", room: roomId, event: true});
|
||||||
|
|
||||||
let buckets = {};
|
const buckets = {};
|
||||||
buckets[eventA.getId()] = "queue_A";
|
buckets[eventA.getId()] = "queue_A";
|
||||||
buckets[eventD.getId()] = "queue_A";
|
buckets[eventD.getId()] = "queue_A";
|
||||||
buckets[eventB.getId()] = "queue_B";
|
buckets[eventB.getId()] = "queue_B";
|
||||||
@@ -164,12 +165,12 @@ describe("MatrixScheduler", function() {
|
|||||||
return buckets[event.getId()];
|
return buckets[event.getId()];
|
||||||
};
|
};
|
||||||
|
|
||||||
let expectOrder = [
|
const expectOrder = [
|
||||||
eventA.getId(), eventB.getId(), eventD.getId(),
|
eventA.getId(), eventB.getId(), eventD.getId(),
|
||||||
];
|
];
|
||||||
let deferA = q.defer();
|
const deferA = q.defer();
|
||||||
scheduler.setProcessFunction(function(event) {
|
scheduler.setProcessFunction(function(event) {
|
||||||
let id = expectOrder.shift();
|
const id = expectOrder.shift();
|
||||||
expect(id).toEqual(event.getId());
|
expect(id).toEqual(event.getId());
|
||||||
if (expectOrder.length === 0) {
|
if (expectOrder.length === 0) {
|
||||||
done();
|
done();
|
||||||
@@ -200,7 +201,7 @@ describe("MatrixScheduler", function() {
|
|||||||
queueFn = function() {
|
queueFn = function() {
|
||||||
return "yep";
|
return "yep";
|
||||||
};
|
};
|
||||||
let prom = scheduler.queueEvent(eventA);
|
const prom = scheduler.queueEvent(eventA);
|
||||||
expect(prom).toBeDefined();
|
expect(prom).toBeDefined();
|
||||||
expect(prom.then).toBeDefined();
|
expect(prom.then).toBeDefined();
|
||||||
});
|
});
|
||||||
@@ -228,15 +229,15 @@ describe("MatrixScheduler", function() {
|
|||||||
};
|
};
|
||||||
scheduler.queueEvent(eventA);
|
scheduler.queueEvent(eventA);
|
||||||
scheduler.queueEvent(eventB);
|
scheduler.queueEvent(eventB);
|
||||||
let queue = scheduler.getQueueForEvent(eventA);
|
const queue = scheduler.getQueueForEvent(eventA);
|
||||||
expect(queue.length).toEqual(2);
|
expect(queue.length).toEqual(2);
|
||||||
expect(queue).toEqual([eventA, eventB]);
|
expect(queue).toEqual([eventA, eventB]);
|
||||||
// modify the queue
|
// modify the queue
|
||||||
let eventC = utils.mkMessage(
|
const eventC = utils.mkMessage(
|
||||||
{user: "@a:bar", room: roomId, event: true}
|
{user: "@a:bar", room: roomId, event: true},
|
||||||
);
|
);
|
||||||
queue.push(eventC);
|
queue.push(eventC);
|
||||||
let queueAgain = scheduler.getQueueForEvent(eventA);
|
const queueAgain = scheduler.getQueueForEvent(eventA);
|
||||||
expect(queueAgain.length).toEqual(2);
|
expect(queueAgain.length).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -247,9 +248,9 @@ describe("MatrixScheduler", function() {
|
|||||||
};
|
};
|
||||||
scheduler.queueEvent(eventA);
|
scheduler.queueEvent(eventA);
|
||||||
scheduler.queueEvent(eventB);
|
scheduler.queueEvent(eventB);
|
||||||
let queue = scheduler.getQueueForEvent(eventA);
|
const queue = scheduler.getQueueForEvent(eventA);
|
||||||
queue[1].event.content.body = "foo";
|
queue[1].event.content.body = "foo";
|
||||||
let queueAgain = scheduler.getQueueForEvent(eventA);
|
const queueAgain = scheduler.getQueueForEvent(eventA);
|
||||||
expect(queueAgain[1].event.content.body).toEqual("foo");
|
expect(queueAgain[1].event.content.body).toEqual("foo");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -312,40 +313,40 @@ describe("MatrixScheduler", function() {
|
|||||||
expect(MatrixScheduler.QUEUE_MESSAGES(
|
expect(MatrixScheduler.QUEUE_MESSAGES(
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
user: "@alice:bar", room: roomId, mship: "join", event: true,
|
user: "@alice:bar", room: roomId, mship: "join", event: true,
|
||||||
})
|
}),
|
||||||
)).toEqual(null);
|
)).toEqual(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("RETRY_BACKOFF_RATELIMIT", function() {
|
describe("RETRY_BACKOFF_RATELIMIT", function() {
|
||||||
it("should wait at least the time given on M_LIMIT_EXCEEDED", function() {
|
it("should wait at least the time given on M_LIMIT_EXCEEDED", function() {
|
||||||
let res = MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
const res = MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
||||||
eventA, 1, new MatrixError({
|
eventA, 1, new MatrixError({
|
||||||
errcode: "M_LIMIT_EXCEEDED", retry_after_ms: 5000,
|
errcode: "M_LIMIT_EXCEEDED", retry_after_ms: 5000,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
expect(res >= 500).toBe(true, "Didn't wait long enough.");
|
expect(res >= 500).toBe(true, "Didn't wait long enough.");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should give up after 5 attempts", function() {
|
it("should give up after 5 attempts", function() {
|
||||||
let res = MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
const res = MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
||||||
eventA, 5, {}
|
eventA, 5, {},
|
||||||
);
|
);
|
||||||
expect(res).toBe(-1, "Didn't give up.");
|
expect(res).toBe(-1, "Didn't give up.");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should do exponential backoff", function() {
|
it("should do exponential backoff", function() {
|
||||||
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
||||||
eventA, 1, {}
|
eventA, 1, {},
|
||||||
)).toEqual(2000);
|
)).toEqual(2000);
|
||||||
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
||||||
eventA, 2, {}
|
eventA, 2, {},
|
||||||
)).toEqual(4000);
|
)).toEqual(4000);
|
||||||
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
||||||
eventA, 3, {}
|
eventA, 3, {},
|
||||||
)).toEqual(8000);
|
)).toEqual(8000);
|
||||||
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
expect(MatrixScheduler.RETRY_BACKOFF_RATELIMIT(
|
||||||
eventA, 4, {}
|
eventA, 4, {},
|
||||||
)).toEqual(16000);
|
)).toEqual(16000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let EventTimeline = sdk.EventTimeline;
|
const EventTimeline = sdk.EventTimeline;
|
||||||
let TimelineWindow = sdk.TimelineWindow;
|
const TimelineWindow = sdk.TimelineWindow;
|
||||||
let TimelineIndex = require("../../lib/timeline-window").TimelineIndex;
|
const TimelineIndex = require("../../lib/timeline-window").TimelineIndex;
|
||||||
|
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
let ROOM_ID = "roomId";
|
const ROOM_ID = "roomId";
|
||||||
let USER_ID = "userId";
|
const USER_ID = "userId";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create a timeline with a bunch (default 3) events.
|
* create a timeline with a bunch (default 3) events.
|
||||||
@@ -23,12 +23,12 @@ function createTimeline(numEvents, baseIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XXX: this is a horrid hack
|
// XXX: this is a horrid hack
|
||||||
let timelineSet = { room: { roomId: ROOM_ID }};
|
const timelineSet = { room: { roomId: ROOM_ID }};
|
||||||
timelineSet.room.getUnfilteredTimelineSet = function() {
|
timelineSet.room.getUnfilteredTimelineSet = function() {
|
||||||
return timelineSet;
|
return timelineSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
let timeline = new EventTimeline(timelineSet);
|
const timeline = new EventTimeline(timelineSet);
|
||||||
|
|
||||||
// add the events after the baseIndex first
|
// add the events after the baseIndex first
|
||||||
addEventsToTimeline(timeline, numEvents - baseIndex, false);
|
addEventsToTimeline(timeline, numEvents - baseIndex, false);
|
||||||
@@ -46,7 +46,7 @@ function addEventsToTimeline(timeline, numEvents, atStart) {
|
|||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: ROOM_ID, user: USER_ID,
|
room: ROOM_ID, user: USER_ID,
|
||||||
event: true,
|
event: true,
|
||||||
}), atStart
|
}), atStart,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,8 +56,8 @@ function addEventsToTimeline(timeline, numEvents, atStart) {
|
|||||||
* create a pair of linked timelines
|
* create a pair of linked timelines
|
||||||
*/
|
*/
|
||||||
function createLinkedTimelines() {
|
function createLinkedTimelines() {
|
||||||
let tl1 = createTimeline();
|
const tl1 = createTimeline();
|
||||||
let tl2 = createTimeline();
|
const tl2 = createTimeline();
|
||||||
tl1.setNeighbouringTimeline(tl2, EventTimeline.FORWARDS);
|
tl1.setNeighbouringTimeline(tl2, EventTimeline.FORWARDS);
|
||||||
tl2.setNeighbouringTimeline(tl1, EventTimeline.BACKWARDS);
|
tl2.setNeighbouringTimeline(tl1, EventTimeline.BACKWARDS);
|
||||||
return [tl1, tl2];
|
return [tl1, tl2];
|
||||||
@@ -71,41 +71,42 @@ describe("TimelineIndex", function() {
|
|||||||
|
|
||||||
describe("minIndex", function() {
|
describe("minIndex", function() {
|
||||||
it("should return the min index relative to BaseIndex", function() {
|
it("should return the min index relative to BaseIndex", function() {
|
||||||
let timelineIndex = new TimelineIndex(createTimeline(), 0);
|
const timelineIndex = new TimelineIndex(createTimeline(), 0);
|
||||||
expect(timelineIndex.minIndex()).toEqual(-1);
|
expect(timelineIndex.minIndex()).toEqual(-1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("maxIndex", function() {
|
describe("maxIndex", function() {
|
||||||
it("should return the max index relative to BaseIndex", function() {
|
it("should return the max index relative to BaseIndex", function() {
|
||||||
let timelineIndex = new TimelineIndex(createTimeline(), 0);
|
const timelineIndex = new TimelineIndex(createTimeline(), 0);
|
||||||
expect(timelineIndex.maxIndex()).toEqual(2);
|
expect(timelineIndex.maxIndex()).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("advance", function() {
|
describe("advance", function() {
|
||||||
it("should advance up to the end of the timeline", function() {
|
it("should advance up to the end of the timeline", function() {
|
||||||
let timelineIndex = new TimelineIndex(createTimeline(), 0);
|
const timelineIndex = new TimelineIndex(createTimeline(), 0);
|
||||||
let result = timelineIndex.advance(3);
|
const result = timelineIndex.advance(3);
|
||||||
expect(result).toEqual(2);
|
expect(result).toEqual(2);
|
||||||
expect(timelineIndex.index).toEqual(2);
|
expect(timelineIndex.index).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should retreat back to the start of the timeline", function() {
|
it("should retreat back to the start of the timeline", function() {
|
||||||
let timelineIndex = new TimelineIndex(createTimeline(), 0);
|
const timelineIndex = new TimelineIndex(createTimeline(), 0);
|
||||||
let result = timelineIndex.advance(-2);
|
const result = timelineIndex.advance(-2);
|
||||||
expect(result).toEqual(-1);
|
expect(result).toEqual(-1);
|
||||||
expect(timelineIndex.index).toEqual(-1);
|
expect(timelineIndex.index).toEqual(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should advance into the next timeline", function() {
|
it("should advance into the next timeline", function() {
|
||||||
let timelines = createLinkedTimelines();
|
const timelines = createLinkedTimelines();
|
||||||
let tl1 = timelines[0], tl2 = timelines[1];
|
const tl1 = timelines[0];
|
||||||
|
const tl2 = timelines[1];
|
||||||
|
|
||||||
// initialise the index pointing at the end of the first timeline
|
// initialise the index pointing at the end of the first timeline
|
||||||
let timelineIndex = new TimelineIndex(tl1, 2);
|
const timelineIndex = new TimelineIndex(tl1, 2);
|
||||||
|
|
||||||
let result = timelineIndex.advance(1);
|
const result = timelineIndex.advance(1);
|
||||||
expect(result).toEqual(1);
|
expect(result).toEqual(1);
|
||||||
expect(timelineIndex.timeline).toBe(tl2);
|
expect(timelineIndex.timeline).toBe(tl2);
|
||||||
|
|
||||||
@@ -116,14 +117,15 @@ describe("TimelineIndex", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should retreat into the previous timeline", function() {
|
it("should retreat into the previous timeline", function() {
|
||||||
let timelines = createLinkedTimelines();
|
const timelines = createLinkedTimelines();
|
||||||
let tl1 = timelines[0], tl2 = timelines[1];
|
const tl1 = timelines[0];
|
||||||
|
const tl2 = timelines[1];
|
||||||
|
|
||||||
// initialise the index pointing at the start of the second
|
// initialise the index pointing at the start of the second
|
||||||
// timeline
|
// timeline
|
||||||
let timelineIndex = new TimelineIndex(tl2, -1);
|
const timelineIndex = new TimelineIndex(tl2, -1);
|
||||||
|
|
||||||
let result = timelineIndex.advance(-1);
|
const result = timelineIndex.advance(-1);
|
||||||
expect(result).toEqual(-1);
|
expect(result).toEqual(-1);
|
||||||
expect(timelineIndex.timeline).toBe(tl1);
|
expect(timelineIndex.timeline).toBe(tl1);
|
||||||
expect(timelineIndex.index).toEqual(1);
|
expect(timelineIndex.index).toEqual(1);
|
||||||
@@ -132,8 +134,8 @@ describe("TimelineIndex", function() {
|
|||||||
|
|
||||||
describe("retreat", function() {
|
describe("retreat", function() {
|
||||||
it("should retreat up to the start of the timeline", function() {
|
it("should retreat up to the start of the timeline", function() {
|
||||||
let timelineIndex = new TimelineIndex(createTimeline(), 0);
|
const timelineIndex = new TimelineIndex(createTimeline(), 0);
|
||||||
let result = timelineIndex.retreat(2);
|
const result = timelineIndex.retreat(2);
|
||||||
expect(result).toEqual(1);
|
expect(result).toEqual(1);
|
||||||
expect(timelineIndex.index).toEqual(-1);
|
expect(timelineIndex.index).toEqual(-1);
|
||||||
});
|
});
|
||||||
@@ -146,7 +148,8 @@ describe("TimelineWindow", function() {
|
|||||||
* create a dummy eventTimelineSet and client, and a TimelineWindow
|
* create a dummy eventTimelineSet and client, and a TimelineWindow
|
||||||
* attached to them.
|
* attached to them.
|
||||||
*/
|
*/
|
||||||
let timelineSet, client;
|
let timelineSet;
|
||||||
|
let client;
|
||||||
function createWindow(timeline, opts) {
|
function createWindow(timeline, opts) {
|
||||||
timelineSet = {};
|
timelineSet = {};
|
||||||
client = {};
|
client = {};
|
||||||
@@ -164,50 +167,50 @@ describe("TimelineWindow", function() {
|
|||||||
|
|
||||||
describe("load", function() {
|
describe("load", function() {
|
||||||
it("should initialise from the live timeline", function(done) {
|
it("should initialise from the live timeline", function(done) {
|
||||||
let liveTimeline = createTimeline();
|
const liveTimeline = createTimeline();
|
||||||
let room = {};
|
const room = {};
|
||||||
room.getLiveTimeline = function() {
|
room.getLiveTimeline = function() {
|
||||||
return liveTimeline;
|
return liveTimeline;
|
||||||
};
|
};
|
||||||
|
|
||||||
let timelineWindow = new TimelineWindow(undefined, room);
|
const timelineWindow = new TimelineWindow(undefined, room);
|
||||||
timelineWindow.load(undefined, 2).then(function() {
|
timelineWindow.load(undefined, 2).then(function() {
|
||||||
let expectedEvents = liveTimeline.getEvents().slice(1);
|
const expectedEvents = liveTimeline.getEvents().slice(1);
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should initialise from a specific event", function(done) {
|
it("should initialise from a specific event", function(done) {
|
||||||
let timeline = createTimeline();
|
const timeline = createTimeline();
|
||||||
let eventId = timeline.getEvents()[1].getId();
|
const eventId = timeline.getEvents()[1].getId();
|
||||||
|
|
||||||
let timelineSet = {};
|
const timelineSet = {};
|
||||||
let client = {};
|
const client = {};
|
||||||
client.getEventTimeline = function(timelineSet0, eventId0) {
|
client.getEventTimeline = function(timelineSet0, eventId0) {
|
||||||
expect(timelineSet0).toBe(timelineSet);
|
expect(timelineSet0).toBe(timelineSet);
|
||||||
expect(eventId0).toEqual(eventId);
|
expect(eventId0).toEqual(eventId);
|
||||||
return q(timeline);
|
return q(timeline);
|
||||||
};
|
};
|
||||||
|
|
||||||
let timelineWindow = new TimelineWindow(client, timelineSet);
|
const timelineWindow = new TimelineWindow(client, timelineSet);
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = timeline.getEvents();
|
const expectedEvents = timeline.getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("canPaginate should return false until load has returned",
|
it("canPaginate should return false until load has returned",
|
||||||
function(done) {
|
function(done) {
|
||||||
let timeline = createTimeline();
|
const timeline = createTimeline();
|
||||||
timeline.setPaginationToken("toktok1", EventTimeline.BACKWARDS);
|
timeline.setPaginationToken("toktok1", EventTimeline.BACKWARDS);
|
||||||
timeline.setPaginationToken("toktok2", EventTimeline.FORWARDS);
|
timeline.setPaginationToken("toktok2", EventTimeline.FORWARDS);
|
||||||
|
|
||||||
let eventId = timeline.getEvents()[1].getId();
|
const eventId = timeline.getEvents()[1].getId();
|
||||||
|
|
||||||
let timelineSet = {};
|
const timelineSet = {};
|
||||||
let client = {};
|
const client = {};
|
||||||
|
|
||||||
let timelineWindow = new TimelineWindow(client, timelineSet);
|
const timelineWindow = new TimelineWindow(client, timelineSet);
|
||||||
|
|
||||||
client.getEventTimeline = function(timelineSet0, eventId0) {
|
client.getEventTimeline = function(timelineSet0, eventId0) {
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -218,7 +221,7 @@ describe("TimelineWindow", function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = timeline.getEvents();
|
const expectedEvents = timeline.getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
.toBe(true);
|
.toBe(true);
|
||||||
@@ -231,12 +234,12 @@ describe("TimelineWindow", function() {
|
|||||||
describe("pagination", function() {
|
describe("pagination", function() {
|
||||||
it("should be able to advance across the initial timeline",
|
it("should be able to advance across the initial timeline",
|
||||||
function(done) {
|
function(done) {
|
||||||
let timeline = createTimeline();
|
const timeline = createTimeline();
|
||||||
let eventId = timeline.getEvents()[1].getId();
|
const eventId = timeline.getEvents()[1].getId();
|
||||||
let timelineWindow = createWindow(timeline);
|
const timelineWindow = createWindow(timeline);
|
||||||
|
|
||||||
timelineWindow.load(eventId, 1).then(function() {
|
timelineWindow.load(eventId, 1).then(function() {
|
||||||
let expectedEvents = [timeline.getEvents()[1]];
|
const expectedEvents = [timeline.getEvents()[1]];
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -247,7 +250,7 @@ describe("TimelineWindow", function() {
|
|||||||
return timelineWindow.paginate(EventTimeline.FORWARDS, 2);
|
return timelineWindow.paginate(EventTimeline.FORWARDS, 2);
|
||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
let expectedEvents = timeline.getEvents().slice(1);
|
const expectedEvents = timeline.getEvents().slice(1);
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -262,7 +265,7 @@ describe("TimelineWindow", function() {
|
|||||||
return timelineWindow.paginate(EventTimeline.BACKWARDS, 2);
|
return timelineWindow.paginate(EventTimeline.BACKWARDS, 2);
|
||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
let expectedEvents = timeline.getEvents();
|
const expectedEvents = timeline.getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -276,12 +279,12 @@ describe("TimelineWindow", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should advance into next timeline", function(done) {
|
it("should advance into next timeline", function(done) {
|
||||||
let tls = createLinkedTimelines();
|
const tls = createLinkedTimelines();
|
||||||
let eventId = tls[0].getEvents()[1].getId();
|
const eventId = tls[0].getEvents()[1].getId();
|
||||||
let timelineWindow = createWindow(tls[0], {windowLimit: 5});
|
const timelineWindow = createWindow(tls[0], {windowLimit: 5});
|
||||||
|
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = tls[0].getEvents();
|
const expectedEvents = tls[0].getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -292,7 +295,7 @@ describe("TimelineWindow", function() {
|
|||||||
return timelineWindow.paginate(EventTimeline.FORWARDS, 2);
|
return timelineWindow.paginate(EventTimeline.FORWARDS, 2);
|
||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
let expectedEvents = tls[0].getEvents()
|
const expectedEvents = tls[0].getEvents()
|
||||||
.concat(tls[1].getEvents().slice(0, 2));
|
.concat(tls[1].getEvents().slice(0, 2));
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
@@ -306,7 +309,7 @@ describe("TimelineWindow", function() {
|
|||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
// the windowLimit should have made us drop an event from
|
// the windowLimit should have made us drop an event from
|
||||||
// tls[0]
|
// tls[0]
|
||||||
let expectedEvents = tls[0].getEvents().slice(1)
|
const expectedEvents = tls[0].getEvents().slice(1)
|
||||||
.concat(tls[1].getEvents());
|
.concat(tls[1].getEvents());
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
@@ -321,12 +324,12 @@ describe("TimelineWindow", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should retreat into previous timeline", function(done) {
|
it("should retreat into previous timeline", function(done) {
|
||||||
let tls = createLinkedTimelines();
|
const tls = createLinkedTimelines();
|
||||||
let eventId = tls[1].getEvents()[1].getId();
|
const eventId = tls[1].getEvents()[1].getId();
|
||||||
let timelineWindow = createWindow(tls[1], {windowLimit: 5});
|
const timelineWindow = createWindow(tls[1], {windowLimit: 5});
|
||||||
|
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = tls[1].getEvents();
|
const expectedEvents = tls[1].getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -337,7 +340,7 @@ describe("TimelineWindow", function() {
|
|||||||
return timelineWindow.paginate(EventTimeline.BACKWARDS, 2);
|
return timelineWindow.paginate(EventTimeline.BACKWARDS, 2);
|
||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
let expectedEvents = tls[0].getEvents().slice(1, 3)
|
const expectedEvents = tls[0].getEvents().slice(1, 3)
|
||||||
.concat(tls[1].getEvents());
|
.concat(tls[1].getEvents());
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
@@ -351,7 +354,7 @@ describe("TimelineWindow", function() {
|
|||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
// the windowLimit should have made us drop an event from
|
// the windowLimit should have made us drop an event from
|
||||||
// tls[1]
|
// tls[1]
|
||||||
let expectedEvents = tls[0].getEvents()
|
const expectedEvents = tls[0].getEvents()
|
||||||
.concat(tls[1].getEvents().slice(0, 2));
|
.concat(tls[1].getEvents().slice(0, 2));
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
@@ -366,11 +369,11 @@ describe("TimelineWindow", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should make forward pagination requests", function(done) {
|
it("should make forward pagination requests", function(done) {
|
||||||
let timeline = createTimeline();
|
const timeline = createTimeline();
|
||||||
timeline.setPaginationToken("toktok", EventTimeline.FORWARDS);
|
timeline.setPaginationToken("toktok", EventTimeline.FORWARDS);
|
||||||
|
|
||||||
let timelineWindow = createWindow(timeline, {windowLimit: 5});
|
const timelineWindow = createWindow(timeline, {windowLimit: 5});
|
||||||
let eventId = timeline.getEvents()[1].getId();
|
const eventId = timeline.getEvents()[1].getId();
|
||||||
|
|
||||||
client.paginateEventTimeline = function(timeline0, opts) {
|
client.paginateEventTimeline = function(timeline0, opts) {
|
||||||
expect(timeline0).toBe(timeline);
|
expect(timeline0).toBe(timeline);
|
||||||
@@ -382,7 +385,7 @@ describe("TimelineWindow", function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = timeline.getEvents();
|
const expectedEvents = timeline.getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -392,18 +395,18 @@ describe("TimelineWindow", function() {
|
|||||||
return timelineWindow.paginate(EventTimeline.FORWARDS, 2);
|
return timelineWindow.paginate(EventTimeline.FORWARDS, 2);
|
||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
let expectedEvents = timeline.getEvents().slice(0, 5);
|
const expectedEvents = timeline.getEvents().slice(0, 5);
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("should make backward pagination requests", function(done) {
|
it("should make backward pagination requests", function(done) {
|
||||||
let timeline = createTimeline();
|
const timeline = createTimeline();
|
||||||
timeline.setPaginationToken("toktok", EventTimeline.BACKWARDS);
|
timeline.setPaginationToken("toktok", EventTimeline.BACKWARDS);
|
||||||
|
|
||||||
let timelineWindow = createWindow(timeline, {windowLimit: 5});
|
const timelineWindow = createWindow(timeline, {windowLimit: 5});
|
||||||
let eventId = timeline.getEvents()[1].getId();
|
const eventId = timeline.getEvents()[1].getId();
|
||||||
|
|
||||||
client.paginateEventTimeline = function(timeline0, opts) {
|
client.paginateEventTimeline = function(timeline0, opts) {
|
||||||
expect(timeline0).toBe(timeline);
|
expect(timeline0).toBe(timeline);
|
||||||
@@ -415,7 +418,7 @@ describe("TimelineWindow", function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = timeline.getEvents();
|
const expectedEvents = timeline.getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -425,18 +428,18 @@ describe("TimelineWindow", function() {
|
|||||||
return timelineWindow.paginate(EventTimeline.BACKWARDS, 2);
|
return timelineWindow.paginate(EventTimeline.BACKWARDS, 2);
|
||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(true);
|
expect(success).toBe(true);
|
||||||
let expectedEvents = timeline.getEvents().slice(1, 6);
|
const expectedEvents = timeline.getEvents().slice(1, 6);
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
}).catch(utils.failTest).done(done);
|
}).catch(utils.failTest).done(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should limit the number of unsuccessful pagination requests",
|
it("should limit the number of unsuccessful pagination requests",
|
||||||
function(done) {
|
function(done) {
|
||||||
let timeline = createTimeline();
|
const timeline = createTimeline();
|
||||||
timeline.setPaginationToken("toktok", EventTimeline.FORWARDS);
|
timeline.setPaginationToken("toktok", EventTimeline.FORWARDS);
|
||||||
|
|
||||||
let timelineWindow = createWindow(timeline, {windowLimit: 5});
|
const timelineWindow = createWindow(timeline, {windowLimit: 5});
|
||||||
let eventId = timeline.getEvents()[1].getId();
|
const eventId = timeline.getEvents()[1].getId();
|
||||||
|
|
||||||
let paginateCount = 0;
|
let paginateCount = 0;
|
||||||
client.paginateEventTimeline = function(timeline0, opts) {
|
client.paginateEventTimeline = function(timeline0, opts) {
|
||||||
@@ -448,7 +451,7 @@ describe("TimelineWindow", function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
timelineWindow.load(eventId, 3).then(function() {
|
timelineWindow.load(eventId, 3).then(function() {
|
||||||
let expectedEvents = timeline.getEvents();
|
const expectedEvents = timeline.getEvents();
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
@@ -459,7 +462,7 @@ describe("TimelineWindow", function() {
|
|||||||
}).then(function(success) {
|
}).then(function(success) {
|
||||||
expect(success).toBe(false);
|
expect(success).toBe(false);
|
||||||
expect(paginateCount).toEqual(3);
|
expect(paginateCount).toEqual(3);
|
||||||
let expectedEvents = timeline.getEvents().slice(0, 3);
|
const expectedEvents = timeline.getEvents().slice(0, 3);
|
||||||
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
expect(timelineWindow.getEvents()).toEqual(expectedEvents);
|
||||||
|
|
||||||
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let sdk = require("../..");
|
const sdk = require("../..");
|
||||||
let User = sdk.User;
|
const User = sdk.User;
|
||||||
let utils = require("../test-utils");
|
const utils = require("../test-utils");
|
||||||
|
|
||||||
describe("User", function() {
|
describe("User", function() {
|
||||||
let userId = "@alice:bar";
|
const userId = "@alice:bar";
|
||||||
let user;
|
let user;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -13,7 +13,7 @@ describe("User", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("setPresenceEvent", function() {
|
describe("setPresenceEvent", function() {
|
||||||
let event = utils.mkEvent({
|
const event = utils.mkEvent({
|
||||||
type: "m.presence", content: {
|
type: "m.presence", content: {
|
||||||
presence: "online",
|
presence: "online",
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
let utils = require("../../lib/utils");
|
const utils = require("../../lib/utils");
|
||||||
let testUtils = require("../test-utils");
|
const testUtils = require("../test-utils");
|
||||||
|
|
||||||
describe("utils", function() {
|
describe("utils", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@@ -9,32 +9,32 @@ describe("utils", function() {
|
|||||||
|
|
||||||
describe("encodeParams", function() {
|
describe("encodeParams", function() {
|
||||||
it("should url encode and concat with &s", function() {
|
it("should url encode and concat with &s", function() {
|
||||||
let params = {
|
const params = {
|
||||||
foo: "bar",
|
foo: "bar",
|
||||||
baz: "beer@",
|
baz: "beer@",
|
||||||
};
|
};
|
||||||
expect(utils.encodeParams(params)).toEqual(
|
expect(utils.encodeParams(params)).toEqual(
|
||||||
"foo=bar&baz=beer%40"
|
"foo=bar&baz=beer%40",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("encodeUri", function() {
|
describe("encodeUri", function() {
|
||||||
it("should replace based on object keys and url encode", function() {
|
it("should replace based on object keys and url encode", function() {
|
||||||
let path = "foo/bar/%something/%here";
|
const path = "foo/bar/%something/%here";
|
||||||
let vals = {
|
const vals = {
|
||||||
"%something": "baz",
|
"%something": "baz",
|
||||||
"%here": "beer@",
|
"%here": "beer@",
|
||||||
};
|
};
|
||||||
expect(utils.encodeUri(path, vals)).toEqual(
|
expect(utils.encodeUri(path, vals)).toEqual(
|
||||||
"foo/bar/baz/beer%40"
|
"foo/bar/baz/beer%40",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("forEach", function() {
|
describe("forEach", function() {
|
||||||
it("should be invoked for each element", function() {
|
it("should be invoked for each element", function() {
|
||||||
let arr = [];
|
const arr = [];
|
||||||
utils.forEach([55, 66, 77], function(element) {
|
utils.forEach([55, 66, 77], function(element) {
|
||||||
arr.push(element);
|
arr.push(element);
|
||||||
});
|
});
|
||||||
@@ -44,50 +44,50 @@ describe("utils", function() {
|
|||||||
|
|
||||||
describe("findElement", function() {
|
describe("findElement", function() {
|
||||||
it("should find only 1 element if there is a match", function() {
|
it("should find only 1 element if there is a match", function() {
|
||||||
let matchFn = function() {
|
const matchFn = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let arr = [55, 66, 77];
|
const arr = [55, 66, 77];
|
||||||
expect(utils.findElement(arr, matchFn)).toEqual(55);
|
expect(utils.findElement(arr, matchFn)).toEqual(55);
|
||||||
});
|
});
|
||||||
it("should be able to find in reverse order", function() {
|
it("should be able to find in reverse order", function() {
|
||||||
let matchFn = function() {
|
const matchFn = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let arr = [55, 66, 77];
|
const arr = [55, 66, 77];
|
||||||
expect(utils.findElement(arr, matchFn, true)).toEqual(77);
|
expect(utils.findElement(arr, matchFn, true)).toEqual(77);
|
||||||
});
|
});
|
||||||
it("should find nothing if the function never returns true", function() {
|
it("should find nothing if the function never returns true", function() {
|
||||||
let matchFn = function() {
|
const matchFn = function() {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let arr = [55, 66, 77];
|
const arr = [55, 66, 77];
|
||||||
expect(utils.findElement(arr, matchFn)).toBeFalsy();
|
expect(utils.findElement(arr, matchFn)).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeElement", function() {
|
describe("removeElement", function() {
|
||||||
it("should remove only 1 element if there is a match", function() {
|
it("should remove only 1 element if there is a match", function() {
|
||||||
let matchFn = function() {
|
const matchFn = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let arr = [55, 66, 77];
|
const arr = [55, 66, 77];
|
||||||
utils.removeElement(arr, matchFn);
|
utils.removeElement(arr, matchFn);
|
||||||
expect(arr).toEqual([66, 77]);
|
expect(arr).toEqual([66, 77]);
|
||||||
});
|
});
|
||||||
it("should be able to remove in reverse order", function() {
|
it("should be able to remove in reverse order", function() {
|
||||||
let matchFn = function() {
|
const matchFn = function() {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let arr = [55, 66, 77];
|
const arr = [55, 66, 77];
|
||||||
utils.removeElement(arr, matchFn, true);
|
utils.removeElement(arr, matchFn, true);
|
||||||
expect(arr).toEqual([55, 66]);
|
expect(arr).toEqual([55, 66]);
|
||||||
});
|
});
|
||||||
it("should remove nothing if the function never returns true", function() {
|
it("should remove nothing if the function never returns true", function() {
|
||||||
let matchFn = function() {
|
const matchFn = function() {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let arr = [55, 66, 77];
|
const arr = [55, 66, 77];
|
||||||
utils.removeElement(arr, matchFn);
|
utils.removeElement(arr, matchFn);
|
||||||
expect(arr).toEqual(arr);
|
expect(arr).toEqual(arr);
|
||||||
});
|
});
|
||||||
@@ -104,7 +104,7 @@ describe("utils", function() {
|
|||||||
expect(utils.isFunction(555)).toBe(false);
|
expect(utils.isFunction(555)).toBe(false);
|
||||||
|
|
||||||
expect(utils.isFunction(function() {})).toBe(true);
|
expect(utils.isFunction(function() {})).toBe(true);
|
||||||
let s = { foo: function() {} };
|
const s = { foo: function() {} };
|
||||||
expect(utils.isFunction(s.foo)).toBe(true);
|
expect(utils.isFunction(s.foo)).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -154,7 +154,7 @@ describe("utils", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("deepCompare", function() {
|
describe("deepCompare", function() {
|
||||||
let assert = {
|
const assert = {
|
||||||
isTrue: function(x) {
|
isTrue: function(x) {
|
||||||
expect(x).toBe(true);
|
expect(x).toBe(true);
|
||||||
},
|
},
|
||||||
@@ -174,7 +174,7 @@ describe("utils", function() {
|
|||||||
it("should handle regexps", function() {
|
it("should handle regexps", function() {
|
||||||
assert.isTrue(utils.deepCompare(/abc/, /abc/));
|
assert.isTrue(utils.deepCompare(/abc/, /abc/));
|
||||||
assert.isFalse(utils.deepCompare(/abc/, /123/));
|
assert.isFalse(utils.deepCompare(/abc/, /123/));
|
||||||
let r = /abc/;
|
const r = /abc/;
|
||||||
assert.isTrue(utils.deepCompare(r, r));
|
assert.isTrue(utils.deepCompare(r, r));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -216,10 +216,10 @@ describe("utils", function() {
|
|||||||
// no two different function is equal really, they capture their
|
// no two different function is equal really, they capture their
|
||||||
// context variables so even if they have same toString(), they
|
// context variables so even if they have same toString(), they
|
||||||
// won't have same functionality
|
// won't have same functionality
|
||||||
let func = function(x) {
|
const func = function(x) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let func2 = function(x) {
|
const func2 = function(x) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
assert.isTrue(utils.deepCompare(func, func));
|
assert.isTrue(utils.deepCompare(func, func));
|
||||||
@@ -231,44 +231,44 @@ describe("utils", function() {
|
|||||||
|
|
||||||
|
|
||||||
describe("extend", function() {
|
describe("extend", function() {
|
||||||
let SOURCE = { "prop2": 1, "string2": "x", "newprop": "new" };
|
const SOURCE = { "prop2": 1, "string2": "x", "newprop": "new" };
|
||||||
|
|
||||||
it("should extend", function() {
|
it("should extend", function() {
|
||||||
let target = {
|
const target = {
|
||||||
"prop1": 5, "prop2": 7, "string1": "baz", "string2": "foo",
|
"prop1": 5, "prop2": 7, "string1": "baz", "string2": "foo",
|
||||||
};
|
};
|
||||||
let merged = {
|
const merged = {
|
||||||
"prop1": 5, "prop2": 1, "string1": "baz", "string2": "x",
|
"prop1": 5, "prop2": 1, "string1": "baz", "string2": "x",
|
||||||
"newprop": "new",
|
"newprop": "new",
|
||||||
};
|
};
|
||||||
let source_orig = JSON.stringify(SOURCE);
|
const sourceOrig = JSON.stringify(SOURCE);
|
||||||
|
|
||||||
utils.extend(target, SOURCE);
|
utils.extend(target, SOURCE);
|
||||||
expect(JSON.stringify(target)).toEqual(JSON.stringify(merged));
|
expect(JSON.stringify(target)).toEqual(JSON.stringify(merged));
|
||||||
|
|
||||||
// check the originial wasn't modified
|
// check the originial wasn't modified
|
||||||
expect(JSON.stringify(SOURCE)).toEqual(source_orig);
|
expect(JSON.stringify(SOURCE)).toEqual(sourceOrig);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should ignore null", function() {
|
it("should ignore null", function() {
|
||||||
let target = {
|
const target = {
|
||||||
"prop1": 5, "prop2": 7, "string1": "baz", "string2": "foo",
|
"prop1": 5, "prop2": 7, "string1": "baz", "string2": "foo",
|
||||||
};
|
};
|
||||||
let merged = {
|
const merged = {
|
||||||
"prop1": 5, "prop2": 1, "string1": "baz", "string2": "x",
|
"prop1": 5, "prop2": 1, "string1": "baz", "string2": "x",
|
||||||
"newprop": "new",
|
"newprop": "new",
|
||||||
};
|
};
|
||||||
let source_orig = JSON.stringify(SOURCE);
|
const sourceOrig = JSON.stringify(SOURCE);
|
||||||
|
|
||||||
utils.extend(target, null, SOURCE);
|
utils.extend(target, null, SOURCE);
|
||||||
expect(JSON.stringify(target)).toEqual(JSON.stringify(merged));
|
expect(JSON.stringify(target)).toEqual(JSON.stringify(merged));
|
||||||
|
|
||||||
// check the originial wasn't modified
|
// check the originial wasn't modified
|
||||||
expect(JSON.stringify(SOURCE)).toEqual(source_orig);
|
expect(JSON.stringify(SOURCE)).toEqual(sourceOrig);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle properties created with defineProperties", function() {
|
it("should handle properties created with defineProperties", function() {
|
||||||
let source = Object.defineProperties({}, {
|
const source = Object.defineProperties({}, {
|
||||||
"enumerableProp": {
|
"enumerableProp": {
|
||||||
get: function() {
|
get: function() {
|
||||||
return true;
|
return true;
|
||||||
@@ -282,7 +282,7 @@ describe("utils", function() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let target = {};
|
const target = {};
|
||||||
utils.extend(target, source);
|
utils.extend(target, source);
|
||||||
expect(target.enumerableProp).toBe(true);
|
expect(target.enumerableProp).toBe(true);
|
||||||
expect(target.nonenumerableProp).toBe(undefined);
|
expect(target.nonenumerableProp).toBe(undefined);
|
||||||
|
|||||||
182
src/base-apis.js
182
src/base-apis.js
@@ -22,8 +22,8 @@ limitations under the License.
|
|||||||
* @module base-apis
|
* @module base-apis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let httpApi = require("./http-api");
|
const httpApi = require("./http-api");
|
||||||
let utils = require("./utils");
|
const utils = require("./utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Low-level wrappers for the Matrix APIs
|
* Low-level wrappers for the Matrix APIs
|
||||||
@@ -60,7 +60,7 @@ function MatrixBaseApis(opts) {
|
|||||||
this.baseUrl = opts.baseUrl;
|
this.baseUrl = opts.baseUrl;
|
||||||
this.idBaseUrl = opts.idBaseUrl;
|
this.idBaseUrl = opts.idBaseUrl;
|
||||||
|
|
||||||
let httpOpts = {
|
const httpOpts = {
|
||||||
baseUrl: opts.baseUrl,
|
baseUrl: opts.baseUrl,
|
||||||
idBaseUrl: opts.idBaseUrl,
|
idBaseUrl: opts.idBaseUrl,
|
||||||
accessToken: opts.accessToken,
|
accessToken: opts.accessToken,
|
||||||
@@ -133,7 +133,7 @@ MatrixBaseApis.prototype.makeTxnId = function() {
|
|||||||
MatrixBaseApis.prototype.register = function(
|
MatrixBaseApis.prototype.register = function(
|
||||||
username, password,
|
username, password,
|
||||||
sessionId, auth, bindEmail, guestAccessToken,
|
sessionId, auth, bindEmail, guestAccessToken,
|
||||||
callback
|
callback,
|
||||||
) {
|
) {
|
||||||
if (auth === undefined) {
|
if (auth === undefined) {
|
||||||
auth = {};
|
auth = {};
|
||||||
@@ -142,7 +142,7 @@ MatrixBaseApis.prototype.register = function(
|
|||||||
auth.session = sessionId;
|
auth.session = sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
let params = {
|
const params = {
|
||||||
auth: auth,
|
auth: auth,
|
||||||
};
|
};
|
||||||
if (username !== undefined && username !== null) {
|
if (username !== undefined && username !== null) {
|
||||||
@@ -183,13 +183,13 @@ MatrixBaseApis.prototype.registerGuest = function(opts, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.registerRequest = function(data, kind, callback) {
|
MatrixBaseApis.prototype.registerRequest = function(data, kind, callback) {
|
||||||
let params = {};
|
const params = {};
|
||||||
if (kind) {
|
if (kind) {
|
||||||
params.kind = kind;
|
params.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._http.request(
|
return this._http.request(
|
||||||
callback, "POST", "/register", params, data
|
callback, "POST", "/register", params, data,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ MatrixBaseApis.prototype.loginFlows = function(callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.login = function(loginType, data, callback) {
|
MatrixBaseApis.prototype.login = function(loginType, data, callback) {
|
||||||
let login_data = {
|
const login_data = {
|
||||||
type: loginType,
|
type: loginType,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ MatrixBaseApis.prototype.login = function(loginType, data, callback) {
|
|||||||
utils.extend(login_data, data);
|
utils.extend(login_data, data);
|
||||||
|
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", "/login", undefined, login_data
|
callback, "POST", "/login", undefined, login_data,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ MatrixBaseApis.prototype.loginWithToken = function(token, callback) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.logout = function(callback) {
|
MatrixBaseApis.prototype.logout = function(callback) {
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", '/logout'
|
callback, "POST", '/logout',
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ MatrixBaseApis.prototype.deactivateAccount = function(auth, callback) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
callback, "POST", '/account/deactivate', undefined, body, httpApi.PREFIX_UNSTABLE
|
callback, "POST", '/account/deactivate', undefined, body, httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ MatrixBaseApis.prototype.deactivateAccount = function(auth, callback) {
|
|||||||
* @return {string} HS URL to hit to for the fallback interface
|
* @return {string} HS URL to hit to for the fallback interface
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getFallbackAuthUrl = function(loginType, authSessionId) {
|
MatrixBaseApis.prototype.getFallbackAuthUrl = function(loginType, authSessionId) {
|
||||||
let path = utils.encodeUri("/auth/$loginType/fallback/web", {
|
const path = utils.encodeUri("/auth/$loginType/fallback/web", {
|
||||||
$loginType: loginType,
|
$loginType: loginType,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ MatrixBaseApis.prototype.getFallbackAuthUrl = function(loginType, authSessionId)
|
|||||||
MatrixBaseApis.prototype.createRoom = function(options, callback) {
|
MatrixBaseApis.prototype.createRoom = function(options, callback) {
|
||||||
// valid options include: room_alias_name, visibility, invite
|
// valid options include: room_alias_name, visibility, invite
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", "/createRoom", undefined, options
|
callback, "POST", "/createRoom", undefined, options,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ MatrixBaseApis.prototype.createRoom = function(options, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.roomState = function(roomId, callback) {
|
MatrixBaseApis.prototype.roomState = function(roomId, callback) {
|
||||||
let path = utils.encodeUri("/rooms/$roomId/state", {$roomId: roomId});
|
const path = utils.encodeUri("/rooms/$roomId/state", {$roomId: roomId});
|
||||||
return this._http.authedRequest(callback, "GET", path);
|
return this._http.authedRequest(callback, "GET", path);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -372,7 +372,7 @@ MatrixBaseApis.prototype.roomState = function(roomId, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, callback) {
|
MatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, callback) {
|
||||||
let pathParams = {
|
const pathParams = {
|
||||||
$roomId: roomId,
|
$roomId: roomId,
|
||||||
$eventType: eventType,
|
$eventType: eventType,
|
||||||
$stateKey: stateKey,
|
$stateKey: stateKey,
|
||||||
@@ -382,7 +382,7 @@ MatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, c
|
|||||||
path = utils.encodeUri(path + "/$stateKey", pathParams);
|
path = utils.encodeUri(path + "/$stateKey", pathParams);
|
||||||
}
|
}
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "GET", path
|
callback, "GET", path,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ MatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, c
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, stateKey,
|
MatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, stateKey,
|
||||||
callback) {
|
callback) {
|
||||||
let pathParams = {
|
const pathParams = {
|
||||||
$roomId: roomId,
|
$roomId: roomId,
|
||||||
$eventType: eventType,
|
$eventType: eventType,
|
||||||
$stateKey: stateKey,
|
$stateKey: stateKey,
|
||||||
@@ -407,7 +407,7 @@ MatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, s
|
|||||||
path = utils.encodeUri(path + "/$stateKey", pathParams);
|
path = utils.encodeUri(path + "/$stateKey", pathParams);
|
||||||
}
|
}
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, content
|
callback, "PUT", path, undefined, content,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ MatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, s
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.redactEvent = function(roomId, eventId, callback) {
|
MatrixBaseApis.prototype.redactEvent = function(roomId, eventId, callback) {
|
||||||
let path = utils.encodeUri("/rooms/$roomId/redact/$eventId", {
|
const path = utils.encodeUri("/rooms/$roomId/redact/$eventId", {
|
||||||
$roomId: roomId,
|
$roomId: roomId,
|
||||||
$eventId: eventId,
|
$eventId: eventId,
|
||||||
});
|
});
|
||||||
@@ -437,14 +437,14 @@ MatrixBaseApis.prototype.roomInitialSync = function(roomId, limit, callback) {
|
|||||||
if (utils.isFunction(limit)) {
|
if (utils.isFunction(limit)) {
|
||||||
callback = limit; limit = undefined;
|
callback = limit; limit = undefined;
|
||||||
}
|
}
|
||||||
let path = utils.encodeUri("/rooms/$roomId/initialSync",
|
const path = utils.encodeUri("/rooms/$roomId/initialSync",
|
||||||
{$roomId: roomId}
|
{$roomId: roomId},
|
||||||
);
|
);
|
||||||
if (!limit) {
|
if (!limit) {
|
||||||
limit = 30;
|
limit = 30;
|
||||||
}
|
}
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "GET", path, { limit: limit }
|
callback, "GET", path, { limit: limit },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -474,7 +474,7 @@ MatrixBaseApis.prototype.publicRooms = function(options, callback) {
|
|||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
let query_params = {};
|
const query_params = {};
|
||||||
if (options.server) {
|
if (options.server) {
|
||||||
query_params.server = options.server;
|
query_params.server = options.server;
|
||||||
delete options.server;
|
delete options.server;
|
||||||
@@ -484,7 +484,7 @@ MatrixBaseApis.prototype.publicRooms = function(options, callback) {
|
|||||||
return this._http.authedRequest(callback, "GET", "/publicRooms");
|
return this._http.authedRequest(callback, "GET", "/publicRooms");
|
||||||
} else {
|
} else {
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", "/publicRooms", query_params, options
|
callback, "POST", "/publicRooms", query_params, options,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -498,14 +498,14 @@ MatrixBaseApis.prototype.publicRooms = function(options, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.createAlias = function(alias, roomId, callback) {
|
MatrixBaseApis.prototype.createAlias = function(alias, roomId, callback) {
|
||||||
let path = utils.encodeUri("/directory/room/$alias", {
|
const path = utils.encodeUri("/directory/room/$alias", {
|
||||||
$alias: alias,
|
$alias: alias,
|
||||||
});
|
});
|
||||||
let data = {
|
const data = {
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
};
|
};
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, data
|
callback, "PUT", path, undefined, data,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -518,11 +518,11 @@ MatrixBaseApis.prototype.createAlias = function(alias, roomId, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.deleteAlias = function(alias, callback) {
|
MatrixBaseApis.prototype.deleteAlias = function(alias, callback) {
|
||||||
let path = utils.encodeUri("/directory/room/$alias", {
|
const path = utils.encodeUri("/directory/room/$alias", {
|
||||||
$alias: alias,
|
$alias: alias,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "DELETE", path, undefined, undefined
|
callback, "DELETE", path, undefined, undefined,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -535,11 +535,11 @@ MatrixBaseApis.prototype.deleteAlias = function(alias, callback) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) {
|
MatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) {
|
||||||
// TODO: deprecate this or resolveRoomAlias
|
// TODO: deprecate this or resolveRoomAlias
|
||||||
let path = utils.encodeUri("/directory/room/$alias", {
|
const path = utils.encodeUri("/directory/room/$alias", {
|
||||||
$alias: alias,
|
$alias: alias,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "GET", path
|
callback, "GET", path,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -551,7 +551,7 @@ MatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) {
|
MatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) {
|
||||||
// TODO: deprecate this or getRoomIdForAlias
|
// TODO: deprecate this or getRoomIdForAlias
|
||||||
let path = utils.encodeUri("/directory/room/$alias", {$alias: roomAlias});
|
const path = utils.encodeUri("/directory/room/$alias", {$alias: roomAlias});
|
||||||
return this._http.request(callback, "GET", path);
|
return this._http.request(callback, "GET", path);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ MatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getRoomDirectoryVisibility =
|
MatrixBaseApis.prototype.getRoomDirectoryVisibility =
|
||||||
function(roomId, callback) {
|
function(roomId, callback) {
|
||||||
let path = utils.encodeUri("/directory/list/room/$roomId", {
|
const path = utils.encodeUri("/directory/list/room/$roomId", {
|
||||||
$roomId: roomId,
|
$roomId: roomId,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(callback, "GET", path);
|
return this._http.authedRequest(callback, "GET", path);
|
||||||
@@ -582,11 +582,11 @@ MatrixBaseApis.prototype.getRoomDirectoryVisibility =
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setRoomDirectoryVisibility =
|
MatrixBaseApis.prototype.setRoomDirectoryVisibility =
|
||||||
function(roomId, visibility, callback) {
|
function(roomId, visibility, callback) {
|
||||||
let path = utils.encodeUri("/directory/list/room/$roomId", {
|
const path = utils.encodeUri("/directory/list/room/$roomId", {
|
||||||
$roomId: roomId,
|
$roomId: roomId,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, { "visibility": visibility }
|
callback, "PUT", path, undefined, { "visibility": visibility },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -605,12 +605,12 @@ MatrixBaseApis.prototype.setRoomDirectoryVisibility =
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setRoomDirectoryVisibilityAppService =
|
MatrixBaseApis.prototype.setRoomDirectoryVisibilityAppService =
|
||||||
function(networkId, roomId, visibility, callback) {
|
function(networkId, roomId, visibility, callback) {
|
||||||
let path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", {
|
const path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", {
|
||||||
$networkId: networkId,
|
$networkId: networkId,
|
||||||
$roomId: roomId,
|
$roomId: roomId,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, { "visibility": visibility }
|
callback, "PUT", path, undefined, { "visibility": visibility },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -692,7 +692,7 @@ MatrixBaseApis.prototype.getProfileInfo = function(userId, info, callback) {
|
|||||||
callback = info; info = undefined;
|
callback = info; info = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = info ?
|
const path = info ?
|
||||||
utils.encodeUri("/profile/$userId/$info",
|
utils.encodeUri("/profile/$userId/$info",
|
||||||
{ $userId: userId, $info: info }) :
|
{ $userId: userId, $info: info }) :
|
||||||
utils.encodeUri("/profile/$userId",
|
utils.encodeUri("/profile/$userId",
|
||||||
@@ -710,9 +710,9 @@ MatrixBaseApis.prototype.getProfileInfo = function(userId, info, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getThreePids = function(callback) {
|
MatrixBaseApis.prototype.getThreePids = function(callback) {
|
||||||
let path = "/account/3pid";
|
const path = "/account/3pid";
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "GET", path, undefined, undefined
|
callback, "GET", path, undefined, undefined,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -724,13 +724,13 @@ MatrixBaseApis.prototype.getThreePids = function(callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {
|
MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {
|
||||||
let path = "/account/3pid";
|
const path = "/account/3pid";
|
||||||
let data = {
|
const data = {
|
||||||
'threePidCreds': creds,
|
'threePidCreds': creds,
|
||||||
'bind': bind,
|
'bind': bind,
|
||||||
};
|
};
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", path, null, data
|
callback, "POST", path, null, data,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -743,13 +743,13 @@ MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.deleteThreePid = function(medium, address) {
|
MatrixBaseApis.prototype.deleteThreePid = function(medium, address) {
|
||||||
let path = "/account/3pid/delete";
|
const path = "/account/3pid/delete";
|
||||||
let data = {
|
const data = {
|
||||||
'medium': medium,
|
'medium': medium,
|
||||||
'address': address,
|
'address': address,
|
||||||
};
|
};
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "POST", path, null, data, httpApi.PREFIX_UNSTABLE
|
undefined, "POST", path, null, data, httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -762,14 +762,14 @@ MatrixBaseApis.prototype.deleteThreePid = function(medium, address) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback) {
|
MatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback) {
|
||||||
let path = "/account/password";
|
const path = "/account/password";
|
||||||
let data = {
|
const data = {
|
||||||
'auth': authDict,
|
'auth': authDict,
|
||||||
'new_password': newPassword,
|
'new_password': newPassword,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", path, null, data
|
callback, "POST", path, null, data,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -783,10 +783,10 @@ MatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback)
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getDevices = function() {
|
MatrixBaseApis.prototype.getDevices = function() {
|
||||||
let path = "/devices";
|
const path = "/devices";
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "GET", path, undefined, undefined,
|
undefined, "GET", path, undefined, undefined,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -799,14 +799,14 @@ MatrixBaseApis.prototype.getDevices = function() {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setDeviceDetails = function(device_id, body) {
|
MatrixBaseApis.prototype.setDeviceDetails = function(device_id, body) {
|
||||||
let path = utils.encodeUri("/devices/$device_id", {
|
const path = utils.encodeUri("/devices/$device_id", {
|
||||||
$device_id: device_id,
|
$device_id: device_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "PUT", path, undefined, body,
|
undefined, "PUT", path, undefined, body,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -819,11 +819,11 @@ MatrixBaseApis.prototype.setDeviceDetails = function(device_id, body) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.deleteDevice = function(device_id, auth) {
|
MatrixBaseApis.prototype.deleteDevice = function(device_id, auth) {
|
||||||
let path = utils.encodeUri("/devices/$device_id", {
|
const path = utils.encodeUri("/devices/$device_id", {
|
||||||
$device_id: device_id,
|
$device_id: device_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = {};
|
const body = {};
|
||||||
|
|
||||||
if (auth) {
|
if (auth) {
|
||||||
body.auth = auth;
|
body.auth = auth;
|
||||||
@@ -831,7 +831,7 @@ MatrixBaseApis.prototype.deleteDevice = function(device_id, auth) {
|
|||||||
|
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "DELETE", path, undefined, body,
|
undefined, "DELETE", path, undefined, body,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -847,9 +847,9 @@ MatrixBaseApis.prototype.deleteDevice = function(device_id, auth) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getPushers = function(callback) {
|
MatrixBaseApis.prototype.getPushers = function(callback) {
|
||||||
let path = "/pushers";
|
const path = "/pushers";
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "GET", path, undefined, undefined
|
callback, "GET", path, undefined, undefined,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -862,9 +862,9 @@ MatrixBaseApis.prototype.getPushers = function(callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setPusher = function(pusher, callback) {
|
MatrixBaseApis.prototype.setPusher = function(pusher, callback) {
|
||||||
let path = "/pushers/set";
|
const path = "/pushers/set";
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", path, null, pusher
|
callback, "POST", path, null, pusher,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -888,12 +888,12 @@ MatrixBaseApis.prototype.getPushRules = function(callback) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.addPushRule = function(scope, kind, ruleId, body, callback) {
|
MatrixBaseApis.prototype.addPushRule = function(scope, kind, ruleId, body, callback) {
|
||||||
// NB. Scope not uri encoded because devices need the '/'
|
// NB. Scope not uri encoded because devices need the '/'
|
||||||
let path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
|
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
|
||||||
$kind: kind,
|
$kind: kind,
|
||||||
$ruleId: ruleId,
|
$ruleId: ruleId,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, body
|
callback, "PUT", path, undefined, body,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -907,7 +907,7 @@ MatrixBaseApis.prototype.addPushRule = function(scope, kind, ruleId, body, callb
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.deletePushRule = function(scope, kind, ruleId, callback) {
|
MatrixBaseApis.prototype.deletePushRule = function(scope, kind, ruleId, callback) {
|
||||||
// NB. Scope not uri encoded because devices need the '/'
|
// NB. Scope not uri encoded because devices need the '/'
|
||||||
let path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
|
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
|
||||||
$kind: kind,
|
$kind: kind,
|
||||||
$ruleId: ruleId,
|
$ruleId: ruleId,
|
||||||
});
|
});
|
||||||
@@ -926,12 +926,12 @@ MatrixBaseApis.prototype.deletePushRule = function(scope, kind, ruleId, callback
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind,
|
MatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind,
|
||||||
ruleId, enabled, callback) {
|
ruleId, enabled, callback) {
|
||||||
let path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", {
|
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", {
|
||||||
$kind: kind,
|
$kind: kind,
|
||||||
$ruleId: ruleId,
|
$ruleId: ruleId,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, {"enabled": enabled}
|
callback, "PUT", path, undefined, {"enabled": enabled},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -947,12 +947,12 @@ MatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind,
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.setPushRuleActions = function(scope, kind,
|
MatrixBaseApis.prototype.setPushRuleActions = function(scope, kind,
|
||||||
ruleId, actions, callback) {
|
ruleId, actions, callback) {
|
||||||
let path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", {
|
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", {
|
||||||
$kind: kind,
|
$kind: kind,
|
||||||
$ruleId: ruleId,
|
$ruleId: ruleId,
|
||||||
});
|
});
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "PUT", path, undefined, {"actions": actions}
|
callback, "PUT", path, undefined, {"actions": actions},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -970,12 +970,12 @@ MatrixBaseApis.prototype.setPushRuleActions = function(scope, kind,
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.search = function(opts, callback) {
|
MatrixBaseApis.prototype.search = function(opts, callback) {
|
||||||
let queryparams = {};
|
const queryparams = {};
|
||||||
if (opts.next_batch) {
|
if (opts.next_batch) {
|
||||||
queryparams.next_batch = opts.next_batch;
|
queryparams.next_batch = opts.next_batch;
|
||||||
}
|
}
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
callback, "POST", "/search", queryparams, opts.body
|
callback, "POST", "/search", queryparams, opts.body,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -999,7 +999,7 @@ MatrixBaseApis.prototype.search = function(opts, callback) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
|
MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
let deviceId = opts.device_id;
|
const deviceId = opts.device_id;
|
||||||
let path;
|
let path;
|
||||||
if (deviceId) {
|
if (deviceId) {
|
||||||
path = utils.encodeUri("/keys/upload/$deviceId", {
|
path = utils.encodeUri("/keys/upload/$deviceId", {
|
||||||
@@ -1009,7 +1009,7 @@ MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
|
|||||||
path = "/keys/upload";
|
path = "/keys/upload";
|
||||||
}
|
}
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
callback, "POST", path, undefined, content, httpApi.PREFIX_UNSTABLE
|
callback, "POST", path, undefined, content, httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1024,15 +1024,15 @@ MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
|
|||||||
* an error response ({@link module:http-api.MatrixError}).
|
* an error response ({@link module:http-api.MatrixError}).
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, callback) {
|
MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, callback) {
|
||||||
let downloadQuery = {};
|
const downloadQuery = {};
|
||||||
|
|
||||||
for (let i = 0; i < userIds.length; ++i) {
|
for (let i = 0; i < userIds.length; ++i) {
|
||||||
downloadQuery[userIds[i]] = {};
|
downloadQuery[userIds[i]] = {};
|
||||||
}
|
}
|
||||||
let content = {device_keys: downloadQuery};
|
const content = {device_keys: downloadQuery};
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
callback, "POST", "/keys/query", undefined, content,
|
callback, "POST", "/keys/query", undefined, content,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1047,23 +1047,23 @@ MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, callback) {
|
|||||||
* an error response ({@link module:http-api.MatrixError}).
|
* an error response ({@link module:http-api.MatrixError}).
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm) {
|
MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm) {
|
||||||
let queries = {};
|
const queries = {};
|
||||||
|
|
||||||
if (key_algorithm === undefined) {
|
if (key_algorithm === undefined) {
|
||||||
key_algorithm = "signed_curve25519";
|
key_algorithm = "signed_curve25519";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < devices.length; ++i) {
|
for (let i = 0; i < devices.length; ++i) {
|
||||||
let userId = devices[i][0];
|
const userId = devices[i][0];
|
||||||
let deviceId = devices[i][1];
|
const deviceId = devices[i][1];
|
||||||
let query = queries[userId] || {};
|
const query = queries[userId] || {};
|
||||||
queries[userId] = query;
|
queries[userId] = query;
|
||||||
query[deviceId] = key_algorithm;
|
query[deviceId] = key_algorithm;
|
||||||
}
|
}
|
||||||
let content = {one_time_keys: queries};
|
const content = {one_time_keys: queries};
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "POST", "/keys/claim", undefined, content,
|
undefined, "POST", "/keys/claim", undefined, content,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1093,7 +1093,7 @@ MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm) {
|
|||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,
|
MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,
|
||||||
sendAttempt, nextLink, callback) {
|
sendAttempt, nextLink, callback) {
|
||||||
let params = {
|
const params = {
|
||||||
client_secret: clientSecret,
|
client_secret: clientSecret,
|
||||||
email: email,
|
email: email,
|
||||||
send_attempt: sendAttempt,
|
send_attempt: sendAttempt,
|
||||||
@@ -1101,7 +1101,7 @@ MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,
|
|||||||
};
|
};
|
||||||
return this._http.idServerRequest(
|
return this._http.idServerRequest(
|
||||||
callback, "POST", "/validate/email/requestToken",
|
callback, "POST", "/validate/email/requestToken",
|
||||||
params, httpApi.PREFIX_IDENTITY_V1
|
params, httpApi.PREFIX_IDENTITY_V1,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1117,13 +1117,13 @@ MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.lookupThreePid = function(medium, address, callback) {
|
MatrixBaseApis.prototype.lookupThreePid = function(medium, address, callback) {
|
||||||
let params = {
|
const params = {
|
||||||
medium: medium,
|
medium: medium,
|
||||||
address: address,
|
address: address,
|
||||||
};
|
};
|
||||||
return this._http.idServerRequest(
|
return this._http.idServerRequest(
|
||||||
callback, "GET", "/lookup",
|
callback, "GET", "/lookup",
|
||||||
params, httpApi.PREFIX_IDENTITY_V1
|
params, httpApi.PREFIX_IDENTITY_V1,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1142,20 +1142,20 @@ MatrixBaseApis.prototype.lookupThreePid = function(medium, address, callback) {
|
|||||||
* @return {module:client.Promise} Resolves to the result object
|
* @return {module:client.Promise} Resolves to the result object
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.sendToDevice = function(
|
MatrixBaseApis.prototype.sendToDevice = function(
|
||||||
eventType, contentMap, txnId
|
eventType, contentMap, txnId,
|
||||||
) {
|
) {
|
||||||
let path = utils.encodeUri("/sendToDevice/$eventType/$txnId", {
|
const path = utils.encodeUri("/sendToDevice/$eventType/$txnId", {
|
||||||
$eventType: eventType,
|
$eventType: eventType,
|
||||||
$txnId: txnId ? txnId : this.makeTxnId(),
|
$txnId: txnId ? txnId : this.makeTxnId(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = {
|
const body = {
|
||||||
messages: contentMap,
|
messages: contentMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "PUT", path, undefined, body,
|
undefined, "PUT", path, undefined, body,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1170,7 +1170,7 @@ MatrixBaseApis.prototype.sendToDevice = function(
|
|||||||
MatrixBaseApis.prototype.getThirdpartyProtocols = function() {
|
MatrixBaseApis.prototype.getThirdpartyProtocols = function() {
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "GET", "/thirdparty/protocols", undefined, undefined,
|
undefined, "GET", "/thirdparty/protocols", undefined, undefined,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1183,13 +1183,13 @@ MatrixBaseApis.prototype.getThirdpartyProtocols = function() {
|
|||||||
* @return {module:client.Promise} Resolves to the result object
|
* @return {module:client.Promise} Resolves to the result object
|
||||||
*/
|
*/
|
||||||
MatrixBaseApis.prototype.getThirdpartyLocation = function(protocol, params) {
|
MatrixBaseApis.prototype.getThirdpartyLocation = function(protocol, params) {
|
||||||
let path = utils.encodeUri("/thirdparty/location/$protocol", {
|
const path = utils.encodeUri("/thirdparty/location/$protocol", {
|
||||||
$protocol: protocol,
|
$protocol: protocol,
|
||||||
});
|
});
|
||||||
|
|
||||||
return this._http.authedRequestWithPrefix(
|
return this._http.authedRequestWithPrefix(
|
||||||
undefined, "GET", path, params, undefined,
|
undefined, "GET", path, params, undefined,
|
||||||
httpApi.PREFIX_UNSTABLE
|
httpApi.PREFIX_UNSTABLE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
421
src/client.js
421
src/client.js
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
/**
|
/**
|
||||||
* @module content-repo
|
* @module content-repo
|
||||||
*/
|
*/
|
||||||
let utils = require("./utils");
|
const utils = require("./utils");
|
||||||
|
|
||||||
/** Content Repo utility functions */
|
/** Content Repo utility functions */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -48,7 +48,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
let serverAndMediaId = mxc.slice(6); // strips mxc://
|
let serverAndMediaId = mxc.slice(6); // strips mxc://
|
||||||
let prefix = "/_matrix/media/v1/download/";
|
let prefix = "/_matrix/media/v1/download/";
|
||||||
let params = {};
|
const params = {};
|
||||||
|
|
||||||
if (width) {
|
if (width) {
|
||||||
params.width = width;
|
params.width = width;
|
||||||
@@ -65,8 +65,8 @@ module.exports = {
|
|||||||
prefix = "/_matrix/media/v1/thumbnail/";
|
prefix = "/_matrix/media/v1/thumbnail/";
|
||||||
}
|
}
|
||||||
|
|
||||||
let fragmentOffset = serverAndMediaId.indexOf("#"),
|
const fragmentOffset = serverAndMediaId.indexOf("#");
|
||||||
fragment = "";
|
let fragment = "";
|
||||||
if (fragmentOffset >= 0) {
|
if (fragmentOffset >= 0) {
|
||||||
fragment = serverAndMediaId.substr(fragmentOffset);
|
fragment = serverAndMediaId.substr(fragmentOffset);
|
||||||
serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset);
|
serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset);
|
||||||
@@ -94,12 +94,12 @@ module.exports = {
|
|||||||
if (!height) {
|
if (!height) {
|
||||||
height = 96;
|
height = 96;
|
||||||
}
|
}
|
||||||
let params = {
|
const params = {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = utils.encodeUri("/_matrix/media/v1/identicon/$ident", {
|
const path = utils.encodeUri("/_matrix/media/v1/identicon/$ident", {
|
||||||
$ident: identiconString,
|
$ident: identiconString,
|
||||||
});
|
});
|
||||||
return baseUrl + path +
|
return baseUrl + path +
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ limitations under the License.
|
|||||||
*
|
*
|
||||||
* @module crypto/OlmDevice
|
* @module crypto/OlmDevice
|
||||||
*/
|
*/
|
||||||
let Olm = require("olm");
|
const Olm = require("olm");
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
|
|
||||||
|
|
||||||
// The maximum size of an event is 65K, and we base64 the content, so this is a
|
// 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.
|
// reasonable approximation to the biggest plaintext we can encrypt.
|
||||||
let MAX_PLAINTEXT_LENGTH = 65536 * 3 / 4;
|
const MAX_PLAINTEXT_LENGTH = 65536 * 3 / 4;
|
||||||
|
|
||||||
function checkPayloadLength(payloadString) {
|
function checkPayloadLength(payloadString) {
|
||||||
if (payloadString === undefined) {
|
if (payloadString === undefined) {
|
||||||
@@ -47,6 +47,18 @@ function checkPayloadLength(payloadString) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of object we use for importing and exporting megolm session data.
|
||||||
|
*
|
||||||
|
* @typedef {Object} module:crypto/OlmDevice.MegolmSessionData
|
||||||
|
* @property {String} sender_key Sender's Curve25519 device key
|
||||||
|
* @property {Object<string, string>} sender_claimed_keys Other keys the sender claims.
|
||||||
|
* @property {String} room_id Room this session is used in
|
||||||
|
* @property {String} session_id Unique id for the session
|
||||||
|
* @property {String} session_key Base64'ed key data
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the olm cryptography functions. Each OlmDevice has a single
|
* Manages the olm cryptography functions. Each OlmDevice has a single
|
||||||
* OlmAccount and a number of OlmSessions.
|
* OlmAccount and a number of OlmSessions.
|
||||||
@@ -67,7 +79,7 @@ function OlmDevice(sessionStore) {
|
|||||||
this._pickleKey = "DEFAULT_KEY";
|
this._pickleKey = "DEFAULT_KEY";
|
||||||
|
|
||||||
let e2eKeys;
|
let e2eKeys;
|
||||||
let account = new Olm.Account();
|
const account = new Olm.Account();
|
||||||
try {
|
try {
|
||||||
_initialise_account(this._sessionStore, this._pickleKey, account);
|
_initialise_account(this._sessionStore, this._pickleKey, account);
|
||||||
e2eKeys = JSON.parse(account.identity_keys());
|
e2eKeys = JSON.parse(account.identity_keys());
|
||||||
@@ -96,14 +108,14 @@ function OlmDevice(sessionStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _initialise_account(sessionStore, pickleKey, account) {
|
function _initialise_account(sessionStore, pickleKey, account) {
|
||||||
let e2eAccount = sessionStore.getEndToEndAccount();
|
const e2eAccount = sessionStore.getEndToEndAccount();
|
||||||
if (e2eAccount !== null) {
|
if (e2eAccount !== null) {
|
||||||
account.unpickle(pickleKey, e2eAccount);
|
account.unpickle(pickleKey, e2eAccount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
account.create();
|
account.create();
|
||||||
let pickled = account.pickle(pickleKey);
|
const pickled = account.pickle(pickleKey);
|
||||||
sessionStore.storeEndToEndAccount(pickled);
|
sessionStore.storeEndToEndAccount(pickled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +135,9 @@ OlmDevice.getOlmVersion = function() {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._getAccount = function(func) {
|
OlmDevice.prototype._getAccount = function(func) {
|
||||||
let account = new Olm.Account();
|
const account = new Olm.Account();
|
||||||
try {
|
try {
|
||||||
let pickledAccount = this._sessionStore.getEndToEndAccount();
|
const pickledAccount = this._sessionStore.getEndToEndAccount();
|
||||||
account.unpickle(this._pickleKey, pickledAccount);
|
account.unpickle(this._pickleKey, pickledAccount);
|
||||||
return func(account);
|
return func(account);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -141,7 +153,7 @@ OlmDevice.prototype._getAccount = function(func) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._saveAccount = function(account) {
|
OlmDevice.prototype._saveAccount = function(account) {
|
||||||
let pickledAccount = account.pickle(this._pickleKey);
|
const pickledAccount = account.pickle(this._pickleKey);
|
||||||
this._sessionStore.storeEndToEndAccount(pickledAccount);
|
this._sessionStore.storeEndToEndAccount(pickledAccount);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -156,10 +168,10 @@ OlmDevice.prototype._saveAccount = function(account) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._getSession = function(deviceKey, sessionId, func) {
|
OlmDevice.prototype._getSession = function(deviceKey, sessionId, func) {
|
||||||
let sessions = this._sessionStore.getEndToEndSessions(deviceKey);
|
const sessions = this._sessionStore.getEndToEndSessions(deviceKey);
|
||||||
let pickledSession = sessions[sessionId];
|
const pickledSession = sessions[sessionId];
|
||||||
|
|
||||||
let session = new Olm.Session();
|
const session = new Olm.Session();
|
||||||
try {
|
try {
|
||||||
session.unpickle(this._pickleKey, pickledSession);
|
session.unpickle(this._pickleKey, pickledSession);
|
||||||
return func(session);
|
return func(session);
|
||||||
@@ -177,9 +189,9 @@ OlmDevice.prototype._getSession = function(deviceKey, sessionId, func) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._saveSession = function(deviceKey, session) {
|
OlmDevice.prototype._saveSession = function(deviceKey, session) {
|
||||||
let pickledSession = session.pickle(this._pickleKey);
|
const pickledSession = session.pickle(this._pickleKey);
|
||||||
this._sessionStore.storeEndToEndSession(
|
this._sessionStore.storeEndToEndSession(
|
||||||
deviceKey, session.session_id(), pickledSession
|
deviceKey, session.session_id(), pickledSession,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,7 +204,7 @@ OlmDevice.prototype._saveSession = function(deviceKey, session) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._getUtility = function(func) {
|
OlmDevice.prototype._getUtility = function(func) {
|
||||||
let utility = new Olm.Utility();
|
const utility = new Olm.Utility();
|
||||||
try {
|
try {
|
||||||
return func(utility);
|
return func(utility);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -242,7 +254,7 @@ OlmDevice.prototype.maxNumberOfOneTimeKeys = function() {
|
|||||||
* Marks all of the one-time keys as published.
|
* Marks all of the one-time keys as published.
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.markKeysAsPublished = function() {
|
OlmDevice.prototype.markKeysAsPublished = function() {
|
||||||
let self = this;
|
const self = this;
|
||||||
this._getAccount(function(account) {
|
this._getAccount(function(account) {
|
||||||
account.mark_keys_as_published();
|
account.mark_keys_as_published();
|
||||||
self._saveAccount(account);
|
self._saveAccount(account);
|
||||||
@@ -255,7 +267,7 @@ OlmDevice.prototype.markKeysAsPublished = function() {
|
|||||||
* @param {number} numKeys number of keys to generate
|
* @param {number} numKeys number of keys to generate
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.generateOneTimeKeys = function(numKeys) {
|
OlmDevice.prototype.generateOneTimeKeys = function(numKeys) {
|
||||||
let self = this;
|
const self = this;
|
||||||
this._getAccount(function(account) {
|
this._getAccount(function(account) {
|
||||||
account.generate_one_time_keys(numKeys);
|
account.generate_one_time_keys(numKeys);
|
||||||
self._saveAccount(account);
|
self._saveAccount(account);
|
||||||
@@ -272,11 +284,11 @@ OlmDevice.prototype.generateOneTimeKeys = function(numKeys) {
|
|||||||
* @return {string} sessionId for the outbound session.
|
* @return {string} sessionId for the outbound session.
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.createOutboundSession = function(
|
OlmDevice.prototype.createOutboundSession = function(
|
||||||
theirIdentityKey, theirOneTimeKey
|
theirIdentityKey, theirOneTimeKey,
|
||||||
) {
|
) {
|
||||||
let self = this;
|
const self = this;
|
||||||
return this._getAccount(function(account) {
|
return this._getAccount(function(account) {
|
||||||
let session = new Olm.Session();
|
const session = new Olm.Session();
|
||||||
try {
|
try {
|
||||||
session.create_outbound(account, theirIdentityKey, theirOneTimeKey);
|
session.create_outbound(account, theirIdentityKey, theirOneTimeKey);
|
||||||
self._saveSession(theirIdentityKey, session);
|
self._saveSession(theirIdentityKey, session);
|
||||||
@@ -302,21 +314,21 @@ OlmDevice.prototype.createOutboundSession = function(
|
|||||||
* didn't use a valid one-time key).
|
* didn't use a valid one-time key).
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.createInboundSession = function(
|
OlmDevice.prototype.createInboundSession = function(
|
||||||
theirDeviceIdentityKey, message_type, ciphertext
|
theirDeviceIdentityKey, message_type, ciphertext,
|
||||||
) {
|
) {
|
||||||
if (message_type !== 0) {
|
if (message_type !== 0) {
|
||||||
throw new Error("Need message_type == 0 to create inbound session");
|
throw new Error("Need message_type == 0 to create inbound session");
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
return this._getAccount(function(account) {
|
return this._getAccount(function(account) {
|
||||||
let session = new Olm.Session();
|
const session = new Olm.Session();
|
||||||
try {
|
try {
|
||||||
session.create_inbound_from(account, theirDeviceIdentityKey, ciphertext);
|
session.create_inbound_from(account, theirDeviceIdentityKey, ciphertext);
|
||||||
account.remove_one_time_keys(session);
|
account.remove_one_time_keys(session);
|
||||||
self._saveAccount(account);
|
self._saveAccount(account);
|
||||||
|
|
||||||
let payloadString = session.decrypt(message_type, ciphertext);
|
const payloadString = session.decrypt(message_type, ciphertext);
|
||||||
|
|
||||||
self._saveSession(theirDeviceIdentityKey, session);
|
self._saveSession(theirDeviceIdentityKey, session);
|
||||||
|
|
||||||
@@ -339,8 +351,8 @@ OlmDevice.prototype.createInboundSession = function(
|
|||||||
* @return {string[]} a list of known session ids for the device
|
* @return {string[]} a list of known session ids for the device
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.getSessionIdsForDevice = function(theirDeviceIdentityKey) {
|
OlmDevice.prototype.getSessionIdsForDevice = function(theirDeviceIdentityKey) {
|
||||||
let sessions = this._sessionStore.getEndToEndSessions(
|
const sessions = this._sessionStore.getEndToEndSessions(
|
||||||
theirDeviceIdentityKey
|
theirDeviceIdentityKey,
|
||||||
);
|
);
|
||||||
return utils.keys(sessions);
|
return utils.keys(sessions);
|
||||||
};
|
};
|
||||||
@@ -353,7 +365,7 @@ OlmDevice.prototype.getSessionIdsForDevice = function(theirDeviceIdentityKey) {
|
|||||||
* @return {string?} session id, or null if no established session
|
* @return {string?} session id, or null if no established session
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.getSessionIdForDevice = function(theirDeviceIdentityKey) {
|
OlmDevice.prototype.getSessionIdForDevice = function(theirDeviceIdentityKey) {
|
||||||
let sessionIds = this.getSessionIdsForDevice(theirDeviceIdentityKey);
|
const sessionIds = this.getSessionIdsForDevice(theirDeviceIdentityKey);
|
||||||
if (sessionIds.length === 0) {
|
if (sessionIds.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -374,10 +386,10 @@ OlmDevice.prototype.getSessionIdForDevice = function(theirDeviceIdentityKey) {
|
|||||||
* @return {Array.<{sessionId: string, hasReceivedMessage: Boolean}>}
|
* @return {Array.<{sessionId: string, hasReceivedMessage: Boolean}>}
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.getSessionInfoForDevice = function(deviceIdentityKey) {
|
OlmDevice.prototype.getSessionInfoForDevice = function(deviceIdentityKey) {
|
||||||
let sessionIds = this.getSessionIdsForDevice(deviceIdentityKey);
|
const sessionIds = this.getSessionIdsForDevice(deviceIdentityKey);
|
||||||
sessionIds.sort();
|
sessionIds.sort();
|
||||||
|
|
||||||
let info = [];
|
const info = [];
|
||||||
|
|
||||||
function getSessionInfo(session) {
|
function getSessionInfo(session) {
|
||||||
return {
|
return {
|
||||||
@@ -386,8 +398,8 @@ OlmDevice.prototype.getSessionInfoForDevice = function(deviceIdentityKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < sessionIds.length; i++) {
|
for (let i = 0; i < sessionIds.length; i++) {
|
||||||
let sessionId = sessionIds[i];
|
const sessionId = sessionIds[i];
|
||||||
let res = this._getSession(deviceIdentityKey, sessionId, getSessionInfo);
|
const res = this._getSession(deviceIdentityKey, sessionId, getSessionInfo);
|
||||||
res.sessionId = sessionId;
|
res.sessionId = sessionId;
|
||||||
info.push(res);
|
info.push(res);
|
||||||
}
|
}
|
||||||
@@ -405,14 +417,14 @@ OlmDevice.prototype.getSessionInfoForDevice = function(deviceIdentityKey) {
|
|||||||
* @return {string} ciphertext
|
* @return {string} ciphertext
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.encryptMessage = function(
|
OlmDevice.prototype.encryptMessage = function(
|
||||||
theirDeviceIdentityKey, sessionId, payloadString
|
theirDeviceIdentityKey, sessionId, payloadString,
|
||||||
) {
|
) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
checkPayloadLength(payloadString);
|
checkPayloadLength(payloadString);
|
||||||
|
|
||||||
return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {
|
return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {
|
||||||
let res = session.encrypt(payloadString);
|
const res = session.encrypt(payloadString);
|
||||||
self._saveSession(theirDeviceIdentityKey, session);
|
self._saveSession(theirDeviceIdentityKey, session);
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
@@ -430,12 +442,12 @@ OlmDevice.prototype.encryptMessage = function(
|
|||||||
* @return {string} decrypted payload.
|
* @return {string} decrypted payload.
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.decryptMessage = function(
|
OlmDevice.prototype.decryptMessage = function(
|
||||||
theirDeviceIdentityKey, sessionId, message_type, ciphertext
|
theirDeviceIdentityKey, sessionId, message_type, ciphertext,
|
||||||
) {
|
) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {
|
return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {
|
||||||
let payloadString = session.decrypt(message_type, ciphertext);
|
const payloadString = session.decrypt(message_type, ciphertext);
|
||||||
self._saveSession(theirDeviceIdentityKey, session);
|
self._saveSession(theirDeviceIdentityKey, session);
|
||||||
|
|
||||||
return payloadString;
|
return payloadString;
|
||||||
@@ -455,7 +467,7 @@ OlmDevice.prototype.decryptMessage = function(
|
|||||||
* the given session.
|
* the given session.
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.matchesSession = function(
|
OlmDevice.prototype.matchesSession = function(
|
||||||
theirDeviceIdentityKey, sessionId, message_type, ciphertext
|
theirDeviceIdentityKey, sessionId, message_type, ciphertext,
|
||||||
) {
|
) {
|
||||||
if (message_type !== 0) {
|
if (message_type !== 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -477,7 +489,7 @@ OlmDevice.prototype.matchesSession = function(
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._saveOutboundGroupSession = function(session) {
|
OlmDevice.prototype._saveOutboundGroupSession = function(session) {
|
||||||
let pickledSession = session.pickle(this._pickleKey);
|
const pickledSession = session.pickle(this._pickleKey);
|
||||||
this._outboundGroupSessionStore[session.session_id()] = pickledSession;
|
this._outboundGroupSessionStore[session.session_id()] = pickledSession;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -492,12 +504,12 @@ OlmDevice.prototype._saveOutboundGroupSession = function(session) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) {
|
OlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) {
|
||||||
let pickled = this._outboundGroupSessionStore[sessionId];
|
const pickled = this._outboundGroupSessionStore[sessionId];
|
||||||
if (pickled === null) {
|
if (pickled === null) {
|
||||||
throw new Error("Unknown outbound group session " + sessionId);
|
throw new Error("Unknown outbound group session " + sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
let session = new Olm.OutboundGroupSession();
|
const session = new Olm.OutboundGroupSession();
|
||||||
try {
|
try {
|
||||||
session.unpickle(this._pickleKey, pickled);
|
session.unpickle(this._pickleKey, pickled);
|
||||||
return func(session);
|
return func(session);
|
||||||
@@ -513,7 +525,7 @@ OlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) {
|
|||||||
* @return {string} sessionId for the outbound session.
|
* @return {string} sessionId for the outbound session.
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.createOutboundGroupSession = function() {
|
OlmDevice.prototype.createOutboundGroupSession = function() {
|
||||||
let session = new Olm.OutboundGroupSession();
|
const session = new Olm.OutboundGroupSession();
|
||||||
try {
|
try {
|
||||||
session.create();
|
session.create();
|
||||||
this._saveOutboundGroupSession(session);
|
this._saveOutboundGroupSession(session);
|
||||||
@@ -533,12 +545,12 @@ OlmDevice.prototype.createOutboundGroupSession = function() {
|
|||||||
* @return {string} ciphertext
|
* @return {string} ciphertext
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.encryptGroupMessage = function(sessionId, payloadString) {
|
OlmDevice.prototype.encryptGroupMessage = function(sessionId, payloadString) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
checkPayloadLength(payloadString);
|
checkPayloadLength(payloadString);
|
||||||
|
|
||||||
return this._getOutboundGroupSession(sessionId, function(session) {
|
return this._getOutboundGroupSession(sessionId, function(session) {
|
||||||
let res = session.encrypt(payloadString);
|
const res = session.encrypt(payloadString);
|
||||||
self._saveOutboundGroupSession(session);
|
self._saveOutboundGroupSession(session);
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
@@ -576,16 +588,16 @@ OlmDevice.prototype.getOutboundGroupSessionKey = function(sessionId) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._saveInboundGroupSession = function(
|
OlmDevice.prototype._saveInboundGroupSession = function(
|
||||||
roomId, senderCurve25519Key, sessionId, session, keysClaimed
|
roomId, senderCurve25519Key, sessionId, session, keysClaimed,
|
||||||
) {
|
) {
|
||||||
let r = {
|
const r = {
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
session: session.pickle(this._pickleKey),
|
session: session.pickle(this._pickleKey),
|
||||||
keysClaimed: keysClaimed,
|
keysClaimed: keysClaimed,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._sessionStore.storeEndToEndInboundGroupSession(
|
this._sessionStore.storeEndToEndInboundGroupSession(
|
||||||
senderCurve25519Key, sessionId, JSON.stringify(r)
|
senderCurve25519Key, sessionId, JSON.stringify(r),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -606,10 +618,10 @@ OlmDevice.prototype._saveInboundGroupSession = function(
|
|||||||
* @template {T}
|
* @template {T}
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype._getInboundGroupSession = function(
|
OlmDevice.prototype._getInboundGroupSession = function(
|
||||||
roomId, senderKey, sessionId, func
|
roomId, senderKey, sessionId, func,
|
||||||
) {
|
) {
|
||||||
let r = this._sessionStore.getEndToEndInboundGroupSession(
|
let r = this._sessionStore.getEndToEndInboundGroupSession(
|
||||||
senderKey, sessionId
|
senderKey, sessionId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (r === null) {
|
if (r === null) {
|
||||||
@@ -623,11 +635,11 @@ OlmDevice.prototype._getInboundGroupSession = function(
|
|||||||
if (roomId !== r.room_id) {
|
if (roomId !== r.room_id) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Mismatched room_id for inbound group session (expected " + r.room_id +
|
"Mismatched room_id for inbound group session (expected " + r.room_id +
|
||||||
", was " + roomId + ")"
|
", was " + roomId + ")",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let session = new Olm.InboundGroupSession();
|
const session = new Olm.InboundGroupSession();
|
||||||
try {
|
try {
|
||||||
session.unpickle(this._pickleKey, r.session);
|
session.unpickle(this._pickleKey, r.session);
|
||||||
return func(session, r.keysClaimed || {});
|
return func(session, r.keysClaimed || {});
|
||||||
@@ -646,9 +658,9 @@ OlmDevice.prototype._getInboundGroupSession = function(
|
|||||||
* @param {Object<string, string>} keysClaimed Other keys the sender claims.
|
* @param {Object<string, string>} keysClaimed Other keys the sender claims.
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.addInboundGroupSession = function(
|
OlmDevice.prototype.addInboundGroupSession = function(
|
||||||
roomId, senderKey, sessionId, sessionKey, keysClaimed
|
roomId, senderKey, sessionId, sessionKey, keysClaimed,
|
||||||
) {
|
) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
/* if we already have this session, consider updating it */
|
/* if we already have this session, consider updating it */
|
||||||
function updateSession(session) {
|
function updateSession(session) {
|
||||||
@@ -658,8 +670,8 @@ OlmDevice.prototype.addInboundGroupSession = function(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = this._getInboundGroupSession(
|
const r = this._getInboundGroupSession(
|
||||||
roomId, senderKey, sessionId, updateSession
|
roomId, senderKey, sessionId, updateSession,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (r !== null) {
|
if (r !== null) {
|
||||||
@@ -667,16 +679,58 @@ OlmDevice.prototype.addInboundGroupSession = function(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// new session.
|
// new session.
|
||||||
let session = new Olm.InboundGroupSession();
|
const session = new Olm.InboundGroupSession();
|
||||||
try {
|
try {
|
||||||
session.create(sessionKey);
|
session.create(sessionKey);
|
||||||
if (sessionId != session.session_id()) {
|
if (sessionId != session.session_id()) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Mismatched group session ID from senderKey: " + senderKey
|
"Mismatched group session ID from senderKey: " + senderKey,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self._saveInboundGroupSession(
|
self._saveInboundGroupSession(
|
||||||
roomId, senderKey, sessionId, session, keysClaimed
|
roomId, senderKey, sessionId, session, keysClaimed,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
session.free();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a previously-exported inbound group session to the session store
|
||||||
|
*
|
||||||
|
* @param {module:crypto/OlmDevice.MegolmSessionData} data session data
|
||||||
|
*/
|
||||||
|
OlmDevice.prototype.importInboundGroupSession = function(data) {
|
||||||
|
/* if we already have this session, consider updating it */
|
||||||
|
function updateSession(session) {
|
||||||
|
console.log("Update for megolm session " + data.sender_key + "|" +
|
||||||
|
data.session_id);
|
||||||
|
// for now we just ignore updates. TODO: implement something here
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const r = this._getInboundGroupSession(
|
||||||
|
data.room_id, data.sender_key, data.session_id, updateSession,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (r !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new session.
|
||||||
|
const session = new Olm.InboundGroupSession();
|
||||||
|
try {
|
||||||
|
session.import_session(data.session_key);
|
||||||
|
if (data.session_id != session.session_id()) {
|
||||||
|
throw new Error(
|
||||||
|
"Mismatched group session ID from senderKey: " + data.sender_key,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this._saveInboundGroupSession(
|
||||||
|
data.room_id, data.sender_key, data.session_id, session,
|
||||||
|
data.sender_claimed_keys,
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
session.free();
|
session.free();
|
||||||
@@ -697,12 +751,12 @@ OlmDevice.prototype.addInboundGroupSession = function(
|
|||||||
* Object<string, string>}} result
|
* Object<string, string>}} result
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.decryptGroupMessage = function(
|
OlmDevice.prototype.decryptGroupMessage = function(
|
||||||
roomId, senderKey, sessionId, body
|
roomId, senderKey, sessionId, body,
|
||||||
) {
|
) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
function decrypt(session, keysClaimed) {
|
function decrypt(session, keysClaimed) {
|
||||||
let res = session.decrypt(body);
|
const res = session.decrypt(body);
|
||||||
|
|
||||||
let plaintext = res.plaintext;
|
let plaintext = res.plaintext;
|
||||||
if (plaintext === undefined) {
|
if (plaintext === undefined) {
|
||||||
@@ -710,11 +764,11 @@ OlmDevice.prototype.decryptGroupMessage = function(
|
|||||||
plaintext = res;
|
plaintext = res;
|
||||||
} else {
|
} else {
|
||||||
// Check if we have seen this message index before to detect replay attacks.
|
// Check if we have seen this message index before to detect replay attacks.
|
||||||
let messageIndexKey = senderKey + "|" + sessionId + "|" + res.message_index;
|
const messageIndexKey = senderKey + "|" + sessionId + "|" + res.message_index;
|
||||||
if (messageIndexKey in self._inboundGroupSessionMessageIndexes) {
|
if (messageIndexKey in self._inboundGroupSessionMessageIndexes) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Duplicate message index, possible replay attack: " +
|
"Duplicate message index, possible replay attack: " +
|
||||||
messageIndexKey
|
messageIndexKey,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self._inboundGroupSessionMessageIndexes[messageIndexKey] = true;
|
self._inboundGroupSessionMessageIndexes[messageIndexKey] = true;
|
||||||
@@ -722,10 +776,10 @@ OlmDevice.prototype.decryptGroupMessage = function(
|
|||||||
|
|
||||||
// the sender must have had the senderKey to persuade us to save the
|
// the sender must have had the senderKey to persuade us to save the
|
||||||
// session.
|
// session.
|
||||||
let keysProved = {curve25519: senderKey};
|
const keysProved = {curve25519: senderKey};
|
||||||
|
|
||||||
self._saveInboundGroupSession(
|
self._saveInboundGroupSession(
|
||||||
roomId, senderKey, sessionId, session, keysClaimed
|
roomId, senderKey, sessionId, session, keysClaimed,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
result: plaintext,
|
result: plaintext,
|
||||||
@@ -735,10 +789,45 @@ OlmDevice.prototype.decryptGroupMessage = function(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this._getInboundGroupSession(
|
return this._getInboundGroupSession(
|
||||||
roomId, senderKey, sessionId, decrypt
|
roomId, senderKey, sessionId, decrypt,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export an inbound group session
|
||||||
|
*
|
||||||
|
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||||
|
* @param {string} sessionId session identifier
|
||||||
|
* @return {module:crypto/OlmDevice.MegolmSessionData} exported session data
|
||||||
|
*/
|
||||||
|
OlmDevice.prototype.exportInboundGroupSession = function(senderKey, sessionId) {
|
||||||
|
const s = this._sessionStore.getEndToEndInboundGroupSession(
|
||||||
|
senderKey, sessionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (s === null) {
|
||||||
|
throw new Error("Unknown inbound group session [" + senderKey + "," +
|
||||||
|
sessionId + "]");
|
||||||
|
}
|
||||||
|
const r = JSON.parse(s);
|
||||||
|
|
||||||
|
const session = new Olm.InboundGroupSession();
|
||||||
|
try {
|
||||||
|
session.unpickle(this._pickleKey, r.session);
|
||||||
|
|
||||||
|
const messageIndex = session.first_known_index();
|
||||||
|
|
||||||
|
return {
|
||||||
|
"sender_key": senderKey,
|
||||||
|
"sender_claimed_keys": r.keysClaimed,
|
||||||
|
"room_id": r.room_id,
|
||||||
|
"session_id": sessionId,
|
||||||
|
"session_key": session.export_session(messageIndex),
|
||||||
|
};
|
||||||
|
} finally {
|
||||||
|
session.free();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
// =========
|
// =========
|
||||||
@@ -755,7 +844,7 @@ OlmDevice.prototype.decryptGroupMessage = function(
|
|||||||
* was invalid then the message will be "OLM.BAD_MESSAGE_MAC".
|
* was invalid then the message will be "OLM.BAD_MESSAGE_MAC".
|
||||||
*/
|
*/
|
||||||
OlmDevice.prototype.verifySignature = function(
|
OlmDevice.prototype.verifySignature = function(
|
||||||
key, message, signature
|
key, message, signature,
|
||||||
) {
|
) {
|
||||||
this._getUtility(function(util) {
|
this._getUtility(function(util) {
|
||||||
util.ed25519_verify(key, message, signature);
|
util.ed25519_verify(key, message, signature);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ limitations under the License.
|
|||||||
*
|
*
|
||||||
* @module crypto/algorithms/base
|
* @module crypto/algorithms/base
|
||||||
*/
|
*/
|
||||||
let utils = require("../../utils");
|
const utils = require("../../utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* map of registered encryption algorithm classes. A map from string to {@link
|
* map of registered encryption algorithm classes. A map from string to {@link
|
||||||
@@ -53,7 +53,7 @@ module.exports.DECRYPTION_CLASSES = {};
|
|||||||
* @param {string} params.roomId The ID of the room we will be sending to
|
* @param {string} params.roomId The ID of the room we will be sending to
|
||||||
* @param {object} params.config The body of the m.room.encryption event
|
* @param {object} params.config The body of the m.room.encryption event
|
||||||
*/
|
*/
|
||||||
let EncryptionAlgorithm = function(params) {
|
const EncryptionAlgorithm = function(params) {
|
||||||
this._userId = params.userId;
|
this._userId = params.userId;
|
||||||
this._deviceId = params.deviceId;
|
this._deviceId = params.deviceId;
|
||||||
this._crypto = params.crypto;
|
this._crypto = params.crypto;
|
||||||
@@ -85,7 +85,7 @@ module.exports.EncryptionAlgorithm = EncryptionAlgorithm;
|
|||||||
* @param {string=} oldMembership previous membership
|
* @param {string=} oldMembership previous membership
|
||||||
*/
|
*/
|
||||||
EncryptionAlgorithm.prototype.onRoomMembership = function(
|
EncryptionAlgorithm.prototype.onRoomMembership = function(
|
||||||
event, member, oldMembership
|
event, member, oldMembership,
|
||||||
) {};
|
) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,7 +101,7 @@ EncryptionAlgorithm.prototype.onRoomMembership = function(
|
|||||||
* @param {string=} params.roomId The ID of the room we will be receiving
|
* @param {string=} params.roomId The ID of the room we will be receiving
|
||||||
* from. Null for to-device events.
|
* from. Null for to-device events.
|
||||||
*/
|
*/
|
||||||
let DecryptionAlgorithm = function(params) {
|
const DecryptionAlgorithm = function(params) {
|
||||||
this._userId = params.userId;
|
this._userId = params.userId;
|
||||||
this._crypto = params.crypto;
|
this._crypto = params.crypto;
|
||||||
this._olmDevice = params.olmDevice;
|
this._olmDevice = params.olmDevice;
|
||||||
@@ -136,6 +136,15 @@ DecryptionAlgorithm.prototype.onRoomKeyEvent = function(params) {
|
|||||||
// ignore by default
|
// ignore by default
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a room key
|
||||||
|
*
|
||||||
|
* @param {module:crypto/OlmDevice.MegolmSessionData} session
|
||||||
|
*/
|
||||||
|
DecryptionAlgorithm.prototype.importRoomKey = function(session) {
|
||||||
|
// ignore by default
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when decryption fails
|
* Exception thrown when decryption fails
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ limitations under the License.
|
|||||||
* @module crypto/algorithms
|
* @module crypto/algorithms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let base = require("./base");
|
const base = require("./base");
|
||||||
|
|
||||||
require("./olm");
|
require("./olm");
|
||||||
require("./megolm");
|
require("./megolm");
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ limitations under the License.
|
|||||||
* @module crypto/algorithms/megolm
|
* @module crypto/algorithms/megolm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
|
|
||||||
let utils = require("../../utils");
|
const utils = require("../../utils");
|
||||||
let olmlib = require("../olmlib");
|
const olmlib = require("../olmlib");
|
||||||
let base = require("./base");
|
const base = require("./base");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -57,16 +57,16 @@ function OutboundSessionInfo(sessionId) {
|
|||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
OutboundSessionInfo.prototype.needsRotation = function(
|
OutboundSessionInfo.prototype.needsRotation = function(
|
||||||
rotationPeriodMsgs, rotationPeriodMs
|
rotationPeriodMsgs, rotationPeriodMs,
|
||||||
) {
|
) {
|
||||||
let sessionLifetime = new Date().getTime() - this.creationTime;
|
const sessionLifetime = new Date().getTime() - this.creationTime;
|
||||||
|
|
||||||
if (this.useCount >= rotationPeriodMsgs ||
|
if (this.useCount >= rotationPeriodMsgs ||
|
||||||
sessionLifetime >= rotationPeriodMs
|
sessionLifetime >= rotationPeriodMs
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
"Rotating megolm session after " + this.useCount +
|
"Rotating megolm session after " + this.useCount +
|
||||||
" messages, " + sessionLifetime + "ms"
|
" messages, " + sessionLifetime + "ms",
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -86,9 +86,9 @@ OutboundSessionInfo.prototype.needsRotation = function(
|
|||||||
* in devicesInRoom.
|
* in devicesInRoom.
|
||||||
*/
|
*/
|
||||||
OutboundSessionInfo.prototype.sharedWithTooManyDevices = function(
|
OutboundSessionInfo.prototype.sharedWithTooManyDevices = function(
|
||||||
devicesInRoom
|
devicesInRoom,
|
||||||
) {
|
) {
|
||||||
for (let userId in this.sharedWithDevices) {
|
for (const userId in this.sharedWithDevices) {
|
||||||
if (!this.sharedWithDevices.hasOwnProperty(userId)) {
|
if (!this.sharedWithDevices.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ OutboundSessionInfo.prototype.sharedWithTooManyDevices = function(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let deviceId in this.sharedWithDevices[userId]) {
|
for (const deviceId in this.sharedWithDevices[userId]) {
|
||||||
if (!this.sharedWithDevices[userId].hasOwnProperty(deviceId)) {
|
if (!this.sharedWithDevices[userId].hasOwnProperty(deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ OutboundSessionInfo.prototype.sharedWithTooManyDevices = function(
|
|||||||
if (!devicesInRoom[userId].hasOwnProperty(deviceId)) {
|
if (!devicesInRoom[userId].hasOwnProperty(deviceId)) {
|
||||||
console.log(
|
console.log(
|
||||||
"Starting new session because we shared with " +
|
"Starting new session because we shared with " +
|
||||||
userId + ":" + deviceId
|
userId + ":" + deviceId,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ utils.inherits(MegolmEncryption, base.EncryptionAlgorithm);
|
|||||||
* OutboundSessionInfo when setup is complete.
|
* OutboundSessionInfo when setup is complete.
|
||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
let session;
|
let session;
|
||||||
|
|
||||||
@@ -187,23 +187,23 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now check if we need to share with any devices
|
// now check if we need to share with any devices
|
||||||
let shareMap = {};
|
const shareMap = {};
|
||||||
|
|
||||||
for (let userId in devicesInRoom) {
|
for (const userId in devicesInRoom) {
|
||||||
if (!devicesInRoom.hasOwnProperty(userId)) {
|
if (!devicesInRoom.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let userDevices = devicesInRoom[userId];
|
const userDevices = devicesInRoom[userId];
|
||||||
|
|
||||||
for (let deviceId in userDevices) {
|
for (const deviceId in userDevices) {
|
||||||
if (!userDevices.hasOwnProperty(deviceId)) {
|
if (!userDevices.hasOwnProperty(deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let deviceInfo = userDevices[deviceId];
|
const deviceInfo = userDevices[deviceId];
|
||||||
|
|
||||||
let key = deviceInfo.getIdentityKey();
|
const key = deviceInfo.getIdentityKey();
|
||||||
if (key == self._olmDevice.deviceCurve25519Key) {
|
if (key == self._olmDevice.deviceCurve25519Key) {
|
||||||
// don't bother sending to ourself
|
// don't bother sending to ourself
|
||||||
continue;
|
continue;
|
||||||
@@ -220,7 +220,7 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return self._shareKeyWithDevices(
|
return self._shareKeyWithDevices(
|
||||||
session, shareMap
|
session, shareMap,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first wait for the previous share to complete
|
// first wait for the previous share to complete
|
||||||
let prom = this._setupPromise.then(prepareSession);
|
const prom = this._setupPromise.then(prepareSession);
|
||||||
|
|
||||||
// _setupPromise resolves to `session` whether or not the share succeeds
|
// _setupPromise resolves to `session` whether or not the share succeeds
|
||||||
this._setupPromise = prom.then(returnSession, returnSession);
|
this._setupPromise = prom.then(returnSession, returnSession);
|
||||||
@@ -245,12 +245,12 @@ MegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {
|
|||||||
* @return {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
* @return {module:crypto/algorithms/megolm.OutboundSessionInfo} session
|
||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype._prepareNewSession = function() {
|
MegolmEncryption.prototype._prepareNewSession = function() {
|
||||||
let session_id = this._olmDevice.createOutboundGroupSession();
|
const session_id = this._olmDevice.createOutboundGroupSession();
|
||||||
let key = this._olmDevice.getOutboundGroupSessionKey(session_id);
|
const key = this._olmDevice.getOutboundGroupSessionKey(session_id);
|
||||||
|
|
||||||
this._olmDevice.addInboundGroupSession(
|
this._olmDevice.addInboundGroupSession(
|
||||||
this._roomId, this._olmDevice.deviceCurve25519Key, session_id,
|
this._roomId, this._olmDevice.deviceCurve25519Key, session_id,
|
||||||
key.key, {ed25519: this._olmDevice.deviceEd25519Key}
|
key.key, {ed25519: this._olmDevice.deviceEd25519Key},
|
||||||
);
|
);
|
||||||
|
|
||||||
return new OutboundSessionInfo(session_id);
|
return new OutboundSessionInfo(session_id);
|
||||||
@@ -268,10 +268,10 @@ MegolmEncryption.prototype._prepareNewSession = function() {
|
|||||||
* message has been sent.
|
* message has been sent.
|
||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUser) {
|
MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUser) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
let key = this._olmDevice.getOutboundGroupSessionKey(session.sessionId);
|
const key = this._olmDevice.getOutboundGroupSessionKey(session.sessionId);
|
||||||
let payload = {
|
const payload = {
|
||||||
type: "m.room_key",
|
type: "m.room_key",
|
||||||
content: {
|
content: {
|
||||||
algorithm: olmlib.MEGOLM_ALGORITHM,
|
algorithm: olmlib.MEGOLM_ALGORITHM,
|
||||||
@@ -282,26 +282,26 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let contentMap = {};
|
const contentMap = {};
|
||||||
|
|
||||||
return olmlib.ensureOlmSessionsForDevices(
|
return olmlib.ensureOlmSessionsForDevices(
|
||||||
this._olmDevice, this._baseApis, devicesByUser
|
this._olmDevice, this._baseApis, devicesByUser,
|
||||||
).then(function(devicemap) {
|
).then(function(devicemap) {
|
||||||
let haveTargets = false;
|
let haveTargets = false;
|
||||||
|
|
||||||
for (let userId in devicesByUser) {
|
for (const userId in devicesByUser) {
|
||||||
if (!devicesByUser.hasOwnProperty(userId)) {
|
if (!devicesByUser.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let devicesToShareWith = devicesByUser[userId];
|
const devicesToShareWith = devicesByUser[userId];
|
||||||
let sessionResults = devicemap[userId];
|
const sessionResults = devicemap[userId];
|
||||||
|
|
||||||
for (let i = 0; i < devicesToShareWith.length; i++) {
|
for (let i = 0; i < devicesToShareWith.length; i++) {
|
||||||
let deviceInfo = devicesToShareWith[i];
|
const deviceInfo = devicesToShareWith[i];
|
||||||
let deviceId = deviceInfo.deviceId;
|
const deviceId = deviceInfo.deviceId;
|
||||||
|
|
||||||
let sessionResult = sessionResults[deviceId];
|
const sessionResult = sessionResults[deviceId];
|
||||||
if (!sessionResult.sessionId) {
|
if (!sessionResult.sessionId) {
|
||||||
// no session with this device, probably because there
|
// no session with this device, probably because there
|
||||||
// were no one-time keys.
|
// were no one-time keys.
|
||||||
@@ -318,10 +318,10 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"sharing keys with device " + userId + ":" + deviceId
|
"sharing keys with device " + userId + ":" + deviceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
let encryptedContent = {
|
const encryptedContent = {
|
||||||
algorithm: olmlib.OLM_ALGORITHM,
|
algorithm: olmlib.OLM_ALGORITHM,
|
||||||
sender_key: self._olmDevice.deviceCurve25519Key,
|
sender_key: self._olmDevice.deviceCurve25519Key,
|
||||||
ciphertext: {},
|
ciphertext: {},
|
||||||
@@ -334,7 +334,7 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse
|
|||||||
self._olmDevice,
|
self._olmDevice,
|
||||||
userId,
|
userId,
|
||||||
deviceInfo,
|
deviceInfo,
|
||||||
payload
|
payload,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!contentMap[userId]) {
|
if (!contentMap[userId]) {
|
||||||
@@ -359,16 +359,16 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse
|
|||||||
// attempted to share with) rather than the contentMap (those we did
|
// attempted to share with) rather than the contentMap (those we did
|
||||||
// share with), because we don't want to try to claim a one-time-key
|
// share with), because we don't want to try to claim a one-time-key
|
||||||
// for dead devices on every message.
|
// for dead devices on every message.
|
||||||
for (let userId in devicesByUser) {
|
for (const userId in devicesByUser) {
|
||||||
if (!devicesByUser.hasOwnProperty(userId)) {
|
if (!devicesByUser.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!session.sharedWithDevices[userId]) {
|
if (!session.sharedWithDevices[userId]) {
|
||||||
session.sharedWithDevices[userId] = {};
|
session.sharedWithDevices[userId] = {};
|
||||||
}
|
}
|
||||||
let devicesToShareWith = devicesByUser[userId];
|
const devicesToShareWith = devicesByUser[userId];
|
||||||
for (let i = 0; i < devicesToShareWith.length; i++) {
|
for (let i = 0; i < devicesToShareWith.length; i++) {
|
||||||
let deviceInfo = devicesToShareWith[i];
|
const deviceInfo = devicesToShareWith[i];
|
||||||
session.sharedWithDevices[userId][deviceInfo.deviceId] =
|
session.sharedWithDevices[userId][deviceInfo.deviceId] =
|
||||||
key.chain_index;
|
key.chain_index;
|
||||||
}
|
}
|
||||||
@@ -386,21 +386,21 @@ MegolmEncryption.prototype._shareKeyWithDevices = function(session, devicesByUse
|
|||||||
* @return {module:client.Promise} Promise which resolves to the new event body
|
* @return {module:client.Promise} Promise which resolves to the new event body
|
||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
||||||
let self = this;
|
const self = this;
|
||||||
return this._getDevicesInRoom(room).then(function(devicesInRoom) {
|
return this._getDevicesInRoom(room).then(function(devicesInRoom) {
|
||||||
return self._ensureOutboundSession(devicesInRoom);
|
return self._ensureOutboundSession(devicesInRoom);
|
||||||
}).then(function(session) {
|
}).then(function(session) {
|
||||||
let payloadJson = {
|
const payloadJson = {
|
||||||
room_id: self._roomId,
|
room_id: self._roomId,
|
||||||
type: eventType,
|
type: eventType,
|
||||||
content: content,
|
content: content,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ciphertext = self._olmDevice.encryptGroupMessage(
|
const ciphertext = self._olmDevice.encryptGroupMessage(
|
||||||
session.sessionId, JSON.stringify(payloadJson)
|
session.sessionId, JSON.stringify(payloadJson),
|
||||||
);
|
);
|
||||||
|
|
||||||
let encryptedContent = {
|
const encryptedContent = {
|
||||||
algorithm: olmlib.MEGOLM_ALGORITHM,
|
algorithm: olmlib.MEGOLM_ALGORITHM,
|
||||||
sender_key: self._olmDevice.deviceCurve25519Key,
|
sender_key: self._olmDevice.deviceCurve25519Key,
|
||||||
ciphertext: ciphertext,
|
ciphertext: ciphertext,
|
||||||
@@ -425,7 +425,7 @@ MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
|||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype._getDevicesInRoom = function(room) {
|
MegolmEncryption.prototype._getDevicesInRoom = function(room) {
|
||||||
// XXX what about rooms where invitees can see the content?
|
// XXX what about rooms where invitees can see the content?
|
||||||
let roomMembers = utils.map(room.getJoinedMembers(), function(u) {
|
const roomMembers = utils.map(room.getJoinedMembers(), function(u) {
|
||||||
return u.userId;
|
return u.userId;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -435,13 +435,13 @@ MegolmEncryption.prototype._getDevicesInRoom = function(room) {
|
|||||||
// an m.new_device.
|
// an m.new_device.
|
||||||
return this._crypto.downloadKeys(roomMembers, false).then(function(devices) {
|
return this._crypto.downloadKeys(roomMembers, false).then(function(devices) {
|
||||||
// remove any blocked devices
|
// remove any blocked devices
|
||||||
for (let userId in devices) {
|
for (const userId in devices) {
|
||||||
if (!devices.hasOwnProperty(userId)) {
|
if (!devices.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let userDevices = devices[userId];
|
const userDevices = devices[userId];
|
||||||
for (let deviceId in userDevices) {
|
for (const deviceId in userDevices) {
|
||||||
if (!userDevices.hasOwnProperty(deviceId)) {
|
if (!userDevices.hasOwnProperty(deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -482,7 +482,7 @@ utils.inherits(MegolmDecryption, base.DecryptionAlgorithm);
|
|||||||
* problem decrypting the event
|
* problem decrypting the event
|
||||||
*/
|
*/
|
||||||
MegolmDecryption.prototype.decryptEvent = function(event) {
|
MegolmDecryption.prototype.decryptEvent = function(event) {
|
||||||
let content = event.getWireContent();
|
const content = event.getWireContent();
|
||||||
|
|
||||||
if (!content.sender_key || !content.session_id ||
|
if (!content.sender_key || !content.session_id ||
|
||||||
!content.ciphertext
|
!content.ciphertext
|
||||||
@@ -493,7 +493,7 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
res = this._olmDevice.decryptGroupMessage(
|
res = this._olmDevice.decryptGroupMessage(
|
||||||
event.getRoomId(), content.sender_key, content.session_id, content.ciphertext
|
event.getRoomId(), content.sender_key, content.session_id, content.ciphertext,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
|
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
|
||||||
@@ -506,18 +506,18 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
// We've got a message for a session we don't have.
|
// We've got a message for a session we don't have.
|
||||||
this._addEventToPendingList(event);
|
this._addEventToPendingList(event);
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"The sender's device has not sent us the keys for this message."
|
"The sender's device has not sent us the keys for this message.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let payload = JSON.parse(res.result);
|
const payload = JSON.parse(res.result);
|
||||||
|
|
||||||
// belt-and-braces check that the room id matches that indicated by the HS
|
// belt-and-braces check that the room id matches that indicated by the HS
|
||||||
// (this is somewhat redundant, since the megolm session is scoped to the
|
// (this is somewhat redundant, since the megolm session is scoped to the
|
||||||
// room, so neither the sender nor a MITM can lie about the room_id).
|
// room, so neither the sender nor a MITM can lie about the room_id).
|
||||||
if (payload.room_id !== event.getRoomId()) {
|
if (payload.room_id !== event.getRoomId()) {
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message intended for room " + payload.room_id
|
"Message intended for room " + payload.room_id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,8 +534,8 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
* @param {module:models/event.MatrixEvent} event
|
* @param {module:models/event.MatrixEvent} event
|
||||||
*/
|
*/
|
||||||
MegolmDecryption.prototype._addEventToPendingList = function(event) {
|
MegolmDecryption.prototype._addEventToPendingList = function(event) {
|
||||||
let content = event.getWireContent();
|
const content = event.getWireContent();
|
||||||
let k = content.sender_key + "|" + content.session_id;
|
const k = content.sender_key + "|" + content.session_id;
|
||||||
if (!this._pendingEvents[k]) {
|
if (!this._pendingEvents[k]) {
|
||||||
this._pendingEvents[k] = [];
|
this._pendingEvents[k] = [];
|
||||||
}
|
}
|
||||||
@@ -549,7 +549,7 @@ MegolmDecryption.prototype._addEventToPendingList = function(event) {
|
|||||||
*/
|
*/
|
||||||
MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
||||||
console.log("Adding key from ", event);
|
console.log("Adding key from ", event);
|
||||||
let content = event.getContent();
|
const content = event.getContent();
|
||||||
|
|
||||||
if (!content.room_id ||
|
if (!content.room_id ||
|
||||||
!content.session_id ||
|
!content.session_id ||
|
||||||
@@ -561,13 +561,40 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
|||||||
|
|
||||||
this._olmDevice.addInboundGroupSession(
|
this._olmDevice.addInboundGroupSession(
|
||||||
content.room_id, event.getSenderKey(), content.session_id,
|
content.room_id, event.getSenderKey(), content.session_id,
|
||||||
content.session_key, event.getKeysClaimed()
|
content.session_key, event.getKeysClaimed(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let k = event.getSenderKey() + "|" + content.session_id;
|
|
||||||
let pending = this._pendingEvents[k];
|
|
||||||
if (pending) {
|
|
||||||
// have another go at decrypting events sent with this session.
|
// have another go at decrypting events sent with this session.
|
||||||
|
this._retryDecryption(event.getSenderKey, content.session_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*
|
||||||
|
* @param {module:crypto/OlmDevice.MegolmSessionData} session
|
||||||
|
*/
|
||||||
|
MegolmDecryption.prototype.importRoomKey = function(session) {
|
||||||
|
this._olmDevice.importInboundGroupSession(session);
|
||||||
|
|
||||||
|
// have another go at decrypting events sent with this session.
|
||||||
|
this._retryDecryption(session.sender_key, session.session_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Have another go at decrypting events after we receive a key
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} senderKey
|
||||||
|
* @param {String} sessionId
|
||||||
|
*/
|
||||||
|
MegolmDecryption.prototype._retryDecryption = function(senderKey, sessionId) {
|
||||||
|
const k = senderKey + "|" + sessionId;
|
||||||
|
const pending = this._pendingEvents[k];
|
||||||
|
if (!pending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
delete this._pendingEvents[k];
|
delete this._pendingEvents[k];
|
||||||
|
|
||||||
for (let i = 0; i < pending.length; i++) {
|
for (let i = 0; i < pending.length; i++) {
|
||||||
@@ -578,9 +605,8 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
|||||||
console.log("Still can't decrypt", pending[i], e.stack || e);
|
console.log("Still can't decrypt", pending[i], e.stack || e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
base.registerAlgorithm(
|
base.registerAlgorithm(
|
||||||
olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption
|
olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ limitations under the License.
|
|||||||
*
|
*
|
||||||
* @module crypto/algorithms/olm
|
* @module crypto/algorithms/olm
|
||||||
*/
|
*/
|
||||||
let q = require('q');
|
const q = require('q');
|
||||||
|
|
||||||
let utils = require("../../utils");
|
const utils = require("../../utils");
|
||||||
let olmlib = require("../olmlib");
|
const olmlib = require("../olmlib");
|
||||||
let DeviceInfo = require("../deviceinfo");
|
const DeviceInfo = require("../deviceinfo");
|
||||||
let DeviceVerification = DeviceInfo.DeviceVerification;
|
const DeviceVerification = DeviceInfo.DeviceVerification;
|
||||||
|
|
||||||
|
|
||||||
let base = require("./base");
|
const base = require("./base");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Olm encryption implementation
|
* Olm encryption implementation
|
||||||
@@ -63,7 +63,7 @@ OlmEncryption.prototype._ensureSession = function(roomMembers) {
|
|||||||
return q();
|
return q();
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
this._prepPromise = self._crypto.downloadKeys(roomMembers, true).then(function(res) {
|
this._prepPromise = self._crypto.downloadKeys(roomMembers, true).then(function(res) {
|
||||||
return self._crypto.ensureOlmSessionsForUsers(roomMembers);
|
return self._crypto.ensureOlmSessionsForUsers(roomMembers);
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
@@ -89,31 +89,31 @@ OlmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
|||||||
// TODO: there is a race condition here! What if a new user turns up
|
// TODO: there is a race condition here! What if a new user turns up
|
||||||
// just as you are sending a secret message?
|
// just as you are sending a secret message?
|
||||||
|
|
||||||
let users = utils.map(room.getJoinedMembers(), function(u) {
|
const users = utils.map(room.getJoinedMembers(), function(u) {
|
||||||
return u.userId;
|
return u.userId;
|
||||||
});
|
});
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
return this._ensureSession(users).then(function() {
|
return this._ensureSession(users).then(function() {
|
||||||
let payloadFields = {
|
const payloadFields = {
|
||||||
room_id: room.roomId,
|
room_id: room.roomId,
|
||||||
type: eventType,
|
type: eventType,
|
||||||
content: content,
|
content: content,
|
||||||
};
|
};
|
||||||
|
|
||||||
let encryptedContent = {
|
const encryptedContent = {
|
||||||
algorithm: olmlib.OLM_ALGORITHM,
|
algorithm: olmlib.OLM_ALGORITHM,
|
||||||
sender_key: self._olmDevice.deviceCurve25519Key,
|
sender_key: self._olmDevice.deviceCurve25519Key,
|
||||||
ciphertext: {},
|
ciphertext: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i = 0; i < users.length; ++i) {
|
for (let i = 0; i < users.length; ++i) {
|
||||||
let userId = users[i];
|
const userId = users[i];
|
||||||
let devices = self._crypto.getStoredDevicesForUser(userId);
|
const devices = self._crypto.getStoredDevicesForUser(userId);
|
||||||
|
|
||||||
for (let j = 0; j < devices.length; ++j) {
|
for (let j = 0; j < devices.length; ++j) {
|
||||||
let deviceInfo = devices[j];
|
const deviceInfo = devices[j];
|
||||||
let key = deviceInfo.getIdentityKey();
|
const key = deviceInfo.getIdentityKey();
|
||||||
if (key == self._olmDevice.deviceCurve25519Key) {
|
if (key == self._olmDevice.deviceCurve25519Key) {
|
||||||
// don't bother sending to ourself
|
// don't bother sending to ourself
|
||||||
continue;
|
continue;
|
||||||
@@ -126,7 +126,7 @@ OlmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
|||||||
olmlib.encryptMessageForDevice(
|
olmlib.encryptMessageForDevice(
|
||||||
encryptedContent.ciphertext,
|
encryptedContent.ciphertext,
|
||||||
self._userId, self._deviceId, self._olmDevice,
|
self._userId, self._deviceId, self._olmDevice,
|
||||||
userId, deviceInfo, payloadFields
|
userId, deviceInfo, payloadFields,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,9 +157,9 @@ utils.inherits(OlmDecryption, base.DecryptionAlgorithm);
|
|||||||
* problem decrypting the event
|
* problem decrypting the event
|
||||||
*/
|
*/
|
||||||
OlmDecryption.prototype.decryptEvent = function(event) {
|
OlmDecryption.prototype.decryptEvent = function(event) {
|
||||||
let content = event.getWireContent();
|
const content = event.getWireContent();
|
||||||
let deviceKey = content.sender_key;
|
const deviceKey = content.sender_key;
|
||||||
let ciphertext = content.ciphertext;
|
const ciphertext = content.ciphertext;
|
||||||
|
|
||||||
if (!ciphertext) {
|
if (!ciphertext) {
|
||||||
throw new base.DecryptionError("Missing ciphertext");
|
throw new base.DecryptionError("Missing ciphertext");
|
||||||
@@ -168,7 +168,7 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
if (!(this._olmDevice.deviceCurve25519Key in ciphertext)) {
|
if (!(this._olmDevice.deviceCurve25519Key in ciphertext)) {
|
||||||
throw new base.DecryptionError("Not included in recipients");
|
throw new base.DecryptionError("Not included in recipients");
|
||||||
}
|
}
|
||||||
let message = ciphertext[this._olmDevice.deviceCurve25519Key];
|
const message = ciphertext[this._olmDevice.deviceCurve25519Key];
|
||||||
let payloadString;
|
let payloadString;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -177,22 +177,22 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
console.warn(
|
console.warn(
|
||||||
"Failed to decrypt Olm event (id=" +
|
"Failed to decrypt Olm event (id=" +
|
||||||
event.getId() + ") from " + deviceKey +
|
event.getId() + ") from " + deviceKey +
|
||||||
": " + e.message
|
": " + e.message,
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError("Bad Encrypted Message");
|
throw new base.DecryptionError("Bad Encrypted Message");
|
||||||
}
|
}
|
||||||
|
|
||||||
let payload = JSON.parse(payloadString);
|
const payload = JSON.parse(payloadString);
|
||||||
|
|
||||||
// check that we were the intended recipient, to avoid unknown-key attack
|
// check that we were the intended recipient, to avoid unknown-key attack
|
||||||
// https://github.com/vector-im/vector-web/issues/2483
|
// https://github.com/vector-im/vector-web/issues/2483
|
||||||
if (payload.recipient != this._userId) {
|
if (payload.recipient != this._userId) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Event " + event.getId() + ": Intended recipient " +
|
"Event " + event.getId() + ": Intended recipient " +
|
||||||
payload.recipient + " does not match our id " + this._userId
|
payload.recipient + " does not match our id " + this._userId,
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message was intented for " + payload.recipient
|
"Message was intented for " + payload.recipient,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
this._olmDevice.deviceEd25519Key) {
|
this._olmDevice.deviceEd25519Key) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Event " + event.getId() + ": Intended recipient ed25519 key " +
|
"Event " + event.getId() + ": Intended recipient ed25519 key " +
|
||||||
payload.recipient_keys.ed25519 + " did not match ours"
|
payload.recipient_keys.ed25519 + " did not match ours",
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError("Message not intended for this device");
|
throw new base.DecryptionError("Message not intended for this device");
|
||||||
}
|
}
|
||||||
@@ -212,10 +212,10 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
if (payload.sender != event.getSender()) {
|
if (payload.sender != event.getSender()) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Event " + event.getId() + ": original sender " + payload.sender +
|
"Event " + event.getId() + ": original sender " + payload.sender +
|
||||||
" does not match reported sender " + event.getSender()
|
" does not match reported sender " + event.getSender(),
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message forwarded from " + payload.sender
|
"Message forwarded from " + payload.sender,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,10 +223,10 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
if (payload.room_id !== event.getRoomId()) {
|
if (payload.room_id !== event.getRoomId()) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Event " + event.getId() + ": original room " + payload.room_id +
|
"Event " + event.getId() + ": original room " + payload.room_id +
|
||||||
" does not match reported room " + event.room_id
|
" does not match reported room " + event.room_id,
|
||||||
);
|
);
|
||||||
throw new base.DecryptionError(
|
throw new base.DecryptionError(
|
||||||
"Message intended for room " + payload.room_id
|
"Message intended for room " + payload.room_id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,24 +243,24 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
* @return {string} payload, if decrypted successfully.
|
* @return {string} payload, if decrypted successfully.
|
||||||
*/
|
*/
|
||||||
OlmDecryption.prototype._decryptMessage = function(theirDeviceIdentityKey, message) {
|
OlmDecryption.prototype._decryptMessage = function(theirDeviceIdentityKey, message) {
|
||||||
let sessionIds = this._olmDevice.getSessionIdsForDevice(theirDeviceIdentityKey);
|
const sessionIds = this._olmDevice.getSessionIdsForDevice(theirDeviceIdentityKey);
|
||||||
|
|
||||||
// try each session in turn.
|
// try each session in turn.
|
||||||
let decryptionErrors = {};
|
const decryptionErrors = {};
|
||||||
for (let i = 0; i < sessionIds.length; i++) {
|
for (let i = 0; i < sessionIds.length; i++) {
|
||||||
let sessionId = sessionIds[i];
|
const sessionId = sessionIds[i];
|
||||||
try {
|
try {
|
||||||
let payload = this._olmDevice.decryptMessage(
|
const payload = this._olmDevice.decryptMessage(
|
||||||
theirDeviceIdentityKey, sessionId, message.type, message.body
|
theirDeviceIdentityKey, sessionId, message.type, message.body,
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
"Decrypted Olm message from " + theirDeviceIdentityKey +
|
"Decrypted Olm message from " + theirDeviceIdentityKey +
|
||||||
" with session " + sessionId
|
" with session " + sessionId,
|
||||||
);
|
);
|
||||||
return payload;
|
return payload;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
let foundSession = this._olmDevice.matchesSession(
|
const foundSession = this._olmDevice.matchesSession(
|
||||||
theirDeviceIdentityKey, sessionId, message.type, message.body
|
theirDeviceIdentityKey, sessionId, message.type, message.body,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (foundSession) {
|
if (foundSession) {
|
||||||
@@ -268,7 +268,7 @@ OlmDecryption.prototype._decryptMessage = function(theirDeviceIdentityKey, messa
|
|||||||
// session, so it should have worked.
|
// session, so it should have worked.
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Error decrypting prekey message with existing session id " +
|
"Error decrypting prekey message with existing session id " +
|
||||||
sessionId + ": " + e.message
|
sessionId + ": " + e.message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ OlmDecryption.prototype._decryptMessage = function(theirDeviceIdentityKey, messa
|
|||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Error decrypting non-prekey message with existing sessions: " +
|
"Error decrypting non-prekey message with existing sessions: " +
|
||||||
JSON.stringify(decryptionErrors)
|
JSON.stringify(decryptionErrors),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,19 +298,19 @@ OlmDecryption.prototype._decryptMessage = function(theirDeviceIdentityKey, messa
|
|||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
res = this._olmDevice.createInboundSession(
|
res = this._olmDevice.createInboundSession(
|
||||||
theirDeviceIdentityKey, message.type, message.body
|
theirDeviceIdentityKey, message.type, message.body,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
decryptionErrors["(new)"] = e.message;
|
decryptionErrors["(new)"] = e.message;
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Error decrypting prekey message: " +
|
"Error decrypting prekey message: " +
|
||||||
JSON.stringify(decryptionErrors)
|
JSON.stringify(decryptionErrors),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"created new inbound Olm session ID " +
|
"created new inbound Olm session ID " +
|
||||||
res.session_id + " with " + theirDeviceIdentityKey
|
res.session_id + " with " + theirDeviceIdentityKey,
|
||||||
);
|
);
|
||||||
return res.payload;
|
return res.payload;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ function DeviceInfo(deviceId) {
|
|||||||
* @return {module:crypto~DeviceInfo} new DeviceInfo
|
* @return {module:crypto~DeviceInfo} new DeviceInfo
|
||||||
*/
|
*/
|
||||||
DeviceInfo.fromStorage = function(obj, deviceId) {
|
DeviceInfo.fromStorage = function(obj, deviceId) {
|
||||||
let res = new DeviceInfo(deviceId);
|
const res = new DeviceInfo(deviceId);
|
||||||
for (let prop in obj) {
|
for (const prop in obj) {
|
||||||
if (obj.hasOwnProperty(prop)) {
|
if (obj.hasOwnProperty(prop)) {
|
||||||
res[prop] = obj[prop];
|
res[prop] = obj[prop];
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ DeviceInfo.DeviceVerification = {
|
|||||||
BLOCKED: -1,
|
BLOCKED: -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
let DeviceVerification = DeviceInfo.DeviceVerification;
|
const DeviceVerification = DeviceInfo.DeviceVerification;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
module.exports = DeviceInfo;
|
module.exports = DeviceInfo;
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ limitations under the License.
|
|||||||
* @module crypto
|
* @module crypto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let anotherjson = require('another-json');
|
const anotherjson = require('another-json');
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
|
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let OlmDevice = require("./OlmDevice");
|
const OlmDevice = require("./OlmDevice");
|
||||||
let olmlib = require("./olmlib");
|
const olmlib = require("./olmlib");
|
||||||
let algorithms = require("./algorithms");
|
const algorithms = require("./algorithms");
|
||||||
let DeviceInfo = require("./deviceinfo");
|
const DeviceInfo = require("./deviceinfo");
|
||||||
let DeviceVerification = DeviceInfo.DeviceVerification;
|
const DeviceVerification = DeviceInfo.DeviceVerification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cryptography bits
|
* Cryptography bits
|
||||||
@@ -69,7 +69,7 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
|
|||||||
this._roomDecryptors = {};
|
this._roomDecryptors = {};
|
||||||
|
|
||||||
this._supportedAlgorithms = utils.keys(
|
this._supportedAlgorithms = utils.keys(
|
||||||
algorithms.DECRYPTION_CLASSES
|
algorithms.DECRYPTION_CLASSES,
|
||||||
);
|
);
|
||||||
|
|
||||||
// build our device keys: these will later be uploaded
|
// build our device keys: these will later be uploaded
|
||||||
@@ -80,7 +80,7 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
|
|||||||
this._olmDevice.deviceCurve25519Key;
|
this._olmDevice.deviceCurve25519Key;
|
||||||
|
|
||||||
let myDevices = this._sessionStore.getEndToEndDevicesForUser(
|
let myDevices = this._sessionStore.getEndToEndDevicesForUser(
|
||||||
this._userId
|
this._userId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!myDevices) {
|
if (!myDevices) {
|
||||||
@@ -92,7 +92,7 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
|
|||||||
|
|
||||||
if (!myDevices[this._deviceId]) {
|
if (!myDevices[this._deviceId]) {
|
||||||
// add our own deviceinfo to the sessionstore
|
// add our own deviceinfo to the sessionstore
|
||||||
let deviceInfo = {
|
const deviceInfo = {
|
||||||
keys: this._deviceKeys,
|
keys: this._deviceKeys,
|
||||||
algorithms: this._supportedAlgorithms,
|
algorithms: this._supportedAlgorithms,
|
||||||
verified: DeviceVerification.VERIFIED,
|
verified: DeviceVerification.VERIFIED,
|
||||||
@@ -100,7 +100,7 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
|
|||||||
|
|
||||||
myDevices[this._deviceId] = deviceInfo;
|
myDevices[this._deviceId] = deviceInfo;
|
||||||
this._sessionStore.storeEndToEndDevicesForUser(
|
this._sessionStore.storeEndToEndDevicesForUser(
|
||||||
this._userId, myDevices
|
this._userId, myDevices,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ function _registerEventHandlers(crypto, eventEmitter) {
|
|||||||
if (syncState == "PREPARED") {
|
if (syncState == "PREPARED") {
|
||||||
// XXX ugh. we're assuming the eventEmitter is a MatrixClient.
|
// XXX ugh. we're assuming the eventEmitter is a MatrixClient.
|
||||||
// how can we avoid doing so?
|
// how can we avoid doing so?
|
||||||
let rooms = eventEmitter.getRooms();
|
const rooms = eventEmitter.getRooms();
|
||||||
crypto._onInitialSyncCompleted(rooms);
|
crypto._onInitialSyncCompleted(rooms);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -176,7 +176,7 @@ Crypto.prototype.getDeviceEd25519Key = function() {
|
|||||||
* @return {object} A promise that will resolve when the keys are uploaded.
|
* @return {object} A promise that will resolve when the keys are uploaded.
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.uploadKeys = function(maxKeys) {
|
Crypto.prototype.uploadKeys = function(maxKeys) {
|
||||||
let self = this;
|
const self = this;
|
||||||
return _uploadDeviceKeys(this).then(function(res) {
|
return _uploadDeviceKeys(this).then(function(res) {
|
||||||
// We need to keep a pool of one time public keys on the server so that
|
// We need to keep a pool of one time public keys on the server so that
|
||||||
// other devices can start conversations with us. But we can only store
|
// other devices can start conversations with us. But we can only store
|
||||||
@@ -191,16 +191,16 @@ Crypto.prototype.uploadKeys = function(maxKeys) {
|
|||||||
// these factors.
|
// these factors.
|
||||||
|
|
||||||
// We first find how many keys the server has for us.
|
// We first find how many keys the server has for us.
|
||||||
let keyCount = res.one_time_key_counts.signed_curve25519 || 0;
|
const keyCount = res.one_time_key_counts.signed_curve25519 || 0;
|
||||||
// We then check how many keys we can store in the Account object.
|
// We then check how many keys we can store in the Account object.
|
||||||
let maxOneTimeKeys = self._olmDevice.maxNumberOfOneTimeKeys();
|
const maxOneTimeKeys = self._olmDevice.maxNumberOfOneTimeKeys();
|
||||||
// Try to keep at most half that number on the server. This leaves the
|
// Try to keep at most half that number on the server. This leaves the
|
||||||
// rest of the slots free to hold keys that have been claimed from the
|
// rest of the slots free to hold keys that have been claimed from the
|
||||||
// server but we haven't recevied a message for.
|
// server but we haven't recevied a message for.
|
||||||
// If we run out of slots when generating new keys then olm will
|
// If we run out of slots when generating new keys then olm will
|
||||||
// discard the oldest private keys first. This will eventually clean
|
// discard the oldest private keys first. This will eventually clean
|
||||||
// out stale private keys that won't receive a message.
|
// out stale private keys that won't receive a message.
|
||||||
let keyLimit = Math.floor(maxOneTimeKeys / 2);
|
const keyLimit = Math.floor(maxOneTimeKeys / 2);
|
||||||
// We work out how many new keys we need to create to top up the server
|
// We work out how many new keys we need to create to top up the server
|
||||||
// If there are too many keys on the server then we don't need to
|
// If there are too many keys on the server then we don't need to
|
||||||
// create any more keys.
|
// create any more keys.
|
||||||
@@ -225,10 +225,10 @@ Crypto.prototype.uploadKeys = function(maxKeys) {
|
|||||||
|
|
||||||
// returns a promise which resolves to the response
|
// returns a promise which resolves to the response
|
||||||
function _uploadDeviceKeys(crypto) {
|
function _uploadDeviceKeys(crypto) {
|
||||||
let userId = crypto._userId;
|
const userId = crypto._userId;
|
||||||
let deviceId = crypto._deviceId;
|
const deviceId = crypto._deviceId;
|
||||||
|
|
||||||
let deviceKeys = {
|
const deviceKeys = {
|
||||||
algorithms: crypto._supportedAlgorithms,
|
algorithms: crypto._supportedAlgorithms,
|
||||||
device_id: deviceId,
|
device_id: deviceId,
|
||||||
keys: crypto._deviceKeys,
|
keys: crypto._deviceKeys,
|
||||||
@@ -247,12 +247,12 @@ function _uploadDeviceKeys(crypto) {
|
|||||||
|
|
||||||
// returns a promise which resolves to the response
|
// returns a promise which resolves to the response
|
||||||
function _uploadOneTimeKeys(crypto) {
|
function _uploadOneTimeKeys(crypto) {
|
||||||
let oneTimeKeys = crypto._olmDevice.getOneTimeKeys();
|
const oneTimeKeys = crypto._olmDevice.getOneTimeKeys();
|
||||||
let oneTimeJson = {};
|
const oneTimeJson = {};
|
||||||
|
|
||||||
for (let keyId in oneTimeKeys.curve25519) {
|
for (const keyId in oneTimeKeys.curve25519) {
|
||||||
if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) {
|
if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) {
|
||||||
let k = {
|
const k = {
|
||||||
key: oneTimeKeys.curve25519[keyId],
|
key: oneTimeKeys.curve25519[keyId],
|
||||||
};
|
};
|
||||||
crypto._signObject(k);
|
crypto._signObject(k);
|
||||||
@@ -282,10 +282,10 @@ function _uploadOneTimeKeys(crypto) {
|
|||||||
* module:crypto/deviceinfo|DeviceInfo}.
|
* module:crypto/deviceinfo|DeviceInfo}.
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.downloadKeys = function(userIds, forceDownload) {
|
Crypto.prototype.downloadKeys = function(userIds, forceDownload) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
// promises we need to wait for while the download happens
|
// promises we need to wait for while the download happens
|
||||||
let promises = [];
|
const promises = [];
|
||||||
|
|
||||||
// list of userids we need to download keys for
|
// list of userids we need to download keys for
|
||||||
let downloadUsers = [];
|
let downloadUsers = [];
|
||||||
@@ -300,9 +300,9 @@ Crypto.prototype.downloadKeys = function(userIds, forceDownload) {
|
|||||||
downloadUsers = userIds;
|
downloadUsers = userIds;
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < userIds.length; ++i) {
|
for (let i = 0; i < userIds.length; ++i) {
|
||||||
let u = userIds[i];
|
const u = userIds[i];
|
||||||
|
|
||||||
let inprogress = this._keyDownloadsInProgressByUser[u];
|
const inprogress = this._keyDownloadsInProgressByUser[u];
|
||||||
if (inprogress) {
|
if (inprogress) {
|
||||||
// wait for the download to complete
|
// wait for the download to complete
|
||||||
promises.push(q.any(inprogress).catch(perUserCatch(u)));
|
promises.push(q.any(inprogress).catch(perUserCatch(u)));
|
||||||
@@ -313,7 +313,7 @@ Crypto.prototype.downloadKeys = function(userIds, forceDownload) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (downloadUsers.length > 0) {
|
if (downloadUsers.length > 0) {
|
||||||
let r = this._doKeyDownloadForUsers(downloadUsers);
|
const r = this._doKeyDownloadForUsers(downloadUsers);
|
||||||
downloadUsers.map(function(u) {
|
downloadUsers.map(function(u) {
|
||||||
promises.push(r[u].catch(perUserCatch(u)));
|
promises.push(r[u].catch(perUserCatch(u)));
|
||||||
});
|
});
|
||||||
@@ -333,11 +333,11 @@ Crypto.prototype.downloadKeys = function(userIds, forceDownload) {
|
|||||||
* @return {Object} userId->deviceId->{@link module:crypto/deviceinfo|DeviceInfo}.
|
* @return {Object} userId->deviceId->{@link module:crypto/deviceinfo|DeviceInfo}.
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._getDevicesFromStore = function(userIds) {
|
Crypto.prototype._getDevicesFromStore = function(userIds) {
|
||||||
let stored = {};
|
const stored = {};
|
||||||
let self = this;
|
const self = this;
|
||||||
userIds.map(function(u) {
|
userIds.map(function(u) {
|
||||||
stored[u] = {};
|
stored[u] = {};
|
||||||
let devices = self.getStoredDevicesForUser(u) || [];
|
const devices = self.getStoredDevicesForUser(u) || [];
|
||||||
devices.map(function(dev) {
|
devices.map(function(dev) {
|
||||||
stored[u][dev.deviceId] = dev;
|
stored[u][dev.deviceId] = dev;
|
||||||
});
|
});
|
||||||
@@ -351,17 +351,17 @@ Crypto.prototype._getDevicesFromStore = function(userIds) {
|
|||||||
* @return {Object} a map from userId to a promise for a result for that user
|
* @return {Object} a map from userId to a promise for a result for that user
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._doKeyDownloadForUsers = function(downloadUsers) {
|
Crypto.prototype._doKeyDownloadForUsers = function(downloadUsers) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
console.log('Starting key download for ' + downloadUsers);
|
console.log('Starting key download for ' + downloadUsers);
|
||||||
|
|
||||||
let deferMap = {};
|
const deferMap = {};
|
||||||
let promiseMap = {};
|
const promiseMap = {};
|
||||||
|
|
||||||
downloadUsers.map(function(u) {
|
downloadUsers.map(function(u) {
|
||||||
let deferred = q.defer();
|
const deferred = q.defer();
|
||||||
let promise = deferred.promise.finally(function() {
|
const promise = deferred.promise.finally(function() {
|
||||||
let inProgress = self._keyDownloadsInProgressByUser[u];
|
const inProgress = self._keyDownloadsInProgressByUser[u];
|
||||||
utils.removeElement(inProgress, function(e) {
|
utils.removeElement(inProgress, function(e) {
|
||||||
return e === promise;
|
return e === promise;
|
||||||
});
|
});
|
||||||
@@ -381,42 +381,42 @@ Crypto.prototype._doKeyDownloadForUsers = function(downloadUsers) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this._baseApis.downloadKeysForUsers(
|
this._baseApis.downloadKeysForUsers(
|
||||||
downloadUsers
|
downloadUsers,
|
||||||
).done(function(res) {
|
).done(function(res) {
|
||||||
let dk = res.device_keys || {};
|
const dk = res.device_keys || {};
|
||||||
|
|
||||||
for (let i = 0; i < downloadUsers.length; ++i) {
|
for (let i = 0; i < downloadUsers.length; ++i) {
|
||||||
let userId = downloadUsers[i];
|
const userId = downloadUsers[i];
|
||||||
var deviceId;
|
var deviceId;
|
||||||
|
|
||||||
console.log('got keys for ' + userId + ':', dk[userId]);
|
console.log('got keys for ' + userId + ':', dk[userId]);
|
||||||
|
|
||||||
if (!dk[userId]) {
|
if (!dk[userId]) {
|
||||||
// no result for this user
|
// no result for this user
|
||||||
let err = 'Unknown';
|
const err = 'Unknown';
|
||||||
// TODO: do something with res.failures
|
// TODO: do something with res.failures
|
||||||
deferMap[userId].reject(err);
|
deferMap[userId].reject(err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// map from deviceid -> deviceinfo for this user
|
// map from deviceid -> deviceinfo for this user
|
||||||
let userStore = {};
|
const userStore = {};
|
||||||
let devs = self._sessionStore.getEndToEndDevicesForUser(userId);
|
const devs = self._sessionStore.getEndToEndDevicesForUser(userId);
|
||||||
if (devs) {
|
if (devs) {
|
||||||
for (deviceId in devs) {
|
for (deviceId in devs) {
|
||||||
if (devs.hasOwnProperty(deviceId)) {
|
if (devs.hasOwnProperty(deviceId)) {
|
||||||
let d = DeviceInfo.fromStorage(devs[deviceId], deviceId);
|
const d = DeviceInfo.fromStorage(devs[deviceId], deviceId);
|
||||||
userStore[deviceId] = d;
|
userStore[deviceId] = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateStoredDeviceKeysForUser(
|
_updateStoredDeviceKeysForUser(
|
||||||
self._olmDevice, userId, userStore, dk[userId]
|
self._olmDevice, userId, userStore, dk[userId],
|
||||||
);
|
);
|
||||||
|
|
||||||
// update the session store
|
// update the session store
|
||||||
let storage = {};
|
const storage = {};
|
||||||
for (deviceId in userStore) {
|
for (deviceId in userStore) {
|
||||||
if (!userStore.hasOwnProperty(deviceId)) {
|
if (!userStore.hasOwnProperty(deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -425,7 +425,7 @@ Crypto.prototype._doKeyDownloadForUsers = function(downloadUsers) {
|
|||||||
storage[deviceId] = userStore[deviceId].toStorage();
|
storage[deviceId] = userStore[deviceId].toStorage();
|
||||||
}
|
}
|
||||||
self._sessionStore.storeEndToEndDevicesForUser(
|
self._sessionStore.storeEndToEndDevicesForUser(
|
||||||
userId, storage
|
userId, storage,
|
||||||
);
|
);
|
||||||
|
|
||||||
deferMap[userId].resolve();
|
deferMap[userId].resolve();
|
||||||
@@ -462,7 +462,7 @@ function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let deviceResult = userResult[deviceId];
|
const deviceResult = userResult[deviceId];
|
||||||
|
|
||||||
// check that the user_id and device_id in the response object are
|
// check that the user_id and device_id in the response object are
|
||||||
// correct
|
// correct
|
||||||
@@ -496,18 +496,18 @@ function _storeDeviceKeys(_olmDevice, userStore, deviceResult) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let deviceId = deviceResult.device_id;
|
const deviceId = deviceResult.device_id;
|
||||||
let userId = deviceResult.user_id;
|
const userId = deviceResult.user_id;
|
||||||
|
|
||||||
let signKeyId = "ed25519:" + deviceId;
|
const signKeyId = "ed25519:" + deviceId;
|
||||||
let signKey = deviceResult.keys[signKeyId];
|
const signKey = deviceResult.keys[signKeyId];
|
||||||
if (!signKey) {
|
if (!signKey) {
|
||||||
console.log("Device " + userId + ":" + deviceId +
|
console.log("Device " + userId + ":" + deviceId +
|
||||||
" has no ed25519 key");
|
" has no ed25519 key");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let unsigned = deviceResult.unsigned || {};
|
const unsigned = deviceResult.unsigned || {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
olmlib.verifySignature(_olmDevice, deviceResult, userId, deviceId, signKey);
|
olmlib.verifySignature(_olmDevice, deviceResult, userId, deviceId, signKey);
|
||||||
@@ -552,12 +552,12 @@ function _storeDeviceKeys(_olmDevice, userStore, deviceResult) {
|
|||||||
* managed to get a list of devices for this user yet.
|
* managed to get a list of devices for this user yet.
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.getStoredDevicesForUser = function(userId) {
|
Crypto.prototype.getStoredDevicesForUser = function(userId) {
|
||||||
let devs = this._sessionStore.getEndToEndDevicesForUser(userId);
|
const devs = this._sessionStore.getEndToEndDevicesForUser(userId);
|
||||||
if (!devs) {
|
if (!devs) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let res = [];
|
const res = [];
|
||||||
for (let deviceId in devs) {
|
for (const deviceId in devs) {
|
||||||
if (devs.hasOwnProperty(deviceId)) {
|
if (devs.hasOwnProperty(deviceId)) {
|
||||||
res.push(DeviceInfo.fromStorage(devs[deviceId], deviceId));
|
res.push(DeviceInfo.fromStorage(devs[deviceId], deviceId));
|
||||||
}
|
}
|
||||||
@@ -575,7 +575,7 @@ Crypto.prototype.getStoredDevicesForUser = function(userId) {
|
|||||||
* if we don't know about this device
|
* if we don't know about this device
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.getStoredDevice = function(userId, deviceId) {
|
Crypto.prototype.getStoredDevice = function(userId, deviceId) {
|
||||||
let devs = this._sessionStore.getEndToEndDevicesForUser(userId);
|
const devs = this._sessionStore.getEndToEndDevicesForUser(userId);
|
||||||
if (!devs || !devs[deviceId]) {
|
if (!devs || !devs[deviceId]) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -593,13 +593,13 @@ Crypto.prototype.getStoredDevice = function(userId, deviceId) {
|
|||||||
* "key", and "display_name" parameters.
|
* "key", and "display_name" parameters.
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.listDeviceKeys = function(userId) {
|
Crypto.prototype.listDeviceKeys = function(userId) {
|
||||||
let devices = this.getStoredDevicesForUser(userId) || [];
|
const devices = this.getStoredDevicesForUser(userId) || [];
|
||||||
|
|
||||||
let result = [];
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < devices.length; ++i) {
|
for (let i = 0; i < devices.length; ++i) {
|
||||||
let device = devices[i];
|
const device = devices[i];
|
||||||
let ed25519Key = device.getFingerprint();
|
const ed25519Key = device.getFingerprint();
|
||||||
if (ed25519Key) {
|
if (ed25519Key) {
|
||||||
result.push({
|
result.push({
|
||||||
id: device.deviceId,
|
id: device.deviceId,
|
||||||
@@ -643,25 +643,25 @@ Crypto.prototype.getDeviceByIdentityKey = function(userId, algorithm, sender_key
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let devices = this._sessionStore.getEndToEndDevicesForUser(userId);
|
const devices = this._sessionStore.getEndToEndDevicesForUser(userId);
|
||||||
if (!devices) {
|
if (!devices) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let deviceId in devices) {
|
for (const deviceId in devices) {
|
||||||
if (!devices.hasOwnProperty(deviceId)) {
|
if (!devices.hasOwnProperty(deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let device = devices[deviceId];
|
const device = devices[deviceId];
|
||||||
for (let keyId in device.keys) {
|
for (const keyId in device.keys) {
|
||||||
if (!device.keys.hasOwnProperty(keyId)) {
|
if (!device.keys.hasOwnProperty(keyId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (keyId.indexOf("curve25519:") !== 0) {
|
if (keyId.indexOf("curve25519:") !== 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let deviceKey = device.keys[keyId];
|
const deviceKey = device.keys[keyId];
|
||||||
if (deviceKey == sender_key) {
|
if (deviceKey == sender_key) {
|
||||||
return DeviceInfo.fromStorage(device, deviceId);
|
return DeviceInfo.fromStorage(device, deviceId);
|
||||||
}
|
}
|
||||||
@@ -686,12 +686,12 @@ Crypto.prototype.getDeviceByIdentityKey = function(userId, algorithm, sender_key
|
|||||||
* leave unchanged.
|
* leave unchanged.
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.setDeviceVerification = function(userId, deviceId, verified, blocked) {
|
Crypto.prototype.setDeviceVerification = function(userId, deviceId, verified, blocked) {
|
||||||
let devices = this._sessionStore.getEndToEndDevicesForUser(userId);
|
const devices = this._sessionStore.getEndToEndDevicesForUser(userId);
|
||||||
if (!devices || !devices[deviceId]) {
|
if (!devices || !devices[deviceId]) {
|
||||||
throw new Error("Unknown device " + userId + ":" + deviceId);
|
throw new Error("Unknown device " + userId + ":" + deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dev = devices[deviceId];
|
const dev = devices[deviceId];
|
||||||
let verificationStatus = dev.verified;
|
let verificationStatus = dev.verified;
|
||||||
|
|
||||||
if (verified) {
|
if (verified) {
|
||||||
@@ -729,12 +729,12 @@ Crypto.prototype.setDeviceVerification = function(userId, deviceId, verified, bl
|
|||||||
* @return {Object.<string, {deviceIdKey: string, sessions: object[]}>}
|
* @return {Object.<string, {deviceIdKey: string, sessions: object[]}>}
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.getOlmSessionsForUser = function(userId) {
|
Crypto.prototype.getOlmSessionsForUser = function(userId) {
|
||||||
let devices = this.getStoredDevicesForUser(userId) || [];
|
const devices = this.getStoredDevicesForUser(userId) || [];
|
||||||
let result = {};
|
const result = {};
|
||||||
for (let j = 0; j < devices.length; ++j) {
|
for (let j = 0; j < devices.length; ++j) {
|
||||||
let device = devices[j];
|
const device = devices[j];
|
||||||
let deviceKey = device.getIdentityKey();
|
const deviceKey = device.getIdentityKey();
|
||||||
let sessions = this._olmDevice.getSessionInfoForDevice(deviceKey);
|
const sessions = this._olmDevice.getSessionInfoForDevice(deviceKey);
|
||||||
|
|
||||||
result[device.deviceId] = {
|
result[device.deviceId] = {
|
||||||
deviceIdKey: deviceKey,
|
deviceIdKey: deviceKey,
|
||||||
@@ -753,8 +753,8 @@ Crypto.prototype.getOlmSessionsForUser = function(userId) {
|
|||||||
* @return {module:crypto/deviceinfo?}
|
* @return {module:crypto/deviceinfo?}
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.getEventSenderDeviceInfo = function(event) {
|
Crypto.prototype.getEventSenderDeviceInfo = function(event) {
|
||||||
let sender_key = event.getSenderKey();
|
const sender_key = event.getSenderKey();
|
||||||
let algorithm = event.getWireContent().algorithm;
|
const algorithm = event.getWireContent().algorithm;
|
||||||
|
|
||||||
if (!sender_key || !algorithm) {
|
if (!sender_key || !algorithm) {
|
||||||
return null;
|
return null;
|
||||||
@@ -764,8 +764,8 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) {
|
|||||||
// was sent from. In the case of Megolm, it's actually the Curve25519
|
// was sent from. In the case of Megolm, it's actually the Curve25519
|
||||||
// identity key of the device which set up the Megolm session.
|
// identity key of the device which set up the Megolm session.
|
||||||
|
|
||||||
let device = this.getDeviceByIdentityKey(
|
const device = this.getDeviceByIdentityKey(
|
||||||
event.getSender(), algorithm, sender_key
|
event.getSender(), algorithm, sender_key,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (device === null) {
|
if (device === null) {
|
||||||
@@ -781,7 +781,7 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) {
|
|||||||
//
|
//
|
||||||
// (see https://github.com/vector-im/vector-web/issues/2215)
|
// (see https://github.com/vector-im/vector-web/issues/2215)
|
||||||
|
|
||||||
let claimedKey = event.getKeysClaimed().ed25519;
|
const claimedKey = event.getKeysClaimed().ed25519;
|
||||||
if (!claimedKey) {
|
if (!claimedKey) {
|
||||||
console.warn("Event " + event.getId() + " claims no ed25519 key: " +
|
console.warn("Event " + event.getId() + " claims no ed25519 key: " +
|
||||||
"cannot verify sending device");
|
"cannot verify sending device");
|
||||||
@@ -808,7 +808,7 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) {
|
|||||||
Crypto.prototype.setRoomEncryption = function(roomId, config) {
|
Crypto.prototype.setRoomEncryption = function(roomId, config) {
|
||||||
// if we already have encryption in this room, we should ignore this event
|
// if we already have encryption in this room, we should ignore this event
|
||||||
// (for now at least. maybe we should alert the user somehow?)
|
// (for now at least. maybe we should alert the user somehow?)
|
||||||
let existingConfig = this._sessionStore.getEndToEndRoom(roomId);
|
const existingConfig = this._sessionStore.getEndToEndRoom(roomId);
|
||||||
if (existingConfig) {
|
if (existingConfig) {
|
||||||
if (JSON.stringify(existingConfig) != JSON.stringify(config)) {
|
if (JSON.stringify(existingConfig) != JSON.stringify(config)) {
|
||||||
console.error("Ignoring m.room.encryption event which requests " +
|
console.error("Ignoring m.room.encryption event which requests " +
|
||||||
@@ -817,7 +817,7 @@ Crypto.prototype.setRoomEncryption = function(roomId, config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let AlgClass = algorithms.ENCRYPTION_CLASSES[config.algorithm];
|
const AlgClass = algorithms.ENCRYPTION_CLASSES[config.algorithm];
|
||||||
if (!AlgClass) {
|
if (!AlgClass) {
|
||||||
throw new Error("Unable to encrypt with " + config.algorithm);
|
throw new Error("Unable to encrypt with " + config.algorithm);
|
||||||
}
|
}
|
||||||
@@ -828,7 +828,7 @@ Crypto.prototype.setRoomEncryption = function(roomId, config) {
|
|||||||
};
|
};
|
||||||
this._sessionStore.storeEndToEndRoom(roomId, config);
|
this._sessionStore.storeEndToEndRoom(roomId, config);
|
||||||
|
|
||||||
let alg = new AlgClass({
|
const alg = new AlgClass({
|
||||||
userId: this._userId,
|
userId: this._userId,
|
||||||
deviceId: this._deviceId,
|
deviceId: this._deviceId,
|
||||||
crypto: this,
|
crypto: this,
|
||||||
@@ -859,17 +859,17 @@ Crypto.prototype.setRoomEncryption = function(roomId, config) {
|
|||||||
* {@link module:crypto~OlmSessionResult}
|
* {@link module:crypto~OlmSessionResult}
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.ensureOlmSessionsForUsers = function(users) {
|
Crypto.prototype.ensureOlmSessionsForUsers = function(users) {
|
||||||
let devicesByUser = {};
|
const devicesByUser = {};
|
||||||
|
|
||||||
for (let i = 0; i < users.length; ++i) {
|
for (let i = 0; i < users.length; ++i) {
|
||||||
let userId = users[i];
|
const userId = users[i];
|
||||||
devicesByUser[userId] = [];
|
devicesByUser[userId] = [];
|
||||||
|
|
||||||
let devices = this.getStoredDevicesForUser(userId) || [];
|
const devices = this.getStoredDevicesForUser(userId) || [];
|
||||||
for (let j = 0; j < devices.length; ++j) {
|
for (let j = 0; j < devices.length; ++j) {
|
||||||
let deviceInfo = devices[j];
|
const deviceInfo = devices[j];
|
||||||
|
|
||||||
let key = deviceInfo.getIdentityKey();
|
const key = deviceInfo.getIdentityKey();
|
||||||
if (key == this._olmDevice.deviceCurve25519Key) {
|
if (key == this._olmDevice.deviceCurve25519Key) {
|
||||||
// don't bother setting up session to ourself
|
// don't bother setting up session to ourself
|
||||||
continue;
|
continue;
|
||||||
@@ -884,7 +884,7 @@ Crypto.prototype.ensureOlmSessionsForUsers = function(users) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return olmlib.ensureOlmSessionsForDevices(
|
return olmlib.ensureOlmSessionsForDevices(
|
||||||
this._olmDevice, this._baseApis, devicesByUser
|
this._olmDevice, this._baseApis, devicesByUser,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -897,6 +897,45 @@ Crypto.prototype.isRoomEncrypted = function(roomId) {
|
|||||||
return Boolean(this._roomEncryptors[roomId]);
|
return Boolean(this._roomEncryptors[roomId]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list containing all of the room keys
|
||||||
|
*
|
||||||
|
* @return {module:client.Promise} a promise which resolves to a list of
|
||||||
|
* session export objects
|
||||||
|
*/
|
||||||
|
Crypto.prototype.exportRoomKeys = function() {
|
||||||
|
return q(
|
||||||
|
this._sessionStore.getAllEndToEndInboundGroupSessionKeys().map(
|
||||||
|
(s) => {
|
||||||
|
const sess = this._olmDevice.exportInboundGroupSession(
|
||||||
|
s.senderKey, s.sessionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
sess.algorithm = olmlib.MEGOLM_ALGORITHM;
|
||||||
|
return sess;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a list of room keys previously exported by exportRoomKeys
|
||||||
|
*
|
||||||
|
* @param {Object[]} keys a list of session export objects
|
||||||
|
*/
|
||||||
|
Crypto.prototype.importRoomKeys = function(keys) {
|
||||||
|
keys.map((session) => {
|
||||||
|
if (!session.room_id || !session.algorithm) {
|
||||||
|
console.warn("ignoring session entry with missing fields", session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const alg = this._getRoomDecryptor(session.room_id, session.algorithm);
|
||||||
|
alg.importRoomKey(session);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt an event according to the configuration of the room, if necessary.
|
* Encrypt an event according to the configuration of the room, if necessary.
|
||||||
*
|
*
|
||||||
@@ -920,9 +959,9 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
|
|||||||
throw new Error("Cannot send encrypted messages in unknown rooms");
|
throw new Error("Cannot send encrypted messages in unknown rooms");
|
||||||
}
|
}
|
||||||
|
|
||||||
let roomId = event.getRoomId();
|
const roomId = event.getRoomId();
|
||||||
|
|
||||||
let alg = this._roomEncryptors[roomId];
|
const alg = this._roomEncryptors[roomId];
|
||||||
if (!alg) {
|
if (!alg) {
|
||||||
// not encrypting messages in this room
|
// not encrypting messages in this room
|
||||||
|
|
||||||
@@ -931,7 +970,7 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
|
|||||||
throw new Error(
|
throw new Error(
|
||||||
"Room was previously configured to use encryption, but is " +
|
"Room was previously configured to use encryption, but is " +
|
||||||
"no longer. Perhaps the homeserver is hiding the " +
|
"no longer. Perhaps the homeserver is hiding the " +
|
||||||
"configuration event."
|
"configuration event.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -940,13 +979,13 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
|
|||||||
// We can claim and prove ownership of all our device keys in the local
|
// We can claim and prove ownership of all our device keys in the local
|
||||||
// echo of the event since we know that all the local echos come from
|
// echo of the event since we know that all the local echos come from
|
||||||
// this device.
|
// this device.
|
||||||
let myKeys = {
|
const myKeys = {
|
||||||
curve25519: this._olmDevice.deviceCurve25519Key,
|
curve25519: this._olmDevice.deviceCurve25519Key,
|
||||||
ed25519: this._olmDevice.deviceEd25519Key,
|
ed25519: this._olmDevice.deviceEd25519Key,
|
||||||
};
|
};
|
||||||
|
|
||||||
return alg.encryptMessage(
|
return alg.encryptMessage(
|
||||||
room, event.getType(), event.getContent()
|
room, event.getType(), event.getContent(),
|
||||||
).then(function(encryptedContent) {
|
).then(function(encryptedContent) {
|
||||||
event.makeEncrypted("m.room.encrypted", encryptedContent, myKeys);
|
event.makeEncrypted("m.room.encrypted", encryptedContent, myKeys);
|
||||||
});
|
});
|
||||||
@@ -960,8 +999,8 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
|
|||||||
* @raises {algorithms.DecryptionError} if there is a problem decrypting the event
|
* @raises {algorithms.DecryptionError} if there is a problem decrypting the event
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.decryptEvent = function(event) {
|
Crypto.prototype.decryptEvent = function(event) {
|
||||||
let content = event.getWireContent();
|
const content = event.getWireContent();
|
||||||
let alg = this._getRoomDecryptor(event.getRoomId(), content.algorithm);
|
const alg = this._getRoomDecryptor(event.getRoomId(), content.algorithm);
|
||||||
alg.decryptEvent(event);
|
alg.decryptEvent(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -972,8 +1011,8 @@ Crypto.prototype.decryptEvent = function(event) {
|
|||||||
* @param {module:models/event.MatrixEvent} event encryption event
|
* @param {module:models/event.MatrixEvent} event encryption event
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._onCryptoEvent = function(event) {
|
Crypto.prototype._onCryptoEvent = function(event) {
|
||||||
let roomId = event.getRoomId();
|
const roomId = event.getRoomId();
|
||||||
let content = event.getContent();
|
const content = event.getContent();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.setRoomEncryption(roomId, content);
|
this.setRoomEncryption(roomId, content);
|
||||||
@@ -1004,27 +1043,27 @@ Crypto.prototype._onInitialSyncCompleted = function(rooms) {
|
|||||||
// we need to tell all the devices in all the rooms we are members of that
|
// we need to tell all the devices in all the rooms we are members of that
|
||||||
// we have arrived.
|
// we have arrived.
|
||||||
// build a list of rooms for each user.
|
// build a list of rooms for each user.
|
||||||
let roomsByUser = {};
|
const roomsByUser = {};
|
||||||
for (let i = 0; i < rooms.length; i++) {
|
for (let i = 0; i < rooms.length; i++) {
|
||||||
let room = rooms[i];
|
const room = rooms[i];
|
||||||
|
|
||||||
// check for rooms with encryption enabled
|
// check for rooms with encryption enabled
|
||||||
let alg = this._roomEncryptors[room.roomId];
|
const alg = this._roomEncryptors[room.roomId];
|
||||||
if (!alg) {
|
if (!alg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore any rooms which we have left
|
// ignore any rooms which we have left
|
||||||
let me = room.getMember(this._userId);
|
const me = room.getMember(this._userId);
|
||||||
if (!me || (
|
if (!me || (
|
||||||
me.membership !== "join" && me.membership !== "invite"
|
me.membership !== "join" && me.membership !== "invite"
|
||||||
)) {
|
)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let members = room.getJoinedMembers();
|
const members = room.getJoinedMembers();
|
||||||
for (let j = 0; j < members.length; j++) {
|
for (let j = 0; j < members.length; j++) {
|
||||||
let m = members[j];
|
const m = members[j];
|
||||||
if (!roomsByUser[m.userId]) {
|
if (!roomsByUser[m.userId]) {
|
||||||
roomsByUser[m.userId] = [];
|
roomsByUser[m.userId] = [];
|
||||||
}
|
}
|
||||||
@@ -1033,8 +1072,8 @@ Crypto.prototype._onInitialSyncCompleted = function(rooms) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build a per-device message for each user
|
// build a per-device message for each user
|
||||||
let content = {};
|
const content = {};
|
||||||
for (let userId in roomsByUser) {
|
for (const userId in roomsByUser) {
|
||||||
if (!roomsByUser.hasOwnProperty(userId)) {
|
if (!roomsByUser.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1046,10 +1085,10 @@ Crypto.prototype._onInitialSyncCompleted = function(rooms) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
this._baseApis.sendToDevice(
|
this._baseApis.sendToDevice(
|
||||||
"m.new_device", // OH HAI!
|
"m.new_device", // OH HAI!
|
||||||
content
|
content,
|
||||||
).done(function() {
|
).done(function() {
|
||||||
self._sessionStore.setDeviceAnnounced();
|
self._sessionStore.setDeviceAnnounced();
|
||||||
});
|
});
|
||||||
@@ -1062,14 +1101,14 @@ Crypto.prototype._onInitialSyncCompleted = function(rooms) {
|
|||||||
* @param {module:models/event.MatrixEvent} event key event
|
* @param {module:models/event.MatrixEvent} event key event
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._onRoomKeyEvent = function(event) {
|
Crypto.prototype._onRoomKeyEvent = function(event) {
|
||||||
let content = event.getContent();
|
const content = event.getContent();
|
||||||
|
|
||||||
if (!content.room_id || !content.algorithm) {
|
if (!content.room_id || !content.algorithm) {
|
||||||
console.error("key event is missing fields");
|
console.error("key event is missing fields");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let alg = this._getRoomDecryptor(content.room_id, content.algorithm);
|
const alg = this._getRoomDecryptor(content.room_id, content.algorithm);
|
||||||
alg.onRoomKeyEvent(event);
|
alg.onRoomKeyEvent(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1090,9 +1129,9 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) {
|
|||||||
// Further, it is automatically registered and called when new members
|
// Further, it is automatically registered and called when new members
|
||||||
// arrive in the room.
|
// arrive in the room.
|
||||||
|
|
||||||
let roomId = member.roomId;
|
const roomId = member.roomId;
|
||||||
|
|
||||||
let alg = this._roomEncryptors[roomId];
|
const alg = this._roomEncryptors[roomId];
|
||||||
if (!alg) {
|
if (!alg) {
|
||||||
// not encrypting in this room
|
// not encrypting in this room
|
||||||
return;
|
return;
|
||||||
@@ -1109,10 +1148,10 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) {
|
|||||||
* @param {module:models/event.MatrixEvent} event announcement event
|
* @param {module:models/event.MatrixEvent} event announcement event
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._onNewDeviceEvent = function(event) {
|
Crypto.prototype._onNewDeviceEvent = function(event) {
|
||||||
let content = event.getContent();
|
const content = event.getContent();
|
||||||
let userId = event.getSender();
|
const userId = event.getSender();
|
||||||
let deviceId = content.device_id;
|
const deviceId = content.device_id;
|
||||||
let rooms = content.rooms;
|
const rooms = content.rooms;
|
||||||
|
|
||||||
if (!rooms || !deviceId) {
|
if (!rooms || !deviceId) {
|
||||||
console.warn("new_device event missing keys");
|
console.warn("new_device event missing keys");
|
||||||
@@ -1140,15 +1179,15 @@ Crypto.prototype._onNewDeviceEvent = function(event) {
|
|||||||
* Start device queries for any users who sent us an m.new_device recently
|
* Start device queries for any users who sent us an m.new_device recently
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._flushNewDeviceRequests = function() {
|
Crypto.prototype._flushNewDeviceRequests = function() {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
let users = utils.keys(this._pendingUsersWithNewDevices);
|
const users = utils.keys(this._pendingUsersWithNewDevices);
|
||||||
|
|
||||||
if (users.length === 0) {
|
if (users.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = this._doKeyDownloadForUsers(users);
|
const r = this._doKeyDownloadForUsers(users);
|
||||||
|
|
||||||
// we've kicked off requests to these users: remove their
|
// we've kicked off requests to these users: remove their
|
||||||
// pending flag for now.
|
// pending flag for now.
|
||||||
@@ -1157,7 +1196,7 @@ Crypto.prototype._flushNewDeviceRequests = function() {
|
|||||||
users.map(function(u) {
|
users.map(function(u) {
|
||||||
r[u] = r[u].catch(function(e) {
|
r[u] = r[u].catch(function(e) {
|
||||||
console.error(
|
console.error(
|
||||||
'Error updating device keys for user ' + u + ':', e
|
'Error updating device keys for user ' + u + ':', e,
|
||||||
);
|
);
|
||||||
|
|
||||||
// reinstate the pending flags on any users which failed; this will
|
// reinstate the pending flags on any users which failed; this will
|
||||||
@@ -1206,10 +1245,10 @@ Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let AlgClass = algorithms.DECRYPTION_CLASSES[algorithm];
|
const AlgClass = algorithms.DECRYPTION_CLASSES[algorithm];
|
||||||
if (!AlgClass) {
|
if (!AlgClass) {
|
||||||
throw new algorithms.DecryptionError(
|
throw new algorithms.DecryptionError(
|
||||||
'Unknown encryption algorithm "' + algorithm + '".'
|
'Unknown encryption algorithm "' + algorithm + '".',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
alg = new AlgClass({
|
alg = new AlgClass({
|
||||||
@@ -1232,7 +1271,7 @@ Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) {
|
|||||||
* @param {Object} obj Object to which we will add a 'signatures' property
|
* @param {Object} obj Object to which we will add a 'signatures' property
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._signObject = function(obj) {
|
Crypto.prototype._signObject = function(obj) {
|
||||||
let sigs = {};
|
const sigs = {};
|
||||||
sigs[this._userId] = {};
|
sigs[this._userId] = {};
|
||||||
sigs[this._userId]["ed25519:" + this._deviceId] =
|
sigs[this._userId]["ed25519:" + this._deviceId] =
|
||||||
this._olmDevice.sign(anotherjson.stringify(obj));
|
this._olmDevice.sign(anotherjson.stringify(obj));
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ limitations under the License.
|
|||||||
* Utilities common to olm encryption algorithms
|
* Utilities common to olm encryption algorithms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let q = require('q');
|
const q = require('q');
|
||||||
let anotherjson = require('another-json');
|
const anotherjson = require('another-json');
|
||||||
|
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* matrix algorithm tag for olm
|
* matrix algorithm tag for olm
|
||||||
@@ -52,10 +52,10 @@ module.exports.MEGOLM_ALGORITHM = "m.megolm.v1.aes-sha2";
|
|||||||
module.exports.encryptMessageForDevice = function(
|
module.exports.encryptMessageForDevice = function(
|
||||||
resultsObject,
|
resultsObject,
|
||||||
ourUserId, ourDeviceId, olmDevice, recipientUserId, recipientDevice,
|
ourUserId, ourDeviceId, olmDevice, recipientUserId, recipientDevice,
|
||||||
payloadFields
|
payloadFields,
|
||||||
) {
|
) {
|
||||||
let deviceKey = recipientDevice.getIdentityKey();
|
const deviceKey = recipientDevice.getIdentityKey();
|
||||||
let sessionId = olmDevice.getSessionIdForDevice(deviceKey);
|
const sessionId = olmDevice.getSessionIdForDevice(deviceKey);
|
||||||
if (sessionId === null) {
|
if (sessionId === null) {
|
||||||
// If we don't have a session for a device then
|
// If we don't have a session for a device then
|
||||||
// we can't encrypt a message for it.
|
// we can't encrypt a message for it.
|
||||||
@@ -64,10 +64,10 @@ module.exports.encryptMessageForDevice = function(
|
|||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"Using sessionid " + sessionId + " for device " +
|
"Using sessionid " + sessionId + " for device " +
|
||||||
recipientUserId + ":" + recipientDevice.deviceId
|
recipientUserId + ":" + recipientDevice.deviceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
let payload = {
|
const payload = {
|
||||||
sender: ourUserId,
|
sender: ourUserId,
|
||||||
sender_device: ourDeviceId,
|
sender_device: ourDeviceId,
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ module.exports.encryptMessageForDevice = function(
|
|||||||
utils.extend(payload, payloadFields);
|
utils.extend(payload, payloadFields);
|
||||||
|
|
||||||
resultsObject[deviceKey] = olmDevice.encryptMessage(
|
resultsObject[deviceKey] = olmDevice.encryptMessage(
|
||||||
deviceKey, sessionId, JSON.stringify(payload)
|
deviceKey, sessionId, JSON.stringify(payload),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,24 +119,24 @@ module.exports.encryptMessageForDevice = function(
|
|||||||
* {@link module:crypto~OlmSessionResult}
|
* {@link module:crypto~OlmSessionResult}
|
||||||
*/
|
*/
|
||||||
module.exports.ensureOlmSessionsForDevices = function(
|
module.exports.ensureOlmSessionsForDevices = function(
|
||||||
olmDevice, baseApis, devicesByUser
|
olmDevice, baseApis, devicesByUser,
|
||||||
) {
|
) {
|
||||||
let devicesWithoutSession = [
|
const devicesWithoutSession = [
|
||||||
// [userId, deviceId], ...
|
// [userId, deviceId], ...
|
||||||
];
|
];
|
||||||
let result = {};
|
const result = {};
|
||||||
|
|
||||||
for (let userId in devicesByUser) {
|
for (const userId in devicesByUser) {
|
||||||
if (!devicesByUser.hasOwnProperty(userId)) {
|
if (!devicesByUser.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result[userId] = {};
|
result[userId] = {};
|
||||||
let devices = devicesByUser[userId];
|
const devices = devicesByUser[userId];
|
||||||
for (let j = 0; j < devices.length; j++) {
|
for (let j = 0; j < devices.length; j++) {
|
||||||
let deviceInfo = devices[j];
|
const deviceInfo = devices[j];
|
||||||
let deviceId = deviceInfo.deviceId;
|
const deviceId = deviceInfo.deviceId;
|
||||||
let key = deviceInfo.getIdentityKey();
|
const key = deviceInfo.getIdentityKey();
|
||||||
let sessionId = olmDevice.getSessionIdForDevice(key);
|
const sessionId = olmDevice.getSessionIdForDevice(key);
|
||||||
if (sessionId === null) {
|
if (sessionId === null) {
|
||||||
devicesWithoutSession.push([userId, deviceId]);
|
devicesWithoutSession.push([userId, deviceId]);
|
||||||
}
|
}
|
||||||
@@ -157,28 +157,28 @@ module.exports.ensureOlmSessionsForDevices = function(
|
|||||||
//
|
//
|
||||||
// That should eventually resolve itself, but it's poor form.
|
// That should eventually resolve itself, but it's poor form.
|
||||||
|
|
||||||
let oneTimeKeyAlgorithm = "signed_curve25519";
|
const oneTimeKeyAlgorithm = "signed_curve25519";
|
||||||
return baseApis.claimOneTimeKeys(
|
return baseApis.claimOneTimeKeys(
|
||||||
devicesWithoutSession, oneTimeKeyAlgorithm
|
devicesWithoutSession, oneTimeKeyAlgorithm,
|
||||||
).then(function(res) {
|
).then(function(res) {
|
||||||
let otk_res = res.one_time_keys || {};
|
const otk_res = res.one_time_keys || {};
|
||||||
for (let userId in devicesByUser) {
|
for (const userId in devicesByUser) {
|
||||||
if (!devicesByUser.hasOwnProperty(userId)) {
|
if (!devicesByUser.hasOwnProperty(userId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let userRes = otk_res[userId] || {};
|
const userRes = otk_res[userId] || {};
|
||||||
let devices = devicesByUser[userId];
|
const devices = devicesByUser[userId];
|
||||||
for (let j = 0; j < devices.length; j++) {
|
for (let j = 0; j < devices.length; j++) {
|
||||||
let deviceInfo = devices[j];
|
const deviceInfo = devices[j];
|
||||||
let deviceId = deviceInfo.deviceId;
|
const deviceId = deviceInfo.deviceId;
|
||||||
if (result[userId][deviceId].sessionId) {
|
if (result[userId][deviceId].sessionId) {
|
||||||
// we already have a result for this device
|
// we already have a result for this device
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let deviceRes = userRes[deviceId] || {};
|
const deviceRes = userRes[deviceId] || {};
|
||||||
let oneTimeKey = null;
|
let oneTimeKey = null;
|
||||||
for (let keyId in deviceRes) {
|
for (const keyId in deviceRes) {
|
||||||
if (keyId.indexOf(oneTimeKeyAlgorithm + ":") === 0) {
|
if (keyId.indexOf(oneTimeKeyAlgorithm + ":") === 0) {
|
||||||
oneTimeKey = deviceRes[keyId];
|
oneTimeKey = deviceRes[keyId];
|
||||||
}
|
}
|
||||||
@@ -187,13 +187,13 @@ module.exports.ensureOlmSessionsForDevices = function(
|
|||||||
if (!oneTimeKey) {
|
if (!oneTimeKey) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"No one-time keys (alg=" + oneTimeKeyAlgorithm +
|
"No one-time keys (alg=" + oneTimeKeyAlgorithm +
|
||||||
") for device " + userId + ":" + deviceId
|
") for device " + userId + ":" + deviceId,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sid = _verifyKeyAndStartSession(
|
const sid = _verifyKeyAndStartSession(
|
||||||
olmDevice, oneTimeKey, userId, deviceInfo
|
olmDevice, oneTimeKey, userId, deviceInfo,
|
||||||
);
|
);
|
||||||
result[userId][deviceId].sessionId = sid;
|
result[userId][deviceId].sessionId = sid;
|
||||||
}
|
}
|
||||||
@@ -204,16 +204,16 @@ module.exports.ensureOlmSessionsForDevices = function(
|
|||||||
|
|
||||||
|
|
||||||
function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) {
|
function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) {
|
||||||
let deviceId = deviceInfo.deviceId;
|
const deviceId = deviceInfo.deviceId;
|
||||||
try {
|
try {
|
||||||
_verifySignature(
|
_verifySignature(
|
||||||
olmDevice, oneTimeKey, userId, deviceId,
|
olmDevice, oneTimeKey, userId, deviceId,
|
||||||
deviceInfo.getFingerprint()
|
deviceInfo.getFingerprint(),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(
|
console.error(
|
||||||
"Unable to verify signature on one-time key for device " +
|
"Unable to verify signature on one-time key for device " +
|
||||||
userId + ":" + deviceId + ":", e
|
userId + ":" + deviceId + ":", e,
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) {
|
|||||||
let sid;
|
let sid;
|
||||||
try {
|
try {
|
||||||
sid = olmDevice.createOutboundSession(
|
sid = olmDevice.createOutboundSession(
|
||||||
deviceInfo.getIdentityKey(), oneTimeKey.key
|
deviceInfo.getIdentityKey(), oneTimeKey.key,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// possibly a bad key
|
// possibly a bad key
|
||||||
@@ -250,13 +250,13 @@ function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) {
|
|||||||
*
|
*
|
||||||
* @param {string} signingKey base64-ed ed25519 public key
|
* @param {string} signingKey base64-ed ed25519 public key
|
||||||
*/
|
*/
|
||||||
let _verifySignature = module.exports.verifySignature = function(
|
const _verifySignature = module.exports.verifySignature = function(
|
||||||
olmDevice, obj, signingUserId, signingDeviceId, signingKey
|
olmDevice, obj, signingUserId, signingDeviceId, signingKey,
|
||||||
) {
|
) {
|
||||||
let signKeyId = "ed25519:" + signingDeviceId;
|
const signKeyId = "ed25519:" + signingDeviceId;
|
||||||
let signatures = obj.signatures || {};
|
const signatures = obj.signatures || {};
|
||||||
let userSigs = signatures[signingUserId] || {};
|
const userSigs = signatures[signingUserId] || {};
|
||||||
let signature = userSigs[signKeyId];
|
const signature = userSigs[signKeyId];
|
||||||
if (!signature) {
|
if (!signature) {
|
||||||
throw Error("No signature");
|
throw Error("No signature");
|
||||||
}
|
}
|
||||||
@@ -265,9 +265,9 @@ let _verifySignature = module.exports.verifySignature = function(
|
|||||||
// anotherjson
|
// anotherjson
|
||||||
delete obj.unsigned;
|
delete obj.unsigned;
|
||||||
delete obj.signatures;
|
delete obj.signatures;
|
||||||
let json = anotherjson.stringify(obj);
|
const json = anotherjson.stringify(obj);
|
||||||
|
|
||||||
olmDevice.verifySignature(
|
olmDevice.verifySignature(
|
||||||
signingKey, json, signature
|
signingKey, json, signature,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
function _matches_wildcard(actual_value, filter_value) {
|
function _matches_wildcard(actual_value, filter_value) {
|
||||||
if (filter_value.endsWith("*")) {
|
if (filter_value.endsWith("*")) {
|
||||||
let type_prefix = filter_value.slice(0, -1);
|
const type_prefix = filter_value.slice(0, -1);
|
||||||
return actual_value.substr(0, type_prefix.length) === type_prefix;
|
return actual_value.substr(0, type_prefix.length) === type_prefix;
|
||||||
} else {
|
} else {
|
||||||
return actual_value === filter_value;
|
return actual_value === filter_value;
|
||||||
@@ -70,7 +70,7 @@ FilterComponent.prototype.check = function(event) {
|
|||||||
event.getRoomId(),
|
event.getRoomId(),
|
||||||
event.getSender(),
|
event.getSender(),
|
||||||
event.getType(),
|
event.getType(),
|
||||||
event.getContent() ? event.getContent().url !== undefined : false
|
event.getContent() ? event.getContent().url !== undefined : false,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ FilterComponent.prototype.check = function(event) {
|
|||||||
*/
|
*/
|
||||||
FilterComponent.prototype._checkFields =
|
FilterComponent.prototype._checkFields =
|
||||||
function(room_id, sender, event_type, contains_url) {
|
function(room_id, sender, event_type, contains_url) {
|
||||||
let literal_keys = {
|
const literal_keys = {
|
||||||
"rooms": function(v) {
|
"rooms": function(v) {
|
||||||
return room_id === v;
|
return room_id === v;
|
||||||
},
|
},
|
||||||
@@ -96,16 +96,16 @@ FilterComponent.prototype._checkFields =
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
Object.keys(literal_keys).forEach(function(name) {
|
Object.keys(literal_keys).forEach(function(name) {
|
||||||
let match_func = literal_keys[name];
|
const match_func = literal_keys[name];
|
||||||
let not_name = "not_" + name;
|
const not_name = "not_" + name;
|
||||||
let disallowed_values = self[not_name];
|
const disallowed_values = self[not_name];
|
||||||
if (disallowed_values.map(match_func)) {
|
if (disallowed_values.map(match_func)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowed_values = self[name];
|
const allowed_values = self[name];
|
||||||
if (allowed_values) {
|
if (allowed_values) {
|
||||||
if (!allowed_values.map(match_func)) {
|
if (!allowed_values.map(match_func)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -113,7 +113,7 @@ FilterComponent.prototype._checkFields =
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let contains_url_filter = this.filter_json.contains_url;
|
const contains_url_filter = this.filter_json.contains_url;
|
||||||
if (contains_url_filter !== undefined) {
|
if (contains_url_filter !== undefined) {
|
||||||
if (contains_url_filter !== contains_url) {
|
if (contains_url_filter !== contains_url) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ limitations under the License.
|
|||||||
* @module filter
|
* @module filter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let FilterComponent = require("./filter-component");
|
const FilterComponent = require("./filter-component");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
@@ -26,7 +26,7 @@ let FilterComponent = require("./filter-component");
|
|||||||
* @param {*} val
|
* @param {*} val
|
||||||
*/
|
*/
|
||||||
function setProp(obj, keyNesting, val) {
|
function setProp(obj, keyNesting, val) {
|
||||||
let nestedKeys = keyNesting.split(".");
|
const nestedKeys = keyNesting.split(".");
|
||||||
let currentObj = obj;
|
let currentObj = obj;
|
||||||
for (let i = 0; i < (nestedKeys.length - 1); i++) {
|
for (let i = 0; i < (nestedKeys.length - 1); i++) {
|
||||||
if (!currentObj[nestedKeys[i]]) {
|
if (!currentObj[nestedKeys[i]]) {
|
||||||
@@ -106,10 +106,10 @@ Filter.prototype.setDefinition = function(definition) {
|
|||||||
// "event_fields": ["type", "content", "sender"]
|
// "event_fields": ["type", "content", "sender"]
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let room_filter_json = definition.room;
|
const room_filter_json = definition.room;
|
||||||
|
|
||||||
// consider the top level rooms/not_rooms filter
|
// consider the top level rooms/not_rooms filter
|
||||||
let room_filter_fields = {};
|
const room_filter_fields = {};
|
||||||
if (room_filter_json) {
|
if (room_filter_json) {
|
||||||
if (room_filter_json.rooms) {
|
if (room_filter_json.rooms) {
|
||||||
room_filter_fields.rooms = room_filter_json.rooms;
|
room_filter_fields.rooms = room_filter_json.rooms;
|
||||||
@@ -123,7 +123,7 @@ Filter.prototype.setDefinition = function(definition) {
|
|||||||
|
|
||||||
this._room_filter = new FilterComponent(room_filter_fields);
|
this._room_filter = new FilterComponent(room_filter_fields);
|
||||||
this._room_timeline_filter = new FilterComponent(
|
this._room_timeline_filter = new FilterComponent(
|
||||||
room_filter_json ? (room_filter_json.timeline || {}) : {}
|
room_filter_json ? (room_filter_json.timeline || {}) : {},
|
||||||
);
|
);
|
||||||
|
|
||||||
// don't bother porting this from synapse yet:
|
// don't bother porting this from synapse yet:
|
||||||
@@ -183,7 +183,7 @@ Filter.prototype.setIncludeLeaveRooms = function(includeLeave) {
|
|||||||
* @return {Filter}
|
* @return {Filter}
|
||||||
*/
|
*/
|
||||||
Filter.fromJson = function(userId, filterId, jsonObj) {
|
Filter.fromJson = function(userId, filterId, jsonObj) {
|
||||||
let filter = new Filter(userId, filterId);
|
const filter = new Filter(userId, filterId);
|
||||||
filter.setDefinition(jsonObj);
|
filter.setDefinition(jsonObj);
|
||||||
return filter;
|
return filter;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ limitations under the License.
|
|||||||
* This is an internal module. See {@link MatrixHttpApi} for the public class.
|
* This is an internal module. See {@link MatrixHttpApi} for the public class.
|
||||||
* @module http-api
|
* @module http-api
|
||||||
*/
|
*/
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let utils = require("./utils");
|
const utils = require("./utils");
|
||||||
|
|
||||||
// we use our own implementation of setTimeout, so that if we get suspended in
|
// we use our own implementation of setTimeout, so that if we get suspended in
|
||||||
// the middle of a /sync, we cancel the sync as soon as we awake, rather than
|
// the middle of a /sync, we cancel the sync as soon as we awake, rather than
|
||||||
// waiting for the delay to elapse.
|
// waiting for the delay to elapse.
|
||||||
let callbacks = require("./realtime-callbacks");
|
const callbacks = require("./realtime-callbacks");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
@@ -91,7 +91,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
* path and query parameters respectively.
|
* path and query parameters respectively.
|
||||||
*/
|
*/
|
||||||
getContentUri: function() {
|
getContentUri: function() {
|
||||||
let params = {
|
const params = {
|
||||||
access_token: this.opts.accessToken,
|
access_token: this.opts.accessToken,
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
@@ -145,12 +145,12 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
|
|
||||||
// if the file doesn't have a mime type, use a default since
|
// if the file doesn't have a mime type, use a default since
|
||||||
// the HS errors if we don't supply one.
|
// the HS errors if we don't supply one.
|
||||||
let contentType = opts.type || file.type || 'application/octet-stream';
|
const contentType = opts.type || file.type || 'application/octet-stream';
|
||||||
let fileName = opts.name || file.name;
|
const fileName = opts.name || file.name;
|
||||||
|
|
||||||
// we used to recommend setting file.stream to the thing to upload on
|
// we used to recommend setting file.stream to the thing to upload on
|
||||||
// nodejs.
|
// nodejs.
|
||||||
let body = file.stream ? file.stream : file;
|
const body = file.stream ? file.stream : file;
|
||||||
|
|
||||||
// backwards-compatibility hacks where we used to do different things
|
// backwards-compatibility hacks where we used to do different things
|
||||||
// between browser and node.
|
// between browser and node.
|
||||||
@@ -163,7 +163,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
"Returning the raw JSON from uploadContent(). Future " +
|
"Returning the raw JSON from uploadContent(). Future " +
|
||||||
"versions of the js-sdk will change this default, to " +
|
"versions of the js-sdk will change this default, to " +
|
||||||
"return the parsed object. Set opts.rawResponse=false " +
|
"return the parsed object. Set opts.rawResponse=false " +
|
||||||
"to change this behaviour now."
|
"to change this behaviour now.",
|
||||||
);
|
);
|
||||||
rawResponse = true;
|
rawResponse = true;
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
"Returning only the content-uri from uploadContent(). " +
|
"Returning only the content-uri from uploadContent(). " +
|
||||||
"Future versions of the js-sdk will change this " +
|
"Future versions of the js-sdk will change this " +
|
||||||
"default, to return the whole response object. Set " +
|
"default, to return the whole response object. Set " +
|
||||||
"opts.onlyContentUri=false to change this behaviour now."
|
"opts.onlyContentUri=false to change this behaviour now.",
|
||||||
);
|
);
|
||||||
onlyContentUri = true;
|
onlyContentUri = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -192,7 +192,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
// (browser-request doesn't support progress either, which is also kind
|
// (browser-request doesn't support progress either, which is also kind
|
||||||
// of important here)
|
// of important here)
|
||||||
|
|
||||||
let upload = { loaded: 0, total: 0 };
|
const upload = { loaded: 0, total: 0 };
|
||||||
let promise;
|
let promise;
|
||||||
|
|
||||||
// XMLHttpRequest doesn't parse JSON for us. request normally does, but
|
// XMLHttpRequest doesn't parse JSON for us. request normally does, but
|
||||||
@@ -214,12 +214,12 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (global.XMLHttpRequest) {
|
if (global.XMLHttpRequest) {
|
||||||
let defer = q.defer();
|
const defer = q.defer();
|
||||||
let xhr = new global.XMLHttpRequest();
|
const xhr = new global.XMLHttpRequest();
|
||||||
upload.xhr = xhr;
|
upload.xhr = xhr;
|
||||||
let cb = requestCallback(defer, opts.callback, this.opts.onlyData);
|
const cb = requestCallback(defer, opts.callback, this.opts.onlyData);
|
||||||
|
|
||||||
let timeout_fn = function() {
|
const timeout_fn = function() {
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
cb(new Error('Timeout'));
|
cb(new Error('Timeout'));
|
||||||
};
|
};
|
||||||
@@ -269,7 +269,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
// dirty hack (as per _request) to allow the upload to be cancelled.
|
// dirty hack (as per _request) to allow the upload to be cancelled.
|
||||||
promise.abort = xhr.abort.bind(xhr);
|
promise.abort = xhr.abort.bind(xhr);
|
||||||
} else {
|
} else {
|
||||||
let queryParams = {
|
const queryParams = {
|
||||||
filename: fileName,
|
filename: fileName,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -279,14 +279,14 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
headers: {"Content-Type": contentType},
|
headers: {"Content-Type": contentType},
|
||||||
json: false,
|
json: false,
|
||||||
bodyParser: bodyParser,
|
bodyParser: bodyParser,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
// remove the upload from the list on completion
|
// remove the upload from the list on completion
|
||||||
let promise0 = promise.finally(function() {
|
const promise0 = promise.finally(function() {
|
||||||
for (let i = 0; i < self.uploads.length; ++i) {
|
for (let i = 0; i < self.uploads.length; ++i) {
|
||||||
if (self.uploads[i] === upload) {
|
if (self.uploads[i] === upload) {
|
||||||
self.uploads.splice(i, 1);
|
self.uploads.splice(i, 1);
|
||||||
@@ -317,15 +317,15 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
idServerRequest: function(callback, method, path, params, prefix) {
|
idServerRequest: function(callback, method, path, params, prefix) {
|
||||||
let fullUri = this.opts.idBaseUrl + prefix + path;
|
const fullUri = this.opts.idBaseUrl + prefix + path;
|
||||||
|
|
||||||
if (callback !== undefined && !utils.isFunction(callback)) {
|
if (callback !== undefined && !utils.isFunction(callback)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
"Expected callback to be a function but got " + typeof callback
|
"Expected callback to be a function but got " + typeof callback,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let opts = {
|
const opts = {
|
||||||
uri: fullUri,
|
uri: fullUri,
|
||||||
method: method,
|
method: method,
|
||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
@@ -338,10 +338,10 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
opts.form = params;
|
opts.form = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
let defer = q.defer();
|
const defer = q.defer();
|
||||||
this.opts.request(
|
this.opts.request(
|
||||||
opts,
|
opts,
|
||||||
requestCallback(defer, callback, this.opts.onlyData)
|
requestCallback(defer, callback, this.opts.onlyData),
|
||||||
);
|
);
|
||||||
// ID server does not always take JSON, so we can't use requests' 'json'
|
// ID server does not always take JSON, so we can't use requests' 'json'
|
||||||
// option as we do with the home server, but it does return JSON, so
|
// option as we do with the home server, but it does return JSON, so
|
||||||
@@ -389,11 +389,11 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
queryParams.access_token = this.opts.accessToken;
|
queryParams.access_token = this.opts.accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
let request_promise = this.request(
|
const request_promise = this.request(
|
||||||
callback, method, path, queryParams, data, opts
|
callback, method, path, queryParams, data, opts,
|
||||||
);
|
);
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
request_promise.catch(function(err) {
|
request_promise.catch(function(err) {
|
||||||
if (err.errcode == 'M_UNKNOWN_TOKEN') {
|
if (err.errcode == 'M_UNKNOWN_TOKEN') {
|
||||||
self.event_emitter.emit("Session.logged_out");
|
self.event_emitter.emit("Session.logged_out");
|
||||||
@@ -437,11 +437,11 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
*/
|
*/
|
||||||
request: function(callback, method, path, queryParams, data, opts) {
|
request: function(callback, method, path, queryParams, data, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
let prefix = opts.prefix !== undefined ? opts.prefix : this.opts.prefix;
|
const prefix = opts.prefix !== undefined ? opts.prefix : this.opts.prefix;
|
||||||
let fullUri = this.opts.baseUrl + prefix + path;
|
const fullUri = this.opts.baseUrl + prefix + path;
|
||||||
|
|
||||||
return this.requestOtherUrl(
|
return this.requestOtherUrl(
|
||||||
callback, method, fullUri, queryParams, data, opts
|
callback, method, fullUri, queryParams, data, opts,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -476,7 +476,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
callback, method, path, queryParams, data, {
|
callback, method, path, queryParams, data, {
|
||||||
localTimeoutMs: localTimeoutMs,
|
localTimeoutMs: localTimeoutMs,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
callback, method, path, queryParams, data, {
|
callback, method, path, queryParams, data, {
|
||||||
localTimeoutMs: localTimeoutMs,
|
localTimeoutMs: localTimeoutMs,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -556,7 +556,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this._request(
|
return this._request(
|
||||||
callback, method, uri, queryParams, data, opts
|
callback, method, uri, queryParams, data, opts,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -608,14 +608,14 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
_request: function(callback, method, uri, queryParams, data, opts) {
|
_request: function(callback, method, uri, queryParams, data, opts) {
|
||||||
if (callback !== undefined && !utils.isFunction(callback)) {
|
if (callback !== undefined && !utils.isFunction(callback)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
"Expected callback to be a function but got " + typeof callback
|
"Expected callback to be a function but got " + typeof callback,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
if (this.opts.extraParams) {
|
if (this.opts.extraParams) {
|
||||||
for (let key in this.opts.extraParams) {
|
for (const key in this.opts.extraParams) {
|
||||||
if (!this.opts.extraParams.hasOwnProperty(key)) {
|
if (!this.opts.extraParams.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -623,14 +623,14 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let json = opts.json === undefined ? true : opts.json;
|
const json = opts.json === undefined ? true : opts.json;
|
||||||
|
|
||||||
let defer = q.defer();
|
const defer = q.defer();
|
||||||
|
|
||||||
let timeoutId;
|
let timeoutId;
|
||||||
let timedOut = false;
|
let timedOut = false;
|
||||||
let req;
|
let req;
|
||||||
let localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs;
|
const localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs;
|
||||||
if (localTimeoutMs) {
|
if (localTimeoutMs) {
|
||||||
timeoutId = callbacks.setTimeout(function() {
|
timeoutId = callbacks.setTimeout(function() {
|
||||||
timedOut = true;
|
timedOut = true;
|
||||||
@@ -645,7 +645,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
}, localTimeoutMs);
|
}, localTimeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
let reqPromise = defer.promise;
|
const reqPromise = defer.promise;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
req = this.opts.request(
|
req = this.opts.request(
|
||||||
@@ -670,14 +670,14 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
|
|
||||||
// if json is falsy, we won't parse any error response, so need
|
// if json is falsy, we won't parse any error response, so need
|
||||||
// to do so before turning it into a MatrixError
|
// to do so before turning it into a MatrixError
|
||||||
let parseErrorJson = !json;
|
const parseErrorJson = !json;
|
||||||
let handlerFn = requestCallback(
|
const handlerFn = requestCallback(
|
||||||
defer, callback, self.opts.onlyData,
|
defer, callback, self.opts.onlyData,
|
||||||
parseErrorJson,
|
parseErrorJson,
|
||||||
opts.bodyParser
|
opts.bodyParser,
|
||||||
);
|
);
|
||||||
handlerFn(err, response, body);
|
handlerFn(err, response, body);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
if (req && req.abort) {
|
if (req && req.abort) {
|
||||||
// FIXME: This is EVIL, but I can't think of a better way to expose
|
// FIXME: This is EVIL, but I can't think of a better way to expose
|
||||||
@@ -705,9 +705,9 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
* If parseErrorJson is true, we will JSON.parse the body if we get a 4xx error.
|
* If parseErrorJson is true, we will JSON.parse the body if we get a 4xx error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
let requestCallback = function(
|
const requestCallback = function(
|
||||||
defer, userDefinedCallback, onlyData,
|
defer, userDefinedCallback, onlyData,
|
||||||
parseErrorJson, bodyParser
|
parseErrorJson, bodyParser,
|
||||||
) {
|
) {
|
||||||
userDefinedCallback = userDefinedCallback || function() {};
|
userDefinedCallback = userDefinedCallback || function() {};
|
||||||
|
|
||||||
@@ -735,7 +735,7 @@ let requestCallback = function(
|
|||||||
defer.reject(err);
|
defer.reject(err);
|
||||||
userDefinedCallback(err);
|
userDefinedCallback(err);
|
||||||
} else {
|
} else {
|
||||||
let res = {
|
const res = {
|
||||||
code: response.statusCode,
|
code: response.statusCode,
|
||||||
headers: response.headers,
|
headers: response.headers,
|
||||||
data: body,
|
data: body,
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ limitations under the License.
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/** @module interactive-auth */
|
/** @module interactive-auth */
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
|
|
||||||
let utils = require("./utils");
|
const utils = require("./utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstracts the logic used to drive the interactive auth process.
|
* Abstracts the logic used to drive the interactive auth process.
|
||||||
@@ -115,7 +115,7 @@ InteractiveAuth.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use the sessionid from the last request.
|
// use the sessionid from the last request.
|
||||||
let auth = {
|
const auth = {
|
||||||
session: this._data.session,
|
session: this._data.session,
|
||||||
};
|
};
|
||||||
utils.extend(auth, authData);
|
utils.extend(auth, authData);
|
||||||
@@ -131,7 +131,7 @@ InteractiveAuth.prototype = {
|
|||||||
* @param {object?} auth new auth dict, including session id
|
* @param {object?} auth new auth dict, including session id
|
||||||
*/
|
*/
|
||||||
_doRequest: function(auth) {
|
_doRequest: function(auth) {
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
// hackery to make sure that synchronous exceptions end up in the catch
|
// hackery to make sure that synchronous exceptions end up in the catch
|
||||||
// handler (without the additional event loop entailed by q.fcall or an
|
// handler (without the additional event loop entailed by q.fcall or an
|
||||||
@@ -154,7 +154,7 @@ InteractiveAuth.prototype = {
|
|||||||
}
|
}
|
||||||
self._data = error.data;
|
self._data = error.data;
|
||||||
self._startNextAuthStage();
|
self._startNextAuthStage();
|
||||||
}
|
},
|
||||||
).catch(this._completionDeferred.reject).done();
|
).catch(this._completionDeferred.reject).done();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ InteractiveAuth.prototype = {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_startNextAuthStage: function() {
|
_startNextAuthStage: function() {
|
||||||
let nextStage = this._chooseStage();
|
const nextStage = this._chooseStage();
|
||||||
if (!nextStage) {
|
if (!nextStage) {
|
||||||
throw new Error("No incomplete flows from the server");
|
throw new Error("No incomplete flows from the server");
|
||||||
}
|
}
|
||||||
@@ -186,9 +186,9 @@ InteractiveAuth.prototype = {
|
|||||||
* @return {string?} login type
|
* @return {string?} login type
|
||||||
*/
|
*/
|
||||||
_chooseStage: function() {
|
_chooseStage: function() {
|
||||||
let flow = this._chooseFlow();
|
const flow = this._chooseFlow();
|
||||||
console.log("Active flow => %s", JSON.stringify(flow));
|
console.log("Active flow => %s", JSON.stringify(flow));
|
||||||
let nextStage = this._firstUncompletedStage(flow);
|
const nextStage = this._firstUncompletedStage(flow);
|
||||||
console.log("Next stage: %s", nextStage);
|
console.log("Next stage: %s", nextStage);
|
||||||
return nextStage;
|
return nextStage;
|
||||||
},
|
},
|
||||||
@@ -200,7 +200,7 @@ InteractiveAuth.prototype = {
|
|||||||
* @return {object} flow
|
* @return {object} flow
|
||||||
*/
|
*/
|
||||||
_chooseFlow: function() {
|
_chooseFlow: function() {
|
||||||
let flows = this._data.flows || [];
|
const flows = this._data.flows || [];
|
||||||
// always use the first flow for now
|
// always use the first flow for now
|
||||||
return flows[0];
|
return flows[0];
|
||||||
},
|
},
|
||||||
@@ -213,9 +213,9 @@ InteractiveAuth.prototype = {
|
|||||||
* @return {string} login type
|
* @return {string} login type
|
||||||
*/
|
*/
|
||||||
_firstUncompletedStage: function(flow) {
|
_firstUncompletedStage: function(flow) {
|
||||||
let completed = (this._data || {}).completed || [];
|
const completed = (this._data || {}).completed || [];
|
||||||
for (let i = 0; i < flow.stages.length; ++i) {
|
for (let i = 0; i < flow.stages.length; ++i) {
|
||||||
let stageType = flow.stages[i];
|
const stageType = flow.stages[i];
|
||||||
if (completed.indexOf(stageType) === -1) {
|
if (completed.indexOf(stageType) === -1) {
|
||||||
return stageType;
|
return stageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ module.exports.getRequest = function() {
|
|||||||
* @param {requestWrapperFunction} wrapper The wrapping function.
|
* @param {requestWrapperFunction} wrapper The wrapping function.
|
||||||
*/
|
*/
|
||||||
module.exports.wrapRequest = function(wrapper) {
|
module.exports.wrapRequest = function(wrapper) {
|
||||||
let origRequest = request;
|
const origRequest = request;
|
||||||
request = function(options, callback) {
|
request = function(options, callback) {
|
||||||
return wrapper(origRequest, options, callback);
|
return wrapper(origRequest, options, callback);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ limitations under the License.
|
|||||||
/**
|
/**
|
||||||
* @module models/event-timeline-set
|
* @module models/event-timeline-set
|
||||||
*/
|
*/
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let EventTimeline = require("./event-timeline");
|
const EventTimeline = require("./event-timeline");
|
||||||
|
|
||||||
// var DEBUG = false;
|
// var DEBUG = false;
|
||||||
let DEBUG = true;
|
const DEBUG = true;
|
||||||
|
|
||||||
let debuglog;
|
let debuglog;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -136,7 +136,7 @@ EventTimelineSet.prototype.eventIdToTimeline = function(eventId) {
|
|||||||
* @param {String} newEventId event ID of the replacement event
|
* @param {String} newEventId event ID of the replacement event
|
||||||
*/
|
*/
|
||||||
EventTimelineSet.prototype.replaceEventId = function(oldEventId, newEventId) {
|
EventTimelineSet.prototype.replaceEventId = function(oldEventId, newEventId) {
|
||||||
let existingTimeline = this._eventIdToTimeline[oldEventId];
|
const existingTimeline = this._eventIdToTimeline[oldEventId];
|
||||||
if (existingTimeline) {
|
if (existingTimeline) {
|
||||||
delete this._eventIdToTimeline[oldEventId];
|
delete this._eventIdToTimeline[oldEventId];
|
||||||
this._eventIdToTimeline[newEventId] = existingTimeline;
|
this._eventIdToTimeline[newEventId] = existingTimeline;
|
||||||
@@ -166,13 +166,13 @@ EventTimelineSet.prototype.resetLiveTimeline = function(backPaginationToken, flu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initialise the state in the new timeline from our last known state
|
// initialise the state in the new timeline from our last known state
|
||||||
let evMap = this._liveTimeline.getState(EventTimeline.FORWARDS).events;
|
const evMap = this._liveTimeline.getState(EventTimeline.FORWARDS).events;
|
||||||
let events = [];
|
const events = [];
|
||||||
for (let evtype in evMap) {
|
for (const evtype in evMap) {
|
||||||
if (!evMap.hasOwnProperty(evtype)) {
|
if (!evMap.hasOwnProperty(evtype)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (let stateKey in evMap[evtype]) {
|
for (const stateKey in evMap[evtype]) {
|
||||||
if (!evMap[evtype].hasOwnProperty(stateKey)) {
|
if (!evMap[evtype].hasOwnProperty(stateKey)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ EventTimelineSet.prototype.resetLiveTimeline = function(backPaginationToken, flu
|
|||||||
* the given event, or null if unknown
|
* the given event, or null if unknown
|
||||||
*/
|
*/
|
||||||
EventTimelineSet.prototype.getTimelineForEvent = function(eventId) {
|
EventTimelineSet.prototype.getTimelineForEvent = function(eventId) {
|
||||||
let res = this._eventIdToTimeline[eventId];
|
const res = this._eventIdToTimeline[eventId];
|
||||||
return (res === undefined) ? null : res;
|
return (res === undefined) ? null : res;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ EventTimelineSet.prototype.getTimelineForEvent = function(eventId) {
|
|||||||
* @return {?module:models/event~MatrixEvent} the given event, or undefined if unknown
|
* @return {?module:models/event~MatrixEvent} the given event, or undefined if unknown
|
||||||
*/
|
*/
|
||||||
EventTimelineSet.prototype.findEventById = function(eventId) {
|
EventTimelineSet.prototype.findEventById = function(eventId) {
|
||||||
let tl = this.getTimelineForEvent(eventId);
|
const tl = this.getTimelineForEvent(eventId);
|
||||||
if (!tl) {
|
if (!tl) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,7 @@ EventTimelineSet.prototype.addTimeline = function() {
|
|||||||
" it.");
|
" it.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeline = new EventTimeline(this);
|
const timeline = new EventTimeline(this);
|
||||||
this._timelines.push(timeline);
|
this._timelines.push(timeline);
|
||||||
return timeline;
|
return timeline;
|
||||||
};
|
};
|
||||||
@@ -259,14 +259,14 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel
|
|||||||
timeline, paginationToken) {
|
timeline, paginationToken) {
|
||||||
if (!timeline) {
|
if (!timeline) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'timeline' not specified for EventTimelineSet.addEventsToTimeline"
|
"'timeline' not specified for EventTimelineSet.addEventsToTimeline",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!toStartOfTimeline && timeline == this._liveTimeline) {
|
if (!toStartOfTimeline && timeline == this._liveTimeline) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"EventTimelineSet.addEventsToTimeline cannot be used for adding events to " +
|
"EventTimelineSet.addEventsToTimeline cannot be used for adding events to " +
|
||||||
"the live timeline - use Room.addLiveEvents instead"
|
"the live timeline - use Room.addLiveEvents instead",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,9 +277,9 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let direction = toStartOfTimeline ? EventTimeline.BACKWARDS :
|
const direction = toStartOfTimeline ? EventTimeline.BACKWARDS :
|
||||||
EventTimeline.FORWARDS;
|
EventTimeline.FORWARDS;
|
||||||
let inverseDirection = toStartOfTimeline ? EventTimeline.FORWARDS :
|
const inverseDirection = toStartOfTimeline ? EventTimeline.FORWARDS :
|
||||||
EventTimeline.BACKWARDS;
|
EventTimeline.BACKWARDS;
|
||||||
|
|
||||||
// Adding events to timelines can be quite complicated. The following
|
// Adding events to timelines can be quite complicated. The following
|
||||||
@@ -354,10 +354,10 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel
|
|||||||
let didUpdate = false;
|
let didUpdate = false;
|
||||||
let lastEventWasNew = false;
|
let lastEventWasNew = false;
|
||||||
for (let i = 0; i < events.length; i++) {
|
for (let i = 0; i < events.length; i++) {
|
||||||
let event = events[i];
|
const event = events[i];
|
||||||
let eventId = event.getId();
|
const eventId = event.getId();
|
||||||
|
|
||||||
let existingTimeline = this._eventIdToTimeline[eventId];
|
const existingTimeline = this._eventIdToTimeline[eventId];
|
||||||
|
|
||||||
if (!existingTimeline) {
|
if (!existingTimeline) {
|
||||||
// we don't know about this event yet. Just add it to the timeline.
|
// we don't know about this event yet. Just add it to the timeline.
|
||||||
@@ -374,7 +374,7 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let neighbour = timeline.getNeighbouringTimeline(direction);
|
const neighbour = timeline.getNeighbouringTimeline(direction);
|
||||||
if (neighbour) {
|
if (neighbour) {
|
||||||
// this timeline already has a neighbour in the relevant direction;
|
// this timeline already has a neighbour in the relevant direction;
|
||||||
// let's assume the timelines are already correctly linked up, and
|
// let's assume the timelines are already correctly linked up, and
|
||||||
@@ -422,25 +422,25 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel
|
|||||||
*/
|
*/
|
||||||
EventTimelineSet.prototype.addLiveEvent = function(event, duplicateStrategy) {
|
EventTimelineSet.prototype.addLiveEvent = function(event, duplicateStrategy) {
|
||||||
if (this._filter) {
|
if (this._filter) {
|
||||||
let events = this._filter.filterRoomTimeline([event]);
|
const events = this._filter.filterRoomTimeline([event]);
|
||||||
if (!events.length) {
|
if (!events.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeline = this._eventIdToTimeline[event.getId()];
|
const timeline = this._eventIdToTimeline[event.getId()];
|
||||||
if (timeline) {
|
if (timeline) {
|
||||||
if (duplicateStrategy === "replace") {
|
if (duplicateStrategy === "replace") {
|
||||||
debuglog("EventTimelineSet.addLiveEvent: replacing duplicate event " +
|
debuglog("EventTimelineSet.addLiveEvent: replacing duplicate event " +
|
||||||
event.getId());
|
event.getId());
|
||||||
let tlEvents = timeline.getEvents();
|
const tlEvents = timeline.getEvents();
|
||||||
for (let j = 0; j < tlEvents.length; j++) {
|
for (let j = 0; j < tlEvents.length; j++) {
|
||||||
if (tlEvents[j].getId() === event.getId()) {
|
if (tlEvents[j].getId() === event.getId()) {
|
||||||
// still need to set the right metadata on this event
|
// still need to set the right metadata on this event
|
||||||
EventTimeline.setEventMetadata(
|
EventTimeline.setEventMetadata(
|
||||||
event,
|
event,
|
||||||
timeline.getState(EventTimeline.FORWARDS),
|
timeline.getState(EventTimeline.FORWARDS),
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!tlEvents[j].encryptedType) {
|
if (!tlEvents[j].encryptedType) {
|
||||||
@@ -475,11 +475,11 @@ EventTimelineSet.prototype.addLiveEvent = function(event, duplicateStrategy) {
|
|||||||
*/
|
*/
|
||||||
EventTimelineSet.prototype.addEventToTimeline = function(event, timeline,
|
EventTimelineSet.prototype.addEventToTimeline = function(event, timeline,
|
||||||
toStartOfTimeline) {
|
toStartOfTimeline) {
|
||||||
let eventId = event.getId();
|
const eventId = event.getId();
|
||||||
timeline.addEvent(event, toStartOfTimeline);
|
timeline.addEvent(event, toStartOfTimeline);
|
||||||
this._eventIdToTimeline[eventId] = timeline;
|
this._eventIdToTimeline[eventId] = timeline;
|
||||||
|
|
||||||
let data = {
|
const data = {
|
||||||
timeline: timeline,
|
timeline: timeline,
|
||||||
liveEvent: !toStartOfTimeline && timeline == this._liveTimeline,
|
liveEvent: !toStartOfTimeline && timeline == this._liveTimeline,
|
||||||
};
|
};
|
||||||
@@ -500,7 +500,7 @@ EventTimelineSet.prototype.addEventToTimeline = function(event, timeline,
|
|||||||
EventTimelineSet.prototype.handleRemoteEcho = function(localEvent, oldEventId,
|
EventTimelineSet.prototype.handleRemoteEcho = function(localEvent, oldEventId,
|
||||||
newEventId) {
|
newEventId) {
|
||||||
// XXX: why don't we infer newEventId from localEvent?
|
// XXX: why don't we infer newEventId from localEvent?
|
||||||
let existingTimeline = this._eventIdToTimeline[oldEventId];
|
const existingTimeline = this._eventIdToTimeline[oldEventId];
|
||||||
if (existingTimeline) {
|
if (existingTimeline) {
|
||||||
delete this._eventIdToTimeline[oldEventId];
|
delete this._eventIdToTimeline[oldEventId];
|
||||||
this._eventIdToTimeline[newEventId] = existingTimeline;
|
this._eventIdToTimeline[newEventId] = existingTimeline;
|
||||||
@@ -524,15 +524,15 @@ EventTimelineSet.prototype.handleRemoteEcho = function(localEvent, oldEventId,
|
|||||||
* in this room.
|
* in this room.
|
||||||
*/
|
*/
|
||||||
EventTimelineSet.prototype.removeEvent = function(eventId) {
|
EventTimelineSet.prototype.removeEvent = function(eventId) {
|
||||||
let timeline = this._eventIdToTimeline[eventId];
|
const timeline = this._eventIdToTimeline[eventId];
|
||||||
if (!timeline) {
|
if (!timeline) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let removed = timeline.removeEvent(eventId);
|
const removed = timeline.removeEvent(eventId);
|
||||||
if (removed) {
|
if (removed) {
|
||||||
delete this._eventIdToTimeline[eventId];
|
delete this._eventIdToTimeline[eventId];
|
||||||
let data = {
|
const data = {
|
||||||
timeline: timeline,
|
timeline: timeline,
|
||||||
};
|
};
|
||||||
this.emit("Room.timeline", removed, this.room, undefined, true, data);
|
this.emit("Room.timeline", removed, this.room, undefined, true, data);
|
||||||
@@ -558,8 +558,8 @@ EventTimelineSet.prototype.compareEventOrdering = function(eventId1, eventId2) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeline1 = this._eventIdToTimeline[eventId1];
|
const timeline1 = this._eventIdToTimeline[eventId1];
|
||||||
let timeline2 = this._eventIdToTimeline[eventId2];
|
const timeline2 = this._eventIdToTimeline[eventId2];
|
||||||
|
|
||||||
if (timeline1 === undefined) {
|
if (timeline1 === undefined) {
|
||||||
return null;
|
return null;
|
||||||
@@ -572,10 +572,10 @@ EventTimelineSet.prototype.compareEventOrdering = function(eventId1, eventId2) {
|
|||||||
// both events are in the same timeline - figure out their
|
// both events are in the same timeline - figure out their
|
||||||
// relative indices
|
// relative indices
|
||||||
let idx1, idx2;
|
let idx1, idx2;
|
||||||
let events = timeline1.getEvents();
|
const events = timeline1.getEvents();
|
||||||
for (let idx = 0; idx < events.length &&
|
for (let idx = 0; idx < events.length &&
|
||||||
(idx1 === undefined || idx2 === undefined); idx++) {
|
(idx1 === undefined || idx2 === undefined); idx++) {
|
||||||
let evId = events[idx].getId();
|
const evId = events[idx].getId();
|
||||||
if (evId == eventId1) {
|
if (evId == eventId1) {
|
||||||
idx1 = idx;
|
idx1 = idx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
* @module models/event-timeline
|
* @module models/event-timeline
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let RoomState = require("./room-state");
|
const RoomState = require("./room-state");
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let MatrixEvent = require("./event").MatrixEvent;
|
const MatrixEvent = require("./event").MatrixEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new EventTimeline
|
* Construct a new EventTimeline
|
||||||
@@ -75,11 +75,11 @@ EventTimeline.prototype.initialiseState = function(stateEvents) {
|
|||||||
|
|
||||||
// we deep-copy the events here, in case they get changed later - we don't
|
// we deep-copy the events here, in case they get changed later - we don't
|
||||||
// want changes to the start state leaking through to the end state.
|
// want changes to the start state leaking through to the end state.
|
||||||
let oldStateEvents = utils.map(
|
const oldStateEvents = utils.map(
|
||||||
utils.deepCopy(
|
utils.deepCopy(
|
||||||
stateEvents.map(function(mxEvent) {
|
stateEvents.map(function(mxEvent) {
|
||||||
return mxEvent.event;
|
return mxEvent.event;
|
||||||
})
|
}),
|
||||||
),
|
),
|
||||||
function(ev) {
|
function(ev) {
|
||||||
return new MatrixEvent(ev);
|
return new MatrixEvent(ev);
|
||||||
@@ -237,10 +237,10 @@ EventTimeline.prototype.setNeighbouringTimeline = function(neighbour, direction)
|
|||||||
* @param {boolean} atStart true to insert new event at the start
|
* @param {boolean} atStart true to insert new event at the start
|
||||||
*/
|
*/
|
||||||
EventTimeline.prototype.addEvent = function(event, atStart) {
|
EventTimeline.prototype.addEvent = function(event, atStart) {
|
||||||
let stateContext = atStart ? this._startState : this._endState;
|
const stateContext = atStart ? this._startState : this._endState;
|
||||||
|
|
||||||
// only call setEventMetadata on the unfiltered timelineSets
|
// only call setEventMetadata on the unfiltered timelineSets
|
||||||
let timelineSet = this.getTimelineSet();
|
const timelineSet = this.getTimelineSet();
|
||||||
if (timelineSet.room &&
|
if (timelineSet.room &&
|
||||||
timelineSet.room.getUnfilteredTimelineSet() === timelineSet) {
|
timelineSet.room.getUnfilteredTimelineSet() === timelineSet) {
|
||||||
EventTimeline.setEventMetadata(event, stateContext, atStart);
|
EventTimeline.setEventMetadata(event, stateContext, atStart);
|
||||||
@@ -288,11 +288,11 @@ EventTimeline.prototype.addEvent = function(event, atStart) {
|
|||||||
EventTimeline.setEventMetadata = function(event, stateContext, toStartOfTimeline) {
|
EventTimeline.setEventMetadata = function(event, stateContext, toStartOfTimeline) {
|
||||||
// set sender and target properties
|
// set sender and target properties
|
||||||
event.sender = stateContext.getSentinelMember(
|
event.sender = stateContext.getSentinelMember(
|
||||||
event.getSender()
|
event.getSender(),
|
||||||
);
|
);
|
||||||
if (event.getType() === "m.room.member") {
|
if (event.getType() === "m.room.member") {
|
||||||
event.target = stateContext.getSentinelMember(
|
event.target = stateContext.getSentinelMember(
|
||||||
event.getStateKey()
|
event.getStateKey(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (event.isState()) {
|
if (event.isState()) {
|
||||||
@@ -314,7 +314,7 @@ EventTimeline.setEventMetadata = function(event, stateContext, toStartOfTimeline
|
|||||||
*/
|
*/
|
||||||
EventTimeline.prototype.removeEvent = function(eventId) {
|
EventTimeline.prototype.removeEvent = function(eventId) {
|
||||||
for (let i = this._events.length - 1; i >= 0; i--) {
|
for (let i = this._events.length - 1; i >= 0; i--) {
|
||||||
let ev = this._events[i];
|
const ev = this._events[i];
|
||||||
if (ev.getId() == eventId) {
|
if (ev.getId() == eventId) {
|
||||||
this._events.splice(i, 1);
|
this._events.splice(i, 1);
|
||||||
if (i < this._baseIndex) {
|
if (i < this._baseIndex) {
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ limitations under the License.
|
|||||||
* @module models/event
|
* @module models/event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
|
|
||||||
let utils = require('../utils.js');
|
const utils = require('../utils.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum for event statuses.
|
* Enum for event statuses.
|
||||||
@@ -70,7 +70,7 @@ module.exports.EventStatus = {
|
|||||||
* Default: true. <strong>This property is experimental and may change.</strong>
|
* Default: true. <strong>This property is experimental and may change.</strong>
|
||||||
*/
|
*/
|
||||||
module.exports.MatrixEvent = function MatrixEvent(
|
module.exports.MatrixEvent = function MatrixEvent(
|
||||||
event
|
event,
|
||||||
) {
|
) {
|
||||||
this.event = event || {};
|
this.event = event || {};
|
||||||
this.sender = null;
|
this.sender = null;
|
||||||
@@ -350,8 +350,8 @@ utils.extend(module.exports.MatrixEvent.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let keeps = _REDACT_KEEP_CONTENT_MAP[this.getType()] || {};
|
const keeps = _REDACT_KEEP_CONTENT_MAP[this.getType()] || {};
|
||||||
let content = this.getContent();
|
const content = this.getContent();
|
||||||
for (key in content) {
|
for (key in content) {
|
||||||
if (!content.hasOwnProperty(key)) {
|
if (!content.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -424,7 +424,7 @@ utils.extend(module.exports.MatrixEvent.prototype, {
|
|||||||
* m.room.aliases allows key aliases
|
* m.room.aliases allows key aliases
|
||||||
*/
|
*/
|
||||||
// a map giving the keys we keep when an event is redacted
|
// a map giving the keys we keep when an event is redacted
|
||||||
let _REDACT_KEEP_KEY_MAP = [
|
const _REDACT_KEEP_KEY_MAP = [
|
||||||
'event_id', 'type', 'room_id', 'user_id', 'state_key', 'prev_state',
|
'event_id', 'type', 'room_id', 'user_id', 'state_key', 'prev_state',
|
||||||
'content', 'unsigned',
|
'content', 'unsigned',
|
||||||
].reduce(function(ret, val) {
|
].reduce(function(ret, val) {
|
||||||
@@ -432,7 +432,7 @@ let _REDACT_KEEP_KEY_MAP = [
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
// a map from event type to the .content keys we keep when an event is redacted
|
// a map from event type to the .content keys we keep when an event is redacted
|
||||||
let _REDACT_KEEP_CONTENT_MAP = {
|
const _REDACT_KEEP_CONTENT_MAP = {
|
||||||
'm.room.member': {'membership': 1},
|
'm.room.member': {'membership': 1},
|
||||||
'm.room.create': {'creator': 1},
|
'm.room.create': {'creator': 1},
|
||||||
'm.room.join_rules': {'join_rule': 1},
|
'm.room.join_rules': {'join_rule': 1},
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ limitations under the License.
|
|||||||
/**
|
/**
|
||||||
* @module models/room-member
|
* @module models/room-member
|
||||||
*/
|
*/
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
let ContentRepo = require("../content-repo");
|
const ContentRepo = require("../content-repo");
|
||||||
|
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new room member.
|
* Construct a new room member.
|
||||||
@@ -73,10 +73,10 @@ RoomMember.prototype.setMembershipEvent = function(event, roomState) {
|
|||||||
}
|
}
|
||||||
this.events.member = event;
|
this.events.member = event;
|
||||||
|
|
||||||
let oldMembership = this.membership;
|
const oldMembership = this.membership;
|
||||||
this.membership = event.getDirectionalContent().membership;
|
this.membership = event.getDirectionalContent().membership;
|
||||||
|
|
||||||
let oldName = this.name;
|
const oldName = this.name;
|
||||||
this.name = calculateDisplayName(this, event, roomState);
|
this.name = calculateDisplayName(this, event, roomState);
|
||||||
if (oldMembership !== this.membership) {
|
if (oldMembership !== this.membership) {
|
||||||
this._updateModifiedTime();
|
this._updateModifiedTime();
|
||||||
@@ -103,8 +103,8 @@ RoomMember.prototype.setPowerLevelEvent = function(powerLevelEvent) {
|
|||||||
utils.forEach(utils.values(powerLevelEvent.getContent().users), function(lvl) {
|
utils.forEach(utils.values(powerLevelEvent.getContent().users), function(lvl) {
|
||||||
maxLevel = Math.max(maxLevel, lvl);
|
maxLevel = Math.max(maxLevel, lvl);
|
||||||
});
|
});
|
||||||
let oldPowerLevel = this.powerLevel;
|
const oldPowerLevel = this.powerLevel;
|
||||||
let oldPowerLevelNorm = this.powerLevelNorm;
|
const oldPowerLevelNorm = this.powerLevelNorm;
|
||||||
|
|
||||||
if (powerLevelEvent.getContent().users[this.userId] !== undefined) {
|
if (powerLevelEvent.getContent().users[this.userId] !== undefined) {
|
||||||
this.powerLevel = powerLevelEvent.getContent().users[this.userId];
|
this.powerLevel = powerLevelEvent.getContent().users[this.userId];
|
||||||
@@ -136,9 +136,9 @@ RoomMember.prototype.setTypingEvent = function(event) {
|
|||||||
if (event.getType() !== "m.typing") {
|
if (event.getType() !== "m.typing") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let oldTyping = this.typing;
|
const oldTyping = this.typing;
|
||||||
this.typing = false;
|
this.typing = false;
|
||||||
let typingList = event.getContent().user_ids;
|
const typingList = event.getContent().user_ids;
|
||||||
if (!utils.isArray(typingList)) {
|
if (!utils.isArray(typingList)) {
|
||||||
// malformed event :/ bail early. TODO: whine?
|
// malformed event :/ bail early. TODO: whine?
|
||||||
return;
|
return;
|
||||||
@@ -195,23 +195,23 @@ RoomMember.prototype.getAvatarUrl =
|
|||||||
if (!this.events.member && !allowDefault) {
|
if (!this.events.member && !allowDefault) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let rawUrl = this.events.member ? this.events.member.getContent().avatar_url : null;
|
const rawUrl = this.events.member ? this.events.member.getContent().avatar_url : null;
|
||||||
let httpUrl = ContentRepo.getHttpUriForMxc(
|
const httpUrl = ContentRepo.getHttpUriForMxc(
|
||||||
baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks
|
baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks,
|
||||||
);
|
);
|
||||||
if (httpUrl) {
|
if (httpUrl) {
|
||||||
return httpUrl;
|
return httpUrl;
|
||||||
} else if (allowDefault) {
|
} else if (allowDefault) {
|
||||||
return ContentRepo.getIdenticonUri(
|
return ContentRepo.getIdenticonUri(
|
||||||
baseUrl, this.userId, width, height
|
baseUrl, this.userId, width, height,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
function calculateDisplayName(member, event, roomState) {
|
function calculateDisplayName(member, event, roomState) {
|
||||||
let displayName = event.getDirectionalContent().displayname;
|
const displayName = event.getDirectionalContent().displayname;
|
||||||
let selfUserId = member.userId;
|
const selfUserId = member.userId;
|
||||||
|
|
||||||
if (!displayName) {
|
if (!displayName) {
|
||||||
return selfUserId;
|
return selfUserId;
|
||||||
@@ -221,8 +221,8 @@ function calculateDisplayName(member, event, roomState) {
|
|||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
let userIds = roomState.getUserIdsWithDisplayName(displayName);
|
const userIds = roomState.getUserIdsWithDisplayName(displayName);
|
||||||
let otherUsers = userIds.filter(function(u) {
|
const otherUsers = userIds.filter(function(u) {
|
||||||
return u !== selfUserId;
|
return u !== selfUserId;
|
||||||
});
|
});
|
||||||
if (otherUsers.length > 0) {
|
if (otherUsers.length > 0) {
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ limitations under the License.
|
|||||||
/**
|
/**
|
||||||
* @module models/room-state
|
* @module models/room-state
|
||||||
*/
|
*/
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
|
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let RoomMember = require("./room-member");
|
const RoomMember = require("./room-member");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct room state.
|
* Construct room state.
|
||||||
@@ -100,7 +100,7 @@ RoomState.prototype.getStateEvents = function(eventType, stateKey) {
|
|||||||
if (stateKey === undefined) { // return all values
|
if (stateKey === undefined) { // return all values
|
||||||
return utils.values(this.events[eventType]);
|
return utils.values(this.events[eventType]);
|
||||||
}
|
}
|
||||||
let event = this.events[eventType][stateKey];
|
const event = this.events[eventType][stateKey];
|
||||||
return event ? event : null;
|
return event ? event : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ RoomState.prototype.getStateEvents = function(eventType, stateKey) {
|
|||||||
* @fires module:client~MatrixClient#event:"RoomState.events"
|
* @fires module:client~MatrixClient#event:"RoomState.events"
|
||||||
*/
|
*/
|
||||||
RoomState.prototype.setStateEvents = function(stateEvents) {
|
RoomState.prototype.setStateEvents = function(stateEvents) {
|
||||||
let self = this;
|
const self = this;
|
||||||
this._updateModifiedTime();
|
this._updateModifiedTime();
|
||||||
|
|
||||||
// update the core event dict
|
// update the core event dict
|
||||||
@@ -133,7 +133,7 @@ RoomState.prototype.setStateEvents = function(stateEvents) {
|
|||||||
self.events[event.getType()][event.getStateKey()] = event;
|
self.events[event.getType()][event.getStateKey()] = event;
|
||||||
if (event.getType() === "m.room.member") {
|
if (event.getType() === "m.room.member") {
|
||||||
_updateDisplayNameCache(
|
_updateDisplayNameCache(
|
||||||
self, event.getStateKey(), event.getContent().displayname
|
self, event.getStateKey(), event.getContent().displayname,
|
||||||
);
|
);
|
||||||
_updateThirdPartyTokenCache(self, event);
|
_updateThirdPartyTokenCache(self, event);
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ RoomState.prototype.setStateEvents = function(stateEvents) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event.getType() === "m.room.member") {
|
if (event.getType() === "m.room.member") {
|
||||||
let userId = event.getStateKey();
|
const userId = event.getStateKey();
|
||||||
|
|
||||||
// leave events apparently elide the displayname or avatar_url,
|
// leave events apparently elide the displayname or avatar_url,
|
||||||
// so let's fake one up so that we don't leak user ids
|
// so let's fake one up so that we don't leak user ids
|
||||||
@@ -178,11 +178,11 @@ RoomState.prototype.setStateEvents = function(stateEvents) {
|
|||||||
// so we don't make assumptions about the properties of RoomMember
|
// so we don't make assumptions about the properties of RoomMember
|
||||||
// (e.g. and manage to break it because deep copying doesn't do
|
// (e.g. and manage to break it because deep copying doesn't do
|
||||||
// everything).
|
// everything).
|
||||||
let sentinel = new RoomMember(event.getRoomId(), userId);
|
const sentinel = new RoomMember(event.getRoomId(), userId);
|
||||||
utils.forEach([member, sentinel], function(roomMember) {
|
utils.forEach([member, sentinel], function(roomMember) {
|
||||||
roomMember.setMembershipEvent(event, self);
|
roomMember.setMembershipEvent(event, self);
|
||||||
// this member may have a power level already, so set it.
|
// this member may have a power level already, so set it.
|
||||||
let pwrLvlEvent = self.getStateEvents("m.room.power_levels", "");
|
const pwrLvlEvent = self.getStateEvents("m.room.power_levels", "");
|
||||||
if (pwrLvlEvent) {
|
if (pwrLvlEvent) {
|
||||||
roomMember.setPowerLevelEvent(pwrLvlEvent);
|
roomMember.setPowerLevelEvent(pwrLvlEvent);
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ RoomState.prototype.setStateEvents = function(stateEvents) {
|
|||||||
self.members[userId] = member;
|
self.members[userId] = member;
|
||||||
self.emit("RoomState.members", event, self, member);
|
self.emit("RoomState.members", event, self, member);
|
||||||
} else if (event.getType() === "m.room.power_levels") {
|
} else if (event.getType() === "m.room.power_levels") {
|
||||||
let members = utils.values(self.members);
|
const members = utils.values(self.members);
|
||||||
utils.forEach(members, function(member) {
|
utils.forEach(members, function(member) {
|
||||||
member.setPowerLevelEvent(event);
|
member.setPowerLevelEvent(event);
|
||||||
self.emit("RoomState.members", event, self, member);
|
self.emit("RoomState.members", event, self, member);
|
||||||
@@ -312,12 +312,12 @@ RoomState.prototype.maySendStateEvent = function(stateEventType, userId) {
|
|||||||
* according to the room's state.
|
* according to the room's state.
|
||||||
*/
|
*/
|
||||||
RoomState.prototype._maySendEventOfType = function(eventType, userId, state) {
|
RoomState.prototype._maySendEventOfType = function(eventType, userId, state) {
|
||||||
let member = this.getMember(userId);
|
const member = this.getMember(userId);
|
||||||
if (!member || member.membership == 'leave') {
|
if (!member || member.membership == 'leave') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let power_levels_event = this.getStateEvents('m.room.power_levels', '');
|
const power_levels_event = this.getStateEvents('m.room.power_levels', '');
|
||||||
|
|
||||||
let power_levels;
|
let power_levels;
|
||||||
let events_levels = {};
|
let events_levels = {};
|
||||||
@@ -355,12 +355,12 @@ function _updateThirdPartyTokenCache(roomState, memberEvent) {
|
|||||||
if (!memberEvent.getContent().third_party_invite) {
|
if (!memberEvent.getContent().third_party_invite) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let token = (memberEvent.getContent().third_party_invite.signed || {}).token;
|
const token = (memberEvent.getContent().third_party_invite.signed || {}).token;
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let threePidInvite = roomState.getStateEvents(
|
const threePidInvite = roomState.getStateEvents(
|
||||||
"m.room.third_party_invite", token
|
"m.room.third_party_invite", token,
|
||||||
);
|
);
|
||||||
if (!threePidInvite) {
|
if (!threePidInvite) {
|
||||||
return;
|
return;
|
||||||
@@ -369,14 +369,14 @@ function _updateThirdPartyTokenCache(roomState, memberEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _updateDisplayNameCache(roomState, userId, displayName) {
|
function _updateDisplayNameCache(roomState, userId, displayName) {
|
||||||
let oldName = roomState._userIdsToDisplayNames[userId];
|
const oldName = roomState._userIdsToDisplayNames[userId];
|
||||||
delete roomState._userIdsToDisplayNames[userId];
|
delete roomState._userIdsToDisplayNames[userId];
|
||||||
if (oldName) {
|
if (oldName) {
|
||||||
// Remove the old name from the cache.
|
// Remove the old name from the cache.
|
||||||
// We clobber the user_id > name lookup but the name -> [user_id] lookup
|
// We clobber the user_id > name lookup but the name -> [user_id] lookup
|
||||||
// means we need to remove that user ID from that array rather than nuking
|
// means we need to remove that user ID from that array rather than nuking
|
||||||
// the lot.
|
// the lot.
|
||||||
let existingUserIds = roomState._displayNameToUserIds[oldName] || [];
|
const existingUserIds = roomState._displayNameToUserIds[oldName] || [];
|
||||||
for (let i = 0; i < existingUserIds.length; i++) {
|
for (let i = 0; i < existingUserIds.length; i++) {
|
||||||
if (existingUserIds[i] === userId) {
|
if (existingUserIds[i] === userId) {
|
||||||
// remove this user ID from this array
|
// remove this user ID from this array
|
||||||
|
|||||||
@@ -17,22 +17,22 @@ limitations under the License.
|
|||||||
/**
|
/**
|
||||||
* @module models/room
|
* @module models/room
|
||||||
*/
|
*/
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
|
|
||||||
let EventStatus = require("./event").EventStatus;
|
const EventStatus = require("./event").EventStatus;
|
||||||
let RoomSummary = require("./room-summary");
|
const RoomSummary = require("./room-summary");
|
||||||
let MatrixEvent = require("./event").MatrixEvent;
|
const MatrixEvent = require("./event").MatrixEvent;
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let ContentRepo = require("../content-repo");
|
const ContentRepo = require("../content-repo");
|
||||||
let EventTimeline = require("./event-timeline");
|
const EventTimeline = require("./event-timeline");
|
||||||
let EventTimelineSet = require("./event-timeline-set");
|
const EventTimelineSet = require("./event-timeline-set");
|
||||||
|
|
||||||
|
|
||||||
function synthesizeReceipt(userId, event, receiptType) {
|
function synthesizeReceipt(userId, event, receiptType) {
|
||||||
// console.log("synthesizing receipt for "+event.getId());
|
// console.log("synthesizing receipt for "+event.getId());
|
||||||
// This is really ugly because JS has no way to express an object literal
|
// This is really ugly because JS has no way to express an object literal
|
||||||
// where the name of a key comes from an expression
|
// where the name of a key comes from an expression
|
||||||
let fakeReceipt = {
|
const fakeReceipt = {
|
||||||
content: {},
|
content: {},
|
||||||
type: "m.receipt",
|
type: "m.receipt",
|
||||||
room_id: event.getRoomId(),
|
room_id: event.getRoomId(),
|
||||||
@@ -108,7 +108,7 @@ function Room(roomId, opts) {
|
|||||||
if (["chronological", "detached"].indexOf(opts.pendingEventOrdering) === -1) {
|
if (["chronological", "detached"].indexOf(opts.pendingEventOrdering) === -1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"opts.pendingEventOrdering MUST be either 'chronological' or " +
|
"opts.pendingEventOrdering MUST be either 'chronological' or " +
|
||||||
"'detached'. Got: '" + opts.pendingEventOrdering + "'"
|
"'detached'. Got: '" + opts.pendingEventOrdering + "'",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ Room.prototype.setUnreadNotificationCount = function(type, count) {
|
|||||||
*/
|
*/
|
||||||
Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod,
|
Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod,
|
||||||
allowDefault) {
|
allowDefault) {
|
||||||
let roomAvatarEvent = this.currentState.getStateEvents("m.room.avatar", "");
|
const roomAvatarEvent = this.currentState.getStateEvents("m.room.avatar", "");
|
||||||
if (allowDefault === undefined) {
|
if (allowDefault === undefined) {
|
||||||
allowDefault = true;
|
allowDefault = true;
|
||||||
}
|
}
|
||||||
@@ -316,14 +316,14 @@ Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod,
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null;
|
const mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null;
|
||||||
if (mainUrl) {
|
if (mainUrl) {
|
||||||
return ContentRepo.getHttpUriForMxc(
|
return ContentRepo.getHttpUriForMxc(
|
||||||
baseUrl, mainUrl, width, height, resizeMethod
|
baseUrl, mainUrl, width, height, resizeMethod,
|
||||||
);
|
);
|
||||||
} else if (allowDefault) {
|
} else if (allowDefault) {
|
||||||
return ContentRepo.getIdenticonUri(
|
return ContentRepo.getIdenticonUri(
|
||||||
baseUrl, this.roomId, width, height
|
baseUrl, this.roomId, width, height,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,15 +337,15 @@ Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod,
|
|||||||
* @return {array} The room's alias as an array of strings
|
* @return {array} The room's alias as an array of strings
|
||||||
*/
|
*/
|
||||||
Room.prototype.getAliases = function() {
|
Room.prototype.getAliases = function() {
|
||||||
let alias_strings = [];
|
const alias_strings = [];
|
||||||
|
|
||||||
let alias_events = this.currentState.getStateEvents("m.room.aliases");
|
const alias_events = this.currentState.getStateEvents("m.room.aliases");
|
||||||
if (alias_events) {
|
if (alias_events) {
|
||||||
for (let i = 0; i < alias_events.length; ++i) {
|
for (let i = 0; i < alias_events.length; ++i) {
|
||||||
let alias_event = alias_events[i];
|
const alias_event = alias_events[i];
|
||||||
if (utils.isArray(alias_event.getContent().aliases)) {
|
if (utils.isArray(alias_event.getContent().aliases)) {
|
||||||
Array.prototype.push.apply(
|
Array.prototype.push.apply(
|
||||||
alias_strings, alias_event.getContent().aliases
|
alias_strings, alias_event.getContent().aliases,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,7 +360,7 @@ Room.prototype.getAliases = function() {
|
|||||||
* @return {?string} The room's canonical alias, or null if there is none
|
* @return {?string} The room's canonical alias, or null if there is none
|
||||||
*/
|
*/
|
||||||
Room.prototype.getCanonicalAlias = function() {
|
Room.prototype.getCanonicalAlias = function() {
|
||||||
let canonicalAlias = this.currentState.getStateEvents("m.room.canonical_alias", "");
|
const canonicalAlias = this.currentState.getStateEvents("m.room.canonical_alias", "");
|
||||||
if (canonicalAlias) {
|
if (canonicalAlias) {
|
||||||
return canonicalAlias.getContent().alias;
|
return canonicalAlias.getContent().alias;
|
||||||
}
|
}
|
||||||
@@ -390,7 +390,7 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline,
|
|||||||
timeline, paginationToken) {
|
timeline, paginationToken) {
|
||||||
timeline.getTimelineSet().addEventsToTimeline(
|
timeline.getTimelineSet().addEventsToTimeline(
|
||||||
events, toStartOfTimeline,
|
events, toStartOfTimeline,
|
||||||
timeline, paginationToken
|
timeline, paginationToken,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -400,7 +400,7 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline,
|
|||||||
* @return {RoomMember} The member or <code>null</code>.
|
* @return {RoomMember} The member or <code>null</code>.
|
||||||
*/
|
*/
|
||||||
Room.prototype.getMember = function(userId) {
|
Room.prototype.getMember = function(userId) {
|
||||||
let member = this.currentState.members[userId];
|
const member = this.currentState.members[userId];
|
||||||
if (!member) {
|
if (!member) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -445,7 +445,7 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline,
|
|||||||
* @return {boolean} True if this user_id has the given membership state.
|
* @return {boolean} True if this user_id has the given membership state.
|
||||||
*/
|
*/
|
||||||
Room.prototype.hasMembershipState = function(userId, membership) {
|
Room.prototype.hasMembershipState = function(userId, membership) {
|
||||||
let member = this.getMember(userId);
|
const member = this.getMember(userId);
|
||||||
if (!member) {
|
if (!member) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -461,8 +461,8 @@ Room.prototype.getOrCreateFilteredTimelineSet = function(filter) {
|
|||||||
if (this._filteredTimelineSets[filter.filterId]) {
|
if (this._filteredTimelineSets[filter.filterId]) {
|
||||||
return this._filteredTimelineSets[filter.filterId];
|
return this._filteredTimelineSets[filter.filterId];
|
||||||
}
|
}
|
||||||
let opts = Object.assign({ filter: filter }, this._opts);
|
const opts = Object.assign({ filter: filter }, this._opts);
|
||||||
let timelineSet = new EventTimelineSet(this, opts);
|
const timelineSet = new EventTimelineSet(this, opts);
|
||||||
reEmit(this, timelineSet, ["Room.timeline", "Room.timelineReset"]);
|
reEmit(this, timelineSet, ["Room.timeline", "Room.timelineReset"]);
|
||||||
this._filteredTimelineSets[filter.filterId] = timelineSet;
|
this._filteredTimelineSets[filter.filterId] = timelineSet;
|
||||||
this._timelineSets.push(timelineSet);
|
this._timelineSets.push(timelineSet);
|
||||||
@@ -474,7 +474,7 @@ Room.prototype.getOrCreateFilteredTimelineSet = function(filter) {
|
|||||||
// may have grown huge and so take a long time to filter.
|
// may have grown huge and so take a long time to filter.
|
||||||
// see https://github.com/vector-im/vector-web/issues/2109
|
// see https://github.com/vector-im/vector-web/issues/2109
|
||||||
|
|
||||||
let unfilteredLiveTimeline = this.getLiveTimeline();
|
const unfilteredLiveTimeline = this.getLiveTimeline();
|
||||||
|
|
||||||
unfilteredLiveTimeline.getEvents().forEach(function(event) {
|
unfilteredLiveTimeline.getEvents().forEach(function(event) {
|
||||||
timelineSet.addLiveEvent(event);
|
timelineSet.addLiveEvent(event);
|
||||||
@@ -488,7 +488,7 @@ Room.prototype.getOrCreateFilteredTimelineSet = function(filter) {
|
|||||||
|
|
||||||
timelineSet.getLiveTimeline().setPaginationToken(
|
timelineSet.getLiveTimeline().setPaginationToken(
|
||||||
timeline.getPaginationToken(EventTimeline.BACKWARDS),
|
timeline.getPaginationToken(EventTimeline.BACKWARDS),
|
||||||
EventTimeline.BACKWARDS
|
EventTimeline.BACKWARDS,
|
||||||
);
|
);
|
||||||
|
|
||||||
// alternatively, we could try to do something like this to try and re-paginate
|
// alternatively, we could try to do something like this to try and re-paginate
|
||||||
@@ -508,9 +508,9 @@ Room.prototype.getOrCreateFilteredTimelineSet = function(filter) {
|
|||||||
* @param {Filter} filter the filter whose timelineSet is to be forgotten
|
* @param {Filter} filter the filter whose timelineSet is to be forgotten
|
||||||
*/
|
*/
|
||||||
Room.prototype.removeFilteredTimelineSet = function(filter) {
|
Room.prototype.removeFilteredTimelineSet = function(filter) {
|
||||||
let timelineSet = this._filteredTimelineSets[filter.filterId];
|
const timelineSet = this._filteredTimelineSets[filter.filterId];
|
||||||
delete this._filteredTimelineSets[filter.filterId];
|
delete this._filteredTimelineSets[filter.filterId];
|
||||||
let i = this._timelineSets.indexOf(timelineSet);
|
const i = this._timelineSets.indexOf(timelineSet);
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
this._timelineSets.splice(i, 1);
|
this._timelineSets.splice(i, 1);
|
||||||
}
|
}
|
||||||
@@ -528,10 +528,10 @@ Room.prototype.removeFilteredTimelineSet = function(filter) {
|
|||||||
Room.prototype._addLiveEvent = function(event, duplicateStrategy) {
|
Room.prototype._addLiveEvent = function(event, duplicateStrategy) {
|
||||||
let i;
|
let i;
|
||||||
if (event.getType() === "m.room.redaction") {
|
if (event.getType() === "m.room.redaction") {
|
||||||
let redactId = event.event.redacts;
|
const redactId = event.event.redacts;
|
||||||
|
|
||||||
// if we know about this event, redact its contents now.
|
// if we know about this event, redact its contents now.
|
||||||
let redactedEvent = this.getUnfilteredTimelineSet().findEventById(redactId);
|
const redactedEvent = this.getUnfilteredTimelineSet().findEventById(redactId);
|
||||||
if (redactedEvent) {
|
if (redactedEvent) {
|
||||||
redactedEvent.makeRedacted(event);
|
redactedEvent.makeRedacted(event);
|
||||||
this.emit("Room.redaction", event, this);
|
this.emit("Room.redaction", event, this);
|
||||||
@@ -551,7 +551,7 @@ Room.prototype._addLiveEvent = function(event, duplicateStrategy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event.getUnsigned().transaction_id) {
|
if (event.getUnsigned().transaction_id) {
|
||||||
let existingEvent = this._txnToEvent[event.getUnsigned().transaction_id];
|
const existingEvent = this._txnToEvent[event.getUnsigned().transaction_id];
|
||||||
if (existingEvent) {
|
if (existingEvent) {
|
||||||
// remote echo of an event we sent earlier
|
// remote echo of an event we sent earlier
|
||||||
this._handleRemoteEcho(event, existingEvent);
|
this._handleRemoteEcho(event, existingEvent);
|
||||||
@@ -569,7 +569,7 @@ Room.prototype._addLiveEvent = function(event, duplicateStrategy) {
|
|||||||
// pointing to an event that wasn't yet in the timeline
|
// pointing to an event that wasn't yet in the timeline
|
||||||
if (event.sender) {
|
if (event.sender) {
|
||||||
this.addReceipt(synthesizeReceipt(
|
this.addReceipt(synthesizeReceipt(
|
||||||
event.sender.userId, event, "m.read"
|
event.sender.userId, event, "m.read",
|
||||||
), true);
|
), true);
|
||||||
|
|
||||||
// Any live events from a user could be taken as implicit
|
// Any live events from a user could be taken as implicit
|
||||||
@@ -616,7 +616,7 @@ Room.prototype.addPendingEvent = function(event, txnId) {
|
|||||||
EventTimeline.setEventMetadata(
|
EventTimeline.setEventMetadata(
|
||||||
event,
|
event,
|
||||||
this.getLiveTimeline().getState(EventTimeline.FORWARDS),
|
this.getLiveTimeline().getState(EventTimeline.FORWARDS),
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
this._txnToEvent[txnId] = event;
|
this._txnToEvent[txnId] = event;
|
||||||
@@ -625,7 +625,7 @@ Room.prototype.addPendingEvent = function(event, txnId) {
|
|||||||
this._pendingEventList.push(event);
|
this._pendingEventList.push(event);
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < this._timelineSets.length; i++) {
|
for (let i = 0; i < this._timelineSets.length; i++) {
|
||||||
let timelineSet = this._timelineSets[i];
|
const timelineSet = this._timelineSets[i];
|
||||||
if (timelineSet.getFilter()) {
|
if (timelineSet.getFilter()) {
|
||||||
if (this._filter.filterRoomTimeline([event]).length) {
|
if (this._filter.filterRoomTimeline([event]).length) {
|
||||||
timelineSet.addEventToTimeline(event,
|
timelineSet.addEventToTimeline(event,
|
||||||
@@ -656,9 +656,9 @@ Room.prototype.addPendingEvent = function(event, txnId) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Room.prototype._handleRemoteEcho = function(remoteEvent, localEvent) {
|
Room.prototype._handleRemoteEcho = function(remoteEvent, localEvent) {
|
||||||
let oldEventId = localEvent.getId();
|
const oldEventId = localEvent.getId();
|
||||||
let newEventId = remoteEvent.getId();
|
const newEventId = remoteEvent.getId();
|
||||||
let oldStatus = localEvent.status;
|
const oldStatus = localEvent.status;
|
||||||
|
|
||||||
// no longer pending
|
// no longer pending
|
||||||
delete this._txnToEvent[remoteEvent.transaction_id];
|
delete this._txnToEvent[remoteEvent.transaction_id];
|
||||||
@@ -669,7 +669,7 @@ Room.prototype._handleRemoteEcho = function(remoteEvent, localEvent) {
|
|||||||
this._pendingEventList,
|
this._pendingEventList,
|
||||||
function(ev) {
|
function(ev) {
|
||||||
return ev.getId() == oldEventId;
|
return ev.getId() == oldEventId;
|
||||||
}, false
|
}, false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,7 +678,7 @@ Room.prototype._handleRemoteEcho = function(remoteEvent, localEvent) {
|
|||||||
localEvent.handleRemoteEcho(remoteEvent.event);
|
localEvent.handleRemoteEcho(remoteEvent.event);
|
||||||
|
|
||||||
for (let i = 0; i < this._timelineSets.length; i++) {
|
for (let i = 0; i < this._timelineSets.length; i++) {
|
||||||
let timelineSet = this._timelineSets[i];
|
const timelineSet = this._timelineSets[i];
|
||||||
|
|
||||||
// if it's already in the timeline, update the timeline map. If it's not, add it.
|
// if it's already in the timeline, update the timeline map. If it's not, add it.
|
||||||
timelineSet.handleRemoteEcho(localEvent, oldEventId, newEventId);
|
timelineSet.handleRemoteEcho(localEvent, oldEventId, newEventId);
|
||||||
@@ -690,7 +690,7 @@ Room.prototype._handleRemoteEcho = function(remoteEvent, localEvent) {
|
|||||||
|
|
||||||
/* a map from current event status to a list of allowed next statuses
|
/* a map from current event status to a list of allowed next statuses
|
||||||
*/
|
*/
|
||||||
let ALLOWED_TRANSITIONS = {};
|
const ALLOWED_TRANSITIONS = {};
|
||||||
|
|
||||||
ALLOWED_TRANSITIONS[EventStatus.ENCRYPTING] = [
|
ALLOWED_TRANSITIONS[EventStatus.ENCRYPTING] = [
|
||||||
EventStatus.SENDING,
|
EventStatus.SENDING,
|
||||||
@@ -737,7 +737,7 @@ Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) {
|
|||||||
|
|
||||||
// SENT races against /sync, so we have to special-case it.
|
// SENT races against /sync, so we have to special-case it.
|
||||||
if (newStatus == EventStatus.SENT) {
|
if (newStatus == EventStatus.SENT) {
|
||||||
let timeline = this.getUnfilteredTimelineSet().eventIdToTimeline(newEventId);
|
const timeline = this.getUnfilteredTimelineSet().eventIdToTimeline(newEventId);
|
||||||
if (timeline) {
|
if (timeline) {
|
||||||
// we've already received the event via the event stream.
|
// we've already received the event via the event stream.
|
||||||
// nothing more to do here.
|
// nothing more to do here.
|
||||||
@@ -745,15 +745,15 @@ Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldStatus = event.status;
|
const oldStatus = event.status;
|
||||||
let oldEventId = event.getId();
|
const oldEventId = event.getId();
|
||||||
|
|
||||||
if (!oldStatus) {
|
if (!oldStatus) {
|
||||||
throw new Error("updatePendingEventStatus called on an event which is " +
|
throw new Error("updatePendingEventStatus called on an event which is " +
|
||||||
"not a local echo.");
|
"not a local echo.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowed = ALLOWED_TRANSITIONS[oldStatus];
|
const allowed = ALLOWED_TRANSITIONS[oldStatus];
|
||||||
if (!allowed || allowed.indexOf(newStatus) < 0) {
|
if (!allowed || allowed.indexOf(newStatus) < 0) {
|
||||||
throw new Error("Invalid EventStatus transition " + oldStatus + "->" +
|
throw new Error("Invalid EventStatus transition " + oldStatus + "->" +
|
||||||
newStatus);
|
newStatus);
|
||||||
@@ -778,7 +778,7 @@ Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) {
|
|||||||
this._pendingEventList,
|
this._pendingEventList,
|
||||||
function(ev) {
|
function(ev) {
|
||||||
return ev.getId() == oldEventId;
|
return ev.getId() == oldEventId;
|
||||||
}, false
|
}, false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.removeEvent(oldEventId);
|
this.removeEvent(oldEventId);
|
||||||
@@ -812,17 +812,17 @@ Room.prototype.addLiveEvents = function(events, duplicateStrategy) {
|
|||||||
|
|
||||||
// sanity check that the live timeline is still live
|
// sanity check that the live timeline is still live
|
||||||
for (i = 0; i < this._timelineSets.length; i++) {
|
for (i = 0; i < this._timelineSets.length; i++) {
|
||||||
let liveTimeline = this._timelineSets[i].getLiveTimeline();
|
const liveTimeline = this._timelineSets[i].getLiveTimeline();
|
||||||
if (liveTimeline.getPaginationToken(EventTimeline.FORWARDS)) {
|
if (liveTimeline.getPaginationToken(EventTimeline.FORWARDS)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"live timeline " + i + " is no longer live - it has a pagination token " +
|
"live timeline " + i + " is no longer live - it has a pagination token " +
|
||||||
"(" + liveTimeline.getPaginationToken(EventTimeline.FORWARDS) + ")"
|
"(" + liveTimeline.getPaginationToken(EventTimeline.FORWARDS) + ")",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (liveTimeline.getNeighbouringTimeline(EventTimeline.FORWARDS)) {
|
if (liveTimeline.getNeighbouringTimeline(EventTimeline.FORWARDS)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"live timeline " + i + " is no longer live - " +
|
"live timeline " + i + " is no longer live - " +
|
||||||
"it has a neighbouring timeline"
|
"it has a neighbouring timeline",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -863,7 +863,7 @@ Room.prototype.removeEvents = function(event_ids) {
|
|||||||
Room.prototype.removeEvent = function(eventId) {
|
Room.prototype.removeEvent = function(eventId) {
|
||||||
let removedAny = false;
|
let removedAny = false;
|
||||||
for (let i = 0; i < this._timelineSets.length; i++) {
|
for (let i = 0; i < this._timelineSets.length; i++) {
|
||||||
let removed = this._timelineSets[i].removeEvent(eventId);
|
const removed = this._timelineSets[i].removeEvent(eventId);
|
||||||
if (removed) {
|
if (removed) {
|
||||||
removedAny = true;
|
removedAny = true;
|
||||||
}
|
}
|
||||||
@@ -882,15 +882,15 @@ Room.prototype.removeEvent = function(eventId) {
|
|||||||
Room.prototype.recalculate = function(userId) {
|
Room.prototype.recalculate = function(userId) {
|
||||||
// set fake stripped state events if this is an invite room so logic remains
|
// set fake stripped state events if this is an invite room so logic remains
|
||||||
// consistent elsewhere.
|
// consistent elsewhere.
|
||||||
let self = this;
|
const self = this;
|
||||||
let membershipEvent = this.currentState.getStateEvents(
|
const membershipEvent = this.currentState.getStateEvents(
|
||||||
"m.room.member", userId
|
"m.room.member", userId,
|
||||||
);
|
);
|
||||||
if (membershipEvent && membershipEvent.getContent().membership === "invite") {
|
if (membershipEvent && membershipEvent.getContent().membership === "invite") {
|
||||||
let strippedStateEvents = membershipEvent.event.invite_room_state || [];
|
const strippedStateEvents = membershipEvent.event.invite_room_state || [];
|
||||||
utils.forEach(strippedStateEvents, function(strippedEvent) {
|
utils.forEach(strippedStateEvents, function(strippedEvent) {
|
||||||
let existingEvent = self.currentState.getStateEvents(
|
const existingEvent = self.currentState.getStateEvents(
|
||||||
strippedEvent.type, strippedEvent.state_key
|
strippedEvent.type, strippedEvent.state_key,
|
||||||
);
|
);
|
||||||
if (!existingEvent) {
|
if (!existingEvent) {
|
||||||
// set the fake stripped event instead
|
// set the fake stripped event instead
|
||||||
@@ -906,7 +906,7 @@ Room.prototype.recalculate = function(userId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldName = this.name;
|
const oldName = this.name;
|
||||||
this.name = calculateRoomName(this, userId);
|
this.name = calculateRoomName(this, userId);
|
||||||
this.summary = new RoomSummary(this.roomId, {
|
this.summary = new RoomSummary(this.roomId, {
|
||||||
title: this.name,
|
title: this.name,
|
||||||
@@ -1004,18 +1004,18 @@ Room.prototype.addReceipt = function(event, fake) {
|
|||||||
* @param {Object} receipts The object to add receipts to
|
* @param {Object} receipts The object to add receipts to
|
||||||
*/
|
*/
|
||||||
Room.prototype._addReceiptsToStructure = function(event, receipts) {
|
Room.prototype._addReceiptsToStructure = function(event, receipts) {
|
||||||
let self = this;
|
const self = this;
|
||||||
utils.keys(event.getContent()).forEach(function(eventId) {
|
utils.keys(event.getContent()).forEach(function(eventId) {
|
||||||
utils.keys(event.getContent()[eventId]).forEach(function(receiptType) {
|
utils.keys(event.getContent()[eventId]).forEach(function(receiptType) {
|
||||||
utils.keys(event.getContent()[eventId][receiptType]).forEach(
|
utils.keys(event.getContent()[eventId][receiptType]).forEach(
|
||||||
function(userId) {
|
function(userId) {
|
||||||
let receipt = event.getContent()[eventId][receiptType][userId];
|
const receipt = event.getContent()[eventId][receiptType][userId];
|
||||||
|
|
||||||
if (!receipts[receiptType]) {
|
if (!receipts[receiptType]) {
|
||||||
receipts[receiptType] = {};
|
receipts[receiptType] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
let existingReceipt = receipts[receiptType][userId];
|
const existingReceipt = receipts[receiptType][userId];
|
||||||
|
|
||||||
if (!existingReceipt) {
|
if (!existingReceipt) {
|
||||||
receipts[receiptType][userId] = {};
|
receipts[receiptType][userId] = {};
|
||||||
@@ -1024,7 +1024,7 @@ Room.prototype._addReceiptsToStructure = function(event, receipts) {
|
|||||||
// than the one we already have. (This is managed
|
// than the one we already have. (This is managed
|
||||||
// server-side, but because we synthesize RRs locally we
|
// server-side, but because we synthesize RRs locally we
|
||||||
// have to do it here too.)
|
// have to do it here too.)
|
||||||
let ordering = self.getUnfilteredTimelineSet().compareEventOrdering(
|
const ordering = self.getUnfilteredTimelineSet().compareEventOrdering(
|
||||||
existingReceipt.eventId, eventId);
|
existingReceipt.eventId, eventId);
|
||||||
if (ordering !== null && ordering >= 0) {
|
if (ordering !== null && ordering >= 0) {
|
||||||
return;
|
return;
|
||||||
@@ -1046,10 +1046,10 @@ Room.prototype._addReceiptsToStructure = function(event, receipts) {
|
|||||||
* @return {Object} Map of receipts by event ID
|
* @return {Object} Map of receipts by event ID
|
||||||
*/
|
*/
|
||||||
Room.prototype._buildReceiptCache = function(receipts) {
|
Room.prototype._buildReceiptCache = function(receipts) {
|
||||||
let receiptCacheByEventId = {};
|
const receiptCacheByEventId = {};
|
||||||
utils.keys(receipts).forEach(function(receiptType) {
|
utils.keys(receipts).forEach(function(receiptType) {
|
||||||
utils.keys(receipts[receiptType]).forEach(function(userId) {
|
utils.keys(receipts[receiptType]).forEach(function(userId) {
|
||||||
let receipt = receipts[receiptType][userId];
|
const receipt = receipts[receiptType][userId];
|
||||||
if (!receiptCacheByEventId[receipt.eventId]) {
|
if (!receiptCacheByEventId[receipt.eventId]) {
|
||||||
receiptCacheByEventId[receipt.eventId] = [];
|
receiptCacheByEventId[receipt.eventId] = [];
|
||||||
}
|
}
|
||||||
@@ -1102,7 +1102,7 @@ Room.prototype.addTags = function(event) {
|
|||||||
*/
|
*/
|
||||||
Room.prototype.addAccountData = function(events) {
|
Room.prototype.addAccountData = function(events) {
|
||||||
for (let i = 0; i < events.length; i++) {
|
for (let i = 0; i < events.length; i++) {
|
||||||
let event = events[i];
|
const event = events[i];
|
||||||
if (event.getType() === "m.tag") {
|
if (event.getType() === "m.tag") {
|
||||||
this.addTags(event);
|
this.addTags(event);
|
||||||
}
|
}
|
||||||
@@ -1134,7 +1134,7 @@ function calculateRoomName(room, userId, ignoreRoomNameEvent) {
|
|||||||
if (!ignoreRoomNameEvent) {
|
if (!ignoreRoomNameEvent) {
|
||||||
// check for an alias, if any. for now, assume first alias is the
|
// check for an alias, if any. for now, assume first alias is the
|
||||||
// official one.
|
// official one.
|
||||||
let mRoomName = room.currentState.getStateEvents("m.room.name", "");
|
const mRoomName = room.currentState.getStateEvents("m.room.name", "");
|
||||||
if (mRoomName && mRoomName.getContent() && mRoomName.getContent().name) {
|
if (mRoomName && mRoomName.getContent() && mRoomName.getContent().name) {
|
||||||
return mRoomName.getContent().name;
|
return mRoomName.getContent().name;
|
||||||
}
|
}
|
||||||
@@ -1143,7 +1143,7 @@ function calculateRoomName(room, userId, ignoreRoomNameEvent) {
|
|||||||
let alias = room.getCanonicalAlias();
|
let alias = room.getCanonicalAlias();
|
||||||
|
|
||||||
if (!alias) {
|
if (!alias) {
|
||||||
let aliases = room.getAliases();
|
const aliases = room.getAliases();
|
||||||
|
|
||||||
if (aliases.length) {
|
if (aliases.length) {
|
||||||
alias = aliases[0];
|
alias = aliases[0];
|
||||||
@@ -1154,16 +1154,16 @@ function calculateRoomName(room, userId, ignoreRoomNameEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get members that are NOT ourselves and are actually in the room.
|
// get members that are NOT ourselves and are actually in the room.
|
||||||
let otherMembers = utils.filter(room.currentState.getMembers(), function(m) {
|
const otherMembers = utils.filter(room.currentState.getMembers(), function(m) {
|
||||||
return (m.userId !== userId && m.membership !== "leave");
|
return (m.userId !== userId && m.membership !== "leave");
|
||||||
});
|
});
|
||||||
let allMembers = utils.filter(room.currentState.getMembers(), function(m) {
|
const allMembers = utils.filter(room.currentState.getMembers(), function(m) {
|
||||||
return (m.membership !== "leave");
|
return (m.membership !== "leave");
|
||||||
});
|
});
|
||||||
let myMemberEventArray = utils.filter(room.currentState.getMembers(), function(m) {
|
const myMemberEventArray = utils.filter(room.currentState.getMembers(), function(m) {
|
||||||
return (m.userId == userId);
|
return (m.userId == userId);
|
||||||
});
|
});
|
||||||
let myMemberEvent = (
|
const myMemberEvent = (
|
||||||
(myMemberEventArray.length && myMemberEventArray[0].events) ?
|
(myMemberEventArray.length && myMemberEventArray[0].events) ?
|
||||||
myMemberEventArray[0].events.member.event : undefined
|
myMemberEventArray[0].events.member.event : undefined
|
||||||
);
|
);
|
||||||
@@ -1173,7 +1173,7 @@ function calculateRoomName(room, userId, ignoreRoomNameEvent) {
|
|||||||
if (room.currentState.getMember(myMemberEvent.sender)) {
|
if (room.currentState.getMember(myMemberEvent.sender)) {
|
||||||
// extract who invited us to the room
|
// extract who invited us to the room
|
||||||
return "Invite from " + room.currentState.getMember(
|
return "Invite from " + room.currentState.getMember(
|
||||||
myMemberEvent.sender
|
myMemberEvent.sender,
|
||||||
).name;
|
).name;
|
||||||
} else if (allMembers[0].events.member) {
|
} else if (allMembers[0].events.member) {
|
||||||
// use the sender field from the invite event, although this only
|
// use the sender field from the invite event, although this only
|
||||||
@@ -1190,7 +1190,7 @@ function calculateRoomName(room, userId, ignoreRoomNameEvent) {
|
|||||||
// self-chat, peeked room with 1 participant,
|
// self-chat, peeked room with 1 participant,
|
||||||
// or inbound invite, or outbound 3PID invite.
|
// or inbound invite, or outbound 3PID invite.
|
||||||
if (allMembers[0].userId === userId) {
|
if (allMembers[0].userId === userId) {
|
||||||
let thirdPartyInvites =
|
const thirdPartyInvites =
|
||||||
room.currentState.getStateEvents("m.room.third_party_invite");
|
room.currentState.getStateEvents("m.room.third_party_invite");
|
||||||
if (thirdPartyInvites && thirdPartyInvites.length > 0) {
|
if (thirdPartyInvites && thirdPartyInvites.length > 0) {
|
||||||
let name = "Inviting " +
|
let name = "Inviting " +
|
||||||
@@ -1238,7 +1238,7 @@ function reEmit(reEmitEntity, emittableEntity, eventNames) {
|
|||||||
// Transformation Example:
|
// Transformation Example:
|
||||||
// listener on "foo" => function(a,b) { ... }
|
// listener on "foo" => function(a,b) { ... }
|
||||||
// Re-emit on "thing" => thing.emit("foo", a, b)
|
// Re-emit on "thing" => thing.emit("foo", a, b)
|
||||||
let newArgs = [eventName];
|
const newArgs = [eventName];
|
||||||
for (let i = 0; i < arguments.length; i++) {
|
for (let i = 0; i < arguments.length; i++) {
|
||||||
newArgs.push(arguments[i]);
|
newArgs.push(arguments[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ limitations under the License.
|
|||||||
* @module models/search-result
|
* @module models/search-result
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let EventContext = require("./event-context");
|
const EventContext = require("./event-context");
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new SearchResult
|
* Construct a new SearchResult
|
||||||
@@ -45,11 +45,11 @@ function SearchResult(rank, eventContext) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SearchResult.fromJson = function(jsonObj, eventMapper) {
|
SearchResult.fromJson = function(jsonObj, eventMapper) {
|
||||||
let jsonContext = jsonObj.context || {};
|
const jsonContext = jsonObj.context || {};
|
||||||
let events_before = jsonContext.events_before || [];
|
const events_before = jsonContext.events_before || [];
|
||||||
let events_after = jsonContext.events_after || [];
|
const events_after = jsonContext.events_after || [];
|
||||||
|
|
||||||
let context = new EventContext(eventMapper(jsonObj.result));
|
const context = new EventContext(eventMapper(jsonObj.result));
|
||||||
|
|
||||||
context.setPaginateToken(jsonContext.start, true);
|
context.setPaginateToken(jsonContext.start, true);
|
||||||
context.addEvents(utils.map(events_before, eventMapper), true);
|
context.addEvents(utils.map(events_before, eventMapper), true);
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ limitations under the License.
|
|||||||
/**
|
/**
|
||||||
* @module models/user
|
* @module models/user
|
||||||
*/
|
*/
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new User. A User must have an ID and can optionally have extra
|
* Construct a new User. A User must have an ID and can optionally have extra
|
||||||
@@ -73,10 +73,10 @@ User.prototype.setPresenceEvent = function(event) {
|
|||||||
if (event.getType() !== "m.presence") {
|
if (event.getType() !== "m.presence") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let firstFire = this.events.presence === null;
|
const firstFire = this.events.presence === null;
|
||||||
this.events.presence = event;
|
this.events.presence = event;
|
||||||
|
|
||||||
let eventsToFire = [];
|
const eventsToFire = [];
|
||||||
if (event.getContent().presence !== this.presence || firstFire) {
|
if (event.getContent().presence !== this.presence || firstFire) {
|
||||||
eventsToFire.push("User.presence");
|
eventsToFire.push("User.presence");
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ User.prototype.setPresenceEvent = function(event) {
|
|||||||
* @param {string} name The new display name.
|
* @param {string} name The new display name.
|
||||||
*/
|
*/
|
||||||
User.prototype.setDisplayName = function(name) {
|
User.prototype.setDisplayName = function(name) {
|
||||||
let oldName = this.displayName;
|
const oldName = this.displayName;
|
||||||
this.displayName = name;
|
this.displayName = name;
|
||||||
if (name !== oldName) {
|
if (name !== oldName) {
|
||||||
this._updateModifiedTime();
|
this._updateModifiedTime();
|
||||||
@@ -146,7 +146,7 @@ User.prototype.setRawDisplayName = function(name) {
|
|||||||
* @param {string} url The new avatar URL.
|
* @param {string} url The new avatar URL.
|
||||||
*/
|
*/
|
||||||
User.prototype.setAvatarUrl = function(url) {
|
User.prototype.setAvatarUrl = function(url) {
|
||||||
let oldUrl = this.avatarUrl;
|
const oldUrl = this.avatarUrl;
|
||||||
this.avatarUrl = url;
|
this.avatarUrl = url;
|
||||||
if (url !== oldUrl) {
|
if (url !== oldUrl) {
|
||||||
this._updateModifiedTime();
|
this._updateModifiedTime();
|
||||||
|
|||||||
@@ -23,25 +23,25 @@ limitations under the License.
|
|||||||
* @param {Object} client The Matrix client object to use
|
* @param {Object} client The Matrix client object to use
|
||||||
*/
|
*/
|
||||||
function PushProcessor(client) {
|
function PushProcessor(client) {
|
||||||
let escapeRegExp = function(string) {
|
const escapeRegExp = function(string) {
|
||||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
};
|
};
|
||||||
|
|
||||||
let matchingRuleFromKindSet = function(ev, kindset, device) {
|
const matchingRuleFromKindSet = function(ev, kindset, device) {
|
||||||
let rulekinds_in_order = ['override', 'content', 'room', 'sender', 'underride'];
|
const rulekinds_in_order = ['override', 'content', 'room', 'sender', 'underride'];
|
||||||
for (let ruleKindIndex = 0;
|
for (let ruleKindIndex = 0;
|
||||||
ruleKindIndex < rulekinds_in_order.length;
|
ruleKindIndex < rulekinds_in_order.length;
|
||||||
++ruleKindIndex) {
|
++ruleKindIndex) {
|
||||||
let kind = rulekinds_in_order[ruleKindIndex];
|
const kind = rulekinds_in_order[ruleKindIndex];
|
||||||
let ruleset = kindset[kind];
|
const ruleset = kindset[kind];
|
||||||
|
|
||||||
for (let ruleIndex = 0; ruleIndex < ruleset.length; ++ruleIndex) {
|
for (let ruleIndex = 0; ruleIndex < ruleset.length; ++ruleIndex) {
|
||||||
let rule = ruleset[ruleIndex];
|
const rule = ruleset[ruleIndex];
|
||||||
if (!rule.enabled) {
|
if (!rule.enabled) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rawrule = templateRuleToRaw(kind, rule, device);
|
const rawrule = templateRuleToRaw(kind, rule, device);
|
||||||
if (!rawrule) {
|
if (!rawrule) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -55,8 +55,8 @@ function PushProcessor(client) {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
let templateRuleToRaw = function(kind, tprule, device) {
|
const templateRuleToRaw = function(kind, tprule, device) {
|
||||||
let rawrule = {
|
const rawrule = {
|
||||||
'rule_id': tprule.rule_id,
|
'rule_id': tprule.rule_id,
|
||||||
'actions': tprule.actions,
|
'actions': tprule.actions,
|
||||||
'conditions': [],
|
'conditions': [],
|
||||||
@@ -106,18 +106,18 @@ function PushProcessor(client) {
|
|||||||
return rawrule;
|
return rawrule;
|
||||||
};
|
};
|
||||||
|
|
||||||
let ruleMatchesEvent = function(rule, ev) {
|
const ruleMatchesEvent = function(rule, ev) {
|
||||||
let ret = true;
|
let ret = true;
|
||||||
for (let i = 0; i < rule.conditions.length; ++i) {
|
for (let i = 0; i < rule.conditions.length; ++i) {
|
||||||
let cond = rule.conditions[i];
|
const cond = rule.conditions[i];
|
||||||
ret &= eventFulfillsCondition(cond, ev);
|
ret &= eventFulfillsCondition(cond, ev);
|
||||||
}
|
}
|
||||||
//console.log("Rule "+rule.rule_id+(ret ? " matches" : " doesn't match"));
|
//console.log("Rule "+rule.rule_id+(ret ? " matches" : " doesn't match"));
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
let eventFulfillsCondition = function(cond, ev) {
|
const eventFulfillsCondition = function(cond, ev) {
|
||||||
let condition_functions = {
|
const condition_functions = {
|
||||||
"event_match": eventFulfillsEventMatchCondition,
|
"event_match": eventFulfillsEventMatchCondition,
|
||||||
"device": eventFulfillsDeviceCondition,
|
"device": eventFulfillsDeviceCondition,
|
||||||
"contains_display_name": eventFulfillsDisplayNameCondition,
|
"contains_display_name": eventFulfillsDisplayNameCondition,
|
||||||
@@ -129,26 +129,26 @@ function PushProcessor(client) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
let eventFulfillsRoomMemberCountCondition = function(cond, ev) {
|
const eventFulfillsRoomMemberCountCondition = function(cond, ev) {
|
||||||
if (!cond.is) {
|
if (!cond.is) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let room = client.getRoom(ev.getRoomId());
|
const room = client.getRoom(ev.getRoomId());
|
||||||
if (!room || !room.currentState || !room.currentState.members) {
|
if (!room || !room.currentState || !room.currentState.members) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let memberCount = Object.keys(room.currentState.members).filter(function(m) {
|
const memberCount = Object.keys(room.currentState.members).filter(function(m) {
|
||||||
return room.currentState.members[m].membership == 'join';
|
return room.currentState.members[m].membership == 'join';
|
||||||
}).length;
|
}).length;
|
||||||
|
|
||||||
let m = cond.is.match(/^([=<>]*)([0-9]*)$/);
|
const m = cond.is.match(/^([=<>]*)([0-9]*)$/);
|
||||||
if (!m) {
|
if (!m) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let ineq = m[1];
|
const ineq = m[1];
|
||||||
let rhs = parseInt(m[2]);
|
const rhs = parseInt(m[2]);
|
||||||
if (isNaN(rhs)) {
|
if (isNaN(rhs)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -169,32 +169,32 @@ function PushProcessor(client) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let eventFulfillsDisplayNameCondition = function(cond, ev) {
|
const eventFulfillsDisplayNameCondition = function(cond, ev) {
|
||||||
let content = ev.getContent();
|
const content = ev.getContent();
|
||||||
if (!content || !content.body || typeof content.body != 'string') {
|
if (!content || !content.body || typeof content.body != 'string') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let room = client.getRoom(ev.getRoomId());
|
const room = client.getRoom(ev.getRoomId());
|
||||||
if (!room || !room.currentState || !room.currentState.members ||
|
if (!room || !room.currentState || !room.currentState.members ||
|
||||||
!room.currentState.getMember(client.credentials.userId)) {
|
!room.currentState.getMember(client.credentials.userId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let displayName = room.currentState.getMember(client.credentials.userId).name;
|
const displayName = room.currentState.getMember(client.credentials.userId).name;
|
||||||
|
|
||||||
// N.B. we can't use \b as it chokes on unicode. however \W seems to be okay
|
// N.B. we can't use \b as it chokes on unicode. however \W seems to be okay
|
||||||
// as shorthand for [^0-9A-Za-z_].
|
// as shorthand for [^0-9A-Za-z_].
|
||||||
let pat = new RegExp("(^|\\W)" + escapeRegExp(displayName) + "(\\W|$)", 'i');
|
const pat = new RegExp("(^|\\W)" + escapeRegExp(displayName) + "(\\W|$)", 'i');
|
||||||
return content.body.search(pat) > -1;
|
return content.body.search(pat) > -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
let eventFulfillsDeviceCondition = function(cond, ev) {
|
const eventFulfillsDeviceCondition = function(cond, ev) {
|
||||||
return false; // XXX: Allow a profile tag to be set for the web client instance
|
return false; // XXX: Allow a profile tag to be set for the web client instance
|
||||||
};
|
};
|
||||||
|
|
||||||
let eventFulfillsEventMatchCondition = function(cond, ev) {
|
const eventFulfillsEventMatchCondition = function(cond, ev) {
|
||||||
let val = valueForDottedKey(cond.key, ev);
|
const val = valueForDottedKey(cond.key, ev);
|
||||||
if (!val || typeof val != 'string') {
|
if (!val || typeof val != 'string') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -205,11 +205,11 @@ function PushProcessor(client) {
|
|||||||
} else {
|
} else {
|
||||||
pat = '^' + globToRegexp(cond.pattern) + '$';
|
pat = '^' + globToRegexp(cond.pattern) + '$';
|
||||||
}
|
}
|
||||||
let regex = new RegExp(pat, 'i');
|
const regex = new RegExp(pat, 'i');
|
||||||
return !!val.match(regex);
|
return !!val.match(regex);
|
||||||
};
|
};
|
||||||
|
|
||||||
let globToRegexp = function(glob) {
|
const globToRegexp = function(glob) {
|
||||||
// From
|
// From
|
||||||
// https://github.com/matrix-org/synapse/blob/abbee6b29be80a77e05730707602f3bbfc3f38cb/synapse/push/__init__.py#L132
|
// https://github.com/matrix-org/synapse/blob/abbee6b29be80a77e05730707602f3bbfc3f38cb/synapse/push/__init__.py#L132
|
||||||
// Because micromatch is about 130KB with dependencies,
|
// Because micromatch is about 130KB with dependencies,
|
||||||
@@ -218,19 +218,19 @@ function PushProcessor(client) {
|
|||||||
pat = pat.replace(/\\\*/, '.*');
|
pat = pat.replace(/\\\*/, '.*');
|
||||||
pat = pat.replace(/\?/, '.');
|
pat = pat.replace(/\?/, '.');
|
||||||
pat = pat.replace(/\\\[(!|)(.*)\\]/, function(match, p1, p2, offset, string) {
|
pat = pat.replace(/\\\[(!|)(.*)\\]/, function(match, p1, p2, offset, string) {
|
||||||
let first = p1 && '^' || '';
|
const first = p1 && '^' || '';
|
||||||
let second = p2.replace(/\\\-/, '-');
|
const second = p2.replace(/\\\-/, '-');
|
||||||
return '[' + first + second + ']';
|
return '[' + first + second + ']';
|
||||||
});
|
});
|
||||||
return pat;
|
return pat;
|
||||||
};
|
};
|
||||||
|
|
||||||
let valueForDottedKey = function(key, ev) {
|
const valueForDottedKey = function(key, ev) {
|
||||||
let parts = key.split('.');
|
const parts = key.split('.');
|
||||||
let val;
|
let val;
|
||||||
|
|
||||||
// special-case the first component to deal with encrypted messages
|
// special-case the first component to deal with encrypted messages
|
||||||
let firstPart = parts[0];
|
const firstPart = parts[0];
|
||||||
if (firstPart == 'content') {
|
if (firstPart == 'content') {
|
||||||
val = ev.getContent();
|
val = ev.getContent();
|
||||||
parts.shift();
|
parts.shift();
|
||||||
@@ -243,7 +243,7 @@ function PushProcessor(client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (parts.length > 0) {
|
while (parts.length > 0) {
|
||||||
let thispart = parts.shift();
|
const thispart = parts.shift();
|
||||||
if (!val[thispart]) {
|
if (!val[thispart]) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,7 @@ function PushProcessor(client) {
|
|||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
|
|
||||||
let matchingRuleForEventWithRulesets = function(ev, rulesets) {
|
const matchingRuleForEventWithRulesets = function(ev, rulesets) {
|
||||||
if (!rulesets || !rulesets.device) {
|
if (!rulesets || !rulesets.device) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -260,12 +260,12 @@ function PushProcessor(client) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let allDevNames = Object.keys(rulesets.device);
|
const allDevNames = Object.keys(rulesets.device);
|
||||||
for (let i = 0; i < allDevNames.length; ++i) {
|
for (let i = 0; i < allDevNames.length; ++i) {
|
||||||
let devname = allDevNames[i];
|
const devname = allDevNames[i];
|
||||||
let devrules = rulesets.device[devname];
|
const devrules = rulesets.device[devname];
|
||||||
|
|
||||||
let matchingRule = matchingRuleFromKindSet(devrules, devname);
|
const matchingRule = matchingRuleFromKindSet(devrules, devname);
|
||||||
if (matchingRule) {
|
if (matchingRule) {
|
||||||
return matchingRule;
|
return matchingRule;
|
||||||
}
|
}
|
||||||
@@ -273,13 +273,13 @@ function PushProcessor(client) {
|
|||||||
return matchingRuleFromKindSet(ev, rulesets.global);
|
return matchingRuleFromKindSet(ev, rulesets.global);
|
||||||
};
|
};
|
||||||
|
|
||||||
let pushActionsForEventAndRulesets = function(ev, rulesets) {
|
const pushActionsForEventAndRulesets = function(ev, rulesets) {
|
||||||
let rule = matchingRuleForEventWithRulesets(ev, rulesets);
|
const rule = matchingRuleForEventWithRulesets(ev, rulesets);
|
||||||
if (!rule) {
|
if (!rule) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
let actionObj = PushProcessor.actionListToActionsObject(rule.actions);
|
const actionObj = PushProcessor.actionListToActionsObject(rule.actions);
|
||||||
|
|
||||||
// Some actions are implicit in some situations: we add those here
|
// Some actions are implicit in some situations: we add those here
|
||||||
if (actionObj.tweaks.highlight === undefined) {
|
if (actionObj.tweaks.highlight === undefined) {
|
||||||
@@ -312,9 +312,9 @@ function PushProcessor(client) {
|
|||||||
* @return {object} A object with key 'notify' (true or false) and an object of actions
|
* @return {object} A object with key 'notify' (true or false) and an object of actions
|
||||||
*/
|
*/
|
||||||
PushProcessor.actionListToActionsObject = function(actionlist) {
|
PushProcessor.actionListToActionsObject = function(actionlist) {
|
||||||
let actionobj = { 'notify': false, 'tweaks': {} };
|
const actionobj = { 'notify': false, 'tweaks': {} };
|
||||||
for (let i = 0; i < actionlist.length; ++i) {
|
for (let i = 0; i < actionlist.length; ++i) {
|
||||||
let action = actionlist[i];
|
const action = actionlist[i];
|
||||||
if (action === 'notify') {
|
if (action === 'notify') {
|
||||||
actionobj.notify = true;
|
actionobj.notify = true;
|
||||||
} else if (typeof action === 'object') {
|
} else if (typeof action === 'object') {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ limitations under the License.
|
|||||||
|
|
||||||
// we schedule a callback at least this often, to check if we've missed out on
|
// we schedule a callback at least this often, to check if we've missed out on
|
||||||
// some wall-clock time due to being suspended.
|
// some wall-clock time due to being suspended.
|
||||||
let TIMER_CHECK_PERIOD_MS = 1000;
|
const TIMER_CHECK_PERIOD_MS = 1000;
|
||||||
|
|
||||||
// counter, for making up ids to return from setTimeout
|
// counter, for making up ids to return from setTimeout
|
||||||
let _count = 0;
|
let _count = 0;
|
||||||
@@ -37,10 +37,10 @@ let _realCallbackKey;
|
|||||||
|
|
||||||
// a sorted list of the callbacks to be run.
|
// a sorted list of the callbacks to be run.
|
||||||
// each is an object with keys [runAt, func, params, key].
|
// each is an object with keys [runAt, func, params, key].
|
||||||
let _callbackList = [];
|
const _callbackList = [];
|
||||||
|
|
||||||
// var debuglog = console.log.bind(console);
|
// var debuglog = console.log.bind(console);
|
||||||
let debuglog = function() {};
|
const debuglog = function() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the function used by this module to get the current time.
|
* Replace the function used by this module to get the current time.
|
||||||
@@ -72,12 +72,12 @@ module.exports.setTimeout = function(func, delayMs) {
|
|||||||
delayMs = 0;
|
delayMs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let params = Array.prototype.slice.call(arguments, 2);
|
const params = Array.prototype.slice.call(arguments, 2);
|
||||||
let runAt = _now() + delayMs;
|
const runAt = _now() + delayMs;
|
||||||
let key = _count++;
|
const key = _count++;
|
||||||
debuglog("setTimeout: scheduling cb", key, "at", runAt,
|
debuglog("setTimeout: scheduling cb", key, "at", runAt,
|
||||||
"(delay", delayMs, ")");
|
"(delay", delayMs, ")");
|
||||||
let data = {
|
const data = {
|
||||||
runAt: runAt,
|
runAt: runAt,
|
||||||
func: func,
|
func: func,
|
||||||
params: params,
|
params: params,
|
||||||
@@ -85,10 +85,10 @@ module.exports.setTimeout = function(func, delayMs) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// figure out where it goes in the list
|
// figure out where it goes in the list
|
||||||
let idx = binarySearch(
|
const idx = binarySearch(
|
||||||
_callbackList, function(el) {
|
_callbackList, function(el) {
|
||||||
return el.runAt - runAt;
|
return el.runAt - runAt;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
_callbackList.splice(idx, 0, data);
|
_callbackList.splice(idx, 0, data);
|
||||||
@@ -110,7 +110,7 @@ module.exports.clearTimeout = function(key) {
|
|||||||
// remove the element from the list
|
// remove the element from the list
|
||||||
let i;
|
let i;
|
||||||
for (i = 0; i < _callbackList.length; i++) {
|
for (i = 0; i < _callbackList.length; i++) {
|
||||||
let cb = _callbackList[i];
|
const cb = _callbackList[i];
|
||||||
if (cb.key == key) {
|
if (cb.key == key) {
|
||||||
_callbackList.splice(i, 1);
|
_callbackList.splice(i, 1);
|
||||||
break;
|
break;
|
||||||
@@ -129,15 +129,15 @@ function _scheduleRealCallback() {
|
|||||||
global.clearTimeout(_realCallbackKey);
|
global.clearTimeout(_realCallbackKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
let first = _callbackList[0];
|
const first = _callbackList[0];
|
||||||
|
|
||||||
if (!first) {
|
if (!first) {
|
||||||
debuglog("_scheduleRealCallback: no more callbacks, not rescheduling");
|
debuglog("_scheduleRealCallback: no more callbacks, not rescheduling");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let now = _now();
|
const now = _now();
|
||||||
let delayMs = Math.min(first.runAt - now, TIMER_CHECK_PERIOD_MS);
|
const delayMs = Math.min(first.runAt - now, TIMER_CHECK_PERIOD_MS);
|
||||||
|
|
||||||
debuglog("_scheduleRealCallback: now:", now, "delay:", delayMs);
|
debuglog("_scheduleRealCallback: now:", now, "delay:", delayMs);
|
||||||
_realCallbackKey = global.setTimeout(_runCallbacks, delayMs);
|
_realCallbackKey = global.setTimeout(_runCallbacks, delayMs);
|
||||||
@@ -145,13 +145,13 @@ function _scheduleRealCallback() {
|
|||||||
|
|
||||||
function _runCallbacks() {
|
function _runCallbacks() {
|
||||||
let cb;
|
let cb;
|
||||||
let now = _now();
|
const now = _now();
|
||||||
debuglog("_runCallbacks: now:", now);
|
debuglog("_runCallbacks: now:", now);
|
||||||
|
|
||||||
// get the list of things to call
|
// get the list of things to call
|
||||||
let callbacksToRun = [];
|
const callbacksToRun = [];
|
||||||
while (true) {
|
while (true) {
|
||||||
let first = _callbackList[0];
|
const first = _callbackList[0];
|
||||||
if (!first || first.runAt > now) {
|
if (!first || first.runAt > now) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -188,8 +188,8 @@ function binarySearch(array, func) {
|
|||||||
max = array.length;
|
max = array.length;
|
||||||
|
|
||||||
while (min < max) {
|
while (min < max) {
|
||||||
let mid = (min + max) >> 1;
|
const mid = (min + max) >> 1;
|
||||||
let res = func(array[mid]);
|
const res = func(array[mid]);
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
// the element at 'mid' is too big; set it as the new max.
|
// the element at 'mid' is too big; set it as the new max.
|
||||||
max = mid;
|
max = mid;
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ limitations under the License.
|
|||||||
* of requests.
|
* of requests.
|
||||||
* @module scheduler
|
* @module scheduler
|
||||||
*/
|
*/
|
||||||
let utils = require("./utils");
|
const utils = require("./utils");
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
|
|
||||||
let DEBUG = false; // set true to enable console logging.
|
const DEBUG = false; // set true to enable console logging.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a scheduler for Matrix. Requires
|
* Construct a scheduler for Matrix. Requires
|
||||||
@@ -60,7 +60,7 @@ function MatrixScheduler(retryAlgorithm, queueAlgorithm) {
|
|||||||
* @see MatrixScheduler.removeEventFromQueue To remove an event from the queue.
|
* @see MatrixScheduler.removeEventFromQueue To remove an event from the queue.
|
||||||
*/
|
*/
|
||||||
MatrixScheduler.prototype.getQueueForEvent = function(event) {
|
MatrixScheduler.prototype.getQueueForEvent = function(event) {
|
||||||
let name = this.queueAlgorithm(event);
|
const name = this.queueAlgorithm(event);
|
||||||
if (!name || !this._queues[name]) {
|
if (!name || !this._queues[name]) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ MatrixScheduler.prototype.getQueueForEvent = function(event) {
|
|||||||
* @return {boolean} True if this event was removed.
|
* @return {boolean} True if this event was removed.
|
||||||
*/
|
*/
|
||||||
MatrixScheduler.prototype.removeEventFromQueue = function(event) {
|
MatrixScheduler.prototype.removeEventFromQueue = function(event) {
|
||||||
let name = this.queueAlgorithm(event);
|
const name = this.queueAlgorithm(event);
|
||||||
if (!name || !this._queues[name]) {
|
if (!name || !this._queues[name]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ MatrixScheduler.prototype.setProcessFunction = function(fn) {
|
|||||||
* resolved or rejected in due time, else null.
|
* resolved or rejected in due time, else null.
|
||||||
*/
|
*/
|
||||||
MatrixScheduler.prototype.queueEvent = function(event) {
|
MatrixScheduler.prototype.queueEvent = function(event) {
|
||||||
let queueName = this.queueAlgorithm(event);
|
const queueName = this.queueAlgorithm(event);
|
||||||
if (!queueName) {
|
if (!queueName) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ MatrixScheduler.prototype.queueEvent = function(event) {
|
|||||||
if (!this._queues[queueName]) {
|
if (!this._queues[queueName]) {
|
||||||
this._queues[queueName] = [];
|
this._queues[queueName] = [];
|
||||||
}
|
}
|
||||||
let defer = q.defer();
|
const defer = q.defer();
|
||||||
this._queues[queueName].push({
|
this._queues[queueName].push({
|
||||||
event: event,
|
event: event,
|
||||||
defer: defer,
|
defer: defer,
|
||||||
@@ -126,7 +126,7 @@ MatrixScheduler.prototype.queueEvent = function(event) {
|
|||||||
});
|
});
|
||||||
debuglog(
|
debuglog(
|
||||||
"Queue algorithm dumped event %s into queue '%s'",
|
"Queue algorithm dumped event %s into queue '%s'",
|
||||||
event.getId(), queueName
|
event.getId(), queueName,
|
||||||
);
|
);
|
||||||
_startProcessingQueues(this);
|
_startProcessingQueues(this);
|
||||||
return defer.promise;
|
return defer.promise;
|
||||||
@@ -155,7 +155,7 @@ MatrixScheduler.RETRY_BACKOFF_RATELIMIT = function(event, attempts, err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err.name === "M_LIMIT_EXCEEDED") {
|
if (err.name === "M_LIMIT_EXCEEDED") {
|
||||||
let waitTime = err.data.retry_after_ms;
|
const waitTime = err.data.retry_after_ms;
|
||||||
if (waitTime) {
|
if (waitTime) {
|
||||||
return waitTime;
|
return waitTime;
|
||||||
}
|
}
|
||||||
@@ -201,10 +201,10 @@ function _startProcessingQueues(scheduler) {
|
|||||||
|
|
||||||
function _processQueue(scheduler, queueName) {
|
function _processQueue(scheduler, queueName) {
|
||||||
// get head of queue
|
// get head of queue
|
||||||
let obj = _peekNextEvent(scheduler, queueName);
|
const obj = _peekNextEvent(scheduler, queueName);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
// queue is empty. Mark as inactive and stop recursing.
|
// queue is empty. Mark as inactive and stop recursing.
|
||||||
let index = scheduler._activeQueues.indexOf(queueName);
|
const index = scheduler._activeQueues.indexOf(queueName);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
scheduler._activeQueues.splice(index, 1);
|
scheduler._activeQueues.splice(index, 1);
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ function _processQueue(scheduler, queueName) {
|
|||||||
}
|
}
|
||||||
debuglog(
|
debuglog(
|
||||||
"Queue '%s' has %s pending events",
|
"Queue '%s' has %s pending events",
|
||||||
queueName, scheduler._queues[queueName].length
|
queueName, scheduler._queues[queueName].length,
|
||||||
);
|
);
|
||||||
// fire the process function and if it resolves, resolve the deferred. Else
|
// fire the process function and if it resolves, resolve the deferred. Else
|
||||||
// invoke the retry algorithm.
|
// invoke the retry algorithm.
|
||||||
@@ -227,14 +227,14 @@ function _processQueue(scheduler, queueName) {
|
|||||||
}, function(err) {
|
}, function(err) {
|
||||||
obj.attempts += 1;
|
obj.attempts += 1;
|
||||||
// ask the retry algorithm when/if we should try again
|
// ask the retry algorithm when/if we should try again
|
||||||
let waitTimeMs = scheduler.retryAlgorithm(obj.event, obj.attempts, err);
|
const waitTimeMs = scheduler.retryAlgorithm(obj.event, obj.attempts, err);
|
||||||
debuglog(
|
debuglog(
|
||||||
"retry(%s) err=%s event_id=%s waitTime=%s",
|
"retry(%s) err=%s event_id=%s waitTime=%s",
|
||||||
obj.attempts, err, obj.event.getId(), waitTimeMs
|
obj.attempts, err, obj.event.getId(), waitTimeMs,
|
||||||
);
|
);
|
||||||
if (waitTimeMs === -1) { // give up (you quitter!)
|
if (waitTimeMs === -1) { // give up (you quitter!)
|
||||||
debuglog(
|
debuglog(
|
||||||
"Queue '%s' giving up on event %s", queueName, obj.event.getId()
|
"Queue '%s' giving up on event %s", queueName, obj.event.getId(),
|
||||||
);
|
);
|
||||||
// remove this from the queue
|
// remove this from the queue
|
||||||
_removeNextEvent(scheduler, queueName);
|
_removeNextEvent(scheduler, queueName);
|
||||||
@@ -250,7 +250,7 @@ function _processQueue(scheduler, queueName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _peekNextEvent(scheduler, queueName) {
|
function _peekNextEvent(scheduler, queueName) {
|
||||||
let queue = scheduler._queues[queueName];
|
const queue = scheduler._queues[queueName];
|
||||||
if (!utils.isArray(queue)) {
|
if (!utils.isArray(queue)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ function _peekNextEvent(scheduler, queueName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _removeNextEvent(scheduler, queueName) {
|
function _removeNextEvent(scheduler, queueName) {
|
||||||
let queue = scheduler._queues[queueName];
|
const queue = scheduler._queues[queueName];
|
||||||
if (!utils.isArray(queue)) {
|
if (!utils.isArray(queue)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ limitations under the License.
|
|||||||
* This is an internal module. See {@link MatrixInMemoryStore} for the public class.
|
* This is an internal module. See {@link MatrixInMemoryStore} for the public class.
|
||||||
* @module store/memory
|
* @module store/memory
|
||||||
*/
|
*/
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let User = require("../models/user");
|
const User = require("../models/user");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new in-memory data store for the Matrix Client.
|
* Construct a new in-memory data store for the Matrix Client.
|
||||||
@@ -77,7 +77,7 @@ module.exports.MatrixInMemoryStore.prototype = {
|
|||||||
// map up-to-date.
|
// map up-to-date.
|
||||||
room.currentState.on("RoomState.members", this._onRoomMember.bind(this));
|
room.currentState.on("RoomState.members", this._onRoomMember.bind(this));
|
||||||
// add existing members
|
// add existing members
|
||||||
let self = this;
|
const self = this;
|
||||||
room.currentState.getMembers().forEach(function(m) {
|
room.currentState.getMembers().forEach(function(m) {
|
||||||
self._onRoomMember(null, room.currentState, m);
|
self._onRoomMember(null, room.currentState, m);
|
||||||
});
|
});
|
||||||
@@ -97,12 +97,12 @@ module.exports.MatrixInMemoryStore.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = this.users[member.userId] || new User(member.userId);
|
const user = this.users[member.userId] || new User(member.userId);
|
||||||
if (member.name) {
|
if (member.name) {
|
||||||
user.setDisplayName(member.name);
|
user.setDisplayName(member.name);
|
||||||
if (member.events.member) {
|
if (member.events.member) {
|
||||||
user.setRawDisplayName(
|
user.setRawDisplayName(
|
||||||
member.events.member.getDirectionalContent().displayname
|
member.events.member.getDirectionalContent().displayname,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ module.exports.MatrixInMemoryStore.prototype = {
|
|||||||
* @param {Array<MatrixEvent>} events The events to store.
|
* @param {Array<MatrixEvent>} events The events to store.
|
||||||
*/
|
*/
|
||||||
storeAccountDataEvents: function(events) {
|
storeAccountDataEvents: function(events) {
|
||||||
let self = this;
|
const self = this;
|
||||||
events.forEach(function(event) {
|
events.forEach(function(event) {
|
||||||
self.accountData[event.getType()] = event;
|
self.accountData[event.getType()] = event;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ limitations under the License.
|
|||||||
* @module store/session/webstorage
|
* @module store/session/webstorage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let utils = require("../../utils");
|
const utils = require("../../utils");
|
||||||
|
|
||||||
let DEBUG = false; // set true to enable console logging.
|
const DEBUG = false; // set true to enable console logging.
|
||||||
let E2E_PREFIX = "session.e2e.";
|
const E2E_PREFIX = "session.e2e.";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a web storage session store, capable of storing account keys,
|
* Construct a web storage session store, capable of storing account keys,
|
||||||
@@ -37,9 +37,12 @@ function WebStorageSessionStore(webStore) {
|
|||||||
this.store = webStore;
|
this.store = webStore;
|
||||||
if (!utils.isFunction(webStore.getItem) ||
|
if (!utils.isFunction(webStore.getItem) ||
|
||||||
!utils.isFunction(webStore.setItem) ||
|
!utils.isFunction(webStore.setItem) ||
|
||||||
!utils.isFunction(webStore.removeItem)) {
|
!utils.isFunction(webStore.removeItem) ||
|
||||||
|
!utils.isFunction(webStore.key) ||
|
||||||
|
typeof(webStore.length) !== 'number'
|
||||||
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Supplied webStore does not meet the WebStorage API interface"
|
"Supplied webStore does not meet the WebStorage API interface",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,10 +106,10 @@ WebStorageSessionStore.prototype = {
|
|||||||
* @param {string} session Base64 encoded end-to-end session.
|
* @param {string} session Base64 encoded end-to-end session.
|
||||||
*/
|
*/
|
||||||
storeEndToEndSession: function(deviceKey, sessionId, session) {
|
storeEndToEndSession: function(deviceKey, sessionId, session) {
|
||||||
let sessions = this.getEndToEndSessions(deviceKey) || {};
|
const sessions = this.getEndToEndSessions(deviceKey) || {};
|
||||||
sessions[sessionId] = session;
|
sessions[sessionId] = session;
|
||||||
setJsonItem(
|
setJsonItem(
|
||||||
this.store, keyEndToEndSessions(deviceKey), sessions
|
this.store, keyEndToEndSessions(deviceKey), sessions,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -120,13 +123,39 @@ WebStorageSessionStore.prototype = {
|
|||||||
return getJsonItem(this.store, keyEndToEndSessions(deviceKey));
|
return getJsonItem(this.store, keyEndToEndSessions(deviceKey));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of all known inbound group sessions
|
||||||
|
*
|
||||||
|
* @return {{senderKey: string, sessionId: string}}
|
||||||
|
*/
|
||||||
|
getAllEndToEndInboundGroupSessionKeys: function() {
|
||||||
|
const prefix = E2E_PREFIX + 'inboundgroupsessions/';
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < this.store.length; i++) {
|
||||||
|
const key = this.store.key(i);
|
||||||
|
if (!key.startsWith(prefix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// we can't use split, as the components we are trying to split out
|
||||||
|
// might themselves contain '/' characters. We rely on the
|
||||||
|
// senderKey being a (32-byte) curve25519 key, base64-encoded
|
||||||
|
// (hence 43 characters long).
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
senderKey: key.substr(prefix.length, 43),
|
||||||
|
sessionId: key.substr(prefix.length + 44),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
getEndToEndInboundGroupSession: function(senderKey, sessionId) {
|
getEndToEndInboundGroupSession: function(senderKey, sessionId) {
|
||||||
let key = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
const key = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
||||||
return this.store.getItem(key);
|
return this.store.getItem(key);
|
||||||
},
|
},
|
||||||
|
|
||||||
storeEndToEndInboundGroupSession: function(senderKey, sessionId, pickledSession) {
|
storeEndToEndInboundGroupSession: function(senderKey, sessionId, pickledSession) {
|
||||||
let key = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
const key = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
||||||
return this.store.setItem(key, pickledSession);
|
return this.store.setItem(key, pickledSession);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -149,8 +178,8 @@ WebStorageSessionStore.prototype = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account";
|
const KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account";
|
||||||
let KEY_END_TO_END_ANNOUNCED = E2E_PREFIX + "announced";
|
const KEY_END_TO_END_ANNOUNCED = E2E_PREFIX + "announced";
|
||||||
|
|
||||||
function keyEndToEndDevicesForUser(userId) {
|
function keyEndToEndDevicesForUser(userId) {
|
||||||
return E2E_PREFIX + "devices/" + userId;
|
return E2E_PREFIX + "devices/" + userId;
|
||||||
|
|||||||
174
src/sync.js
174
src/sync.js
@@ -23,20 +23,20 @@ limitations under the License.
|
|||||||
* an alternative syncing API, we may want to have a proper syncing interface
|
* an alternative syncing API, we may want to have a proper syncing interface
|
||||||
* for HTTP and WS at some point.
|
* for HTTP and WS at some point.
|
||||||
*/
|
*/
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let User = require("./models/user");
|
const User = require("./models/user");
|
||||||
let Room = require("./models/room");
|
const Room = require("./models/room");
|
||||||
let utils = require("./utils");
|
const utils = require("./utils");
|
||||||
let Filter = require("./filter");
|
const Filter = require("./filter");
|
||||||
let EventTimeline = require("./models/event-timeline");
|
const EventTimeline = require("./models/event-timeline");
|
||||||
|
|
||||||
let DEBUG = true;
|
const DEBUG = true;
|
||||||
|
|
||||||
// /sync requests allow you to set a timeout= but the request may continue
|
// /sync requests allow you to set a timeout= but the request may continue
|
||||||
// beyond that and wedge forever, so we need to track how long we are willing
|
// beyond that and wedge forever, so we need to track how long we are willing
|
||||||
// to keep open the connection. This constant is *ADDED* to the timeout= value
|
// to keep open the connection. This constant is *ADDED* to the timeout= value
|
||||||
// to determine the max time we're willing to wait.
|
// to determine the max time we're willing to wait.
|
||||||
let BUFFER_PERIOD_MS = 80 * 1000;
|
const BUFFER_PERIOD_MS = 80 * 1000;
|
||||||
|
|
||||||
function getFilterName(userId, suffix) {
|
function getFilterName(userId, suffix) {
|
||||||
// scope this on the user ID because people may login on many accounts
|
// scope this on the user ID because people may login on many accounts
|
||||||
@@ -88,8 +88,8 @@ function SyncApi(client, opts) {
|
|||||||
* @return {Room}
|
* @return {Room}
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype.createRoom = function(roomId) {
|
SyncApi.prototype.createRoom = function(roomId) {
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
let room = new Room(roomId, {
|
const room = new Room(roomId, {
|
||||||
pendingEventOrdering: this.opts.pendingEventOrdering,
|
pendingEventOrdering: this.opts.pendingEventOrdering,
|
||||||
timelineSupport: client.timelineSupport,
|
timelineSupport: client.timelineSupport,
|
||||||
});
|
});
|
||||||
@@ -108,7 +108,7 @@ SyncApi.prototype.createRoom = function(roomId) {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._registerStateListeners = function(room) {
|
SyncApi.prototype._registerStateListeners = function(room) {
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
// we need to also re-emit room state and room member events, so hook it up
|
// we need to also re-emit room state and room member events, so hook it up
|
||||||
// to the client now. We need to add a listener for RoomState.members in
|
// to the client now. We need to add a listener for RoomState.members in
|
||||||
// order to hook them correctly. (TODO: find a better way?)
|
// order to hook them correctly. (TODO: find a better way?)
|
||||||
@@ -122,7 +122,7 @@ SyncApi.prototype._registerStateListeners = function(room) {
|
|||||||
[
|
[
|
||||||
"RoomMember.name", "RoomMember.typing", "RoomMember.powerLevel",
|
"RoomMember.name", "RoomMember.typing", "RoomMember.powerLevel",
|
||||||
"RoomMember.membership",
|
"RoomMember.membership",
|
||||||
]
|
],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -144,34 +144,34 @@ SyncApi.prototype._deregisterStateListeners = function(room) {
|
|||||||
* @return {Promise} Resolved when they've been added to the store.
|
* @return {Promise} Resolved when they've been added to the store.
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype.syncLeftRooms = function() {
|
SyncApi.prototype.syncLeftRooms = function() {
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
// grab a filter with limit=1 and include_leave=true
|
// grab a filter with limit=1 and include_leave=true
|
||||||
let filter = new Filter(this.client.credentials.userId);
|
const filter = new Filter(this.client.credentials.userId);
|
||||||
filter.setTimelineLimit(1);
|
filter.setTimelineLimit(1);
|
||||||
filter.setIncludeLeaveRooms(true);
|
filter.setIncludeLeaveRooms(true);
|
||||||
|
|
||||||
let localTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
const localTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
||||||
let qps = {
|
const qps = {
|
||||||
timeout: 0, // don't want to block since this is a single isolated req
|
timeout: 0, // don't want to block since this is a single isolated req
|
||||||
};
|
};
|
||||||
|
|
||||||
return client.getOrCreateFilter(
|
return client.getOrCreateFilter(
|
||||||
getFilterName(client.credentials.userId, "LEFT_ROOMS"), filter
|
getFilterName(client.credentials.userId, "LEFT_ROOMS"), filter,
|
||||||
).then(function(filterId) {
|
).then(function(filterId) {
|
||||||
qps.filter = filterId;
|
qps.filter = filterId;
|
||||||
return client._http.authedRequest(
|
return client._http.authedRequest(
|
||||||
undefined, "GET", "/sync", qps, undefined, localTimeoutMs
|
undefined, "GET", "/sync", qps, undefined, localTimeoutMs,
|
||||||
);
|
);
|
||||||
}).then(function(data) {
|
}).then(function(data) {
|
||||||
let leaveRooms = [];
|
let leaveRooms = [];
|
||||||
if (data.rooms && data.rooms.leave) {
|
if (data.rooms && data.rooms.leave) {
|
||||||
leaveRooms = self._mapSyncResponseToRoomArray(data.rooms.leave);
|
leaveRooms = self._mapSyncResponseToRoomArray(data.rooms.leave);
|
||||||
}
|
}
|
||||||
let rooms = [];
|
const rooms = [];
|
||||||
leaveRooms.forEach(function(leaveObj) {
|
leaveRooms.forEach(function(leaveObj) {
|
||||||
let room = leaveObj.room;
|
const room = leaveObj.room;
|
||||||
rooms.push(room);
|
rooms.push(room);
|
||||||
if (!leaveObj.isBrandNewRoom) {
|
if (!leaveObj.isBrandNewRoom) {
|
||||||
// the intention behind syncLeftRooms is to add in rooms which were
|
// the intention behind syncLeftRooms is to add in rooms which were
|
||||||
@@ -185,9 +185,9 @@ SyncApi.prototype.syncLeftRooms = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
leaveObj.timeline = leaveObj.timeline || {};
|
leaveObj.timeline = leaveObj.timeline || {};
|
||||||
let timelineEvents =
|
const timelineEvents =
|
||||||
self._mapSyncEventsFormat(leaveObj.timeline, room);
|
self._mapSyncEventsFormat(leaveObj.timeline, room);
|
||||||
let stateEvents = self._mapSyncEventsFormat(leaveObj.state, room);
|
const stateEvents = self._mapSyncEventsFormat(leaveObj.state, room);
|
||||||
|
|
||||||
// set the back-pagination token. Do this *before* adding any
|
// set the back-pagination token. Do this *before* adding any
|
||||||
// events so that clients can start back-paginating.
|
// events so that clients can start back-paginating.
|
||||||
@@ -212,8 +212,8 @@ SyncApi.prototype.syncLeftRooms = function() {
|
|||||||
* store.
|
* store.
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype.peek = function(roomId) {
|
SyncApi.prototype.peek = function(roomId) {
|
||||||
let self = this;
|
const self = this;
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
this._peekRoomId = roomId;
|
this._peekRoomId = roomId;
|
||||||
return this.client.roomInitialSync(roomId, 20).then(function(response) {
|
return this.client.roomInitialSync(roomId, 20).then(function(response) {
|
||||||
// make sure things are init'd
|
// make sure things are init'd
|
||||||
@@ -221,18 +221,18 @@ SyncApi.prototype.peek = function(roomId) {
|
|||||||
response.messages.chunk = response.messages.chunk || [];
|
response.messages.chunk = response.messages.chunk || [];
|
||||||
response.state = response.state || [];
|
response.state = response.state || [];
|
||||||
|
|
||||||
let peekRoom = self.createRoom(roomId);
|
const peekRoom = self.createRoom(roomId);
|
||||||
|
|
||||||
// FIXME: Mostly duplicated from _processRoomEvents but not entirely
|
// FIXME: Mostly duplicated from _processRoomEvents but not entirely
|
||||||
// because "state" in this API is at the BEGINNING of the chunk
|
// because "state" in this API is at the BEGINNING of the chunk
|
||||||
let oldStateEvents = utils.map(
|
const oldStateEvents = utils.map(
|
||||||
utils.deepCopy(response.state), client.getEventMapper()
|
utils.deepCopy(response.state), client.getEventMapper(),
|
||||||
);
|
);
|
||||||
let stateEvents = utils.map(
|
const stateEvents = utils.map(
|
||||||
response.state, client.getEventMapper()
|
response.state, client.getEventMapper(),
|
||||||
);
|
);
|
||||||
let messages = utils.map(
|
const messages = utils.map(
|
||||||
response.messages.chunk, client.getEventMapper()
|
response.messages.chunk, client.getEventMapper(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// XXX: copypasted from /sync until we kill off this
|
// XXX: copypasted from /sync until we kill off this
|
||||||
@@ -301,7 +301,7 @@ SyncApi.prototype._peekPoll = function(roomId, token) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
// FIXME: gut wrenching; hard-coded timeout values
|
// FIXME: gut wrenching; hard-coded timeout values
|
||||||
this.client._http.authedRequest(undefined, "GET", "/events", {
|
this.client._http.authedRequest(undefined, "GET", "/events", {
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
@@ -332,10 +332,10 @@ SyncApi.prototype._peekPoll = function(roomId, token) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// strip out events which aren't for the given room_id (e.g presence)
|
// strip out events which aren't for the given room_id (e.g presence)
|
||||||
let events = res.chunk.filter(function(e) {
|
const events = res.chunk.filter(function(e) {
|
||||||
return e.room_id === roomId;
|
return e.room_id === roomId;
|
||||||
}).map(self.client.getEventMapper());
|
}).map(self.client.getEventMapper());
|
||||||
let room = self.client.getRoom(roomId);
|
const room = self.client.getRoom(roomId);
|
||||||
room.addLiveEvents(events);
|
room.addLiveEvents(events);
|
||||||
self._peekPoll(roomId, res.end);
|
self._peekPoll(roomId, res.end);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
@@ -362,8 +362,8 @@ SyncApi.prototype.sync = function() {
|
|||||||
debuglog("SyncApi.sync: starting with sync token " +
|
debuglog("SyncApi.sync: starting with sync token " +
|
||||||
this.client.store.getSyncToken());
|
this.client.store.getSyncToken());
|
||||||
|
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
this._running = true;
|
this._running = true;
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ SyncApi.prototype.sync = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
client.getOrCreateFilter(
|
client.getOrCreateFilter(
|
||||||
getFilterName(client.credentials.userId), filter
|
getFilterName(client.credentials.userId), filter,
|
||||||
).done(function(filterId) {
|
).done(function(filterId) {
|
||||||
// reset the notifications timeline to prepare it to paginate from
|
// reset the notifications timeline to prepare it to paginate from
|
||||||
// the current point in time.
|
// the current point in time.
|
||||||
@@ -465,8 +465,8 @@ SyncApi.prototype.retryImmediately = function() {
|
|||||||
* @param {boolean} syncOptions.hasSyncedBefore
|
* @param {boolean} syncOptions.hasSyncedBefore
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._sync = function(syncOptions) {
|
SyncApi.prototype._sync = function(syncOptions) {
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
if (!this._running) {
|
if (!this._running) {
|
||||||
debuglog("Sync no longer running: exiting.");
|
debuglog("Sync no longer running: exiting.");
|
||||||
@@ -483,9 +483,9 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
filterId = this._getGuestFilter();
|
filterId = this._getGuestFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
let syncToken = client.store.getSyncToken();
|
const syncToken = client.store.getSyncToken();
|
||||||
|
|
||||||
let qps = {
|
const qps = {
|
||||||
filter: filterId,
|
filter: filterId,
|
||||||
timeout: this.opts.pollTimeout,
|
timeout: this.opts.pollTimeout,
|
||||||
};
|
};
|
||||||
@@ -508,10 +508,10 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// normal timeout= plus buffer time
|
// normal timeout= plus buffer time
|
||||||
let clientSideTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
const clientSideTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
||||||
|
|
||||||
this._currentSyncRequest = client._http.authedRequest(
|
this._currentSyncRequest = client._http.authedRequest(
|
||||||
undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs
|
undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs,
|
||||||
);
|
);
|
||||||
|
|
||||||
this._currentSyncRequest.done(function(data) {
|
this._currentSyncRequest.done(function(data) {
|
||||||
@@ -576,8 +576,8 @@ SyncApi.prototype._sync = function(syncOptions) {
|
|||||||
* @param {Object} data The response from /sync
|
* @param {Object} data The response from /sync
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
// data looks like:
|
// data looks like:
|
||||||
// {
|
// {
|
||||||
@@ -635,7 +635,7 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
|
|
||||||
// handle non-room account_data
|
// handle non-room account_data
|
||||||
if (data.account_data && utils.isArray(data.account_data.events)) {
|
if (data.account_data && utils.isArray(data.account_data.events)) {
|
||||||
let events = data.account_data.events.map(client.getEventMapper());
|
const events = data.account_data.events.map(client.getEventMapper());
|
||||||
client.store.storeAccountDataEvents(events);
|
client.store.storeAccountDataEvents(events);
|
||||||
events.forEach(
|
events.forEach(
|
||||||
function(accountDataEvent) {
|
function(accountDataEvent) {
|
||||||
@@ -644,7 +644,7 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
}
|
}
|
||||||
client.emit("accountData", accountDataEvent);
|
client.emit("accountData", accountDataEvent);
|
||||||
return accountDataEvent;
|
return accountDataEvent;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,19 +654,19 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
.map(client.getEventMapper())
|
.map(client.getEventMapper())
|
||||||
.forEach(
|
.forEach(
|
||||||
function(toDeviceEvent) {
|
function(toDeviceEvent) {
|
||||||
let content = toDeviceEvent.getContent();
|
const content = toDeviceEvent.getContent();
|
||||||
if (
|
if (
|
||||||
toDeviceEvent.getType() == "m.room.message" &&
|
toDeviceEvent.getType() == "m.room.message" &&
|
||||||
content.msgtype == "m.bad.encrypted"
|
content.msgtype == "m.bad.encrypted"
|
||||||
) {
|
) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Unable to decrypt to-device event: " + content.body
|
"Unable to decrypt to-device event: " + content.body,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
client.emit("toDeviceEvent", toDeviceEvent);
|
client.emit("toDeviceEvent", toDeviceEvent);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,8 +693,8 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
|
|
||||||
// Handle invites
|
// Handle invites
|
||||||
inviteRooms.forEach(function(inviteObj) {
|
inviteRooms.forEach(function(inviteObj) {
|
||||||
let room = inviteObj.room;
|
const room = inviteObj.room;
|
||||||
let stateEvents =
|
const stateEvents =
|
||||||
self._mapSyncEventsFormat(inviteObj.invite_state, room);
|
self._mapSyncEventsFormat(inviteObj.invite_state, room);
|
||||||
self._processRoomEvents(room, stateEvents);
|
self._processRoomEvents(room, stateEvents);
|
||||||
if (inviteObj.isBrandNewRoom) {
|
if (inviteObj.isBrandNewRoom) {
|
||||||
@@ -709,19 +709,19 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
|
|
||||||
// Handle joins
|
// Handle joins
|
||||||
joinRooms.forEach(function(joinObj) {
|
joinRooms.forEach(function(joinObj) {
|
||||||
let room = joinObj.room;
|
const room = joinObj.room;
|
||||||
let stateEvents = self._mapSyncEventsFormat(joinObj.state, room);
|
const stateEvents = self._mapSyncEventsFormat(joinObj.state, room);
|
||||||
let timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room);
|
const timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room);
|
||||||
let ephemeralEvents = self._mapSyncEventsFormat(joinObj.ephemeral);
|
const ephemeralEvents = self._mapSyncEventsFormat(joinObj.ephemeral);
|
||||||
let accountDataEvents = self._mapSyncEventsFormat(joinObj.account_data);
|
const accountDataEvents = self._mapSyncEventsFormat(joinObj.account_data);
|
||||||
|
|
||||||
// we do this first so it's correct when any of the events fire
|
// we do this first so it's correct when any of the events fire
|
||||||
if (joinObj.unread_notifications) {
|
if (joinObj.unread_notifications) {
|
||||||
room.setUnreadNotificationCount(
|
room.setUnreadNotificationCount(
|
||||||
'total', joinObj.unread_notifications.notification_count
|
'total', joinObj.unread_notifications.notification_count,
|
||||||
);
|
);
|
||||||
room.setUnreadNotificationCount(
|
room.setUnreadNotificationCount(
|
||||||
'highlight', joinObj.unread_notifications.highlight_count
|
'highlight', joinObj.unread_notifications.highlight_count,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,7 +748,7 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
// will stop us linking the empty timeline into the chain).
|
// will stop us linking the empty timeline into the chain).
|
||||||
//
|
//
|
||||||
for (let i = timelineEvents.length - 1; i >= 0; i--) {
|
for (let i = timelineEvents.length - 1; i >= 0; i--) {
|
||||||
let eventId = timelineEvents[i].getId();
|
const eventId = timelineEvents[i].getId();
|
||||||
if (room.getTimelineForEvent(eventId)) {
|
if (room.getTimelineForEvent(eventId)) {
|
||||||
debuglog("Already have event " + eventId + " in limited " +
|
debuglog("Already have event " + eventId + " in limited " +
|
||||||
"sync - not resetting");
|
"sync - not resetting");
|
||||||
@@ -818,12 +818,12 @@ SyncApi.prototype._processSyncResponse = function(syncToken, data) {
|
|||||||
|
|
||||||
// Handle leaves (e.g. kicked rooms)
|
// Handle leaves (e.g. kicked rooms)
|
||||||
leaveRooms.forEach(function(leaveObj) {
|
leaveRooms.forEach(function(leaveObj) {
|
||||||
let room = leaveObj.room;
|
const room = leaveObj.room;
|
||||||
let stateEvents =
|
const stateEvents =
|
||||||
self._mapSyncEventsFormat(leaveObj.state, room);
|
self._mapSyncEventsFormat(leaveObj.state, room);
|
||||||
let timelineEvents =
|
const timelineEvents =
|
||||||
self._mapSyncEventsFormat(leaveObj.timeline, room);
|
self._mapSyncEventsFormat(leaveObj.timeline, room);
|
||||||
let accountDataEvents =
|
const accountDataEvents =
|
||||||
self._mapSyncEventsFormat(leaveObj.account_data);
|
self._mapSyncEventsFormat(leaveObj.account_data);
|
||||||
|
|
||||||
self._processRoomEvents(room, stateEvents, timelineEvents);
|
self._processRoomEvents(room, stateEvents, timelineEvents);
|
||||||
@@ -876,11 +876,11 @@ SyncApi.prototype._startKeepAlives = function(delay) {
|
|||||||
if (this._keepAliveTimer !== null) {
|
if (this._keepAliveTimer !== null) {
|
||||||
clearTimeout(this._keepAliveTimer);
|
clearTimeout(this._keepAliveTimer);
|
||||||
}
|
}
|
||||||
let self = this;
|
const self = this;
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
self._keepAliveTimer = setTimeout(
|
self._keepAliveTimer = setTimeout(
|
||||||
self._pokeKeepAlive.bind(self),
|
self._pokeKeepAlive.bind(self),
|
||||||
delay
|
delay,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
self._pokeKeepAlive();
|
self._pokeKeepAlive();
|
||||||
@@ -895,7 +895,7 @@ SyncApi.prototype._startKeepAlives = function(delay) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._pokeKeepAlive = function() {
|
SyncApi.prototype._pokeKeepAlive = function() {
|
||||||
let self = this;
|
const self = this;
|
||||||
function success() {
|
function success() {
|
||||||
clearTimeout(self._keepAliveTimer);
|
clearTimeout(self._keepAliveTimer);
|
||||||
if (self._connectionReturnedDefer) {
|
if (self._connectionReturnedDefer) {
|
||||||
@@ -912,7 +912,7 @@ SyncApi.prototype._pokeKeepAlive = function() {
|
|||||||
{
|
{
|
||||||
prefix: '',
|
prefix: '',
|
||||||
localTimeoutMs: 15 * 1000,
|
localTimeoutMs: 15 * 1000,
|
||||||
}
|
},
|
||||||
).done(function() {
|
).done(function() {
|
||||||
success();
|
success();
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
@@ -926,7 +926,7 @@ SyncApi.prototype._pokeKeepAlive = function() {
|
|||||||
} else {
|
} else {
|
||||||
self._keepAliveTimer = setTimeout(
|
self._keepAliveTimer = setTimeout(
|
||||||
self._pokeKeepAlive.bind(self),
|
self._pokeKeepAlive.bind(self),
|
||||||
5000 + Math.floor(Math.random() * 5000)
|
5000 + Math.floor(Math.random() * 5000),
|
||||||
);
|
);
|
||||||
// A keepalive has failed, so we emit the
|
// A keepalive has failed, so we emit the
|
||||||
// error state (whether or not this is the
|
// error state (whether or not this is the
|
||||||
@@ -947,10 +947,10 @@ SyncApi.prototype._mapSyncResponseToRoomArray = function(obj) {
|
|||||||
// Maps { roomid: {stuff}, roomid: {stuff} }
|
// Maps { roomid: {stuff}, roomid: {stuff} }
|
||||||
// to
|
// to
|
||||||
// [{stuff+Room+isBrandNewRoom}, {stuff+Room+isBrandNewRoom}]
|
// [{stuff+Room+isBrandNewRoom}, {stuff+Room+isBrandNewRoom}]
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
let self = this;
|
const self = this;
|
||||||
return utils.keys(obj).map(function(roomId) {
|
return utils.keys(obj).map(function(roomId) {
|
||||||
let arrObj = obj[roomId];
|
const arrObj = obj[roomId];
|
||||||
let room = client.store.getRoom(roomId);
|
let room = client.store.getRoom(roomId);
|
||||||
let isBrandNewRoom = false;
|
let isBrandNewRoom = false;
|
||||||
if (!room) {
|
if (!room) {
|
||||||
@@ -972,7 +972,7 @@ SyncApi.prototype._mapSyncEventsFormat = function(obj, room) {
|
|||||||
if (!obj || !utils.isArray(obj.events)) {
|
if (!obj || !utils.isArray(obj.events)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let mapper = this.client.getEventMapper();
|
const mapper = this.client.getEventMapper();
|
||||||
return obj.events.map(function(e) {
|
return obj.events.map(function(e) {
|
||||||
if (room) {
|
if (room) {
|
||||||
e.room_id = room.roomId;
|
e.room_id = room.roomId;
|
||||||
@@ -988,7 +988,7 @@ SyncApi.prototype._resolveInvites = function(room) {
|
|||||||
if (!room || !this.opts.resolveInvitesToProfiles) {
|
if (!room || !this.opts.resolveInvitesToProfiles) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
// For each invited room member we want to give them a displayname/avatar url
|
// For each invited room member we want to give them a displayname/avatar url
|
||||||
// if they have one (the m.room.member invites don't contain this).
|
// if they have one (the m.room.member invites don't contain this).
|
||||||
room.getMembersWithMembership("invite").forEach(function(member) {
|
room.getMembersWithMembership("invite").forEach(function(member) {
|
||||||
@@ -997,7 +997,7 @@ SyncApi.prototype._resolveInvites = function(room) {
|
|||||||
}
|
}
|
||||||
member._requestedProfileInfo = true;
|
member._requestedProfileInfo = true;
|
||||||
// try to get a cached copy first.
|
// try to get a cached copy first.
|
||||||
let user = client.getUser(member.userId);
|
const user = client.getUser(member.userId);
|
||||||
let promise;
|
let promise;
|
||||||
if (user) {
|
if (user) {
|
||||||
promise = q({
|
promise = q({
|
||||||
@@ -1011,7 +1011,7 @@ SyncApi.prototype._resolveInvites = function(room) {
|
|||||||
// slightly naughty by doctoring the invite event but this means all
|
// slightly naughty by doctoring the invite event but this means all
|
||||||
// the code paths remain the same between invite/join display name stuff
|
// the code paths remain the same between invite/join display name stuff
|
||||||
// which is a worthy trade-off for some minor pollution.
|
// which is a worthy trade-off for some minor pollution.
|
||||||
let inviteEvent = member.events.member;
|
const inviteEvent = member.events.member;
|
||||||
if (inviteEvent.getContent().membership !== "invite") {
|
if (inviteEvent.getContent().membership !== "invite") {
|
||||||
// between resolving and now they have since joined, so don't clobber
|
// between resolving and now they have since joined, so don't clobber
|
||||||
return;
|
return;
|
||||||
@@ -1036,19 +1036,19 @@ SyncApi.prototype._resolveInvites = function(room) {
|
|||||||
SyncApi.prototype._processRoomEvents = function(room, stateEventList,
|
SyncApi.prototype._processRoomEvents = function(room, stateEventList,
|
||||||
timelineEventList) {
|
timelineEventList) {
|
||||||
timelineEventList = timelineEventList || [];
|
timelineEventList = timelineEventList || [];
|
||||||
let client = this.client;
|
const client = this.client;
|
||||||
// "old" and "current" state are the same initially; they
|
// "old" and "current" state are the same initially; they
|
||||||
// start diverging if the user paginates.
|
// start diverging if the user paginates.
|
||||||
// We must deep copy otherwise membership changes in old state
|
// We must deep copy otherwise membership changes in old state
|
||||||
// will leak through to current state!
|
// will leak through to current state!
|
||||||
let oldStateEvents = utils.map(
|
const oldStateEvents = utils.map(
|
||||||
utils.deepCopy(
|
utils.deepCopy(
|
||||||
stateEventList.map(function(mxEvent) {
|
stateEventList.map(function(mxEvent) {
|
||||||
return mxEvent.event;
|
return mxEvent.event;
|
||||||
})
|
}),
|
||||||
), client.getEventMapper()
|
), client.getEventMapper(),
|
||||||
);
|
);
|
||||||
let stateEvents = stateEventList;
|
const stateEvents = stateEventList;
|
||||||
|
|
||||||
// set the state of the room to as it was before the timeline executes
|
// set the state of the room to as it was before the timeline executes
|
||||||
//
|
//
|
||||||
@@ -1068,7 +1068,7 @@ SyncApi.prototype._processRoomEvents = function(room, stateEventList,
|
|||||||
// gather our notifications into this._notifEvents
|
// gather our notifications into this._notifEvents
|
||||||
if (client.getNotifTimelineSet()) {
|
if (client.getNotifTimelineSet()) {
|
||||||
for (let i = 0; i < timelineEventList.length; i++) {
|
for (let i = 0; i < timelineEventList.length; i++) {
|
||||||
let pushActions = client.getPushActionsForEvent(timelineEventList[i]);
|
const pushActions = client.getPushActionsForEvent(timelineEventList[i]);
|
||||||
if (pushActions && pushActions.notify &&
|
if (pushActions && pushActions.notify &&
|
||||||
pushActions.tweaks && pushActions.tweaks.highlight) {
|
pushActions.tweaks && pushActions.tweaks.highlight) {
|
||||||
this._notifEvents.push(timelineEventList[i]);
|
this._notifEvents.push(timelineEventList[i]);
|
||||||
@@ -1085,7 +1085,7 @@ SyncApi.prototype._processRoomEvents = function(room, stateEventList,
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._getGuestFilter = function() {
|
SyncApi.prototype._getGuestFilter = function() {
|
||||||
let guestRooms = this.client._guestRooms; // FIXME: horrible gut-wrenching
|
const guestRooms = this.client._guestRooms; // FIXME: horrible gut-wrenching
|
||||||
if (!guestRooms) {
|
if (!guestRooms) {
|
||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
@@ -1106,7 +1106,7 @@ SyncApi.prototype._getGuestFilter = function() {
|
|||||||
* @param {Object} data Object of additional data to emit in the event
|
* @param {Object} data Object of additional data to emit in the event
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype._updateSyncState = function(newState, data) {
|
SyncApi.prototype._updateSyncState = function(newState, data) {
|
||||||
let old = this._syncState;
|
const old = this._syncState;
|
||||||
this._syncState = newState;
|
this._syncState = newState;
|
||||||
this.client.emit("sync", this._syncState, old, data);
|
this.client.emit("sync", this._syncState, old, data);
|
||||||
};
|
};
|
||||||
@@ -1123,7 +1123,7 @@ SyncApi.prototype._onOnline = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function createNewUser(client, userId) {
|
function createNewUser(client, userId) {
|
||||||
let user = new User(userId);
|
const user = new User(userId);
|
||||||
reEmit(client, user, [
|
reEmit(client, user, [
|
||||||
"User.avatarUrl", "User.displayName", "User.presence",
|
"User.avatarUrl", "User.displayName", "User.presence",
|
||||||
"User.currentlyActive", "User.lastPresenceTs",
|
"User.currentlyActive", "User.lastPresenceTs",
|
||||||
@@ -1140,7 +1140,7 @@ function reEmit(reEmitEntity, emittableEntity, eventNames) {
|
|||||||
// Transformation Example:
|
// Transformation Example:
|
||||||
// listener on "foo" => function(a,b) { ... }
|
// listener on "foo" => function(a,b) { ... }
|
||||||
// Re-emit on "thing" => thing.emit("foo", a, b)
|
// Re-emit on "thing" => thing.emit("foo", a, b)
|
||||||
let newArgs = [eventName];
|
const newArgs = [eventName];
|
||||||
for (let i = 0; i < arguments.length; i++) {
|
for (let i = 0; i < arguments.length; i++) {
|
||||||
newArgs.push(arguments[i]);
|
newArgs.push(arguments[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,25 +17,25 @@ limitations under the License.
|
|||||||
|
|
||||||
/** @module timeline-window */
|
/** @module timeline-window */
|
||||||
|
|
||||||
let q = require("q");
|
const q = require("q");
|
||||||
let EventTimeline = require("./models/event-timeline");
|
const EventTimeline = require("./models/event-timeline");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
let DEBUG = false;
|
const DEBUG = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
let debuglog = DEBUG ? console.log.bind(console) : function() {};
|
const debuglog = DEBUG ? console.log.bind(console) : function() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the number of times we ask the server for more events before giving up
|
* the number of times we ask the server for more events before giving up
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
let DEFAULT_PAGINATE_LOOP_LIMIT = 5;
|
const DEFAULT_PAGINATE_LOOP_LIMIT = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a TimelineWindow.
|
* Construct a TimelineWindow.
|
||||||
@@ -92,15 +92,15 @@ function TimelineWindow(client, timelineSet, opts) {
|
|||||||
* @return {module:client.Promise}
|
* @return {module:client.Promise}
|
||||||
*/
|
*/
|
||||||
TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {
|
TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {
|
||||||
let self = this;
|
const self = this;
|
||||||
initialWindowSize = initialWindowSize || 20;
|
initialWindowSize = initialWindowSize || 20;
|
||||||
|
|
||||||
// given an EventTimeline, and an event index within it, initialise our
|
// given an EventTimeline, and an event index within it, initialise our
|
||||||
// fields so that the event in question is in the middle of the window.
|
// fields so that the event in question is in the middle of the window.
|
||||||
let initFields = function(timeline, eventIndex) {
|
const initFields = function(timeline, eventIndex) {
|
||||||
let endIndex = Math.min(timeline.getEvents().length,
|
const endIndex = Math.min(timeline.getEvents().length,
|
||||||
eventIndex + Math.ceil(initialWindowSize / 2));
|
eventIndex + Math.ceil(initialWindowSize / 2));
|
||||||
let startIndex = Math.max(0, endIndex - initialWindowSize);
|
const startIndex = Math.max(0, endIndex - initialWindowSize);
|
||||||
self._start = new TimelineIndex(timeline, startIndex - timeline.getBaseIndex());
|
self._start = new TimelineIndex(timeline, startIndex - timeline.getBaseIndex());
|
||||||
self._end = new TimelineIndex(timeline, endIndex - timeline.getBaseIndex());
|
self._end = new TimelineIndex(timeline, endIndex - timeline.getBaseIndex());
|
||||||
self._eventCount = endIndex - startIndex;
|
self._eventCount = endIndex - startIndex;
|
||||||
@@ -126,7 +126,7 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// start with the most recent events
|
// start with the most recent events
|
||||||
let tl = this._timelineSet.getLiveTimeline();
|
const tl = this._timelineSet.getLiveTimeline();
|
||||||
initFields(tl, tl.getEvents().length);
|
initFields(tl, tl.getEvents().length);
|
||||||
return q();
|
return q();
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try moving the cap
|
// try moving the cap
|
||||||
let count = (direction == EventTimeline.BACKWARDS) ?
|
const count = (direction == EventTimeline.BACKWARDS) ?
|
||||||
tl.retreat(size) : tl.advance(size);
|
tl.retreat(size) : tl.advance(size);
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
@@ -236,7 +236,7 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest,
|
|||||||
debuglog("TimelineWindow: increased cap by " + count +
|
debuglog("TimelineWindow: increased cap by " + count +
|
||||||
" (now " + this._eventCount + ")");
|
" (now " + this._eventCount + ")");
|
||||||
// remove some events from the other end, if necessary
|
// remove some events from the other end, if necessary
|
||||||
let excess = this._eventCount - this._windowLimit;
|
const excess = this._eventCount - this._windowLimit;
|
||||||
if (excess > 0) {
|
if (excess > 0) {
|
||||||
this.unpaginate(excess, direction != EventTimeline.BACKWARDS);
|
this.unpaginate(excess, direction != EventTimeline.BACKWARDS);
|
||||||
}
|
}
|
||||||
@@ -250,16 +250,16 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try making a pagination request
|
// try making a pagination request
|
||||||
let token = tl.timeline.getPaginationToken(direction);
|
const token = tl.timeline.getPaginationToken(direction);
|
||||||
if (!token) {
|
if (!token) {
|
||||||
debuglog("TimelineWindow: no token");
|
debuglog("TimelineWindow: no token");
|
||||||
return q(false);
|
return q(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("TimelineWindow: starting request");
|
debuglog("TimelineWindow: starting request");
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
let prom = this._client.paginateEventTimeline(tl.timeline, {
|
const prom = this._client.paginateEventTimeline(tl.timeline, {
|
||||||
backwards: direction == EventTimeline.BACKWARDS,
|
backwards: direction == EventTimeline.BACKWARDS,
|
||||||
limit: size,
|
limit: size,
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
@@ -298,7 +298,7 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest,
|
|||||||
* of the timeline.
|
* of the timeline.
|
||||||
*/
|
*/
|
||||||
TimelineWindow.prototype.unpaginate = function(delta, startOfTimeline) {
|
TimelineWindow.prototype.unpaginate = function(delta, startOfTimeline) {
|
||||||
let tl = startOfTimeline ? this._start : this._end;
|
const tl = startOfTimeline ? this._start : this._end;
|
||||||
|
|
||||||
// sanity-check the delta
|
// sanity-check the delta
|
||||||
if (delta > this._eventCount || delta < 0) {
|
if (delta > this._eventCount || delta < 0) {
|
||||||
@@ -307,7 +307,7 @@ TimelineWindow.prototype.unpaginate = function(delta, startOfTimeline) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (delta > 0) {
|
while (delta > 0) {
|
||||||
let count = startOfTimeline ? tl.advance(delta) : tl.retreat(delta);
|
const count = startOfTimeline ? tl.advance(delta) : tl.retreat(delta);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
// sadness. This shouldn't be possible.
|
// sadness. This shouldn't be possible.
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -334,13 +334,13 @@ TimelineWindow.prototype.getEvents = function() {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = [];
|
const result = [];
|
||||||
|
|
||||||
// iterate through each timeline between this._start and this._end
|
// iterate through each timeline between this._start and this._end
|
||||||
// (inclusive).
|
// (inclusive).
|
||||||
let timeline = this._start.timeline;
|
let timeline = this._start.timeline;
|
||||||
while (true) {
|
while (true) {
|
||||||
let events = timeline.getEvents();
|
const events = timeline.getEvents();
|
||||||
|
|
||||||
// For the first timeline in the chain, we want to start at
|
// For the first timeline in the chain, we want to start at
|
||||||
// this._start.index. For the last timeline in the chain, we want to
|
// this._start.index. For the last timeline in the chain, we want to
|
||||||
@@ -447,7 +447,7 @@ TimelineIndex.prototype.advance = function(delta) {
|
|||||||
// the index is already at the start/end of the current timeline.
|
// the index is already at the start/end of the current timeline.
|
||||||
//
|
//
|
||||||
// next see if there is a neighbouring timeline to switch to.
|
// next see if there is a neighbouring timeline to switch to.
|
||||||
let neighbour = this.timeline.getNeighbouringTimeline(
|
const neighbour = this.timeline.getNeighbouringTimeline(
|
||||||
delta < 0 ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS);
|
delta < 0 ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS);
|
||||||
if (neighbour) {
|
if (neighbour) {
|
||||||
this.timeline = neighbour;
|
this.timeline = neighbour;
|
||||||
|
|||||||
58
src/utils.js
58
src/utils.js
@@ -27,7 +27,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
module.exports.encodeParams = function(params) {
|
module.exports.encodeParams = function(params) {
|
||||||
let qs = "";
|
let qs = "";
|
||||||
for (let key in params) {
|
for (const key in params) {
|
||||||
if (!params.hasOwnProperty(key)) {
|
if (!params.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -46,12 +46,12 @@ module.exports.encodeParams = function(params) {
|
|||||||
* @return {string} The result of replacing all template variables e.g. '/foo/baz'.
|
* @return {string} The result of replacing all template variables e.g. '/foo/baz'.
|
||||||
*/
|
*/
|
||||||
module.exports.encodeUri = function(pathTemplate, variables) {
|
module.exports.encodeUri = function(pathTemplate, variables) {
|
||||||
for (let key in variables) {
|
for (const key in variables) {
|
||||||
if (!variables.hasOwnProperty(key)) {
|
if (!variables.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pathTemplate = pathTemplate.replace(
|
pathTemplate = pathTemplate.replace(
|
||||||
key, encodeURIComponent(variables[key])
|
key, encodeURIComponent(variables[key]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return pathTemplate;
|
return pathTemplate;
|
||||||
@@ -65,7 +65,7 @@ module.exports.encodeUri = function(pathTemplate, variables) {
|
|||||||
* @return {Array} A new array with the results of the function.
|
* @return {Array} A new array with the results of the function.
|
||||||
*/
|
*/
|
||||||
module.exports.map = function(array, fn) {
|
module.exports.map = function(array, fn) {
|
||||||
let results = new Array(array.length);
|
const results = new Array(array.length);
|
||||||
for (let i = 0; i < array.length; i++) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
results[i] = fn(array[i]);
|
results[i] = fn(array[i]);
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ module.exports.map = function(array, fn) {
|
|||||||
* @return {Array} A new array with the results of the function.
|
* @return {Array} A new array with the results of the function.
|
||||||
*/
|
*/
|
||||||
module.exports.filter = function(array, fn) {
|
module.exports.filter = function(array, fn) {
|
||||||
let results = [];
|
const results = [];
|
||||||
for (let i = 0; i < array.length; i++) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
if (fn(array[i], i, array)) {
|
if (fn(array[i], i, array)) {
|
||||||
results.push(array[i]);
|
results.push(array[i]);
|
||||||
@@ -96,8 +96,8 @@ module.exports.filter = function(array, fn) {
|
|||||||
* @return {string[]} The keys of the object.
|
* @return {string[]} The keys of the object.
|
||||||
*/
|
*/
|
||||||
module.exports.keys = function(obj) {
|
module.exports.keys = function(obj) {
|
||||||
let keys = [];
|
const keys = [];
|
||||||
for (let key in obj) {
|
for (const key in obj) {
|
||||||
if (!obj.hasOwnProperty(key)) {
|
if (!obj.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -112,8 +112,8 @@ module.exports.keys = function(obj) {
|
|||||||
* @return {Array<*>} The values of the object.
|
* @return {Array<*>} The values of the object.
|
||||||
*/
|
*/
|
||||||
module.exports.values = function(obj) {
|
module.exports.values = function(obj) {
|
||||||
let values = [];
|
const values = [];
|
||||||
for (let key in obj) {
|
for (const key in obj) {
|
||||||
if (!obj.hasOwnProperty(key)) {
|
if (!obj.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ module.exports.checkObjectHasKeys = function(obj, keys) {
|
|||||||
* @throws If there are extra keys.
|
* @throws If there are extra keys.
|
||||||
*/
|
*/
|
||||||
module.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) {
|
module.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) {
|
||||||
for (let key in obj) {
|
for (const key in obj) {
|
||||||
if (!obj.hasOwnProperty(key)) {
|
if (!obj.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -263,7 +263,7 @@ module.exports.deepCopy = function(obj) {
|
|||||||
*
|
*
|
||||||
* @return {boolean} true if the two objects are equal
|
* @return {boolean} true if the two objects are equal
|
||||||
*/
|
*/
|
||||||
let deepCompare = module.exports.deepCompare = function(x, y) {
|
const deepCompare = module.exports.deepCompare = function(x, y) {
|
||||||
// Inspired by
|
// Inspired by
|
||||||
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript#1144249
|
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript#1144249
|
||||||
|
|
||||||
@@ -355,10 +355,10 @@ let deepCompare = module.exports.deepCompare = function(x, y) {
|
|||||||
* @return {Object} target
|
* @return {Object} target
|
||||||
*/
|
*/
|
||||||
module.exports.extend = function() {
|
module.exports.extend = function() {
|
||||||
let target = arguments[0] || {};
|
const target = arguments[0] || {};
|
||||||
for (let i = 1; i < arguments.length; i++) {
|
for (let i = 1; i < arguments.length; i++) {
|
||||||
let source = arguments[i];
|
const source = arguments[i];
|
||||||
for (let propName in source) { // eslint-disable-line guard-for-in
|
for (const propName in source) { // eslint-disable-line guard-for-in
|
||||||
target[propName] = source[propName];
|
target[propName] = source[propName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,17 +379,17 @@ module.exports.runPolyfills = function() {
|
|||||||
throw new TypeError();
|
throw new TypeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
let t = Object(this);
|
const t = Object(this);
|
||||||
let len = t.length >>> 0;
|
const len = t.length >>> 0;
|
||||||
if (typeof fun !== 'function') {
|
if (typeof fun !== 'function') {
|
||||||
throw new TypeError();
|
throw new TypeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = [];
|
const res = [];
|
||||||
let thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
const thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
if (i in t) {
|
if (i in t) {
|
||||||
let val = t[i];
|
const val = t[i];
|
||||||
|
|
||||||
// NOTE: Technically this should Object.defineProperty at
|
// NOTE: Technically this should Object.defineProperty at
|
||||||
// the next index, as push can be affected by
|
// the next index, as push can be affected by
|
||||||
@@ -414,7 +414,7 @@ module.exports.runPolyfills = function() {
|
|||||||
// Reference: http://es5.github.io/#x15.4.4.19
|
// Reference: http://es5.github.io/#x15.4.4.19
|
||||||
if (!Array.prototype.map) {
|
if (!Array.prototype.map) {
|
||||||
Array.prototype.map = function(callback, thisArg) {
|
Array.prototype.map = function(callback, thisArg) {
|
||||||
let T, A, k;
|
let T, k;
|
||||||
|
|
||||||
if (this === null || this === undefined) {
|
if (this === null || this === undefined) {
|
||||||
throw new TypeError(' this is null or not defined');
|
throw new TypeError(' this is null or not defined');
|
||||||
@@ -422,12 +422,12 @@ module.exports.runPolyfills = function() {
|
|||||||
|
|
||||||
// 1. Let O be the result of calling ToObject passing the |this|
|
// 1. Let O be the result of calling ToObject passing the |this|
|
||||||
// value as the argument.
|
// value as the argument.
|
||||||
let O = Object(this);
|
const O = Object(this);
|
||||||
|
|
||||||
// 2. Let lenValue be the result of calling the Get internal
|
// 2. Let lenValue be the result of calling the Get internal
|
||||||
// method of O with the argument "length".
|
// method of O with the argument "length".
|
||||||
// 3. Let len be ToUint32(lenValue).
|
// 3. Let len be ToUint32(lenValue).
|
||||||
let len = O.length >>> 0;
|
const len = O.length >>> 0;
|
||||||
|
|
||||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||||
// See: http://es5.github.com/#x9.11
|
// See: http://es5.github.com/#x9.11
|
||||||
@@ -443,7 +443,7 @@ module.exports.runPolyfills = function() {
|
|||||||
// 6. Let A be a new array created as if by the expression new Array(len)
|
// 6. Let A be a new array created as if by the expression new Array(len)
|
||||||
// where Array is the standard built-in constructor with that name and
|
// where Array is the standard built-in constructor with that name and
|
||||||
// len is the value of len.
|
// len is the value of len.
|
||||||
A = new Array(len);
|
const A = new Array(len);
|
||||||
|
|
||||||
// 7. Let k be 0
|
// 7. Let k be 0
|
||||||
k = 0;
|
k = 0;
|
||||||
@@ -512,12 +512,12 @@ module.exports.runPolyfills = function() {
|
|||||||
|
|
||||||
// 1. Let O be the result of calling ToObject passing the |this| value as the
|
// 1. Let O be the result of calling ToObject passing the |this| value as the
|
||||||
// argument.
|
// argument.
|
||||||
let O = Object(this);
|
const O = Object(this);
|
||||||
|
|
||||||
// 2. Let lenValue be the result of calling the Get internal method of O with the
|
// 2. Let lenValue be the result of calling the Get internal method of O with the
|
||||||
// argument "length".
|
// argument "length".
|
||||||
// 3. Let len be ToUint32(lenValue).
|
// 3. Let len be ToUint32(lenValue).
|
||||||
let len = O.length >>> 0;
|
const len = O.length >>> 0;
|
||||||
|
|
||||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||||
// See: http://es5.github.com/#x9.11
|
// See: http://es5.github.com/#x9.11
|
||||||
@@ -582,7 +582,7 @@ module.exports.inherits = function(ctor, superCtor) {
|
|||||||
function Temp() {}
|
function Temp() {}
|
||||||
|
|
||||||
// make a safe reference to Object.prototype.hasOwnProperty
|
// make a safe reference to Object.prototype.hasOwnProperty
|
||||||
let hasOwn = Object.prototype.hasOwnProperty;
|
const hasOwn = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
return function(O) {
|
return function(O) {
|
||||||
// 1. If Type(O) is not Object or Null throw a TypeError exception.
|
// 1. If Type(O) is not Object or Null throw a TypeError exception.
|
||||||
@@ -595,7 +595,7 @@ module.exports.inherits = function(ctor, superCtor) {
|
|||||||
// constructor with that name
|
// constructor with that name
|
||||||
// 3. Set the [[Prototype]] internal property of obj to O.
|
// 3. Set the [[Prototype]] internal property of obj to O.
|
||||||
Temp.prototype = O;
|
Temp.prototype = O;
|
||||||
let obj = new Temp();
|
const obj = new Temp();
|
||||||
Temp.prototype = null; // Let's not keep a stray reference to O...
|
Temp.prototype = null; // Let's not keep a stray reference to O...
|
||||||
|
|
||||||
// 4. If the argument Properties is present and not undefined, add
|
// 4. If the argument Properties is present and not undefined, add
|
||||||
@@ -604,8 +604,8 @@ module.exports.inherits = function(ctor, superCtor) {
|
|||||||
// Properties.
|
// Properties.
|
||||||
if (arguments.length > 1) {
|
if (arguments.length > 1) {
|
||||||
// Object.defineProperties does ToObject on its first argument.
|
// Object.defineProperties does ToObject on its first argument.
|
||||||
let Properties = Object(arguments[1]);
|
const Properties = Object(arguments[1]);
|
||||||
for (let prop in Properties) {
|
for (const prop in Properties) {
|
||||||
if (hasOwn.call(Properties, prop)) {
|
if (hasOwn.call(Properties, prop)) {
|
||||||
obj[prop] = Properties[prop];
|
obj[prop] = Properties[prop];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ limitations under the License.
|
|||||||
* This is an internal module. See {@link createNewMatrixCall} for the public API.
|
* This is an internal module. See {@link createNewMatrixCall} for the public API.
|
||||||
* @module webrtc/call
|
* @module webrtc/call
|
||||||
*/
|
*/
|
||||||
let utils = require("../utils");
|
const utils = require("../utils");
|
||||||
let EventEmitter = require("events").EventEmitter;
|
const EventEmitter = require("events").EventEmitter;
|
||||||
let DEBUG = true; // set true to enable console logging.
|
const DEBUG = true; // set true to enable console logging.
|
||||||
|
|
||||||
// events: hangup, error(err), replaced(call), state(state, oldState)
|
// events: hangup, error(err), replaced(call), state(state, oldState)
|
||||||
|
|
||||||
@@ -125,24 +125,24 @@ MatrixCall.prototype.placeScreenSharingCall =
|
|||||||
function(remoteVideoElement, localVideoElement) {
|
function(remoteVideoElement, localVideoElement) {
|
||||||
debuglog("placeScreenSharingCall");
|
debuglog("placeScreenSharingCall");
|
||||||
checkForErrorListener(this);
|
checkForErrorListener(this);
|
||||||
let screenConstraints = _getChromeScreenSharingConstraints(this);
|
const screenConstraints = _getChromeScreenSharingConstraints(this);
|
||||||
if (!screenConstraints) {
|
if (!screenConstraints) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.localVideoElement = localVideoElement;
|
this.localVideoElement = localVideoElement;
|
||||||
this.remoteVideoElement = remoteVideoElement;
|
this.remoteVideoElement = remoteVideoElement;
|
||||||
let self = this;
|
const self = this;
|
||||||
this.webRtc.getUserMedia(screenConstraints, function(stream) {
|
this.webRtc.getUserMedia(screenConstraints, function(stream) {
|
||||||
self.screenSharingStream = stream;
|
self.screenSharingStream = stream;
|
||||||
debuglog("Got screen stream, requesting audio stream...");
|
debuglog("Got screen stream, requesting audio stream...");
|
||||||
let audioConstraints = _getUserMediaVideoContraints('voice');
|
const audioConstraints = _getUserMediaVideoContraints('voice');
|
||||||
_placeCallWithConstraints(self, audioConstraints);
|
_placeCallWithConstraints(self, audioConstraints);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
self.emit("error",
|
self.emit("error",
|
||||||
callError(
|
callError(
|
||||||
MatrixCall.ERR_NO_USER_MEDIA,
|
MatrixCall.ERR_NO_USER_MEDIA,
|
||||||
"Failed to get screen-sharing stream: " + err
|
"Failed to get screen-sharing stream: " + err,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
this.type = 'video';
|
this.type = 'video';
|
||||||
@@ -266,9 +266,9 @@ MatrixCall.prototype.setLocalVideoElement = function(element) {
|
|||||||
this.URL.createObjectURL(this.localAVStream),
|
this.URL.createObjectURL(this.localAVStream),
|
||||||
"localVideo");
|
"localVideo");
|
||||||
element.muted = true;
|
element.muted = true;
|
||||||
let self = this;
|
const self = this;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
let vel = self.getLocalVideoElement();
|
const vel = self.getLocalVideoElement();
|
||||||
if (vel.play) {
|
if (vel.play) {
|
||||||
self.playElement(vel, "localVideo");
|
self.playElement(vel, "localVideo");
|
||||||
}
|
}
|
||||||
@@ -306,12 +306,12 @@ MatrixCall.prototype.setRemoteAudioElement = function(element) {
|
|||||||
MatrixCall.prototype._initWithInvite = function(event) {
|
MatrixCall.prototype._initWithInvite = function(event) {
|
||||||
this.msg = event.getContent();
|
this.msg = event.getContent();
|
||||||
this.peerConn = _createPeerConnection(this);
|
this.peerConn = _createPeerConnection(this);
|
||||||
let self = this;
|
const self = this;
|
||||||
if (this.peerConn) {
|
if (this.peerConn) {
|
||||||
this.peerConn.setRemoteDescription(
|
this.peerConn.setRemoteDescription(
|
||||||
new this.webRtc.RtcSessionDescription(this.msg.offer),
|
new this.webRtc.RtcSessionDescription(this.msg.offer),
|
||||||
hookCallback(self, self._onSetRemoteDescriptionSuccess),
|
hookCallback(self, self._onSetRemoteDescriptionSuccess),
|
||||||
hookCallback(self, self._onSetRemoteDescriptionError)
|
hookCallback(self, self._onSetRemoteDescriptionError),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setState(this, 'ringing');
|
setState(this, 'ringing');
|
||||||
@@ -364,13 +364,13 @@ MatrixCall.prototype._initWithHangup = function(event) {
|
|||||||
*/
|
*/
|
||||||
MatrixCall.prototype.answer = function() {
|
MatrixCall.prototype.answer = function() {
|
||||||
debuglog("Answering call %s of type %s", this.callId, this.type);
|
debuglog("Answering call %s of type %s", this.callId, this.type);
|
||||||
let self = this;
|
const self = this;
|
||||||
|
|
||||||
if (!this.localAVStream && !this.waitForLocalAVStream) {
|
if (!this.localAVStream && !this.waitForLocalAVStream) {
|
||||||
this.webRtc.getUserMedia(
|
this.webRtc.getUserMedia(
|
||||||
_getUserMediaVideoContraints(this.type),
|
_getUserMediaVideoContraints(this.type),
|
||||||
hookCallback(self, self._gotUserMediaForAnswer),
|
hookCallback(self, self._gotUserMediaForAnswer),
|
||||||
hookCallback(self, self._getUserMediaFailed)
|
hookCallback(self, self._getUserMediaFailed),
|
||||||
);
|
);
|
||||||
setState(this, 'wait_local_media');
|
setState(this, 'wait_local_media');
|
||||||
} else if (this.localAVStream) {
|
} else if (this.localAVStream) {
|
||||||
@@ -416,7 +416,7 @@ MatrixCall.prototype._replacedBy = function(newCall) {
|
|||||||
MatrixCall.prototype.hangup = function(reason, suppressEvent) {
|
MatrixCall.prototype.hangup = function(reason, suppressEvent) {
|
||||||
debuglog("Ending call " + this.callId);
|
debuglog("Ending call " + this.callId);
|
||||||
terminate(this, "local", reason, !suppressEvent);
|
terminate(this, "local", reason, !suppressEvent);
|
||||||
let content = {
|
const content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: this.callId,
|
call_id: this.callId,
|
||||||
reason: reason,
|
reason: reason,
|
||||||
@@ -492,8 +492,8 @@ MatrixCall.prototype._gotUserMediaForInvite = function(stream) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debuglog("_gotUserMediaForInvite -> " + this.type);
|
debuglog("_gotUserMediaForInvite -> " + this.type);
|
||||||
let self = this;
|
const self = this;
|
||||||
let videoEl = this.getLocalVideoElement();
|
const videoEl = this.getLocalVideoElement();
|
||||||
|
|
||||||
if (videoEl && this.type == 'video') {
|
if (videoEl && this.type == 'video') {
|
||||||
videoEl.autoplay = true;
|
videoEl.autoplay = true;
|
||||||
@@ -509,15 +509,17 @@ MatrixCall.prototype._gotUserMediaForInvite = function(stream) {
|
|||||||
}
|
}
|
||||||
videoEl.muted = true;
|
videoEl.muted = true;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
let vel = self.getLocalVideoElement();
|
const vel = self.getLocalVideoElement();
|
||||||
if (vel.play) {
|
if (vel.play) {
|
||||||
self.playElement(vel, "localVideo");
|
self.playElement(vel, "localVideo");
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.screenSharingStream) {
|
||||||
this.screenSharingStream.addTrack(stream.getAudioTracks()[0]);
|
this.screenSharingStream.addTrack(stream.getAudioTracks()[0]);
|
||||||
stream = this.screenSharingStream;
|
stream = this.screenSharingStream;
|
||||||
|
}
|
||||||
|
|
||||||
this.localAVStream = stream;
|
this.localAVStream = stream;
|
||||||
// why do we enable audio (and only audio) tracks here? -- matthew
|
// why do we enable audio (and only audio) tracks here? -- matthew
|
||||||
@@ -526,7 +528,7 @@ MatrixCall.prototype._gotUserMediaForInvite = function(stream) {
|
|||||||
this.peerConn.addStream(stream);
|
this.peerConn.addStream(stream);
|
||||||
this.peerConn.createOffer(
|
this.peerConn.createOffer(
|
||||||
hookCallback(self, self._gotLocalOffer),
|
hookCallback(self, self._gotLocalOffer),
|
||||||
hookCallback(self, self._getLocalOfferFailed)
|
hookCallback(self, self._getLocalOfferFailed),
|
||||||
);
|
);
|
||||||
setState(self, 'create_offer');
|
setState(self, 'create_offer');
|
||||||
};
|
};
|
||||||
@@ -537,11 +539,11 @@ MatrixCall.prototype._gotUserMediaForInvite = function(stream) {
|
|||||||
* @param {Object} stream
|
* @param {Object} stream
|
||||||
*/
|
*/
|
||||||
MatrixCall.prototype._gotUserMediaForAnswer = function(stream) {
|
MatrixCall.prototype._gotUserMediaForAnswer = function(stream) {
|
||||||
let self = this;
|
const self = this;
|
||||||
if (self.state == 'ended') {
|
if (self.state == 'ended') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let localVidEl = self.getLocalVideoElement();
|
const localVidEl = self.getLocalVideoElement();
|
||||||
|
|
||||||
if (localVidEl && self.type == 'video') {
|
if (localVidEl && self.type == 'video') {
|
||||||
localVidEl.autoplay = true;
|
localVidEl.autoplay = true;
|
||||||
@@ -550,7 +552,7 @@ MatrixCall.prototype._gotUserMediaForAnswer = function(stream) {
|
|||||||
"localVideo");
|
"localVideo");
|
||||||
localVidEl.muted = true;
|
localVidEl.muted = true;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
let vel = self.getLocalVideoElement();
|
const vel = self.getLocalVideoElement();
|
||||||
if (vel.play) {
|
if (vel.play) {
|
||||||
self.playElement(vel, "localVideo");
|
self.playElement(vel, "localVideo");
|
||||||
}
|
}
|
||||||
@@ -561,7 +563,7 @@ MatrixCall.prototype._gotUserMediaForAnswer = function(stream) {
|
|||||||
setTracksEnabled(stream.getAudioTracks(), true);
|
setTracksEnabled(stream.getAudioTracks(), true);
|
||||||
self.peerConn.addStream(stream);
|
self.peerConn.addStream(stream);
|
||||||
|
|
||||||
let constraints = {
|
const constraints = {
|
||||||
'mandatory': {
|
'mandatory': {
|
||||||
'OfferToReceiveAudio': true,
|
'OfferToReceiveAudio': true,
|
||||||
'OfferToReceiveVideo': self.type == 'video',
|
'OfferToReceiveVideo': self.type == 'video',
|
||||||
@@ -570,7 +572,7 @@ MatrixCall.prototype._gotUserMediaForAnswer = function(stream) {
|
|||||||
self.peerConn.createAnswer(function(description) {
|
self.peerConn.createAnswer(function(description) {
|
||||||
debuglog("Created answer: " + description);
|
debuglog("Created answer: " + description);
|
||||||
self.peerConn.setLocalDescription(description, function() {
|
self.peerConn.setLocalDescription(description, function() {
|
||||||
let content = {
|
const content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: self.callId,
|
call_id: self.callId,
|
||||||
answer: {
|
answer: {
|
||||||
@@ -598,11 +600,11 @@ MatrixCall.prototype._gotLocalIceCandidate = function(event) {
|
|||||||
if (event.candidate) {
|
if (event.candidate) {
|
||||||
debuglog(
|
debuglog(
|
||||||
"Got local ICE " + event.candidate.sdpMid + " candidate: " +
|
"Got local ICE " + event.candidate.sdpMid + " candidate: " +
|
||||||
event.candidate.candidate
|
event.candidate.candidate,
|
||||||
);
|
);
|
||||||
// As with the offer, note we need to make a copy of this object, not
|
// As with the offer, note we need to make a copy of this object, not
|
||||||
// pass the original: that broke in Chrome ~m43.
|
// pass the original: that broke in Chrome ~m43.
|
||||||
let c = {
|
const c = {
|
||||||
candidate: event.candidate.candidate,
|
candidate: event.candidate.candidate,
|
||||||
sdpMid: event.candidate.sdpMid,
|
sdpMid: event.candidate.sdpMid,
|
||||||
sdpMLineIndex: event.candidate.sdpMLineIndex,
|
sdpMLineIndex: event.candidate.sdpMLineIndex,
|
||||||
@@ -625,7 +627,7 @@ MatrixCall.prototype._gotRemoteIceCandidate = function(cand) {
|
|||||||
this.peerConn.addIceCandidate(
|
this.peerConn.addIceCandidate(
|
||||||
new this.webRtc.RtcIceCandidate(cand),
|
new this.webRtc.RtcIceCandidate(cand),
|
||||||
function() {},
|
function() {},
|
||||||
function(e) {}
|
function(e) {},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -639,11 +641,11 @@ MatrixCall.prototype._receivedAnswer = function(msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
this.peerConn.setRemoteDescription(
|
this.peerConn.setRemoteDescription(
|
||||||
new this.webRtc.RtcSessionDescription(msg.answer),
|
new this.webRtc.RtcSessionDescription(msg.answer),
|
||||||
hookCallback(self, self._onSetRemoteDescriptionSuccess),
|
hookCallback(self, self._onSetRemoteDescriptionSuccess),
|
||||||
hookCallback(self, self._onSetRemoteDescriptionError)
|
hookCallback(self, self._onSetRemoteDescriptionError),
|
||||||
);
|
);
|
||||||
setState(self, 'connecting');
|
setState(self, 'connecting');
|
||||||
};
|
};
|
||||||
@@ -654,7 +656,7 @@ MatrixCall.prototype._receivedAnswer = function(msg) {
|
|||||||
* @param {Object} description
|
* @param {Object} description
|
||||||
*/
|
*/
|
||||||
MatrixCall.prototype._gotLocalOffer = function(description) {
|
MatrixCall.prototype._gotLocalOffer = function(description) {
|
||||||
let self = this;
|
const self = this;
|
||||||
debuglog("Created offer: " + description);
|
debuglog("Created offer: " + description);
|
||||||
|
|
||||||
if (self.state == 'ended') {
|
if (self.state == 'ended') {
|
||||||
@@ -664,7 +666,7 @@ MatrixCall.prototype._gotLocalOffer = function(description) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.peerConn.setLocalDescription(description, function() {
|
self.peerConn.setLocalDescription(description, function() {
|
||||||
let content = {
|
const content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: self.callId,
|
call_id: self.callId,
|
||||||
// OpenWebRTC appears to add extra stuff (like the DTLS fingerprint)
|
// OpenWebRTC appears to add extra stuff (like the DTLS fingerprint)
|
||||||
@@ -703,7 +705,7 @@ MatrixCall.prototype._gotLocalOffer = function(description) {
|
|||||||
MatrixCall.prototype._getLocalOfferFailed = function(error) {
|
MatrixCall.prototype._getLocalOfferFailed = function(error) {
|
||||||
this.emit(
|
this.emit(
|
||||||
"error",
|
"error",
|
||||||
callError(MatrixCall.ERR_LOCAL_OFFER_FAILED, "Failed to start audio for call!")
|
callError(MatrixCall.ERR_LOCAL_OFFER_FAILED, "Failed to start audio for call!"),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -718,8 +720,8 @@ MatrixCall.prototype._getUserMediaFailed = function(error) {
|
|||||||
callError(
|
callError(
|
||||||
MatrixCall.ERR_NO_USER_MEDIA,
|
MatrixCall.ERR_NO_USER_MEDIA,
|
||||||
"Couldn't start capturing media! Is your microphone set up and " +
|
"Couldn't start capturing media! Is your microphone set up and " +
|
||||||
"does this app have permission?"
|
"does this app have permission?",
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
this.hangup("user_media_failed");
|
this.hangup("user_media_failed");
|
||||||
};
|
};
|
||||||
@@ -733,7 +735,7 @@ MatrixCall.prototype._onIceConnectionStateChanged = function() {
|
|||||||
return; // because ICE can still complete as we're ending the call
|
return; // because ICE can still complete as we're ending the call
|
||||||
}
|
}
|
||||||
debuglog(
|
debuglog(
|
||||||
"Ice connection state changed to: " + this.peerConn.iceConnectionState
|
"Ice connection state changed to: " + this.peerConn.iceConnectionState,
|
||||||
);
|
);
|
||||||
// ideally we'd consider the call to be connected when we get media but
|
// ideally we'd consider the call to be connected when we get media but
|
||||||
// chrome doesn't implement any of the 'onstarted' events yet
|
// chrome doesn't implement any of the 'onstarted' events yet
|
||||||
@@ -753,7 +755,7 @@ MatrixCall.prototype._onIceConnectionStateChanged = function() {
|
|||||||
MatrixCall.prototype._onSignallingStateChanged = function() {
|
MatrixCall.prototype._onSignallingStateChanged = function() {
|
||||||
debuglog(
|
debuglog(
|
||||||
"call " + this.callId + ": Signalling state changed to: " +
|
"call " + this.callId + ": Signalling state changed to: " +
|
||||||
this.peerConn.signalingState
|
this.peerConn.signalingState,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -782,7 +784,7 @@ MatrixCall.prototype._onSetRemoteDescriptionError = function(e) {
|
|||||||
MatrixCall.prototype._onAddStream = function(event) {
|
MatrixCall.prototype._onAddStream = function(event) {
|
||||||
debuglog("Stream id " + event.stream.id + " added");
|
debuglog("Stream id " + event.stream.id + " added");
|
||||||
|
|
||||||
let s = event.stream;
|
const s = event.stream;
|
||||||
|
|
||||||
if (s.getVideoTracks().length > 0) {
|
if (s.getVideoTracks().length > 0) {
|
||||||
this.type = 'video';
|
this.type = 'video';
|
||||||
@@ -793,7 +795,7 @@ MatrixCall.prototype._onAddStream = function(event) {
|
|||||||
this.remoteAStream = s;
|
this.remoteAStream = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
const self = this;
|
||||||
forAllTracksOnStream(s, function(t) {
|
forAllTracksOnStream(s, function(t) {
|
||||||
debuglog("Track id " + t.id + " added");
|
debuglog("Track id " + t.id + " added");
|
||||||
// not currently implemented in chrome
|
// not currently implemented in chrome
|
||||||
@@ -872,13 +874,13 @@ MatrixCall.prototype._onAnsweredElsewhere = function(msg) {
|
|||||||
terminate(this, "remote", "answered_elsewhere", true);
|
terminate(this, "remote", "answered_elsewhere", true);
|
||||||
};
|
};
|
||||||
|
|
||||||
let setTracksEnabled = function(tracks, enabled) {
|
const setTracksEnabled = function(tracks, enabled) {
|
||||||
for (let i = 0; i < tracks.length; i++) {
|
for (let i = 0; i < tracks.length; i++) {
|
||||||
tracks[i].enabled = enabled;
|
tracks[i].enabled = enabled;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let isTracksEnabled = function(tracks) {
|
const isTracksEnabled = function(tracks) {
|
||||||
for (let i = 0; i < tracks.length; i++) {
|
for (let i = 0; i < tracks.length; i++) {
|
||||||
if (tracks[i].enabled) {
|
if (tracks[i].enabled) {
|
||||||
return true; // at least one track is enabled
|
return true; // at least one track is enabled
|
||||||
@@ -887,8 +889,8 @@ let isTracksEnabled = function(tracks) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let setState = function(self, state) {
|
const setState = function(self, state) {
|
||||||
let oldState = self.state;
|
const oldState = self.state;
|
||||||
self.state = state;
|
self.state = state;
|
||||||
self.emit("state", state, oldState);
|
self.emit("state", state, oldState);
|
||||||
};
|
};
|
||||||
@@ -900,11 +902,11 @@ let setState = function(self, state) {
|
|||||||
* @param {Object} content
|
* @param {Object} content
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
let sendEvent = function(self, eventType, content) {
|
const sendEvent = function(self, eventType, content) {
|
||||||
return self.client.sendEvent(self.roomId, eventType, content);
|
return self.client.sendEvent(self.roomId, eventType, content);
|
||||||
};
|
};
|
||||||
|
|
||||||
let sendCandidate = function(self, content) {
|
const sendCandidate = function(self, content) {
|
||||||
// Sends candidates with are sent in a special way because we try to amalgamate
|
// Sends candidates with are sent in a special way because we try to amalgamate
|
||||||
// them into one message
|
// them into one message
|
||||||
self.candidateSendQueue.push(content);
|
self.candidateSendQueue.push(content);
|
||||||
@@ -915,7 +917,7 @@ let sendCandidate = function(self, content) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let terminate = function(self, hangupParty, hangupReason, shouldEmit) {
|
const terminate = function(self, hangupParty, hangupReason, shouldEmit) {
|
||||||
if (self.getRemoteVideoElement()) {
|
if (self.getRemoteVideoElement()) {
|
||||||
if (self.getRemoteVideoElement().pause) {
|
if (self.getRemoteVideoElement().pause) {
|
||||||
self.pauseElement(self.getRemoteVideoElement(), "remoteVideo");
|
self.pauseElement(self.getRemoteVideoElement(), "remoteVideo");
|
||||||
@@ -946,7 +948,7 @@ let terminate = function(self, hangupParty, hangupReason, shouldEmit) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let stopAllMedia = function(self) {
|
const stopAllMedia = function(self) {
|
||||||
debuglog("stopAllMedia (stream=%s)", self.localAVStream);
|
debuglog("stopAllMedia (stream=%s)", self.localAVStream);
|
||||||
if (self.localAVStream) {
|
if (self.localAVStream) {
|
||||||
forAllTracksOnStream(self.localAVStream, function(t) {
|
forAllTracksOnStream(self.localAVStream, function(t) {
|
||||||
@@ -986,15 +988,15 @@ let stopAllMedia = function(self) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let _tryPlayRemoteStream = function(self) {
|
const _tryPlayRemoteStream = function(self) {
|
||||||
if (self.getRemoteVideoElement() && self.remoteAVStream) {
|
if (self.getRemoteVideoElement() && self.remoteAVStream) {
|
||||||
let player = self.getRemoteVideoElement();
|
const player = self.getRemoteVideoElement();
|
||||||
player.autoplay = true;
|
player.autoplay = true;
|
||||||
self.assignElement(player,
|
self.assignElement(player,
|
||||||
self.URL.createObjectURL(self.remoteAVStream),
|
self.URL.createObjectURL(self.remoteAVStream),
|
||||||
"remoteVideo");
|
"remoteVideo");
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
let vel = self.getRemoteVideoElement();
|
const vel = self.getRemoteVideoElement();
|
||||||
if (vel.play) {
|
if (vel.play) {
|
||||||
self.playElement(vel, "remoteVideo");
|
self.playElement(vel, "remoteVideo");
|
||||||
}
|
}
|
||||||
@@ -1006,15 +1008,15 @@ let _tryPlayRemoteStream = function(self) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let _tryPlayRemoteAudioStream = function(self) {
|
const _tryPlayRemoteAudioStream = function(self) {
|
||||||
if (self.getRemoteAudioElement() && self.remoteAStream) {
|
if (self.getRemoteAudioElement() && self.remoteAStream) {
|
||||||
let player = self.getRemoteAudioElement();
|
const player = self.getRemoteAudioElement();
|
||||||
player.autoplay = true;
|
player.autoplay = true;
|
||||||
self.assignElement(player,
|
self.assignElement(player,
|
||||||
self.URL.createObjectURL(self.remoteAStream),
|
self.URL.createObjectURL(self.remoteAStream),
|
||||||
"remoteAudio");
|
"remoteAudio");
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
let ael = self.getRemoteAudioElement();
|
const ael = self.getRemoteAudioElement();
|
||||||
if (ael.play) {
|
if (ael.play) {
|
||||||
self.playElement(ael, "remoteAudio");
|
self.playElement(ael, "remoteAudio");
|
||||||
}
|
}
|
||||||
@@ -1026,35 +1028,35 @@ let _tryPlayRemoteAudioStream = function(self) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let checkForErrorListener = function(self) {
|
const checkForErrorListener = function(self) {
|
||||||
if (self.listeners("error").length === 0) {
|
if (self.listeners("error").length === 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"You MUST attach an error listener using call.on('error', function() {})"
|
"You MUST attach an error listener using call.on('error', function() {})",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let callError = function(code, msg) {
|
const callError = function(code, msg) {
|
||||||
let e = new Error(msg);
|
const e = new Error(msg);
|
||||||
e.code = code;
|
e.code = code;
|
||||||
return e;
|
return e;
|
||||||
};
|
};
|
||||||
|
|
||||||
let debuglog = function() {
|
const debuglog = function() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
console.log(...arguments);
|
console.log(...arguments);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let _sendCandidateQueue = function(self) {
|
const _sendCandidateQueue = function(self) {
|
||||||
if (self.candidateSendQueue.length === 0) {
|
if (self.candidateSendQueue.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cands = self.candidateSendQueue;
|
const cands = self.candidateSendQueue;
|
||||||
self.candidateSendQueue = [];
|
self.candidateSendQueue = [];
|
||||||
++self.candidateSendTries;
|
++self.candidateSendTries;
|
||||||
let content = {
|
const content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: self.callId,
|
call_id: self.callId,
|
||||||
candidates: cands,
|
candidates: cands,
|
||||||
@@ -1071,13 +1073,13 @@ let _sendCandidateQueue = function(self) {
|
|||||||
if (self.candidateSendTries > 5) {
|
if (self.candidateSendTries > 5) {
|
||||||
debuglog(
|
debuglog(
|
||||||
"Failed to send candidates on attempt %s. Giving up for now.",
|
"Failed to send candidates on attempt %s. Giving up for now.",
|
||||||
self.candidateSendTries
|
self.candidateSendTries,
|
||||||
);
|
);
|
||||||
self.candidateSendTries = 0;
|
self.candidateSendTries = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let delayMs = 500 * Math.pow(2, self.candidateSendTries);
|
const delayMs = 500 * Math.pow(2, self.candidateSendTries);
|
||||||
++self.candidateSendTries;
|
++self.candidateSendTries;
|
||||||
debuglog("Failed to send candidates. Retrying in " + delayMs + "ms");
|
debuglog("Failed to send candidates. Retrying in " + delayMs + "ms");
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@@ -1086,19 +1088,19 @@ let _sendCandidateQueue = function(self) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let _placeCallWithConstraints = function(self, constraints) {
|
const _placeCallWithConstraints = function(self, constraints) {
|
||||||
self.client.callList[self.callId] = self;
|
self.client.callList[self.callId] = self;
|
||||||
self.webRtc.getUserMedia(
|
self.webRtc.getUserMedia(
|
||||||
constraints,
|
constraints,
|
||||||
hookCallback(self, self._gotUserMediaForInvite),
|
hookCallback(self, self._gotUserMediaForInvite),
|
||||||
hookCallback(self, self._getUserMediaFailed)
|
hookCallback(self, self._getUserMediaFailed),
|
||||||
);
|
);
|
||||||
setState(self, 'wait_local_media');
|
setState(self, 'wait_local_media');
|
||||||
self.direction = 'outbound';
|
self.direction = 'outbound';
|
||||||
self.config = constraints;
|
self.config = constraints;
|
||||||
};
|
};
|
||||||
|
|
||||||
let _createPeerConnection = function(self) {
|
const _createPeerConnection = function(self) {
|
||||||
let servers = self.turnServers;
|
let servers = self.turnServers;
|
||||||
if (self.webRtc.vendor === "mozilla") {
|
if (self.webRtc.vendor === "mozilla") {
|
||||||
// modify turnServers struct to match what mozilla expects.
|
// modify turnServers struct to match what mozilla expects.
|
||||||
@@ -1114,7 +1116,7 @@ let _createPeerConnection = function(self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pc = new self.webRtc.RtcPeerConnection({
|
const pc = new self.webRtc.RtcPeerConnection({
|
||||||
iceServers: servers,
|
iceServers: servers,
|
||||||
});
|
});
|
||||||
pc.oniceconnectionstatechange = hookCallback(self, self._onIceConnectionStateChanged);
|
pc.oniceconnectionstatechange = hookCallback(self, self._onIceConnectionStateChanged);
|
||||||
@@ -1124,12 +1126,12 @@ let _createPeerConnection = function(self) {
|
|||||||
return pc;
|
return pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
let _getChromeScreenSharingConstraints = function(call) {
|
const _getChromeScreenSharingConstraints = function(call) {
|
||||||
let screen = global.screen;
|
const screen = global.screen;
|
||||||
if (!screen) {
|
if (!screen) {
|
||||||
call.emit("error", callError(
|
call.emit("error", callError(
|
||||||
MatrixCall.ERR_NO_USER_MEDIA,
|
MatrixCall.ERR_NO_USER_MEDIA,
|
||||||
"Couldn't determine screen sharing constaints."
|
"Couldn't determine screen sharing constaints.",
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1148,7 +1150,7 @@ let _getChromeScreenSharingConstraints = function(call) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
let _getUserMediaVideoContraints = function(callType) {
|
const _getUserMediaVideoContraints = function(callType) {
|
||||||
switch (callType) {
|
switch (callType) {
|
||||||
case 'voice':
|
case 'voice':
|
||||||
return ({audio: true, video: false});
|
return ({audio: true, video: false});
|
||||||
@@ -1164,27 +1166,27 @@ let _getUserMediaVideoContraints = function(callType) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let hookCallback = function(call, fn) {
|
const hookCallback = function(call, fn) {
|
||||||
return function() {
|
return function() {
|
||||||
return fn.apply(call, arguments);
|
return fn.apply(call, arguments);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
let forAllVideoTracksOnStream = function(s, f) {
|
const forAllVideoTracksOnStream = function(s, f) {
|
||||||
let tracks = s.getVideoTracks();
|
const tracks = s.getVideoTracks();
|
||||||
for (let i = 0; i < tracks.length; i++) {
|
for (let i = 0; i < tracks.length; i++) {
|
||||||
f(tracks[i]);
|
f(tracks[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let forAllAudioTracksOnStream = function(s, f) {
|
const forAllAudioTracksOnStream = function(s, f) {
|
||||||
let tracks = s.getAudioTracks();
|
const tracks = s.getAudioTracks();
|
||||||
for (let i = 0; i < tracks.length; i++) {
|
for (let i = 0; i < tracks.length; i++) {
|
||||||
f(tracks[i]);
|
f(tracks[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let forAllTracksOnStream = function(s, f) {
|
const forAllTracksOnStream = function(s, f) {
|
||||||
forAllVideoTracksOnStream(s, f);
|
forAllVideoTracksOnStream(s, f);
|
||||||
forAllAudioTracksOnStream(s, f);
|
forAllAudioTracksOnStream(s, f);
|
||||||
};
|
};
|
||||||
@@ -1200,14 +1202,14 @@ module.exports.MatrixCall = MatrixCall;
|
|||||||
* @return {MatrixCall} the call or null if the browser doesn't support calling.
|
* @return {MatrixCall} the call or null if the browser doesn't support calling.
|
||||||
*/
|
*/
|
||||||
module.exports.createNewMatrixCall = function(client, roomId) {
|
module.exports.createNewMatrixCall = function(client, roomId) {
|
||||||
let w = global.window;
|
const w = global.window;
|
||||||
let doc = global.document;
|
const doc = global.document;
|
||||||
if (!w || !doc) {
|
if (!w || !doc) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let webRtc = {};
|
const webRtc = {};
|
||||||
webRtc.isOpenWebRTC = function() {
|
webRtc.isOpenWebRTC = function() {
|
||||||
let scripts = doc.getElementById("script");
|
const scripts = doc.getElementById("script");
|
||||||
if (!scripts || !scripts.length) {
|
if (!scripts || !scripts.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1218,7 +1220,7 @@ module.exports.createNewMatrixCall = function(client, roomId) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let getUserMedia = (
|
const getUserMedia = (
|
||||||
w.navigator.getUserMedia || w.navigator.webkitGetUserMedia ||
|
w.navigator.getUserMedia || w.navigator.webkitGetUserMedia ||
|
||||||
w.navigator.mozGetUserMedia
|
w.navigator.mozGetUserMedia
|
||||||
);
|
);
|
||||||
@@ -1249,7 +1251,7 @@ module.exports.createNewMatrixCall = function(client, roomId) {
|
|||||||
!webRtc.RtcPeerConnection || !webRtc.getUserMedia) {
|
!webRtc.RtcPeerConnection || !webRtc.getUserMedia) {
|
||||||
return null; // WebRTC is not supported.
|
return null; // WebRTC is not supported.
|
||||||
}
|
}
|
||||||
let opts = {
|
const opts = {
|
||||||
webRtc: webRtc,
|
webRtc: webRtc,
|
||||||
client: client,
|
client: client,
|
||||||
URL: w.URL,
|
URL: w.URL,
|
||||||
|
|||||||
Reference in New Issue
Block a user