mirror of https://github.com/logseq/logseq
enhance(sync): check token not expired before api-calls (#7267)
* enhance(sync): check token not expired before api-calls * fix(sync): ensure id-token exists when calling user/user-uuid * enhance(sync): add <wrap-ensure-id&access-token, remove refresh-token-loop * fix: check exception before using the result of <user-uuid * fix: notify users ex message instead of ex info Co-authored-by: Tienson Qin <tiensonqin@gmail.com>pull/7279/head
parent
4aeaaeb01e
commit
decd47c8a9
|
@ -370,9 +370,13 @@
|
|||
(state/pub-event! [:file-sync/onboarding-tip :unavailable])
|
||||
|
||||
;; current graph belong to other user, do nothing
|
||||
(and (first @graphs-txid)
|
||||
(not (fs-sync/check-graph-belong-to-current-user (user-handler/user-uuid)
|
||||
(first @graphs-txid))))
|
||||
(let [user-uuid (async/<! (user-handler/<user-uuid))
|
||||
user-uuid (when-not (instance? ExceptionInfo user-uuid) user-uuid)]
|
||||
(and (first @graphs-txid)
|
||||
user-uuid
|
||||
(not (fs-sync/check-graph-belong-to-current-user
|
||||
user-uuid
|
||||
(first @graphs-txid)))))
|
||||
nil
|
||||
|
||||
(and synced-file-graph?
|
||||
|
|
|
@ -278,8 +278,8 @@
|
|||
"max retry count is 5.
|
||||
*stop: volatile var, stop retry-request when it's true,
|
||||
and return :stop"
|
||||
([api-name body token refresh-token-fn *stop] (<request* api-name body token refresh-token-fn 0 *stop))
|
||||
([api-name body token refresh-token-fn retry-count *stop]
|
||||
([api-name body token *stop] (<request* api-name body token 0 *stop))
|
||||
([api-name body token retry-count *stop]
|
||||
(go
|
||||
(if (and *stop @*stop (contains? stoppable-apis api-name))
|
||||
:stop
|
||||
|
@ -291,8 +291,7 @@
|
|||
(throw (js/Error. :file-sync-request))
|
||||
(do (println "will retry after" (min 60000 (* 1000 retry-count)) "ms")
|
||||
(<! (timeout (min 60000 (* 1000 retry-count))))
|
||||
(let [token (<! (refresh-token-fn))]
|
||||
(<! (<request* api-name body token refresh-token-fn (inc retry-count) *stop)))))
|
||||
(<! (<request* api-name body token (inc retry-count) *stop))))
|
||||
(:resp resp)))))))
|
||||
|
||||
(defn <request [api-name & args]
|
||||
|
@ -721,8 +720,7 @@
|
|||
(<upload-graph-encrypt-keys [this graph-uuid public-key encrypted-private-key]))
|
||||
|
||||
(defprotocol IToken
|
||||
(<get-token [this])
|
||||
(<refresh-token [this]))
|
||||
(<get-token [this]))
|
||||
|
||||
|
||||
(defn <case-different-local-file-exist?
|
||||
|
@ -767,14 +765,9 @@
|
|||
|
||||
(deftype RSAPI [^:mutable graph-uuid' ^:mutable private-key' ^:mutable public-key']
|
||||
IToken
|
||||
(<get-token [this]
|
||||
(go
|
||||
(or (state/get-auth-id-token)
|
||||
(<! (<refresh-token this)))))
|
||||
(<refresh-token [_]
|
||||
(go
|
||||
(<! (user/<refresh-id-token&access-token))
|
||||
(state/get-auth-id-token)))
|
||||
(<get-token [_this]
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(state/get-auth-id-token)))
|
||||
|
||||
IRSAPI
|
||||
(rsapi-ready? [_ graph-uuid] (and (= graph-uuid graph-uuid') private-key' public-key'))
|
||||
|
@ -855,14 +848,9 @@
|
|||
|
||||
(deftype ^:large-vars/cleanup-todo CapacitorAPI [^:mutable graph-uuid' ^:mutable private-key ^:mutable public-key']
|
||||
IToken
|
||||
(<get-token [this]
|
||||
(go
|
||||
(or (state/get-auth-id-token)
|
||||
(<! (<refresh-token this)))))
|
||||
(<refresh-token [_]
|
||||
(go
|
||||
(<! (user/<refresh-id-token&access-token))
|
||||
(state/get-auth-id-token)))
|
||||
(<get-token [_this]
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(state/get-auth-id-token)))
|
||||
|
||||
IRSAPI
|
||||
(rsapi-ready? [_ graph-uuid] (and (= graph-uuid graph-uuid') private-key public-key'))
|
||||
|
@ -1128,7 +1116,7 @@
|
|||
|
||||
(<request [this api-name body]
|
||||
(go
|
||||
(let [resp (<! (<request api-name body (<! (<get-token this)) #(<refresh-token this) *stopped?))]
|
||||
(let [resp (<! (<request api-name body (<! (<get-token this)) *stopped?))]
|
||||
(if (http/unexceptional-status? (:status resp))
|
||||
(get-resp-json-body resp)
|
||||
(let [exp (ex-info "request failed"
|
||||
|
@ -1147,186 +1135,189 @@
|
|||
(.<request this "update_files" {:GraphUUID graph-uuid :TXId txid :Files files}))
|
||||
|
||||
IToken
|
||||
(<get-token [this]
|
||||
(go
|
||||
(or (state/get-auth-id-token)
|
||||
(<! (<refresh-token this)))))
|
||||
|
||||
(<refresh-token [_]
|
||||
(go
|
||||
(<! (user/<refresh-id-token&access-token))
|
||||
(state/get-auth-id-token))))
|
||||
(<get-token [_this]
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(state/get-auth-id-token))))
|
||||
|
||||
(extend-type RemoteAPI
|
||||
IRemoteAPI
|
||||
(<user-info [this] (.<request this "user_info" {}))
|
||||
(<user-info [this]
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "user_info" {}))))
|
||||
(<get-remote-all-files-meta [this graph-uuid]
|
||||
(go
|
||||
(let [file-meta-list (transient #{})
|
||||
encrypted-path-list (transient [])
|
||||
exp-r
|
||||
(<!
|
||||
(go-loop [continuation-token nil]
|
||||
(let [r (<! (.<request this "get_all_files"
|
||||
(into
|
||||
{}
|
||||
(remove (comp nil? second)
|
||||
{:GraphUUID graph-uuid :ContinuationToken continuation-token}))))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [next-continuation-token (:NextContinuationToken r)
|
||||
objs (:Objects r)]
|
||||
(apply conj! encrypted-path-list (map (comp remove-user-graph-uuid-prefix :Key) objs))
|
||||
(apply conj! file-meta-list
|
||||
(map
|
||||
#(hash-map :checksum (:checksum %)
|
||||
:encrypted-path (remove-user-graph-uuid-prefix (:Key %))
|
||||
:size (:Size %)
|
||||
:last-modified (:LastModified %))
|
||||
objs))
|
||||
(when-not (empty? next-continuation-token)
|
||||
(recur next-continuation-token)))))))]
|
||||
(if (instance? ExceptionInfo exp-r)
|
||||
exp-r
|
||||
(let [file-meta-list* (persistent! file-meta-list)
|
||||
encrypted-path-list* (persistent! encrypted-path-list)
|
||||
path-list-or-exp (<! (<decrypt-fnames rsapi graph-uuid encrypted-path-list*))]
|
||||
(if (instance? ExceptionInfo path-list-or-exp)
|
||||
path-list-or-exp
|
||||
(let [encrypted-path->path-map (zipmap encrypted-path-list* path-list-or-exp)]
|
||||
(set
|
||||
(mapv
|
||||
#(->FileMetadata (:size %)
|
||||
(:checksum %)
|
||||
(get encrypted-path->path-map (:encrypted-path %))
|
||||
(:encrypted-path %)
|
||||
(:last-modified %)
|
||||
true nil)
|
||||
file-meta-list*)))))))))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(let [file-meta-list (transient #{})
|
||||
encrypted-path-list (transient [])
|
||||
exp-r
|
||||
(<!
|
||||
(go-loop [continuation-token nil]
|
||||
(let [r (<! (.<request this "get_all_files"
|
||||
(into
|
||||
{}
|
||||
(remove (comp nil? second)
|
||||
{:GraphUUID graph-uuid :ContinuationToken continuation-token}))))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [next-continuation-token (:NextContinuationToken r)
|
||||
objs (:Objects r)]
|
||||
(apply conj! encrypted-path-list (map (comp remove-user-graph-uuid-prefix :Key) objs))
|
||||
(apply conj! file-meta-list
|
||||
(map
|
||||
#(hash-map :checksum (:checksum %)
|
||||
:encrypted-path (remove-user-graph-uuid-prefix (:Key %))
|
||||
:size (:Size %)
|
||||
:last-modified (:LastModified %))
|
||||
objs))
|
||||
(when-not (empty? next-continuation-token)
|
||||
(recur next-continuation-token)))))))]
|
||||
(if (instance? ExceptionInfo exp-r)
|
||||
exp-r
|
||||
(let [file-meta-list* (persistent! file-meta-list)
|
||||
encrypted-path-list* (persistent! encrypted-path-list)
|
||||
path-list-or-exp (<! (<decrypt-fnames rsapi graph-uuid encrypted-path-list*))]
|
||||
(if (instance? ExceptionInfo path-list-or-exp)
|
||||
path-list-or-exp
|
||||
(let [encrypted-path->path-map (zipmap encrypted-path-list* path-list-or-exp)]
|
||||
(set
|
||||
(mapv
|
||||
#(->FileMetadata (:size %)
|
||||
(:checksum %)
|
||||
(get encrypted-path->path-map (:encrypted-path %))
|
||||
(:encrypted-path %)
|
||||
(:last-modified %)
|
||||
true nil)
|
||||
file-meta-list*)))))))))
|
||||
|
||||
(<get-remote-files-meta [this graph-uuid filepaths]
|
||||
{:pre [(coll? filepaths)]}
|
||||
(go
|
||||
(let [encrypted-paths* (<! (<encrypt-fnames rsapi graph-uuid filepaths))
|
||||
r (<! (.<request this "get_files_meta" {:GraphUUID graph-uuid :Files encrypted-paths*}))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [encrypted-paths (mapv :FilePath r)
|
||||
paths-or-exp (<! (<decrypt-fnames rsapi graph-uuid encrypted-paths))]
|
||||
(if (instance? ExceptionInfo paths-or-exp)
|
||||
paths-or-exp
|
||||
(let [encrypted-path->path-map (zipmap encrypted-paths paths-or-exp)]
|
||||
(into #{}
|
||||
(comp
|
||||
(filter #(not= "filepath too long" (:Error %)))
|
||||
(map #(->FileMetadata (:Size %)
|
||||
(:Checksum %)
|
||||
(get encrypted-path->path-map (:FilePath %))
|
||||
(:FilePath %)
|
||||
(:LastModified %)
|
||||
true nil)))
|
||||
r))))))))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(let [encrypted-paths* (<! (<encrypt-fnames rsapi graph-uuid filepaths))
|
||||
r (<! (.<request this "get_files_meta" {:GraphUUID graph-uuid :Files encrypted-paths*}))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [encrypted-paths (mapv :FilePath r)
|
||||
paths-or-exp (<! (<decrypt-fnames rsapi graph-uuid encrypted-paths))]
|
||||
(if (instance? ExceptionInfo paths-or-exp)
|
||||
paths-or-exp
|
||||
(let [encrypted-path->path-map (zipmap encrypted-paths paths-or-exp)]
|
||||
(into #{}
|
||||
(comp
|
||||
(filter #(not= "filepath too long" (:Error %)))
|
||||
(map #(->FileMetadata (:Size %)
|
||||
(:Checksum %)
|
||||
(get encrypted-path->path-map (:FilePath %))
|
||||
(:FilePath %)
|
||||
(:LastModified %)
|
||||
true nil)))
|
||||
r))))))))
|
||||
|
||||
(<get-remote-graph [this graph-name-opt graph-uuid-opt]
|
||||
{:pre [(or graph-name-opt graph-uuid-opt)]}
|
||||
(.<request this "get_graph" (cond-> {}
|
||||
(seq graph-name-opt)
|
||||
(assoc :GraphName graph-name-opt)
|
||||
(seq graph-uuid-opt)
|
||||
(assoc :GraphUUID graph-uuid-opt))))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "get_graph" (cond-> {}
|
||||
(seq graph-name-opt)
|
||||
(assoc :GraphName graph-name-opt)
|
||||
(seq graph-uuid-opt)
|
||||
(assoc :GraphUUID graph-uuid-opt))))))
|
||||
|
||||
(<get-remote-file-versions [this graph-uuid filepath]
|
||||
(go
|
||||
(let [encrypted-path (first (<! (<encrypt-fnames rsapi graph-uuid [filepath])))]
|
||||
(<! (.<request this "get_file_version_list" {:GraphUUID graph-uuid :File encrypted-path})))))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(let [encrypted-path (first (<! (<encrypt-fnames rsapi graph-uuid [filepath])))]
|
||||
(<! (.<request this "get_file_version_list" {:GraphUUID graph-uuid :File encrypted-path})))))
|
||||
|
||||
(<list-remote-graphs [this]
|
||||
(.<request this "list_graphs"))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "list_graphs"))))
|
||||
|
||||
(<get-deletion-logs [this graph-uuid from-txid]
|
||||
(go
|
||||
(let [r (<! (.<request this "get_deletion_log" {:GraphUUID graph-uuid :FromTXId from-txid}))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [txns-with-encrypted-paths (mapv #(update % :path remove-user-graph-uuid-prefix) (:Transactions r))
|
||||
encrypted-paths (mapv :path txns-with-encrypted-paths)
|
||||
encrypted-path->path-map
|
||||
(zipmap
|
||||
encrypted-paths
|
||||
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
|
||||
txns
|
||||
(mapv
|
||||
(fn [txn] (update txn :path #(get encrypted-path->path-map %)))
|
||||
txns-with-encrypted-paths)]
|
||||
txns)))))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(let [r (<! (.<request this "get_deletion_log" {:GraphUUID graph-uuid :FromTXId from-txid}))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [txns-with-encrypted-paths (mapv #(update % :path remove-user-graph-uuid-prefix) (:Transactions r))
|
||||
encrypted-paths (mapv :path txns-with-encrypted-paths)
|
||||
encrypted-path->path-map
|
||||
(zipmap
|
||||
encrypted-paths
|
||||
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
|
||||
txns
|
||||
(mapv
|
||||
(fn [txn] (update txn :path #(get encrypted-path->path-map %)))
|
||||
txns-with-encrypted-paths)]
|
||||
txns)))))
|
||||
|
||||
(<get-diff [this graph-uuid from-txid]
|
||||
;; TODO: path in transactions should be relative path(now s3 key, which includes graph-uuid and user-uuid)
|
||||
(go
|
||||
(let [r (<! (.<request this "get_diff" {:GraphUUID graph-uuid :FromTXId from-txid}))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [txns-with-encrypted-paths (sort-by :TXId (:Transactions r))
|
||||
txns-with-encrypted-paths*
|
||||
(mapv
|
||||
(fn [txn]
|
||||
(assoc txn :TXContent
|
||||
(mapv
|
||||
(fn [[to-path from-path checksum]]
|
||||
[(remove-user-graph-uuid-prefix to-path)
|
||||
(some-> from-path remove-user-graph-uuid-prefix)
|
||||
checksum])
|
||||
(:TXContent txn))))
|
||||
txns-with-encrypted-paths)
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(let [r (<! (.<request this "get_diff" {:GraphUUID graph-uuid :FromTXId from-txid}))]
|
||||
(if (instance? ExceptionInfo r)
|
||||
r
|
||||
(let [txns-with-encrypted-paths (sort-by :TXId (:Transactions r))
|
||||
txns-with-encrypted-paths*
|
||||
(mapv
|
||||
(fn [txn]
|
||||
(assoc txn :TXContent
|
||||
(mapv
|
||||
(fn [[to-path from-path checksum]]
|
||||
[(remove-user-graph-uuid-prefix to-path)
|
||||
(some-> from-path remove-user-graph-uuid-prefix)
|
||||
checksum])
|
||||
(:TXContent txn))))
|
||||
txns-with-encrypted-paths)
|
||||
encrypted-paths
|
||||
(mapcat
|
||||
(fn [txn]
|
||||
(remove
|
||||
#(or (nil? %) (not (string/starts-with? % "e.")))
|
||||
(mapcat
|
||||
(fn [[to-path from-path _checksum]] [to-path from-path])
|
||||
(:TXContent txn))))
|
||||
txns-with-encrypted-paths*)
|
||||
encrypted-path->path-map
|
||||
(zipmap
|
||||
encrypted-paths
|
||||
(mapcat
|
||||
(fn [txn]
|
||||
(remove
|
||||
#(or (nil? %) (not (string/starts-with? % "e.")))
|
||||
(mapcat
|
||||
(fn [[to-path from-path _checksum]] [to-path from-path])
|
||||
(:TXContent txn))))
|
||||
txns-with-encrypted-paths*)
|
||||
encrypted-path->path-map
|
||||
(zipmap
|
||||
encrypted-paths
|
||||
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
|
||||
txns
|
||||
(mapv
|
||||
(fn [txn]
|
||||
(assoc
|
||||
txn :TXContent
|
||||
(mapv
|
||||
(fn [[to-path from-path checksum]]
|
||||
[(get encrypted-path->path-map to-path to-path)
|
||||
(some->> from-path (get encrypted-path->path-map))
|
||||
checksum])
|
||||
(:TXContent txn))))
|
||||
txns-with-encrypted-paths*)]
|
||||
[txns
|
||||
(:TXId (last txns))
|
||||
(:TXId (first txns))])))))
|
||||
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
|
||||
txns
|
||||
(mapv
|
||||
(fn [txn]
|
||||
(assoc
|
||||
txn :TXContent
|
||||
(mapv
|
||||
(fn [[to-path from-path checksum]]
|
||||
[(get encrypted-path->path-map to-path to-path)
|
||||
(some->> from-path (get encrypted-path->path-map))
|
||||
checksum])
|
||||
(:TXContent txn))))
|
||||
txns-with-encrypted-paths*)]
|
||||
[txns
|
||||
(:TXId (last txns))
|
||||
(:TXId (first txns))])))))
|
||||
|
||||
(<create-graph [this graph-name]
|
||||
(.<request this "create_graph" {:GraphName graph-name}))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "create_graph" {:GraphName graph-name}))))
|
||||
|
||||
(<delete-graph [this graph-uuid]
|
||||
(.<request this "delete_graph" {:GraphUUID graph-uuid}))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "delete_graph" {:GraphUUID graph-uuid}))))
|
||||
|
||||
(<get-graph-salt [this graph-uuid]
|
||||
(.<request this "get_graph_salt" {:GraphUUID graph-uuid}))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "get_graph_salt" {:GraphUUID graph-uuid}))))
|
||||
|
||||
(<create-graph-salt [this graph-uuid]
|
||||
(.<request this "create_graph_salt" {:GraphUUID graph-uuid}))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "create_graph_salt" {:GraphUUID graph-uuid}))))
|
||||
|
||||
(<get-graph-encrypt-keys [this graph-uuid]
|
||||
(.<request this "get_graph_encrypt_keys" {:GraphUUID graph-uuid}))
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "get_graph_encrypt_keys" {:GraphUUID graph-uuid}))))
|
||||
|
||||
(<upload-graph-encrypt-keys [this graph-uuid public-key encrypted-private-key]
|
||||
(.<request this "upload_graph_encrypt_keys" {:GraphUUID graph-uuid
|
||||
:public-key public-key
|
||||
:encrypted-private-key encrypted-private-key})))
|
||||
|
||||
(user/<wrap-ensure-id&access-token
|
||||
(<! (.<request this "upload_graph_encrypt_keys" {:GraphUUID graph-uuid
|
||||
:public-key public-key
|
||||
:encrypted-private-key encrypted-private-key})))))
|
||||
|
||||
(def remoteapi (->RemoteAPI nil))
|
||||
|
||||
|
@ -3049,43 +3040,44 @@
|
|||
(when (false? @*sync-entered?)
|
||||
(reset! *sync-entered? true)
|
||||
(let [*sync-state (atom (sync-state))
|
||||
current-user-uuid (user/user-uuid)
|
||||
current-user-uuid (<! (user/<user-uuid))
|
||||
;; put @graph-uuid & get-current-repo together,
|
||||
;; prevent to get older repo dir and current graph-uuid.
|
||||
_ (<! (p->c (persist-var/-load graphs-txid)))
|
||||
[user-uuid graph-uuid txid] @graphs-txid
|
||||
txid (or txid 0)
|
||||
repo (state/get-current-repo)]
|
||||
(when (and repo
|
||||
(graph-sync-off? repo) @network-online-cursor
|
||||
user-uuid graph-uuid txid
|
||||
(user/logged-in?)
|
||||
(not (config/demo-graph? repo)))
|
||||
(try
|
||||
(when-let [sm (sync-manager-singleton current-user-uuid graph-uuid
|
||||
(config/get-repo-dir repo) repo
|
||||
txid *sync-state)]
|
||||
(when (check-graph-belong-to-current-user current-user-uuid user-uuid)
|
||||
(if-not (<! (<check-remote-graph-exists graph-uuid)) ; remote graph has been deleted
|
||||
(clear-graphs-txid! repo)
|
||||
(do
|
||||
(state/set-file-sync-state graph-uuid @*sync-state)
|
||||
(state/set-file-sync-manager graph-uuid sm)
|
||||
(when-not (instance? ExceptionInfo current-user-uuid)
|
||||
(when (and repo
|
||||
(graph-sync-off? repo) @network-online-cursor
|
||||
user-uuid graph-uuid txid
|
||||
(user/logged-in?)
|
||||
(not (config/demo-graph? repo)))
|
||||
(try
|
||||
(when-let [sm (sync-manager-singleton current-user-uuid graph-uuid
|
||||
(config/get-repo-dir repo) repo
|
||||
txid *sync-state)]
|
||||
(when (check-graph-belong-to-current-user current-user-uuid user-uuid)
|
||||
(if-not (<! (<check-remote-graph-exists graph-uuid)) ; remote graph has been deleted
|
||||
(clear-graphs-txid! repo)
|
||||
(do
|
||||
(state/set-file-sync-state graph-uuid @*sync-state)
|
||||
(state/set-file-sync-manager graph-uuid sm)
|
||||
|
||||
;; update global state when *sync-state changes
|
||||
(add-watch *sync-state ::update-global-state
|
||||
(fn [_ _ _ n]
|
||||
(state/set-file-sync-state graph-uuid n)))
|
||||
;; update global state when *sync-state changes
|
||||
(add-watch *sync-state ::update-global-state
|
||||
(fn [_ _ _ n]
|
||||
(state/set-file-sync-state graph-uuid n)))
|
||||
|
||||
(state/set-state! [:file-sync/graph-state :current-graph-uuid] graph-uuid)
|
||||
(state/set-state! [:file-sync/graph-state :current-graph-uuid] graph-uuid)
|
||||
|
||||
(.start sm)
|
||||
(.start sm)
|
||||
|
||||
(offer! remote->local-full-sync-chan true)
|
||||
(offer! full-sync-chan true)))))
|
||||
(catch :default e
|
||||
(prn "Sync start error: ")
|
||||
(log/error :exception e))))
|
||||
(offer! remote->local-full-sync-chan true)
|
||||
(offer! full-sync-chan true)))))
|
||||
(catch :default e
|
||||
(prn "Sync start error: ")
|
||||
(log/error :exception e)))))
|
||||
(reset! *sync-entered? false)))))
|
||||
|
||||
;;; ### some add-watches
|
||||
|
|
|
@ -236,7 +236,6 @@
|
|||
(el/listen!))
|
||||
(persist-var/load-vars)
|
||||
(user-handler/restore-tokens-from-localstorage)
|
||||
(user-handler/refresh-tokens-loop)
|
||||
(js/setTimeout instrument! (* 60 1000)))
|
||||
|
||||
(defn stop! []
|
||||
|
|
|
@ -44,28 +44,33 @@
|
|||
[name]
|
||||
(go
|
||||
(let [r* (<! (sync/<create-graph sync/remoteapi name))
|
||||
r (if (instance? ExceptionInfo r*) r* (:GraphUUID r*))]
|
||||
(if (and (not (instance? ExceptionInfo r))
|
||||
(string? r))
|
||||
(let [tx-info [0 r (user/user-uuid) (state/get-current-repo)]]
|
||||
(<! (apply sync/<update-graphs-txid! tx-info))
|
||||
(swap! refresh-file-sync-component not)
|
||||
tx-info)
|
||||
(do
|
||||
(state/set-state! [:ui/loading? :graph/create-remote?] false)
|
||||
(cond
|
||||
;; already processed this exception by events
|
||||
;; - :file-sync/storage-exceed-limit
|
||||
;; - :file-sync/graph-count-exceed-limit
|
||||
(or (sync/storage-exceed-limit? r)
|
||||
(sync/graph-count-exceed-limit? r))
|
||||
nil
|
||||
user-uuid-or-exp (<! (user/<user-uuid))
|
||||
r (if (instance? ExceptionInfo r*) r*
|
||||
(if (instance? ExceptionInfo user-uuid-or-exp)
|
||||
user-uuid-or-exp
|
||||
(:GraphUUID r*)))]
|
||||
(when-not (instance? ExceptionInfo user-uuid-or-exp)
|
||||
(if (and (not (instance? ExceptionInfo r))
|
||||
(string? r))
|
||||
(let [tx-info [0 r user-uuid-or-exp (state/get-current-repo)]]
|
||||
(<! (apply sync/<update-graphs-txid! tx-info))
|
||||
(swap! refresh-file-sync-component not)
|
||||
tx-info)
|
||||
(do
|
||||
(state/set-state! [:ui/loading? :graph/create-remote?] false)
|
||||
(cond
|
||||
;; already processed this exception by events
|
||||
;; - :file-sync/storage-exceed-limit
|
||||
;; - :file-sync/graph-count-exceed-limit
|
||||
(or (sync/storage-exceed-limit? r)
|
||||
(sync/graph-count-exceed-limit? r))
|
||||
nil
|
||||
|
||||
(contains? #{400 404} (get-in (ex-data r) [:err :status]))
|
||||
(notification/show! (str "Create graph failed: already existed graph: " name) :warning true nil 4000)
|
||||
(contains? #{400 404} (get-in (ex-data r) [:err :status]))
|
||||
(notification/show! (str "Create graph failed: already existed graph: " name) :warning true nil 4000)
|
||||
|
||||
:else
|
||||
(notification/show! (str "Create graph failed:" r) :warning true nil 4000)))))))
|
||||
:else
|
||||
(notification/show! (str "Create graph failed: " (ex-message r)) :warning true nil 4000))))))))
|
||||
|
||||
(defn <delete-graph
|
||||
[graph-uuid]
|
||||
|
@ -100,11 +105,14 @@
|
|||
(defn init-graph [graph-uuid]
|
||||
(go
|
||||
(let [repo (state/get-current-repo)
|
||||
user-uuid (user/user-uuid)]
|
||||
(state/set-state! :sync-graph/init? true)
|
||||
(<! (sync/<update-graphs-txid! 0 graph-uuid user-uuid repo))
|
||||
(swap! refresh-file-sync-component not)
|
||||
(state/pub-event! [:graph/switch repo {:persist? false}]))))
|
||||
user-uuid-or-exp (<! (user/<user-uuid))]
|
||||
(if (instance? ExceptionInfo user-uuid-or-exp)
|
||||
(notification/show! (ex-message user-uuid-or-exp) :error)
|
||||
(do
|
||||
(state/set-state! :sync-graph/init? true)
|
||||
(<! (sync/<update-graphs-txid! 0 graph-uuid user-uuid-or-exp repo))
|
||||
(swap! refresh-file-sync-component not)
|
||||
(state/pub-event! [:graph/switch repo {:persist? false}]))))))
|
||||
|
||||
(defn download-version-file
|
||||
([graph-uuid file-uuid version-uuid]
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
(ns frontend.handler.user
|
||||
"Macros.")
|
||||
|
||||
(defmacro <wrap-ensure-id&access-token
|
||||
[& body]
|
||||
`(cljs.core.async/go
|
||||
(if-some [exp# (cljs.core.async/<! (<ensure-id&access-token))]
|
||||
exp#
|
||||
(do ~@body))))
|
|
@ -1,5 +1,6 @@
|
|||
(ns frontend.handler.user
|
||||
"Provides user related handler fns like login and logout"
|
||||
(:require-macros [frontend.handler.user])
|
||||
(:require [frontend.config :as config]
|
||||
[frontend.handler.config :as config-handler]
|
||||
[frontend.state :as state]
|
||||
|
@ -8,7 +9,7 @@
|
|||
[cljs-time.core :as t]
|
||||
[cljs-time.coerce :as tc]
|
||||
[cljs-http.client :as http]
|
||||
[cljs.core.async :as async :refer [go go-loop <! timeout]]))
|
||||
[cljs.core.async :as async :refer [go <!]]))
|
||||
|
||||
(defn set-preferred-format!
|
||||
[format]
|
||||
|
@ -57,19 +58,14 @@
|
|||
parse-jwt
|
||||
:email))
|
||||
|
||||
(defn user-uuid []
|
||||
(defn- user-uuid []
|
||||
(some->
|
||||
(state/get-auth-id-token)
|
||||
parse-jwt
|
||||
:sub))
|
||||
|
||||
(defn logged-in? []
|
||||
(boolean
|
||||
(some->
|
||||
(state/get-auth-id-token)
|
||||
parse-jwt
|
||||
expired?
|
||||
not)))
|
||||
(some? (state/get-auth-refresh-token)))
|
||||
|
||||
(defn- set-token-to-localstorage!
|
||||
([id-token access-token]
|
||||
|
@ -83,12 +79,19 @@
|
|||
(js/localStorage.setItem "refresh-token" refresh-token)))
|
||||
|
||||
(defn- clear-tokens
|
||||
[]
|
||||
(state/set-auth-id-token nil)
|
||||
(state/set-auth-access-token nil)
|
||||
(state/set-auth-refresh-token nil)
|
||||
(set-token-to-localstorage! "" "" ""))
|
||||
|
||||
([]
|
||||
(state/set-auth-id-token nil)
|
||||
(state/set-auth-access-token nil)
|
||||
(state/set-auth-refresh-token nil)
|
||||
(set-token-to-localstorage! "" "" ""))
|
||||
([except-refresh-token?]
|
||||
(state/set-auth-id-token nil)
|
||||
(state/set-auth-access-token nil)
|
||||
(when-not except-refresh-token?
|
||||
(state/set-auth-refresh-token nil))
|
||||
(if except-refresh-token?
|
||||
(set-token-to-localstorage! "" "")
|
||||
(set-token-to-localstorage! "" "" ""))))
|
||||
|
||||
(defn- set-tokens!
|
||||
([id-token access-token]
|
||||
|
@ -109,8 +112,25 @@
|
|||
(when-let [refresh-token (state/get-auth-refresh-token)]
|
||||
(let [resp (<! (http/get (str "https://" config/API-DOMAIN "/auth_refresh_token?refresh_token=" refresh-token)
|
||||
{:with-credentials? false}))]
|
||||
(cond
|
||||
(and (<= 400 (:status resp))
|
||||
(> 500 (:status resp)))
|
||||
;; invalid refresh-token
|
||||
(clear-tokens)
|
||||
|
||||
;; e.g. api return 500, server internal error
|
||||
;; we shouldn't clear tokens if they aren't expired yet
|
||||
;; the `refresh-tokens-loop` will retry soon
|
||||
(and (not (http/unexceptional-status? (:status resp)))
|
||||
(not (-> (state/get-auth-id-token) parse-jwt expired?)))
|
||||
nil ; do nothing
|
||||
|
||||
(not (http/unexceptional-status? (:status resp)))
|
||||
(clear-tokens true)
|
||||
|
||||
:else ; ok
|
||||
(when (and (:id_token (:body resp)) (:access_token (:body resp)))
|
||||
(set-tokens! (:id_token (:body resp)) (:access_token (:body resp))))))))
|
||||
(set-tokens! (:id_token (:body resp)) (:access_token (:body resp)))))))))
|
||||
|
||||
(defn restore-tokens-from-localstorage
|
||||
"Restore id-token, access-token, refresh-token from localstorage,
|
||||
|
@ -148,22 +168,25 @@
|
|||
(clear-tokens)
|
||||
(state/pub-event! [:user/logout]))
|
||||
|
||||
(defn <ensure-id&access-token
|
||||
[]
|
||||
(go
|
||||
(when (or (nil? (state/get-auth-id-token))
|
||||
(-> (state/get-auth-id-token) parse-jwt almost-expired-or-expired?))
|
||||
(debug/pprint (str "refresh tokens... " (tc/to-string (t/now))))
|
||||
(<! (<refresh-id-token&access-token))
|
||||
(when (or (nil? (state/get-auth-id-token))
|
||||
(-> (state/get-auth-id-token) parse-jwt expired?))
|
||||
(ex-info "empty or expired token and refresh failed" {})))))
|
||||
|
||||
(defn <user-uuid
|
||||
[]
|
||||
(go
|
||||
(if-some [exp (<! (<ensure-id&access-token))]
|
||||
exp
|
||||
(user-uuid))))
|
||||
|
||||
;;; refresh tokens loop
|
||||
(def stop-refresh false)
|
||||
(defn refresh-tokens-loop []
|
||||
(debug/pprint "start refresh-tokens-loop")
|
||||
(go-loop []
|
||||
(<! (timeout 60000))
|
||||
(when (state/get-auth-refresh-token)
|
||||
(let [id-token (state/get-auth-id-token)]
|
||||
(when (or (nil? id-token)
|
||||
(-> id-token (parse-jwt) (almost-expired-or-expired?)))
|
||||
(debug/pprint (str "refresh tokens... " (tc/to-string(t/now))))
|
||||
(<! (<refresh-id-token&access-token)))))
|
||||
(when-not stop-refresh
|
||||
(recur))))
|
||||
;;; user groups
|
||||
|
||||
(defn alpha-user?
|
||||
[]
|
||||
|
|
Loading…
Reference in New Issue