import { NextResponse } from 'next/server'; import { getAdminAuth, getAdminDb } from '@/lib/firebase/admin'; import { FieldValue } from 'firebase-admin/firestore'; /** * Store GitHub connection for authenticated user * Encrypts and stores the access token securely */ export async function POST(request: Request) { try { const authHeader = request.headers.get('Authorization'); if (!authHeader?.startsWith('Bearer ')) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const idToken = authHeader.split('Bearer ')[1]; const adminAuth = getAdminAuth(); const adminDb = getAdminDb(); let userId: string; try { const decodedToken = await adminAuth.verifyIdToken(idToken); userId = decodedToken.uid; } catch (error) { return NextResponse.json({ error: 'Invalid token' }, { status: 401 }); } const { accessToken, githubUser } = await request.json(); if (!accessToken || !githubUser) { return NextResponse.json( { error: 'Missing required fields' }, { status: 400 } ); } // TODO: Encrypt the access token before storing // For now, we'll store it directly (should use crypto.subtle or a library) const encryptedToken = accessToken; // PLACEHOLDER // Store GitHub connection const connectionRef = adminDb.collection('githubConnections').doc(userId); await connectionRef.set({ userId, githubUserId: githubUser.id, githubUsername: githubUser.login, githubName: githubUser.name, githubEmail: githubUser.email, githubAvatarUrl: githubUser.avatar_url, accessToken: encryptedToken, connectedAt: FieldValue.serverTimestamp(), lastSyncedAt: null, }); return NextResponse.json({ success: true, githubUsername: githubUser.login, }); } catch (error) { console.error('[GitHub Connect] Error:', error); return NextResponse.json( { error: 'Failed to store GitHub connection' }, { status: 500 } ); } } /** * Get GitHub connection status for authenticated user */ export async function GET(request: Request) { try { const authHeader = request.headers.get('Authorization'); if (!authHeader?.startsWith('Bearer ')) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const idToken = authHeader.split('Bearer ')[1]; const adminAuth = getAdminAuth(); const adminDb = getAdminDb(); let userId: string; try { const decodedToken = await adminAuth.verifyIdToken(idToken); userId = decodedToken.uid; } catch (error) { return NextResponse.json({ error: 'Invalid token' }, { status: 401 }); } const connectionDoc = await adminDb .collection('githubConnections') .doc(userId) .get(); if (!connectionDoc.exists) { return NextResponse.json({ connected: false }); } const data = connectionDoc.data()!; return NextResponse.json({ connected: true, githubUsername: data.githubUsername, githubName: data.githubName, githubAvatarUrl: data.githubAvatarUrl, connectedAt: data.connectedAt, lastSyncedAt: data.lastSyncedAt, }); } catch (error) { console.error('[GitHub Connect] Error:', error); return NextResponse.json( { error: 'Failed to fetch GitHub connection' }, { status: 500 } ); } } /** * Disconnect GitHub account */ export async function DELETE(request: Request) { try { const authHeader = request.headers.get('Authorization'); if (!authHeader?.startsWith('Bearer ')) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const idToken = authHeader.split('Bearer ')[1]; const adminAuth = getAdminAuth(); const adminDb = getAdminDb(); let userId: string; try { const decodedToken = await adminAuth.verifyIdToken(idToken); userId = decodedToken.uid; } catch (error) { return NextResponse.json({ error: 'Invalid token' }, { status: 401 }); } await adminDb.collection('githubConnections').doc(userId).delete(); return NextResponse.json({ success: true }); } catch (error) { console.error('[GitHub Disconnect] Error:', error); return NextResponse.json( { error: 'Failed to disconnect GitHub' }, { status: 500 } ); } }