@@ -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 ;
0 commit comments