Skip to content
This repository has been archived by the owner on Feb 10, 2025. It is now read-only.

Commit

Permalink
feat(auth): automatically refresh expired tokens
Browse files Browse the repository at this point in the history
Thanks to @hierophantos and PR #9 for the inspiration.

This commit also includes a base case for the `expired?` function
allowing handling unauthenticated user scenarios.
  • Loading branch information
goshatch committed Jan 15, 2025
1 parent b8ba848 commit 60cc88a
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions src/net/gosha/atproto/client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@
json/read-json)))

(defn- expired? [token]
(let [exp (:exp (decode-jwt token))
now (quot (inst-ms (java.time.Instant/now)) 1000)]
(<= exp now)))
(if (nil? token)
false
(let [exp (get (decode-jwt token) "exp")
now (quot (inst-ms (java.time.Instant/now)) 1000)]
(<= exp now))))

;; TODO: automatically refresh expired tokens
(defn authenticate
Expand Down Expand Up @@ -136,11 +138,20 @@
- `session` The API session returned by `init`.
- `endpoint` API endpoint for the format :com.atproto.server.get-session
- `params` Map of params to pass to the endpoint"
- `opts` Map of options to pass to the endpoint"
[session endpoint & {:as opts}]
(when (expired? (:access @(:tokens (:opts session))))
(refresh-token! session))
(martian/response-for session endpoint opts))
(let [tokens (:tokens (:opts session))]
(when (and tokens
(expired? (:access @tokens)))
(refresh-token! session)))
(let [res @(martian/response-for session endpoint opts)
error (-> res :body :error)]
(if (= error "ExpiredToken")
(do
(log/info "Access token expired, refreshing.")
(refresh-token! session)
(call session endpoint opts))
res)))

(defn call-async
"Like `call`, but returns a core.async channel instead of a IBlockingDeref.
Expand Down

0 comments on commit 60cc88a

Please sign in to comment.