import { cookies } from "next/headers"; import { NextRequest, NextResponse } from "next/server"; import { requireAdmin } from "@/lib/auth"; function escapeHtml(value: unknown) { return String(value ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); } export async function GET(request: NextRequest) { await requireAdmin(); const params = new URL(request.url).searchParams; const cookieStore = await cookies(); const expected = cookieStore.get("youtube-oauth-state")?.value; cookieStore.delete("youtube-oauth-state"); if (!expected || expected !== params.get("state")) return NextResponse.json( { error: "Invalid OAuth state." }, { status: 400 }, ); const code = params.get("code"); if (!code) return NextResponse.json( { error: "No authorization code received." }, { status: 400 }, ); const response = await fetch("https://oauth2.googleapis.com/token", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ code, client_id: process.env.YOUTUBE_CLIENT_ID ?? "", client_secret: process.env.YOUTUBE_CLIENT_SECRET ?? "", redirect_uri: `${process.env.BASE_URL}/api/auth/youtube/callback`, grant_type: "authorization_code", }), }); const data = (await response.json()) as Record; if (!response.ok || !data.refresh_token) return NextResponse.json( { error: "YouTube token exchange failed." }, { status: 400 }, ); const html = `

YouTube OAuth success

Copy these values into your server environment:

YOUTUBE_REFRESH_TOKEN=${escapeHtml(data.refresh_token)}\nYOUTUBE_ACCESS_TOKEN=${escapeHtml(data.access_token)}

Restart the app after saving them.

`; return new NextResponse(html, { headers: { "Content-Type": "text/html" } }); }