use decryption result to show message verification status in timeline
This commit is contained in:
parent
9137d5dcbb
commit
c32ac2c764
11 changed files with 56 additions and 0 deletions
|
@ -71,6 +71,10 @@ export class MessageTile extends SimpleTile {
|
|||
return this._isContinuation;
|
||||
}
|
||||
|
||||
get isUnverified() {
|
||||
return this._entry.isUnverified;
|
||||
}
|
||||
|
||||
_getContent() {
|
||||
return this._entry.content;
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ export class Sync {
|
|||
storeNames.userIdentities,
|
||||
storeNames.inboundGroupSessions,
|
||||
storeNames.groupSessionDecryptions,
|
||||
storeNames.deviceIdentities,
|
||||
]);
|
||||
const roomChanges = [];
|
||||
let sessionChanges;
|
||||
|
|
|
@ -270,4 +270,8 @@ export class DeviceTracker {
|
|||
});
|
||||
return devices;
|
||||
}
|
||||
|
||||
async getDeviceByCurve25519Key(curve25519Key, txn) {
|
||||
return await txn.deviceIdentities.getByCurve25519Key(curve25519Key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -38,6 +38,7 @@ export class TimelineReader {
|
|||
this._storage.storeNames.timelineFragments,
|
||||
this._storage.storeNames.inboundGroupSessions,
|
||||
this._storage.storeNames.groupSessionDecryptions,
|
||||
this._storage.storeNames.deviceIdentities,
|
||||
]);
|
||||
|
||||
} else {
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
Reference in a new issue