fix(communication): adopt legacy general chat rooms safely

This commit is contained in:
2026-10-02 16:06:31 +02:00
parent b01cf2c207
commit 64299843e2
2 changed files with 89 additions and 11 deletions

View File

@@ -88,13 +88,13 @@ export default async function communicationRoutes(server: FastifyInstance) {
.onConflictDoNothing()
}
const ensureGeneralRoom = async (tenantId: number, creatorId: string) => {
let [room] = await server.db.select().from(communicationRooms)
.where(and(eq(communicationRooms.tenantId, tenantId), eq(communicationRooms.key, "allgemein")))
.limit(1)
const ensureGeneralRoom = async (tenantId: number, creatorId: string) => server.db.transaction(async (tx) => {
const generalKey = and(eq(communicationRooms.tenantId, tenantId), eq(communicationRooms.key, "allgemein"))
let [room] = await tx.select().from(communicationRooms)
.where(generalKey).limit(1).for("update")
if (!room) {
const [created] = await server.db.insert(communicationRooms).values({
const [created] = await tx.insert(communicationRooms).values({
tenantId,
key: "allgemein",
name: "Allgemeiner Chat",
@@ -104,16 +104,28 @@ export default async function communicationRoutes(server: FastifyInstance) {
}).onConflictDoNothing().returning()
room = created
if (!room) {
[room] = await server.db.select().from(communicationRooms)
.where(and(eq(communicationRooms.tenantId, tenantId), eq(communicationRooms.key, "allgemein")))
.limit(1)
[room] = await tx.select().from(communicationRooms)
.where(generalKey).limit(1).for("update")
}
}
if (room.type !== "general" || room.archived) chatError("Allgemeiner Chat ist nicht verfügbar", 409)
await addMembers(room.id, (await tenantUsers(tenantId)).map((user) => user.userId))
// Old Matrix general-room endpoints omitted the type and persisted its default 'room'.
// Only unarchived, unbound tenant rooms may be adopted; a key collision must not grant access.
if (!room || !["general", "room"].includes(room.type) || room.archived
|| room.entityType !== null || room.entityId !== null || room.entityUuid !== null) {
chatError("Allgemeiner Chat ist nicht verfügbar", 409)
}
if (room.type === "room") {
[room] = await tx.update(communicationRooms).set({ type: "general" })
.where(eq(communicationRooms.id, room.id)).returning()
}
const users = await tx.select({ userId: authTenantUsers.user_id }).from(authTenantUsers)
.where(eq(authTenantUsers.tenant_id, tenantId))
if (users.length) await tx.insert(communicationRoomMembers)
.values([...new Set(users.map(user => user.userId))].map(userId => ({ roomId: room.id, userId })))
.onConflictDoNothing()
return room
}
})
const requireRoom = async (req: any, tenantId: number, userId: string, roomKey: string) => {
const [row] = await server.db.select({ room: communicationRooms }).from(communicationRooms)