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

feat(token): fetch token if token expires

defclass 5 лет назад
Родитель
Сommit
b5d49c8ac6

+ 9 - 7
src/main/frontend/components/diff.cljs

@@ -13,6 +13,7 @@
             [frontend.ui :as ui]
             [frontend.db :as db]
             [frontend.git :as git]
+            [frontend.helper :as helper]
             [goog.object :as gobj]
             [promesa.core :as p]
             [frontend.github :as github]
@@ -135,20 +136,22 @@
        [:div "loading..."])]))
 
 ;; TODO: `n` shortcut for next diff, `p` for previous diff
-(rum/defcc diff < rum/reactive
+(rum/defcc diff <
+  rum/reactive
   {:will-mount
    (fn [state]
      (when-let [repo (state/get-current-repo)]
        (p/let [remote-latest-commit (common-handler/get-remote-ref repo)
                local-latest-commit (common-handler/get-ref repo)
-               result (git/get-local-diffs repo local-latest-commit remote-latest-commit)]
+               result (git/get-local-diffs repo local-latest-commit remote-latest-commit)
+               token (helper/get-github-token repo)]
          (reset! diffs result)
          (reset! remote-hash-id remote-latest-commit)
          (doseq [{:keys [type path]} result]
            (when (contains? #{"added" "modify"}
                             type)
              (github/get-content
-              (state/get-github-token repo)
+              token
               repo
               path
               remote-latest-commit
@@ -167,7 +170,6 @@
                       :href (str "https://github.com/apps/" config/github-app-name "/installations/new"))]
                    :error
                    false))))))))
-     state)
    :will-unmount
    (fn [state]
      (reset! diffs nil)
@@ -197,9 +199,9 @@
             path))
         [:div
          (ui/textarea
-          {:placeholder "Commit message (optional)"
-           :on-change (fn [e]
-                        (reset! commit-message (util/evalue e)))})
+           {:placeholder "Commit message (optional)"
+            :on-change (fn [e]
+                         (reset! commit-message (util/evalue e)))})
          (if pushing?
            [:span (ui/loading "Pushing")]
            (ui/button "Commit and push"

+ 3 - 1
src/main/frontend/core.cljs

@@ -4,8 +4,10 @@
             [frontend.handler.route :as route]
             [frontend.page :as page]
             [frontend.routes :as routes]
+            [frontend.spec]
             [reitit.frontend :as rf]
-            [reitit.frontend.easy :as rfe]))
+            [reitit.frontend.easy :as rfe]
+            ))
 
 (defn set-router!
   []

+ 3 - 2
src/main/frontend/handler.cljs

@@ -12,7 +12,8 @@
             [frontend.handler.file :as file-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.ui :as ui]
-            [goog.object :as gobj]))
+            [goog.object :as gobj]
+            [frontend.helper :as helper]))
 
 (defn- watch-for-date!
   []
@@ -50,7 +51,7 @@
                               (state/set-db-restoring! false))
                             (if (seq (:repos me))
                               ;; FIXME: handle error
-                              (repo-handler/request-app-tokens!
+                              (helper/request-app-tokens!
                                (fn []
                                  (repo-handler/clone-and-pull-repos me))
                                (fn []

+ 4 - 4
src/main/frontend/handler/git.cljs

@@ -10,7 +10,8 @@
             [frontend.handler.notification :as notification]
             [frontend.handler.route :as route-handler]
             [frontend.handler.common :as common-handler]
-            [cljs-time.local :as tl]))
+            [cljs-time.local :as tl]
+            [frontend.helper :as helper]))
 
 (defn- set-git-status!
   [repo-url value]
@@ -43,9 +44,8 @@
     (p/let [remote-oid (common-handler/get-remote-ref repo)
             commit-oid (git/commit repo commit-message (array remote-oid))
             result (git/write-ref! repo commit-oid)
-            push-result (git/push repo
-                                  (state/get-github-token repo)
-                                  true)]
+            token (helper/get-github-token repo)
+            push-result (git/push repo token true)]
       (reset! pushing? false)
       (notification/clear! nil)
       (route-handler/redirect! {:to :home}))))

