import { getMember, updateRoom, getPendingRequests, approveRequest, rejectRequest, banMember, setMemberRole, createRoomMessage, } from "../../../../db/chat-rooms"; import { getUsersMeta } from "../../../../utils/getUsersMeta"; /** PATCH /api/chat/rooms/[roomId] – Room editieren + Anfragen verwalten */ export default defineEventHandler(async (event) => { const user = await requireUser(event); const roomId = getRouterParam(event, "roomId"); if (!roomId) throw createError({ statusCode: 400, message: "roomId fehlt" }); const member = await getMember(roomId, user.id); if (!member || (member.role !== "owner" && member.role !== "admin")) { throw createError({ statusCode: 403, message: "Nur Admins können den Raum bearbeiten", }); } const body = await readBody(event); // Handle join request approval/rejection if (body?.action === "approve" && body?.targetUserId) { await approveRequest(roomId, body.targetUserId); return { ok: true, action: "approved" }; } if (body?.action === "reject" && body?.targetUserId) { await rejectRequest(roomId, body.targetUserId); return { ok: true, action: "rejected" }; } // Handle pending requests list if (body?.action === "list_requests") { const requests = await getPendingRequests(roomId); const userIds = requests.map((r) => r.userId); const meta = userIds.length > 0 ? await getUsersMeta(userIds) : {}; return requests.map((r) => ({ userId: r.userId, nickname: meta[r.userId]?.nickname ?? "Anonym", avatar: meta[r.userId]?.avatar ?? null, requestedAt: r.joinedAt, })); } // Ban member – owner OR admin can ban regular members (not other admins unless owner) if (body?.action === "ban" && body?.targetUserId) { const target = await getMember(roomId, body.targetUserId); if (!target) throw createError({ statusCode: 404, message: "Mitglied nicht gefunden", }); if (target.role === "owner") throw createError({ statusCode: 403, message: "Owner kann nicht gebannt werden", }); // Admins dürfen keine anderen Admins bannen – nur Owner darf das if (target.role === "admin" && member.role !== "owner") { throw createError({ statusCode: 403, message: "Nur der Owner kann Admins bannen", }); } const bannedMeta = await getUsersMeta([body.targetUserId]); const bannedName = bannedMeta[body.targetUserId]?.nickname ?? "Ein Mitglied"; await banMember(roomId, body.targetUserId); // Systemnachricht in Gruppe const SYSTEM_ID = "00000000-0000-0000-0000-000000000000"; await createRoomMessage({ userId: SYSTEM_ID, roomId, content: `🚫 ${bannedName} wurde aus der Gruppe entfernt.`, }).catch(() => {}); return { ok: true, action: "banned" }; } // Promote member to admin – only Owner can do this (not sub-admins) if (body?.action === "promote_admin" && body?.targetUserId) { if (member.role !== "owner") { throw createError({ statusCode: 403, message: "Nur der Owner kann Admins ernennen", }); } const target = await getMember(roomId, body.targetUserId); if (!target || target.status !== "active") { throw createError({ statusCode: 404, message: "Mitglied nicht gefunden", }); } await setMemberRole(roomId, body.targetUserId, "admin"); return { ok: true, action: "promoted" }; } // Demote admin back to member – only Owner can do this if (body?.action === "demote_admin" && body?.targetUserId) { if (member.role !== "owner") { throw createError({ statusCode: 403, message: "Nur der Owner kann Admins zurückstufen", }); } await setMemberRole(roomId, body.targetUserId, "member"); return { ok: true, action: "demoted" }; } // Update room settings const update: Record = {}; if (body?.name) update.name = String(body.name).trim().slice(0, 60); if (body?.description !== undefined) update.description = String(body.description).trim().slice(0, 200) || null; if ( body?.joinMode && ["open", "approval", "invite_only"].includes(body.joinMode) ) { update.joinMode = body.joinMode; } if (body?.avatarUrl !== undefined) { update.avatarUrl = body.avatarUrl ? String(body.avatarUrl).trim() : null; } if (Object.keys(update).length > 0) { await updateRoom(roomId, update); } return { ok: true }; });