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