aboutsummaryrefslogtreecommitdiff
path: root/lib/connection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/connection.cpp')
-rw-r--r--lib/connection.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 1485a347..66590bd8 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -102,6 +102,13 @@ public:
QMetaObject::Connection syncLoopConnection {};
int syncTimeout = -1;
+#ifdef Quotient_E2EE_ENABLED
+ QSet<QString> trackedUsers;
+ QSet<QString> outdatedUsers;
+ QHash<QString, QHash<QString, QueryKeysJob::DeviceInformation>> deviceKeys;
+ QueryKeysJob *currentQueryKeysJob = nullptr;
+#endif
+
GetCapabilitiesJob* capabilitiesJob = nullptr;
GetCapabilitiesJob::Capabilities capabilities;
@@ -153,6 +160,7 @@ public:
void consumeAccountData(Events&& accountDataEvents);
void consumePresenceData(Events&& presenceData);
void consumeToDeviceEvents(Events&& toDeviceEvents);
+ void consumeDevicesList(DevicesList&& devicesList);
template <typename EventT>
EventT* unpackAccountData() const
@@ -247,6 +255,10 @@ public:
return std::move(decryptedEvent);
#endif // Quotient_E2EE_ENABLED
}
+#ifdef Quotient_E2EE_ENABLED
+ void loadOutdatedUserDevices();
+ void createDevicesList();
+#endif
};
Connection::Connection(const QUrl& server, QObject* parent)
@@ -468,6 +480,11 @@ void Connection::Private::completeSetup(const QString& mxId)
emit q->stateChanged();
emit q->connected();
q->reloadCapabilities();
+#ifdef Quotient_E2EE_ENABLED
+ connectSingleShot(q, &Connection::syncDone, q, [=](){
+ createDevicesList();
+ });
+#endif
}
void Connection::Private::checkAndConnect(const QString& userId,
@@ -637,6 +654,7 @@ void Connection::onSyncSuccess(SyncData&& data, bool fromCache)
});
}
#endif // Quotient_E2EE_ENABLED
+ d->consumeDevicesList(data.takeDevicesList());
}
void Connection::Private::consumeRoomData(SyncDataList&& roomDataList,
@@ -790,6 +808,21 @@ void Connection::Private::consumeToDeviceEvents(Events&& toDeviceEvents)
#endif
}
+void Connection::Private::consumeDevicesList(DevicesList&& devicesList)
+{
+#ifdef Quotient_E2EE_ENABLED
+ for(const auto &changed : devicesList.changed) {
+ outdatedUsers += changed;
+ }
+ for(const auto &left : devicesList.left) {
+ trackedUsers -= left;
+ outdatedUsers -= left;
+ deviceKeys.remove(left);
+ }
+ loadOutdatedUserDevices();
+#endif
+}
+
void Connection::stopSync()
{
// If there's a sync loop, break it
@@ -1784,3 +1817,43 @@ QVector<Connection::SupportedRoomVersion> Connection::availableRoomVersions() co
}
return result;
}
+
+#ifdef Quotient_E2EE_ENABLED
+void Connection::Private::createDevicesList()
+{
+ for(const auto &room : q->allRooms()) {
+ if(!room->usesEncryption()) {
+ continue;
+ }
+ for(const auto &user : room->users()) {
+ if(user->id() != q->userId()) {
+ trackedUsers += user->id();
+ }
+ }
+ }
+ outdatedUsers += trackedUsers;
+ loadOutdatedUserDevices();
+}
+
+void Connection::Private::loadOutdatedUserDevices()
+{
+ QHash<QString, QStringList> users;
+ for(const auto &user : outdatedUsers) {
+ users[user] += QStringList();
+ }
+ if(currentQueryKeysJob) {
+ currentQueryKeysJob->abandon();
+ currentQueryKeysJob = nullptr;
+ }
+ auto queryKeysJob = q->callApi<QueryKeysJob>(users);
+ currentQueryKeysJob = queryKeysJob;
+ connect(queryKeysJob, &BaseJob::success, q, [=](){
+ const auto data = queryKeysJob->deviceKeys();
+ for(const auto &[user, keys] : asKeyValueRange(data)) {
+ //TODO Check key signature
+ deviceKeys[user] = keys;
+ outdatedUsers -= user;
+ }
+ });
+}
+#endif