Просмотр исходного кода

refactor: use reitit for worker routes

Tienson Qin 3 недель назад
Родитель
Сommit
cd0a2568b1

+ 1 - 0
deps/db-sync/deps.edn

@@ -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

+ 1 - 1
deps/db-sync/package.json

@@ -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"

+ 263 - 302
deps/db-sync/src/logseq/db_sync/worker.cljs

@@ -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)
-
-            (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)))
-
-            (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
+          (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)
+
+              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)))
+
+                :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
+                               (not (string? user-id))
+                               (unauthorized)
+
                                (nil? body)
                                (bad-request "invalid body")
 
-                               (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)
+                               (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})))))))))
+
+                :graphs/access
+                (let [user-id (aget claims "sub")]
+                  (cond
+                    (not (string? user-id))
+                    (unauthorized)
 
-                (not (string? member-id))
-                (bad-request "invalid user id")
+                    :else
+                    (p/let [owns? (index/<user-has-access-to-graph? db graph-id user-id)]
+                      (if owns?
+                        (json-response :graphs/access {:ok true})
+                        (forbidden)))))
 
-                :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")
+                :graph-members/list
+                (let [user-id (aget claims "sub")]
+                  (cond
+                    (not (string? user-id))
+                    (unauthorized)
 
-                               :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})))))))))))
-
-            (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)
+                    :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}))))))
+
+                :graph-members/create
+                (let [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/create body)
+                                     member-id (:user-id body)
+                                     email (:email body)
+                                     role (or (:role body) "member")]
+                                 (cond
+                                   (nil? body)
+                                   (bad-request "invalid body")
+
+                                   (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}))))))))))))
+
+                :graph-members/update
+                (let [user-id (aget claims "sub")]
+                  (cond
+                    (not (string? user-id))
+                    (unauthorized)
 
-                :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))]
+                    (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})))))))))))
+
+                :graph-members/delete
+                (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}))
+                    (not (string? user-id))
+                    (unauthorized)
 
-                    self-leave?
-                    (p/let [_ (index/<graph-member-delete! db graph-id member-id)]
-                      (json-response :graph-members/delete {:ok true}))
+                    (not (string? member-id))
+                    (bad-request "invalid user id")
 
                     :else
-                    (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)))
-
-            (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)
-
-                           (nil? body)
-                           (bad-request "invalid body")
-
-                           :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}))))))))
-
-            (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 (= 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)
+                    (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")
 
-                :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))))))))
-
-            (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? user-id))
+                    (unauthorized)
 
-                :else
+                    :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)
-                               (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)
+                                 body (coerce-http-request :e2ee/user-keys body)
+                                 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)
+                               (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))))))))))))))
-
-            (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")
 
-                (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}))))))))
+
+                :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)))))
+
+                :e2ee/graph-aes-key-get
+                (let [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 (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))))
+                    :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))))))))
+
+                :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 - 0
deps/db-sync/src/logseq/db_sync/worker/routes.cljs

@@ -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 - 0
deps/db-sync/test/logseq/db_sync/worker_routes_test.cljs

@@ -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")))))