Explorar o código

enhance(rtc,crypt): add sync-encrypted-private-key

rcmerci hai 1 ano
pai
achega
b420d4a024

+ 10 - 10
src/main/frontend/worker/crypt.cljs

@@ -4,18 +4,18 @@
             [frontend.worker.state :as worker-state]
             [promesa.core :as p]))
 
-(comment
-  (defonce ^:private encoder (new js/TextEncoder "utf-8"))
-  (defonce ^:private decoder (new js/TextDecoder "utf-8"))
+(defonce ^:private encoder (new js/TextEncoder "utf-8"))
+(comment (defonce ^:private decoder (new js/TextDecoder "utf-8")))
 
-  (defn <encrypt
-    [message public-key]
-    (let [data (.encode encoder message)]
-      (js/crypto.subtle.encrypt
-       #js{:name "RSA-OAEP"}
-       public-key
-       data)))
+(defn <encrypt
+  [message public-key]
+  (let [data (.encode encoder message)]
+    (js/crypto.subtle.encrypt
+     #js{:name "RSA-OAEP"}
+     public-key
+     data)))
 
+(comment
   (defn <decrypt
     [cipher-text private-key]
     (p/let [result (js/crypto.subtle.decrypt

+ 42 - 0
src/main/frontend/worker/device.cljs

@@ -6,7 +6,9 @@
             [clojure.string :as string]
             [frontend.common.missionary-util :as c.m]
             [frontend.worker.crypt :as crypt]
+            [frontend.worker.rtc.client-op :as client-op]
             [frontend.worker.rtc.ws-util :as ws-util]
+            [frontend.worker.state :as worker-state]
             [logseq.db :as ldb]
             [missionary.core :as m]
             [promesa.core :as p]))
@@ -75,6 +77,13 @@
                                          :device-uuid device-uuid
                                          :key-name key-name}))
 
+(defn- new-task--sync-encrypted-private-key*
+  [get-ws-create-task device-uuid->encrypted-private-key graph-uuid]
+  (ws-util/send&recv get-ws-create-task
+                     {:action "sync-encrypted-private-key"
+                      :device-uuid->encrypted-private-key device-uuid->encrypted-private-key
+                      :graph-uuid graph-uuid}))
+
 (defn- new-get-ws-create-task
   [token]
   (:get-ws-create-task (ws-util/gen-get-ws-create-map--memoized (ws-util/get-ws-url token))))
@@ -160,3 +169,36 @@
     (when-let [device-uuid* (cond-> device-uuid (string? device-uuid) parse-uuid)]
       (let [get-ws-create-task (new-get-ws-create-task token)]
         (m/? (new-task--remove-user-device* get-ws-create-task device-uuid*))))))
+
+(defn new-task--sync-current-graph-encrypted-private-key
+  [token device-uuids]
+  (assert (and (seq device-uuids) (every? uuid? device-uuids)))
+  (m/sp
+    (let [repo (worker-state/get-current-repo)]
+      (when-let [graph-uuid (client-op/get-graph-uuid repo)]
+        (when-let [{:keys [private-key-jwk]} (crypt/get-graph-keys-jwk repo)]
+          (let [device-uuids (set device-uuids)
+                get-ws-create-task (new-get-ws-create-task token)
+                devices (m/? (new-task--get-user-devices get-ws-create-task))]
+            (when-let [devices* (not-empty
+                                 (filter
+                                  (fn [device]
+                                    (and (contains? device-uuids (uuid (:device-id device)))
+                                         (some? (get-in device [:keys :default-public-key]))))
+                                  devices))]
+              (let [device-uuid->encrypted-private-key
+                    (m/?
+                     (apply m/join (fn [& x] (into {} x))
+                            (map
+                             (fn [device]
+                               (m/sp
+                                 (let [device-public-key
+                                       (c.m/<?
+                                        (crypt/<import-public-key
+                                         (ldb/read-transit-str
+                                          (get-in device [:keys :default-public-key :public-key]))))]
+                                   [(uuid (:device-id device))
+                                    (c.m/<? (crypt/<encrypt private-key-jwk device-public-key))])))
+                             devices*)))]
+                (m/? (new-task--sync-encrypted-private-key*
+                      get-ws-create-task device-uuid->encrypted-private-key graph-uuid))))))))))

+ 5 - 0
src/main/frontend/worker/rtc/client_op.cljs

@@ -68,6 +68,11 @@
     (assert (nil? (first (d/datoms @conn :avet :graph-uuid))))
     (d/transact! conn [[:db/add "e" :graph-uuid graph-uuid]])))
 
+(defn get-graph-uuid
+  [repo]
+  (when-let [conn (worker-state/get-client-ops-conn repo)]
+    (first (d/datoms @conn :avet :graph-uuid))))
+
 (defn update-local-tx
   [repo t]
   {:pre [(some? t)]}

+ 8 - 1
src/main/frontend/worker/rtc/const.cljs

@@ -294,7 +294,14 @@
       [:req-id :string]
       [:action :string]
       [:device-uuid :uuid]
-      [:key-name :string]]]]))
+      [:key-name :string]]]
+    ["sync-encrypted-private-key"
+     [:map
+      [:req-id :string]
+      [:action :string]
+      [:device-uuid->encrypted-private-key [:map-of :uuid :string]]
+      [:graph-uuid :uuid]]]]))
+
 (def data-to-ws-encoder (m/encoder data-to-ws-schema (mt/transformer
                                                       mt/string-transformer
                                                       (mt/key-transformer {:encode m/-keyword->string}))))