FIX: Minor fixes to previous commit.

FIX: Minor fixes to previous commit.

diff --git a/assets/javascripts/discourse/controllers/activate-encrypt.js.es6 b/assets/javascripts/discourse/controllers/activate-encrypt.js.es6
index 09b14b2..1e127c4 100644
--- a/assets/javascripts/discourse/controllers/activate-encrypt.js.es6
+++ b/assets/javascripts/discourse/controllers/activate-encrypt.js.es6
@@ -1,6 +1,6 @@
 import ModalFunctionality from "discourse/mixins/modal-functionality";
 import { saveDbIdentity } from "discourse/plugins/discourse-encrypt/lib/database";
-import { importIdentity } from "discourse/plugins/discourse-encrypt/lib/discourse";
+import { importIdentity } from "discourse/plugins/discourse-encrypt/lib/protocol";
 
 export default Ember.Controller.extend(ModalFunctionality, {
   onShow() {
@@ -28,9 +28,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
     activate() {
       this.set("inProgress", true);
 
-      const user = Discourse.User.current();
-
-      const exported = user.get("model.custom_fields.encrypt_private");
+      const exported = this.currentUser.custom_fields.encrypt_private;
       return importIdentity(exported, this.passphrase)
         .then(identity => saveDbIdentity(identity))
         .then(() => {
diff --git a/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6 b/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6
index 0765541..42cc317 100644
--- a/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6
+++ b/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6
@@ -127,16 +127,23 @@ export default {
           const ciphertext = attrs.encrypted_raw;
           if (
             hasTopicKey(topicId) &&
+            ciphertext &&
             (!state.encrypted || state.encrypted !== ciphertext)
           ) {
             state.encrypted = ciphertext;
             state.decrypting = true;
 
-            getIdentity()
-              .then(() => {
-                getTopicKey(topicId)
-                  .then(key => decrypt(key, ciphertext))
-                  .then(plaintext => {
+            getIdentity().then(identity => {
+              if (!identity) {
+                // Absence of private key means user did not activate encryption.
+                showModal("activate-encrypt", { model: this });
+                return;
+              }
+
+              getTopicKey(topicId)
+                .then(key => decrypt(key, ciphertext))
+                .then(plaintext => {
+                  if (plaintext.signature) {
                     getUserIdentities([plaintext.signed_by_name])
                       .then(identities =>
                         verify(
@@ -153,23 +160,22 @@ export default {
                       .catch(() => {
                         verified[attrs.id] = false;
                       });
-
-                    return cookAsync(plaintext.raw);
-                  })
-                  .then(cooked => {
-                    state.decrypting = false;
-                    state.decrypted = cooked.string;
-                    this.scheduleRerender();
-                  })
-                  // Absence of topic key underlies a bigger error.
-                  .catch(() => {
-                    state.decrypting = false;
-                    state.decrypted = true;
-                    this.scheduleRerender();
-                  });
-              })
-              // Absence of private key means user did not activate encryption.
-              .catch(() => showModal("activate-encrypt", { model: this }));
+                  }
+
+                  return cookAsync(plaintext.raw);
+                })
+                .then(cooked => {
+                  state.decrypting = false;
+                  state.decrypted = cooked.string;
+                  this.scheduleRerender();
+                })
+                // Absence of topic key underlies a bigger error.
+                .catch(() => {
+                  state.decrypting = false;
+                  state.decrypted = true;
+                  this.scheduleRerender();
+                });
+            });
           }
 
           if (state.decrypted && state.decrypted !== true) {
diff --git a/assets/javascripts/discourse/initializers/hook-save.js.es6 b/assets/javascripts/discourse/initializers/hook-save.js.es6
index bce2533..34a0183 100644
--- a/assets/javascripts/discourse/initializers/hook-save.js.es6
+++ b/assets/javascripts/discourse/initializers/hook-save.js.es6
@@ -172,25 +172,26 @@ export default {
           encryptedKeysPromise
         ])
           .then(() => _super.call(this, ...arguments))
-          .then(result => {
-            return Ember.RSVP.Promise.all([
-              topicKey.then(key => putTopicKey(result.payload.topic_id, key)),
-              Ember.RSVP.Promise.all([topicKey, identityPromise])
-                .then(([key, identity]) =>
-                  encrypt(
-                    key,
-                    addMetadata({
-                      raw,
-                      topic_id: result.payload.topic_id,
-                      post_id: result.payload.id
-                    }),
-                    {
-                      signKey: identity.signPrivate,
-                      includeUploads: true
-                    }
-                  )
-                )
-                .then(encryptedRaw =>
+          .then(result =>
+            Ember.RSVP.Promise.all([topicKey, identityPromise])
+              .then(([key, identity]) => {
+                putTopicKey(result.payload.topic_id, key);
+                if (!identity.signPrivate) {
+                  return;
+                }
+
+                return encrypt(
+                  key,
+                  addMetadata({
+                    raw,
+                    topic_id: result.payload.topic_id,
+                    post_id: result.payload.id
+                  }),
+                  {
+                    signKey: identity.signPrivate,
+                    includeUploads: true
+                  }
+                ).then(encryptedRaw =>
                   ajax(
                     this.pathFor(store, type, result.payload.id),
                     this.getPayload("PUT", {
@@ -201,9 +202,10 @@ export default {
                       }
                     })
                   )
-                )
-            ]).then(() => result);
-          });
+                );
+              })
+              .then(() => result)
+          );
       },
 
       update(store, type, id, attrs) {
diff --git a/assets/javascripts/lib/protocol.js.es6 b/assets/javascripts/lib/protocol.js.es6
index 27c8a07..ea31a14 100644
--- a/assets/javascripts/lib/protocol.js.es6
+++ b/assets/javascripts/lib/protocol.js.es6
@@ -64,7 +64,13 @@ export function generateIdentity() {
 export function exportIdentity(identity, passphrase) {
   let promise;
   if (identity.version === 0) {
-    promise = exportIdentityV0(identity, passphrase);
+    promise = exportIdentityV0(
+      {
+        publicKey: identity.encryptPublic,
+        privateKey: identity.encryptPrivate
+      },
+      passphrase
+    );
   } else if (identity.version === 1) {
     promise = exportIdentityV1(identity, passphrase);
   }
@@ -146,7 +152,7 @@ export function encrypt(key, data, opts) {
 
   let promise;
   if (version === 0) {
-    promise = encryptV0(key, data.raw);
+    promise = encryptV0(key, typeof data === "object" ? data.raw : data);
   } else if (version === 1) {
     promise = encryptV1(key, opts && opts.signKey, data);
   }
@@ -220,10 +226,10 @@ export function generateKey() {
 }
 
 /**
- * Exports a symmetric key, but wraps (encrypts) it first.
+ * Exports and wraps a symmetric key.
  *
  * @param {CryptoKey} key
- * @param {CryptoKey} publicKey   Key used to wrap the symmetric key.
+ * @param {CryptoKey} publicKey
  *
  * @return {Promise<String>}
  */
@@ -240,10 +246,10 @@ export function exportKey(key, publicKey) {
 }
 
 /**
- * Imports a symmetric key, but unwraps (decrypts) it first.
+ * Unwraps and imports a symmetric key.
  *

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

GitHub sha: 78c59d15