mirror of
https://github.com/logseq/logseq.git
synced 2026-04-28 08:04:40 +00:00
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>
This commit is contained in:
@@ -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?
|
||||
[]
|
||||
|
||||
Reference in New Issue
Block a user