| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- (ns frontend.handler.user
- (:require [frontend.config :as config]
- [frontend.db :as db]
- [frontend.handler.config :as config-handler]
- [frontend.handler.notification :as notification]
- [frontend.idb :as idb]
- [frontend.state :as state]
- [frontend.util :as util]
- [frontend.debug :as debug]
- [lambdaisland.glogi :as log]
- [promesa.core :as p]))
- (defn set-cors!
- [cors-proxy]
- (util/post (str config/api "cors_proxy")
- {:cors-proxy cors-proxy}
- (fn [_result]
- (db/transact! [{:me/cors_proxy cors-proxy}])
- (swap! state/state assoc-in [:me :cors_proxy] cors-proxy))
- (fn [error]
- (notification/show! "Set cors proxy failed." :error)
- (js/console.dir error))))
- (defn set-preferred-format!
- [format]
- (when format
- (config-handler/set-config! :preferred-format format)
- (state/set-preferred-format! format)
- ;; (when (:name (:me @state/state))
- ;; (when (state/logged?)
- ;; (util/post (str config/api "set_preferred_format")
- ;; {:preferred_format (name format)}
- ;; (fn [_result]
- ;; (notification/show! "Format set successfully!" :success))
- ;; (fn [_e]))))
- ))
- (defn set-preferred-workflow!
- [workflow]
- (when workflow
- (config-handler/set-config! :preferred-workflow workflow)
- (state/set-preferred-workflow! workflow)
- ;; (when (:name (:me @state/state))
- ;; (util/post (str config/api "set_preferred_workflow")
- ;; {:preferred_workflow (name workflow)}
- ;; (fn [_result]
- ;; (notification/show! "Workflow set successfully!" :success))
- ;; (fn [_e])))
- ))
- (defn sign-out!
- {:deprecated "-"}
- ([]
- (sign-out! true))
- ([confirm?]
- (when (or (not confirm?)
- (js/confirm "Your local notes will be completely removed after signing out. Continue?"))
- (->
- (idb/clear-local-storage-and-idb!)
- (p/catch (fn [e]
- (println "sign out error: ")
- (js/console.dir e)))
- (p/finally (fn []
- (set! (.-href js/window.location) "/logout")))))))
- (defn delete-account!
- []
- (p/let [_ (idb/clear-local-storage-and-idb!)]
- (util/delete (str config/api "account")
- (fn []
- (sign-out! false))
- (fn [error]
- (log/error :user/delete-account-failed error)))))
- ;;; userinfo, token, login/logout, ...
- (defn- parse-jwt [jwt]
- (some-> jwt
- (string/split ".")
- (second)
- (js/atob)
- (js/JSON.parse)
- (js->clj :keywordize-keys true)))
- (defn- expired? [parsed-jwt]
- (some->
- (* 1000 (:exp parsed-jwt))
- (tc/from-long)
- (t/before? (t/now))))
- (defn- almost-expired? [parsed-jwt]
- "return true when jwt will expire after 1h"
- (some->
- (* 1000 (:exp parsed-jwt))
- (tc/from-long)
- (t/before? (-> 1 t/hours t/from-now))))
- (defn email []
- (some->
- (state/get-auth-id-token)
- (parse-jwt)
- (:email)))
- (defn logged? []
- (boolean
- (some->
- (state/get-auth-id-token)
- (parse-jwt)
- (expired?)
- (not))))
- (defn- clear-tokens []
- (state/set-auth-id-token nil)
- (state/set-auth-access-token nil)
- (state/set-auth-refresh-token nil))
- (defn- set-tokens!
- ([id-token access-token]
- (state/set-auth-id-token id-token)
- (state/set-auth-access-token access-token))
- ([id-token access-token refresh-token]
- (state/set-auth-id-token id-token)
- (state/set-auth-access-token access-token)
- (state/set-auth-refresh-token refresh-token)))
- (defn login-callback [code]
- (go
- (let [resp (<! (http/get (str "https://api.logseq.com/auth_callback?code=" code)))]
- (if (= 200 (:status resp))
- (-> resp
- (:body)
- (js/JSON.parse)
- (js->clj :keywordize-keys true)
- (as-> $ (set-tokens! (:id_token $) (:access_token $) (:refresh_token $))))
- (debug/pprint "login-callback" resp)))))
- (defn refresh-id-token&access-token []
- "refresh id-token and access-token, if refresh_token expired, clear all tokens
- return true if success, else false"
- (when-let [refresh-token (state/get-auth-refresh-token)]
- (go
- (let [resp (<! (http/get (str "https://api.logseq.com/auth_refresh_token?refresh_token=" refresh-token)))]
- (if (= 400 (:status resp))
- ;; invalid refresh_token
- (do
- (clear-tokens)
- false)
- (do
- (->
- resp
- (as-> $ (and (http/unexceptional-status? (:status $)) $))
- (:body)
- (js/JSON.parse)
- (js->clj :keywordize-keys true)
- (as-> $ (set-tokens! (:id_token $) (:access_token $))))
- true))))))
- ;;; refresh tokens loop
- (def stop-refresh false)
- (defn refresh-tokens-loop []
- (debug/pprint "start refresh-tokens-loop")
- (go-loop []
- (<! (timeout 60000))
- (when-some [refresh-token (state/get-auth-refresh-token)]
- (let [id-token (state/get-auth-id-token)]
- (when (or (nil? id-token)
- (-> id-token (parse-jwt) (almost-expired?)))
- (debug/pprint (str "refresh tokens... " (tc/to-string(t/now))))
- (refresh-id-token&access-token))))
- (when-not stop-refresh
- (recur))))
|