fix(rtc,e2ee): fix save/read password process

This commit is contained in:
rcmerci
2025-11-11 10:04:14 +08:00
committed by Tienson Qin
parent edbcb5179f
commit 75d44c1d95
4 changed files with 66 additions and 20 deletions

View File

@@ -287,6 +287,64 @@
m)))
(p/promise m) encrypt-attr-set))
(defn <encrypt-text-by-text-password
[text-password text]
(assert (and (string? text-password) (string? text)))
(p/let [salt (js/crypto.getRandomValues (js/Uint8Array. 16))
iv (js/crypto.getRandomValues (js/Uint8Array. 12))
password-key (.importKey subtle "raw"
(.encode (js/TextEncoder.) text-password)
"PBKDF2"
false
#js ["deriveKey"])
derived-key (.deriveKey subtle
#js {:name "PBKDF2"
:salt salt
:iterations 100000
:hash "SHA-256"}
password-key
#js {:name "AES-GCM" :length 256}
true
#js ["encrypt" "decrypt"])
encoded-text (.encode (js/TextEncoder.) text)
encrypted-text (.encrypt subtle
#js {:name "AES-GCM" :iv iv}
derived-key
encoded-text)]
[salt iv (js/Uint8Array. encrypted-text)]))
(defn <decrypt-text-by-text-password
[text-password encrypted-data-vector]
(assert (and (string? text-password) (vector? encrypted-data-vector)))
(->
(p/let [[salt-data iv-data encrypted-data] encrypted-data-vector
salt (js/Uint8Array. salt-data)
iv (js/Uint8Array. iv-data)
encrypted-data (js/Uint8Array. encrypted-data)
password-key (.importKey subtle "raw"
(.encode (js/TextEncoder.) text-password)
"PBKDF2"
false
#js ["deriveKey"])
derived-key (.deriveKey subtle
#js {:name "PBKDF2"
:salt salt
:iterations 100000
:hash "SHA-256"}
password-key
#js {:name "AES-GCM" :length 256}
true
#js ["encrypt" "decrypt"])
decrypted-data (.decrypt subtle
#js {:name "AES-GCM" :iv iv}
derived-key
encrypted-data)]
(.decode (js/TextDecoder.) decrypted-data))
(p/catch
(fn [e]
(log/error "decrypt-text-by-text-password" e)
(ex-info "decrypt-text-by-text-password" {} e)))))
(comment
(let [array-buffers-equal?
(fn [^js/ArrayBuffer buf1 ^js/ArrayBuffer buf2]

View File

@@ -36,6 +36,7 @@
[frontend.version :as fv]
[goog.object :as gobj]
[goog.string :as gstring]
[lambdaisland.glogi :as log]
[logseq.db :as ldb]
[logseq.shui.hooks :as hooks]
[logseq.shui.ui :as shui]
@@ -1254,7 +1255,8 @@
token refresh-token user-uuid new-password)
(set-reset-password-status! "Password updated successfully!"))
(p/catch (fn [e]
(js/console.error e)))))
(log/error :reset-password-failed e)
(set-reset-password-status! "Failed to update password.")))))
:disabled (string/blank? new-password)}
"Reset Password")]))])])

View File

@@ -4,6 +4,7 @@
[frontend.components.e2ee :as e2ee]
[frontend.handler.events :as events]
[frontend.state :as state]
[lambdaisland.glogi :as log]
[logseq.shui.ui :as shui]
[promesa.core :as p]))
@@ -17,8 +18,7 @@
(p/resolve! private-key-promise private-key))
(p/catch
(fn [error]
(prn :debug :read-e2ee-password-failed)
(js/console.error error)
(log/error :read-e2ee-password-failed error)
(shui/dialog-open!
#(e2ee/e2ee-password-to-decrypt-private-key encrypted-private-key private-key-promise refresh-token)
{:auto-width? true

View File

@@ -20,29 +20,15 @@
(defn- <save-e2ee-password
[refresh-token password]
(prn :debug :<save-e2ee-password password)
(assert (and (string? refresh-token)
(string? password)))
(p/let [raw (.encode (js/TextEncoder.) refresh-token)
digestbuf (.digest js/crypto.subtle "SHA-256" raw)
key-bytes (js/Uint8Array. digestbuf)
aes-key (crypt/<import-aes-key key-bytes)
result (crypt/<encrypt-text aes-key password)
(p/let [result (crypt/<encrypt-text-by-text-password refresh-token password)
text (ldb/write-transit-str result)]
(opfs/<write-text! e2ee-password-file text)))
(defn- <read-e2ee-password
[refresh-token]
(prn :debug :<read-e2ee-password)
(assert (string? refresh-token))
(p/let [raw (.encode (js/TextEncoder.) refresh-token)
digestbuf (.digest js/crypto.subtle "SHA-256" raw)
key-bytes (js/Uint8Array. digestbuf)
aes-key (crypt/<import-aes-key key-bytes)
text (opfs/<read-text! e2ee-password-file)
(p/let [text (opfs/<read-text! e2ee-password-file)
data (ldb/read-transit-str text)
password (crypt/<decrypt-text aes-key data)]
(prn :debug :text text :password password)
password (crypt/<decrypt-text-by-text-password refresh-token data)]
password))
(defn- <get-item