Skip to content

Commit 498f759

Browse files
committed
feat(auth): refactor to use core.async (wip)
1 parent 4db0dc6 commit 498f759

File tree

1 file changed

+121
-54
lines changed

1 file changed

+121
-54
lines changed

src/main/parts/frontend/components/auth.cljs

+121-54
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,85 @@
11
(ns parts.frontend.components.auth
22
(:require
33
[uix.core :refer [defui $ use-state use-effect use-callback]]
4-
[cljs.core.async :refer [<!]]
4+
[cljs.core.async :refer [<! chan]]
55
[parts.frontend.context :as ctx]
6-
[parts.frontend.utils.api :as api]
6+
[parts.frontend.api.core :as api]
7+
[parts.frontend.utils.api :as utils] ;; Still need for token storage functions
78
[parts.frontend.components.modal :refer [modal]])
89
(:require-macros
910
[cljs.core.async.macros :refer [go]]))
1011

12+
;; Auth-specific API operations using core API functions
13+
(defn login-user [email password csrf-token]
14+
(let [result-chan (chan)]
15+
;; Create the request
16+
(api/create-entity "/auth/login"
17+
{:email email
18+
:password password
19+
:__anti-forgery-token csrf-token})
20+
21+
;; Wait for the response on the event channel
22+
(go
23+
(loop []
24+
(let [event (<! api/event-channel)]
25+
(cond
26+
;; Success event for our login
27+
(and (= (:event event) :api-success)
28+
(= (:type event) :create-entity))
29+
(do
30+
(js/console.log "Got login success event" event)
31+
(put! result-chan {:success true :data (:data event)}))
32+
33+
;; Error event for our login
34+
(and (= (:event event) :api-error)
35+
(= (:type (:error event)) :create-entity))
36+
(do
37+
(js/console.log "Got login error event" event)
38+
(put! result-chan {:success false :error (:message (:error event))}))
39+
40+
;; Neither success nor error yet, keep waiting
41+
:else
42+
(recur)))))
43+
44+
result-chan))
45+
46+
(defn logout-user []
47+
(let [result-chan (chan)
48+
tokens (utils/get-tokens)]
49+
50+
(when tokens
51+
;; Create the logout request
52+
(api/create-entity "/auth/logout"
53+
{:refresh_token (:refresh_token tokens)
54+
:__anti-forgery-token (utils/get-csrf-token)})
55+
56+
;; Wait for response on event channel
57+
(go
58+
(loop []
59+
(let [event (<! api/event-channel)]
60+
(when (or (and (= (:event event) :api-success)
61+
(= (:type event) :create-entity))
62+
(and (= (:event event) :api-error)
63+
(= (:type (:error event)) :create-entity)))
64+
;; Success or error, either way we're logged out
65+
(put! result-chan {:success true}))
66+
67+
;; Keep waiting
68+
(recur)))))
69+
70+
;; If no tokens, just return success
71+
(when-not tokens
72+
(put! result-chan {:success true}))
73+
74+
result-chan))
75+
76+
(defn get-user-info []
77+
(let [result-chan (chan)]
78+
(go
79+
(let [user-data (<! (api/fetch-data "/account"))]
80+
(put! result-chan user-data)))
81+
result-chan))
82+
1183
(defui auth-provider [{:keys [children]}]
1284
(let [[auth-state set-auth-state] (use-state
1385
{:logged-in false
@@ -16,40 +88,36 @@
1688

1789
login (use-callback
1890
(fn [email password csrf-token]
19-
(let [login-promise (js/Promise.
20-
(fn [resolve reject]
21-
(go
22-
(let [response (<! (api/login email password csrf-token))
23-
_ (js/console.log "Login response:", response)
24-
{:keys [success data error]} response]
25-
(if success
26-
(do
27-
(js/console.log "Login success, saving tokens:", data)
28-
(api/save-tokens data)
29-
(api/save-user-email email)
30-
(set-auth-state
31-
{:logged-in true
32-
:email email
33-
:loading false})
34-
(resolve true))
35-
(do
36-
(js/console.log "Login failed:", error)
37-
(reject (or error "Login failed"))))))))]
38-
login-promise))
91+
(let [result-chan (chan)]
92+
(go
93+
(let [response (<! (login-user email password csrf-token))]
94+
(js/console.log "Login response:", response)
95+
(if (:success response)
96+
(let [data (:data response)]
97+
(js/console.log "Login success, saving tokens:", data)
98+
(utils/save-tokens data)
99+
(utils/save-user-email email)
100+
(set-auth-state
101+
{:logged-in true
102+
:email email
103+
:loading false})
104+
(put! result-chan true))
105+
(put! result-chan (js/Error. "Login failed")))))
106+
result-chan))
39107
[])
40108

41109
logout (use-callback
42110
(fn []
43-
(let [logout-promise (js/Promise.
44-
(fn [resolve _reject]
45-
(go
46-
(let [_ (<! (api/logout))]
47-
(set-auth-state
48-
{:logged-in false
49-
:email nil
50-
:loading false})
51-
(resolve true)))))]
52-
logout-promise))
111+
(let [result-chan (chan)]
112+
(go
113+
(let [_ (<! (logout-user))]
114+
(utils/clear-tokens)
115+
(set-auth-state
116+
{:logged-in false
117+
:email nil
118+
:loading false})
119+
(put! result-chan true)))
120+
result-chan))
53121
[])]
54122

55123
;; Load auth state on mount
@@ -58,8 +126,8 @@
58126
(let [effect-fn
59127
(fn []
60128
(go
61-
(if-let [tokens (api/get-tokens)]
62-
(let [stored-email (api/get-user-email)]
129+
(if-let [tokens (utils/get-tokens)]
130+
(let [stored-email (utils/get-user-email)]
63131
(js/console.log "Found tokens in storage:", tokens)
64132
(js/console.log "Found email in storage:", stored-email)
65133

@@ -75,22 +143,21 @@
75143
:loading false}))
76144

77145
;; No email stored, try to get user info
78-
(let [response (<! (api/get-user-info))
79-
_ (js/console.log "Get user info response:", response)
80-
{:keys [success data]} response]
81-
(if success
146+
(let [user-data (<! (get-user-info))]
147+
(js/console.log "Get user info response:", user-data)
148+
(if user-data
82149
(do
83-
(js/console.log "Successfully got user info:", data)
84-
(when-let [email (:email data)]
85-
(api/save-user-email email))
150+
(js/console.log "Successfully got user info:", user-data)
151+
(when-let [email (:email user-data)]
152+
(utils/save-user-email email))
86153
(set-auth-state
87154
{:logged-in true
88-
:email (:email data)
155+
:email (:email user-data)
89156
:loading false}))
90157
(do
91158
(js/console.log "Failed to get user info with token")
92159
;; Failed to get user info with existing token
93-
(api/clear-tokens)
160+
(utils/clear-tokens)
94161
(set-auth-state
95162
{:logged-in false
96163
:email nil
@@ -118,21 +185,21 @@
118185
[error set-error] (use-state nil)
119186
[loading set-loading] (use-state false)
120187
{:keys [login]} (uix.core/use-context ctx/auth-context)
121-
csrf-token (or (api/get-csrf-token) "")
188+
csrf-token (or (utils/get-csrf-token) "")
122189

123190
handle-submit (fn [e]
124191
(.preventDefault e)
125192
(set-loading true)
126193
(set-error nil)
127-
(.then
128-
(login email password csrf-token)
129-
(fn [_]
130-
(set-loading false)
131-
(on-close))
132-
(fn [err]
133-
(js/console.log "Login error:", err)
134-
(set-loading false)
135-
(set-error "Invalid email or password"))))]
194+
(go
195+
(try
196+
(let [result (<! (login email password csrf-token))]
197+
(set-loading false)
198+
(on-close))
199+
(catch js/Error err
200+
(js/console.log "Login error:", err)
201+
(set-loading false)
202+
(set-error "Invalid email or password")))))]
136203

137204
($ modal
138205
{:show show
@@ -145,7 +212,7 @@
145212
error))
146213

147214
;; Anti-forgery token - hidden field
148-
(when-let [token (api/get-csrf-token)]
215+
(when-let [token (utils/get-csrf-token)]
149216
($ :input
150217
{:type "hidden"
151218
:id "__anti-forgery-token"

0 commit comments

Comments
 (0)