import crypto from "crypto" import { NextResponse } from "next/server" import { getSessionUser } from "@/lib/session" import { getAccountContext } from "@/lib/account" import { getAdapter } from "@/lib/esign" import { signState, ESIGN_NONCE_COOKIE } from "@/lib/esign/state" // Starts the OAuth connect flow for an e-signature provider (owner-only). // API-key providers (Dropbox Sign) don't use this — they connect via a form. export async function GET(request: Request, { params }: { params: Promise<{ provider: string }> }) { const { provider } = await params const adapter = getAdapter(provider) const settings = new URL("/settings/integrations", request.url) if (!adapter) { settings.searchParams.set("error", "unknown_provider") return NextResponse.redirect(settings) } const user = await getSessionUser() if (!user) return NextResponse.redirect(new URL("/login", request.url)) const ctx = await getAccountContext(user.id) if (!ctx.isOwner) { settings.searchParams.set("error", "owner_only") return NextResponse.redirect(settings) } if (adapter.kind !== "oauth") { settings.searchParams.set("error", "use_api_key") return NextResponse.redirect(settings) } if (!adapter.available()) { settings.searchParams.set("error", "not_configured") return NextResponse.redirect(settings) } // Bind the round-trip to this browser: nonce in the signed state AND a cookie. const nonce = crypto.randomUUID() const state = signState({ ownerId: ctx.ownerId, provider, nonce }) const res = NextResponse.redirect(adapter.getAuthUrl(state)) res.cookies.set(ESIGN_NONCE_COOKIE, nonce, { httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "lax", path: "/", maxAge: 600, }) return res }