profit-planet-frontend/src/app/api/i18n/preferences/route.ts
DeathKaioken e769132f84 fml
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 04:52:11 +02:00

139 lines
4.5 KiB
TypeScript

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<string, string> = {
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');
}