Skip to content

Commit b94d81b

Browse files
committed
feat: Send state event to timeline when sharing megolm session
1 parent 51b1005 commit b94d81b

File tree

2 files changed

+73
-24
lines changed

2 files changed

+73
-24
lines changed

lib/encryption/key_manager.dart

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,43 @@ class KeyManager {
292292
return roomInboundGroupSessions[sessionId] = dbSess;
293293
}
294294

295+
void _sendEncryptionInfoEvent({
296+
required String roomId,
297+
required List<String> userIds,
298+
List<String>? deviceIds,
299+
}) async {
300+
await client.database?.transaction(() async {
301+
await client.handleSync(
302+
SyncUpdate(
303+
nextBatch: '',
304+
rooms: RoomsUpdate(
305+
join: {
306+
roomId: JoinedRoomUpdate(
307+
timeline: TimelineUpdate(
308+
events: [
309+
MatrixEvent(
310+
eventId:
311+
'fake_event_${client.generateUniqueTransactionId()}',
312+
content: {
313+
'body':
314+
'${userIds.join(', ')} can now read along${deviceIds != null ? ' on a new device' : ''}',
315+
if (deviceIds != null) 'devices': deviceIds,
316+
'users': userIds,
317+
},
318+
type: 'sdk.dart.matrix.new_megolm_session',
319+
senderId: client.userID!,
320+
originServerTs: DateTime.now(),
321+
),
322+
],
323+
),
324+
),
325+
},
326+
),
327+
),
328+
);
329+
});
330+
}
331+
295332
Map<String, Map<String, bool>> _getDeviceKeyIdMap(
296333
List<DeviceKeys> deviceKeys,
297334
) {
@@ -327,21 +364,6 @@ class KeyManager {
327364
return true;
328365
}
329366

330-
if (!wipe) {
331-
// first check if it needs to be rotated
332-
final encryptionContent =
333-
room.getState(EventTypes.Encryption)?.parsedRoomEncryptionContent;
334-
final maxMessages = encryptionContent?.rotationPeriodMsgs ?? 100;
335-
final maxAge = encryptionContent?.rotationPeriodMs ??
336-
604800000; // default of one week
337-
if ((sess.sentMessages ?? maxMessages) >= maxMessages ||
338-
sess.creationTime
339-
.add(Duration(milliseconds: maxAge))
340-
.isBefore(DateTime.now())) {
341-
wipe = true;
342-
}
343-
}
344-
345367
final inboundSess = await loadInboundGroupSession(
346368
room.id,
347369
sess.outboundGroupSession!.session_id(),
@@ -369,6 +391,7 @@ class KeyManager {
369391
// new user! Gotta send the megolm session to them
370392
devicesToReceive
371393
.addAll(newDeviceKeys.where((d) => newUsers.contains(d.userId)));
394+
_sendEncryptionInfoEvent(roomId: roomId, userIds: newUsers.toList());
372395
}
373396
// okay, now we must test all the individual user devices, if anything new got blocked
374397
// or if we need to send to any new devices.
@@ -388,12 +411,6 @@ class KeyManager {
388411
.map((e) => e.key)
389412
.toSet()
390413
: <String>{};
391-
// we don't really care about old devices that got dropped (deleted), we only care if new ones got added and if new ones got blocked
392-
// check if new devices got blocked
393-
if (newBlockedDevices.difference(oldBlockedDevices).isNotEmpty) {
394-
wipe = true;
395-
break;
396-
}
397414
// and now add all the new devices!
398415
final oldDeviceIds = sess.devices.containsKey(userId)
399416
? sess.devices[userId]!.entries
@@ -409,14 +426,30 @@ class KeyManager {
409426
.toSet()
410427
: <String>{};
411428

429+
// check if any new devices need keys
430+
final newDevices = newDeviceIds.difference(oldDeviceIds);
431+
432+
if (userId != client.userID && newDevices.isNotEmpty) {
433+
_sendEncryptionInfoEvent(
434+
roomId: roomId,
435+
userIds: [userId],
436+
deviceIds: newDevices.toList(),
437+
);
438+
}
439+
440+
// we don't really care about old devices that got dropped (deleted), we only care if new ones got added and if new ones got blocked
441+
// check if new devices got blocked
442+
if (newBlockedDevices.difference(oldBlockedDevices).isNotEmpty) {
443+
wipe = true;
444+
continue;
445+
}
446+
412447
// check if a device got removed
413448
if (oldDeviceIds.difference(newDeviceIds).isNotEmpty) {
414449
wipe = true;
415-
break;
450+
continue;
416451
}
417452

418-
// check if any new devices need keys
419-
final newDevices = newDeviceIds.difference(oldDeviceIds);
420453
if (newDeviceIds.isNotEmpty) {
421454
devicesToReceive.addAll(
422455
newDeviceKeys.where(
@@ -427,6 +460,21 @@ class KeyManager {
427460
}
428461
}
429462

463+
if (!wipe) {
464+
// first check if it needs to be rotated
465+
final encryptionContent =
466+
room.getState(EventTypes.Encryption)?.parsedRoomEncryptionContent;
467+
final maxMessages = encryptionContent?.rotationPeriodMsgs ?? 100;
468+
final maxAge = encryptionContent?.rotationPeriodMs ??
469+
604800000; // default of one week
470+
if ((sess.sentMessages ?? maxMessages) >= maxMessages ||
471+
sess.creationTime
472+
.add(Duration(milliseconds: maxAge))
473+
.isBefore(DateTime.now())) {
474+
wipe = true;
475+
}
476+
}
477+
430478
if (!wipe) {
431479
if (!use) {
432480
return false;

lib/src/utils/event_localizations.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ abstract class EventLocalizations {
119119
EventTypes.Sticker: (event, i18n, body) => i18n.sentASticker(
120120
event.senderFromMemoryOrFallback.calcDisplayname(i18n: i18n),
121121
),
122+
'sdk.dart.matrix.new_megolm_session': (event, i18n, body) => body,
122123
EventTypes.Redaction: (event, i18n, body) => i18n.redactedAnEvent(event),
123124
EventTypes.RoomAliases: (event, i18n, body) => i18n.changedTheRoomAliases(
124125
event.senderFromMemoryOrFallback.calcDisplayname(i18n: i18n),

0 commit comments

Comments
 (0)