// routes/github-oauth.js const express = require('express'); const router = express.Router(); const GitHubOAuthService = require('../services/github-oauth'); const oauthService = new GitHubOAuthService(); // Initiate GitHub OAuth flow router.get('/auth/github', async (req, res) => { try { const state = Math.random().toString(36).substring(7); const authUrl = oauthService.getAuthUrl(state); res.json({ success: true, data: { auth_url: authUrl, state: state } }); } catch (error) { console.error('Error initiating GitHub OAuth:', error); res.status(500).json({ success: false, message: error.message || 'Failed to initiate GitHub authentication' }); } }); // Handle GitHub OAuth callback router.get('/auth/github/callback', async (req, res) => { try { const { code, state } = req.query; if (!code) { return res.status(400).json({ success: false, message: 'Authorization code missing' }); } // Exchange code for token const accessToken = await oauthService.exchangeCodeForToken(code); // Get user info from GitHub const githubUser = await oauthService.getUserInfo(accessToken); // Store token const tokenRecord = await oauthService.storeToken(accessToken, githubUser); // Redirect back to frontend if configured const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3000'; try { const redirectUrl = `${frontendUrl}/project-builder?github_connected=1&user=${encodeURIComponent(githubUser.login)}`; return res.redirect(302, redirectUrl); } catch (e) { // Fallback to JSON if redirect fails return res.json({ success: true, message: 'GitHub account connected successfully', data: { github_username: githubUser.login, github_user_id: githubUser.id, connected_at: tokenRecord.created_at } }); } } catch (error) { console.error('Error handling GitHub callback:', error); res.status(500).json({ success: false, message: error.message || 'Failed to connect GitHub account' }); } }); // Get GitHub connection status router.get('/auth/github/status', async (req, res) => { try { const tokenRecord = await oauthService.getToken(); if (tokenRecord) { res.json({ success: true, data: { connected: true, github_username: tokenRecord.github_username, github_user_id: tokenRecord.github_user_id, connected_at: tokenRecord.created_at, scopes: tokenRecord.scopes } }); } else { res.json({ success: true, data: { connected: false } }); } } catch (error) { console.error('Error checking GitHub status:', error); res.status(500).json({ success: false, message: error.message || 'Failed to check GitHub connection status' }); } }); // Disconnect GitHub account router.delete('/auth/github', async (req, res) => { try { await oauthService.revokeToken(); res.json({ success: true, message: 'GitHub account disconnected successfully' }); } catch (error) { console.error('Error disconnecting GitHub:', error); res.status(500).json({ success: false, message: error.message || 'Failed to disconnect GitHub account' }); } }); // Test repository access router.post('/test-access', async (req, res) => { try { const { repository_url } = req.body; if (!repository_url) { return res.status(400).json({ success: false, message: 'Repository URL is required' }); } const GitHubIntegrationService = require('../services/github-integration.service'); const githubService = new GitHubIntegrationService(); const { owner, repo } = githubService.parseGitHubUrl(repository_url); const canAccess = await oauthService.canAccessRepository(owner, repo); res.json({ success: true, data: { repository_url, owner, repo, can_access: canAccess } }); } catch (error) { console.error('Error testing repository access:', error); res.status(500).json({ success: false, message: error.message || 'Failed to test repository access' }); } }); module.exports = router;