···664664// High-level helper to delete a session, including revoking access/refresh tokens if supported by the AS
665665func (app *ClientApp) Logout(ctx context.Context, did syntax.DID, sessionID string) error {
666666 sess, err := app.ResumeSession(ctx, did, sessionID)
667667- // TODO: Should this be idempotent? i.e. logging out of a session that does not exist does nothing and succeeds?
668667 if err != nil {
669668 return err
670669 }
671670672671 // Tell the AS to revoke the tokens
673673- err = sess.RevokeSession(ctx)
674674- if err != nil {
675675- return err
676676- }
672672+ sess.RevokeSession(ctx)
677673678674 // Delete from our own session store
679675 err = app.Store.DeleteSession(ctx, did, sessionID)
+6-9
atproto/auth/oauth/session.go
···186186 return sess.Data.AccessToken, nil
187187}
188188189189-// TODO: writeme
190190-func (sess *ClientSession) RevokeSession(ctx context.Context) error {
189189+// If supported by the AS, use the revocation endpoint to revoke both the access token and the refresh token.
190190+// This method always succeeds - any errors during revocation are logged but not returned.
191191+func (sess *ClientSession) RevokeSession(ctx context.Context) {
191192 if sess.Data.AuthServerRevocationEndpoint == "" {
192193 slog.Info("AS does not advertise token revocation support, skipping")
193193- return nil
194194+ return
194195 }
195196196197 sess.lk.Lock()
···203204 })
204205 if err != nil {
205206 slog.Warn("failed revoking access token", "err", err)
206206- }
207207- if resp != nil {
207207+ } else {
208208 if resp.StatusCode != http.StatusOK {
209209 slog.Warn("bad HTTP status while revoking access token", "status_code", resp.StatusCode)
210210 }
···218218 })
219219 if err != nil {
220220 slog.Warn("failed revoking refresh token", "err", err)
221221- }
222222- if resp != nil {
221221+ } else {
223222 if resp.StatusCode != 200 {
224223 slog.Warn("bad HTTP status while revoking refresh token", "status_code", resp.StatusCode)
225224 }
226225 resp.Body.Close()
227226 }
228228-229229- return nil
230227}
231228232229// Constructs and signs a DPoP JWT to include in request header to Host (aka Resource Server, aka PDS). These tokens are different from those used with Auth Server token endpoints (even if the PDS is filling both roles)