// app/api/profile/avatar/route.ts import { NextRequest, NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth-options'; import { prisma } from '@/lib/prisma'; import fs from 'fs'; import path from 'path'; export async function POST(req: NextRequest) { const session = await getServerSession(authOptions); const user = session?.user as any | undefined; const nwkennung: string | undefined = user?.nwkennung; if (!session || !nwkennung) { return NextResponse.json({ error: 'UNAUTHORIZED' }, { status: 401 }); } const formData = await req.formData(); const file = formData.get('avatar'); if (!file || !(file instanceof Blob)) { return NextResponse.json({ error: 'NO_FILE' }, { status: 400 }); } const MAX_SIZE = 5 * 1024 * 1024; // 5 MB const mime = file.type || ''; if (!mime.startsWith('image/')) { return NextResponse.json({ error: 'INVALID_TYPE' }, { status: 400 }); } const size: number | undefined = file.size; if (typeof size === 'number' && size > MAX_SIZE) { return NextResponse.json( { error: 'TOO_LARGE', maxSizeBytes: MAX_SIZE }, { status: 413 }, ); } // Dateiendung bestimmen let ext = ''; if ('name' in file) { const name = (file as any).name as string; ext = path.extname(name); } if (!ext) { if (mime === 'image/jpeg') ext = '.jpg'; else if (mime === 'image/png') ext = '.png'; else if (mime === 'image/gif') ext = '.gif'; else ext = '.img'; } const avatarsDir = path.join(process.cwd(), 'public', 'avatars'); await fs.promises.mkdir(avatarsDir, { recursive: true }); // alte Avatare löschen const existingFiles = await fs.promises.readdir(avatarsDir); await Promise.all( existingFiles .filter((f) => f.startsWith(`${nwkennung}-`)) .map((f) => fs.promises.unlink(path.join(avatarsDir, f))), ); // Neuer, eindeutiger Dateiname const timestamp = Date.now(); const fileName = `${nwkennung}-${timestamp}${ext.toLowerCase()}`; const filePath = path.join(avatarsDir, fileName); const arrayBuffer = await file.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); await fs.promises.writeFile(filePath, buffer); const avatarUrl = `/avatars/${fileName}`; await prisma.user.update({ where: { nwkennung }, data: { avatarUrl }, }); return NextResponse.json({ ok: true, avatarUrl }); } // 👇 Neu: Profilbild löschen export async function DELETE(req: NextRequest) { const session = await getServerSession(authOptions); const user = session?.user as any | undefined; const nwkennung: string | undefined = user?.nwkennung; if (!session || !nwkennung) { return NextResponse.json({ error: 'UNAUTHORIZED' }, { status: 401 }); } const avatarsDir = path.join(process.cwd(), 'public', 'avatars'); // Dateien löschen (falls vorhanden) try { const existingFiles = await fs.promises.readdir(avatarsDir); const userFiles = existingFiles.filter((f) => f.startsWith(`${nwkennung}-`), ); await Promise.all( userFiles.map((f) => fs.promises.unlink(path.join(avatarsDir, f))), ); } catch (err: any) { // Wenn es den Ordner nicht gibt, ignorieren if (err?.code !== 'ENOENT') { console.error('[DELETE /api/profile/avatar] cleanup error', err); } } // avatarUrl in DB auf null setzen await prisma.user.update({ where: { nwkennung }, data: { avatarUrl: null }, }); return NextResponse.json({ ok: true, avatarUrl: null }); }