Merge branch 'soru/megolm-session-on-typing' into 'main'
feat: Start megolm sessions while typing See merge request famedly/famedlysdk!589
This commit is contained in:
commit
71fb80aa1f
|
|
@ -271,7 +271,7 @@ class KeyManager {
|
|||
/// devices have been changed. Returns false if the session has not been cleared because
|
||||
/// it wasn't necessary. Otherwise returns true.
|
||||
Future<bool> clearOrUseOutboundGroupSession(String roomId,
|
||||
{bool wipe = false}) async {
|
||||
{bool wipe = false, bool use = true}) async {
|
||||
final room = client.getRoomById(roomId);
|
||||
final sess = getOutboundGroupSession(roomId);
|
||||
if (room == null || sess == null) {
|
||||
|
|
@ -334,8 +334,13 @@ class KeyManager {
|
|||
break;
|
||||
}
|
||||
// and now add all the new devices!
|
||||
final oldDeviceIds = Set.from(sess.devices[userId].keys);
|
||||
final newDeviceIds = Set.from(newDeviceKeyIds[userId].keys);
|
||||
final oldDeviceIds = Set.from(sess.devices[userId].entries
|
||||
.where((e) => !e.value)
|
||||
.map((e) => e.key));
|
||||
final newDeviceIds = Set.from(newDeviceKeyIds[userId]
|
||||
.entries
|
||||
.where((e) => !e.value)
|
||||
.map((e) => e.key));
|
||||
final newDevices = newDeviceIds.difference(oldDeviceIds);
|
||||
if (newDeviceIds.isNotEmpty) {
|
||||
devicesToReceive.addAll(newDeviceKeys.where(
|
||||
|
|
@ -345,6 +350,9 @@ class KeyManager {
|
|||
}
|
||||
|
||||
if (!wipe) {
|
||||
if (!use) {
|
||||
return false;
|
||||
}
|
||||
// okay, we use the outbound group session!
|
||||
sess.sentMessages++;
|
||||
sess.devices = newDeviceKeyIds;
|
||||
|
|
@ -355,7 +363,7 @@ class KeyManager {
|
|||
'session_key': sess.outboundGroupSession.session_key(),
|
||||
};
|
||||
try {
|
||||
devicesToReceive.removeWhere((k) => k.blocked);
|
||||
devicesToReceive.removeWhere((k) => !k.encryptToDevice);
|
||||
if (devicesToReceive.isNotEmpty) {
|
||||
// update allowedAtIndex
|
||||
for (final device in devicesToReceive) {
|
||||
|
|
@ -394,6 +402,7 @@ class KeyManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Store an outbound group session in the database
|
||||
Future<void> storeOutboundGroupSession(
|
||||
String roomId, OutboundGroupSession sess) async {
|
||||
if (sess == null) {
|
||||
|
|
@ -411,6 +420,7 @@ class KeyManager {
|
|||
final Map<String, Future<OutboundGroupSession>>
|
||||
_pendingNewOutboundGroupSessions = {};
|
||||
|
||||
/// Creates an outbound group session for a given room id
|
||||
Future<OutboundGroupSession> createOutboundGroupSession(String roomId) async {
|
||||
if (_pendingNewOutboundGroupSessions.containsKey(roomId)) {
|
||||
return _pendingNewOutboundGroupSessions[roomId];
|
||||
|
|
@ -421,6 +431,18 @@ class KeyManager {
|
|||
return _pendingNewOutboundGroupSessions.remove(roomId);
|
||||
}
|
||||
|
||||
/// Prepares an outbound group session for a given room ID. That is, load it from
|
||||
/// the database, cycle it if needed and create it if absent.
|
||||
Future<void> prepareOutboundGroupSession(String roomId) async {
|
||||
if (getOutboundGroupSession(roomId) == null) {
|
||||
await loadOutboundGroupSession(roomId);
|
||||
}
|
||||
await clearOrUseOutboundGroupSession(roomId, use: false);
|
||||
if (getOutboundGroupSession(roomId) == null) {
|
||||
await createOutboundGroupSession(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
Future<OutboundGroupSession> _createOutboundGroupSession(
|
||||
String roomId) async {
|
||||
await clearOrUseOutboundGroupSession(roomId, wipe: true);
|
||||
|
|
@ -477,10 +499,12 @@ class KeyManager {
|
|||
return sess;
|
||||
}
|
||||
|
||||
/// Get an outbound group session for a room id
|
||||
OutboundGroupSession getOutboundGroupSession(String roomId) {
|
||||
return _outboundGroupSessions[roomId];
|
||||
}
|
||||
|
||||
/// Load an outbound group session from database
|
||||
Future<void> loadOutboundGroupSession(String roomId) async {
|
||||
if (_loadedOutboundGroupSessions.contains(roomId) ||
|
||||
_outboundGroupSessions.containsKey(roomId) ||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import 'dart:core';
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:pedantic/pedantic.dart';
|
||||
|
||||
import '../encryption.dart';
|
||||
import '../famedlysdk.dart';
|
||||
|
|
@ -542,6 +543,22 @@ class Client extends MatrixApi {
|
|||
return mxc;
|
||||
}
|
||||
|
||||
/// Sends a typing notification and initiates a megolm session, if needed
|
||||
@override
|
||||
Future<void> sendTypingNotification(
|
||||
String userId,
|
||||
String roomId,
|
||||
bool typing, {
|
||||
int timeout,
|
||||
}) async {
|
||||
await super
|
||||
.sendTypingNotification(userId, roomId, typing, timeout: timeout);
|
||||
final room = getRoomById(roomId);
|
||||
if (typing && room != null && encryptionEnabled && room.encrypted) {
|
||||
unawaited(encryption.keyManager.prepareOutboundGroupSession(roomId));
|
||||
}
|
||||
}
|
||||
|
||||
/// Uploads a new user avatar for this user.
|
||||
Future<void> setAvatar(MatrixFile file) async {
|
||||
final uploadResp = await upload(file.bytes, file.name);
|
||||
|
|
|
|||
|
|
@ -133,6 +133,26 @@ void main() {
|
|||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||
.blocked = false;
|
||||
|
||||
// lazy-create if it would rotate
|
||||
sess =
|
||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||
final oldSessKey = sess.outboundGroupSession.session_key();
|
||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||
.blocked = true;
|
||||
await client.encryption.keyManager.prepareOutboundGroupSession(roomId);
|
||||
expect(
|
||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||
true);
|
||||
expect(
|
||||
client.encryption.keyManager
|
||||
.getOutboundGroupSession(roomId)
|
||||
.outboundGroupSession
|
||||
.session_key() !=
|
||||
oldSessKey,
|
||||
true);
|
||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||
.blocked = false;
|
||||
|
||||
// rotate if too far in the past
|
||||
sess =
|
||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue