FIX: Show decrypted topic title in window name (#115)

FIX: Show decrypted topic title in window name (#115)

The window name used to show the placeholder instead of the decrypted topic title.

diff --git a/assets/javascripts/discourse/initializers/hook-decrypt-topic.js b/assets/javascripts/discourse/initializers/hook-decrypt-topic.js
index cb8e626..2786f57 100644
--- a/assets/javascripts/discourse/initializers/hook-decrypt-topic.js
+++ b/assets/javascripts/discourse/initializers/hook-decrypt-topic.js
@@ -1,10 +1,10 @@
-import I18n from "I18n";
+import Component from "@ember/component";
 import { scheduleOnce } from "@ember/runloop";
-import debounce from "discourse/plugins/discourse-encrypt/lib/debounce";
 import { iconHTML } from "discourse-common/lib/icon-library";
 import { withPluginApi } from "discourse/lib/plugin-api";
 import { emojiUnescape } from "discourse/lib/text";
 import { escapeExpression } from "discourse/lib/utilities";
+import debounce from "discourse/plugins/discourse-encrypt/lib/debounce";
 import {
   ENCRYPT_ACTIVE,
   getEncryptionStatus,
@@ -13,6 +13,7 @@ import {
   syncGetTopicTitle,
   waitForPendingTitles,
 } from "discourse/plugins/discourse-encrypt/lib/discourse";
+import I18n from "I18n";
 
 /**
  * Decrypts all elements described by a selector.
@@ -63,6 +64,7 @@ function decryptElements(containerSelector, elementSelector, opts) {
 
 export default {
   name: "hook-decrypt-topic",
+  container: null,
 
   initialize(container) {
     const currentUser = container.lookup("current-user:main");
@@ -71,13 +73,16 @@ export default {
       return;
     }
 
+    // Save a reference to container to be used by `decryptDocTitle`.
+    this.container = container;
+
     const appEvents = container.lookup("service:app-events");
     appEvents.on("encrypt:status-changed", this, this.decryptTitles);
     appEvents.on("page:changed", this, this.decryptDocTitle);
 
     // Try to decrypt new titles that may appear after rendering a component.
-    let self = this;
-    Ember.Component.reopen({
+    const self = this;
+    Component.reopen({
       didRender() {
         scheduleOnce("afterRender", self, () => {
           debounce(self, self.decryptTitles, 500);
@@ -165,19 +170,18 @@ export default {
   },
 
   decryptDocTitle(data) {
-    if (data.currentRouteName.startsWith("topic.")) {
-      const topicId = Discourse.__container__
-        .lookup("controller:topic")
-        .get("model.id");
-      getTopicTitle(topicId).then((topicTitle) =>
-        Discourse.set(
-          "_docTitle",
-          data.title.replace(
-            I18n.t("encrypt.encrypted_topic_title"),
-            topicTitle
-          )
-        )
-      );
+    if (!data.currentRouteName.startsWith("topic.")) {
+      return;
     }
+
+    const topicId = this.container.lookup("controller:topic").get("model.id");
+    getTopicTitle(topicId).then((topicTitle) => {
+      const documentTitle = this.container.lookup("service:document-title");
+      documentTitle.setTitle(
+        documentTitle
+          .getTitle()
+          .replace(I18n.t("encrypt.encrypted_topic_title"), topicTitle)
+      );
+    });
   },
 };
diff --git a/test/javascripts/acceptance/encrypt-test.js b/test/javascripts/acceptance/encrypt-test.js
index d519acb..1720639 100644
--- a/test/javascripts/acceptance/encrypt-test.js
+++ b/test/javascripts/acceptance/encrypt-test.js
@@ -1,3 +1,4 @@
+import { visit } from "@ember/test-helpers";
 import User from "discourse/models/user";
 import {
   deleteDb,
@@ -24,11 +25,13 @@ import { parsePostData } from "discourse/tests/helpers/create-pretender";
 import {
   acceptance,
   count,
+  query,
   queryAll,
   updateCurrentUser,
 } from "discourse/tests/helpers/qunit-helpers";
 import selectKit from "discourse/tests/helpers/select-kit-helper";
 import I18n from "I18n";
+import { test } from "qunit";
 import { Promise } from "rsvp";
 import sinon from "sinon";
 
@@ -173,6 +176,8 @@ acceptance("Encrypt", function (needs) {
     // Restore `XMLHttpRequest`.
     XMLHttpRequest.prototype.send = XMLHttpRequest.prototype.send_;
     delete XMLHttpRequest.prototype.send_;
+
+    globalAssert = null;
   });
 
   needs.pretender((server, helper) => {
@@ -204,8 +209,6 @@ acceptance("Encrypt", function (needs) {
       () => requests.includes("/posts"),
       () => click("button.create")
     );
-
-    globalAssert = null;
   });
 
   test("posting does not leak plaintext", async (assert) => {
@@ -256,11 +259,6 @@ acceptance("Encrypt", function (needs) {
     await composerActions.expand();
     await composerActions.selectRowByValue("reply_as_private_message");
 
-    if (find(".users-input").text().trim() !== "") {
-      globalAssert = null;
-      throw new Error("Another test is leaking composer state");
-    }
-
     // simulate selecting from autocomplete suggestions
     await fillIn("#private-message-users .filter-input", "evilt");
     await keyEvent("#private-message-users .filter-input", "keydown", 13);
@@ -282,8 +280,6 @@ acceptance("Encrypt", function (needs) {
       () => requests.includes("/posts") && requests.includes("/encrypt/post"),
       () => click("button.create")
     );
-
-    globalAssert = null;
   });
 
   test("new draft for public topic is not encrypted", async (assert) => {
@@ -356,6 +352,260 @@ acceptance("Encrypt", function (needs) {
     assert.rejects(loadDbIdentity());
   });
 
+  test("viewing encrypted topic works", async (assert) => {
+    await setEncryptionStatus(ENCRYPT_ACTIVE);
+    globalAssert = assert;
+
+    const identity = await getIdentity();
+    const topicKey = await generateKey();
+    const exportedTopicKey = await exportKey(topicKey, identity.encryptPublic);
+    const encryptedTitle = await encrypt(topicKey, { raw: "Top Secret Title" });
+    const encryptedRaw = await encrypt(topicKey, { raw: "Top Secret Post" });
+
+    server.get("/t/42.json", () => {
+      return [
+        200,
+        { "Content-Type": "application/json" },
+        {
+          post_stream: {
+            posts: [
+              {
+                id: 42,
+                name: null,
+                username: "bar",
+                avatar_template:
+                  "/letter_avatar_proxy/v4/letter/b/000000/{size}.png",
+                created_at: "2020-01-01T12:00:00.000Z",
+                cooked:
+                  "<p>This is a secret message with end to end encryption. To view it, you must be invited to this topic.</p>",
+                post_number: 1,
+                post_type: 1,
+                updated_at: "2020-01-01T12:00:00.000Z",
+                reply_count: 0,
+                reply_to_post_number: null,
+                quote_count: 0,
+                incoming_link_count: 0,
+                reads: 2,
+                readers_count: 1,
+                score: 0.4,
+                yours: false,
+                topic_id: 42,
+                topic_slug: "a-secret-message",
+                display_username: null,
+                primary_group_name: null,
+                primary_group_flair_url: null,
+                primary_group_flair_bg_color: null,
+                primary_group_flair_color: null,
+                version: 1,
+                can_edit: true,
+                can_delete: false,
+                can_recover: false,
+                can_wiki: true,
+                read: true,
+                user_title: null,
+                title_is_group: false,
+                bookmarked: false,
+                actions_summary: [
+                  {
+                    id: 2,
+                    can_act: true,
+                  },
+                  {
+                    id: 3,
+                    can_act: true,
+                  },
+                  {
+                    id: 4,
+                    can_act: true,
+                  },
+                  {
+                    id: 8,
+                    can_act: true,
+                  },
+                  {
+                    id: 6,
+                    can_act: true,
+                  },
+                  {
+                    id: 7,
+                    can_act: true,
+                  },

[... diff too long, it was truncated ...]

GitHub sha: 5263858048ba93db0a1db57b706cc5fece1c68a7

1 Like