diff --git a/CMakeLists.txt b/CMakeLists.txt
index 90cd3d67..a9bdeec1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -336,6 +336,7 @@ set(SRC_FILES
src/encryption/DeviceVerificationFlow.cpp
src/encryption/Olm.cpp
src/encryption/SelfVerificationStatus.cpp
+ src/encryption/VerificationManager.cpp
# Generic notification stuff
src/notifications/Manager.cpp
@@ -548,9 +549,10 @@ qt5_wrap_cpp(MOC_HEADERS
src/voip/CallManager.h
src/voip/WebRTCSession.h
- src/encryption/SelfVerificationStatus.h
src/encryption/DeviceVerificationFlow.h
src/encryption/Olm.h
+ src/encryption/SelfVerificationStatus.h
+ src/encryption/VerificationManager.h
src/notifications/Manager.h
diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml
index 18130469..361099ed 100644
--- a/resources/qml/Root.qml
+++ b/resources/qml/Root.qml
@@ -178,6 +178,10 @@ Page {
dialog.show();
}
+ target: VerificationManager
+ }
+
+ Connections {
function onOpenProfile(profile) {
var userProfile = userProfileComponent.createObject(timelineRoot, {
"profile": profile
diff --git a/resources/qml/device-verification/DeviceVerification.qml b/resources/qml/device-verification/DeviceVerification.qml
index 01e3bad4..5bc8b9c8 100644
--- a/resources/qml/device-verification/DeviceVerification.qml
+++ b/resources/qml/device-verification/DeviceVerification.qml
@@ -12,7 +12,7 @@ ApplicationWindow {
property var flow
- onClosing: TimelineManager.removeVerificationFlow(flow)
+ onClosing: VerificationManager.removeVerificationFlow(flow)
title: stack.currentItem.title
modality: Qt.NonModal
palette: Nheko.colors
diff --git a/resources/res.qrc b/resources/res.qrc
index ffbadd91..e544316b 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -141,37 +141,42 @@
qml/SelfVerificationCheck.qml
qml/TypingIndicator.qml
qml/NotificationWarning.qml
- qml/emoji/EmojiPicker.qml
- qml/emoji/StickerPicker.qml
- qml/delegates/MessageDelegate.qml
+ qml/components/AdaptiveLayout.qml
+ qml/components/AdaptiveLayoutElement.qml
+ qml/components/AvatarListTile.qml
+ qml/components/FlatButton.qml
qml/delegates/Encrypted.qml
qml/delegates/FileMessage.qml
qml/delegates/ImageMessage.qml
+ qml/delegates/MessageDelegate.qml
qml/delegates/NoticeMessage.qml
qml/delegates/Pill.qml
qml/delegates/Placeholder.qml
qml/delegates/PlayableMediaMessage.qml
qml/delegates/Reply.qml
qml/delegates/TextMessage.qml
- qml/device-verification/Waiting.qml
qml/device-verification/DeviceVerification.qml
qml/device-verification/DigitVerification.qml
qml/device-verification/EmojiVerification.qml
- qml/device-verification/NewVerificationRequest.qml
qml/device-verification/Failed.qml
- qml/device-verification/Success.qml
- qml/dialogs/ImagePackSettingsDialog.qml
+ qml/device-verification/NewVerificationRequest.qml
+ qml/device-verification/Success.qml
+ qml/device-verification/Waiting.qml
qml/dialogs/ImagePackEditorDialog.qml
- qml/dialogs/InputDialog.qml
- qml/dialogs/InviteDialog.qml
- qml/dialogs/JoinRoomDialog.qml
- qml/dialogs/LogoutDialog.qml
- qml/dialogs/RawMessageDialog.qml
- qml/dialogs/ReadReceipts.qml
- qml/dialogs/RoomDirectory.qml
- qml/dialogs/RoomMembers.qml
- qml/dialogs/RoomSettings.qml
- qml/dialogs/UserProfile.qml
+ qml/dialogs/ImagePackSettingsDialog.qml
+ qml/dialogs/InputDialog.qml
+ qml/dialogs/InviteDialog.qml
+ qml/dialogs/JoinRoomDialog.qml
+ qml/dialogs/LeaveRoomDialog.qml
+ qml/dialogs/LogoutDialog.qml
+ qml/dialogs/RawMessageDialog.qml
+ qml/dialogs/ReadReceipts.qml
+ qml/dialogs/RoomDirectory.qml
+ qml/dialogs/RoomMembers.qml
+ qml/dialogs/RoomSettings.qml
+ qml/dialogs/UserProfile.qml
+ qml/emoji/EmojiPicker.qml
+ qml/emoji/StickerPicker.qml
qml/ui/Ripple.qml
qml/ui/Spinner.qml
qml/ui/animations/BlinkAnimation.qml
@@ -183,18 +188,6 @@
qml/voip/PlaceCall.qml
qml/voip/ScreenShare.qml
qml/voip/VideoCall.qml
- qml/components/AdaptiveLayout.qml
- qml/components/AdaptiveLayoutElement.qml
- qml/components/AvatarListTile.qml
- qml/components/FlatButton.qml
- qml/dialogs/InviteDialog.qml
- qml/dialogs/LeaveRoomDialog.qml
- qml/dialogs/RawMessageDialog.qml
- qml/dialogs/ReadReceipts.qml
- qml/dialogs/RoomDirectory.qml
- qml/dialogs/RoomMembers.qml
- qml/dialogs/RoomSettings.qml
- qml/dialogs/UserProfile.qml
media/ring.ogg
diff --git a/src/encryption/VerificationManager.cpp b/src/encryption/VerificationManager.cpp
new file mode 100644
index 00000000..b9b51d35
--- /dev/null
+++ b/src/encryption/VerificationManager.cpp
@@ -0,0 +1,126 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "VerificationManager.h"
+#include "Cache.h"
+#include "ChatPage.h"
+#include "DeviceVerificationFlow.h"
+#include "timeline/TimelineViewManager.h"
+
+VerificationManager::VerificationManager(TimelineViewManager *o)
+ : QObject(o)
+ , rooms_(o->rooms())
+{}
+
+void
+VerificationManager::receivedRoomDeviceVerificationRequest(
+ const mtx::events::RoomEvent &message,
+ TimelineModel *model)
+{
+ if (this->isInitialSync_)
+ return;
+
+ auto event_id = QString::fromStdString(message.event_id);
+ if (!this->dvList.contains(event_id)) {
+ if (auto flow = DeviceVerificationFlow::NewInRoomVerification(
+ this, model, message.content, QString::fromStdString(message.sender), event_id)) {
+ dvList[event_id] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+ }
+ }
+}
+
+void
+VerificationManager::receivedDeviceVerificationRequest(
+ const mtx::events::msg::KeyVerificationRequest &msg,
+ std::string sender)
+{
+ if (this->isInitialSync_)
+ return;
+
+ if (!msg.transaction_id)
+ return;
+
+ auto txnid = QString::fromStdString(msg.transaction_id.value());
+ if (!this->dvList.contains(txnid)) {
+ if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
+ this, msg, QString::fromStdString(sender), txnid)) {
+ dvList[txnid] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+ }
+ }
+}
+
+void
+VerificationManager::receivedDeviceVerificationStart(
+ const mtx::events::msg::KeyVerificationStart &msg,
+ std::string sender)
+{
+ if (this->isInitialSync_)
+ return;
+
+ if (!msg.transaction_id)
+ return;
+
+ auto txnid = QString::fromStdString(msg.transaction_id.value());
+ if (!this->dvList.contains(txnid)) {
+ if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
+ this, msg, QString::fromStdString(sender), txnid)) {
+ dvList[txnid] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+ }
+ }
+}
+
+void
+VerificationManager::verifyUser(QString userid)
+{
+ auto joined_rooms = cache::joinedRooms();
+ auto room_infos = cache::getRoomInfo(joined_rooms);
+
+ for (std::string room_id : joined_rooms) {
+ if ((room_infos[QString::fromStdString(room_id)].member_count == 2) &&
+ cache::isRoomEncrypted(room_id)) {
+ auto room_members = cache::roomMembers(room_id);
+ if (std::find(room_members.begin(), room_members.end(), (userid).toStdString()) !=
+ room_members.end()) {
+ if (auto model = rooms_->getRoomById(QString::fromStdString(room_id))) {
+ auto flow =
+ DeviceVerificationFlow::InitiateUserVerification(this, model.data(), userid);
+ connect(model.data(),
+ &TimelineModel::updateFlowEventId,
+ this,
+ [this, flow](std::string eventId) {
+ dvList[QString::fromStdString(eventId)] = flow;
+ });
+ emit newDeviceVerificationRequest(flow.data());
+ return;
+ }
+ }
+ }
+ }
+
+ emit ChatPage::instance()->showNotification(
+ tr("No encrypted private chat found with this user. Create an "
+ "encrypted private chat with this user and try again."));
+}
+
+void
+VerificationManager::removeVerificationFlow(DeviceVerificationFlow *flow)
+{
+ for (auto it = dvList.keyValueBegin(); it != dvList.keyValueEnd(); ++it) {
+ if ((*it).second == flow) {
+ dvList.remove((*it).first);
+ return;
+ }
+ }
+}
+
+void
+VerificationManager::verifyDevice(QString userid, QString deviceid)
+{
+ auto flow = DeviceVerificationFlow::InitiateDeviceVerification(this, userid, deviceid);
+ this->dvList[flow->transactionId()] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+}
diff --git a/src/encryption/VerificationManager.h b/src/encryption/VerificationManager.h
new file mode 100644
index 00000000..e00ddc10
--- /dev/null
+++ b/src/encryption/VerificationManager.h
@@ -0,0 +1,48 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include
+#include
+#include
+
+#include
+#include
+
+class DeviceVerificationFlow;
+class TimelineModel;
+class TimelineModel;
+class TimelineViewManager;
+class RoomlistModel;
+
+class VerificationManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ VerificationManager(TimelineViewManager *o = nullptr);
+
+ Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow);
+ void verifyUser(QString userid);
+ void verifyDevice(QString userid, QString deviceid);
+
+signals:
+ void newDeviceVerificationRequest(DeviceVerificationFlow *flow);
+
+public slots:
+ void receivedRoomDeviceVerificationRequest(
+ const mtx::events::RoomEvent &message,
+ TimelineModel *model);
+ void receivedDeviceVerificationRequest(const mtx::events::msg::KeyVerificationRequest &msg,
+ std::string sender);
+ void receivedDeviceVerificationStart(const mtx::events::msg::KeyVerificationStart &msg,
+ std::string sender);
+
+private:
+ QHash> dvList;
+ bool isInitialSync_ = false;
+ RoomlistModel *rooms_;
+};
+
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 86f59c52..94e6a0d7 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -143,9 +143,10 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
, colorImgProvider(new ColorImageProvider())
, blurhashProvider(new BlurhashProvider())
, jdenticonProvider(new JdenticonProvider())
- , callManager_(callManager)
, rooms_(new RoomlistModel(this))
, communities_(new CommunitiesModel(this))
+ , callManager_(callManager)
+ , verificationManager_(new VerificationManager(this))
{
qRegisterMetaType();
qRegisterMetaType();
@@ -244,6 +245,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
"im.nheko", 1, 0, "Nheko", [](QQmlEngine *, QJSEngine *) -> QObject * {
return new Nheko();
});
+ qmlRegisterSingletonInstance("im.nheko", 1, 0, "VerificationManager", verificationManager_);
qmlRegisterSingletonType(
"im.nheko", 1, 0, "SelfVerificationStatus", [](QQmlEngine *, QJSEngine *) -> QObject * {
return new SelfVerificationStatus();
@@ -285,63 +287,16 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette);
connect(dynamic_cast(parent),
&ChatPage::receivedRoomDeviceVerificationRequest,
- this,
- [this](const mtx::events::RoomEvent &message,
- TimelineModel *model) {
- if (this->isInitialSync_)
- return;
-
- auto event_id = QString::fromStdString(message.event_id);
- if (!this->dvList.contains(event_id)) {
- if (auto flow = DeviceVerificationFlow::NewInRoomVerification(
- this,
- model,
- message.content,
- QString::fromStdString(message.sender),
- event_id)) {
- dvList[event_id] = flow;
- emit newDeviceVerificationRequest(flow.data());
- }
- }
- });
+ verificationManager_,
+ &VerificationManager::receivedRoomDeviceVerificationRequest);
connect(dynamic_cast(parent),
&ChatPage::receivedDeviceVerificationRequest,
- this,
- [this](const mtx::events::msg::KeyVerificationRequest &msg, std::string sender) {
- if (this->isInitialSync_)
- return;
-
- if (!msg.transaction_id)
- return;
-
- auto txnid = QString::fromStdString(msg.transaction_id.value());
- if (!this->dvList.contains(txnid)) {
- if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
- this, msg, QString::fromStdString(sender), txnid)) {
- dvList[txnid] = flow;
- emit newDeviceVerificationRequest(flow.data());
- }
- }
- });
+ verificationManager_,
+ &VerificationManager::receivedDeviceVerificationRequest);
connect(dynamic_cast(parent),
&ChatPage::receivedDeviceVerificationStart,
- this,
- [this](const mtx::events::msg::KeyVerificationStart &msg, std::string sender) {
- if (this->isInitialSync_)
- return;
-
- if (!msg.transaction_id)
- return;
-
- auto txnid = QString::fromStdString(msg.transaction_id.value());
- if (!this->dvList.contains(txnid)) {
- if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
- this, msg, QString::fromStdString(sender), txnid)) {
- dvList[txnid] = flow;
- emit newDeviceVerificationRequest(flow.data());
- }
- }
- });
+ verificationManager_,
+ &VerificationManager::receivedDeviceVerificationStart);
connect(parent, &ChatPage::loggedOut, this, [this]() {
isInitialSync_ = true;
emit initialSyncChanged(true);
@@ -475,58 +430,6 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img)
});
}
-void
-TimelineViewManager::verifyUser(QString userid)
-{
- auto joined_rooms = cache::joinedRooms();
- auto room_infos = cache::getRoomInfo(joined_rooms);
-
- for (std::string room_id : joined_rooms) {
- if ((room_infos[QString::fromStdString(room_id)].member_count == 2) &&
- cache::isRoomEncrypted(room_id)) {
- auto room_members = cache::roomMembers(room_id);
- if (std::find(room_members.begin(), room_members.end(), (userid).toStdString()) !=
- room_members.end()) {
- if (auto model = rooms_->getRoomById(QString::fromStdString(room_id))) {
- auto flow =
- DeviceVerificationFlow::InitiateUserVerification(this, model.data(), userid);
- connect(model.data(),
- &TimelineModel::updateFlowEventId,
- this,
- [this, flow](std::string eventId) {
- dvList[QString::fromStdString(eventId)] = flow;
- });
- emit newDeviceVerificationRequest(flow.data());
- return;
- }
- }
- }
- }
-
- emit ChatPage::instance()->showNotification(
- tr("No encrypted private chat found with this user. Create an "
- "encrypted private chat with this user and try again."));
-}
-
-void
-TimelineViewManager::removeVerificationFlow(DeviceVerificationFlow *flow)
-{
- for (auto it = dvList.keyValueBegin(); it != dvList.keyValueEnd(); ++it) {
- if ((*it).second == flow) {
- dvList.remove((*it).first);
- return;
- }
- }
-}
-
-void
-TimelineViewManager::verifyDevice(QString userid, QString deviceid)
-{
- auto flow = DeviceVerificationFlow::InitiateDeviceVerification(this, userid, deviceid);
- this->dvList[flow->transactionId()] = flow;
- emit newDeviceVerificationRequest(flow.data());
-}
-
void
TimelineViewManager::updateReadReceipts(const QString &room_id,
const std::vector &event_ids)
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 723282d6..6696b1c4 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -9,7 +9,6 @@
#include
#include
#include
-#include
#include
#include
@@ -23,6 +22,7 @@
#include "Utils.h"
#include "emoji/EmojiModel.h"
#include "emoji/Provider.h"
+#include "encryption/VerificationManager.h"
#include "timeline/CommunitiesModel.h"
#include "timeline/RoomlistModel.h"
#include "voip/CallManager.h"
@@ -33,7 +33,6 @@ class BlurhashProvider;
class ColorImageProvider;
class UserSettings;
class ChatPage;
-class DeviceVerificationFlow;
class ImagePackListModel;
class TimelineViewManager : public QObject
@@ -53,6 +52,7 @@ public:
MxcImageProvider *imageProvider() { return imgProvider; }
CallManager *callManager() { return callManager_; }
+ VerificationManager *verificationManager() { return verificationManager_; }
void clearAll() { rooms_->clear(); }
@@ -73,19 +73,14 @@ public:
Q_INVOKABLE void openGlobalUserProfile(QString userId);
Q_INVOKABLE void focusMessageInput();
- Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow);
Q_INVOKABLE void fixImageRendering(QQuickTextDocument *t, QQuickItem *i);
- void verifyUser(QString userid);
- void verifyDevice(QString userid, QString deviceid);
-
signals:
void activeTimelineChanged(TimelineModel *timeline);
void initialSyncChanged(bool isInitialSync);
void replyingEventChanged(QString replyingEvent);
void replyClosed();
- void newDeviceVerificationRequest(DeviceVerificationFlow *flow);
void inviteUsers(QString roomId, QStringList users);
void showRoomList();
void narrowViewChanged();
@@ -142,17 +137,17 @@ private:
BlurhashProvider *blurhashProvider;
JdenticonProvider *jdenticonProvider;
- CallManager *callManager_ = nullptr;
-
bool isInitialSync_ = true;
bool isWindowFocused_ = false;
RoomlistModel *rooms_ = nullptr;
CommunitiesModel *communities_ = nullptr;
- QHash userColors;
+ // don't move this above the rooms_
+ CallManager *callManager_ = nullptr;
+ VerificationManager *verificationManager_ = nullptr;
- QHash> dvList;
+ QHash userColors;
};
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationAccept)
Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationCancel)
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
index d62e3248..0e3fd39f 100644
--- a/src/ui/UserProfile.cpp
+++ b/src/ui/UserProfile.cpp
@@ -338,9 +338,9 @@ void
UserProfile::verify(QString device)
{
if (!device.isEmpty())
- manager->verifyDevice(userid_, device);
+ manager->verificationManager()->verifyDevice(userid_, device);
else {
- manager->verifyUser(userid_);
+ manager->verificationManager()->verifyUser(userid_);
}
}