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 {
Logs().i(
'[KeyManager] Requesting session key for $sessionId for room ${room.id}',
);
if (tryOnlineBackup && await isCached()) {
// let's first check our online key backup store thingy...
final hadSessionBefore =
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,
);
}
}
final storedSession = getInboundGroupSession(room.id, sessionId);
// We loaded *something* from backup we didn't have before — peers are
// unlikely to do better, so don't spam to-device requests.
final loadedFreshFromBackup = !hadSessionBefore && storedSession != null;
// We have the session from its very first index; peers literally cannot
// give us anything better.
final hasFullSession =
storedSession?.inboundGroupSession?.firstKnownIndex == 0;
if (loadedFreshFromBackup || hasFullSession) {
return;
}
}
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,
'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);
}
}