mirror of
https://github.com/logseq/logseq.git
synced 2026-05-15 16:32:21 +00:00
fix(cli-e2e): disable keychain only in e2e runs
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
text)))
|
||||
|
||||
(def template-pattern #"\{\{([^}]+)\}\}")
|
||||
(def ^:private e2e-env {"CLI_E2E_TEST" "1"})
|
||||
|
||||
(defn- render-string
|
||||
[template context]
|
||||
@@ -165,6 +166,7 @@
|
||||
[command context {:keys [run-command stdin allow-failure phase step-index step-total case-id]}]
|
||||
(run-command {:cmd (render-string command context)
|
||||
:dir (paths/repo-root)
|
||||
:env e2e-env
|
||||
:stdin (some-> stdin (render-string context))
|
||||
:phase phase
|
||||
:step-index step-index
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
(ns frontend.handler.e2ee
|
||||
"rtc E2EE related fns"
|
||||
(:require [electron.ipc :as ipc]
|
||||
[frontend.common.crypt :as crypt]
|
||||
[frontend.common.thread-api :refer [def-thread-api]]
|
||||
[frontend.mobile.secure-storage :as secure-storage]
|
||||
[frontend.state :as state]
|
||||
[frontend.util :as util]
|
||||
[lambdaisland.glogi :as log]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(def ^:private save-op :keychain/save-e2ee-password)
|
||||
@@ -70,35 +66,3 @@
|
||||
(if (native-storage-supported?)
|
||||
(<keychain-delete! key)
|
||||
(p/resolved nil)))
|
||||
|
||||
(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))
|
||||
|
||||
(def-thread-api :thread-api/native-save-e2ee-password
|
||||
[encrypted-text]
|
||||
(<native-save-secret! "logseq-encrypted-password" encrypted-text))
|
||||
|
||||
(def-thread-api :thread-api/native-get-e2ee-password
|
||||
[]
|
||||
(<native-get-secret "logseq-encrypted-password"))
|
||||
|
||||
(def-thread-api :thread-api/native-delete-e2ee-password
|
||||
[]
|
||||
(<native-delete-secret! "logseq-encrypted-password"))
|
||||
|
||||
@@ -59,23 +59,17 @@
|
||||
[k value]
|
||||
(idb/set-item! k value))
|
||||
|
||||
(def ^:private secret-prefix "worker-secret###")
|
||||
|
||||
(defn- secret-key
|
||||
[key]
|
||||
(str secret-prefix key))
|
||||
|
||||
(defn- save-secret-text!
|
||||
[key text]
|
||||
(kv-set! (secret-key key) text))
|
||||
(kv-set! key text))
|
||||
|
||||
(defn- read-secret-text
|
||||
[key]
|
||||
(kv-get (secret-key key)))
|
||||
(kv-get key))
|
||||
|
||||
(defn- delete-secret-text!
|
||||
[key]
|
||||
(kv-set! (secret-key key) nil))
|
||||
(kv-set! key nil))
|
||||
|
||||
(defn- install-opfs-pool
|
||||
[sqlite pool-name]
|
||||
|
||||
@@ -327,43 +327,62 @@
|
||||
[state]
|
||||
(transit/write kv-transit-writer state))
|
||||
|
||||
(def ^:private secret-prefix "worker-secret###")
|
||||
(def ^:private keychain-service "Logseq E2EE")
|
||||
|
||||
(defn- secret-key
|
||||
[key]
|
||||
(str secret-prefix key))
|
||||
|
||||
(defn- keychain-account
|
||||
[key]
|
||||
(secret-key key))
|
||||
|
||||
(defn- <save-secret-text!
|
||||
[kv key text]
|
||||
(-> (p/let [_ (.setPassword ^js keytar keychain-service (keychain-account key) text)]
|
||||
(-> (p/let [_ (.setPassword ^js keytar keychain-service key text)]
|
||||
nil)
|
||||
(p/catch (fn [e]
|
||||
(log/warn :db-worker/keychain-save-failed {:error e
|
||||
:key key})
|
||||
((:set! kv) (secret-key key) text)))))
|
||||
((:set! kv) key text)))))
|
||||
|
||||
(defn- <read-secret-text
|
||||
[kv key]
|
||||
(-> (p/let [secret (.getPassword ^js keytar keychain-service (keychain-account key))]
|
||||
(-> (p/let [secret (.getPassword ^js keytar keychain-service key)]
|
||||
secret)
|
||||
(p/catch (fn [e]
|
||||
(log/warn :db-worker/keychain-read-failed {:error e
|
||||
:key key})
|
||||
((:get kv) (secret-key key))))))
|
||||
((:get kv) key)))))
|
||||
|
||||
(defn- <delete-secret-text!
|
||||
[kv key]
|
||||
(-> (p/let [_ (.deletePassword ^js keytar keychain-service (keychain-account key))]
|
||||
(-> (p/let [_ (.deletePassword ^js keytar keychain-service key)]
|
||||
nil)
|
||||
(p/catch (fn [e]
|
||||
(log/warn :db-worker/keychain-delete-failed {:error e
|
||||
:key key})
|
||||
((:set! kv) (secret-key key) nil)))))
|
||||
((:set! kv) key nil)))))
|
||||
|
||||
(defn- truthy-env?
|
||||
[value]
|
||||
(contains? #{"1" "true" "yes" "on"}
|
||||
(string/lower-case (string/trim (str (or value ""))))))
|
||||
|
||||
(defn- use-keychain-for-owner?
|
||||
[owner-source]
|
||||
(not (and (= :cli owner-source)
|
||||
(truthy-env? (gobj/get (.-env js/process) "CLI_E2E_TEST")))))
|
||||
|
||||
(defn- <save-secret-text-by-owner!
|
||||
[kv owner-source key text]
|
||||
(if (use-keychain-for-owner? owner-source)
|
||||
(<save-secret-text! kv key text)
|
||||
((:set! kv) key text)))
|
||||
|
||||
(defn- <read-secret-text-by-owner
|
||||
[kv owner-source key]
|
||||
(if (use-keychain-for-owner? owner-source)
|
||||
(<read-secret-text kv key)
|
||||
((:get kv) key)))
|
||||
|
||||
(defn- <delete-secret-text-by-owner!
|
||||
[kv owner-source key]
|
||||
(if (use-keychain-for-owner? owner-source)
|
||||
(<delete-secret-text! kv key)
|
||||
((:set! kv) key nil)))
|
||||
|
||||
(defn- kv-store
|
||||
[data-dir]
|
||||
@@ -435,9 +454,9 @@
|
||||
:backup-db (fn [^js db path]
|
||||
(.backup db path))}
|
||||
:crypto {:save-secret-text! (fn [key text]
|
||||
(<save-secret-text! kv key text))
|
||||
(<save-secret-text-by-owner! kv owner-source key text))
|
||||
:read-secret-text (fn [key]
|
||||
(<read-secret-text kv key))
|
||||
(<read-secret-text-by-owner kv owner-source key))
|
||||
:delete-secret-text! (fn [key]
|
||||
(<delete-secret-text! kv key))}
|
||||
(<delete-secret-text-by-owner! kv owner-source key))}
|
||||
:timers {:set-interval! (fn [f ms] (js/setInterval f ms))}})))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns frontend.worker.platform-node-test
|
||||
(:require ["fs" :as fs]
|
||||
["keytar" :as keytar]
|
||||
["path" :as node-path]
|
||||
[cljs.test :refer [async deftest is testing]]
|
||||
[clojure.string :as string]
|
||||
@@ -76,6 +77,95 @@
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest node-platform-cli-owner-bypasses-keychain-in-cli-e2e-test
|
||||
(async done
|
||||
(let [data-dir (node-helper/create-tmp-dir "platform-node-cli-secrets")
|
||||
process-env (.-env js/process)
|
||||
original-cli-e2e-test (gobj/get process-env "CLI_E2E_TEST")
|
||||
calls (atom {:save 0 :read 0 :delete 0})
|
||||
original-save (gobj/get keytar "setPassword")
|
||||
original-read (gobj/get keytar "getPassword")
|
||||
original-delete (gobj/get keytar "deletePassword")]
|
||||
(gobj/set process-env "CLI_E2E_TEST" "1")
|
||||
(gobj/set keytar "setPassword" (fn [& _]
|
||||
(swap! calls update :save inc)
|
||||
(js/Promise.resolve true)))
|
||||
(gobj/set keytar "getPassword" (fn [& _]
|
||||
(swap! calls update :read inc)
|
||||
(js/Promise.resolve nil)))
|
||||
(gobj/set keytar "deletePassword" (fn [& _]
|
||||
(swap! calls update :delete inc)
|
||||
(js/Promise.resolve true)))
|
||||
(-> (p/let [platform (platform-node/node-platform {:data-dir data-dir
|
||||
:owner-source :cli})
|
||||
crypto (:crypto platform)
|
||||
kv (:kv platform)
|
||||
_ ((:save-secret-text! crypto) "secret-key" "secret-value")
|
||||
kv-value ((:get kv) "secret-key")
|
||||
secret-value ((:read-secret-text crypto) "secret-key")
|
||||
_ ((:delete-secret-text! crypto) "secret-key")
|
||||
kv-cleared ((:get kv) "secret-key")]
|
||||
(is (= "secret-value" kv-value))
|
||||
(is (= "secret-value" secret-value))
|
||||
(is (nil? kv-cleared))
|
||||
(is (= {:save 0 :read 0 :delete 0} @calls)))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally (fn []
|
||||
(gobj/set keytar "setPassword" original-save)
|
||||
(gobj/set keytar "getPassword" original-read)
|
||||
(gobj/set keytar "deletePassword" original-delete)
|
||||
(if (some? original-cli-e2e-test)
|
||||
(gobj/set process-env "CLI_E2E_TEST" original-cli-e2e-test)
|
||||
(gobj/remove process-env "CLI_E2E_TEST"))
|
||||
(done)))))))
|
||||
|
||||
(deftest node-platform-cli-owner-uses-keychain-when-keychain-present
|
||||
(async done
|
||||
(let [data-dir (node-helper/create-tmp-dir "platform-node-cli-secrets-keychain")
|
||||
process-env (.-env js/process)
|
||||
original-cli-e2e-test (gobj/get process-env "CLI_E2E_TEST")
|
||||
calls (atom {:save 0 :read 0 :delete 0})
|
||||
secrets (atom {})
|
||||
original-save (gobj/get keytar "setPassword")
|
||||
original-read (gobj/get keytar "getPassword")
|
||||
original-delete (gobj/get keytar "deletePassword")]
|
||||
(gobj/remove process-env "CLI_E2E_TEST")
|
||||
(gobj/set keytar "setPassword" (fn [_service key value]
|
||||
(swap! calls update :save inc)
|
||||
(swap! secrets assoc key value)
|
||||
(js/Promise.resolve true)))
|
||||
(gobj/set keytar "getPassword" (fn [_service key]
|
||||
(swap! calls update :read inc)
|
||||
(js/Promise.resolve (get @secrets key))))
|
||||
(gobj/set keytar "deletePassword" (fn [_service key]
|
||||
(swap! calls update :delete inc)
|
||||
(swap! secrets dissoc key)
|
||||
(js/Promise.resolve true)))
|
||||
(-> (p/let [platform (platform-node/node-platform {:data-dir data-dir
|
||||
:owner-source :cli})
|
||||
crypto (:crypto platform)
|
||||
kv (:kv platform)
|
||||
_ ((:save-secret-text! crypto) "secret-key" "secret-value")
|
||||
kv-value ((:get kv) "secret-key")
|
||||
secret-value ((:read-secret-text crypto) "secret-key")
|
||||
_ ((:delete-secret-text! crypto) "secret-key")
|
||||
deleted-value ((:read-secret-text crypto) "secret-key")]
|
||||
(is (nil? kv-value))
|
||||
(is (= "secret-value" secret-value))
|
||||
(is (nil? deleted-value))
|
||||
(is (= {:save 1 :read 2 :delete 1} @calls)))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally (fn []
|
||||
(gobj/set keytar "setPassword" original-save)
|
||||
(gobj/set keytar "getPassword" original-read)
|
||||
(gobj/set keytar "deletePassword" original-delete)
|
||||
(if (some? original-cli-e2e-test)
|
||||
(gobj/set process-env "CLI_E2E_TEST" original-cli-e2e-test)
|
||||
(gobj/remove process-env "CLI_E2E_TEST"))
|
||||
(done)))))))
|
||||
|
||||
(deftest kv-store-preserves-uint8array-values-across-reloads-test
|
||||
(async done
|
||||
(let [data-dir (node-helper/create-tmp-dir "platform-node-kv-store")
|
||||
|
||||
Reference in New Issue
Block a user