diff --git a/internal/api/handlers/management/auth_files.go b/internal/api/handlers/management/auth_files.go index d9ecefe5c..775a31a49 100644 --- a/internal/api/handlers/management/auth_files.go +++ b/internal/api/handlers/management/auth_files.go @@ -1919,7 +1919,7 @@ func (h *Handler) RequestCodexToken(c *gin.Context) { bundle, errExchange := openaiAuth.ExchangeCodeForTokens(ctx, code, pkceCodes) if errExchange != nil { authErr := codex.NewAuthenticationError(codex.ErrCodeExchangeFailed, errExchange) - SetOAuthSessionError(state, "Failed to exchange authorization code for tokens") + SetOAuthSessionError(state, oauthSessionErrorWithCause("Failed to exchange authorization code for tokens", errExchange)) log.Errorf("Failed to exchange authorization code for tokens: %v", authErr) return } diff --git a/internal/api/handlers/management/oauth_callback.go b/internal/api/handlers/management/oauth_callback.go index c69a332ee..c7f7be5ec 100644 --- a/internal/api/handlers/management/oauth_callback.go +++ b/internal/api/handlers/management/oauth_callback.go @@ -79,7 +79,7 @@ func (h *Handler) PostOAuthCallback(c *gin.Context) { return } if sessionStatus != "" { - c.JSON(http.StatusConflict, gin.H{"status": "error", "error": "oauth flow is not pending"}) + c.JSON(http.StatusConflict, gin.H{"status": "error", "error": sessionStatus}) return } if !strings.EqualFold(sessionProvider, canonicalProvider) { @@ -89,6 +89,11 @@ func (h *Handler) PostOAuthCallback(c *gin.Context) { if _, errWrite := WriteOAuthCallbackFileForPendingSession(h.cfg.AuthDir, canonicalProvider, state, code, errMsg); errWrite != nil { if errors.Is(errWrite, errOAuthSessionNotPending) { + _, status, okSession := GetOAuthSession(state) + if okSession && status != "" { + c.JSON(http.StatusConflict, gin.H{"status": "error", "error": status}) + return + } c.JSON(http.StatusConflict, gin.H{"status": "error", "error": "oauth flow is not pending"}) return } diff --git a/internal/api/handlers/management/oauth_sessions.go b/internal/api/handlers/management/oauth_sessions.go index 9ab9766fb..56273019d 100644 --- a/internal/api/handlers/management/oauth_sessions.go +++ b/internal/api/handlers/management/oauth_sessions.go @@ -190,6 +190,21 @@ func IsOAuthSessionPending(state, provider string) bool { return oauthSessions.IsPending(state, provider) } +func oauthSessionErrorWithCause(message string, cause error) string { + message = strings.TrimSpace(message) + if message == "" { + message = "Authentication failed" + } + if cause == nil { + return message + } + detail := strings.TrimSpace(cause.Error()) + if detail == "" { + return message + } + return message + ": " + detail +} + func ValidateOAuthState(state string) error { trimmed := strings.TrimSpace(state) if trimmed == "" {