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
Make multi-room key restore work
This commit is contained in:
@@ -68,6 +68,31 @@ try {
|
|||||||
console.warn("Unable to load crypto module: crypto will be disabled: " + e);
|
console.warn("Unable to load crypto module: crypto will be disabled: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function keysFromRecoverySession(sessions, decryptionKey, roomId, keys) {
|
||||||
|
for (const [sessionId, sessionData] of Object.entries(sessions)) {
|
||||||
|
try {
|
||||||
|
const decrypted = keyFromRecoverySession(sessionData, decryptionKey, keys);
|
||||||
|
decrypted.session_id = sessionId;
|
||||||
|
decrypted.room_id = roomId;
|
||||||
|
return decrypted;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Failed to decrypt session from backup");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyFromRecoverySession(session, decryptionKey, keys) {
|
||||||
|
try {
|
||||||
|
keys.push(JSON.parse(decryptionKey.decrypt(
|
||||||
|
session.session_data.ephemeral,
|
||||||
|
session.session_data.mac,
|
||||||
|
session.session_data.ciphertext
|
||||||
|
)));
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Failed to decrypt key from backup", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a Matrix Client. Only directly construct this if you want to use
|
* Construct a Matrix Client. Only directly construct this if you want to use
|
||||||
* custom modules. Normally, {@link createClient} should be used
|
* custom modules. Normally, {@link createClient} should be used
|
||||||
@@ -966,7 +991,7 @@ MatrixClient.prototype.backupAllGroupSessions = function(version) {
|
|||||||
return this._crypto.backupAllGroupSessions(version);
|
return this._crypto.backupAllGroupSessions(version);
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixClient.prototype.restoreKeyBackups = function(decryptionKey, roomId, sessionId, version, callback) {
|
MatrixClient.prototype.restoreKeyBackups = function(decryptionKey, targetRoomId, targetSessionId, version) {
|
||||||
if (this._crypto === null) {
|
if (this._crypto === null) {
|
||||||
throw new Error("End-to-end encryption disabled");
|
throw new Error("End-to-end encryption disabled");
|
||||||
}
|
}
|
||||||
@@ -975,28 +1000,36 @@ MatrixClient.prototype.restoreKeyBackups = function(decryptionKey, roomId, sessi
|
|||||||
const decryption = new global.Olm.PkDecryption();
|
const decryption = new global.Olm.PkDecryption();
|
||||||
decryption.unpickle("secret_key", decryptionKey);
|
decryption.unpickle("secret_key", decryptionKey);
|
||||||
|
|
||||||
const path = this._makeKeyBackupPath(roomId, sessionId, version);
|
let totalKeyCount = 0;
|
||||||
|
const keys = [];
|
||||||
|
|
||||||
|
const path = this._makeKeyBackupPath(targetRoomId, targetSessionId, version);
|
||||||
return this._http.authedRequest(
|
return this._http.authedRequest(
|
||||||
undefined, "GET", path.path, path.queryData,
|
undefined, "GET", path.path, path.queryData,
|
||||||
).then((res) => {
|
).then((res) => {
|
||||||
const keys = [];
|
if (res.rooms) {
|
||||||
// FIXME: for each room, session, if response has multiple
|
for (const [roomId, roomData] of Object.entries(res.rooms)) {
|
||||||
// decrypt response.data.session_data
|
if (!roomData.sessions) continue;
|
||||||
const session_data = res.session_data;
|
|
||||||
const key = JSON.parse(decryption.decrypt(
|
totalKeyCount += Object.keys(roomData.sessions).length;
|
||||||
session_data.ephemeral,
|
const roomKeys = [];
|
||||||
session_data.mac,
|
keysFromRecoverySession(roomData.sessions, decryption, roomId, roomKeys);
|
||||||
session_data.ciphertext
|
for (const k of roomKeys) {
|
||||||
));
|
k.room_id = roomId;
|
||||||
// set room_id and session_id
|
keys.push(k);
|
||||||
key.room_id = roomId;
|
}
|
||||||
key.session_id = sessionId;
|
}
|
||||||
keys.push(key);
|
} else if (res.sessions) {
|
||||||
|
totalKeyCount = Object.keys(res.sessions).length;
|
||||||
|
keys.push(...keysFromRecoverySession(res.sessions, decryption, roomId, keys));
|
||||||
|
} else {
|
||||||
|
totalKeyCount = 1;
|
||||||
|
keys.push(keyFromRecoverySession(res, decryption, keys));
|
||||||
|
}
|
||||||
|
|
||||||
return this.importRoomKeys(keys);
|
return this.importRoomKeys(keys);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (callback) {
|
return {total: totalKeyCount, imported: keys.length};
|
||||||
callback();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -851,6 +851,8 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
|||||||
if (this._crypto.backupInfo) {
|
if (this._crypto.backupInfo) {
|
||||||
// XXX: No retries on this at all: if this request dies for whatever
|
// XXX: No retries on this at all: if this request dies for whatever
|
||||||
// reason, this key will never be uploaded.
|
// 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,
|
||||||
|
|||||||
Reference in New Issue
Block a user