Browse Source

feat(encryption): allow using saved secret phrase in metadata.edn

Kan-Ru Chen 5 years ago
parent
commit
dade034057

+ 27 - 23
src/main/frontend/components/encryption.cljs

@@ -82,37 +82,41 @@
 
 
 (rum/defcs encryption-input-secret-inner <
 (rum/defcs encryption-input-secret-inner <
   (rum/local "" ::secret)
   (rum/local "" ::secret)
-  [state repo-url close-fn]
+  [state repo-url db-encrypted-secret close-fn]
   (rum/with-context [[t] i18n/*tongue-context*]
   (rum/with-context [[t] i18n/*tongue-context*]
     (let [secret (get state ::secret)]
     (let [secret (get state ::secret)]
       [:div
       [:div
-      [:div.sm:flex.sm:items-start
-       [:div.mt-3.text-center.sm:mt-0.sm:text-left
-        [:h3#modal-headline.text-lg.leading-6.font-medium.text-gray-900
-         "Enter your secret phrase"]]]
+       [:div.sm:flex.sm:items-start
+        [:div.mt-3.text-center.sm:mt-0.sm:text-left
+         [:h3#modal-headline.text-lg.leading-6.font-medium.text-gray-900
+          (if db-encrypted-secret
+            "Enter your password"
+            "Enter your secret phrase")]]]
 
 
-      [:input.form-input.block.w-full.sm:text-sm.sm:leading-5.my-2
-       {:auto-focus true
-        :style {:color "#000"}
-        :on-change (fn [e]
-                     (reset! secret (util/evalue e)))}]
+       [:input.form-input.block.w-full.sm:text-sm.sm:leading-5.my-2
+        {:auto-focus true
+         :style {:color "#000"}
+         :on-change (fn [e]
+                      (reset! secret (util/evalue e)))}]
 
 
-      [:div.mt-5.sm:mt-4.sm:flex.sm:flex-row-reverse
-       [:span.flex.w-full.rounded-md.shadow-sm.sm:ml-3.sm:w-auto
-        [:button.inline-flex.justify-center.w-full.rounded-md.border.border-transparent.px-4.py-2.bg-indigo-600.text-base.leading-6.font-medium.text-white.shadow-sm.hover:bg-indigo-500.focus:outline-none.focus:border-indigo-700.focus:shadow-outline-indigo.transition.ease-in-out.duration-150.sm:text-sm.sm:leading-5
-         {:type "button"
-          :on-click (fn []
-                      (let [value @secret]
-                        (when-not (string/blank? value) ; TODO: length or other checks
-                          (let [repo (state/get-current-repo)]
-                            (e/save-mnemonic! repo value)
-                            (close-fn true)))))}
-         "Submit"]]]])))
+       [:div.mt-5.sm:mt-4.sm:flex.sm:flex-row-reverse
+        [:span.flex.w-full.rounded-md.shadow-sm.sm:ml-3.sm:w-auto
+         [:button.inline-flex.justify-center.w-full.rounded-md.border.border-transparent.px-4.py-2.bg-indigo-600.text-base.leading-6.font-medium.text-white.shadow-sm.hover:bg-indigo-500.focus:outline-none.focus:border-indigo-700.focus:shadow-outline-indigo.transition.ease-in-out.duration-150.sm:text-sm.sm:leading-5
+          {:type "button"
+           :on-click (fn []
+                       (let [value @secret]
+                         (when-not (string/blank? value) ; TODO: length or other checks
+                           (let [repo (state/get-current-repo)]
+                             (if db-encrypted-secret
+                               (e/save-mnemonic! repo (e/decrypt-with-passphrase value db-encrypted-secret))
+                               (e/save-mnemonic! repo value))
+                             (close-fn true)))))}
+          "Submit"]]]])))
 
 
 (defn encryption-input-secret-dialog
 (defn encryption-input-secret-dialog
-  [repo-url close-fn]
+  [repo-url db-encrypted-secret close-fn]
   (fn [close-modal-fn]
   (fn [close-modal-fn]
     (let [close-fn (fn [encrypted?]
     (let [close-fn (fn [encrypted?]
                      (close-fn encrypted?)
                      (close-fn encrypted?)
                      (close-modal-fn))]
                      (close-modal-fn))]
-      (encryption-input-secret-inner repo-url close-fn))))
+      (encryption-input-secret-inner repo-url db-encrypted-secret close-fn))))

+ 13 - 1
src/main/frontend/encrypt.cljs

@@ -27,7 +27,7 @@
 
 
 (defn save-mnemonic!
 (defn save-mnemonic!
   [repo-url mnemonic]
   [repo-url mnemonic]
-  (db/set-key-value repo-url :db/secret-phrase mnemonic)
+  (db/set-key-value repo-url :db/secret-phrase (str/trim mnemonic))
   (db/set-key-value repo-url :db/encrypted? true))
   (db/set-key-value repo-url :db/encrypted? true))
 
 
 (defn- generate-mnemonic
 (defn- generate-mnemonic
@@ -82,3 +82,15 @@
          (log/error :encrypt/empty-secret-key (str "Can't find the secret key for repo: " repo-url))))
          (log/error :encrypt/empty-secret-key (str "Can't find the secret key for repo: " repo-url))))
      :else
      :else
      content)))
      content)))
+
+(defn encrypt-with-passphrase
+  [passphrase content]
+  (let [content (utf8/encode content)
+        encrypted (rage/encrypt_with_user_passphrase passphrase content true)]
+    (utf8/decode encrypted)))
+
+(defn decrypt-with-passphrase
+  [passphrase content]
+  (let [content (utf8/encode content)
+        decrypted (rage/decrypt_with_user_passphrase passphrase content)]
+    (utf8/decode decrypted)))

+ 17 - 15
src/main/frontend/handler/repo.cljs

@@ -198,7 +198,7 @@
   [repo-url files delete-files delete-blocks file-paths first-clone? db-encrypted? re-render? re-render-opts encrypted?]
   [repo-url files delete-files delete-blocks file-paths first-clone? db-encrypted? re-render? re-render-opts encrypted?]
   (let [files (if encrypted? (map (fn [file]
   (let [files (if encrypted? (map (fn [file]
                                     (update file :file/content encrypt/decrypt))
                                     (update file :file/content encrypt/decrypt))
-                               files) files)
+                                  files) files)
         parsed-files (filter
         parsed-files (filter
                       (fn [file]
                       (fn [file]
                         (let [format (format/get-format (:file/path file))]
                         (let [format (format/get-format (:file/path file))]
@@ -208,19 +208,19 @@
                        (extract-handler/extract-all-blocks-pages repo-url parsed-files)
                        (extract-handler/extract-all-blocks-pages repo-url parsed-files)
                        [])]
                        [])]
     (reset-contents-and-blocks! repo-url files blocks-pages delete-files delete-blocks))
     (reset-contents-and-blocks! repo-url files blocks-pages delete-files delete-blocks))
-    (let [config-file (config/get-config-path)]
-      (if (contains? (set file-paths) config-file)
-        (when-let [content (some #(when (= (:file/path %) config-file)
-                                    (:file/content %)) files)]
-          (file-handler/restore-config! repo-url content true))))
-    (if (and first-clone? (not db-encrypted?))
-      (state/set-modal!
-       (encryption/encryption-setup-dialog
-        repo-url
-        #(create-default-files! repo-url %)))
-      (create-default-files! repo-url db-encrypted?))
-    (when re-render?
-      (ui-handler/re-render-root! re-render-opts))
+  (let [config-file (config/get-config-path)]
+    (if (contains? (set file-paths) config-file)
+      (when-let [content (some #(when (= (:file/path %) config-file)
+                                  (:file/content %)) files)]
+        (file-handler/restore-config! repo-url content true))))
+  (if (and first-clone? (not db-encrypted?))
+    (state/set-modal!
+     (encryption/encryption-setup-dialog
+      repo-url
+      #(create-default-files! repo-url %)))
+    (create-default-files! repo-url db-encrypted?))
+  (when re-render?
+    (ui-handler/re-render-root! re-render-opts))
   (state/set-importing-to-db! false))
   (state/set-importing-to-db! false))
 
 
 (defn parse-files-and-load-to-db!
 (defn parse-files-and-load-to-db!
@@ -234,11 +234,13 @@
                                     (:file/content %)) files)
                                     (:file/content %)) files)
           metadata (when metadata-content
           metadata (when metadata-content
                      (common-handler/read-metadata! repo-url metadata-content))
                      (common-handler/read-metadata! repo-url metadata-content))
-          db-encrypted? (:db/encrypted? metadata)]
+          db-encrypted? (:db/encrypted? metadata)
+          db-encrypted-secret (if db-encrypted? (:db/encrypted-secret metadata) nil)]
       (if db-encrypted?
       (if db-encrypted?
         (state/set-modal!
         (state/set-modal!
          (encryption/encryption-input-secret-dialog
          (encryption/encryption-input-secret-dialog
           repo-url
           repo-url
+          db-encrypted-secret
           #(parse-files-and-create-default-files! repo-url files delete-files delete-blocks file-paths first-clone? db-encrypted? re-render? re-render-opts true)))
           #(parse-files-and-create-default-files! repo-url files delete-files delete-blocks file-paths first-clone? db-encrypted? re-render? re-render-opts true)))
         (parse-files-and-create-default-files! repo-url files delete-files delete-blocks file-paths first-clone? db-encrypted? re-render? re-render-opts false)))))
         (parse-files-and-create-default-files! repo-url files delete-files delete-blocks file-paths first-clone? db-encrypted? re-render? re-render-opts false)))))