[network/ruqola] src/core: Allow to send encrypted message

Laurent Montel <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit e98bc803068cc7fa38d4876d0d78bad61798b814 by Laurent Montel.
Committed on 06/08/2026 at 11:53.
Pushed by mlaurent into branch 'master'.

Allow to send encrypted message

M  +8    -3    src/core/connection.cpp
M  +7    -2    src/core/connection.h
M  +31   -2    src/core/rocketchataccount.cpp

https://invent.kde.org/network/ruqola/-/commit/e98bc803068cc7fa38d4876d0d78bad61798b814

diff --git a/src/core/connection.cpp b/src/core/connection.cpp
index ab166ff38a..57ea1fc674 100644
--- a/src/core/connection.cpp
+++ b/src/core/connection.cpp
@@ -300,13 +300,14 @@ void Connection::serverInfo()
     }
 }
 
-void Connection::postMessage(const QByteArray &roomId, const QString &text)
+void Connection::postMessage(const QByteArray &roomId, const QString &text, const RocketChatRestApi::EncryptedInfo &encryptedInfo)
 {
     auto job = new PostMessageJob(this);
     connect(job, &PostMessageJob::postMessageDone, this, &Connection::postMessageDone);
     initializeRestApiJob(job);
     job->setRoomIds({roomId});
     job->setText(text);
+    job->setEncryptedInfo(encryptedInfo);
     if (!job->start()) {
         qCWarning(RUQOLA_LOG) << "Impossible to start PostMessageJob job";
     }
@@ -1132,7 +1133,11 @@ void Connection::getThreadMessages(const QByteArray &threadMessageId)
     }
 }
 
-void Connection::sendMessage(const QByteArray &roomId, const QString &text, const QString &messageId, const QByteArray &threadMessageId)
+void Connection::sendMessage(const QByteArray &roomId,
+                             const QString &text,
+                             const QString &messageId,
+                             const QByteArray &threadMessageId,
+                             const RocketChatRestApi::EncryptedInfo &encryptedInfo)
 {
     auto job = new SendMessageJob(this);
     initializeRestApiJob(job);
@@ -1141,7 +1146,7 @@ void Connection::sendMessage(const QByteArray &roomId, const QString &text, cons
         .roomId = QString::fromLatin1(roomId),
         .threadMessageId = QString::fromLatin1(threadMessageId),
         .message = text,
-        .info = EncryptedInfo(),
+        .info = encryptedInfo,
     };
     job->setSendMessageArguments(args);
     if (!job->start()) {
diff --git a/src/core/connection.h b/src/core/connection.h
index 5949302979..a5d546aa3a 100644
--- a/src/core/connection.h
+++ b/src/core/connection.h
@@ -8,6 +8,7 @@
 
 #include "channelgroupbasejob.h"
 #include "channels/channelhistoryjob.h"
+#include "chat/encryptedinfo.h"
 #include "config-ruqola.h"
 #include "createchannelteaminfo.h"
 #include "job/adduserinchanneljob.h"
@@ -65,7 +66,7 @@ public:
     void getOwnInfo();
     RocketChatRestApi::DownloadFileJob *
     downloadFile(const QUrl &url, const QUrl &localFileUrl, const QByteArray &mimeType = "text/plain", bool requiredAuthentication = true);
-    void postMessage(const QByteArray &roomId, const QString &text);
+    void postMessage(const QByteArray &roomId, const QString &text, const RocketChatRestApi::EncryptedInfo &encryptedInfo = {});
     void createChannels(const RocketChatRestApi::CreateChannelTeamInfo &info);
     void createGroups(const RocketChatRestApi::CreateChannelTeamInfo &info);
     void leaveChannel(const QByteArray &roomId);
@@ -121,7 +122,11 @@ public:
     void getMentionedMessages(Utils::ListMessagesInfo &&info);
 
     void getThreadMessages(const QByteArray &threadMessageId);
-    void sendMessage(const QByteArray &roomId, const QString &text, const QString &messageId = QString(), const QByteArray &threadMessageId = QByteArray());
+    void sendMessage(const QByteArray &roomId,
+                     const QString &text,
+                     const QString &messageId = QString(),
+                     const QByteArray &threadMessageId = QByteArray(),
+                     const RocketChatRestApi::EncryptedInfo &encryptedInfo = {});
     void setUserStatus(const QString &userId, RocketChatRestApi::SetStatusJob::StatusType status, const QString &message = QString());
     void usersPresence();
     void usersAutocomplete(const RocketChatRestApi::UsersAutocompleteJob::UsersAutocompleterInfo &info);
diff --git a/src/core/rocketchataccount.cpp b/src/core/rocketchataccount.cpp
index 50c0972d27..52e8e6d52a 100644
--- a/src/core/rocketchataccount.cpp
+++ b/src/core/rocketchataccount.cpp
@@ -39,6 +39,7 @@
 #include "encryption/e2ekeymanager.h"
 #include "managerdatapaths.h"
 #include "messagequeue.h"
+#include "messages/messageencrypted.h"
 #include "notificationhistorymanager.h"
 #include "previewurlcachemanager.h"
 #include "serverconfiginfo.h"
@@ -539,9 +540,37 @@ void RocketChatAccount::sendMessage(const QByteArray &roomID, const QString &mes
     Room *const room = mRoomModel->findRoom(roomID);
     if (room && room->encrypted()) {
         const QByteArray sessionKey = room->sessionKey();
-        if (!sessionKey.isEmpty()) {
-            // TODO mE2eKeyManager->cr
+        if (sessionKey.isEmpty()) {
+            qCWarning(RUQOLA_ENCRYPTION_LOG) << debugCategoryAccountName() << "Unable to send encrypted message: missing room session key for" << roomID;
+            mE2eKeyManager->decodeEncryptionKey();
+            return;
+        }
+
+        const QByteArray keyId = room->e2eKeyId().toLatin1();
+        if (keyId.isEmpty()) {
+            qCWarning(RUQOLA_ENCRYPTION_LOG) << debugCategoryAccountName() << "Unable to send encrypted message: missing room key id for" << roomID;
+            return;
         }
+
+        QJsonObject payload;
+        payload.insert(u"msg"_s, message);
+
+        MessageEncrypted encryptedMessage;
+        const bool ok = encryptedMessage.encrypt(QJsonDocument(payload).toJson(QJsonDocument::Compact), sessionKey, keyId);
+        if (!ok) {
+            qCWarning(RUQOLA_ENCRYPTION_LOG) << debugCategoryAccountName() << "Unable to encrypt message for" << roomID;
+            return;
+        }
+
+        const RocketChatRestApi::EncryptedInfo info{
+            .algorithm = encryptedMessage.algorithm(),
+            .keyId = encryptedMessage.keyId(),
+            .ciphertext = encryptedMessage.ciphertext(),
+            .iv = encryptedMessage.iv(),
+        };
+        restApi()->sendMessage(roomID, message, {}, {}, info);
+        markRoomAsRead(roomID);
+        return;
     }
     restApi()->postMessage(roomID, message);
     markRoomAsRead(roomID);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.