From bc336709af6e0a0a7ec132db991a9418c0f0b149 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 10 Jun 2024 14:22:14 +0200 Subject: [PATCH] fix: state updates being also applied when fetching history This could sometimes lead to the room name or the names of members in the room being incorrect. --- .../database/hive_collections_database.dart | 6 +- lib/src/database/hive_database.dart | 6 +- lib/src/database/matrix_sdk_database.dart | 6 +- test/database_api_test.dart | 118 ++++++++++++++++++ 4 files changed, 133 insertions(+), 3 deletions(-) diff --git a/lib/src/database/hive_collections_database.dart b/lib/src/database/hive_collections_database.dart index 7401500d..abdc67ad 100644 --- a/lib/src/database/hive_collections_database.dart +++ b/lib/src/database/hive_collections_database.dart @@ -1134,7 +1134,11 @@ class HiveCollectionsDatabase extends DatabaseApi { final stateKey = eventUpdate.content['state_key']; // Store a common state event - if (stateKey != null) { + if (stateKey != null && + // Don't store events as state updates when paginating backwards. + (eventUpdate.type == EventUpdateType.timeline || + eventUpdate.type == EventUpdateType.state || + eventUpdate.type == EventUpdateType.inviteState)) { if (eventUpdate.content['type'] == EventTypes.RoomMember) { await _roomMembersBox.put( TupleKey( diff --git a/lib/src/database/hive_database.dart b/lib/src/database/hive_database.dart index 023078a6..e2130912 100644 --- a/lib/src/database/hive_database.dart +++ b/lib/src/database/hive_database.dart @@ -1063,7 +1063,11 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin { final stateKey = eventUpdate.content['state_key']; // Store a common state event - if (stateKey != null) { + if (stateKey != null && + // Don't store events as state updates when paginating backwards. + (eventUpdate.type == EventUpdateType.timeline || + eventUpdate.type == EventUpdateType.state || + eventUpdate.type == EventUpdateType.inviteState)) { if (eventUpdate.content['type'] == EventTypes.RoomMember) { await _roomMembersBox.put( MultiKey( diff --git a/lib/src/database/matrix_sdk_database.dart b/lib/src/database/matrix_sdk_database.dart index 18407abe..c77b5a95 100644 --- a/lib/src/database/matrix_sdk_database.dart +++ b/lib/src/database/matrix_sdk_database.dart @@ -1105,7 +1105,11 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage { final stateKey = eventUpdate.content['state_key']; // Store a common state event - if (stateKey != null) { + if (stateKey != null && + // Don't store events as state updates when paginating backwards. + (eventUpdate.type == EventUpdateType.timeline || + eventUpdate.type == EventUpdateType.state || + eventUpdate.type == EventUpdateType.inviteState)) { if (eventUpdate.content['type'] == EventTypes.RoomMember) { await _roomMembersBox.put( TupleKey( diff --git a/test/database_api_test.dart b/test/database_api_test.dart index 7894da54..fe402e74 100644 --- a/test/database_api_test.dart +++ b/test/database_api_test.dart @@ -231,6 +231,124 @@ void main() { ), Client('testclient')); }); + test('storeEventUpdate (state)', () async { + final roomid = '!testrooma:example.com'; + final client = Client('testclient'); + + await database.storeRoomUpdate( + roomid, + JoinedRoomUpdate(), + null, + client, + ); + + await database.storeEventUpdate( + EventUpdate( + roomID: roomid, + type: EventUpdateType.timeline, + content: { + 'type': EventTypes.RoomName, + 'content': { + 'name': 'start', + }, + 'event_id': '\$eventstart:example.com', + 'sender': '@bob:example.org', + 'state_key': '', + }, + ), + client, + ); + + var room = await database.getSingleRoom(client, roomid); + + expect(room, isNotNull); + + expect(room?.name, 'start'); + + await database.storeEventUpdate( + EventUpdate( + roomID: roomid, + type: EventUpdateType.timeline, + content: { + 'type': EventTypes.RoomName, + 'content': { + 'name': 'update', + }, + 'event_id': '\$eventupdate:example.com', + 'sender': '@bob:example.org', + 'state_key': '', + }, + ), + client, + ); + + room = await database.getSingleRoom(client, roomid); + + expect(room?.name, 'update'); + + await database.storeEventUpdate( + EventUpdate( + roomID: roomid, + type: EventUpdateType.state, + content: { + 'type': EventTypes.RoomName, + 'content': { + 'name': 'update2', + }, + 'event_id': '\$eventupdate2:example.com', + 'sender': '@bob:example.org', + 'state_key': '', + }, + ), + client, + ); + + room = await database.getSingleRoom(client, roomid); + + expect(room?.name, 'update2'); + + await database.storeEventUpdate( + EventUpdate( + roomID: roomid, + type: EventUpdateType.inviteState, + content: { + 'type': EventTypes.RoomName, + 'content': { + 'name': 'update3', + }, + 'event_id': '\$eventupdate3:example.com', + 'sender': '@bob:example.org', + 'state_key': '', + }, + ), + client, + ); + + room = await database.getSingleRoom(client, roomid); + + expect(room?.name, 'update3'); + + await database.storeEventUpdate( + EventUpdate( + roomID: roomid, + type: EventUpdateType.history, + content: { + 'type': EventTypes.RoomName, + 'content': { + 'name': 'notupdate', + }, + 'event_id': '\$eventnotupdate:example.com', + 'sender': '@bob:example.org', + 'state_key': '', + }, + ), + client, + ); + + room = await database.getSingleRoom(client, roomid); + + expect(room?.name, 'update3'); + }); test('getEventById', () async { final event = await database.getEventById('\$event:example.com', Room(id: '!testroom:example.com', client: Client('testclient')));