use decryption result to show message verification status in timeline

This commit is contained in:
Bruno Windels 2020-09-08 10:50:39 +02:00
parent 9137d5dcbb
commit c32ac2c764
11 changed files with 56 additions and 0 deletions

View file

@ -71,6 +71,10 @@ export class MessageTile extends SimpleTile {
return this._isContinuation;
}
get isUnverified() {
return this._entry.isUnverified;
}
_getContent() {
return this._entry.content;
}

View file

@ -135,6 +135,7 @@ export class Sync {
storeNames.userIdentities,
storeNames.inboundGroupSessions,
storeNames.groupSessionDecryptions,
storeNames.deviceIdentities,
]);
const roomChanges = [];
let sessionChanges;

View file

@ -270,4 +270,8 @@ export class DeviceTracker {
});
return devices;
}
async getDeviceByCurve25519Key(curve25519Key, txn) {
return await txn.deviceIdentities.getByCurve25519Key(curve25519Key);
}
}

View file

@ -34,12 +34,14 @@ export class RoomEncryption {
this._megolmSyncCache = this._megolmDecryption.createSessionCache();
// not `event_id`, but an internal event id passed in to the decrypt methods
this._eventIdsByMissingSession = new Map();
this._senderDeviceCache = new Map();
}
notifyTimelineClosed() {
// empty the backfill cache when closing the timeline
this._megolmBackfillCache.dispose();
this._megolmBackfillCache = this._megolmDecryption.createSessionCache();
this._senderDeviceCache = new Map(); // purge the sender device cache
}
async writeMemberChanges(memberChanges, txn) {
@ -56,9 +58,25 @@ export class RoomEncryption {
if (!result) {
this._addMissingSessionEvent(event, isSync, retryData);
}
if (result && isTimelineOpen) {
await this._verifyDecryptionResult(result, txn);
}
return result;
}
async _verifyDecryptionResult(result, txn) {
let device = this._senderDeviceCache.get(result.senderCurve25519Key);
if (!device) {
device = await this._deviceTracker.getDeviceByCurve25519Key(result.senderCurve25519Key, txn);
this._senderDeviceCache.set(result.senderCurve25519Key, device);
}
if (device) {
result.setDevice(device);
} else if (!this._room.isTrackingMembers) {
result.setRoomNotTrackedYet();
}
}
_addMissingSessionEvent(event, isSync, data) {
const senderKey = event.content?.["sender_key"];
const sessionId = event.content?.["session_id"];

View file

@ -57,6 +57,7 @@ export class Room extends EventEmitter {
this._storage.storeNames.timelineEvents,
this._storage.storeNames.inboundGroupSessions,
this._storage.storeNames.groupSessionDecryptions,
this._storage.storeNames.deviceIdentities,
]);
try {
for (const retryEntry of retryEntries) {
@ -280,6 +281,7 @@ export class Room extends EventEmitter {
stores = stores.concat([
this._storage.storeNames.inboundGroupSessions,
this._storage.storeNames.groupSessionDecryptions,
this._storage.storeNames.deviceIdentities,
]);
}
const txn = await this._storage.readWriteTxn(stores);

View file

@ -78,6 +78,16 @@ export class EventEntry extends BaseEntry {
this._decryptionResult = result;
}
get isEncrypted() {
return this._eventEntry.event.type === "m.room.encrypted";
}
get isVerified() {
return this.isEncrypted && this._decryptionResult?.isVerified;
}
get isUnverified() {
return this.isEncrypted && this._decryptionResult?.isUnverified;
}
setDecryptionError(err) {

View file

@ -38,6 +38,7 @@ export class TimelineReader {
this._storage.storeNames.timelineFragments,
this._storage.storeNames.inboundGroupSessions,
this._storage.storeNames.groupSessionDecryptions,
this._storage.storeNames.deviceIdentities,
]);
} else {

View file

@ -14,6 +14,7 @@ export const schema = [
createInboundGroupSessionsStore,
createOutboundGroupSessionsStore,
createGroupSessionDecryptions,
addSenderKeyIndexToDeviceStore
];
// TODO: how to deal with git merge conflicts of this array?
@ -94,3 +95,9 @@ function createOutboundGroupSessionsStore(db) {
function createGroupSessionDecryptions(db) {
db.createObjectStore("groupSessionDecryptions", {keyPath: "key"});
}
//v9
function addSenderKeyIndexToDeviceStore(db, txn) {
const deviceIdentities = txn.objectStore("deviceIdentities");
deviceIdentities.createIndex("byCurve25519Key", "curve25519Key", {unique: true});
}

View file

@ -38,4 +38,8 @@ export class DeviceIdentityStore {
deviceIdentity.key = encodeKey(deviceIdentity.userId, deviceIdentity.deviceId);
return this._store.put(deviceIdentity);
}
getByCurve25519Key(curve25519Key) {
return this._store.index("byCurve25519Key").get(curve25519Key);
}
}

View file

@ -373,6 +373,10 @@ ul.Timeline > li.continuation time {
color: #ccc;
}
.TextMessageView.unverified .message-container {
color: #ff4b55;
}
.message-container p {
margin: 3px 0;
line-height: 2.2rem;

View file

@ -22,6 +22,7 @@ export function renderMessage(t, vm, children) {
"TextMessageView": true,
own: vm.isOwn,
pending: vm.isPending,
unverified: vm.isUnverified,
continuation: vm => vm.isContinuation,
};