diff --git a/src/ChatPage.h b/src/ChatPage.h
index 0e7c889f..72adfe19 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -52,6 +52,7 @@ class TopRoomBar;
class UserInfoWidget;
class UserSettings;
class NotificationsManager;
+class TimelineModel;
constexpr int CONSENSUS_TIMEOUT = 1000;
constexpr int SHOW_CONTENT_TIMEOUT = 3000;
@@ -171,6 +172,9 @@ signals:
void recievedDeviceVerificationRequest(
const mtx::events::msg::KeyVerificationRequest &message,
std::string sender);
+ void recievedRoomDeviceVerificationRequest(
+ const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &message,
+ TimelineModel *model);
void recievedDeviceVerificationCancel(
const mtx::events::msg::KeyVerificationCancel &message);
void recievedDeviceVerificationKey(const mtx::events::msg::KeyVerificationKey &message);
diff --git a/src/DeviceVerificationFlow.cpp b/src/DeviceVerificationFlow.cpp
index 69de4937..0f521f92 100644
--- a/src/DeviceVerificationFlow.cpp
+++ b/src/DeviceVerificationFlow.cpp
@@ -1,7 +1,9 @@
#include "DeviceVerificationFlow.h"
+
#include "Cache.h"
#include "ChatPage.h"
#include "Logging.h"
+#include "timeline/TimelineModel.h"
#include <QDateTime>
#include <QTimer>
@@ -12,12 +14,14 @@ static constexpr int TIMEOUT = 2 * 60 * 1000; // 2 minutes
namespace msgs = mtx::events::msg;
-DeviceVerificationFlow::DeviceVerificationFlow(QObject *, DeviceVerificationFlow::Type)
+DeviceVerificationFlow::DeviceVerificationFlow(QObject *, DeviceVerificationFlow::Type flow_type)
+ : type(flow_type)
{
timeout = new QTimer(this);
timeout->setSingleShot(true);
this->sas = olm::client()->sas_init();
this->isMacVerified = false;
+
connect(timeout, &QTimer::timeout, this, [this]() {
emit timedout();
this->cancelVerification(DeviceVerificationFlow::Error::Timeout);
@@ -267,6 +271,12 @@ DeviceVerificationFlow::getMethod()
return this->method;
}
+DeviceVerificationFlow::Type
+DeviceVerificationFlow::getType()
+{
+ return this->type;
+}
+
bool
DeviceVerificationFlow::getSender()
{
@@ -280,6 +290,12 @@ DeviceVerificationFlow::getSasList()
}
void
+DeviceVerificationFlow::setModel(TimelineModel *&model)
+{
+ this->model_ = model;
+}
+
+void
DeviceVerificationFlow::setTransactionId(QString transaction_id_)
{
this->transaction_id = transaction_id_.toStdString();
@@ -319,6 +335,12 @@ DeviceVerificationFlow::setMethod(DeviceVerificationFlow::Method method_)
}
void
+DeviceVerificationFlow::setType(Type type)
+{
+ this->type = type;
+}
+
+void
DeviceVerificationFlow::setSender(bool sender_)
{
this->sender = sender_;
@@ -328,6 +350,13 @@ DeviceVerificationFlow::setSender(bool sender_)
this->relation.in_reply_to.event_id = http::client()->generate_txn_id();
}
+void
+DeviceVerificationFlow::setEventId(std::string event_id)
+{
+ this->relation.in_reply_to.event_id = event_id;
+ this->transaction_id = event_id;
+}
+
//! accepts a verification
void
DeviceVerificationFlow::acceptVerificationRequest()
@@ -361,8 +390,9 @@ DeviceVerificationFlow::acceptVerificationRequest()
err->matrix_error.error,
static_cast<int>(err->status_code));
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
}
//! responds verification request
@@ -389,8 +419,9 @@ DeviceVerificationFlow::sendVerificationReady()
err->matrix_error.error,
static_cast<int>(err->status_code));
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
}
//! accepts a verification
@@ -414,8 +445,9 @@ DeviceVerificationFlow::sendVerificationDone()
err->matrix_error.error,
static_cast<int>(err->status_code));
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
}
//! starts the verification flow
@@ -448,8 +480,9 @@ DeviceVerificationFlow::startVerificationRequest()
err->matrix_error.error,
static_cast<int>(err->status_code));
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
}
//! sends a verification request
@@ -481,8 +514,8 @@ DeviceVerificationFlow::sendVerificationRequest()
err->matrix_error.error,
static_cast<int>(err->status_code));
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
- std::cout << "lulz" << std::endl;
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
+ (model_.value())->sendMessage(req);
}
}
//! cancels a verification flow
@@ -531,8 +564,9 @@ DeviceVerificationFlow::cancelVerification(DeviceVerificationFlow::Error error_c
this->deleteLater();
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
// TODO : Handle Blocking user better
@@ -570,8 +604,9 @@ DeviceVerificationFlow::sendVerificationKey()
err->matrix_error.error,
static_cast<int>(err->status_code));
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
}
//! sends the mac of the keys
@@ -618,8 +653,9 @@ DeviceVerificationFlow::sendVerificationMac()
else
this->isMacVerified = true;
});
- } else if (this->type == DeviceVerificationFlow::Type::RoomMsg) {
+ } else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_.has_value()) {
req.relates_to = this->relation;
+ (model_.value())->sendMessage(req);
}
}
//! Completes the verification flow
diff --git a/src/DeviceVerificationFlow.h b/src/DeviceVerificationFlow.h
index 3f999e80..bec9f1e0 100644
--- a/src/DeviceVerificationFlow.h
+++ b/src/DeviceVerificationFlow.h
@@ -10,6 +10,8 @@ class QTimer;
using sas_ptr = std::unique_ptr<mtx::crypto::SAS>;
+struct TimelineModel;
+
class DeviceVerificationFlow : public QObject
{
Q_OBJECT
@@ -19,6 +21,7 @@ class DeviceVerificationFlow : public QObject
Q_PROPERTY(QString userId READ getUserId WRITE setUserId)
Q_PROPERTY(QString deviceId READ getDeviceId WRITE setDeviceId)
Q_PROPERTY(Method method READ getMethod WRITE setMethod)
+ Q_PROPERTY(Type type READ getType WRITE setType)
Q_PROPERTY(std::vector<int> sasList READ getSasList CONSTANT)
public:
@@ -27,6 +30,7 @@ public:
ToDevice,
RoomMsg
};
+ Q_ENUM(Type)
enum Method
{
@@ -49,17 +53,24 @@ public:
DeviceVerificationFlow(
QObject *parent = nullptr,
DeviceVerificationFlow::Type = DeviceVerificationFlow::Type::ToDevice);
+ // getters
QString getTransactionId();
QString getUserId();
QString getDeviceId();
Method getMethod();
+ Type getType();
std::vector<int> getSasList();
- void setTransactionId(QString transaction_id_);
bool getSender();
+ // setters
+ void setModel(TimelineModel *&model);
+ void setTransactionId(QString transaction_id_);
void setUserId(QString userID);
void setDeviceId(QString deviceID);
void setMethod(Method method_);
+ void setType(Type type_);
void setSender(bool sender_);
+ void setEventId(std::string event_id);
+
void callback_fn(const mtx::responses::QueryKeys &res,
mtx::http::RequestErr err,
std::string user_id);
@@ -96,20 +107,25 @@ signals:
void refreshProfile();
private:
+ // general
QString userId;
QString deviceId;
Method method;
Type type;
bool sender;
-
QTimer *timeout = nullptr;
sas_ptr sas;
bool isMacVerified = false;
std::string mac_method;
- std::string transaction_id;
std::string commitment;
mtx::identifiers::User toClient;
std::vector<int> sasList;
std::map<std::string, std::string> device_keys;
+ // for to_device messages
+ std::string transaction_id;
+ // for room messages
+ std::optional<std::string> room_id;
+ std::optional<std::string> event_id;
+ std::optional<TimelineModel *> model_;
mtx::common::ReplyRelatesTo relation;
};
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 71cc53c5..adf207ac 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -139,6 +139,11 @@ struct RoomEventType
return qml_mtx_events::EventType::KeyVerificationAccept;
}
qml_mtx_events::EventType operator()(
+ const mtx::events::Event<mtx::events::msg::KeyVerificationReady> &)
+ {
+ return qml_mtx_events::EventType::KeyVerificationReady;
+ }
+ qml_mtx_events::EventType operator()(
const mtx::events::Event<mtx::events::msg::KeyVerificationCancel> &)
{
return qml_mtx_events::EventType::KeyVerificationCancel;
@@ -637,30 +642,6 @@ TimelineModel::internalAddEvents(
continue;
}
- if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>>(
- &e)) {
- std::cout << "got a request" << std::endl;
- }
-
- if (auto cancelVerification =
- std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>>(
- &e)) {
- std::cout<<"it is happening"<<std::endl;
- if (cancelVerification->content.relates_to.has_value()) {
- QString event_id = QString::fromStdString(
- cancelVerification->content.relates_to.value()
- .in_reply_to.event_id);
- auto request =
- std::find(eventOrder.begin(), eventOrder.end(), event_id);
- if (request != eventOrder.end()) {
- auto event = events.value(event_id);
- auto e = std::get_if<mtx::events::RoomEvent<
- mtx::events::msg::KeyVerificationRequest>>(&event);
- std::cout<<json(*e)<<std::endl;
- }
- }
- }
-
if (auto redaction =
std::get_if<mtx::events::RedactionEvent<mtx::events::msg::Redaction>>(&e)) {
QString redacts = QString::fromStdString(redaction->redacts);
@@ -728,6 +709,55 @@ TimelineModel::internalAddEvents(
if (encInfo)
emit newEncryptedImage(encInfo.value());
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>>(
+ &e_)) {
+ last_verification_request_event = *msg;
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>>(
+ &e_)) {
+ last_verification_cancel_event = *msg;
+ ChatPage::instance()->recievedDeviceVerificationCancel(
+ msg->content);
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationAccept>>(
+ &e_)) {
+ ChatPage::instance()->recievedDeviceVerificationAccept(
+ msg->content);
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationKey>>(&e_)) {
+ ChatPage::instance()->recievedDeviceVerificationKey(msg->content);
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationMac>>(&e_)) {
+ ChatPage::instance()->recievedDeviceVerificationMac(msg->content);
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationReady>>(
+ &e_)) {
+ ChatPage::instance()->recievedDeviceVerificationReady(msg->content);
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationDone>>(&e_)) {
+ ChatPage::instance()->recievedDeviceVerificationDone(msg->content);
+ }
+
+ if (auto msg = std::get_if<
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationStart>>(
+ &e_)) {
+ ChatPage::instance()->recievedDeviceVerificationStart(msg->content,
+ msg->sender);
+ }
}
this->events.insert(id, e);
@@ -754,6 +784,13 @@ TimelineModel::internalAddEvents(
});
}
}
+
+ if (last_verification_request_event.origin_server_ts >
+ last_verification_cancel_event.origin_server_ts) {
+ ChatPage::instance()->recievedRoomDeviceVerificationRequest(
+ last_verification_request_event, this);
+ }
+
return ids;
}
@@ -1264,6 +1301,20 @@ struct SendMessageVisitor
};
void
+TimelineModel::processOnePendingMessage()
+{
+ if (pending.isEmpty())
+ return;
+
+ QString txn_id_qstr = pending.first();
+
+ auto event = events.value(txn_id_qstr);
+ std::cout << "Inside the process one pending message" << std::endl;
+ std::cout << std::visit([](auto &e) { return json(e); }, event).dump(2) << std::endl;
+ std::visit(SendMessageVisitor{txn_id_qstr, this}, event);
+}
+
+void
TimelineModel::addPendingMessage(mtx::events::collections::TimelineEvents event)
{
std::visit(
@@ -1275,7 +1326,51 @@ TimelineModel::addPendingMessage(mtx::events::collections::TimelineEvents event)
},
event);
- std::visit(SendMessageVisitor{this}, event);
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationReady>>(&event)) {
+ std::visit(
+ [](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationReady; },
+ event);
+ }
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationStart>>(&event)) {
+ std::visit(
+ [](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationStart; },
+ event);
+ }
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationKey>>(&event)) {
+ std::visit([](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationKey; },
+ event);
+ }
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationMac>>(&event)) {
+ std::visit([](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationMac; },
+ event);
+ }
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationDone>>(&event)) {
+ std::visit(
+ [](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationDone; }, event);
+ }
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>>(&event)) {
+ std::visit(
+ [](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationCancel; },
+ event);
+ }
+ if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationAccept>>(&event)) {
+ std::visit(
+ [](auto &msg) { msg.type = mtx::events::EventType::KeyVerificationAccept; },
+ event);
+ }
+
+ internalAddEvents({event});
+
+ QString txn_id_qstr = QString::fromStdString(mtx::accessors::event_id(event));
+ pending.push_back(txn_id_qstr);
+ if (!std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(&event)) {
+ beginInsertRows(QModelIndex(), 0, 0);
+ this->eventOrder.insert(this->eventOrder.begin(), txn_id_qstr);
+ endInsertRows();
+ }
+ updateLastMessage();
+
+ emit nextPendingMessage();
}
bool
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 708ed38e..1b6f999e 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -297,6 +297,11 @@ private:
std::vector<QString> typingUsers_;
TimelineViewManager *manager_;
+ // probably not the best way to do
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>
+ last_verification_request_event;
+ mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>
+ last_verification_cancel_event;
friend struct SendMessageVisitor;
};
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 02b74d20..c16e09d1 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -17,6 +17,8 @@
#include "emoji/EmojiModel.h"
#include "emoji/Provider.h"
+#include <iostream> //only for debugging
+
Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
@@ -187,16 +189,42 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
&TimelineViewManager::updateEncryptedDescriptions);
connect(
dynamic_cast<ChatPage *>(parent),
+ &ChatPage::recievedRoomDeviceVerificationRequest,
+ this,
+ [this](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &message,
+ TimelineModel *model) {
+ if (!(this->dvList->exist(QString::fromStdString(message.event_id)))) {
+ auto flow =
+ new DeviceVerificationFlow(this, DeviceVerificationFlow::Type::RoomMsg);
+ if (std::find(message.content.methods.begin(),
+ message.content.methods.end(),
+ mtx::events::msg::VerificationMethods::SASv1) !=
+ message.content.methods.end()) {
+ flow->setModel(model);
+ flow->setEventId(message.event_id);
+ emit newDeviceVerificationRequest(
+ std::move(flow),
+ QString::fromStdString(message.event_id),
+ QString::fromStdString(message.sender),
+ QString::fromStdString(message.content.from_device),
+ true);
+ } else {
+ flow->cancelVerification(
+ DeviceVerificationFlow::Error::UnknownMethod);
+ }
+ }
+ });
+ connect(
+ dynamic_cast<ChatPage *>(parent),
&ChatPage::recievedDeviceVerificationRequest,
this,
[this](const mtx::events::msg::KeyVerificationRequest &msg, std::string sender) {
- auto flow = new DeviceVerificationFlow(this);
if (!(this->dvList->exist(QString::fromStdString(msg.transaction_id.value())))) {
+ auto flow = new DeviceVerificationFlow(this);
if (std::find(msg.methods.begin(),
msg.methods.end(),
mtx::events::msg::VerificationMethods::SASv1) !=
msg.methods.end()) {
- // flow->sendVerificationReady();
emit newDeviceVerificationRequest(
std::move(flow),
QString::fromStdString(msg.transaction_id.value()),
@@ -213,9 +241,9 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
&ChatPage::recievedDeviceVerificationStart,
this,
[this](const mtx::events::msg::KeyVerificationStart &msg, std::string sender) {
- auto flow = new DeviceVerificationFlow(this);
- flow->canonical_json = nlohmann::json(msg);
if (!(this->dvList->exist(QString::fromStdString(msg.transaction_id.value())))) {
+ auto flow = new DeviceVerificationFlow(this);
+ flow->canonical_json = nlohmann::json(msg);
if ((std::find(msg.key_agreement_protocols.begin(),
msg.key_agreement_protocols.end(),
"curve25519-hkdf-sha256") !=
@@ -246,7 +274,6 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
QString::fromStdString(msg.transaction_id.value()),
QString::fromStdString(sender),
QString::fromStdString(msg.from_device));
- flow->canonical_json = nlohmann::json(msg);
} else {
flow->cancelVerification(
DeviceVerificationFlow::Error::UnknownMethod);
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 71aee5ef..031d07cc 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -72,7 +72,8 @@ signals:
void newDeviceVerificationRequest(DeviceVerificationFlow *flow,
QString transactionId,
QString userId,
- QString deviceId);
+ QString deviceId,
+ bool isRequest = false);
public slots:
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|