import { NextResponse } from "next/server"; import { promises as fs } from "fs"; import path from "path"; import { prisma } from "../../../../lib/prisma"; import { isSuperAdminSession, requireSession } from "../../../../lib/auth-helpers"; export const dynamic = "force-dynamic"; export const revalidate = 0; const DATA_DIR = path.join(process.cwd(), "prisma", "data"); const UPLOADS_DIR = path.join(DATA_DIR, "uploads"); const MIME_TO_EXT: Record = { "image/png": "png", "image/jpeg": "jpg", "image/webp": "webp", "image/svg+xml": "svg" }; const resolveLogoPath = (relativePath: string) => { const absolutePath = path.join(DATA_DIR, relativePath); if (!absolutePath.startsWith(DATA_DIR)) { throw new Error("Ungültiger Pfad."); } return absolutePath; }; const getLogoSetting = async () => prisma.setting.findUnique({ where: { key: "app_logo_path" } }); const getLogoTypeSetting = async () => prisma.setting.findUnique({ where: { key: "app_logo_type" } }); export async function POST(request: Request) { const { session } = await requireSession(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } if (!isSuperAdminSession(session)) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const formData = await request.formData(); const file = formData.get("file"); if (!file || !(file instanceof File)) { return NextResponse.json({ error: "Datei fehlt." }, { status: 400 }); } const extension = MIME_TO_EXT[file.type]; if (!extension) { return NextResponse.json({ error: "Dateityp nicht unterstützt." }, { status: 400 }); } await fs.mkdir(UPLOADS_DIR, { recursive: true }); const previousSetting = await getLogoSetting(); const previousTypeSetting = await getLogoTypeSetting(); const filename = `app-logo.${extension}`; const relativePath = path.join("uploads", filename); const absolutePath = resolveLogoPath(relativePath); const buffer = Buffer.from(await file.arrayBuffer()); await fs.writeFile(absolutePath, buffer); if (previousSetting?.value && previousSetting.value !== relativePath) { try { await fs.unlink(resolveLogoPath(previousSetting.value)); } catch { // ignore missing old file } } await prisma.setting.upsert({ where: { key: "app_logo_path" }, update: { value: relativePath }, create: { key: "app_logo_path", value: relativePath } }); await prisma.setting.upsert({ where: { key: "app_logo_type" }, update: { value: file.type }, create: { key: "app_logo_type", value: file.type } }); return NextResponse.json({ ok: true }); } export async function DELETE() { const { session } = await requireSession(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } if (!isSuperAdminSession(session)) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const logoSetting = await getLogoSetting(); const typeSetting = await getLogoTypeSetting(); if (logoSetting?.value) { try { await fs.unlink(resolveLogoPath(logoSetting.value)); } catch { // ignore missing file } } if (logoSetting) { await prisma.setting.delete({ where: { key: "app_logo_path" } }); } if (typeSetting) { await prisma.setting.delete({ where: { key: "app_logo_type" } }); } return NextResponse.json({ ok: true }); }