138 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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