fix: db row keys encrypt/decrypt

This commit is contained in:
Tienson Qin
2026-01-22 19:32:48 +08:00
parent 1f71f9e78e
commit 0f3ec8c4eb
5 changed files with 68 additions and 14 deletions

View File

@@ -106,6 +106,18 @@
(assoc opts :headers (merge (or (:headers opts) {}) auth))
opts))
(declare fetch-json)
(defn- fetch-graph-e2ee?
[base graph-uuid]
(if-not (and (string? base) (string? graph-uuid))
false
(p/let [resp (fetch-json (str base "/e2ee/graphs/" graph-uuid "/aes-key")
{:method "GET"}
{:response-schema :e2ee/graph-aes-key})
encrypted-aes-key (:encrypted-aes-key resp)]
(boolean (string? encrypted-aes-key)))))
(declare coerce-http-response)
(defn- fetch-json
@@ -214,7 +226,8 @@
(if graph-id
(p/do!
(ldb/transact! repo [(sqlite-util/kv :logseq.kv/db-type "db")
(sqlite-util/kv :logseq.kv/graph-uuid (uuid graph-id))])
(sqlite-util/kv :logseq.kv/graph-uuid (uuid graph-id))
(sqlite-util/kv :logseq.kv/graph-rtc-e2ee? true)])
graph-id)
(p/rejected (ex-info "db-sync missing graph id in create response"
{:type :db-sync/invalid-graph
@@ -261,6 +274,7 @@
(throw (ex-info "missing snapshot download url"
{:graph graph-name
:response download-resp})))
e2ee? (fetch-graph-e2ee? base (str graph-uuid))
resp (js/fetch download-url (clj->js (with-auth-headers {:method "GET"})))]
(when-not (.-ok resp)
(throw (ex-info "snapshot download failed"
@@ -279,11 +293,10 @@
total' (+ total (count rows))
total-rows' (into total-rows rows)]
(when (seq total-rows')
(let [e2ee? (snapshot-rows-e2ee? total-rows')]
(p/do!
(state/<invoke-db-worker :thread-api/db-sync-import-kvs-rows
graph total-rows' true graph-uuid e2ee?)
(state/<invoke-db-worker :thread-api/db-sync-finalize-kvs-import graph remote-tx))))
(p/do!
(state/<invoke-db-worker :thread-api/db-sync-import-kvs-rows
graph total-rows' true graph-uuid e2ee?)
(state/<invoke-db-worker :thread-api/db-sync-finalize-kvs-import graph remote-tx)))
total')
(let [value (.-value chunk)
{:keys [rows buffer]} (parse-framed-chunk buffer value)

View File

@@ -1,11 +1,9 @@
(ns frontend.handler.db-based.sync
"Dispatch RTC calls between legacy RTC and db-sync implementations."
(:require [frontend.config :as config]
[frontend.db :as db]
[frontend.handler.db-based.db-sync :as db-sync-handler]
[frontend.handler.db-based.rtc :as rtc-handler]
[frontend.state :as state]
[logseq.db :as ldb]
[promesa.core :as p]))
(defn- db-sync-enabled? []

View File

@@ -492,7 +492,7 @@
(defn <decrypt-kvs-rows
[repo graph-id rows e2ee?]
(if-not (true? e2ee?)
(if-not e2ee?
(p/resolved rows)
(p/let [aes-key (<fetch-graph-aes-key-for-download repo graph-id)
_ (when (nil? aes-key)
@@ -552,6 +552,22 @@
(ldb/read-transit-str decrypted)
value))))))
(defn- <encrypt-keys-attrs
[aes-key keys]
(p/all (mapv (fn [[e a v t]]
(if (contains? rtc-const/encrypt-attr-set a)
(p/let [v' (<encrypt-text-value aes-key v)]
[e a v' t])
[e a v t])) keys)))
(defn- <decrypt-keys-attrs
[aes-key keys]
(p/all (mapv (fn [[e a v t]]
(if (contains? rtc-const/encrypt-attr-set a)
(p/let [v' (<decrypt-text-value aes-key v)]
[e a v' t])
[e a v t])) keys)))
(defn- encrypt-tx-item
[aes-key item]
(cond
@@ -622,7 +638,8 @@
(mapv (fn [[addr content addresses]]
(let [data (try-read-transit content)]
(if (and (not= data invalid-transit) (map? data))
(p/let [data' (crypt/<encrypt-map aes-key rtc-const/encrypt-attr-set data)
(p/let [keys' (<encrypt-keys-attrs aes-key (:keys data))
data' (assoc data :keys keys')
content' (ldb/write-transit-str data')]
[addr content' addresses])
(p/resolved [addr content addresses]))))
@@ -637,12 +654,14 @@
(mapv (fn [[addr content addresses]]
(let [data (try-read-transit content)]
(if (and (not= data invalid-transit) (map? data))
(p/let [data' (crypt/<decrypt-map aes-key rtc-const/encrypt-attr-set data)
(p/let [keys (<decrypt-keys-attrs aes-key (:keys data))
data' (assoc data :keys keys)
content' (ldb/write-transit-str data')]
[addr content' addresses])
(p/resolved [addr content addresses]))))
rows))]
(vec items))))
(defn- require-asset-field
[repo field value context]
(when (or (nil? value) (and (string? value) (string/blank? value)))

View File

@@ -618,9 +618,7 @@
[repo rows reset? graph-id e2ee?]
(p/let [_ (when reset?
(close-db! repo))
rows* (if (true? e2ee?)
(db-sync/<decrypt-kvs-rows repo graph-id rows e2ee?)
(p/resolved rows))
rows* (db-sync/<decrypt-kvs-rows repo graph-id rows e2ee?)
db (ensure-db-sync-import-db! repo reset?)]
(when (seq rows*)
(upsert-addr-content! db (rows->sqlite-binds rows*)))

View File

@@ -0,0 +1,26 @@
(ns frontend.handler.db-based.db-sync-test
(:require [cljs.test :refer [deftest is async]]
[frontend.handler.db-based.db-sync :as db-sync]
[promesa.core :as p]))
(deftest download-graph-e2ee-detection-test
(async done
(with-redefs [db-sync/fetch-json (fn [_ _ _]
(p/resolved {:encrypted-aes-key "k"}))]
(-> (p/let [enabled? (#'db-sync/fetch-graph-e2ee? "http://base" "graph-1")]
(is (true? enabled?))
(done))
(p/catch (fn [e]
(is false (str e))
(done)))))))
(deftest download-graph-e2ee-missing-key-test
(async done
(with-redefs [db-sync/fetch-json (fn [_ _ _]
(p/resolved {}))]
(-> (p/let [enabled? (#'db-sync/fetch-graph-e2ee? "http://base" "graph-1")]
(is (false? enabled?))
(done))
(p/catch (fn [e]
(is false (str e))
(done)))))))