diff --git a/lib/src/event.dart b/lib/src/event.dart index e3699d7..cbd96f0 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -425,6 +425,25 @@ class Event { /// if it fails and does nothing if the event was not encrypted. Event get decrypted => room.decryptGroupMessage(this); + /// Trys to decrypt this event and persists it in the database afterwards + Future decryptAndStore([String updateType = 'timeline']) async { + final newEvent = decrypted; + if (newEvent.type == EventTypes.Encrypted || room.client.database == null) { + return newEvent; // decryption failed or we don't have a database + } + await room.client.database.storeEventUpdate( + room.client.id, + EventUpdate( + eventType: newEvent.typeKey, + content: newEvent.toJson(), + roomID: newEvent.roomId, + type: updateType, + sortOrder: newEvent.sortOrder, + ), + ); + return newEvent; + } + /// If this event is encrypted and the decryption was not successful because /// the session is unknown, this requests the session key from other devices /// in the room. If the event is not encrypted or the decryption failed because diff --git a/lib/src/room.dart b/lib/src/room.dart index 4d199ea..1823d3e 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -271,9 +271,9 @@ class Room { onSessionKeyReceived.add(sessionId); } - void _tryAgainDecryptLastMessage() { + Future _tryAgainDecryptLastMessage() async { if (getState('m.room.encrypted') != null) { - final decrypted = getState('m.room.encrypted').decrypted; + final decrypted = await getState('m.room.encrypted').decryptAndStore(); if (decrypted.type != EventTypes.Encrypted) { setState(decrypted); } @@ -1207,19 +1207,7 @@ class Room { if (events[i].type == EventTypes.Encrypted && events[i].content['body'] == DecryptError.UNKNOWN_SESSION) { await events[i].loadSession(); - events[i] = events[i].decrypted; - if (events[i].type != EventTypes.Encrypted) { - await client.database.storeEventUpdate( - client.id, - EventUpdate( - eventType: events[i].typeKey, - content: events[i].toJson(), - roomID: events[i].roomId, - type: 'timeline', - sortOrder: events[i].sortOrder, - ), - ); - } + events[i] = await events[i].decryptAndStore(); } } }); diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index 9ff2a87..aabf279 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -97,18 +97,25 @@ class Timeline { sessionIdReceivedSub?.cancel(); } - void _sessionKeyReceived(String sessionId) { + void _sessionKeyReceived(String sessionId) async { var decryptAtLeastOneEvent = false; - for (var i = 0; i < events.length; i++) { - if (events[i].type == EventTypes.Encrypted && - events[i].messageType == MessageTypes.BadEncrypted && - events[i].content['body'] == DecryptError.UNKNOWN_SESSION && - events[i].content['session_id'] == sessionId) { - events[i] = events[i].decrypted; - if (events[i].type != EventTypes.Encrypted) { - decryptAtLeastOneEvent = true; + final decryptFn = () async { + for (var i = 0; i < events.length; i++) { + if (events[i].type == EventTypes.Encrypted && + events[i].messageType == MessageTypes.BadEncrypted && + events[i].content['body'] == DecryptError.UNKNOWN_SESSION && + events[i].content['session_id'] == sessionId) { + events[i] = await events[i].decryptAndStore(); + if (events[i].type != EventTypes.Encrypted) { + decryptAtLeastOneEvent = true; + } } } + }; + if (room.client.database != null) { + await room.client.database.transaction(decryptFn); + } else { + await decryptFn(); } if (decryptAtLeastOneEvent) onUpdate(); }