Check hierarchy instead of m.space.child
This commit is contained in:
@@ -129,16 +129,10 @@ async function _syncSpace(guild, shouldActuallySync) {
|
||||
// don't try to update rooms with custom avatars though
|
||||
const roomsWithCustomAvatars = select("channel_room", "room_id", {}, "WHERE custom_avatar IS NOT NULL").pluck().all()
|
||||
|
||||
const state = await ks.kstateToState(spaceKState)
|
||||
const childRooms = state.filter(({type, state_key, content}) => {
|
||||
return type === "m.space.child" && "via" in content && !roomsWithCustomAvatars.includes(state_key)
|
||||
}).map(({state_key}) => state_key)
|
||||
|
||||
for (const roomID of childRooms) {
|
||||
const avatarEventContent = await api.getStateEvent(roomID, "m.room.avatar", "")
|
||||
if (avatarEventContent.url !== newAvatarState.url) {
|
||||
await api.sendState(roomID, "m.room.avatar", "", newAvatarState)
|
||||
}
|
||||
for await (const room of api.generateFullHierarchy(spaceID)) {
|
||||
if (room.avatar_url === newAvatarState.url) continue
|
||||
if (roomsWithCustomAvatars.includes(room.room_id)) continue
|
||||
await api.sendState(room.room_id, "m.room.avatar", "", newAvatarState)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -181,6 +181,23 @@ async function getFullHierarchy(roomID) {
|
||||
return rooms
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `getFullHierarchy` but reveals a page at a time through an async iterator.
|
||||
* @param {string} roomID
|
||||
*/
|
||||
async function* generateFullHierarchy(roomID) {
|
||||
/** @type {string | undefined} */
|
||||
let nextBatch = undefined
|
||||
do {
|
||||
/** @type {Ty.HierarchyPagination<Ty.R.Hierarchy>} */
|
||||
const res = await getHierarchy(roomID, {from: nextBatch})
|
||||
for (const room of res.rooms) {
|
||||
yield room
|
||||
}
|
||||
nextBatch = res.next_batch
|
||||
} while (nextBatch)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} roomID
|
||||
* @param {string} eventID
|
||||
@@ -442,6 +459,7 @@ module.exports.getJoinedMembers = getJoinedMembers
|
||||
module.exports.getMembers = getMembers
|
||||
module.exports.getHierarchy = getHierarchy
|
||||
module.exports.getFullHierarchy = getFullHierarchy
|
||||
module.exports.generateFullHierarchy = generateFullHierarchy
|
||||
module.exports.getRelations = getRelations
|
||||
module.exports.getFullRelations = getFullRelations
|
||||
module.exports.sendState = sendState
|
||||
|
@@ -134,12 +134,14 @@ as.router.post("/api/link", defineEventHandler(async event => {
|
||||
if (row) throw createError({status: 400, message: "Bad Request", data: `Channel ID ${row.channel_id} or room ID ${parsedBody.matrix} are already bridged and cannot be reused`})
|
||||
|
||||
// Check room is part of the guild's space
|
||||
/** @type {Ty.Event.M_Space_Child?} */
|
||||
let spaceChildEvent = null
|
||||
try {
|
||||
spaceChildEvent = await api.getStateEvent(spaceID, "m.space.child", parsedBody.matrix)
|
||||
} catch (e) {}
|
||||
if (!Array.isArray(spaceChildEvent?.via)) throw createError({status: 400, message: "Bad Request", data: "Matrix room needs to be part of the bridged space"})
|
||||
let found = false
|
||||
for await (const room of api.generateFullHierarchy(spaceID)) {
|
||||
if (room.room_id === parsedBody.matrix && !room.room_type) {
|
||||
found = true
|
||||
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 {
|
||||
|
@@ -233,13 +233,7 @@ test("web link space: successfully adds entry to database and loads page", async
|
||||
mxid: "@cadence:cadence.moe"
|
||||
},
|
||||
api: {
|
||||
async getStateEvent(roomID, type, key) {
|
||||
return {}
|
||||
},
|
||||
async getMembers(roomID, membership) {
|
||||
return {chunk: []}
|
||||
},
|
||||
async getFullHierarchy(roomID) {
|
||||
async getFullHierarchy(spaceID) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
@@ -344,7 +338,7 @@ test("web link room: checks the autocreate setting if the space doesn't exist ye
|
||||
t.equal(called, 1)
|
||||
})
|
||||
|
||||
test("web link room: check that room is part of space (event missing)", async t => {
|
||||
test("web link room: check that room is part of space (not in hierarchy)", async t => {
|
||||
let called = 0
|
||||
const [error] = await tryToCatch(() => router.test("post", "/api/link", {
|
||||
sessionData: {
|
||||
@@ -356,37 +350,9 @@ test("web link room: check that room is part of space (event missing)", async t
|
||||
guild_id: "665289423482519565"
|
||||
},
|
||||
api: {
|
||||
async getStateEvent(roomID, type, key) {
|
||||
async *generateFullHierarchy(spaceID) {
|
||||
called++
|
||||
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
t.equal(type, "m.space.child")
|
||||
t.equal(key, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
throw new MatrixServerError({errcode: "M_NOT_FOUND", error: "what if I told you there was no such thing as a space"})
|
||||
}
|
||||
}
|
||||
}))
|
||||
t.equal(error.data, "Matrix room needs to be part of the bridged space")
|
||||
t.equal(called, 1)
|
||||
})
|
||||
|
||||
test("web link room: check that room is part of space (event empty)", async t => {
|
||||
let called = 0
|
||||
const [error] = await tryToCatch(() => router.test("post", "/api/link", {
|
||||
sessionData: {
|
||||
managedGuilds: ["665289423482519565"]
|
||||
},
|
||||
body: {
|
||||
discord: "665310973967597573",
|
||||
matrix: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
|
||||
guild_id: "665289423482519565"
|
||||
},
|
||||
api: {
|
||||
async getStateEvent(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
t.equal(type, "m.space.child")
|
||||
t.equal(key, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
return {}
|
||||
t.equal(spaceID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
}
|
||||
}
|
||||
}))
|
||||
@@ -410,12 +376,16 @@ test("web link room: check that bridge can join room", async t => {
|
||||
called++
|
||||
throw new MatrixServerError({errcode: "M_FORBIDDEN", error: "not allowed to join I guess"})
|
||||
},
|
||||
async getStateEvent(roomID, type, key) {
|
||||
async *generateFullHierarchy(spaceID) {
|
||||
called++
|
||||
t.equal(type, "m.space.child")
|
||||
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
t.equal(key, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
return {via: ["cadence.moe"]}
|
||||
t.equal(spaceID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
yield {
|
||||
room_id: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
|
||||
children_state: {},
|
||||
guest_can_join: false,
|
||||
num_joined_members: 2
|
||||
}
|
||||
/* c8 ignore next */
|
||||
}
|
||||
}
|
||||
}))
|
||||
@@ -439,17 +409,23 @@ test("web link room: check that bridge has PL 100 in target room (event missing)
|
||||
called++
|
||||
return roomID
|
||||
},
|
||||
async *generateFullHierarchy(spaceID) {
|
||||
called++
|
||||
t.equal(spaceID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
yield {
|
||||
room_id: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
|
||||
children_state: {},
|
||||
guest_can_join: false,
|
||||
num_joined_members: 2
|
||||
}
|
||||
/* c8 ignore next */
|
||||
},
|
||||
async getStateEvent(roomID, type, key) {
|
||||
called++
|
||||
if (type === "m.space.child") {
|
||||
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
t.equal(key, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
return {via: ["cadence.moe"]}
|
||||
} else if (type === "m.room.power_levels") {
|
||||
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
t.equal(key, "")
|
||||
throw new MatrixServerError({errcode: "M_NOT_FOUND", error: "what if I told you there's no such thing as power levels"})
|
||||
}
|
||||
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
throw new MatrixServerError({errcode: "M_NOT_FOUND", error: "what if I told you there's no such thing as power levels"})
|
||||
}
|
||||
}
|
||||
}))
|
||||
@@ -473,17 +449,23 @@ test("web link room: check that bridge has PL 100 in target room (users default)
|
||||
called++
|
||||
return roomID
|
||||
},
|
||||
async *generateFullHierarchy(spaceID) {
|
||||
called++
|
||||
t.equal(spaceID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
yield {
|
||||
room_id: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
|
||||
children_state: {},
|
||||
guest_can_join: false,
|
||||
num_joined_members: 2
|
||||
}
|
||||
/* c8 ignore next */
|
||||
},
|
||||
async getStateEvent(roomID, type, key) {
|
||||
called++
|
||||
if (type === "m.space.child") {
|
||||
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
t.equal(key, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
return {via: ["cadence.moe"]}
|
||||
} else if (type === "m.room.power_levels") {
|
||||
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
t.equal(key, "")
|
||||
return {users_default: 50}
|
||||
}
|
||||
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
return {users_default: 50}
|
||||
}
|
||||
}
|
||||
}))
|
||||
@@ -507,17 +489,23 @@ test("web link room: successfully calls createRoom", async t => {
|
||||
called++
|
||||
return roomID
|
||||
},
|
||||
async *generateFullHierarchy(spaceID) {
|
||||
called++
|
||||
t.equal(spaceID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
yield {
|
||||
room_id: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
|
||||
children_state: {},
|
||||
guest_can_join: false,
|
||||
num_joined_members: 2
|
||||
}
|
||||
/* c8 ignore next */
|
||||
},
|
||||
async getStateEvent(roomID, type, key) {
|
||||
if (type === "m.room.power_levels") {
|
||||
called++
|
||||
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
t.equal(key, "")
|
||||
return {users: {"@_ooye_bot:cadence.moe": 100}}
|
||||
} else if (type === "m.space.child") {
|
||||
called++
|
||||
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
|
||||
t.equal(key, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
return {via: ["cadence.moe"]}
|
||||
} else if (type === "m.room.name") {
|
||||
called++
|
||||
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
|
||||
|
Reference in New Issue
Block a user