-
Notifications
You must be signed in to change notification settings - Fork 49
fix: GitHub integration not showing as connected after App install #608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: GitHub integration not showing as connected after App install #608
Conversation
…mbient-code#602) Fix multiple issues preventing GitHub App installations from being reflected as "Connected" in the integrations UI: - Forward OAuth `code` param from GitHub callback to backend for verified ownership via token exchange (reuses existing helpers) - Fix `connectGitHub()` return value: backend returns `message`, not `username` - Fix `GitHubConnectResponse` type to match actual backend response - Fix cache invalidation: mutations now also invalidate `['integrations', 'status']` (used by the Integrations page), not just `['github', 'status']` - Remove `redirect_uri` override from connect URL so GitHub uses the configured Callback URL in App settings - Add debug logging to installation lookup and status queries Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code ReviewSummaryThis PR fixes GitHub App installation integration issues by implementing verified ownership via OAuth code exchange and correcting type mismatches between frontend and backend. The changes are well-structured and follow established patterns, but there are several areas requiring attention before merge. Issues by Severity🚫 Blocker IssuesNone identified - No issues that absolutely prevent merge. 🔴 Critical Issues1. Missing Test Coverage for New OAuth Code Path (
Example test structure needed: It("Should verify ownership when OAuth code is provided", func() {
requestBody := map[string]interface{}{
"installationId": 12345,
"code": "valid-oauth-code",
}
// Mock HTTP responses for OAuth exchange
// Assert ownership verification succeeds
})
It("Should reject installation when user doesn't own it", func() {
requestBody := map[string]interface{}{
"installationId": 12345,
"code": "code-for-different-user",
}
// Assert returns 403 Forbidden
})🟡 Major Issues1. Inconsistent Error Handling Pattern (
if err != nil {
log.Printf("LinkGitHubInstallationGlobal: OAuth code exchange failed for user=%s: %v", userIDStr, err)
// Fall through to best-effort enrichment below
}
if err != nil {
// OAuth exchange is optional - installation can proceed without verification
// for backward compatibility with GitHub App installations that don't use OAuth flow
log.Printf("LinkGitHubInstallationGlobal: OAuth code exchange failed for user=%s: %v", userIDStr, err)
}2. Potential Token Leak via Query Parameters (
const code = url.searchParams.get('code')
const code = url.searchParams.get('code')
// Clear sensitive OAuth code from URL to prevent browser history exposure
if (code) {
window.history.replaceState({}, document.title, url.pathname + '?installation_id=' + installationId)
}3. Type Mismatch Not Fully Corrected (
c.JSON(http.StatusOK, gin.H{
"message": "GitHub App installation linked successfully",
"installationId": installation.InstallationID,
})
export type GitHubConnectResponse = {
message: string;
installationId: number; // ✅ Correct
};
return response.message; // ✅ Correct
🔵 Minor Issues1. Debug Logging Should Use Structured Logging (
log.Printf("getGitHubStatusForUser: querying status for user=%s", userID)
log.Printf("getGitHubStatusForUser: user=%s action=query_status", userID)
2. Cache Invalidation Could Be More Granular (
queryClient.invalidateQueries({ queryKey: ['integrations', 'status'] });
queryClient.invalidateQueries({
queryKey: ['integrations', 'status'],
exact: true // Only invalidate exact match, not partial matches
});
3. Missing Comment on redirect_uri Removal (
// Let GitHub use the Callback URL configured in the App settings
// rather than overriding with redirect_uri (which GitHub ignores
// unless it matches a configured callback URL)
// GitHub App installations redirect to the Callback URL configured in App settings.
// The redirect_uri parameter is ignored by GitHub unless it exactly matches
// a pre-configured callback URL. Since our callback URL is already configured
// in the GitHub App settings, we omit redirect_uri to use the default.
// See: https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-login-with-github-button-with-a-github-appPositive Highlights✅ Excellent Type Safety - Fixed type mismatches between frontend and backend systematically RecommendationsHigh Priority (Before Merge)
Medium Priority (Can Address in Follow-up)
Low Priority (Nice-to-Have)
Code Quality Checklist✅ Follows CLAUDE.md backend patterns Final VerdictApproval Status: This PR solves the core issue effectively and is architecturally sound. The critical missing piece is test coverage for the OAuth verification path, which is a security-critical code change. The other issues are minor and can be addressed quickly. Suggested Actions:
Estimated Time to Address: ~1 hour 🔍 View AI decision process (logs available for 90 days) 📋 View memory system files loaded (click to expand)What Amber Loaded for Code ReviewAmber automatically loaded these repository standards from the memory system:
Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines. |
Fix multiple issues preventing GitHub App installations from being reflected as "Connected" in the integrations UI:
codeparam from GitHub callback to backend for verified ownership via token exchange (reuses existing helpers)connectGitHub()return value: backend returnsmessage, notusernameGitHubConnectResponsetype to match actual backend response['integrations', 'status'](used by the Integrations page), not just['github', 'status']redirect_urioverride from connect URL so GitHub uses the configured Callback URL in App settingsfix #602