mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-26 12:14:17 +00:00
65 lines
2.2 KiB
Go
65 lines
2.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"atcr.io/pkg/appview/db"
|
|
"atcr.io/pkg/auth/oauth"
|
|
indigooauth "github.com/bluesky-social/indigo/atproto/auth/oauth"
|
|
"github.com/bluesky-social/indigo/atproto/syntax"
|
|
)
|
|
|
|
// LogoutHandler handles user logout with proper OAuth token revocation
|
|
type LogoutHandler struct {
|
|
OAuthClientApp *indigooauth.ClientApp
|
|
Refresher *oauth.Refresher
|
|
SessionStore *db.SessionStore
|
|
OAuthStore *db.OAuthStore
|
|
}
|
|
|
|
func (h *LogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
// Get UI session ID from cookie
|
|
uiSessionID, hasSession := db.GetSessionID(r)
|
|
if !hasSession {
|
|
// No session to logout from, just redirect
|
|
http.Redirect(w, r, "/", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
// Get UI session to extract OAuth session ID and user info
|
|
uiSession, ok := h.SessionStore.Get(uiSessionID)
|
|
if ok && uiSession != nil && uiSession.DID != "" {
|
|
// Parse DID for OAuth logout
|
|
did, err := syntax.ParseDID(uiSession.DID)
|
|
if err != nil {
|
|
slog.Warn("Failed to parse DID for logout", "component", "logout", "did", uiSession.DID, "error", err)
|
|
} else {
|
|
// Attempt to revoke OAuth tokens on PDS side
|
|
if uiSession.OAuthSessionID != "" {
|
|
// Call indigo's Logout to revoke tokens on PDS
|
|
if err := h.OAuthClientApp.Logout(r.Context(), did, uiSession.OAuthSessionID); err != nil {
|
|
// Log error but don't block logout - best effort revocation
|
|
slog.Warn("Failed to revoke OAuth tokens on PDS", "component", "logout", "did", uiSession.DID, "error", err)
|
|
} else {
|
|
slog.Info("Successfully revoked OAuth tokens on PDS", "component", "logout", "did", uiSession.DID)
|
|
}
|
|
|
|
// Delete OAuth session from database (cleanup, might already be done by Logout)
|
|
if err := h.OAuthStore.DeleteSession(r.Context(), did, uiSession.OAuthSessionID); err != nil {
|
|
slog.Warn("Failed to delete OAuth session from database", "component", "logout", "error", err)
|
|
}
|
|
} else {
|
|
slog.Warn("No OAuth session ID found for user", "component", "logout", "did", uiSession.DID)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Always delete UI session and clear cookie, even if OAuth revocation failed
|
|
h.SessionStore.Delete(uiSessionID)
|
|
db.ClearCookie(w)
|
|
|
|
// Redirect to home page
|
|
http.Redirect(w, r, "/", http.StatusFound)
|
|
}
|