fix: Better handle olm session recovery

This commit is contained in:
Sorunome 2020-10-17 12:03:54 +02:00
parent 9632d68b92
commit d116a52ea9
No known key found for this signature in database
GPG key ID: B19471D07FC9BE9C
2 changed files with 18 additions and 1 deletions

View file

@ -28,6 +28,7 @@ import '../encryption/utils/json_signature_check_extension.dart';
import '../src/utils/logs.dart';
import 'encryption.dart';
import 'utils/olm_session.dart';
import '../src/utils/run_in_root.dart';
class OlmManager {
final Encryption encryption;
@ -344,6 +345,8 @@ class OlmManager {
return res;
}
final Map<String, DateTime> _restoredOlmSessionsTime = {};
Future<void> restoreOlmSession(String userId, String senderKey) async {
if (!client.userDeviceKeys.containsKey(userId)) {
return;
@ -353,6 +356,15 @@ class OlmManager {
if (device == null) {
return;
}
// per device only one olm session per hour should be restored
final mapKey = '$userId;$senderKey';
if (_restoredOlmSessionsTime.containsKey(mapKey) &&
DateTime.now()
.subtract(Duration(hours: 1))
.isBefore(_restoredOlmSessionsTime[mapKey])) {
return;
}
_restoredOlmSessionsTime[mapKey] = DateTime.now();
await startOutgoingOlmSessions([device]);
await client.sendToDeviceEncrypted([device], 'm.dummy', {});
}
@ -386,7 +398,8 @@ class OlmManager {
} catch (_) {
// okay, the thing errored while decrypting. It is safe to assume that the olm session is corrupt and we should generate a new one
if (client.enableE2eeRecovery) {
unawaited(restoreOlmSession(event.senderId, senderKey));
unawaited(
runInRoot(() => restoreOlmSession(event.senderId, senderKey)));
}
rethrow;
}

View file

@ -869,6 +869,8 @@ class Client extends MatrixApi {
var update = RoomUpdate.fromSyncRoomUpdate(room, id);
if (database != null) {
// TODO: This method seems to be rather slow for some updates
// Perhaps don't dynamically build that one query?
await database.storeRoomUpdate(this.id, update, getRoomById(id));
}
_updateRoomsByRoomUpdate(update);
@ -883,6 +885,7 @@ class Client extends MatrixApi {
/// Handle now all room events and save them in the database
if (room is JoinedRoomUpdate) {
if (room.state?.isNotEmpty ?? false) {
// TODO: This method seems to be comperatively slow for some updates
await _handleRoomEvents(
id, room.state.map((i) => i.toJson()).toList(), 'state');
handledEvents = true;
@ -896,6 +899,7 @@ class Client extends MatrixApi {
handledEvents = true;
}
if (room.ephemeral?.isNotEmpty ?? false) {
// TODO: This method seems to be comperatively slow for some updates
await _handleEphemerals(
id, room.ephemeral.map((i) => i.toJson()).toList());
}