Merge pull request #1918 from famedly/nico/fix-archive-rooms-becoming-joined
fix archive rooms becoming joined
This commit is contained in:
commit
ca41a963e3
|
|
@ -164,6 +164,7 @@ class KeyManager {
|
||||||
if (!client.isLogged() || client.encryption == null) {
|
if (!client.isLogged() || client.encryption == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final storeFuture = client.database
|
final storeFuture = client.database
|
||||||
?.storeInboundGroupSession(
|
?.storeInboundGroupSession(
|
||||||
roomId,
|
roomId,
|
||||||
|
|
@ -200,8 +201,19 @@ class KeyManager {
|
||||||
await client.database?.transaction(() async {
|
await client.database?.transaction(() async {
|
||||||
await client.handleSync(
|
await client.handleSync(
|
||||||
SyncUpdate(
|
SyncUpdate(
|
||||||
nextBatch: '',
|
nextBatch: '',
|
||||||
rooms: RoomsUpdate(join: {room.id: JoinedRoomUpdate()})),
|
rooms: switch (room.membership) {
|
||||||
|
Membership.join =>
|
||||||
|
RoomsUpdate(join: {room.id: JoinedRoomUpdate()}),
|
||||||
|
Membership.ban ||
|
||||||
|
Membership.leave =>
|
||||||
|
RoomsUpdate(leave: {room.id: LeftRoomUpdate()}),
|
||||||
|
Membership.invite =>
|
||||||
|
RoomsUpdate(invite: {room.id: InvitedRoomUpdate()}),
|
||||||
|
Membership.knock =>
|
||||||
|
RoomsUpdate(knock: {room.id: KnockRoomUpdate()}),
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,13 @@ class RoomsUpdate {
|
||||||
Map<String, JoinedRoomUpdate>? join;
|
Map<String, JoinedRoomUpdate>? join;
|
||||||
Map<String, InvitedRoomUpdate>? invite;
|
Map<String, InvitedRoomUpdate>? invite;
|
||||||
Map<String, LeftRoomUpdate>? leave;
|
Map<String, LeftRoomUpdate>? leave;
|
||||||
|
Map<String, KnockRoomUpdate>? knock;
|
||||||
|
|
||||||
RoomsUpdate({
|
RoomsUpdate({
|
||||||
this.join,
|
this.join,
|
||||||
this.invite,
|
this.invite,
|
||||||
this.leave,
|
this.leave,
|
||||||
|
this.knock,
|
||||||
});
|
});
|
||||||
|
|
||||||
RoomsUpdate.fromJson(Map<String, Object?> json) {
|
RoomsUpdate.fromJson(Map<String, Object?> json) {
|
||||||
|
|
@ -128,6 +130,8 @@ class RoomsUpdate {
|
||||||
MapEntry(k, InvitedRoomUpdate.fromJson(v as Map<String, Object?>)));
|
MapEntry(k, InvitedRoomUpdate.fromJson(v as Map<String, Object?>)));
|
||||||
leave = json.tryGetMap<String, Object?>('leave')?.catchMap((k, v) =>
|
leave = json.tryGetMap<String, Object?>('leave')?.catchMap((k, v) =>
|
||||||
MapEntry(k, LeftRoomUpdate.fromJson(v as Map<String, Object?>)));
|
MapEntry(k, LeftRoomUpdate.fromJson(v as Map<String, Object?>)));
|
||||||
|
knock = json.tryGetMap<String, Object?>('knock')?.catchMap((k, v) =>
|
||||||
|
MapEntry(k, KnockRoomUpdate.fromJson(v as Map<String, Object?>)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object?> toJson() {
|
Map<String, Object?> toJson() {
|
||||||
|
|
@ -141,6 +145,9 @@ class RoomsUpdate {
|
||||||
if (leave != null) {
|
if (leave != null) {
|
||||||
data['leave'] = leave!.map((k, v) => MapEntry(k, v.toJson()));
|
data['leave'] = leave!.map((k, v) => MapEntry(k, v.toJson()));
|
||||||
}
|
}
|
||||||
|
if (knock != null) {
|
||||||
|
data['knock'] = knock!.map((k, v) => MapEntry(k, v.toJson()));
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -234,6 +241,28 @@ class InvitedRoomUpdate extends SyncRoomUpdate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class KnockRoomUpdate extends SyncRoomUpdate {
|
||||||
|
List<StrippedStateEvent>? knockState;
|
||||||
|
|
||||||
|
KnockRoomUpdate({this.knockState});
|
||||||
|
|
||||||
|
KnockRoomUpdate.fromJson(Map<String, Object?> json)
|
||||||
|
: knockState = json
|
||||||
|
.tryGetMap<String, List<Object?>>('knock_state')?['events']
|
||||||
|
?.map((i) => StrippedStateEvent.fromJson(i as Map<String, Object?>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Map<String, Object?> toJson() {
|
||||||
|
final data = <String, Object?>{};
|
||||||
|
if (knockState != null) {
|
||||||
|
data['knock_state'] = {
|
||||||
|
'events': knockState!.map((i) => i.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class LeftRoomUpdate extends SyncRoomUpdate {
|
class LeftRoomUpdate extends SyncRoomUpdate {
|
||||||
List<MatrixEvent>? state;
|
List<MatrixEvent>? state;
|
||||||
TimelineUpdate? timeline;
|
TimelineUpdate? timeline;
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,8 @@ class BoxCollection with ZoneTransactionMixin {
|
||||||
|
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
assert(_txnCache == null, 'Database closed while in transaction!');
|
assert(_txnCache == null, 'Database closed while in transaction!');
|
||||||
return _db.close();
|
// Note, zoneTransaction and txnCache are different kinds of transactions.
|
||||||
|
return zoneTransaction(() async => _db.close());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated('use collection.deleteDatabase now')
|
@Deprecated('use collection.deleteDatabase now')
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class BoxCollection with ZoneTransactionMixin {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<void> close() => _db.close();
|
Future<void> close() => zoneTransaction(() => _db.close());
|
||||||
|
|
||||||
@Deprecated('use collection.deleteDatabase now')
|
@Deprecated('use collection.deleteDatabase now')
|
||||||
static Future<void> delete(String path, [dynamic factory]) =>
|
static Future<void> delete(String path, [dynamic factory]) =>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import 'package:test/test.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'fake_client.dart';
|
import 'fake_client.dart';
|
||||||
|
|
||||||
void main() {
|
void main() async {
|
||||||
group('Timeline', () {
|
group('Timeline', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
|
|
||||||
|
|
@ -115,6 +115,66 @@ void main() {
|
||||||
expect(client.getArchiveRoomFromCache('!5345234235:example.com'), null);
|
expect(client.getArchiveRoomFromCache('!5345234235:example.com'), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("assert that key updates don't change membership", () async {
|
||||||
|
const roomid = '!5345234235:example.com';
|
||||||
|
|
||||||
|
// prep work to be able to set a last event that would trigger the (fixed) bug
|
||||||
|
await client.loadArchiveWithTimeline();
|
||||||
|
expect(client.getArchiveRoomFromCache(roomid) != null, true);
|
||||||
|
expect(client.getRoomById(roomid)?.membership, Membership.leave);
|
||||||
|
|
||||||
|
final outboundSession = await client.encryption?.keyManager
|
||||||
|
.createOutboundGroupSession(roomid);
|
||||||
|
final inboundSession = client.encryption!.keyManager
|
||||||
|
.getInboundGroupSession(
|
||||||
|
roomid, outboundSession!.outboundGroupSession!.session_id())!;
|
||||||
|
|
||||||
|
// ensure encryption is "enabled"
|
||||||
|
client.getRoomById(roomid)?.setState(StrippedStateEvent(
|
||||||
|
type: EventTypes.Encryption,
|
||||||
|
content: {'algorithm': AlgorithmTypes.megolmV1AesSha2},
|
||||||
|
senderId: client.userID!,
|
||||||
|
stateKey: '',
|
||||||
|
));
|
||||||
|
final encryptedEvent = await client.encryption!
|
||||||
|
.encryptGroupMessagePayload(
|
||||||
|
roomid, {'msgtype': 'm.room.text', 'body': 'empty'});
|
||||||
|
|
||||||
|
// reset client
|
||||||
|
await client.dispose().onError((e, s) {});
|
||||||
|
client = await getClient(
|
||||||
|
sendTimelineEventTimeout: const Duration(seconds: 5),
|
||||||
|
);
|
||||||
|
|
||||||
|
await client.abortSync();
|
||||||
|
insertList.clear();
|
||||||
|
|
||||||
|
// now do our tests
|
||||||
|
await client.loadArchiveWithTimeline();
|
||||||
|
expect(client.getArchiveRoomFromCache(roomid) != null, true);
|
||||||
|
expect(client.getRoomById(roomid)?.membership, Membership.leave);
|
||||||
|
|
||||||
|
// set the last event
|
||||||
|
final room = client.getRoomById(roomid)!;
|
||||||
|
room.lastEvent = Event(
|
||||||
|
type: EventTypes.Encrypted,
|
||||||
|
content: encryptedEvent,
|
||||||
|
senderId: client.userID!,
|
||||||
|
eventId: '\$archivedencr',
|
||||||
|
room: room,
|
||||||
|
originServerTs: DateTime.now());
|
||||||
|
|
||||||
|
// import the inbound session
|
||||||
|
await client.encryption!.keyManager.setInboundGroupSession(
|
||||||
|
roomid,
|
||||||
|
inboundSession.sessionId,
|
||||||
|
inboundSession.senderKey,
|
||||||
|
inboundSession.content);
|
||||||
|
|
||||||
|
expect(client.getArchiveRoomFromCache(roomid) != null, true);
|
||||||
|
expect(client.getRoomById(roomid)?.membership, Membership.leave);
|
||||||
|
}, tags: 'olm');
|
||||||
|
|
||||||
test('clear archive', () async {
|
test('clear archive', () async {
|
||||||
await client.loadArchiveWithTimeline();
|
await client.loadArchiveWithTimeline();
|
||||||
client.clearArchivesFromCache();
|
client.clearArchivesFromCache();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue