From e31ef78e7187d216365d27ad0c52ea2b1c3978f8 Mon Sep 17 00:00:00 2001 From: blue Date: Fri, 10 Nov 2023 19:26:16 -0300 Subject: [PATCH] some refactoring, some improvements --- core/account.cpp | 20 ++++--- core/account.h | 7 +-- core/contact.cpp | 4 ++ core/contact.h | 13 ++--- core/delayManager/manager.h | 41 +++++++------- core/handlers/messagehandler.cpp | 10 ++-- core/handlers/omemohandler.cpp | 65 +++++++++++++--------- core/handlers/omemohandler.h | 38 +++++++------ core/handlers/trusthandler.cpp | 93 ++++++++++++++++++-------------- external/qxmpp | 2 +- shared/enums.h | 8 +++ shared/message.cpp | 10 +++- ui/widgets/chat.cpp | 24 ++++----- 13 files changed, 188 insertions(+), 147 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index a71bf4a..efb4a1a 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -266,6 +266,7 @@ void Core::Account::onClientStateChange(QXmppClient::State st) { #ifdef WITH_OMEMO if (!oh->hasOwnDevice()) { qDebug() << "setting up OMEMO data for account" << getName(); + om->changeDeviceLabel(QGuiApplication::applicationDisplayName() + " - " + QSysInfo::productType()); QXmppTask future = om->setUp(); future.then(this, [this] (bool result) { if (result) @@ -342,9 +343,8 @@ void Core::Account::setAvailability(Shared::Availability avail) { QXmppPresence::AvailableStatusType pres = static_cast(avail); presence.setAvailableStatusType(pres); - if (state != Shared::ConnectionState::disconnected) { + if (state != Shared::ConnectionState::disconnected) client.setClientPresence(presence); - } } } @@ -437,9 +437,9 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess void Core::Account::requestArchive(const QString& jid, int count, const QString& before) { qDebug() << "An archive request for " << jid << ", before " << before; - RosterItem* contact = rh->getRosterItem(jid); + RosterItem* item = rh->getRosterItem(jid); - if (contact == nullptr) { + if (item == nullptr) { qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the contact with such id wasn't found, skipping"; emit responseArchive(jid, std::list(), true); return; @@ -447,10 +447,18 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString& if (state != Shared::ConnectionState::connected) { qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the account is not online, skipping"; - emit responseArchive(contact->jid, std::list(), false); + emit responseArchive(jid, std::list(), false); + return; } - contact->requestHistory(count, before); +#ifdef WITH_OMEMO + if (!item->isMuc()) { + Contact* contact = static_cast(item); + if (contact->omemoBundles == Shared::Possible::unknown) + oh->requestBundles(jid); + } +#endif + item->requestHistory(count, before); } void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at) { diff --git a/core/account.h b/core/account.h index 6442abf..b156059 100644 --- a/core/account.h +++ b/core/account.h @@ -15,9 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#ifndef CORE_ACCOUNT_H -#define CORE_ACCOUNT_H +#pragma once #include #include @@ -248,6 +246,3 @@ private: void runDiscoveryService(); }; } - - -#endif // CORE_ACCOUNT_H diff --git a/core/contact.cpp b/core/contact.cpp index 93139ef..f18dae3 100644 --- a/core/contact.cpp +++ b/core/contact.cpp @@ -24,6 +24,10 @@ Core::Contact::Contact(const QString& pJid, const QString& account, QObject* par groups(), subscriptionState(Shared::SubscriptionState::unknown), pep(Shared::Support::unknown) + +#ifdef WITH_OMEMO + ,omemoBundles(Shared::Possible::unknown) +#endif {} Core::Contact::~Contact() {} diff --git a/core/contact.h b/core/contact.h index bde95f2..c23d0dc 100644 --- a/core/contact.h +++ b/core/contact.h @@ -16,8 +16,7 @@ * along with this program. If not, see . */ -#ifndef CORE_CONTACT_H -#define CORE_CONTACT_H +#pragma once #include #include @@ -28,8 +27,7 @@ namespace Core { -class Contact : public RosterItem -{ +class Contact : public RosterItem { Q_OBJECT public: Contact(const QString& pJid, const QString& account, QObject* parent = 0); @@ -56,7 +54,10 @@ private: QSet groups; Shared::SubscriptionState subscriptionState; Shared::Support pep; + +#ifdef WITH_OMEMO +public: + Shared::Possible omemoBundles; +#endif }; } - -#endif // CORE_CONTACT_H diff --git a/core/delayManager/manager.h b/core/delayManager/manager.h index 127d25a..5d04a8e 100644 --- a/core/delayManager/manager.h +++ b/core/delayManager/manager.h @@ -1,21 +1,21 @@ -// Squawk messenger. -// Copyright (C) 2019 Yury Gubich -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#ifndef CORE_DELAYMANAGER_MANAGER_H -#define CORE_DELAYMANAGER_MANAGER_H +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once #include #include @@ -38,8 +38,7 @@ namespace Core { namespace DelayManager { -class Manager : public QObject -{ +class Manager : public QObject { Q_OBJECT public: Manager(const QString& ownJid, Job::Id maxParallelJobs = 5, QObject* parent = nullptr); @@ -146,5 +145,3 @@ public: } } - -#endif // CORE_DELAYMANAGER_MANAGER_H diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index 0d0c446..2c8526a 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -358,8 +358,8 @@ std::pair Core::MessageHandler::scheduleSending const QXmppE2eeExtension::MessageEncryptResult& res = task.result(); if (std::holds_alternative>(res)) { const std::unique_ptr& encrypted = std::get>(res); - encrypted->setBody("This message is encrypted with OMEMO 2 but could not be decrypted"); - encrypted->setOutOfBandUrl(""); + encrypted->setBody(QString()); + encrypted->setOutOfBandUrl(QString()); bool success = acc->client.sendPacket(*encrypted.get()); if (success) return {Shared::Message::State::sent, ""}; @@ -375,8 +375,8 @@ std::pair Core::MessageHandler::scheduleSending task.then(this, [this, id] (QXmppE2eeExtension::MessageEncryptResult&& result) { if (std::holds_alternative>(result)) { const std::unique_ptr& encrypted = std::get>(result); - encrypted->setBody("This message is encrypted with OMEMO 2 but could not be decrypted"); - encrypted->setOutOfBandUrl(""); + encrypted->setBody(QString()); + encrypted->setOutOfBandUrl(QString()); bool success = acc->client.sendPacket(*encrypted.get()); if (success) { std::tuple ids = getOriginalPendingMessageId(id, false); @@ -602,7 +602,7 @@ void Core::MessageHandler::onUploadFileComplete(const std::list Core::OmemoHandler::allData() { OmemoData data; data.ownDevice = ownDevice; + // LMDBAL::Transaction txn = db.beginReadOnlyTransaction(); TODO need to enable transaction after fixing LMDBAL std::map pkeys = preKeyPairs->readAll(); for (const std::pair& pair : pkeys) { data.preKeyPairs.insert(pair.first, pair.second); @@ -73,28 +74,30 @@ QXmppTask Core::OmemoHandler::allData() { QXmppTask Core::OmemoHandler::addDevice(const QString& jid, uint32_t deviceId, const QXmppOmemoStorage::Device& device) { QHash devs; + LMDBAL::WriteTransaction txn = db.beginTransaction(); bool had = true; try { - devs = devices->getRecord(jid); + devices->getRecord(jid, devs, txn); } catch (const LMDBAL::NotFound& error) { had = false; } - devs.insert(deviceId, device); - if (had) { - devices->changeRecord(jid, devs); - } else { - devices->addRecord(jid, devs); - } + devs.insert(deviceId, device); //overwrites + if (had) + devices->changeRecord(jid, devs, txn); + else + devices->addRecord(jid, devs, txn); + txn.commit(); return Core::makeReadyTask(); } QXmppTask Core::OmemoHandler::addPreKeyPairs(const QHash& keyPairs) { - for (QHash::const_iterator itr = keyPairs.begin(), end = keyPairs.end(); itr != end; ++itr) { - preKeyPairs->forceRecord(itr.key(), itr.value()); - } + LMDBAL::WriteTransaction txn = db.beginTransaction(); + for (QHash::const_iterator itr = keyPairs.begin(), end = keyPairs.end(); itr != end; ++itr) + preKeyPairs->forceRecord(itr.key(), itr.value(), txn); + txn.commit(); return Core::makeReadyTask(); } @@ -104,13 +107,15 @@ QXmppTask Core::OmemoHandler::addSignedPreKeyPair(uint32_t keyId, const QX } QXmppTask Core::OmemoHandler::removeDevice(const QString& jid, uint32_t deviceId) { - QHash devs = devices->getRecord(jid); + LMDBAL::WriteTransaction txn = db.beginTransaction(); + QHash devs = devices->getRecord(jid, txn); devs.remove(deviceId); - if (devs.isEmpty()) { - devices->removeRecord(jid); - } else { - devices->changeRecord(jid, devs); - } + if (devs.isEmpty()) + devices->removeRecord(jid, txn); + else + devices->changeRecord(jid, devs, txn); + + txn.commit(); return Core::makeReadyTask(); } @@ -120,7 +125,11 @@ QXmppTask Core::OmemoHandler::removeDevices(const QString& jid) { } QXmppTask Core::OmemoHandler::removePreKeyPair(uint32_t keyId) { - preKeyPairs->removeRecord(keyId); + try { + preKeyPairs->removeRecord(keyId); + } catch (const LMDBAL::NotFound& e) { + qDebug() << "Couldn't remove preKeyPair " << e.what(); + } return Core::makeReadyTask(); } @@ -135,15 +144,12 @@ QXmppTask Core::OmemoHandler::setOwnDevice(const std::optional& bool had = ownDevice.has_value(); ownDevice = device; if (ownDevice.has_value()) { - if (had) { + if (had) meta->changeRecord("ownDevice", QVariant::fromValue(ownDevice.value())); - } else { + else meta->addRecord("ownDevice", QVariant::fromValue(ownDevice.value())); - } - } else { - if (had) { - meta->removeRecord("ownDevice"); - } + } else if (had) { + meta->removeRecord("ownDevice"); } return Core::makeReadyTask(); } @@ -158,7 +164,7 @@ QXmppTask Core::OmemoHandler::resetAll() { void Core::OmemoHandler::getDevices(const QString& jid, std::list& out) const { QHash devs; try { - devs = devices->getRecord(jid); + devices->getRecord(jid, devs); } catch (const LMDBAL::NotFound& error) {} for (QHash::const_iterator itr = devs.begin(), end = devs.end(); itr != end; ++itr) { @@ -169,6 +175,10 @@ void Core::OmemoHandler::getDevices(const QString& jid, std::list task = acc->om->buildMissingSessions({jid}); + Contact* cnt = acc->rh->getContact(jid); + if (cnt) + cnt->omemoBundles = Shared::Possible::discovering; + task.then(this, std::bind(&OmemoHandler::onBundlesReceived, this, jid)); } @@ -191,6 +201,10 @@ void Core::OmemoHandler::onBundlesReceived(const QString& jid) { } } + Contact* cnt = acc->rh->getContact(jid); + if (cnt) + cnt->omemoBundles = Shared::Possible::present; + acc->delay->receivedBundles(jid, keys); } @@ -217,7 +231,6 @@ void Core::OmemoHandler::onOmemoDeviceAdded(const QString& jid, uint32_t id) { qDebug() << "OMEMO device added for" << jid; } - QDataStream & operator >> (QDataStream& in, QXmppOmemoStorage::Device& device) { in >> device.label; in >> device.keyId; diff --git a/core/handlers/omemohandler.h b/core/handlers/omemohandler.h index e626b4c..60fd8d1 100644 --- a/core/handlers/omemohandler.h +++ b/core/handlers/omemohandler.h @@ -1,21 +1,21 @@ -// Squawk messenger. -// Copyright (C) 2019 Yury Gubich -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#ifndef CORE_OMEMOHANDLER_H -#define CORE_OMEMOHANDLER_H +/* + * Squawk messenger. + * Copyright (C) 2019 Yury Gubich + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once #include #include @@ -87,5 +87,3 @@ QDataStream& operator >> (QDataStream &in, QXmppOmemoStorage::Device& device); QDataStream& operator << (QDataStream &out, const QXmppOmemoStorage::OwnDevice& device); QDataStream& operator >> (QDataStream &in, QXmppOmemoStorage::OwnDevice& device); - -#endif // CORE_OMEMOHANDLER_H diff --git a/core/handlers/trusthandler.cpp b/core/handlers/trusthandler.cpp index 21b3491..566265f 100644 --- a/core/handlers/trusthandler.cpp +++ b/core/handlers/trusthandler.cpp @@ -28,9 +28,8 @@ Core::TrustHandler::TrustHandler(Account* account): ownKeys(db.addCache("ownKeys")), keysByProtocol() { - if (!protocols.open(QIODevice::ReadWrite | QIODevice::Text)) { //never supposed to happen since I have just created a directory; + if (!protocols.open(QIODevice::ReadWrite | QIODevice::Text)) //never supposed to happen since I have just created a directory; throw LMDBAL::Directory(protocols.fileName().toStdString()); - } QTextStream in(&protocols); while(!in.atEnd()) { @@ -53,11 +52,10 @@ Core::TrustHandler::~TrustHandler() { Core::TrustHandler::KeyCache * Core::TrustHandler::getCache(const QString& encryption) { std::map::iterator itr = keysByProtocol.find(encryption); - if (itr == keysByProtocol.end()) { + if (itr == keysByProtocol.end()) return createNewCache(encryption); - } else { + else return itr->second; - } } Core::TrustHandler::KeyCache * Core::TrustHandler::createNewCache(const QString& encryption) { @@ -65,9 +63,9 @@ Core::TrustHandler::KeyCache * Core::TrustHandler::createNewCache(const QString& KeyCache* cache = db.addCache(encryption.toStdString()); keysByProtocol.insert(std::make_pair(encryption, cache)); - if(!protocols.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { + if (!protocols.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) throw LMDBAL::Directory(protocols.fileName().toStdString()); - } + QTextStream out(&protocols); out << encryption + "\n"; protocols.close(); @@ -83,10 +81,12 @@ QXmppTask Core::TrustHandler::resetAll(const QString& encryption) { if (itr == keysByProtocol.end()) return Core::makeReadyTask(); + LMDBAL::WriteTransaction txn = db.beginTransaction(); KeyCache* cache = itr->second; - std::map keys = cache->readAll(); - cache->drop(); + std::map keys = cache->readAll(txn); + cache->drop(txn); + txn.commit(); for (const std::pair& pair : keys) { bool empty = true; for (const std::pair& trust : pair.second) { @@ -105,8 +105,8 @@ QXmppTask Core::TrustHandler::resetAll(const QString& encryption) { QXmppTask Core::TrustHandler::trustLevel( const QString& encryption, const QString& keyOwnerJid, - const QByteArray& keyId) -{ + const QByteArray& keyId +) { KeyCache* cache = getCache(encryption); Shared::TrustLevel level = Shared::TrustLevel::undecided; try { @@ -122,15 +122,17 @@ QXmppTask>> Core::TrustHandler::s const QString& encryption, const QList& keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, - QXmpp::TrustLevel newTrustLevel) -{ + QXmpp::TrustLevel newTrustLevel +) { QHash> modifiedKeys; Shared::TrustLevel oldLevel = convert(oldTrustLevel); Shared::TrustLevel newLevel = convert(newTrustLevel); std::set modifiedJids; KeyCache* cache = getCache(encryption); + + LMDBAL::WriteTransaction txn = db.beginTransaction(); for (const QString& keyOwnerJid : keyOwnerJids) { - Keys map = cache->getRecord(keyOwnerJid); + Keys map = cache->getRecord(keyOwnerJid, txn); uint count = 0; for (std::pair& pair : map) { Shared::TrustLevel& current = pair.second; @@ -142,8 +144,9 @@ QXmppTask>> Core::TrustHandler::s } } if (count > 0) - cache->changeRecord(keyOwnerJid, map); + cache->changeRecord(keyOwnerJid, map, txn); } + txn.commit(); for (const QString& jid : modifiedJids) emit trustLevelsChanged(jid, getSummary(jid)); @@ -153,18 +156,19 @@ QXmppTask>> Core::TrustHandler::s QXmppTask>> Core::TrustHandler::setTrustLevel( const QString& encryption, const QMultiHash& keyIds, - QXmpp::TrustLevel trustLevel) -{ + QXmpp::TrustLevel trustLevel +) { QHash> modifiedKeys; Shared::TrustLevel level = convert(trustLevel); std::set modifiedJids; KeyCache* cache = getCache(encryption); + LMDBAL::WriteTransaction txn = db.beginTransaction(); for (MultySB::const_iterator itr = keyIds.begin(), end = keyIds.end(); itr != end; ++itr) { const QString& keyOwnerJid = itr.key(); const QByteArray& keyId = itr.value(); try { - Keys map = cache->getRecord(keyOwnerJid); + Keys map = cache->getRecord(keyOwnerJid, txn); std::pair result = map.insert(std::make_pair(keyId, level)); bool changed = result.second; if (!changed && result.first->second != level) { @@ -174,15 +178,16 @@ QXmppTask>> Core::TrustHandler::s if (changed) { modifiedKeys[encryption].insert(keyOwnerJid, keyId); modifiedJids.insert(keyOwnerJid); - cache->changeRecord(keyOwnerJid, map); + cache->changeRecord(keyOwnerJid, map, txn); } } catch (const LMDBAL::NotFound& e) { Keys map({{keyId, level}}); modifiedKeys[encryption].insert(keyOwnerJid, keyId); modifiedJids.insert(keyOwnerJid); - cache->addRecord(keyOwnerJid, map); + cache->addRecord(keyOwnerJid, map, txn); } } + txn.commit(); for (const QString& jid : modifiedJids) emit trustLevelsChanged(jid, getSummary(jid)); @@ -190,10 +195,11 @@ QXmppTask>> Core::TrustHandler::s return Core::makeReadyTask(std::move(modifiedKeys)); } -QXmppTask Core::TrustHandler::hasKey(const QString& encryption, - const QString& keyOwnerJid, - QXmpp::TrustLevels trustLevels) -{ +QXmppTask Core::TrustHandler::hasKey( + const QString& encryption, + const QString& keyOwnerJid, + QXmpp::TrustLevels trustLevels +) { KeyCache* cache = getCache(encryption); bool found = false; try { @@ -211,8 +217,8 @@ QXmppTask Core::TrustHandler::hasKey(const QString& encryption, QXmppTask>> Core::TrustHandler::keys( const QString& encryption, const QList& keyOwnerJids, - QXmpp::TrustLevels trustLevels) -{ + QXmpp::TrustLevels trustLevels +) { HSHBTL res; KeyCache* cache = getCache(encryption); @@ -233,8 +239,8 @@ QXmppTask>> Core::TrustHandl QXmppTask>> Core::TrustHandler::keys( const QString& encryption, - QXmpp::TrustLevels trustLevels) -{ + QXmpp::TrustLevels trustLevels +) { QHash res; KeyCache* cache = getCache(encryption); std::map storage = cache->readAll(); @@ -253,9 +259,11 @@ QXmppTask Core::TrustHandler::removeKeys(const QString& encryption) { if (itr == keysByProtocol.end()) return Core::makeReadyTask(); + LMDBAL::WriteTransaction txn = db.beginTransaction(); KeyCache* cache = itr->second; - std::map keys = cache->readAll(); - cache->drop(); + std::map keys = cache->readAll(txn); + cache->drop(txn); + txn.commit(); for (const std::pair& pair : keys) { bool empty = true; @@ -292,8 +300,9 @@ QXmppTask Core::TrustHandler::removeKeys(const QString& encryption, const for (const QByteArray& keyId : keyIds) set.insert(keyId); + LMDBAL::WriteTransaction txn = db.beginTransaction(); KeyCache* cache = getCache(encryption); - std::map data = cache->readAll(); + std::map data = cache->readAll(txn); std::set modifiedJids; for (std::map::iterator cItr = data.begin(), cEnd = data.end(); cItr != cEnd; /*no increment*/) { @@ -311,10 +320,10 @@ QXmppTask Core::TrustHandler::removeKeys(const QString& encryption, const else ++cItr; } - if (modifiedJids.size() > 0) { - cache->replaceAll(data); - } + if (modifiedJids.size() > 0) + cache->replaceAll(data, txn); + txn.commit(); for (const QString& jid : modifiedJids) emit trustLevelsChanged(jid, getSummary(jid)); @@ -325,14 +334,15 @@ QXmppTask Core::TrustHandler::addKeys( const QString& encryption, const QString& keyOwnerJid, const QList& keyIds, - QXmpp::TrustLevel trustLevel) -{ + QXmpp::TrustLevel trustLevel +) { KeyCache* cache = getCache(encryption); Shared::TrustLevel level = convert(trustLevel); Keys data; bool had = false; + LMDBAL::WriteTransaction txn = db.beginTransaction(); try { - data = cache->getRecord(keyOwnerJid); + data = cache->getRecord(keyOwnerJid, txn); had = true; } catch (const LMDBAL::NotFound& e) {} for (const QByteArray& keyId : keyIds) { @@ -342,10 +352,11 @@ QXmppTask Core::TrustHandler::addKeys( } if (had) - cache->changeRecord(keyOwnerJid, data); + cache->changeRecord(keyOwnerJid, data, txn); else - cache->addRecord(keyOwnerJid, data); + cache->addRecord(keyOwnerJid, data, txn); + txn.commit(); emit trustLevelsChanged(keyOwnerJid, getSummary(keyOwnerJid)); return Core::makeReadyTask(); @@ -418,9 +429,9 @@ Shared::TrustSummary Core::TrustHandler::getSummary(const QString& jid) const { try { Keys keys = pair.second->getRecord(jid); Shared::EncryptionProtocol protocol = Shared::TrustSummary::protocolValues.at(pair.first); - for (const std::pair& trust : keys) { + for (const std::pair& trust : keys) result.increment(protocol, trust.second); - } + } catch (const LMDBAL::NotFound& e) {} } diff --git a/external/qxmpp b/external/qxmpp index 9e9c22b..8dda3c9 160000 --- a/external/qxmpp +++ b/external/qxmpp @@ -1 +1 @@ -Subproject commit 9e9c22b16a39c7370fed31c6deea56d8abf72440 +Subproject commit 8dda3c9921c34b9e33883b0d140e8de12edc0736 diff --git a/shared/enums.h b/shared/enums.h index 6b668d6..43d1583 100644 --- a/shared/enums.h +++ b/shared/enums.h @@ -136,6 +136,14 @@ enum class Support { }; Q_ENUM_NS(Support) +enum class Possible { + unknown, + discovering, + present, + abscent +}; +Q_ENUM_NS(Possible) + enum class TrustLevel { /// The key's trust is not decided. undecided, diff --git a/shared/message.cpp b/shared/message.cpp index caf8a97..70fae63 100644 --- a/shared/message.cpp +++ b/shared/message.cpp @@ -268,7 +268,9 @@ QDataStream& operator<<(QDataStream& out, const Shared::Message& info) { out << info.rTo; out << info.id; out << info.body; - out << info.time; + quint64 msecs = info.time.toMSecsSinceEpoch(); + out << msecs; + out << info.thread; out << (quint8)info.type; out << info.outgoing; @@ -297,7 +299,11 @@ QDataStream & operator>>(QDataStream& in, Shared::Message& info) { in >> info.rTo; in >> info.id; in >> info.body; - in >> info.time; + + quint64 msecs; + in >> msecs; + info.time = QDateTime::fromMSecsSinceEpoch(msecs); + in >> info.thread; quint8 t; in >> t; diff --git a/ui/widgets/chat.cpp b/ui/widgets/chat.cpp index 628f30f..b624a5d 100644 --- a/ui/widgets/chat.cpp +++ b/ui/widgets/chat.cpp @@ -32,10 +32,7 @@ Chat::Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent): connect(contact, &Models::Contact::childChanged, this, &Chat::onContactChanged); #ifdef WITH_OMEMO - if (p_contact->hasKeys(Shared::EncryptionProtocol::omemo2)) { - m_ui->encryptionButton->setVisible(true); - updateEncryptionState(); - } + updateEncryptionState(); #endif } @@ -59,9 +56,7 @@ void Chat::onContactChanged(Models::Item* item, int row, int col) { setAvatar(contact->getAvatarPath()); break; #ifdef WITH_OMEMO - case 8: - m_ui->encryptionButton->setVisible(contact->hasKeys(Shared::EncryptionProtocol::omemo2)); - break; + case 8: //[fallthrough] case 9: updateEncryptionState(); break; @@ -77,11 +72,16 @@ void Chat::updateState() { } void Chat::updateEncryptionState() { - m_ui->encryptionButton->setEnabled(true); - if (contact->getEncryption() == Shared::EncryptionProtocol::omemo2) - m_ui->encryptionButton->setIcon(Shared::icon("lock")); - else - m_ui->encryptionButton->setIcon(Shared::icon("unlock")); + if (contact->hasKeys(Shared::EncryptionProtocol::omemo2)) { + m_ui->encryptionButton->setVisible(true); + m_ui->encryptionButton->setEnabled(true); + if (contact->getEncryption() == Shared::EncryptionProtocol::omemo2) + m_ui->encryptionButton->setIcon(Shared::icon("lock")); + else + m_ui->encryptionButton->setIcon(Shared::icon("unlock")); + } else { + m_ui->encryptionButton->setVisible(false); + } }