mirror of
https://github.com/logseq/logseq.git
synced 2026-05-20 19:02:23 +00:00
feat(rtc,e2ee): basic e2ee-password ui
This commit is contained in:
@@ -35,6 +35,20 @@
|
||||
true
|
||||
#js ["encrypt"]))
|
||||
|
||||
(defn <export-private-key
|
||||
[private-key]
|
||||
(assert (instance? js/CryptoKey private-key))
|
||||
(p/let [exported (.exportKey subtle "pkcs8" private-key)]
|
||||
(js/Uint8Array. exported)))
|
||||
|
||||
(defn <import-private-key
|
||||
[exported-private-key]
|
||||
(assert (instance? js/Uint8Array exported-private-key))
|
||||
(.importKey subtle "pkcs8" exported-private-key
|
||||
#js {:name "RSA-OAEP" :hash "SHA-256"}
|
||||
true
|
||||
#js ["decrypt"]))
|
||||
|
||||
(comment
|
||||
(->
|
||||
(p/let [kp (<generate-rsa-key-pair)
|
||||
|
||||
53
src/main/frontend/components/e2ee.cljs
Normal file
53
src/main/frontend/components/e2ee.cljs
Normal file
@@ -0,0 +1,53 @@
|
||||
(ns frontend.components.e2ee
|
||||
(:require [frontend.common.crypt :as crypt]
|
||||
[logseq.shui.hooks :as hooks]
|
||||
[logseq.shui.ui :as shui]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(rum/defc e2ee-request-new-password
|
||||
[password-promise]
|
||||
(let [[password set-password!] (hooks/use-state "")]
|
||||
[:div.e2ee-password-modal-overlay
|
||||
[:div.e2ee-password-modal-content
|
||||
[:h3 "Enter new E2EE Password"]
|
||||
[:input {:type "password"
|
||||
:value password
|
||||
:on-change (fn [e] (set-password! (-> e .-target .-value)))}]
|
||||
(shui/button
|
||||
{:on-click (fn []
|
||||
(p/resolve! password-promise password)
|
||||
(shui/dialog-close!))}
|
||||
"OK")
|
||||
(shui/button
|
||||
{:on-click (fn []
|
||||
(p/reject! password-promise :cancelled)
|
||||
(shui/dialog-close!))}
|
||||
"Cancel")]]))
|
||||
|
||||
(rum/defc e2ee-password-to-decrypt-private-key
|
||||
[encrypted-private-key private-key-promise]
|
||||
(let [[password set-password!] (hooks/use-state "")
|
||||
[decrypt-fail? set-decrypt-fail] (hooks/use-state false)]
|
||||
[:div.e2ee-password-modal-overlay
|
||||
[:div.e2ee-password-modal-content
|
||||
[:h3 "Enter E2EE Password"]
|
||||
(when decrypt-fail? [:p "Wrong Password"])
|
||||
[:input {:type "password"
|
||||
:value password
|
||||
:on-change (fn [e] (set-password! (-> e .-target .-value)))}]
|
||||
(shui/button
|
||||
{:on-click (fn []
|
||||
(->
|
||||
(p/let [private-key (crypt/<decrypt-private-key password encrypted-private-key)]
|
||||
(p/resolve! private-key-promise private-key)
|
||||
(shui/dialog-close!))
|
||||
(p/catch (fn [e]
|
||||
(when (= "decrypt-private-key" (ex-message e))
|
||||
(set-decrypt-fail true))))))}
|
||||
"OK")
|
||||
(shui/button
|
||||
{:on-click (fn []
|
||||
(p/reject! private-key-promise :cancelled)
|
||||
(shui/dialog-close!))}
|
||||
"Cancel")]]))
|
||||
@@ -17,9 +17,10 @@
|
||||
[frontend.db.restore :as db-restore]
|
||||
[frontend.error :as error]
|
||||
[frontend.handler.command-palette :as command-palette]
|
||||
[frontend.handler.crypt]
|
||||
[frontend.handler.db-based.vector-search-flows :as vector-search-flows]
|
||||
[frontend.handler.e2ee]
|
||||
[frontend.handler.events :as events]
|
||||
[frontend.handler.events.rtc]
|
||||
[frontend.handler.events.ui]
|
||||
[frontend.handler.file-based.events]
|
||||
[frontend.handler.file-based.file :as file-handler]
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
(ns frontend.handler.crypt
|
||||
(:require [frontend.common.thread-api :refer [def-thread-api]]))
|
||||
|
||||
(def-thread-api :thread-api/request-e2ee-password
|
||||
[]
|
||||
{:password "test-password"})
|
||||
26
src/main/frontend/handler/e2ee.cljs
Normal file
26
src/main/frontend/handler/e2ee.cljs
Normal file
@@ -0,0 +1,26 @@
|
||||
(ns frontend.handler.e2ee
|
||||
(:require [frontend.common.crypt :as crypt]
|
||||
[frontend.common.thread-api :refer [def-thread-api]]
|
||||
[frontend.state :as state]
|
||||
[lambdaisland.glogi :as log]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(def-thread-api :thread-api/request-e2ee-password
|
||||
[]
|
||||
(p/let [password-promise (state/pub-event! [:rtc/request-e2ee-password])
|
||||
password password-promise]
|
||||
{:password password}))
|
||||
|
||||
(defn- <decrypt-user-e2ee-private-key
|
||||
[encrypted-private-key]
|
||||
(->
|
||||
(p/let [private-key-promise (state/pub-event! [:rtc/decrypt-user-e2ee-private-key encrypted-private-key])
|
||||
private-key private-key-promise]
|
||||
(crypt/<export-private-key private-key))
|
||||
(p/catch (fn [e]
|
||||
(log/error :<decrypt-user-e2ee-private-key e)
|
||||
e))))
|
||||
|
||||
(def-thread-api :thread-api/decrypt-user-e2ee-private-key
|
||||
[encrypted-private-key]
|
||||
(<decrypt-user-e2ee-private-key encrypted-private-key))
|
||||
22
src/main/frontend/handler/events/rtc.cljs
Normal file
22
src/main/frontend/handler/events/rtc.cljs
Normal file
@@ -0,0 +1,22 @@
|
||||
(ns frontend.handler.events.rtc
|
||||
"RTC events"
|
||||
(:require [frontend.components.e2ee :as e2ee]
|
||||
[frontend.handler.events :as events]
|
||||
[logseq.shui.ui :as shui]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(defmethod events/handle :rtc/decrypt-user-e2ee-private-key [[_ encrypted-private-key]]
|
||||
(let [private-key-promise (p/deferred)]
|
||||
(shui/dialog-close-all!)
|
||||
(shui/dialog-open!
|
||||
#(e2ee/e2ee-password-to-decrypt-private-key encrypted-private-key private-key-promise)
|
||||
{:close-btn? false})
|
||||
private-key-promise))
|
||||
|
||||
(defmethod events/handle :rtc/request-e2ee-password [[_]]
|
||||
(let [password-promise (p/deferred)]
|
||||
(shui/dialog-close-all!)
|
||||
(shui/dialog-open!
|
||||
#(e2ee/e2ee-request-new-password password-promise)
|
||||
{:close-btn? false})
|
||||
password-promise))
|
||||
@@ -121,10 +121,13 @@
|
||||
(defn task--get-rsa-key-pair
|
||||
[get-ws-create-task user-uuid]
|
||||
(m/sp
|
||||
(let [{:keys [password]} (c.m/<? (worker-state/<invoke-main-thread :thread-api/request-e2ee-password))
|
||||
{:keys [public-key encrypted-private-key]}
|
||||
(let [{:keys [public-key encrypted-private-key]}
|
||||
(m/? (task--fetch-user-rsa-key-pair get-ws-create-task user-uuid))
|
||||
private-key (c.m/<? (crypt/<decrypt-private-key password encrypted-private-key))]
|
||||
_ (prn :xxxxx1)
|
||||
exported-private-key (c.m/<? (worker-state/<invoke-main-thread
|
||||
:thread-api/decrypt-user-e2ee-private-key encrypted-private-key))
|
||||
_ (prn :xxxxx2)
|
||||
private-key (c.m/<? (crypt/<import-private-key exported-private-key))]
|
||||
{:public-key public-key
|
||||
:private-key private-key})))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user