mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +01:00
add method to fetch missing sender keys
This commit is contained in:
parent
c544819b42
commit
9c13b2b4a4
@ -27,6 +27,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type {DeviceIdentity} from "../storage/idb/stores/DeviceIdentityStore";
|
import type {DeviceIdentity} from "../storage/idb/stores/DeviceIdentityStore";
|
||||||
|
import type {TimelineEvent} from "../storage/types";
|
||||||
|
|
||||||
type DecryptedEvent = {
|
type DecryptedEvent = {
|
||||||
type?: string,
|
type?: string,
|
||||||
@ -35,12 +36,12 @@ type DecryptedEvent = {
|
|||||||
|
|
||||||
export class DecryptionResult {
|
export class DecryptionResult {
|
||||||
private device?: DeviceIdentity;
|
private device?: DeviceIdentity;
|
||||||
private roomTracked: boolean = true;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public readonly event: DecryptedEvent,
|
public readonly event: DecryptedEvent,
|
||||||
public readonly senderCurve25519Key: string,
|
public readonly senderCurve25519Key: string,
|
||||||
public readonly claimedEd25519Key: string
|
public readonly claimedEd25519Key: string,
|
||||||
|
public readonly encryptedEvent?: TimelineEvent
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
setDevice(device: DeviceIdentity): void {
|
setDevice(device: DeviceIdentity): void {
|
||||||
|
@ -221,7 +221,30 @@ export class RoomEncryption {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** fetches the devices that are not yet known locally from the homeserver to verify the sender of this message. */
|
||||||
|
_fetchKeyAndVerifyDecryptionResults(results, hsApi, log) {
|
||||||
|
const resultsWithoutDevice = results.filter(r => r.isVerificationUnknown);
|
||||||
|
if (resultsWithoutDevice.length) {
|
||||||
|
return log.wrap("fetch unverified senders", async log => {
|
||||||
|
const sendersWithoutDevice = Array.from(resultsWithoutDevice.reduce((senders, r) => {
|
||||||
|
return senders.add(r.encryptedEvent.sender);
|
||||||
|
}, new Set()));
|
||||||
|
log.set("senders", sendersWithoutDevice);
|
||||||
|
// fetch the devices, ignore return value,
|
||||||
|
// and just reuse _verifyDecryptionResults method so we only have one impl how to verify
|
||||||
|
await this._deviceTracker.devicesForRoomMembers(this._room.id, sendersWithoutDevice, hsApi, log);
|
||||||
|
// now that we've fetched the missing devices, try verifying the results again
|
||||||
|
const txn = await this._storage.readTxn([this._storage.storeNames.deviceIdentities]);
|
||||||
|
return this._verifyDecryptionResults(resultsWithoutDevice, txn);
|
||||||
|
const resultsWithFoundDevice = resultsWithoutDevice.filter(r => !r.isVerificationUnknown);
|
||||||
|
const resultsToEventIdMap = resultsWithFoundDevice.reduce((map, r) => {
|
||||||
|
map.set(r.encryptedEvent.event_id, r);
|
||||||
|
return map;
|
||||||
|
}, new Map());
|
||||||
|
return new BatchDecryptionResult(resultsToEventIdMap, new Map(), this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
return new BatchDecryptionResult(new Map(), new Map(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _requestMissingSessionFromBackup(senderKey, sessionId, log) {
|
async _requestMissingSessionFromBackup(senderKey, sessionId, log) {
|
||||||
@ -553,6 +576,13 @@ class BatchDecryptionResult {
|
|||||||
verifyKnownSenders(txn) {
|
verifyKnownSenders(txn) {
|
||||||
return this._roomEncryption._verifyDecryptionResults(Array.from(this.results.values()), txn);
|
return this._roomEncryption._verifyDecryptionResults(Array.from(this.results.values()), txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Verify any decryption results for which we could not find a device when
|
||||||
|
* calling `verifyKnownSenders` prior, by fetching them from the homeserver.
|
||||||
|
* @returns {Promise<BatchDecryptionResult>} the results for which we found a device */
|
||||||
|
fetchAndVerifyRemainingSenders(hsApi, log) {
|
||||||
|
return this._roomEncryption._fetchKeyAndVerifyDecryptionResults(Array.from(this.results.values()), hsApi, log);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import {createMockStorage} from "../../mocks/Storage";
|
import {createMockStorage} from "../../mocks/Storage";
|
||||||
|
@ -75,7 +75,7 @@ export class SessionDecryption {
|
|||||||
{encryptedRoomId: payload.room_id, eventRoomId: this.key.roomId});
|
{encryptedRoomId: payload.room_id, eventRoomId: this.key.roomId});
|
||||||
}
|
}
|
||||||
replayEntries.push(new ReplayDetectionEntry(this.key.sessionId, decryptionResult!.message_index, event));
|
replayEntries.push(new ReplayDetectionEntry(this.key.sessionId, decryptionResult!.message_index, event));
|
||||||
const result = new DecryptionResult(payload, this.key.senderKey, this.key.claimedEd25519Key);
|
const result = new DecryptionResult(payload, this.key.senderKey, this.key.claimedEd25519Key, event);
|
||||||
results.set(event.event_id, result);
|
results.set(event.event_id, result);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// ignore AbortError from cancelling decryption requests in dispose method
|
// ignore AbortError from cancelling decryption requests in dispose method
|
||||||
|
Loading…
Reference in New Issue
Block a user