From c4c13a1da9d477dde4f52b1ff9b8327cfef55f9d Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Mon, 8 Nov 2021 19:32:14 +0100
Subject: [PATCH] Fix redaction of edited messages

---
 src/timeline/EventStore.cpp    |  3 ++-
 src/timeline/EventStore.h      |  2 +-
 src/timeline/TimelineModel.cpp | 36 ++++++++++++++++++++++++++++++++--
 src/timeline/TimelineModel.h   |  2 +-
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index a1f4c67f3..7bb985f85 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -447,7 +447,8 @@ EventStore::edits(const std::string &event_id)
     auto event_ids = cache::client()->relatedEvents(room_id_, event_id);
 
     auto original_event = get(event_id, "", false, false);
-    if (!original_event)
+    if (!original_event ||
+        std::holds_alternative<mtx::events::RoomEvent<mtx::events::msg::Redacted>>(*original_event))
         return {};
 
     auto original_sender    = mtx::accessors::sender(*original_event);
diff --git a/src/timeline/EventStore.h b/src/timeline/EventStore.h
index 9b857dcfa..1730f9fdd 100644
--- a/src/timeline/EventStore.h
+++ b/src/timeline/EventStore.h
@@ -77,6 +77,7 @@ public:
     mtx::events::collections::TimelineEvents *get(int idx, bool decrypt = true);
 
     QVariantList reactions(const std::string &event_id);
+    std::vector<mtx::events::collections::TimelineEvents> edits(const std::string &event_id);
     olm::DecryptionErrorCode decryptionError(std::string id);
     void requestSession(const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &ev,
                         bool manual);
@@ -120,7 +121,6 @@ public slots:
     void enableKeyRequests(bool suppressKeyRequests_);
 
 private:
-    std::vector<mtx::events::collections::TimelineEvents> edits(const std::string &event_id);
     olm::DecryptionResult *decryptEvent(
       const IdIndex &idx,
       const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e);
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 0e5ce510b..aa7a68f30 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -344,6 +344,19 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
       [](const QString &msg) { emit ChatPage::instance()->showNotification(msg); },
       Qt::QueuedConnection);
 
+    connect(this, &TimelineModel::dataAtIdChanged, this, [this](QString id) {
+        relatedEventCacheBuster++;
+
+        auto idx = idToIndex(id);
+        if (idx != -1) {
+            auto pos = index(idx);
+            nhlog::ui()->debug("data changed at {}", id.toStdString());
+            emit dataChanged(pos, pos);
+        } else {
+            nhlog::ui()->debug("id not found {}", id.toStdString());
+        }
+    });
+
     connect(this,
             &TimelineModel::newMessageToSend,
             this,
@@ -1095,7 +1108,8 @@ TimelineModel::showReadReceipts(QString id)
 void
 TimelineModel::redactEvent(QString id)
 {
-    if (!id.isEmpty())
+    if (!id.isEmpty()) {
+        auto edits = events.edits(id.toStdString());
         http::client()->redact_event(
           room_id_.toStdString(),
           id.toStdString(),
@@ -1106,8 +1120,26 @@ TimelineModel::redactEvent(QString id)
                   return;
               }
 
-              emit eventRedacted(id);
+              emit dataAtIdChanged(id);
           });
+
+        // redact all edits to prevent leaks
+        for (const auto &e : edits) {
+            auto id_ = mtx::accessors::event_id(e);
+            http::client()->redact_event(
+              room_id_.toStdString(),
+              id_,
+              [this, id, id_](const mtx::responses::EventId &, mtx::http::RequestErr err) {
+                  if (err) {
+                      emit redactionFailed(tr("Message redaction failed: %1")
+                                             .arg(QString::fromStdString(err->matrix_error.error)));
+                      return;
+                  }
+
+                  emit dataAtIdChanged(id);
+              });
+        }
+    }
 }
 
 int
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index f16529e21..af0674760 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -367,9 +367,9 @@ private slots:
     void scrollTimerEvent();
 
 signals:
+    void dataAtIdChanged(QString id);
     void currentIndexChanged(int index);
     void redactionFailed(QString id);
-    void eventRedacted(QString id);
     void mediaCached(QString mxcUrl, QString cacheUrl);
     void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
     void typingUsersChanged(std::vector<QString> users);
-- 
GitLab