+ 60 - 94
src/main/frontend/handler/repo.cljs

@@ -21,8 +21,7 @@
             [cljs.reader :as reader]
             [clojure.string :as string]
             [frontend.dicts :as dicts]
-            ;; [clojure.set :as set]
-))
+            [frontend.helper :as helper]))
 
 ;; Project settings should be checked in two situations:
 ;; 1. User changes the config.edn directly in logseq.com (fn: alter-file)
@@ -43,42 +42,6 @@
    :error
    false))
 
-(defn get-new-token
-  [repo]
-  (when-let [installation-id (-> (filter
-                                  (fn [r]
-                                    (= (:url r) repo))
-                                  (:repos (state/get-me)))
-                                 (first)
-                                 :installation_id)]
-    (util/post (str config/api "refresh_github_token")
-               {:installation-ids [installation-id]}
-               (fn [result]
-                 (let [token (:token (first result))]
-                   (state/set-github-token! repo token)))
-               (fn [error]
-                 (println "Something wrong!")
-                 (js/console.dir error)))))
-
-(defn request-app-tokens!
-  [ok-handler error-handler]
-  (let [repos (:repos (state/get-me))
-        installation-ids (->> (map :installation_id repos)
-                              (remove nil?)
-                              (distinct))]
-    (when (or (seq repos)
-              (seq installation-ids))
-      (util/post (str config/api "refresh_github_token")
-                 {:installation-ids installation-ids
-                  :repos repos}
-                 (fn [result]
-                   (state/set-github-installation-tokens! result)
-                   (when ok-handler (ok-handler)))
-                 (fn [error]
-                   (println "Something wrong!")
-                   (js/console.dir error)
-                   (when error-handler (error-handler)))))))
-
 (defn journal-file-changed?
   [repo-url diffs]
   (contains? (set (map :path diffs))
@@ -364,10 +327,11 @@
                               (and (or (string/includes? (str error) "401")
                                        (string/includes? (str error) "404"))
                                    (not fallback?))
-                              (request-app-tokens!
-                               (fn []
-                                 (pull repo-url (state/get-github-token repo-url) {:fallback? true}))
-                               nil)
+                              (p/let [token (helper/get-github-token repo-url)]
+                               (helper/request-app-tokens!
+                                 (fn []
+                                   (pull repo-url token {:fallback? true}))
+                                 nil))
 
                               (or (string/includes? (str error) "401")
                                   (string/includes? (str error) "404"))
@@ -400,9 +364,10 @@
               (let [commit-message (if (string/blank? commit-message)
                                      "Logseq auto save"
                                      commit-message)]
-                (p/let [commit-oid (git/commit repo-url commit-message)]
+                (p/let [commit-oid (git/commit repo-url commit-message)
+                        token (helper/get-github-token repo-url)]
                   (git-handler/set-git-status! repo-url :pushing)
-                  (when-let [token (state/get-github-token repo-url)]
+                  (when token
                     (util/p-handle
                      (git/push repo-url token force?)
                      (fn [result]
@@ -417,27 +382,27 @@
                                              (string/includes? (str error) "404"))]
                          (cond
                            (and permission? (not fallback?))
-                           (request-app-tokens!
+                           (helper/request-app-tokens!
                             (fn []
                               (git-handler/set-git-status! repo-url :re-push)
                               (push repo-url
-                                    {:commit-message commit-message
-                                     :fallback? true}))
+                                {:commit-message commit-message
+                                 :fallback? true}))
                             nil)
 
-                           :else
-                           (do
-                             (git-handler/set-git-status! repo-url :push-failed)
-                             (git-handler/set-git-error! repo-url error)
-                             (cond
-                               permission?
-                               (show-install-error! repo-url (util/format "Failed to push to %s. " repo-url))
+                          :else
+                          (do
+                            (git-handler/set-git-status! repo-url :push-failed)
+                            (git-handler/set-git-error! repo-url error)
+                            (cond
+                              permission?
+                              (show-install-error! repo-url (util/format "Failed to push to %s. " repo-url))
 
-                               (state/online?)
-                               (pull repo-url token {:force-pull? true})
+                              (state/online?)
+                              (pull repo-url token {:force-pull? true})
 
-                               :else    ; offline
-                               nil)))))))))))
+                              :else                         ; offline
+                              nil))))))))))
           (p/catch (fn [error]
                      (println "Git push error: ")
                      (git-handler/set-git-status! repo-url :push-failed)
@@ -452,39 +417,40 @@
 (defn pull-current-repo
   []
   (when-let [repo (state/get-current-repo)]
-    (when-let [token (state/get-github-token repo)]
-      (pull repo token {:force-pull? true}))))
+    (p/let [token (helper/get-github-token repo)]
+      (when token (pull repo token {:force-pull? true})))))
 
 (defn clone
   ([repo-url]
    (clone repo-url false))
   ([repo-url fallback?]
-   (when-let [token (state/get-github-token repo-url)]
-     (util/p-handle
-      (do
-        (state/set-cloning! true)
-        (git/clone repo-url token))
-      (fn [result]
-        (state/set-git-clone-repo! "")
-        (state/set-current-repo! repo-url)
-        (db/start-db-conn! (:me @state/state) repo-url)
-        (db/mark-repo-as-cloned repo-url))
-      (fn [e]
-        (if (and (not fallback?)
-                 (or (string/includes? (str e) "401")
-                     (string/includes? (str e) "404")))
-          (request-app-tokens!
-           (fn []
-             (clone repo-url true))
-           nil)
-          (do
-            (println "Clone failed, error: ")
-            (js/console.error e)
-            (state/set-cloning! false)
-            (git-handler/set-git-status! repo-url :clone-failed)
-            (git-handler/set-git-error! repo-url e)
-
-            (show-install-error! repo-url (util/format "Failed to clone %s." repo-url)))))))))
+   (p/let [token (helper/get-github-token repo-url)]
+     (when token
+      (util/p-handle
+        (do
+          (state/set-cloning! true)
+          (git/clone repo-url token))
+        (fn [result]
+          (state/set-git-clone-repo! "")
+          (state/set-current-repo! repo-url)
+          (db/start-db-conn! (:me @state/state) repo-url)
+          (db/mark-repo-as-cloned repo-url))
+        (fn [e]
+          (if (and (not fallback?)
+                (or (string/includes? (str e) "401")
+                    (string/includes? (str e) "404")))
+            (helper/request-app-tokens!
+              (fn []
+                (clone repo-url true))
+              nil)
+            (do
+              (println "Clone failed, error: ")
+              (js/console.error e)
+              (state/set-cloning! false)
+              (git-handler/set-git-status! repo-url :clone-failed)
+              (git-handler/set-git-error! repo-url e)
+
+              (show-install-error! repo-url (util/format "Failed to clone %s." repo-url))))))))))
 
 (defn set-config-content!
   [repo path new-config]
@@ -543,18 +509,18 @@
 
 (defn periodically-pull
   [repo-url pull-now?]
-  (when-let [token (state/get-github-token repo-url)]
-    (when pull-now? (pull repo-url token nil))
-    (js/setInterval #(pull repo-url token nil)
-                    (* (config/git-pull-secs) 1000))))
+  (p/let [token (helper/get-github-token repo-url)]
+    (when token
+      (when pull-now? (pull repo-url token nil))
+      (js/setInterval #(pull repo-url token nil)
+        (* (config/git-pull-secs) 1000)))))
 
 (defn periodically-push-tasks
   [repo-url]
-  (let [token (state/get-github-token repo-url)
-        push (fn []
+  (let [push (fn []
                (when (and (not (false? (:git-auto-push (state/get-config repo-url))))
-                          ;; (not config/dev?)
-)
+                       ;; (not config/dev?)
+                       )
                  (push repo-url nil)))]
     (js/setInterval push
                     (* (config/git-push-secs) 1000))))

+ 57 - 0
src/main/frontend/helper.cljs

@@ -0,0 +1,57 @@
+(ns frontend.helper
+  (:require [cljs-time.format :as tf]
+            [cljs-time.core :as t]
+            [frontend.util :as util]
+            [frontend.state :as state]
+            [frontend.config :as config]
+            [promesa.core :as p]))
+
+(defn request-app-tokens!
+  [ok-handler error-handler]
+  (let [repos (:repos (state/get-me))
+        installation-ids (->> (map :installation_id repos)
+                              (remove nil?)
+                              (distinct))]
+    (when (or (seq repos)
+            (seq installation-ids))
+      (util/post (str config/api "refresh_github_token")
+        {:installation-ids installation-ids
+         :repos repos}
+        (fn [result]
+          (state/set-github-installation-tokens! result)
+          (when ok-handler (ok-handler)))
+        (fn [error]
+          (println "Something wrong!")
+          (js/console.dir error)
+          (when error-handler (error-handler)))))))
+
+(defn get-github-token*
+  [repo]
+  (when repo
+    (let [{:keys [token expires_at] :as token-state}
+          (state/get-github-token repo)
+          expires-at (tf/parse (tf/formatters :date-time-no-ms) expires_at)
+          request-time-gap (t/minutes 1)
+          expired? (t/after? (t/now) (t/plus expires-at request-time-gap))]
+      {:expired? expired?
+       :token token})))
+
+(defn get-github-token
+  ([]
+   (get-github-token  (state/get-current-repo)))
+  ([repo]
+   (js/Promise.
+     (fn [resolve reject]
+       (let [{:keys [expired? token]} (get-github-token* repo)]
+        (if-not expired?
+          (resolve token)
+          (request-app-tokens!
+            (fn []
+              (let [{:keys [expired? token]} (get-github-token* repo)]
+                (if-not expired?
+                  (resolve token)
+                  (do (js/console.error "Failed to get GitHub token.")
+                      (reject)))))
+            nil)))))))
+
+

+ 21 - 21
src/main/frontend/state.cljs

@@ -491,36 +491,36 @@
   (storage/set :git/clone-repo repo))
 
 (defn set-github-token!
-  [repo token]
-  (when token
-    (swap! state update-in [:me :repos]
-           (fn [repos]
-             (map (fn [r]
-                    (if (= repo (:url r))
-                      (assoc r :token token)
-                      repo)) repos)))))
+  [repo token-result]
+  (when token-result
+    (let [{:keys [token expires_at]} token-result]
+      (swap! state update-in [:me :repos]
+       (fn [repos]
+         (map (fn [r]
+                (if (= repo (:url r))
+                  (merge r {:token token :expires_at expires_at})
+                  repo)) repos))))))
 
 (defn set-github-installation-tokens!
   [tokens]
   (when (seq tokens)
-    (let [tokens (medley/map-keys name tokens)
+    (let [tokens  (medley/index-by :installation_id tokens)
           repos (get-repos)]
       (when (seq repos)
-        (let [repos (mapv (fn [{:keys [installation_id] :as r}]
-                            (if-let [token (get tokens installation_id)]
-                              (assoc r :token token)
-                              r)) repos)]
+        (let [set-token-f
+              (fn [{:keys [installation_id] :as repo}]
+                (let [{:keys [token expires_at] :as m} (get tokens installation_id)]
+                  (if (and token expires_at)
+                    (merge repo {:token token :expires_at expires_at})
+                    (do (js/conole.log "Can't find token, expires_at key") m))))
+              repos (mapv set-token-f repos)]
           (swap! state assoc-in [:me :repos] repos))))))
 
 (defn get-github-token
-  ([]
-   (get-github-token (get-current-repo)))
-  ([repo]
-   (when repo
-     (let [repos (get-repos)]
-       (-> (filter #(= repo (:url %)) repos)
-           first
-           :token)))))
+  [repo]
+  (when repo
+    (let [repos (get-repos)]
+      (some #(when (= repo (:url %)) %) repos))))
 
 (defn toggle-sidebar-open?!
   []