Fix matrix api joinRoom() for remote rooms

When using self-service mode and trying to link with a remote matrix
room (room not in the same HS as the bridge user), then we need to add
the "via" HSs to join the room with, or else it fails.

We get it from the "m.space.child" in the "children_state" of the space
hierarchy.

It seems like the "via" information can also be stored in the
"m.space.parent" in the states of the room, but hopefully this shouldn't
be needed in sane implementations
This commit is contained in:
Elliu 2025-08-21 21:38:34 +09:00
parent c71044fdec
commit 91d62e7b28
2 changed files with 19 additions and 7 deletions

View file

@ -64,9 +64,9 @@ async function createRoom(content) {
/**
* @returns {Promise<string>} room ID
*/
async function joinRoom(roomIDOrAlias, mxid) {
async function joinRoom(roomIDOrAlias, mxid, via) {
/** @type {Ty.R.RoomJoined} */
const root = await mreq.mreq("POST", path(`/client/v3/join/${roomIDOrAlias}`, mxid), {})
const root = await mreq.mreq("POST", path(`/client/v3/join/${roomIDOrAlias}`, mxid, via), {})
return root.room_id
}

View file

@ -77,7 +77,7 @@ as.router.post("/api/link-space", defineEventHandler(async event => {
// Check space exists and bridge is joined
try {
await api.joinRoom(parsedBody.space_id)
await api.joinRoom(parsedBody.space_id, null, via)
} catch (e) {
throw createError({status: 403, message: e.errcode, data: `${e.errcode} - ${e.message}`})
}
@ -135,19 +135,31 @@ as.router.post("/api/link", defineEventHandler(async event => {
// Check room is part of the guild's space
let found = false
let via = undefined
for await (const room of api.generateFullHierarchy(spaceID)) {
if (room.room_id === parsedBody.matrix && !room.room_type) {
if (via === undefined && room.room_type === "m.space") {
for (state of room.children_state) {
if (state.state_key === parsedBody.matrix){
via = {via: state.content.via}
if (found === true)
break
}
}
}
if (!found && room.room_id === parsedBody.matrix && !room.room_type) {
found = true
break
if (via !== undefined)
break
}
}
if (!found) throw createError({status: 400, message: "Bad Request", data: "Matrix room needs to be part of the bridged space"})
// Check room exists and bridge is joined
try {
await api.joinRoom(parsedBody.matrix)
await api.joinRoom(parsedBody.matrix, null, via ?? {})
} catch (e) {
throw createError({status: 403, message: e.errcode, data: `${e.errcode} - ${e.message}`})
throw createError({status: 403, message: e.errcode, data: `${e.errcode} - ${e.message}${via === null ? " (hint: couln't find a \"via\" in the space children_state for this room in order to help joining this room)" : ""}`})
}
// Check bridge has PL 100