fix: handle wrong e2ee password on download

This commit is contained in:
Tienson Qin
2026-05-09 12:18:45 +08:00
parent b71228a7b0
commit c19eca0fd6
5 changed files with 92 additions and 13 deletions

View File

@@ -24,6 +24,7 @@
[frontend.handler.db-based.rtc-flows :as rtc-flows]
[frontend.handler.db-based.sync :as rtc-handler]
[frontend.handler.editor :as editor-handler]
[frontend.handler.events.rtc-error :as rtc-error]
[frontend.handler.export :as export]
[frontend.handler.graph :as graph-handler]
[frontend.handler.notification :as notification]
@@ -57,13 +58,6 @@
(defmulti handle first)
(defonce ^:private *search-index-build-timeout (atom nil))
(def ^:private decrypt-aes-key-failed-notification
"Failed to decrypt this graph.")
(defn- decrypt-aes-key-failed?
[error]
(string/includes? (or (ex-message error) (str error)) "decrypt-aes-key"))
(defn- <build-search-index!
[repo]
(-> (state/<invoke-db-worker :thread-api/search-build-blocks-indice-in-worker repo)
@@ -389,8 +383,8 @@
(println "RTC download graph failed, error:")
(log/error :rtc-download-graph-failed e)
(shui/popup-hide! :download-rtc-graph)
(when (decrypt-aes-key-failed? e)
(notification/show! decrypt-aes-key-failed-notification :error false))))))
(when (rtc-error/download-decrypt-failed? e)
(notification/show! (t :encryption/wrong-password) :error false))))))
;; db-worker -> UI
(defmethod handle :db/sync-changes [[_ data]]

View File

@@ -0,0 +1,30 @@
(ns frontend.handler.events.rtc-error
"RTC event error helpers."
(:require [clojure.string :as string]))
(defn- throwable-message
[error]
(or (ex-message error)
(when (instance? js/Error error)
(.-message error))
(some-> error str)))
(defn- error-texts
[error]
(when error
(let [data (ex-data error)]
(concat
[(throwable-message error)
(:error-message data)
(:error-cause data)]
(error-texts (:error data))
(error-texts (ex-cause error))))))
(defn download-decrypt-failed?
[error]
(boolean
(some (fn [text]
(and (string? text)
(or (string/includes? text "decrypt-aes-key")
(string/includes? text "decrypt-private-key"))))
(error-texts error))))

View File

@@ -467,10 +467,10 @@
(let [base (sync-auth/http-base-url @worker-state/*db-sync-config)]
(if (and (seq repo) (seq graph-id) (seq base))
(let [stage* (atom :init)
import-id* (atom nil)]
(-> (p/let [log-f (fn [payload]
(rtc-log-and-state/rtc-log :rtc.log/download payload))
_ (log-f {:sub-type :download-progress
import-id* (atom nil)
log-f (fn [payload]
(rtc-log-and-state/rtc-log :rtc.log/download payload))]
(-> (p/let [_ (log-f {:sub-type :download-progress
:graph-uuid graph-id
:message "Preparing graph snapshot download"})
_ (reset! stage* :fetch-pull)
@@ -529,6 +529,9 @@
(p/catch (fn [error]
(when-let [import-id @import-id*]
(clear-import-state! import-id))
(log-f {:sub-type :download-completed
:graph-uuid graph-id
:message "Graph snapshot download failed"})
(log/error :db-sync/download-graph-by-id-failed
{:repo repo
:graph-id graph-id

View File

@@ -0,0 +1,21 @@
(ns frontend.handler.events.rtc-error-test
(:require [cljs.test :refer [deftest is]]
[frontend.handler.events.rtc-error :as rtc-error]))
(deftest download-decrypt-failed-detects-worker-error-data-test
(is (true?
(rtc-error/download-decrypt-failed?
(ex-info "db-sync download failed"
{:error-message "decrypt-private-key"})))))
(deftest download-decrypt-failed-detects-nested-error-test
(is (true?
(rtc-error/download-decrypt-failed?
(ex-info "db-sync download failed"
{:error (ex-info "decrypt-aes-key" {})})))))
(deftest download-decrypt-failed-ignores-other-errors-test
(is (false?
(rtc-error/download-decrypt-failed?
(ex-info "db-sync download failed"
{:error-message "snapshot download failed"})))))

View File

@@ -3,6 +3,7 @@
[frontend.worker.state :as worker-state]
[frontend.worker.sync.crypt :as sync-crypt]
[frontend.worker.sync.download :as sync-download]
[frontend.worker.sync.log-and-state :as rtc-log-and-state]
[logseq.db-sync.snapshot :as snapshot]
[promesa.core :as p]))
@@ -78,3 +79,33 @@
(set! js/fetch fetch-prev)
(reset! worker-state/*db-sync-config config-prev)
(done)))))))
(deftest encrypted-download-failure-emits-completed-log-test
(async done
(let [config-prev @worker-state/*db-sync-config
log-events (atom [])]
(reset! worker-state/*db-sync-config {:http-base "https://sync.example.test"})
(-> (p/with-redefs [sync-download/fetch-json (fn [_url _opts schema]
(case schema
:sync/pull
(p/resolved {:t 42})
:sync/snapshot-download
(p/resolved {:url "https://sync.example.test/snapshot"})
(p/rejected (ex-info "unexpected schema" {:schema schema}))))
sync-crypt/<fetch-graph-aes-key-for-download (fn [_graph-id]
(p/rejected (ex-info "decrypt-private-key" {})))
rtc-log-and-state/rtc-log (fn [type payload]
(swap! log-events conj (assoc payload :type type))
nil)]
(sync-download/download-graph-by-id! "repo" "graph-1" true))
(p/then (fn [_]
(is false "expected download failure")))
(p/catch (fn [error]
(is (= "db-sync download failed" (ex-message error)))
(is (= [:download-progress :download-completed]
(mapv :sub-type @log-events)))))
(p/finally (fn []
(reset! worker-state/*db-sync-config config-prev)
(done)))))))