import { NextResponse } from 'next/server'; import { fetchBackendAccessToken, requireAdminSession } from '../../_utils/backendAuth'; export const runtime = 'nodejs'; function resolvePreferencesBackendPath(): string { const configured = process.env.BACKEND_I18N_PREFERENCES_PATH?.trim(); if (configured) return configured.startsWith('/') ? configured : `/${configured}`; return '/api/admin/i18n/preferences'; } function resolveBackendBaseUrl(): string | null { const value = process.env.NEXT_PUBLIC_API_BASE_URL?.trim(); return value || null; } async function proxyPreferencesRequest(request: Request, method: 'GET' | 'POST' | 'PUT' | 'DELETE') { console.info('[API][i18n/preferences] start', { method }); const access = await requireAdminSession(request); if (!access.ok) { console.warn('[API][i18n/preferences] denied:admin-session', { method }); return access.response; } const tokenResult = await fetchBackendAccessToken(request); if (!tokenResult.ok || !tokenResult.accessToken) { console.warn('[API][i18n/preferences] denied:access-token', { method, status: tokenResult.status, message: tokenResult.message, }); const denied = NextResponse.json( { ok: false, message: tokenResult.message ?? 'Unable to obtain backend access token.' }, { status: tokenResult.status === 401 ? 401 : 403 } ); for (const setCookie of tokenResult.setCookies) { denied.headers.append('set-cookie', setCookie); } return denied; } const apiBase = resolveBackendBaseUrl(); if (!apiBase) { console.error('[API][i18n/preferences] missing NEXT_PUBLIC_API_BASE_URL'); return NextResponse.json({ ok: false, message: 'Missing NEXT_PUBLIC_API_BASE_URL.' }, { status: 500 }); } const cookie = request.headers.get('cookie') ?? ''; const backendPath = resolvePreferencesBackendPath(); const headers: Record = { cookie, Authorization: `Bearer ${tokenResult.accessToken}`, }; let body: string | undefined; // Build the backend URL; for DELETE we forward the languageCode query param if present. const incomingUrl = new URL(request.url); const languageCode = incomingUrl.searchParams.get('languageCode'); const backendQuery = languageCode ? `?languageCode=${encodeURIComponent(languageCode)}` : ''; const backendUrl = `${apiBase}${backendPath}${backendQuery}`; if (method !== 'GET' && method !== 'DELETE') { const payload = await request.json().catch(() => ({})); body = JSON.stringify(payload ?? {}); headers['Content-Type'] = 'application/json'; const categoriesCount = Array.isArray((payload as { categories?: unknown[] })?.categories) ? (payload as { categories?: unknown[] }).categories!.length : 0; const globalKeysCount = Array.isArray((payload as { globalKeys?: unknown[] })?.globalKeys) ? (payload as { globalKeys?: unknown[] }).globalKeys!.length : 0; console.info('[API][i18n/preferences] outgoing-payload', { method, categoriesCount, globalKeysCount, }); } if (method === 'DELETE' && languageCode) { console.info('[API][i18n/preferences] delete-language', { languageCode }); } const backendResponse = await fetch(backendUrl, { method, headers, body, cache: 'no-store', }).catch(() => null); if (!backendResponse) { console.error('[API][i18n/preferences] backend unreachable', { method, backendPath, }); const failed = NextResponse.json({ ok: false, message: 'Preferences backend is unreachable.' }, { status: 502 }); for (const setCookie of tokenResult.setCookies) { failed.headers.append('set-cookie', setCookie); } return failed; } console.info('[API][i18n/preferences] backend-response', { method, status: backendResponse.status, ok: backendResponse.ok, }); const payload = await backendResponse.json().catch(() => null); const out = NextResponse.json(payload ?? { ok: backendResponse.ok }, { status: backendResponse.status }); for (const setCookie of tokenResult.setCookies) { out.headers.append('set-cookie', setCookie); } return out; } export async function GET(request: Request) { return proxyPreferencesRequest(request, 'GET'); } export async function POST(request: Request) { return proxyPreferencesRequest(request, 'POST'); } export async function PUT(request: Request) { return proxyPreferencesRequest(request, 'PUT'); } export async function DELETE(request: Request) { return proxyPreferencesRequest(request, 'DELETE'); }