mirror of
https://github.com/logseq/logseq.git
synced 2026-02-01 22:47:36 +00:00
refactor: use reitit for worker routes
This commit is contained in:
1
deps/db-sync/deps.edn
vendored
1
deps/db-sync/deps.edn
vendored
@@ -10,6 +10,7 @@
|
||||
thheller/shadow-cljs {:mvn/version "3.3.4"}
|
||||
com.lambdaisland/glogi {:git/url "https://github.com/lambdaisland/glogi"
|
||||
:git/sha "30328a045141717aadbbb693465aed55f0904976"}
|
||||
metosin/reitit {:mvn/version "0.4.2"}
|
||||
logseq/common {:local/root "../common"}
|
||||
logseq/db {:local/root "../db"}}
|
||||
:aliases
|
||||
|
||||
2
deps/db-sync/package.json
vendored
2
deps/db-sync/package.json
vendored
@@ -6,7 +6,7 @@
|
||||
"dev": "cd ./worker && npx wrangler dev",
|
||||
"watch": "clojure -M:cljs watch db-sync",
|
||||
"release": "clojure -M:cljs release db-sync",
|
||||
"test": "clojure -M:cljs compile db-sync-test",
|
||||
"test": "clojure -M:cljs compile db-sync-test && node worker/dist/worker-test.js",
|
||||
"clean": "rm -rf ./worker/dist/",
|
||||
"deploy": "yarn clean && yarn release && cd ./worker && wrangler deploy",
|
||||
"deploy-staging": "yarn clean && yarn release && cd ./worker && wrangler deploy --env staging"
|
||||
|
||||
551
deps/db-sync/src/logseq/db_sync/worker.cljs
vendored
551
deps/db-sync/src/logseq/db_sync/worker.cljs
vendored
@@ -13,6 +13,7 @@
|
||||
[logseq.db-sync.protocol :as protocol]
|
||||
[logseq.db-sync.snapshot :as snapshot]
|
||||
[logseq.db-sync.storage :as storage]
|
||||
[logseq.db-sync.worker.routes :as routes]
|
||||
[promesa.core :as p]
|
||||
[shadow.cljs.modern :refer (defclass)]))
|
||||
|
||||
@@ -823,18 +824,12 @@
|
||||
(log/error :db-sync/index-db-missing {:binding "DB"}))
|
||||
db))
|
||||
|
||||
(defn- graph-path-parts [path]
|
||||
(->> (string/split path #"/")
|
||||
(remove string/blank?)
|
||||
(vec)))
|
||||
|
||||
(defn- handle-index-fetch [^js self request]
|
||||
(let [db (index-db self)
|
||||
env (.-env self)
|
||||
url (js/URL. (.-url request))
|
||||
path (.-pathname url)
|
||||
method (.-method request)
|
||||
parts (graph-path-parts path)]
|
||||
method (.-method request)]
|
||||
(try
|
||||
(cond
|
||||
(contains? #{"OPTIONS" "HEAD"} method)
|
||||
@@ -848,331 +843,297 @@
|
||||
claims (auth-claims request env)
|
||||
_ (when claims
|
||||
(index/<user-upsert! db claims))]
|
||||
(cond
|
||||
(nil? claims)
|
||||
(unauthorized)
|
||||
(let [route (routes/match-route method path)
|
||||
path-params (:path-params route)
|
||||
graph-id (:graph-id path-params)
|
||||
member-id (:member-id path-params)]
|
||||
(cond
|
||||
(nil? claims)
|
||||
(unauthorized)
|
||||
|
||||
(and (= method "GET") (= ["graphs"] parts))
|
||||
(let [user-id (aget claims "sub")]
|
||||
(if (string? user-id)
|
||||
(p/let [graphs (index/<index-list db user-id)]
|
||||
(json-response :graphs/list {:graphs graphs}))
|
||||
(unauthorized)))
|
||||
route
|
||||
(case (:handler route)
|
||||
:graphs/list
|
||||
(let [user-id (aget claims "sub")]
|
||||
(if (string? user-id)
|
||||
(p/let [graphs (index/<index-list db user-id)]
|
||||
(json-response :graphs/list {:graphs graphs}))
|
||||
(unauthorized)))
|
||||
|
||||
(and (= method "POST") (= ["graphs"] parts))
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :graphs/create body)
|
||||
graph-id (str (random-uuid))
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
|
||||
:else
|
||||
(p/let [{:keys [graph-name schema-version]} body
|
||||
name-exists? (index/<graph-name-exists? db graph-name user-id)]
|
||||
(if name-exists?
|
||||
(bad-request "duplicate graph name")
|
||||
(p/let [_ (index/<index-upsert! db graph-id graph-name user-id schema-version)
|
||||
_ (index/<graph-member-upsert! db graph-id user-id "manager" user-id)]
|
||||
(json-response :graphs/create {:graph-id graph-id})))))))))
|
||||
|
||||
(and (= method "GET")
|
||||
(= 3 (count parts))
|
||||
(= "graphs" (first parts))
|
||||
(= "access" (nth parts 2)))
|
||||
(let [graph-id (nth parts 1)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(p/let [owns? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if owns?
|
||||
(json-response :graphs/access {:ok true})
|
||||
(forbidden)))))
|
||||
|
||||
(and (= method "GET")
|
||||
(= 3 (count parts))
|
||||
(= "graphs" (first parts))
|
||||
(= "members" (nth parts 2 nil)))
|
||||
(let [graph-id (nth parts 1 nil)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(p/let [can-access? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not can-access?)
|
||||
(forbidden)
|
||||
(p/let [members (index/<graph-members-list db graph-id)]
|
||||
(json-response :graph-members/list {:members members}))))))
|
||||
|
||||
(and (= method "POST")
|
||||
(= 3 (count parts))
|
||||
(= "graphs" (first parts))
|
||||
(= "members" (nth parts 2 nil)))
|
||||
(let [graph-id (nth parts 1 nil)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
:graphs/create
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :graph-members/create body)
|
||||
member-id (:user-id body)
|
||||
email (:email body)
|
||||
role (or (:role body) "member")]
|
||||
body (coerce-http-request :graphs/create body)
|
||||
graph-id (str (random-uuid))
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(and (not (string? member-id))
|
||||
(not (string? email)))
|
||||
(bad-request "invalid user")
|
||||
|
||||
:else
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)
|
||||
resolved-id (if (string? member-id)
|
||||
(p/resolved member-id)
|
||||
(index/<user-id-by-email db email))]
|
||||
(if (not manager?)
|
||||
(forbidden)
|
||||
(if-not (string? resolved-id)
|
||||
(bad-request "user not found")
|
||||
(p/let [_ (index/<graph-member-upsert! db graph-id resolved-id role user-id)]
|
||||
(json-response :graph-members/create {:ok true}))))))))))))
|
||||
|
||||
(and (= method "PUT")
|
||||
(= 4 (count parts))
|
||||
(= "graphs" (first parts))
|
||||
(= "members" (nth parts 2 nil)))
|
||||
(let [graph-id (nth parts 1 nil)
|
||||
member-id (nth parts 3 nil)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(not (string? member-id))
|
||||
(bad-request "invalid user id")
|
||||
|
||||
:else
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :graph-members/update body)
|
||||
role (:role body)]
|
||||
(cond
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
|
||||
:else
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)]
|
||||
(if (not manager?)
|
||||
(forbidden)
|
||||
(p/let [_ (index/<graph-member-update-role! db graph-id member-id role)]
|
||||
(json-response :graph-members/update {:ok true})))))))))))
|
||||
(p/let [{:keys [graph-name schema-version]} body
|
||||
name-exists? (index/<graph-name-exists? db graph-name user-id)]
|
||||
(if name-exists?
|
||||
(bad-request "duplicate graph name")
|
||||
(p/let [_ (index/<index-upsert! db graph-id graph-name user-id schema-version)
|
||||
_ (index/<graph-member-upsert! db graph-id user-id "manager" user-id)]
|
||||
(json-response :graphs/create {:graph-id graph-id})))))))))
|
||||
|
||||
(and (= method "DELETE")
|
||||
(= 4 (count parts))
|
||||
(= "graphs" (first parts))
|
||||
(= "members" (nth parts 2 nil)))
|
||||
(let [graph-id (nth parts 1 nil)
|
||||
member-id (nth parts 3 nil)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(not (string? member-id))
|
||||
(bad-request "invalid user id")
|
||||
|
||||
:else
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)
|
||||
target-role (index/<graph-member-role db graph-id member-id)
|
||||
self-leave? (and (= user-id member-id)
|
||||
(= "member" target-role))]
|
||||
:graphs/access
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(and manager? (not= "manager" target-role))
|
||||
(p/let [_ (index/<graph-member-delete! db graph-id member-id)]
|
||||
(json-response :graph-members/delete {:ok true}))
|
||||
|
||||
self-leave?
|
||||
(p/let [_ (index/<graph-member-delete! db graph-id member-id)]
|
||||
(json-response :graph-members/delete {:ok true}))
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(forbidden)))))
|
||||
(p/let [owns? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if owns?
|
||||
(json-response :graphs/access {:ok true})
|
||||
(forbidden)))))
|
||||
|
||||
(and (= method "GET")
|
||||
(= ["e2ee" "user-keys"] parts))
|
||||
(let [user-id (aget claims "sub")]
|
||||
(if (string? user-id)
|
||||
(p/let [pair (index/<user-rsa-key-pair db user-id)]
|
||||
(json-response :e2ee/user-keys (or pair {})))
|
||||
(unauthorized)))
|
||||
:graph-members/list
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(and (= method "POST")
|
||||
(= ["e2ee" "user-keys"] parts))
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :e2ee/user-keys body)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
:else
|
||||
(p/let [can-access? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not can-access?)
|
||||
(forbidden)
|
||||
(p/let [members (index/<graph-members-list db graph-id)]
|
||||
(json-response :graph-members/list {:members members}))))))
|
||||
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
:graph-members/create
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(let [{:keys [public-key encrypted-private-key]} body]
|
||||
(p/let [_ (index/<user-rsa-key-pair-upsert! db user-id public-key encrypted-private-key)]
|
||||
(json-response :e2ee/user-keys {:public-key public-key
|
||||
:encrypted-private-key encrypted-private-key}))))))))
|
||||
:else
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :graph-members/create body)
|
||||
member-id (:user-id body)
|
||||
email (:email body)
|
||||
role (or (:role body) "member")]
|
||||
(cond
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
|
||||
(and (= method "GET")
|
||||
(= ["e2ee" "user-public-key"] parts))
|
||||
(let [email (.get (.-searchParams url) "email")]
|
||||
(p/let [public-key (index/<user-rsa-public-key-by-email db email)]
|
||||
(json-response :e2ee/user-public-key
|
||||
(cond-> {}
|
||||
(some? public-key)
|
||||
(assoc :public-key public-key)))))
|
||||
(and (not (string? member-id))
|
||||
(not (string? email)))
|
||||
(bad-request "invalid user")
|
||||
|
||||
(and (= method "GET")
|
||||
(= 4 (count parts))
|
||||
(= "e2ee" (first parts))
|
||||
(= "graphs" (nth parts 1))
|
||||
(= "aes-key" (nth parts 3)))
|
||||
(let [graph-id (nth parts 2)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
:else
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)
|
||||
resolved-id (if (string? member-id)
|
||||
(p/resolved member-id)
|
||||
(index/<user-id-by-email db email))]
|
||||
(if (not manager?)
|
||||
(forbidden)
|
||||
(if-not (string? resolved-id)
|
||||
(bad-request "user not found")
|
||||
(p/let [_ (index/<graph-member-upsert! db graph-id resolved-id role user-id)]
|
||||
(json-response :graph-members/create {:ok true}))))))))))))
|
||||
|
||||
:else
|
||||
(p/let [access? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not access?)
|
||||
(forbidden)
|
||||
(p/let [encrypted-aes-key (index/<graph-encrypted-aes-key db graph-id user-id)]
|
||||
(json-response :e2ee/graph-aes-key (cond-> {}
|
||||
(some? encrypted-aes-key)
|
||||
(assoc :encrypted-aes-key encrypted-aes-key))))))))
|
||||
:graph-members/update
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(and (= method "POST")
|
||||
(= 4 (count parts))
|
||||
(= "e2ee" (first parts))
|
||||
(= "graphs" (nth parts 1))
|
||||
(= "aes-key" (nth parts 3)))
|
||||
(let [graph-id (nth parts 2)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
(not (string? member-id))
|
||||
(bad-request "invalid user id")
|
||||
|
||||
:else
|
||||
:else
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :graph-members/update body)
|
||||
role (:role body)]
|
||||
(cond
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
|
||||
:else
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)]
|
||||
(if (not manager?)
|
||||
(forbidden)
|
||||
(p/let [_ (index/<graph-member-update-role! db graph-id member-id role)]
|
||||
(json-response :graph-members/update {:ok true})))))))))))
|
||||
|
||||
:graph-members/delete
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(not (string? member-id))
|
||||
(bad-request "invalid user id")
|
||||
|
||||
:else
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)
|
||||
target-role (index/<graph-member-role db graph-id member-id)
|
||||
self-leave? (and (= user-id member-id)
|
||||
(= "member" target-role))]
|
||||
(cond
|
||||
(and manager? (not= "manager" target-role))
|
||||
(p/let [_ (index/<graph-member-delete! db graph-id member-id)]
|
||||
(json-response :graph-members/delete {:ok true}))
|
||||
|
||||
self-leave?
|
||||
(p/let [_ (index/<graph-member-delete! db graph-id member-id)]
|
||||
(json-response :graph-members/delete {:ok true}))
|
||||
|
||||
:else
|
||||
(forbidden)))))
|
||||
|
||||
:graphs/delete
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (seq graph-id))
|
||||
(bad-request "missing graph id")
|
||||
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(p/let [owns? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not owns?)
|
||||
(forbidden)
|
||||
(p/let [_ (index/<index-delete! db graph-id)]
|
||||
(let [^js namespace (.-LOGSEQ_SYNC_DO (.-env self))
|
||||
do-id (.idFromName namespace graph-id)
|
||||
stub (.get namespace do-id)
|
||||
reset-url (str (.-origin url) "/admin/reset")]
|
||||
(.fetch stub (js/Request. reset-url #js {:method "DELETE"})))
|
||||
(json-response :graphs/delete {:graph-id graph-id :deleted true}))))))
|
||||
|
||||
:e2ee/user-keys-get
|
||||
(let [user-id (aget claims "sub")]
|
||||
(if (string? user-id)
|
||||
(p/let [pair (index/<user-rsa-key-pair db user-id)]
|
||||
(json-response :e2ee/user-keys (or pair {})))
|
||||
(unauthorized)))
|
||||
|
||||
:e2ee/user-keys-post
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :e2ee/graph-aes-key body)]
|
||||
(if (nil? body)
|
||||
body (coerce-http-request :e2ee/user-keys body)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(nil? body)
|
||||
(bad-request "invalid body")
|
||||
(p/let [access? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not access?)
|
||||
(forbidden)
|
||||
(let [{:keys [encrypted-aes-key]} body]
|
||||
(p/let [_ (index/<graph-encrypted-aes-key-upsert! db graph-id user-id encrypted-aes-key)]
|
||||
(json-response :e2ee/graph-aes-key {:encrypted-aes-key encrypted-aes-key}))))))))))))
|
||||
|
||||
(and (= method "POST")
|
||||
(= 4 (count parts))
|
||||
(= "e2ee" (first parts))
|
||||
(= "graphs" (nth parts 1))
|
||||
(= "grant-access" (nth parts 3)))
|
||||
(let [graph-id (nth parts 2)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
:else
|
||||
(let [{:keys [public-key encrypted-private-key]} body]
|
||||
(p/let [_ (index/<user-rsa-key-pair-upsert! db user-id public-key encrypted-private-key)]
|
||||
(json-response :e2ee/user-keys {:public-key public-key
|
||||
:encrypted-private-key encrypted-private-key}))))))))
|
||||
|
||||
:else
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :e2ee/grant-access body)]
|
||||
(if (nil? body)
|
||||
(bad-request "invalid body")
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)]
|
||||
(if (not manager?)
|
||||
(forbidden)
|
||||
(let [entries (:target-user-email+encrypted-aes-key-coll body)
|
||||
missing (atom [])]
|
||||
(p/let [_ (p/all
|
||||
(map (fn [entry]
|
||||
(let [email (:email entry)
|
||||
encrypted-aes-key (:encrypted-aes-key entry)]
|
||||
(p/let [target-user-id (index/<user-id-by-email db email)
|
||||
access? (and target-user-id
|
||||
(index/<user-has-access-to-graph? db graph-id target-user-id))]
|
||||
(if (and target-user-id access?)
|
||||
(index/<graph-encrypted-aes-key-upsert! db graph-id target-user-id encrypted-aes-key)
|
||||
(swap! missing conj email)))))
|
||||
entries))]
|
||||
(json-response :e2ee/grant-access
|
||||
(cond-> {:ok true}
|
||||
(seq @missing)
|
||||
(assoc :missing-users @missing))))))))))))))
|
||||
:e2ee/user-public-key-get
|
||||
(let [email (.get (.-searchParams url) "email")]
|
||||
(p/let [public-key (index/<user-rsa-public-key-by-email db email)]
|
||||
(json-response :e2ee/user-public-key
|
||||
(cond-> {}
|
||||
(some? public-key)
|
||||
(assoc :public-key public-key)))))
|
||||
|
||||
(and (= method "DELETE")
|
||||
(= 2 (count parts))
|
||||
(= "graphs" (first parts)))
|
||||
(let [graph-id (nth parts 1 nil)
|
||||
user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (seq graph-id))
|
||||
(bad-request "missing graph id")
|
||||
:e2ee/graph-aes-key-get
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
:else
|
||||
(p/let [access? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not access?)
|
||||
(forbidden)
|
||||
(p/let [encrypted-aes-key (index/<graph-encrypted-aes-key db graph-id user-id)]
|
||||
(json-response :e2ee/graph-aes-key (cond-> {}
|
||||
(some? encrypted-aes-key)
|
||||
(assoc :encrypted-aes-key encrypted-aes-key))))))))
|
||||
|
||||
:else
|
||||
(p/let [owns? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not owns?)
|
||||
(forbidden)
|
||||
(p/let [_ (index/<index-delete! db graph-id)]
|
||||
(let [^js namespace (.-LOGSEQ_SYNC_DO (.-env self))
|
||||
do-id (.idFromName namespace graph-id)
|
||||
stub (.get namespace do-id)
|
||||
reset-url (str (.-origin url) "/admin/reset")]
|
||||
(.fetch stub (js/Request. reset-url #js {:method "DELETE"})))
|
||||
(json-response :graphs/delete {:graph-id graph-id :deleted true}))))))
|
||||
:else
|
||||
(not-found))))
|
||||
:e2ee/graph-aes-key-post
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :e2ee/graph-aes-key body)]
|
||||
(if (nil? body)
|
||||
(bad-request "invalid body")
|
||||
(p/let [access? (index/<user-has-access-to-graph? db graph-id user-id)]
|
||||
(if (not access?)
|
||||
(forbidden)
|
||||
(let [{:keys [encrypted-aes-key]} body]
|
||||
(p/let [_ (index/<graph-encrypted-aes-key-upsert! db graph-id user-id encrypted-aes-key)]
|
||||
(json-response :e2ee/graph-aes-key {:encrypted-aes-key encrypted-aes-key}))))))))))))
|
||||
|
||||
:e2ee/grant-access
|
||||
(let [user-id (aget claims "sub")]
|
||||
(cond
|
||||
(not (string? user-id))
|
||||
(unauthorized)
|
||||
|
||||
:else
|
||||
(.then (common/read-json request)
|
||||
(fn [result]
|
||||
(if (nil? result)
|
||||
(bad-request "missing body")
|
||||
(let [body (js->clj result :keywordize-keys true)
|
||||
body (coerce-http-request :e2ee/grant-access body)]
|
||||
(if (nil? body)
|
||||
(bad-request "invalid body")
|
||||
(p/let [manager? (index/<user-is-manager? db graph-id user-id)]
|
||||
(if (not manager?)
|
||||
(forbidden)
|
||||
(let [entries (:target-user-email+encrypted-aes-key-coll body)
|
||||
missing (atom [])]
|
||||
(p/let [_ (p/all
|
||||
(map (fn [entry]
|
||||
(let [email (:email entry)
|
||||
encrypted-aes-key (:encrypted-aes-key entry)]
|
||||
(p/let [target-user-id (index/<user-id-by-email db email)
|
||||
access? (and target-user-id
|
||||
(index/<user-has-access-to-graph? db graph-id target-user-id))]
|
||||
(if (and target-user-id access?)
|
||||
(index/<graph-encrypted-aes-key-upsert! db graph-id target-user-id encrypted-aes-key)
|
||||
(swap! missing conj email)))))
|
||||
entries))]
|
||||
(json-response :e2ee/grant-access
|
||||
(cond-> {:ok true}
|
||||
(seq @missing)
|
||||
(assoc :missing-users @missing))))))))))))))
|
||||
|
||||
(not-found))
|
||||
|
||||
:else
|
||||
(not-found)))))
|
||||
(catch :default error
|
||||
(log/error :db-sync/index-error error)
|
||||
(error-response "server error" 500)))))
|
||||
|
||||
31
deps/db-sync/src/logseq/db_sync/worker/routes.cljs
vendored
Normal file
31
deps/db-sync/src/logseq/db_sync/worker/routes.cljs
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
(ns logseq.db-sync.worker.routes
|
||||
(:require [reitit.core :as r]))
|
||||
|
||||
(def ^:private route-data
|
||||
[["/graphs"
|
||||
["" {:methods {"GET" :graphs/list
|
||||
"POST" :graphs/create}}]
|
||||
["/:graph-id"
|
||||
["/access" {:methods {"GET" :graphs/access}}]
|
||||
["/members" {:methods {"GET" :graph-members/list
|
||||
"POST" :graph-members/create}}]
|
||||
["/members/:member-id" {:methods {"PUT" :graph-members/update
|
||||
"DELETE" :graph-members/delete}}]
|
||||
["" {:methods {"DELETE" :graphs/delete}}]]]
|
||||
|
||||
["/e2ee"
|
||||
["/user-keys" {:methods {"GET" :e2ee/user-keys-get
|
||||
"POST" :e2ee/user-keys-post}}]
|
||||
["/user-public-key" {:methods {"GET" :e2ee/user-public-key-get}}]
|
||||
["/graphs/:graph-id"
|
||||
["/aes-key" {:methods {"GET" :e2ee/graph-aes-key-get
|
||||
"POST" :e2ee/graph-aes-key-post}}]
|
||||
["/grant-access" {:methods {"POST" :e2ee/grant-access}}]]]])
|
||||
|
||||
(def ^:private router
|
||||
(r/router route-data))
|
||||
|
||||
(defn match-route [method path]
|
||||
(when-let [match (r/match-by-path router path)]
|
||||
(when-let [handler (get-in match [:data :methods method])]
|
||||
(assoc match :handler handler))))
|
||||
48
deps/db-sync/test/logseq/db_sync/worker_routes_test.cljs
vendored
Normal file
48
deps/db-sync/test/logseq/db_sync/worker_routes_test.cljs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
(ns logseq.db-sync.worker-routes-test
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
[logseq.db-sync.worker.routes :as routes]))
|
||||
|
||||
(deftest match-route-graphs-test
|
||||
(testing "graphs routes"
|
||||
(let [match (routes/match-route "GET" "/graphs")]
|
||||
(is (= :graphs/list (:handler match))))
|
||||
(let [match (routes/match-route "POST" "/graphs")]
|
||||
(is (= :graphs/create (:handler match))))
|
||||
(let [match (routes/match-route "GET" "/graphs/graph-1/access")]
|
||||
(is (= :graphs/access (:handler match)))
|
||||
(is (= "graph-1" (get-in match [:path-params :graph-id]))))
|
||||
(let [match (routes/match-route "GET" "/graphs/graph-2/members")]
|
||||
(is (= :graph-members/list (:handler match)))
|
||||
(is (= "graph-2" (get-in match [:path-params :graph-id]))))
|
||||
(let [match (routes/match-route "POST" "/graphs/graph-3/members")]
|
||||
(is (= :graph-members/create (:handler match))))
|
||||
(let [match (routes/match-route "PUT" "/graphs/graph-4/members/user-9")]
|
||||
(is (= :graph-members/update (:handler match)))
|
||||
(is (= "graph-4" (get-in match [:path-params :graph-id])))
|
||||
(is (= "user-9" (get-in match [:path-params :member-id]))))
|
||||
(let [match (routes/match-route "DELETE" "/graphs/graph-5")]
|
||||
(is (= :graphs/delete (:handler match)))
|
||||
(is (= "graph-5" (get-in match [:path-params :graph-id]))))))
|
||||
|
||||
(deftest match-route-e2ee-test
|
||||
(testing "e2ee routes"
|
||||
(let [match (routes/match-route "GET" "/e2ee/user-keys")]
|
||||
(is (= :e2ee/user-keys-get (:handler match))))
|
||||
(let [match (routes/match-route "POST" "/e2ee/user-keys")]
|
||||
(is (= :e2ee/user-keys-post (:handler match))))
|
||||
(let [match (routes/match-route "GET" "/e2ee/user-public-key")]
|
||||
(is (= :e2ee/user-public-key-get (:handler match))))
|
||||
(let [match (routes/match-route "GET" "/e2ee/graphs/graph-7/aes-key")]
|
||||
(is (= :e2ee/graph-aes-key-get (:handler match)))
|
||||
(is (= "graph-7" (get-in match [:path-params :graph-id]))))
|
||||
(let [match (routes/match-route "POST" "/e2ee/graphs/graph-8/aes-key")]
|
||||
(is (= :e2ee/graph-aes-key-post (:handler match)))
|
||||
(is (= "graph-8" (get-in match [:path-params :graph-id]))))
|
||||
(let [match (routes/match-route "POST" "/e2ee/graphs/graph-9/grant-access")]
|
||||
(is (= :e2ee/grant-access (:handler match)))
|
||||
(is (= "graph-9" (get-in match [:path-params :graph-id]))))))
|
||||
|
||||
(deftest match-route-method-mismatch-test
|
||||
(testing "method mismatch returns nil"
|
||||
(is (nil? (routes/match-route "GET" "/graphs/graph-1/members/user-9")))
|
||||
(is (nil? (routes/match-route "PUT" "/e2ee/user-keys")))))
|
||||
Reference in New Issue
Block a user