/** * QBO OAuth2 Authorization * GET /api/qbo/auth — redirect to Intuit authorization page * GET /api/qbo/auth/callback — exchange code for tokens */ import { NextRequest, NextResponse } from 'next/server'; import { QboClient } from '@/lib/services/qbo-client'; export async function GET(request: NextRequest) { const { searchParams } = request.nextUrl; const code = searchParams.get('code'); const realmId = searchParams.get('realmId'); const error = searchParams.get('error'); const redirectUri = `${process.env.NEXTAUTH_URL}/api/qbo/auth`; // ── Callback from Intuit ────────────────────────────────────────────────── const baseUrl = process.env.NEXTAUTH_URL || 'https://pulse.wulfconsulting.cloud'; if (code && realmId) { try { const client = new QboClient(); await client.exchangeCodeForToken(code, redirectUri); console.log(`[QBO Auth] Tokens saved for realm ${realmId}`); return NextResponse.redirect(`${baseUrl}/admin/qbo?connected=true`); } catch (err) { const msg = err instanceof Error ? err.message : String(err); console.error('[QBO Auth] Token exchange failed:', msg); return NextResponse.redirect(`${baseUrl}/admin/qbo?error=${encodeURIComponent(msg)}`); } } if (error) { return NextResponse.redirect(`${baseUrl}/admin/qbo?error=${encodeURIComponent(error)}`); } // ── Initiate authorization ──────────────────────────────────────────────── try { const client = new QboClient(); const state = Math.random().toString(36).slice(2); const authUrl = client.getAuthorizationUrl(redirectUri, state); return NextResponse.redirect(authUrl); } catch (err) { const msg = err instanceof Error ? err.message : String(err); return NextResponse.json({ error: msg }, { status: 500 }); } }