request method
Request a certain key from another device
Implementation
Future<void> request(
Room room,
String sessionId,
String? senderKey, {
bool tryOnlineBackup = true,
bool onlineKeyBackupOnly = false,
}) async {
if (tryOnlineBackup && await isCached()) {
// let's first check our online key backup store thingy...
final hadPreviously = getInboundGroupSession(room.id, sessionId) != null;
try {
await loadSingleKey(room.id, sessionId);
} catch (err, stacktrace) {
if (err is MatrixException && err.errcode == 'M_NOT_FOUND') {
Logs().i(
'[KeyManager] Key not in online key backup, requesting it from other devices...',
);
} else {
Logs().e(
'[KeyManager] Failed to access online key backup',
err,
stacktrace,
);
}
}
// TODO: also don't request from others if we have an index of 0 now
if (!hadPreviously &&
getInboundGroupSession(room.id, sessionId) != null) {
return; // we managed to load the session from online backup, no need to care about it now
}
}
if (onlineKeyBackupOnly) {
return; // we only want to do the online key backup
}
try {
// while we just send the to-device event to '*', we still need to save the
// devices themself to know where to send the cancel to after receiving a reply
final devices = await room.getUserDeviceKeys();
final requestId = client.generateUniqueTransactionId();
final request = KeyManagerKeyShareRequest(
requestId: requestId,
devices: devices,
room: room,
sessionId: sessionId,
);
final userList = await room.requestParticipants();
await client.sendToDevicesOfUserIds(
userList.map<String>((u) => u.id).toSet(),
EventTypes.RoomKeyRequest,
{
'action': 'request',
'body': {
'algorithm': AlgorithmTypes.megolmV1AesSha2,
'room_id': room.id,
'session_id': sessionId,
if (senderKey != null) 'sender_key': senderKey,
},
'request_id': requestId,
'requesting_device_id': client.deviceID,
},
);
outgoingShareRequests[request.requestId] = request;
} catch (e, s) {
Logs().e('[Key Manager] Sending key verification request failed', e, s);
}
}