forked from mystiq/hydrogen-web
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;
|
return this._isContinuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isUnverified() {
|
||||||
|
return this._entry.isUnverified;
|
||||||
|
}
|
||||||
|
|
||||||
_getContent() {
|
_getContent() {
|
||||||
return this._entry.content;
|
return this._entry.content;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ export class Sync {
|
||||||
storeNames.userIdentities,
|
storeNames.userIdentities,
|
||||||
storeNames.inboundGroupSessions,
|
storeNames.inboundGroupSessions,
|
||||||
storeNames.groupSessionDecryptions,
|
storeNames.groupSessionDecryptions,
|
||||||
|
storeNames.deviceIdentities,
|
||||||
]);
|
]);
|
||||||
const roomChanges = [];
|
const roomChanges = [];
|
||||||
let sessionChanges;
|
let sessionChanges;
|
||||||
|
|
|
@ -270,4 +270,8 @@ export class DeviceTracker {
|
||||||
});
|
});
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getDeviceByCurve25519Key(curve25519Key, txn) {
|
||||||
|
return await txn.deviceIdentities.getByCurve25519Key(curve25519Key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,14 @@ export class RoomEncryption {
|
||||||
this._megolmSyncCache = this._megolmDecryption.createSessionCache();
|
this._megolmSyncCache = this._megolmDecryption.createSessionCache();
|
||||||
// not `event_id`, but an internal event id passed in to the decrypt methods
|
// not `event_id`, but an internal event id passed in to the decrypt methods
|
||||||
this._eventIdsByMissingSession = new Map();
|
this._eventIdsByMissingSession = new Map();
|
||||||
|
this._senderDeviceCache = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyTimelineClosed() {
|
notifyTimelineClosed() {
|
||||||
// empty the backfill cache when closing the timeline
|
// empty the backfill cache when closing the timeline
|
||||||
this._megolmBackfillCache.dispose();
|
this._megolmBackfillCache.dispose();
|
||||||
this._megolmBackfillCache = this._megolmDecryption.createSessionCache();
|
this._megolmBackfillCache = this._megolmDecryption.createSessionCache();
|
||||||
|
this._senderDeviceCache = new Map(); // purge the sender device cache
|
||||||
}
|
}
|
||||||
|
|
||||||
async writeMemberChanges(memberChanges, txn) {
|
async writeMemberChanges(memberChanges, txn) {
|
||||||
|
@ -56,9 +58,25 @@ export class RoomEncryption {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
this._addMissingSessionEvent(event, isSync, retryData);
|
this._addMissingSessionEvent(event, isSync, retryData);
|
||||||
}
|
}
|
||||||
|
if (result && isTimelineOpen) {
|
||||||
|
await this._verifyDecryptionResult(result, txn);
|
||||||
|
}
|
||||||
return result;
|
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) {
|
_addMissingSessionEvent(event, isSync, data) {
|
||||||
const senderKey = event.content?.["sender_key"];
|
const senderKey = event.content?.["sender_key"];
|
||||||
const sessionId = event.content?.["session_id"];
|
const sessionId = event.content?.["session_id"];
|
||||||
|
|
|
@ -57,6 +57,7 @@ export class Room extends EventEmitter {
|
||||||
this._storage.storeNames.timelineEvents,
|
this._storage.storeNames.timelineEvents,
|
||||||
this._storage.storeNames.inboundGroupSessions,
|
this._storage.storeNames.inboundGroupSessions,
|
||||||
this._storage.storeNames.groupSessionDecryptions,
|
this._storage.storeNames.groupSessionDecryptions,
|
||||||
|
this._storage.storeNames.deviceIdentities,
|
||||||
]);
|
]);
|
||||||
try {
|
try {
|
||||||
for (const retryEntry of retryEntries) {
|
for (const retryEntry of retryEntries) {
|
||||||
|
@ -280,6 +281,7 @@ export class Room extends EventEmitter {
|
||||||
stores = stores.concat([
|
stores = stores.concat([
|
||||||
this._storage.storeNames.inboundGroupSessions,
|
this._storage.storeNames.inboundGroupSessions,
|
||||||
this._storage.storeNames.groupSessionDecryptions,
|
this._storage.storeNames.groupSessionDecryptions,
|
||||||
|
this._storage.storeNames.deviceIdentities,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
const txn = await this._storage.readWriteTxn(stores);
|
const txn = await this._storage.readWriteTxn(stores);
|
||||||
|
|
|
@ -78,6 +78,16 @@ export class EventEntry extends BaseEntry {
|
||||||
this._decryptionResult = result;
|
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) {
|
setDecryptionError(err) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ export class TimelineReader {
|
||||||
this._storage.storeNames.timelineFragments,
|
this._storage.storeNames.timelineFragments,
|
||||||
this._storage.storeNames.inboundGroupSessions,
|
this._storage.storeNames.inboundGroupSessions,
|
||||||
this._storage.storeNames.groupSessionDecryptions,
|
this._storage.storeNames.groupSessionDecryptions,
|
||||||
|
this._storage.storeNames.deviceIdentities,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,7 @@ export const schema = [
|
||||||
createInboundGroupSessionsStore,
|
createInboundGroupSessionsStore,
|
||||||
createOutboundGroupSessionsStore,
|
createOutboundGroupSessionsStore,
|
||||||
createGroupSessionDecryptions,
|
createGroupSessionDecryptions,
|
||||||
|
addSenderKeyIndexToDeviceStore
|
||||||
];
|
];
|
||||||
// TODO: how to deal with git merge conflicts of this array?
|
// TODO: how to deal with git merge conflicts of this array?
|
||||||
|
|
||||||
|
@ -94,3 +95,9 @@ function createOutboundGroupSessionsStore(db) {
|
||||||
function createGroupSessionDecryptions(db) {
|
function createGroupSessionDecryptions(db) {
|
||||||
db.createObjectStore("groupSessionDecryptions", {keyPath: "key"});
|
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);
|
deviceIdentity.key = encodeKey(deviceIdentity.userId, deviceIdentity.deviceId);
|
||||||
return this._store.put(deviceIdentity);
|
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;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.TextMessageView.unverified .message-container {
|
||||||
|
color: #ff4b55;
|
||||||
|
}
|
||||||
|
|
||||||
.message-container p {
|
.message-container p {
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
line-height: 2.2rem;
|
line-height: 2.2rem;
|
||||||
|
|
|
@ -22,6 +22,7 @@ export function renderMessage(t, vm, children) {
|
||||||
"TextMessageView": true,
|
"TextMessageView": true,
|
||||||
own: vm.isOwn,
|
own: vm.isOwn,
|
||||||
pending: vm.isPending,
|
pending: vm.isPending,
|
||||||
|
unverified: vm.isUnverified,
|
||||||
continuation: vm => vm.isContinuation,
|
continuation: vm => vm.isContinuation,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue