diff --git a/.gitmodules b/.gitmodules
index bbe5364..098973a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "external/qxmpp"]
path = external/qxmpp
url = https://github.com/qxmpp-project/qxmpp.git
+[submodule "external/storage"]
+ path = external/storage
+ url = https://git.macaw.me/blue/storage
diff --git a/CMakeLists.txt b/CMakeLists.txt
index af1e7f3..3f5bd96 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -147,7 +147,13 @@ else ()
endif ()
## LMDB
-find_package(LMDB REQUIRED)
+#find_package(LMDB REQUIRED)
+
+
+#TODO conditioning!
+add_subdirectory(external/storage)
+target_include_directories(squawk PRIVATE external/storage)
+target_link_libraries(squawk PRIVATE storage)
# Linking
target_link_libraries(squawk
diff --git a/core/handlers/omemohandler.cpp b/core/handlers/omemohandler.cpp
index ef2f5ea..c1dc7ef 100644
--- a/core/handlers/omemohandler.cpp
+++ b/core/handlers/omemohandler.cpp
@@ -14,4 +14,148 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include
#include "omemohandler.h"
+#include "core/account.h"
+
+Core::OmemoHandler::OmemoHandler(Account* account) :
+ QXmppOmemoStorage(),
+ acc(account),
+ ownDevice(std::nullopt),
+ db("omemo"),
+ meta(db.addCache("meta")),
+ devices(db.addCache>("devices")),
+ preKeyPairs(db.addCache("preKeyPairs")),
+ signedPreKeyPairs(db.addCache("signedPreKeyPairs"))
+{
+ db.open();
+ try {
+ QVariant own = meta->getRecord("ownDevice");
+ ownDevice.value() = own.value();
+ qDebug() << "Successfully found own device omemo data for account" << acc->getName();
+ } catch (const DataBase::NotFound& e) {
+ qDebug() << "No device omemo data was found for account" << acc->getName();
+ }
+}
+
+Core::OmemoHandler::~OmemoHandler() {
+ db.close();
+}
+
+QFuture Core::OmemoHandler::emptyVoidFuture() {
+ QFutureInterface result(QFutureInterfaceBase::Started);
+ result.reportFinished();
+ return result.future();
+}
+
+QFuture Core::OmemoHandler::allData() {
+ OmemoData data;
+ data.ownDevice = ownDevice;
+
+ std::map pkeys = preKeyPairs->readAll();
+ for (const std::pair& pair : pkeys) {
+ data.preKeyPairs.insert(pair.first, pair.second);
+ }
+
+ std::map spre = signedPreKeyPairs->readAll();
+ for (const std::pair& pair : spre) {
+ data.signedPreKeyPairs.insert(pair.first, pair.second);
+ }
+
+ std::map> devs = devices->readAll();
+ for (const std::pair>& pair : devs) {
+ data.devices.insert(pair.first, pair.second);
+ }
+
+ QFutureInterface result(QFutureInterfaceBase::Started);
+ result.reportResult(std::move(data));
+ result.reportFinished();
+ return result.future();
+}
+
+QFuture Core::OmemoHandler::addDevice(const QString& jid, uint32_t deviceId, const QXmppOmemoStorage::Device& device) {
+ QHash devs;
+ bool had = true;
+ try {
+ devs = devices->getRecord(jid);
+ } catch (const DataBase::NotFound& error) {
+ had = false;
+ }
+
+ devs.insert(deviceId, device);
+ if (had) {
+ devices->changeRecord(jid, devs);
+ } else {
+ devices->addRecord(jid, devs);
+ }
+
+ return emptyVoidFuture();
+}
+
+QFuture 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());
+ }
+
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::addSignedPreKeyPair(uint32_t keyId, const QXmppOmemoStorage::SignedPreKeyPair& keyPair) {
+ signedPreKeyPairs->addRecord(keyId, keyPair);
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::removeDevice(const QString& jid, uint32_t deviceId) {
+ QHash devs = devices->getRecord(jid);
+ devs.remove(deviceId);
+ if (devs.isEmpty()) {
+ devices->removeRecord(jid);
+ } else {
+ devices->changeRecord(jid, devs);
+ }
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::removeDevices(const QString& jid) {
+ devices->removeRecord(jid);
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::removePreKeyPair(uint32_t keyId) {
+ preKeyPairs->removeRecord(keyId);
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::removeSignedPreKeyPair(uint32_t keyId) {
+ signedPreKeyPairs->removeRecord(keyId);
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::setOwnDevice(const std::optional& device) {
+ bool had = ownDevice.has_value();
+ ownDevice = device;
+ if (ownDevice.has_value()) {
+ if (had) {
+ meta->changeRecord("ownDevice", QVariant::fromValue(ownDevice.value()));
+ } else {
+ meta->addRecord("ownDevice", QVariant::fromValue(ownDevice.value()));
+ }
+ } else {
+ if (had) {
+ meta->removeRecord("ownDevice");
+ }
+ }
+ return emptyVoidFuture();
+}
+
+QFuture Core::OmemoHandler::resetAll() {
+ ownDevice = std::nullopt;
+ db.drop();
+
+ return emptyVoidFuture();
+}
+
+
+
+
+
diff --git a/core/handlers/omemohandler.h b/core/handlers/omemohandler.h
index 2759a21..8f3ac9c 100644
--- a/core/handlers/omemohandler.h
+++ b/core/handlers/omemohandler.h
@@ -18,14 +18,17 @@
#define CORE_OMEMOHANDLER_H
#include
-#include
+#include
+
+Q_DECLARE_METATYPE(QXmppOmemoStorage::OwnDevice);
namespace Core {
+class Account;
class OmemoHandler : public QXmppOmemoStorage
{
public:
- OmemoHandler();
+ OmemoHandler(Account* account);
~OmemoHandler() override;
QFuture allData() override;
@@ -45,13 +48,24 @@ public:
QFuture resetAll() override;
private:
+ static QFuture emptyVoidFuture();
+
+private:
+ Account* acc;
std::optional ownDevice;
- Cache> devices;
- Cache preKeyPairs;
- Cache signedPreKeyPairs;
-
-
+ DataBase db;
+ DataBase::Cache* meta;
+ DataBase::Cache>* devices;
+ DataBase::Cache* preKeyPairs;
+ DataBase::Cache* signedPreKeyPairs;
};
}
+
+QDataStream& operator << (QDataStream &out, const QXmppOmemoStorage::Device& device);
+QDataStream& operator >> (QDataStream &out, QXmppOmemoStorage::Device device);
+
+QDataStream& operator << (QDataStream &out, const QXmppOmemoStorage::SignedPreKeyPair& device);
+QDataStream& operator >> (QDataStream &out, QXmppOmemoStorage::SignedPreKeyPair device);
+
#endif // CORE_OMEMOHANDLER_H
diff --git a/external/qxmpp b/external/qxmpp
index fe83e9c..f6e7591 160000
--- a/external/qxmpp
+++ b/external/qxmpp
@@ -1 +1 @@
-Subproject commit fe83e9c3d42c3becf682e2b5ecfc9d77b24c614f
+Subproject commit f6e7591e21b4c55319918ac296b2341b2e9f1988
diff --git a/external/storage b/external/storage
new file mode 160000
index 0000000..08daad4
--- /dev/null
+++ b/external/storage
@@ -0,0 +1 @@
+Subproject commit 08daad48ad36d9f12dc6485a085190e31e4cf49e
diff --git a/main/main.cpp b/main/main.cpp
index 086dbc0..58063e0 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -33,6 +33,10 @@
#include
#include
+#ifdef WITH_OMEMO
+#include
+#endif
+
int main(int argc, char *argv[])
{
qRegisterMetaType("Shared::Message");
@@ -40,12 +44,15 @@ int main(int argc, char *argv[])
qRegisterMetaType("Shared::VCard");
qRegisterMetaType>("std::list");
qRegisterMetaType>("std::list");
- qRegisterMetaType>("std::list");
- qRegisterMetaType>("std::set");
- qRegisterMetaType>("std::list");
+ qRegisterMetaType>("std::list");
+ qRegisterMetaType>("std::set");
+ qRegisterMetaType>("std::list");
qRegisterMetaType>("QSet");
qRegisterMetaType("Shared::ConnectionState");
qRegisterMetaType("Shared::Availability");
+#ifdef WITH_OMEMO
+ qRegisterMetaType("QXmppOmemoStorage::OwnDevice");
+#endif
QApplication app(argc, argv);
SignalCatcher sc(&app);