request method

Future<void> request(
  1. Room room,
  2. String sessionId,
  3. String? senderKey, {
  4. bool tryOnlineBackup = true,
  5. bool onlineKeyBackupOnly = false,
})

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 SDNException && 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);
  }
}