UX: Improve error handling.

UX: Improve error handling.

Prevent users from enabling encryption multiple times.

From 8c6069bcaeceb4d99a3197e59151d6246384a983 Mon Sep 17 00:00:00 2001
From: Dan Ungureanu <dan@ungureanu.me>
Date: Thu, 29 Nov 2018 22:39:25 +0200
Subject: [PATCH] UX: Improve error handling.

Prevent users from enabling encryption multiple times.

diff --git a/assets/javascripts/discourse/connectors/user-preferences-account/encrypt.js.es6 b/assets/javascripts/discourse/connectors/user-preferences-account/encrypt.js.es6
index d1128d1..62b9b61 100644
--- a/assets/javascripts/discourse/connectors/user-preferences-account/encrypt.js.es6
+++ b/assets/javascripts/discourse/connectors/user-preferences-account/encrypt.js.es6
@@ -1,4 +1,5 @@
 import { ajax } from "discourse/lib/ajax";
+import { popupAjaxError } from "discourse/lib/ajax-error";
 import { registerHelper } from "discourse-common/lib/helpers";
 import {
   exportPrivateKey,
@@ -132,7 +133,9 @@ export default {
             isEnabled: true,
             isActive: true
           });
-        });
+        })
+
+        .catch(popupAjaxError);
     },
 
     activateEncrypt() {
@@ -177,6 +180,7 @@ export default {
     changeEncrypt() {
       this.set("inProgress", true);
 
+      const oldPublicStr = this.get("model.custom_fields.encrypt_public_key");
       const oldPrivateStr = this.get("model.custom_fields.encrypt_private_key");
 
       const oldPassphrase = this.get("old_passphrase");
@@ -203,7 +207,7 @@ export default {
           this.set("model.custom_fields.encrypt_private_key", privateStr);
           return ajax("/encrypt/keys", {
             type: "PUT",
-            data: { private_key: privateStr }
+            data: { public_key: oldPublicStr, private_key: privateStr }
           });
         })
 
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 4f3eb7c..9ae2cc1 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -1,5 +1,6 @@
 en:
   encrypt:
     encrypted_excerpt: "This message is encrypted, please read it in the browser."
+    enabled_already: "You have already enabled encrypted messages."
   site_settings:
     encrypt_enabled: "Enable encrypted private messages."
diff --git a/plugin.rb b/plugin.rb
index 4ee2ef5..ff139ae 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -39,14 +39,22 @@ after_initialize do
       #                 the private key is updated (changed passphrase).
       # +private_key+:: Serialized private key.
       def put
-        public_key  = params[:public_key]
+        public_key  = params.require(:public_key)
         private_key = params.require(:private_key)
 
-        current_user.custom_fields['encrypt_public_key'] = public_key if public_key
+        old_public_key = current_user.custom_fields['encrypt_public_key']
+        old_private_key = current_user.custom_fields['encrypt_private_key']
+
+        # Check if encryption is already enabled (but not changing passphrase).
+        if old_public_key && old_public_key != public_key
+          return render_json_error(I18n.t("encrypt.enabled_already"), status: 409)
+        end
+
+        current_user.custom_fields['encrypt_public_key'] = public_key
         current_user.custom_fields['encrypt_private_key'] = private_key
         current_user.save!
 
-        render json: { success: true }
+        render json: success_json
       end
 
       # Gets public keys of a set of users.

GitHub