Tienson Qin 1 месяц назад
Родитель
Сommit
35d28a976e

+ 10 - 0
deps/db-sync/src/logseq/db_sync/index.cljs

@@ -97,6 +97,16 @@
                         email-verified
                         username)))))
 
+(defn <user-id-by-email [db email]
+  (when (string? email)
+    (p/let [result (common/<d1-all db
+                                   "select id from users where email = ?"
+                                   email)
+            rows (common/get-sql-rows result)
+            row (first rows)]
+      (when row
+        (aget row "id")))))
+
 (defn <graph-member-upsert! [db graph-id user-id role invited-by]
   (let [now (common/now-ms)]
     (common/<d1-run db

+ 7 - 3
deps/db-sync/src/logseq/db_sync/malli_schema.cljs

@@ -120,9 +120,13 @@
    [:deleted :boolean]])
 
 (def graph-member-create-request-schema
-  [:map
-   [:user_id :string]
-   [:role {:optional true} graph-member-role-schema]])
+  [:or
+   [:map
+    [:user_id :string]
+    [:role {:optional true} graph-member-role-schema]]
+   [:map
+    [:email :string]
+    [:role {:optional true} graph-member-role-schema]]])
 
 (def graph-member-update-request-schema
   [:map

+ 12 - 5
deps/db-sync/src/logseq/db_sync/worker.cljs

@@ -628,20 +628,27 @@
                            (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")
 
-                               (not (string? member-id))
-                               (bad-request "invalid user id")
+                               (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)]
+                               (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)
-                                   (p/let [_ (index/<graph-member-upsert! db graph-id member-id role user-id)]
-                                     (json-response :graph-members/create {:ok true})))))))))))
+                                   (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))

+ 34 - 1
src/main/frontend/handler/db_based/db_sync.cljs

@@ -3,6 +3,7 @@
   (:require [clojure.string :as string]
             [frontend.config :as config]
             [frontend.db :as db]
+            [frontend.handler.notification :as notification]
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.user :as user-handler]
             [frontend.state :as state]
@@ -155,7 +156,7 @@
     (-> (if (and graph-uuid base)
           (p/let [_ (js/Promise. user-handler/task--ensure-id&access-token)
                   graph (str config/db-version-prefix graph-name)]
-              (p/loop [after -1           ; root addr is 0
+            (p/loop [after -1           ; root addr is 0
                      first-batch? true]
               (p/let [pull-resp (fetch-json (str base "/sync/" graph-uuid "/pull")
                                             {:method "GET"}
@@ -214,3 +215,35 @@
           (p/finally
             (fn []
               (state/set-state! :rtc/loading-graphs? false)))))))
+
+(defn <rtc-invite-email
+  [graph-uuid email]
+  (let [base (http-base)
+        graph-uuid (str graph-uuid)]
+    (if (and base (string? graph-uuid) (string? email))
+      (->
+       (p/let [_ (js/Promise. user-handler/task--ensure-id&access-token)
+               body (coerce-http-request :graph-members/create
+                                         {:email email
+                                          :role "member"})
+               _ (when (nil? body)
+                   (throw (ex-info "db-sync invalid invite body"
+                                   {:graph-uuid graph-uuid
+                                    :email email})))
+               _ (fetch-json (str base "/graphs/" graph-uuid "/members")
+                             {:method "POST"
+                              :headers {"content-type" "application/json"}
+                              :body (js/JSON.stringify (clj->js body))}
+                             {:response-schema :graph-members/create})]
+         (notification/show! "Invitation sent!" :success))
+       (p/catch (fn [e]
+                  (notification/show! "Something wrong, please try again." :error)
+                  (log/error :db-sync/invite-email-failed
+                             {:error e
+                              :graph-uuid graph-uuid
+                              :email email}))))
+      (p/rejected (ex-info "db-sync missing invite info"
+                           {:type :db-sync/invalid-invite
+                            :graph-uuid graph-uuid
+                            :email email
+                            :base base})))))

+ 4 - 2
src/main/frontend/handler/db_based/sync.cljs

@@ -2,8 +2,8 @@
   "Dispatch RTC calls between legacy RTC and db-sync implementations."
   (:require [frontend.config :as config]
             [frontend.db :as db]
-            [frontend.handler.db-based.rtc :as rtc-handler]
             [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]))
@@ -65,4 +65,6 @@
     (rtc-handler/<get-remote-graphs)))
 
 (defn <rtc-invite-email [graph-uuid email]
-  (rtc-handler/<rtc-invite-email graph-uuid email))
+  (if (db-sync-enabled?)
+    (db-sync-handler/<rtc-invite-email graph-uuid email)
+    (rtc-handler/<rtc-invite-email graph-uuid email)))