import { NextRequest, NextResponse } from 'next/server' import { unsubscribeByUserId } from '@/lib/marketing/preference' import { publicAppOrigin, verifyUnsubscribeToken } from '@/lib/marketing/unsubscribe-token' export const dynamic = 'force-dynamic' function tokenFromRequest(request: NextRequest, bodyToken?: string | null): string | null { return ( request.nextUrl.searchParams.get('token') || bodyToken || null ) } async function applyUnsubscribe(request: NextRequest, token: string | null) { const payload = token ? verifyUnsubscribeToken(token) : null if (!payload) { return NextResponse.json({ ok: false }, { status: 400 }) } const forwarded = request.headers.get('x-forwarded-for') const ip = forwarded?.split(',')[0]?.trim() || request.headers.get('x-real-ip') await unsubscribeByUserId({ userId: payload.userId, source: 'unsubscribe-one-click', meta: { ip, userAgent: request.headers.get('user-agent') }, }) return new NextResponse('OK', { status: 200 }) } export async function POST(request: NextRequest) { let bodyToken: string | null = null const contentType = request.headers.get('content-type') || '' try { if (contentType.includes('application/x-www-form-urlencoded')) { const form = await request.formData() bodyToken = String(form.get('token') || '') } else if (contentType.includes('application/json')) { const json = await request.json().catch(() => null) bodyToken = json?.token ? String(json.token) : null } } catch { bodyToken = null } return applyUnsubscribe(request, tokenFromRequest(request, bodyToken)) } export async function GET(request: NextRequest) { const token = request.nextUrl.searchParams.get('token') || '' const origin = publicAppOrigin() || request.nextUrl.origin const url = new URL('/unsubscribe', origin) if (token) url.searchParams.set('token', token) return NextResponse.redirect(url, 303) }