|
2 | 2 | "Auth and endpoint helpers for db sync." |
3 | 3 | (:require [clojure.string :as string] |
4 | 4 | [frontend.worker-common.util :as worker-util] |
5 | | - [logseq.common.util :as common-util] |
6 | | - [promesa.core :as p] |
| 5 | + [frontend.worker.state :as worker-state] |
7 | 6 | [frontend.worker.sync.util :as sync-util] |
8 | | - [frontend.worker.state :as worker-state])) |
| 7 | + [logseq.common.util :as common-util] |
| 8 | + [promesa.core :as p])) |
9 | 9 |
|
10 | 10 | (defn ws-base-url |
11 | 11 | [db-sync-config] |
|
36 | 36 | (catch :default _ |
37 | 37 | true)))) |
38 | 38 |
|
| 39 | +(defn oauth-token-url |
| 40 | + [db-sync-config] |
| 41 | + (or (:oauth-token-url db-sync-config) |
| 42 | + (when-let [domain (not-empty (:oauth-domain db-sync-config))] |
| 43 | + (str "https://" domain "/oauth2/token")))) |
| 44 | + |
| 45 | +(defn <refresh-id&access-token |
| 46 | + [] |
| 47 | + (let [refresh-token (:auth/refresh-token @worker-state/*state) |
| 48 | + db-sync-config @worker-state/*db-sync-config |
| 49 | + token-url (oauth-token-url db-sync-config) |
| 50 | + oauth-client-id (:oauth-client-id db-sync-config)] |
| 51 | + (when-not (seq refresh-token) |
| 52 | + (throw (ex-info "worker auth refresh requires refresh token" |
| 53 | + {:code :missing-refresh-token}))) |
| 54 | + (when-not (seq token-url) |
| 55 | + (throw (ex-info "worker auth refresh requires oauth token url" |
| 56 | + {:code :missing-oauth-token-url}))) |
| 57 | + (when-not (seq oauth-client-id) |
| 58 | + (throw (ex-info "worker auth refresh requires oauth client id" |
| 59 | + {:code :missing-oauth-client-id}))) |
| 60 | + (let [form-data (js/URLSearchParams.)] |
| 61 | + (.set form-data "grant_type" "refresh_token") |
| 62 | + (.set form-data "client_id" oauth-client-id) |
| 63 | + (.set form-data "refresh_token" refresh-token) |
| 64 | + (p/let [resp (js/fetch token-url #js {:method "POST" |
| 65 | + :headers #js {"content-type" "application/x-www-form-urlencoded"} |
| 66 | + :body (.toString form-data)}) |
| 67 | + text (.text resp) |
| 68 | + data (when (seq text) |
| 69 | + (js->clj (js/JSON.parse text) :keywordize-keys true))] |
| 70 | + (if (.-ok resp) |
| 71 | + {:id-token (:id_token data) |
| 72 | + :access-token (:access_token data)} |
| 73 | + (throw (ex-info "worker auth refresh failed" |
| 74 | + {:code :auth-refresh-failed |
| 75 | + :status (.-status resp) |
| 76 | + :token-url token-url |
| 77 | + :body data}))))))) |
| 78 | + |
39 | 79 | (defn <resolve-ws-token |
40 | 80 | [] |
41 | | - (let [token (sync-util/auth-token)] |
42 | | - (if (and (not (sync-util/cli-node-owner?)) |
43 | | - (id-token-expired? token)) |
44 | | - (p/let [resp (worker-state/<invoke-main-thread :thread-api/ensure-id&access-token) |
45 | | - refreshed-token (:id-token resp)] |
46 | | - (when (string? refreshed-token) |
47 | | - (worker-state/set-new-state! {:auth/id-token refreshed-token}) |
48 | | - refreshed-token)) |
| 81 | + (let [token (sync-util/auth-token) |
| 82 | + token-expired? (id-token-expired? token)] |
| 83 | + (if (and (not (sync-util/cli-node-owner?)) token-expired?) |
| 84 | + (p/let [{:keys [id-token access-token]} (<refresh-id&access-token)] |
| 85 | + (when-not (seq id-token) |
| 86 | + (throw (ex-info "worker auth refresh returned empty id-token" |
| 87 | + {:code :auth-refresh-empty-id-token}))) |
| 88 | + (worker-state/set-new-state! |
| 89 | + (cond-> {:auth/id-token id-token} |
| 90 | + (seq access-token) (assoc :auth/access-token access-token))) |
| 91 | + id-token) |
49 | 92 | (p/resolved token)))) |
50 | 93 |
|
51 | 94 | (defn get-user-uuid |
|
0 commit comments