You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
de-lint plus some minor fixes
This commit is contained in:
@@ -16,6 +16,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
extends: ["eslint:recommended", "google"],
|
extends: ["eslint:recommended", "google"],
|
||||||
rules: {
|
rules: {
|
||||||
|
"indent": ["error", 4],
|
||||||
// rules we've always adhered to or now do
|
// rules we've always adhered to or now do
|
||||||
"max-len": ["error", {
|
"max-len": ["error", {
|
||||||
code: 90,
|
code: 90,
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ if (global.Olm) {
|
|||||||
Crypto = require('../../../lib/crypto');
|
Crypto = require('../../../lib/crypto');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Olm = global.Olm;
|
||||||
|
|
||||||
const MatrixClient = sdk.MatrixClient;
|
const MatrixClient = sdk.MatrixClient;
|
||||||
const MatrixEvent = sdk.MatrixEvent;
|
const MatrixEvent = sdk.MatrixEvent;
|
||||||
const MegolmDecryption = algorithms.DECRYPTION_CLASSES['m.megolm.v1.aes-sha2'];
|
const MegolmDecryption = algorithms.DECRYPTION_CLASSES['m.megolm.v1.aes-sha2'];
|
||||||
@@ -93,16 +95,21 @@ describe("MegolmBackup", function() {
|
|||||||
let sessionStore;
|
let sessionStore;
|
||||||
let cryptoStore;
|
let cryptoStore;
|
||||||
let megolmDecryption;
|
let megolmDecryption;
|
||||||
beforeEach(function() {
|
beforeEach(async function() {
|
||||||
|
await Olm.init();
|
||||||
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
testUtils.beforeEach(this); // eslint-disable-line no-invalid-this
|
||||||
|
|
||||||
mockCrypto = testUtils.mock(Crypto, 'Crypto');
|
mockCrypto = testUtils.mock(Crypto, 'Crypto');
|
||||||
mockCrypto.backupKey = new global.Olm.PkEncryption();
|
mockCrypto.backupKey = new Olm.PkEncryption();
|
||||||
mockCrypto.backupKey.set_recipient_key(
|
mockCrypto.backupKey.set_recipient_key(
|
||||||
"hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo",
|
"hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo",
|
||||||
);
|
);
|
||||||
mockCrypto.backupInfo = {
|
mockCrypto.backupInfo = {
|
||||||
|
algorithm: "m.megolm_backup.v1",
|
||||||
version: 1,
|
version: 1,
|
||||||
|
auth_data: {
|
||||||
|
public_key: "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mockStorage = new MockStorageApi();
|
mockStorage = new MockStorageApi();
|
||||||
@@ -136,7 +143,7 @@ describe("MegolmBackup", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('automatically calls the key back up', function() {
|
it('automatically calls the key back up', function() {
|
||||||
const groupSession = new global.Olm.OutboundGroupSession();
|
const groupSession = new Olm.OutboundGroupSession();
|
||||||
groupSession.create();
|
groupSession.create();
|
||||||
|
|
||||||
// construct a fake decrypted key event via the use of a mocked
|
// construct a fake decrypted key event via the use of a mocked
|
||||||
@@ -161,8 +168,9 @@ describe("MegolmBackup", function() {
|
|||||||
mockCrypto.decryptEvent = function() {
|
mockCrypto.decryptEvent = function() {
|
||||||
return Promise.resolve(decryptedData);
|
return Promise.resolve(decryptedData);
|
||||||
};
|
};
|
||||||
|
mockCrypto.cancelRoomKeyRequest = function() {};
|
||||||
|
|
||||||
mockBaseApis.sendKeyBackup = expect.createSpy();
|
mockCrypto.backupGroupSession = expect.createSpy();
|
||||||
|
|
||||||
return event.attemptDecryption(mockCrypto).then(() => {
|
return event.attemptDecryption(mockCrypto).then(() => {
|
||||||
return megolmDecryption.onRoomKeyEvent(event);
|
return megolmDecryption.onRoomKeyEvent(event);
|
||||||
@@ -171,23 +179,23 @@ describe("MegolmBackup", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends backups to the server', function () {
|
it('sends backups to the server', function() {
|
||||||
this.timeout(12000);
|
this.timeout(12000); // eslint-disable-line no-invalid-this
|
||||||
const groupSession = new global.Olm.OutboundGroupSession();
|
const groupSession = new Olm.OutboundGroupSession();
|
||||||
groupSession.create();
|
groupSession.create();
|
||||||
const ibGroupSession = new global.Olm.InboundGroupSession();
|
const ibGroupSession = new Olm.InboundGroupSession();
|
||||||
ibGroupSession.create(groupSession.session_key());
|
ibGroupSession.create(groupSession.session_key());
|
||||||
|
|
||||||
const scheduler = [
|
const scheduler = [
|
||||||
"getQueueForEvent", "queueEvent", "removeEventFromQueue",
|
"getQueueForEvent", "queueEvent", "removeEventFromQueue",
|
||||||
"setProcessFunction",
|
"setProcessFunction",
|
||||||
].reduce((r, k) => { r[k] = expect.createSpy(); return r; }, {});
|
].reduce((r, k) => {r[k] = expect.createSpy(); return r;}, {});
|
||||||
const store = [
|
const store = [
|
||||||
"getRoom", "getRooms", "getUser", "getSyncToken", "scrollback",
|
"getRoom", "getRooms", "getUser", "getSyncToken", "scrollback",
|
||||||
"save", "wantsSave", "setSyncToken", "storeEvents", "storeRoom",
|
"save", "wantsSave", "setSyncToken", "storeEvents", "storeRoom",
|
||||||
"storeUser", "getFilterIdByName", "setFilterIdByName", "getFilter",
|
"storeUser", "getFilterIdByName", "setFilterIdByName", "getFilter",
|
||||||
"storeFilter", "getSyncAccumulator", "startup", "deleteAllData",
|
"storeFilter", "getSyncAccumulator", "startup", "deleteAllData",
|
||||||
].reduce((r, k) => { r[k] = expect.createSpy(); return r; }, {});
|
].reduce((r, k) => {r[k] = expect.createSpy(); return r;}, {});
|
||||||
store.getSavedSync = expect.createSpy().andReturn(Promise.resolve(null));
|
store.getSavedSync = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
store.getSavedSyncToken = expect.createSpy().andReturn(Promise.resolve(null));
|
store.getSavedSyncToken = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
store.setSyncData = expect.createSpy().andReturn(Promise.resolve(null));
|
store.setSyncData = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
@@ -216,32 +224,37 @@ describe("MegolmBackup", function() {
|
|||||||
|
|
||||||
return client.initCrypto()
|
return client.initCrypto()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return cryptoStore.doTxn("readwrite", [cryptoStore.STORE_SESSION], (txn) => {
|
return cryptoStore.doTxn(
|
||||||
cryptoStore.addEndToEndInboundGroupSession(
|
"readwrite",
|
||||||
"F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI",
|
[cryptoStore.STORE_SESSION],
|
||||||
groupSession.session_id(),
|
(txn) => {
|
||||||
{
|
cryptoStore.addEndToEndInboundGroupSession(
|
||||||
forwardingCurve25519KeyChain: undefined,
|
"F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI",
|
||||||
keysClaimed: {
|
groupSession.session_id(),
|
||||||
ed25519: "SENDER_ED25519",
|
{
|
||||||
|
forwardingCurve25519KeyChain: undefined,
|
||||||
|
keysClaimed: {
|
||||||
|
ed25519: "SENDER_ED25519",
|
||||||
|
},
|
||||||
|
room_id: ROOM_ID,
|
||||||
|
session: ibGroupSession.pickle(olmDevice._pickleKey),
|
||||||
},
|
},
|
||||||
room_id: ROOM_ID,
|
txn);
|
||||||
session: ibGroupSession.pickle(olmDevice._pickleKey),
|
});
|
||||||
},
|
|
||||||
txn);
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
client.enableKeyBackup({
|
client.enableKeyBackup({
|
||||||
algorithm: "foobar",
|
algorithm: "m.megolm_backup.v1",
|
||||||
version: 1,
|
version: 1,
|
||||||
auth_data: {
|
auth_data: {
|
||||||
public_key: "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmoK"
|
public_key: "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let numCalls = 0;
|
let numCalls = 0;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
client._http.authedRequest = function(callback, method, path, queryParams, data, opts) {
|
client._http.authedRequest = function(
|
||||||
|
callback, method, path, queryParams, data, opts,
|
||||||
|
) {
|
||||||
expect(++numCalls <= 1);
|
expect(++numCalls <= 1);
|
||||||
if (numCalls >= 2) {
|
if (numCalls >= 2) {
|
||||||
// exit out of retry loop if there's something wrong
|
// exit out of retry loop if there's something wrong
|
||||||
@@ -252,11 +265,19 @@ describe("MegolmBackup", function() {
|
|||||||
expect(path).toBe("/room_keys/keys");
|
expect(path).toBe("/room_keys/keys");
|
||||||
expect(queryParams.version).toBe(1);
|
expect(queryParams.version).toBe(1);
|
||||||
expect(data.rooms[ROOM_ID].sessions).toExist();
|
expect(data.rooms[ROOM_ID].sessions).toExist();
|
||||||
expect(data.rooms[ROOM_ID].sessions).toIncludeKey(groupSession.session_id());
|
expect(data.rooms[ROOM_ID].sessions).toIncludeKey(
|
||||||
|
groupSession.session_id(),
|
||||||
|
);
|
||||||
resolve();
|
resolve();
|
||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
};
|
};
|
||||||
client._crypto.backupGroupSession("roomId", "F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI", [], groupSession.session_id(), groupSession.session_key());
|
client._crypto.backupGroupSession(
|
||||||
|
"roomId",
|
||||||
|
"F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI",
|
||||||
|
[],
|
||||||
|
groupSession.session_id(),
|
||||||
|
groupSession.session_key(),
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(numCalls).toBe(1);
|
expect(numCalls).toBe(1);
|
||||||
@@ -264,23 +285,23 @@ describe("MegolmBackup", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('retries when a backup fails', function () {
|
it('retries when a backup fails', function() {
|
||||||
this.timeout(12000);
|
this.timeout(12000); // eslint-disable-line no-invalid-this
|
||||||
const groupSession = new global.Olm.OutboundGroupSession();
|
const groupSession = new Olm.OutboundGroupSession();
|
||||||
groupSession.create();
|
groupSession.create();
|
||||||
const ibGroupSession = new global.Olm.InboundGroupSession();
|
const ibGroupSession = new Olm.InboundGroupSession();
|
||||||
ibGroupSession.create(groupSession.session_key());
|
ibGroupSession.create(groupSession.session_key());
|
||||||
|
|
||||||
const scheduler = [
|
const scheduler = [
|
||||||
"getQueueForEvent", "queueEvent", "removeEventFromQueue",
|
"getQueueForEvent", "queueEvent", "removeEventFromQueue",
|
||||||
"setProcessFunction",
|
"setProcessFunction",
|
||||||
].reduce((r, k) => { r[k] = expect.createSpy(); return r; }, {});
|
].reduce((r, k) => {r[k] = expect.createSpy(); return r;}, {});
|
||||||
const store = [
|
const store = [
|
||||||
"getRoom", "getRooms", "getUser", "getSyncToken", "scrollback",
|
"getRoom", "getRooms", "getUser", "getSyncToken", "scrollback",
|
||||||
"save", "wantsSave", "setSyncToken", "storeEvents", "storeRoom",
|
"save", "wantsSave", "setSyncToken", "storeEvents", "storeRoom",
|
||||||
"storeUser", "getFilterIdByName", "setFilterIdByName", "getFilter",
|
"storeUser", "getFilterIdByName", "setFilterIdByName", "getFilter",
|
||||||
"storeFilter", "getSyncAccumulator", "startup", "deleteAllData",
|
"storeFilter", "getSyncAccumulator", "startup", "deleteAllData",
|
||||||
].reduce((r, k) => { r[k] = expect.createSpy(); return r; }, {});
|
].reduce((r, k) => {r[k] = expect.createSpy(); return r;}, {});
|
||||||
store.getSavedSync = expect.createSpy().andReturn(Promise.resolve(null));
|
store.getSavedSync = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
store.getSavedSyncToken = expect.createSpy().andReturn(Promise.resolve(null));
|
store.getSavedSyncToken = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
store.setSyncData = expect.createSpy().andReturn(Promise.resolve(null));
|
store.setSyncData = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
@@ -309,32 +330,37 @@ describe("MegolmBackup", function() {
|
|||||||
|
|
||||||
return client.initCrypto()
|
return client.initCrypto()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return cryptoStore.doTxn("readwrite", [cryptoStore.STORE_SESSION], (txn) => {
|
return cryptoStore.doTxn(
|
||||||
cryptoStore.addEndToEndInboundGroupSession(
|
"readwrite",
|
||||||
"F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI",
|
[cryptoStore.STORE_SESSION],
|
||||||
groupSession.session_id(),
|
(txn) => {
|
||||||
{
|
cryptoStore.addEndToEndInboundGroupSession(
|
||||||
forwardingCurve25519KeyChain: undefined,
|
"F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI",
|
||||||
keysClaimed: {
|
groupSession.session_id(),
|
||||||
ed25519: "SENDER_ED25519",
|
{
|
||||||
|
forwardingCurve25519KeyChain: undefined,
|
||||||
|
keysClaimed: {
|
||||||
|
ed25519: "SENDER_ED25519",
|
||||||
|
},
|
||||||
|
room_id: ROOM_ID,
|
||||||
|
session: ibGroupSession.pickle(olmDevice._pickleKey),
|
||||||
},
|
},
|
||||||
room_id: ROOM_ID,
|
txn);
|
||||||
session: ibGroupSession.pickle(olmDevice._pickleKey),
|
});
|
||||||
},
|
|
||||||
txn);
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
client.enableKeyBackup({
|
client.enableKeyBackup({
|
||||||
algorithm: "foobar",
|
algorithm: "foobar",
|
||||||
version: 1,
|
version: 1,
|
||||||
auth_data: {
|
auth_data: {
|
||||||
public_key: "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmoK"
|
public_key: "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let numCalls = 0;
|
let numCalls = 0;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
client._http.authedRequest = function(callback, method, path, queryParams, data, opts) {
|
client._http.authedRequest = function(
|
||||||
|
callback, method, path, queryParams, data, opts,
|
||||||
|
) {
|
||||||
expect(++numCalls <= 2);
|
expect(++numCalls <= 2);
|
||||||
if (numCalls >= 3) {
|
if (numCalls >= 3) {
|
||||||
// exit out of retry loop if there's something wrong
|
// exit out of retry loop if there's something wrong
|
||||||
@@ -345,15 +371,25 @@ describe("MegolmBackup", function() {
|
|||||||
expect(path).toBe("/room_keys/keys");
|
expect(path).toBe("/room_keys/keys");
|
||||||
expect(queryParams.version).toBe(1);
|
expect(queryParams.version).toBe(1);
|
||||||
expect(data.rooms[ROOM_ID].sessions).toExist();
|
expect(data.rooms[ROOM_ID].sessions).toExist();
|
||||||
expect(data.rooms[ROOM_ID].sessions).toIncludeKey(groupSession.session_id());
|
expect(data.rooms[ROOM_ID].sessions).toIncludeKey(
|
||||||
|
groupSession.session_id(),
|
||||||
|
);
|
||||||
if (numCalls > 1) {
|
if (numCalls > 1) {
|
||||||
resolve();
|
resolve();
|
||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(new Error("this is an expected failure"));
|
return Promise.reject(
|
||||||
|
new Error("this is an expected failure"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
client._crypto.backupGroupSession("roomId", "F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI", [], groupSession.session_id(), groupSession.session_key());
|
client._crypto.backupGroupSession(
|
||||||
|
"roomId",
|
||||||
|
"F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI",
|
||||||
|
[],
|
||||||
|
groupSession.session_id(),
|
||||||
|
groupSession.session_key(),
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(numCalls).toBe(2);
|
expect(numCalls).toBe(2);
|
||||||
@@ -369,13 +405,13 @@ describe("MegolmBackup", function() {
|
|||||||
const scheduler = [
|
const scheduler = [
|
||||||
"getQueueForEvent", "queueEvent", "removeEventFromQueue",
|
"getQueueForEvent", "queueEvent", "removeEventFromQueue",
|
||||||
"setProcessFunction",
|
"setProcessFunction",
|
||||||
].reduce((r, k) => { r[k] = expect.createSpy(); return r; }, {});
|
].reduce((r, k) => {r[k] = expect.createSpy(); return r;}, {});
|
||||||
const store = [
|
const store = [
|
||||||
"getRoom", "getRooms", "getUser", "getSyncToken", "scrollback",
|
"getRoom", "getRooms", "getUser", "getSyncToken", "scrollback",
|
||||||
"save", "wantsSave", "setSyncToken", "storeEvents", "storeRoom",
|
"save", "wantsSave", "setSyncToken", "storeEvents", "storeRoom",
|
||||||
"storeUser", "getFilterIdByName", "setFilterIdByName", "getFilter",
|
"storeUser", "getFilterIdByName", "setFilterIdByName", "getFilter",
|
||||||
"storeFilter", "getSyncAccumulator", "startup", "deleteAllData",
|
"storeFilter", "getSyncAccumulator", "startup", "deleteAllData",
|
||||||
].reduce((r, k) => { r[k] = expect.createSpy(); return r; }, {});
|
].reduce((r, k) => {r[k] = expect.createSpy(); return r;}, {});
|
||||||
store.getSavedSync = expect.createSpy().andReturn(Promise.resolve(null));
|
store.getSavedSync = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
store.getSavedSyncToken = expect.createSpy().andReturn(Promise.resolve(null));
|
store.getSavedSyncToken = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
store.setSyncData = expect.createSpy().andReturn(Promise.resolve(null));
|
store.setSyncData = expect.createSpy().andReturn(Promise.resolve(null));
|
||||||
@@ -411,7 +447,7 @@ describe("MegolmBackup", function() {
|
|||||||
};
|
};
|
||||||
return client.restoreKeyBackups(
|
return client.restoreKeyBackups(
|
||||||
"qx37WTQrjZLz5tId/uBX9B3/okqAbV1ofl9UnHKno1eipByCpXleAAlAZoJgYnCDOQZD"
|
"qx37WTQrjZLz5tId/uBX9B3/okqAbV1ofl9UnHKno1eipByCpXleAAlAZoJgYnCDOQZD"
|
||||||
+ "QWzo3luTSfkF9pU1mOILCbbouubs6TVeDyPfgGD9i86J8irHjA",
|
+ "QWzo3luTSfkF9pU1mOILCbbouubs6TVeDyPfgGD9i86J8irHjA",
|
||||||
ROOM_ID,
|
ROOM_ID,
|
||||||
SESSION_ID,
|
SESSION_ID,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
@@ -435,7 +471,7 @@ describe("MegolmBackup", function() {
|
|||||||
};
|
};
|
||||||
return client.restoreKeyBackups(
|
return client.restoreKeyBackups(
|
||||||
"qx37WTQrjZLz5tId/uBX9B3/okqAbV1ofl9UnHKno1eipByCpXleAAlAZoJgYnCDOQZD"
|
"qx37WTQrjZLz5tId/uBX9B3/okqAbV1ofl9UnHKno1eipByCpXleAAlAZoJgYnCDOQZD"
|
||||||
+ "QWzo3luTSfkF9pU1mOILCbbouubs6TVeDyPfgGD9i86J8irHjA",
|
+ "QWzo3luTSfkF9pU1mOILCbbouubs6TVeDyPfgGD9i86J8irHjA",
|
||||||
).then(() => {
|
).then(() => {
|
||||||
return megolmDecryption.decryptEvent(ENCRYPTED_EVENT);
|
return megolmDecryption.decryptEvent(ENCRYPTED_EVENT);
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
|||||||
@@ -849,10 +849,6 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
|||||||
this._retryDecryption(senderKey, sessionId);
|
this._retryDecryption(senderKey, sessionId);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (this._crypto.backupInfo) {
|
if (this._crypto.backupInfo) {
|
||||||
// XXX: No retries on this at all: if this request dies for whatever
|
|
||||||
// reason, this key will never be uploaded.
|
|
||||||
// More XXX: If this fails it'll cause the message send to fail,
|
|
||||||
// and this will happen if the backup is deleted from another client.
|
|
||||||
return this._crypto.backupGroupSession(
|
return this._crypto.backupGroupSession(
|
||||||
content.room_id, senderKey, forwardingKeyChain,
|
content.room_id, senderKey, forwardingKeyChain,
|
||||||
content.session_id, content.session_key, keysClaimed,
|
content.session_id, content.session_key, keysClaimed,
|
||||||
|
|||||||
@@ -991,33 +991,41 @@ Crypto.prototype._maybeSendKeyBackup = async function() {
|
|||||||
}
|
}
|
||||||
const data = {};
|
const data = {};
|
||||||
for (const session of sessions) {
|
for (const session of sessions) {
|
||||||
const room_id = session.sessionData.room_id;
|
const roomId = session.sessionData.room_id;
|
||||||
if (data[room_id] === undefined)
|
if (data[roomId] === undefined) {
|
||||||
data[room_id] = {sessions: {}};
|
data[roomId] = {sessions: {}};
|
||||||
|
}
|
||||||
|
|
||||||
const sessionData = await this._olmDevice.exportInboundGroupSession(session.senderKey, session.sessionId, session.sessionData);
|
const sessionData = await this._olmDevice.exportInboundGroupSession(
|
||||||
|
session.senderKey, session.sessionId, session.sessionData,
|
||||||
|
);
|
||||||
sessionData.algorithm = olmlib.MEGOLM_ALGORITHM;
|
sessionData.algorithm = olmlib.MEGOLM_ALGORITHM;
|
||||||
delete sessionData.session_id;
|
delete sessionData.session_id;
|
||||||
delete sessionData.room_id;
|
delete sessionData.room_id;
|
||||||
const encrypted = this.backupKey.encrypt(JSON.stringify(sessionData));
|
const encrypted = this.backupKey.encrypt(JSON.stringify(sessionData));
|
||||||
|
|
||||||
data[room_id]['sessions'][session.sessionId] = {
|
data[roomId]['sessions'][session.sessionId] = {
|
||||||
first_message_index: 1, // FIXME
|
first_message_index: 1, // FIXME
|
||||||
forwarded_count: (sessionData.forwardingCurve25519KeyChain || []).length,
|
forwarded_count:
|
||||||
|
(sessionData.forwardingCurve25519KeyChain || []).length,
|
||||||
is_verified: false, // FIXME: how do we determine this?
|
is_verified: false, // FIXME: how do we determine this?
|
||||||
session_data: encrypted,
|
session_data: encrypted,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this._baseApis.sendKeyBackup(undefined, undefined, this.backupInfo.version, {rooms: data});
|
await this._baseApis.sendKeyBackup(
|
||||||
|
undefined, undefined, this.backupInfo.version,
|
||||||
|
{rooms: data},
|
||||||
|
);
|
||||||
numFailures = 0;
|
numFailures = 0;
|
||||||
await this._cryptoStore.unmarkSessionsNeedingBackup(sessions);
|
await this._cryptoStore.unmarkSessionsNeedingBackup(sessions);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
numFailures++;
|
numFailures++;
|
||||||
console.log("send failed", err);
|
console.log("send failed", err);
|
||||||
if (err.httpStatus === 400 || err.httpStatus === 403 || err.httpStatus === 401) {
|
if (err.httpStatus === 400
|
||||||
|
|| err.httpStatus === 403
|
||||||
|
|| err.httpStatus === 401) {
|
||||||
// retrying probably won't help much, so we should give up
|
// retrying probably won't help much, so we should give up
|
||||||
// FIXME: disable backups?
|
// FIXME: disable backups?
|
||||||
return;
|
return;
|
||||||
@@ -1026,17 +1034,18 @@ Crypto.prototype._maybeSendKeyBackup = async function() {
|
|||||||
if (numFailures) {
|
if (numFailures) {
|
||||||
// exponential backoff if we have failures
|
// exponential backoff if we have failures
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
setTimeout(resolve, 1000 * Math.pow(2, Math.min(numFailures - 1, 4)));
|
setTimeout(
|
||||||
|
resolve,
|
||||||
|
1000 * Math.pow(2, Math.min(numFailures - 1, 4)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
finally
|
|
||||||
{
|
|
||||||
this._sendingBackups = false;
|
this._sendingBackups = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Crypto.prototype.backupGroupSession = async function(
|
Crypto.prototype.backupGroupSession = async function(
|
||||||
roomId, senderKey, forwardingCurve25519KeyChain,
|
roomId, senderKey, forwardingCurve25519KeyChain,
|
||||||
@@ -1057,13 +1066,15 @@ Crypto.prototype.backupGroupSession = async function(
|
|||||||
|
|
||||||
Crypto.prototype.backupAllGroupSessions = async function(version) {
|
Crypto.prototype.backupAllGroupSessions = async function(version) {
|
||||||
await this._cryptoStore.doTxn(
|
await this._cryptoStore.doTxn(
|
||||||
'readwrite', [IndexedDBCryptoStore.STORE_SESSIONS, IndexedDBCryptoStore.STORE_BACKUP], (txn) => {
|
'readwrite',
|
||||||
|
[IndexedDBCryptoStore.STORE_SESSIONS, IndexedDBCryptoStore.STORE_BACKUP],
|
||||||
|
(txn) => {
|
||||||
this._cryptoStore.getAllEndToEndInboundGroupSessions(txn, (session) => {
|
this._cryptoStore.getAllEndToEndInboundGroupSessions(txn, (session) => {
|
||||||
if (session !== null) {
|
if (session !== null) {
|
||||||
this._cryptoStore.markSessionsNeedingBackup([session], txn);
|
this._cryptoStore.markSessionsNeedingBackup([session], txn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
this._maybeSendKeyBackup();
|
this._maybeSendKeyBackup();
|
||||||
|
|||||||
@@ -466,31 +466,33 @@ export class Backend {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const sessions = [];
|
const sessions = [];
|
||||||
|
|
||||||
const txn = this._db.transaction(["sessions_needing_backup", "inbound_group_sessions"], "readonly");
|
const txn = this._db.transaction(
|
||||||
|
["sessions_needing_backup", "inbound_group_sessions"],
|
||||||
|
"readonly",
|
||||||
|
);
|
||||||
txn.onerror = reject;
|
txn.onerror = reject;
|
||||||
txn.oncomplete = function() {
|
txn.oncomplete = function() {
|
||||||
resolve(sessions);
|
resolve(sessions);
|
||||||
}
|
};
|
||||||
const objectStore = txn.objectStore("sessions_needing_backup");
|
const objectStore = txn.objectStore("sessions_needing_backup");
|
||||||
const sessionStore = txn.objectStore("inbound_group_sessions");
|
const sessionStore = txn.objectStore("inbound_group_sessions");
|
||||||
const getReq = objectStore.openCursor();
|
const getReq = objectStore.openCursor();
|
||||||
getReq.onsuccess = function() {
|
getReq.onsuccess = function() {
|
||||||
const cursor = getReq.result;
|
const cursor = getReq.result;
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
const sessionGetReq = sessionStore.get(cursor.key)
|
const sessionGetReq = sessionStore.get(cursor.key);
|
||||||
sessionGetReq.onsuccess = function() {
|
sessionGetReq.onsuccess = function() {
|
||||||
sessions.push({
|
sessions.push({
|
||||||
senderKey: sessionGetReq.result.senderCurve25519Key,
|
senderKey: sessionGetReq.result.senderCurve25519Key,
|
||||||
sessionId: sessionGetReq.result.sessionId,
|
sessionId: sessionGetReq.result.sessionId,
|
||||||
sessionData: sessionGetReq.result.session
|
sessionData: sessionGetReq.result.session,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
//sessions.push(cursor.value);
|
|
||||||
if (!limit || sessions.length < limit) {
|
if (!limit || sessions.length < limit) {
|
||||||
cursor.continue();
|
cursor.continue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,13 +518,12 @@ export class Backend {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const req = objectStore.put({
|
const req = objectStore.put({
|
||||||
senderCurve25519Key: session.senderKey,
|
senderCurve25519Key: session.senderKey,
|
||||||
sessionId: session.sessionId
|
sessionId: session.sessionId,
|
||||||
});
|
});
|
||||||
req.onsuccess = resolve;
|
req.onsuccess = resolve;
|
||||||
req.onerror = reject;
|
req.onerror = reject;
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doTxn(mode, stores, func) {
|
doTxn(mode, stores, func) {
|
||||||
|
|||||||
@@ -407,10 +407,13 @@ export default class IndexedDBCryptoStore {
|
|||||||
this._backendPromise.value().getEndToEndRooms(txn, func);
|
this._backendPromise.value().getEndToEndRooms(txn, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// session backups
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the inbound group sessions that need to be backed up.
|
* Get the inbound group sessions that need to be backed up.
|
||||||
* @param {integer} limit The maximum number of sessions to retrieve. 0
|
* @param {integer} limit The maximum number of sessions to retrieve. 0
|
||||||
* for no limit.
|
* for no limit.
|
||||||
|
* @returns {Promise} resolves to an array of inbound group sessions
|
||||||
*/
|
*/
|
||||||
getSessionsNeedingBackup(limit) {
|
getSessionsNeedingBackup(limit) {
|
||||||
return this._connect().then((backend) => {
|
return this._connect().then((backend) => {
|
||||||
@@ -420,7 +423,8 @@ export default class IndexedDBCryptoStore {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmark sessions as needing to be backed up.
|
* Unmark sessions as needing to be backed up.
|
||||||
* @param {[object]} The sessions that need to be backed up.
|
* @param {[object]} sessions The sessions that need to be backed up.
|
||||||
|
* @returns {Promise} resolves when the sessions are unmarked
|
||||||
*/
|
*/
|
||||||
unmarkSessionsNeedingBackup(sessions) {
|
unmarkSessionsNeedingBackup(sessions) {
|
||||||
return this._connect().then((backend) => {
|
return this._connect().then((backend) => {
|
||||||
@@ -430,8 +434,9 @@ export default class IndexedDBCryptoStore {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark sessions as needing to be backed up.
|
* Mark sessions as needing to be backed up.
|
||||||
* @param {[object]} The sessions that need to be backed up.
|
* @param {[object]} sessions The sessions that need to be backed up.
|
||||||
* @param {*} txn An active transaction. See doTxn(). (optional)
|
* @param {*} txn An active transaction. See doTxn(). (optional)
|
||||||
|
* @returns {Promise} resolves when the sessions are marked
|
||||||
*/
|
*/
|
||||||
markSessionsNeedingBackup(sessions, txn) {
|
markSessionsNeedingBackup(sessions, txn) {
|
||||||
return this._connect().then((backend) => {
|
return this._connect().then((backend) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user