diff --git a/src/dev-cljs/shadow/user.clj b/src/dev-cljs/shadow/user.clj index 1ef90c0196..dacf77c56d 100644 --- a/src/dev-cljs/shadow/user.clj +++ b/src/dev-cljs/shadow/user.clj @@ -26,6 +26,15 @@ ([runtime-id] (api/repl :db-worker {:runtime-id runtime-id}))) +(defn worker-node-repl + ([] + (let [runtime-id (->> (api/repl-runtimes :db-worker-node) + (map :client-id) + first)] + (api/repl :db-worker-node {:runtime-id runtime-id}))) + ([runtime-id] + (api/repl :db-worker-node {:runtime-id runtime-id}))) + (defn runtime-id-list [app] (->> (api/repl-runtimes app) diff --git a/src/main/frontend/handler/e2ee.cljs b/src/main/frontend/handler/e2ee.cljs index 3f8006e73b..e0b8d95655 100644 --- a/src/main/frontend/handler/e2ee.cljs +++ b/src/main/frontend/handler/e2ee.cljs @@ -49,6 +49,28 @@ :else (p/resolved nil))) +(defn native-storage-supported? + [] + (or (util/electron?) (util/capacitor?))) + +(defn (p/let [_ (.setPassword ^js keytar keychain-service (keychain-account key) text)] + nil) + (p/catch (fn [e] + (log/warn :db-worker/keychain-save-failed {:error e + :key key}) + ((:set! kv) (secret-key key) text))))) + +(defn- (p/let [secret (.getPassword ^js keytar keychain-service (keychain-account key))] + secret) + (p/catch (fn [e] + (log/warn :db-worker/keychain-read-failed {:error e + :key key}) + ((:get kv) (secret-key key)))))) + +(defn- (p/let [_ (.deletePassword ^js keytar keychain-service (keychain-account key))] + nil) + (p/catch (fn [e] + (log/warn :db-worker/keychain-delete-failed {:error e + :key key}) + ((:set! kv) (secret-key key) nil))))) + (defn- kv-store [data-dir] (let [kv-path (node-path/join data-dir "kv-store.json") @@ -413,9 +446,9 @@ :backup-db (fn [^js db path] (.backup db path))} :crypto {:save-secret-text! (fn [key text] - ((:set! kv) (secret-key key) text)) + (aes-key (atom {})) (defonce ^:private *user-rsa-key-pair-inflight (atom {})) -(defonce ^:private node-default-e2ee-password-file "~/logseq/e2ee-password") (defonce ^:private node-default-auth-file "~/logseq/auth.json") (defonce ^:private e2ee-password-secret-key "logseq-encrypted-password") (def ^:private invalid-transit ::invalid-transit) @@ -36,9 +35,14 @@ [platform'] (= :browser (runtime platform'))) -(defn- e2ee-password-file-path - [] - node-default-e2ee-password-file) +(defn- owner-source + [platform'] + (get-in platform' [:env :owner-source])) + +(defn- capacitor-runtime? + [platform'] + (and (= :browser (runtime platform')) + (= :capacitor (owner-source platform')))) (defn- auth-file-path [] @@ -48,10 +52,10 @@ [] (let [env (:env (platform/current)) runtime' (:runtime env) - owner-source (:owner-source env)] + owner-source' (:owner-source env)] (or (= :browser runtime') (and (= :node runtime') - (= :electron owner-source))))) + (= :electron owner-source'))))) (defn- missing-e2ee-password-ex [data] @@ -115,12 +119,22 @@ ( (ui-request/ (platform/read-secret-text platform' e2ee-password-secret-key) (p/catch (fn [e] @@ -131,11 +145,16 @@ [refresh-token] (ensure-refresh-token! refresh-token) (p/let [platform' (platform/current) - text (if (browser-runtime? platform') - ( (platform/read-text! platform' (e2ee-password-file-path)) - (p/catch (fn [_] - nil))))] + native-result (if (capacitor-runtime? platform') + (-> (ui-request/ (ui-request/ (platform/delete-secret-text! platform' e2ee-password-secret-key) (p/catch (fn [e] (log/warn :db-sync/delete-e2ee-password-secret-failed {:error e}) - nil))) - (-> (platform/write-text! platform' (e2ee-password-file-path) "") - (p/catch (fn [e] - (log/warn :db-sync/clear-e2ee-password-file-failed {:error e}) nil))))] nil)) diff --git a/src/test/frontend/persist_db_test.cljs b/src/test/frontend/persist_db_test.cljs index 8994da291e..a3205d3852 100644 --- a/src/test/frontend/persist_db_test.cljs +++ b/src/test/frontend/persist_db_test.cljs @@ -1,6 +1,7 @@ (ns frontend.persist-db-test (:require [cljs.test :refer [async deftest is use-fixtures]] [electron.ipc :as ipc] + [frontend.config :as config] [frontend.persist-db.browser :as browser] [frontend.persist-db :as persist-db] [frontend.persist-db.protocol :as protocol] @@ -183,6 +184,48 @@ (set! storage/remove original-storage-remove) (done))))))) +(deftest electron-ensure-remote-pushes-db-sync-config-on-start-test + (async done + (let [worker-calls (atom []) + ensure-remote! #'persist-db/FakeRemote repo + (fn [qkw direct-pass? & args] + (swap! worker-calls conj [qkw direct-pass? args]) + (p/resolved nil))))) + (set! remote/stop! (fn [_] (p/resolved true))) + (-> (p/let [_ (ensure-remote! "logseq_db_graph_a")] + (let [set-config-call (first (filter #(= :thread-api/set-db-sync-config (first %)) + @worker-calls))] + (is (= [:thread-api/set-db-sync-config + false + [{:enabled? true + :ws-url "wss://sync.example.test/sync/%s" + :http-base "https://sync.example.test"}]] + set-config-call)))) + (p/catch (fn [e] + (is false (str "unexpected error: " e)))) + (p/finally (fn [] + (set! ipc/ipc original-ipc) + (set! remote/start! original-start!) + (set! remote/stop! original-stop!) + (set! config/db-sync-ws-url original-ws) + (set! config/db-sync-http-base original-http) + (done))))))) + (deftest electron-list-db-without-current-repo-does-not-bootstrap-runtime (async done (let [ipc-calls (atom []) diff --git a/src/test/frontend/worker/sync/crypt_test.cljs b/src/test/frontend/worker/sync/crypt_test.cljs index 89cce24e56..9a07ab0da8 100644 --- a/src/test/frontend/worker/sync/crypt_test.cljs +++ b/src/test/frontend/worker/sync/crypt_test.cljs @@ -138,7 +138,51 @@ (reset! worker-state/*state state-prev) (done))))))) -(deftest save-e2ee-password-uses-file-storage-in-node-runtime-test +(deftest save-e2ee-password-uses-native-storage-in-capacitor-runtime-test + (async done + (let [platform-map {:env {:runtime :browser + :owner-source :capacitor}} + state-prev @worker-state/*state + native-calls (atom []) + secret-calls (atom []) + file-calls (atom []) + encrypt-calls (atom [])] + (reset! worker-state/*state (assoc state-prev :auth/refresh-token "refresh-from-state")) + (-> (p/with-redefs [crypt/ (p/with-redefs [crypt/ (p/with-redefs [platform/current (fn [] platform-map) + ui-request/ (p/with-redefs [platform/current (fn [] platform-map) + platform/read-secret-text (fn [platform' key] + (swap! secret-calls conj {:platform platform' + :key key}) + (p/resolved (ldb/write-transit-str {:cipher "payload"}))) + platform/read-text! (fn [platform' path] + (swap! file-calls conj {:platform platform' + :path path}) + (p/resolved (ldb/write-transit-str {:cipher "legacy"}))) + crypt/ (p/with-redefs [platform/current (fn [] platform-map) + platform/read-secret-text (fn [platform' key] + (swap! secret-calls conj {:platform platform' + :key key}) + (p/resolved (ldb/write-transit-str {:cipher "payload"}))) + platform/read-text! (fn [platform' path] + (swap! file-calls conj {:platform platform' + :path path}) + (p/resolved (ldb/write-transit-str {:cipher "legacy"}))) + crypt/ (p/with-redefs [platform/current (fn [] platform-map) + ui-request/ (p/with-redefs [platform/current (fn [] {:env {:runtime :node :owner-source :cli}}) @@ -269,40 +477,41 @@ (p/resolved "{\"refresh-token\":\"refresh-token\"}")) crypt/ (p/with-redefs [platform/current (fn [] {:env {:runtime :node :owner-source :cli}}) ldb/read-transit-str (fn [_] :encrypted-private-key-payload) crypt/