Merge branch 'master' of ssh://github.com/Nheko-Reborn/nheko

This commit is contained in:
Joseph Donofry 2021-04-13 17:58:39 -04:00
commit a6c89d1362
No known key found for this signature in database
GPG key ID: E8A1D78EF044B0CB
5 changed files with 68 additions and 10 deletions

View file

@ -361,7 +361,7 @@ if(USE_BUNDLED_MTXCLIENT)
FetchContent_Declare( FetchContent_Declare(
MatrixClient MatrixClient
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
GIT_TAG 808605299937203696a572c585a51509b1de28cf GIT_TAG 5b7654c5d4512abc38806a0f44efc199029ceef4
) )
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")

View file

@ -148,7 +148,7 @@ modules:
buildsystem: cmake-ninja buildsystem: cmake-ninja
name: mtxclient name: mtxclient
sources: sources:
- commit: 7194b4f058406b1c10d3741d83abcf2d8963d849 - commit: 5b7654c5d4512abc38806a0f44efc199029ceef4
type: git type: git
url: https://github.com/Nheko-Reborn/mtxclient.git url: https://github.com/Nheko-Reborn/mtxclient.git
- config-opts: - config-opts:

View file

@ -1181,11 +1181,14 @@ Cache::saveState(const mtx::responses::Sync &res)
// Save joined rooms // Save joined rooms
for (const auto &room : res.rooms.join) { for (const auto &room : res.rooms.join) {
auto statesdb = getStatesDb(txn, room.first); auto statesdb = getStatesDb(txn, room.first);
auto membersdb = getMembersDb(txn, room.first); auto stateskeydb = getStatesKeyDb(txn, room.first);
auto membersdb = getMembersDb(txn, room.first);
saveStateEvents(txn, statesdb, membersdb, room.first, room.second.state.events); saveStateEvents(
saveStateEvents(txn, statesdb, membersdb, room.first, room.second.timeline.events); txn, statesdb, stateskeydb, membersdb, room.first, room.second.state.events);
saveStateEvents(
txn, statesdb, stateskeydb, membersdb, room.first, room.second.timeline.events);
saveTimelineMessages(txn, room.first, room.second.timeline); saveTimelineMessages(txn, room.first, room.second.timeline);

View file

@ -273,6 +273,18 @@ public:
return false; return false;
} }
static int compare_state_key(const MDB_val *a, const MDB_val *b)
{
auto get_skey = [](const MDB_val *v) {
return nlohmann::json::parse(
std::string_view(static_cast<const char *>(v->mv_data),
v->mv_size))
.value("key", "");
};
return get_skey(a).compare(get_skey(b));
}
signals: signals:
void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids); void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
void roomReadStatus(const std::map<QString, bool> &status); void roomReadStatus(const std::map<QString, bool> &status);
@ -323,17 +335,19 @@ private:
template<class T> template<class T>
void saveStateEvents(lmdb::txn &txn, void saveStateEvents(lmdb::txn &txn,
lmdb::dbi &statesdb, lmdb::dbi &statesdb,
lmdb::dbi &stateskeydb,
lmdb::dbi &membersdb, lmdb::dbi &membersdb,
const std::string &room_id, const std::string &room_id,
const std::vector<T> &events) const std::vector<T> &events)
{ {
for (const auto &e : events) for (const auto &e : events)
saveStateEvent(txn, statesdb, membersdb, room_id, e); saveStateEvent(txn, statesdb, stateskeydb, membersdb, room_id, e);
} }
template<class T> template<class T>
void saveStateEvent(lmdb::txn &txn, void saveStateEvent(lmdb::txn &txn,
lmdb::dbi &statesdb, lmdb::dbi &statesdb,
lmdb::dbi &stateskeydb,
lmdb::dbi &membersdb, lmdb::dbi &membersdb,
const std::string &room_id, const std::string &room_id,
const T &event) const T &event)
@ -371,9 +385,22 @@ private:
} }
std::visit( std::visit(
[&txn, &statesdb](auto e) { [&txn, &statesdb, &stateskeydb](auto e) {
if (isStateEvent(e) && e.type != EventType::Unsupported) if constexpr (isStateEvent(e))
statesdb.put(txn, to_string(e.type), json(e).dump()); if (e.type != EventType::Unsupported) {
if (e.state_key.empty())
statesdb.put(
txn, to_string(e.type), json(e).dump());
else
stateskeydb.put(
txn,
to_string(e.type),
json::object({
{"key", e.state_key},
{"id", e.event_id},
})
.dump());
}
}, },
event); event);
} }
@ -461,6 +488,14 @@ private:
return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE); return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE);
} }
lmdb::dbi getStatesKeyDb(lmdb::txn &txn, const std::string &room_id)
{
auto db =
lmdb::dbi::open(txn, std::string(room_id + "/state_by_key").c_str(), MDB_CREATE);
lmdb::dbi_set_dupsort(txn, db, compare_state_key);
return db;
}
lmdb::dbi getAccountDataDb(lmdb::txn &txn, const std::string &room_id) lmdb::dbi getAccountDataDb(lmdb::txn &txn, const std::string &room_id)
{ {
return lmdb::dbi::open( return lmdb::dbi::open(

View file

@ -359,6 +359,26 @@ handle_olm_message(const OlmMessage &msg)
return; return;
} }
} }
try {
auto otherUserDeviceKeys = cache::userKeys(msg.sender);
if (!otherUserDeviceKeys)
return;
std::map<std::string, std::vector<std::string>> targets;
for (auto [device_id, key] : otherUserDeviceKeys->device_keys) {
if (key.keys.at("curve25519:" + device_id) == msg.sender_key)
targets[msg.sender].push_back(device_id);
}
send_encrypted_to_device_messages(
targets, mtx::events::DeviceEvent<mtx::events::msg::Dummy>{}, true);
nhlog::crypto()->info(
"Recovering from broken olm channel with {}:{}", msg.sender, msg.sender_key);
} catch (std::exception &e) {
nhlog::crypto()->error("Failed to recover from broken olm sessions: {}", e.what());
}
} }
nlohmann::json nlohmann::json