Fix matrix api joinRoom() for remote rooms #60
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	
	No description provided.
		
		Delete branch "Elliu/out-of-your-element:fix-remote-join"
	
	Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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
@ -149,2 +160,3 @@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)" : ""}`})Not sure if adding this hint is a good idea, or if we should rather put it elsewhere (like in a "hint" member), or if we should not put it at all, or if we should add a "please consider manually inviting the bot user <> in the room"
I added a separate branch for it to say a different error message when the join fails. I felt the ternary was too complicated.
I decided to do it this way because it's better to see actionable feedback (do this) rather than merely identifying a problem (it tells you that the via data is wrong, but not what correct data would look like, or how to actually fix it) (I don't know any clients that allow you to edit the via data without devtools)
e8bb63dd3ato743fec6e69@ -23,3 +23,3 @@if (mxid) u.searchParams.set("user_id", mxid)for (const entry of Object.entries(otherParams)) {if (entry[1] != undefined) {if (Array.isArray(entry[1])) {I fixed
pathso that passing arrays (likevia) to it should work correctly. :)@ -68,2 +74,3 @@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}), {})Third parameter needs to be an object, so I fixed that for you. I also labelled the inbound parameters so that it highlights the call site if the wrong data is passed to
joinRoom. :)@ -78,3 +78,3 @@// Check space exists and bridge is joinedtry {await api.joinRoom(parsedBody.space_id)await api.joinRoom(parsedBody.space_id, null, via)Where are you going to find
viahere?Hmmm, I didn't change that because the bridge needed to be manually invited to the space so that it can be selected.
However indeed, if the bridge is invited to the space, then kicked, the button to the space remains and if clicked, we have the same issue than for joining rooms, didn't notice that.
From the Client-Server API doc there doesn't seem to be "via" or "server_name" information on the
m.room.memberevent, so I'm not sure.I guess it should be safe to take the HS part of the user from
senderin them.room.member: as this user is able to send an invite, the space must be reachable through the inviter's HS(unless the invite is old, all users from this HS left the space, and the room was purged from the HS, but nothing we can do about that)
Last commit uses that, should we add a check to enrich the error message too if for some reasons we cannot detect the via?
Added the error message asking to manually invite in case if /api/link-space joinRoom fails, similarly to /api/link
b6c3e37478to6734c15ca248e2080b94tof6c749accaLooks good. Please address the invididual comments (or ask me to do it for you). Then I can do a final coverage check and merge this. Thanks for your patience!
@ -15,0 +16,4 @@* @param {string} UserID* @returns {string} the HS of the user, or "" if the user ID is malformed*/function getHSOfUser(user) {Please use
server = mxid.match(/:(.*)/)?.[1](see utils.js line 168) which is short enough that it can be used inline without needing to be extracted to a function. So please delete the functiongetHSOfUserand just do the operation inline where needed.Updated, had to add a null coalescing or else linter complains about array of string OR undefined a few lines below
@ -76,2 +90,4 @@if (existing) throw createError({status: 400, message: "Bad Request", data: `Guild ID ${guildID} or space ID ${spaceID} are already bridged and cannot be reused`})const inviteSender = select("invite", "mxid", {mxid: session.data.mxid, room_id: spaceID}).pluck().get()via = [ getHSOfUser(inviteSender) ]When creating a new variable, it ought to be declared with
letorconst. Please useconsthere.@ -80,2 +97,3 @@await api.joinRoom(parsedBody.space_id)await api.joinRoom(parsedBody.space_id, null, via)} catch (e) {if (via.join("") == "") {This condition can't happen, because it's always possible to extract a
viafrom the user who sent the invite. Remove the if statement and just always use the more detailed error message.@ -81,1 +97,4 @@await api.joinRoom(parsedBody.space_id, null, via)} catch (e) {if (via.join("") == "") {throw createError({status: 403, message: "Unable To Join", data: `Unable to join the requested Matrix space. Please invite the bridge to the space and try again. (Server said: ${e.errcode} - ${e.message})`})Status code 400 please.
Note that this error message doesn't make much sense. The user has to have already invited the bridge to the space to reach this point.
I honestly don't know what advice would be good to give if this occurs, because accepting an invite should always work, even for remote invites. /shrug
Yeah, I don't know.
The idea at the back of my mind was a weird state that could happen if:
/api/link-spacegets called somehow(?)Don't know if all of this even makes sense
@ -149,1 +179,4 @@await api.joinRoom(parsedBody.matrix, null, foundVia)} catch (e) {if (!foundVia) {throw createError({status: 403, message: "Unable To Join", data: `Unable to join the requested Matrix room. Please invite the bridge to the room and try again. (Server said: ${e.errcode} - ${e.message})`})This is fine and doesn't need changing (apart from making the status code 400, please)
23d87fb9a4toab69eab8a4789c7b0334toa55d7a1632