Skip to content

Commit d7c4ce8

Browse files
committed
feat: Send state event to timeline when sharing megolm session
1 parent 0874488 commit d7c4ce8

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
@@ -293,6 +293,43 @@ class KeyManager {
293293
return sess;
294294
}
295295

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

331-
if (!wipe) {
332-
// first check if it needs to be rotated
333-
final encryptionContent =
334-
room.getState(EventTypes.Encryption)?.parsedRoomEncryptionContent;
335-
final maxMessages = encryptionContent?.rotationPeriodMsgs ?? 100;
336-
final maxAge = encryptionContent?.rotationPeriodMs ??
337-
604800000; // default of one week
338-
if ((sess.sentMessages ?? maxMessages) >= maxMessages ||
339-
sess.creationTime
340-
.add(Duration(milliseconds: maxAge))
341-
.isBefore(DateTime.now())) {
342-
wipe = true;
343-
}
344-
}
345-
346368
final inboundSess = await loadInboundGroupSession(
347369
room.id,
348370
sess.outboundGroupSession!.session_id(),
@@ -368,6 +390,7 @@ class KeyManager {
368390
// new user! Gotta send the megolm session to them
369391
devicesToReceive
370392
.addAll(newDeviceKeys.where((d) => newUsers.contains(d.userId)));
393+
_sendEncryptionInfoEvent(roomId: roomId, userIds: newUsers.toList());
371394
}
372395
// okay, now we must test all the individual user devices, if anything new got blocked
373396
// or if we need to send to any new devices.
@@ -387,12 +410,6 @@ class KeyManager {
387410
.map((e) => e.key)
388411
.toSet()
389412
: <String>{};
390-
// 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
391-
// check if new devices got blocked
392-
if (newBlockedDevices.difference(oldBlockedDevices).isNotEmpty) {
393-
wipe = true;
394-
break;
395-
}
396413
// and now add all the new devices!
397414
final oldDeviceIds = sess.devices.containsKey(userId)
398415
? sess.devices[userId]!.entries
@@ -408,14 +425,30 @@ class KeyManager {
408425
.toSet()
409426
: <String>{};
410427

428+
// check if any new devices need keys
429+
final newDevices = newDeviceIds.difference(oldDeviceIds);
430+
431+
if (userId != client.userID && newDevices.isNotEmpty) {
432+
_sendEncryptionInfoEvent(
433+
roomId: roomId,
434+
userIds: [userId],
435+
deviceIds: newDevices.toList(),
436+
);
437+
}
438+
439+
// 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
440+
// check if new devices got blocked
441+
if (newBlockedDevices.difference(oldBlockedDevices).isNotEmpty) {
442+
wipe = true;
443+
continue;
444+
}
445+
411446
// check if a device got removed
412447
if (oldDeviceIds.difference(newDeviceIds).isNotEmpty) {
413448
wipe = true;
414-
break;
449+
continue;
415450
}
416451

417-
// check if any new devices need keys
418-
final newDevices = newDeviceIds.difference(oldDeviceIds);
419452
if (newDeviceIds.isNotEmpty) {
420453
devicesToReceive.addAll(
421454
newDeviceKeys.where(
@@ -426,6 +459,21 @@ class KeyManager {
426459
}
427460
}
428461

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