forked from blue/squawk
cant believe it, first ever encrypted messages!
This commit is contained in:
parent
a7d1a28f29
commit
637eb702a8
10 changed files with 190 additions and 69 deletions
|
@ -71,26 +71,12 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) {
|
|||
case QXmppMessage::GroupChat:
|
||||
handled = handleGroupMessage(msg);
|
||||
break;
|
||||
case QXmppMessage::Error: {
|
||||
std::tuple<bool, QString, QString> ids = getOriginalPendingMessageId(msg.id());
|
||||
if (std::get<0>(ids)) {
|
||||
QString id = std::get<1>(ids);
|
||||
QString jid = std::get<2>(ids);
|
||||
RosterItem* cnt = acc->rh->getRosterItem(jid);
|
||||
QMap<QString, QVariant> cData = {
|
||||
{"state", static_cast<uint>(Shared::Message::State::error)},
|
||||
{"errorText", msg.error().text()}
|
||||
};
|
||||
if (cnt != nullptr)
|
||||
cnt->changeMessage(id, cData);
|
||||
|
||||
emit acc->changeMessage(jid, id, cData);
|
||||
handled = true;
|
||||
} else {
|
||||
case QXmppMessage::Error:
|
||||
handled = handlePendingMessageError(msg.id(), msg.error().text());
|
||||
if (!handled)
|
||||
qDebug() << "received a message with type \"Error\", not sure what to do with it now, skipping";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case QXmppMessage::Headline:
|
||||
qDebug() << "received a message with type \"Headline\", not sure what to do with it now, skipping";
|
||||
break;
|
||||
|
@ -99,6 +85,27 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) {
|
|||
logMessage(msg);
|
||||
}
|
||||
|
||||
bool Core::MessageHandler::handlePendingMessageError(const QString& id, const QString& errorText) {
|
||||
std::tuple<bool, QString, QString> ids = getOriginalPendingMessageId(id);
|
||||
if (std::get<0>(ids)) {
|
||||
QString id = std::get<1>(ids);
|
||||
QString jid = std::get<2>(ids);
|
||||
RosterItem* ri = acc->rh->getRosterItem(jid);
|
||||
QMap<QString, QVariant> cData = {
|
||||
{"state", static_cast<uint>(Shared::Message::State::error)},
|
||||
{"errorText", errorText}
|
||||
};
|
||||
if (ri != nullptr)
|
||||
ri->changeMessage(id, cData);
|
||||
|
||||
emit acc->changeMessage(jid, id, cData);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Core::MessageHandler::handleChatMessage(const QXmppMessage& msg, bool outgoing, bool forwarded, bool guessing) {
|
||||
if (msg.body().size() != 0 || msg.outOfBandUrl().size() > 0) {
|
||||
Shared::Message sMsg(Shared::Message::chat);
|
||||
|
@ -182,9 +189,9 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
|
|||
QString id;
|
||||
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0)
|
||||
id = source.originId();
|
||||
if (id.size() == 0) {
|
||||
if (id.size() == 0)
|
||||
id = source.id();
|
||||
}
|
||||
|
||||
target.setStanzaId(source.stanzaId());
|
||||
qDebug() << "initializing message with originId:" << source.originId() << ", id:" << source.id() << ", stansaId:" << source.stanzaId();
|
||||
#else
|
||||
|
@ -202,24 +209,19 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
|
|||
target.setBody(source.body());
|
||||
target.setForwarded(forwarded);
|
||||
|
||||
if (guessing) {
|
||||
if (target.getFromJid() == acc->getBareJid()) {
|
||||
outgoing = true;
|
||||
} else {
|
||||
outgoing = false;
|
||||
}
|
||||
}
|
||||
if (guessing)
|
||||
outgoing = target.getFromJid() == acc->getBareJid();
|
||||
|
||||
target.setOutgoing(outgoing);
|
||||
if (time.isValid()) {
|
||||
if (time.isValid())
|
||||
target.setTime(time);
|
||||
} else {
|
||||
else
|
||||
target.setCurrentTime();
|
||||
}
|
||||
|
||||
|
||||
QString oob = source.outOfBandUrl();
|
||||
if (oob.size() > 0) {
|
||||
if (oob.size() > 0)
|
||||
target.setAttachPath(acc->network->addMessageAndCheckForPath(oob, acc->getName(), target.getPenPalJid(), messageId));
|
||||
}
|
||||
|
||||
target.setOutOfBandUrl(oob);
|
||||
}
|
||||
|
||||
|
@ -249,7 +251,7 @@ void Core::MessageHandler::onCarbonMessageSent(const QXmppMessage& msg) {
|
|||
}
|
||||
#endif
|
||||
|
||||
std::tuple<bool, QString, QString> Core::MessageHandler::getOriginalPendingMessageId(const QString& id) {
|
||||
std::tuple<bool, QString, QString> Core::MessageHandler::getOriginalPendingMessageId(const QString& id, bool clear) {
|
||||
std::tuple<bool, QString, QString> result({false, "", ""});
|
||||
std::map<QString, QString>::const_iterator itr = pendingStateMessages.find(id);
|
||||
if (itr != pendingStateMessages.end()) {
|
||||
|
@ -263,12 +265,14 @@ std::tuple<bool, QString, QString> Core::MessageHandler::getOriginalPendingMessa
|
|||
else
|
||||
std::get<1>(result) = itr->first;
|
||||
|
||||
pendingCorrectionMessages.erase(itrC);
|
||||
if (clear)
|
||||
pendingCorrectionMessages.erase(itrC);
|
||||
} else {
|
||||
std::get<1>(result) = itr->first;
|
||||
}
|
||||
|
||||
pendingStateMessages.erase(itr);
|
||||
if (clear)
|
||||
pendingStateMessages.erase(itr);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -281,9 +285,9 @@ void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString&
|
|||
QMap<QString, QVariant> cData = {{"state", static_cast<uint>(Shared::Message::State::delivered)}};
|
||||
RosterItem* ri = acc->rh->getRosterItem(std::get<2>(ids));
|
||||
|
||||
if (ri != nullptr) {
|
||||
if (ri != nullptr)
|
||||
ri->changeMessage(std::get<1>(ids), cData);
|
||||
}
|
||||
|
||||
emit acc->changeMessage(std::get<2>(ids), std::get<1>(ids), cData);
|
||||
}
|
||||
}
|
||||
|
@ -302,45 +306,25 @@ void Core::MessageHandler::performSending(Shared::Message data, const QString& o
|
|||
QString id = data.getId();
|
||||
qDebug() << "Sending message with id:" << id;
|
||||
if (originalId.size() > 0)
|
||||
qDebug() << "To replace one with id:" << originalId;
|
||||
qDebug() << "To replace the one with id:" << originalId;
|
||||
|
||||
RosterItem* ri = acc->rh->getRosterItem(jid);
|
||||
bool sent = false;
|
||||
if (newMessage && originalId.size() > 0)
|
||||
newMessage = false;
|
||||
|
||||
QDateTime sendTime = QDateTime::currentDateTimeUtc();
|
||||
if (acc->state == Shared::ConnectionState::connected) {
|
||||
QXmppMessage msg(createPacket(data, sendTime, originalId));
|
||||
|
||||
sent = acc->client.sendPacket(msg);
|
||||
if (sent) {
|
||||
data.setState(Shared::Message::State::sent);
|
||||
} else {
|
||||
data.setState(Shared::Message::State::error);
|
||||
data.setErrorText("Couldn't send message: internal QXMPP library error, probably need to check out the logs");
|
||||
}
|
||||
|
||||
} else {
|
||||
data.setState(Shared::Message::State::error);
|
||||
data.setErrorText("You are is offline or reconnecting");
|
||||
}
|
||||
std::pair<Shared::Message::State, QString> result = scheduleSending(data, sendTime, originalId);
|
||||
data.setState(result.first);
|
||||
data.setErrorText(result.second);
|
||||
|
||||
QMap<QString, QVariant> changes(getChanges(data, sendTime, newMessage, originalId));
|
||||
|
||||
QString realId;
|
||||
if (originalId.size() > 0)
|
||||
realId = originalId;
|
||||
else
|
||||
realId = id;
|
||||
|
||||
if (ri != nullptr) {
|
||||
if (newMessage)
|
||||
ri->appendMessageToArchive(data);
|
||||
else
|
||||
ri->changeMessage(realId, changes);
|
||||
ri->changeMessage(originalId.isEmpty() ? id : originalId, changes);
|
||||
|
||||
if (sent) {
|
||||
if (data.getState() != Shared::Message::State::error) {
|
||||
pendingStateMessages.insert(std::make_pair(id, jid));
|
||||
if (originalId.size() > 0)
|
||||
pendingCorrectionMessages.insert(std::make_pair(id, originalId));
|
||||
|
@ -350,9 +334,81 @@ void Core::MessageHandler::performSending(Shared::Message data, const QString& o
|
|||
}
|
||||
}
|
||||
|
||||
emit acc->changeMessage(jid, realId, changes);
|
||||
emit acc->changeMessage(jid, originalId.isEmpty() ? id : originalId, changes);
|
||||
}
|
||||
|
||||
std::pair<Shared::Message::State, QString> Core::MessageHandler::scheduleSending(
|
||||
const Shared::Message& message,
|
||||
const QDateTime& sendTime,
|
||||
const QString& originalId
|
||||
) {
|
||||
if (acc->state != Shared::ConnectionState::connected)
|
||||
return {Shared::Message::State::error, "You are is offline or reconnecting"};
|
||||
|
||||
QXmppMessage msg = createPacket(message, sendTime, originalId);
|
||||
QString id = msg.id();
|
||||
#ifdef WITH_OMEMO
|
||||
if (message.getEncryption() == Shared::EncryptionProtocol::omemo2) {
|
||||
QXmppTask<QXmppE2eeExtension::MessageEncryptResult> task = acc->om->encryptMessage(std::move(msg), std::nullopt);
|
||||
if (task.isFinished()) {
|
||||
const QXmppE2eeExtension::MessageEncryptResult& res = task.result();
|
||||
if (std::holds_alternative<std::unique_ptr<QXmppMessage>>(res)) {
|
||||
const std::unique_ptr<QXmppMessage>& encrypted = std::get<std::unique_ptr<QXmppMessage>>(res);
|
||||
bool success = acc->client.sendPacket(*encrypted.get());
|
||||
if (success)
|
||||
return {Shared::Message::State::sent, ""};
|
||||
else
|
||||
return {Shared::Message::State::error, "Error sending successfully encrypted message"};
|
||||
} else if (std::holds_alternative<QXmppError>(res)) {
|
||||
const QXmppError& err = std::get<QXmppError>(res);
|
||||
return {Shared::Message::State::error, err.description};
|
||||
} else {
|
||||
return {Shared::Message::State::error, "Unexpected error ecryptng the message"};
|
||||
}
|
||||
} else {
|
||||
task.then(this, [this, id] (QXmppE2eeExtension::MessageEncryptResult&& result) {
|
||||
if (std::holds_alternative<std::unique_ptr<QXmppMessage>>(result)) {
|
||||
const std::unique_ptr<QXmppMessage>& encrypted = std::get<std::unique_ptr<QXmppMessage>>(result);
|
||||
encrypted->setBody("This message is encrypted with OMEMO 2 but could not be decrypted");
|
||||
bool success = acc->client.sendPacket(*encrypted.get());
|
||||
if (success) {
|
||||
std::tuple<bool, QString, QString> ids = getOriginalPendingMessageId(id, false);
|
||||
if (std::get<0>(ids)) {
|
||||
QString id = std::get<1>(ids);
|
||||
QString jid = std::get<2>(ids);
|
||||
RosterItem* ri = acc->rh->getRosterItem(jid);
|
||||
QMap<QString, QVariant> cData = {{"state", static_cast<uint>(Shared::Message::State::sent)}};
|
||||
if (ri != nullptr)
|
||||
ri->changeMessage(id, cData);
|
||||
|
||||
emit acc->changeMessage(jid, id, cData);
|
||||
} else {
|
||||
qDebug() << "Encrypted message has been successfully sent, but it couldn't be found to update the sate";
|
||||
}
|
||||
} else {
|
||||
handlePendingMessageError(id, "Error sending successfully encrypted message");
|
||||
}
|
||||
} else if (std::holds_alternative<QXmppError>(result)) {
|
||||
const QXmppError& err = std::get<QXmppError>(result);
|
||||
handlePendingMessageError(id, err.description);
|
||||
} else {
|
||||
handlePendingMessageError(id, "Unexpected error ecryptng the message");
|
||||
}
|
||||
});
|
||||
return {Shared::Message::State::pending, ""};
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
bool success = acc->client.sendPacket(msg);
|
||||
if (success)
|
||||
return {Shared::Message::State::sent, ""};
|
||||
else
|
||||
return {Shared::Message::State::error, "Error sending message, internal QXMPP error"};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QMap<QString, QVariant> Core::MessageHandler::getChanges(Shared::Message& data, const QDateTime& time, bool newMessage, const QString& originalId) const {
|
||||
QMap<QString, QVariant> changes;
|
||||
|
||||
|
|
|
@ -23,9 +23,13 @@
|
|||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
#include <QXmppMessage.h>
|
||||
#include <QXmppHttpUploadIq.h>
|
||||
#ifdef WITH_OMEMO
|
||||
#include <QXmppE2eeExtension.h>
|
||||
#endif
|
||||
|
||||
#include <shared/message.h>
|
||||
#include <shared/messageinfo.h>
|
||||
|
@ -74,7 +78,9 @@ private:
|
|||
void handleUploadError(const QString& jid, const QString& messageId, const QString& errorText);
|
||||
QXmppMessage createPacket(const Shared::Message& data, const QDateTime& time, const QString& originalId) const;
|
||||
QMap<QString, QVariant> getChanges(Shared::Message& data, const QDateTime& time, bool newMessage, const QString& originalId) const;
|
||||
std::tuple<bool, QString, QString> getOriginalPendingMessageId(const QString& id);
|
||||
std::tuple<bool, QString, QString> getOriginalPendingMessageId(const QString& id, bool clear = true);
|
||||
bool handlePendingMessageError(const QString& id, const QString& errorText);
|
||||
std::pair<Shared::Message::State, QString> scheduleSending(const Shared::Message& message, const QDateTime& sendTime, const QString& originalId);
|
||||
|
||||
private:
|
||||
Account* acc;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue