Room version 12 and room upgrades

This commit is contained in:
Cadence Ember
2026-01-07 02:43:20 +13:00
parent 092a4cf7b0
commit 55e0e5dfa1
27 changed files with 666 additions and 483 deletions

View File

@@ -10,6 +10,8 @@ const {discord, db, as, sync, select, from} = require("../../passthrough")
const auth = sync.require("../auth")
/** @type {import("../../matrix/mreq")} */
const mreq = sync.require("../../matrix/mreq")
/** @type {import("../../m2d/converters/utils")}*/
const utils = sync.require("../../m2d/converters/utils")
const {reg} = require("../../matrix/read-registration")
/**
@@ -87,18 +89,11 @@ as.router.post("/api/link-space", defineEventHandler(async event => {
}
// Check bridge has PL 100
const me = `@${reg.sender_localpart}:${reg.ooye.server_name}`
/** @type {Ty.Event.M_Power_Levels?} */
let powerLevelsStateContent = null
try {
powerLevelsStateContent = await api.getStateEvent(spaceID, "m.room.power_levels", "")
} catch (e) {}
const selfPowerLevel = powerLevelsStateContent?.users?.[me] ?? powerLevelsStateContent?.users_default ?? 0
if (selfPowerLevel < (powerLevelsStateContent?.state_default ?? 50) || selfPowerLevel < 100) throw createError({status: 400, message: "Bad Request", data: "OOYE needs power level 100 (admin) in the target Matrix space"})
const {powerLevels, powers: {[utils.bot]: selfPowerLevel, [session.data.mxid]: invitingPowerLevel}} = await utils.getEffectivePower(spaceID, [utils.bot, session.data.mxid], api)
if (selfPowerLevel < (powerLevels?.state_default ?? 50) || selfPowerLevel < 100) throw createError({status: 400, message: "Bad Request", data: "OOYE needs power level 100 (admin) in the target Matrix space"})
// Check inviting user is a moderator in the space
const invitingPowerLevel = powerLevelsStateContent?.users?.[session.data.mxid] ?? powerLevelsStateContent?.users_default ?? 0
if (invitingPowerLevel < (powerLevelsStateContent?.state_default ?? 50)) throw createError({status: 403, message: "Forbidden", data: `You need to be at least power level 50 (moderator) in the target Matrix space to set up OOYE, but you are currently power level ${invitingPowerLevel}.`})
if (invitingPowerLevel < (powerLevels?.state_default ?? 50)) throw createError({status: 403, message: "Forbidden", data: `You need to be at least power level 50 (moderator) in the target Matrix space to set up OOYE, but you are currently power level ${invitingPowerLevel}.`})
// Insert database entry
db.transaction(() => {
@@ -169,14 +164,8 @@ as.router.post("/api/link", defineEventHandler(async event => {
}
// Check bridge has PL 100
const me = `@${reg.sender_localpart}:${reg.ooye.server_name}`
/** @type {Ty.Event.M_Power_Levels?} */
let powerLevelsStateContent = null
try {
powerLevelsStateContent = await api.getStateEvent(parsedBody.matrix, "m.room.power_levels", "")
} catch (e) {}
const selfPowerLevel = powerLevelsStateContent?.users?.[me] ?? powerLevelsStateContent?.users_default ?? 0
if (selfPowerLevel < (powerLevelsStateContent?.state_default ?? 50) || selfPowerLevel < 100) throw createError({status: 400, message: "Bad Request", data: "OOYE needs power level 100 (admin) in the target Matrix room"})
const {powerLevels, powers: {[utils.bot]: selfPowerLevel}} = await utils.getEffectivePower(parsedBody.matrix, [utils.bot], api)
if (selfPowerLevel < (powerLevels?.state_default ?? 50) || selfPowerLevel < 100) throw createError({status: 400, message: "Bad Request", data: "OOYE needs power level 100 (admin) in the target Matrix room"})
// Insert database entry, but keep the room's existing properties if they are set
const nick = await api.getStateEvent(parsedBody.matrix, "m.room.name", "").then(content => content.name || null).catch(() => null)

View File

@@ -81,63 +81,6 @@ test("web link space: check that OOYE is joined", async t => {
t.equal(called, 1)
})
test("web link space: check that OOYE has PL 100 (not missing)", async t => {
let called = 0
const [error] = await tryToCatch(() => router.test("post", "/api/link-space", {
sessionData: {
managedGuilds: ["665289423482519565"],
mxid: "@cadence:cadence.moe"
},
body: {
space_id: "!zTMspHVUBhFLLSdmnS:cadence.moe",
guild_id: "665289423482519565"
},
api: {
async joinRoom(roomID) {
called++
return roomID
},
async getStateEvent(roomID, type, key) {
called++
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
t.equal(type, "m.room.power_levels")
throw new MatrixServerError({errcode: "M_NOT_FOUND", error: "what if I told you that power levels never existed"})
}
}
}))
t.equal(error.data, "OOYE needs power level 100 (admin) in the target Matrix space")
t.equal(called, 2)
})
test("web link space: check that OOYE has PL 100 (not users_default)", async t => {
let called = 0
const [error] = await tryToCatch(() => router.test("post", "/api/link-space", {
sessionData: {
managedGuilds: ["665289423482519565"],
mxid: "@cadence:cadence.moe"
},
body: {
space_id: "!zTMspHVUBhFLLSdmnS:cadence.moe",
guild_id: "665289423482519565"
},
api: {
async joinRoom(roomID) {
called++
return roomID
},
async getStateEvent(roomID, type, key) {
called++
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {}
}
}
}))
t.equal(error.data, "OOYE needs power level 100 (admin) in the target Matrix space")
t.equal(called, 2)
})
test("web link space: check that OOYE has PL 100 (not 50)", async t => {
let called = 0
const [error] = await tryToCatch(() => router.test("post", "/api/link-space", {
@@ -160,11 +103,28 @@ test("web link space: check that OOYE has PL 100 (not 50)", async t => {
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {users: {"@_ooye_bot:cadence.moe": 50}}
},
async getStateEventOuter(roomID, type, key) {
called++
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
t.equal(type, "m.room.create")
t.equal(key, "")
return {
type: "m.room.create",
state_key: "",
sender: "@creator:cadence.moe",
room_id: "!zTMspHVUBhFLLSdmnS:cadence.moe",
event_id: "$create",
origin_server_ts: 0,
content: {
room_version: "11"
}
}
}
}
}))
t.equal(error.data, "OOYE needs power level 100 (admin) in the target Matrix space")
t.equal(called, 2)
t.equal(called, 3)
})
test("web link space: check that inviting user has PL 50", async t => {
@@ -189,11 +149,28 @@ test("web link space: check that inviting user has PL 50", async t => {
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {users: {"@_ooye_bot:cadence.moe": 100}}
},
async getStateEventOuter(roomID, type, key) {
called++
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
t.equal(type, "m.room.create")
t.equal(key, "")
return {
type: "m.room.create",
state_key: "",
sender: "@creator:cadence.moe",
room_id: "!zTMspHVUBhFLLSdmnS:cadence.moe",
event_id: "$create",
origin_server_ts: 0,
content: {
room_version: "11"
}
}
}
}
}))
t.equal(error.data, "You need to be at least power level 50 (moderator) in the target Matrix space to set up OOYE, but you are currently power level 0.")
t.equal(called, 2)
t.equal(called, 3)
})
test("web link space: successfully adds entry to database and loads page", async t => {
@@ -218,10 +195,27 @@ test("web link space: successfully adds entry to database and loads page", async
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {users: {"@_ooye_bot:cadence.moe": 100, "@cadence:cadence.moe": 50}}
},
async getStateEventOuter(roomID, type, key) {
called++
t.equal(roomID, "!zTMspHVUBhFLLSdmnS:cadence.moe")
t.equal(type, "m.room.create")
t.equal(key, "")
return {
type: "m.room.create",
state_key: "",
sender: "@creator:cadence.moe",
room_id: "!zTMspHVUBhFLLSdmnS:cadence.moe",
event_id: "$create",
origin_server_ts: 0,
content: {
room_version: "11"
}
}
}
}
})
t.equal(called, 2)
t.equal(called, 3)
// check that the entry was added to the database
t.equal(select("guild_space", "privacy_level", {guild_id: "665289423482519565", space_id: "!zTMspHVUBhFLLSdmnS:cadence.moe"}).pluck().get(), 0)
@@ -441,47 +435,7 @@ test("web link room: check that bridge can join room (uses via for join attempt)
t.equal(called, 2)
})
test("web link room: check that bridge has PL 100 in target room (event missing)", 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 joinRoom(roomID) {
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++
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"})
}
}
}))
t.equal(error.data, "OOYE needs power level 100 (admin) in the target Matrix room")
t.equal(called, 3)
})
test("web link room: check that bridge has PL 100 in target room (users default)", async t => {
test("web link room: check that bridge has PL 100 in target room", async t => {
let called = 0
const [error] = await tryToCatch(() => router.test("post", "/api/link", {
sessionData: {
@@ -514,11 +468,28 @@ test("web link room: check that bridge has PL 100 in target room (users default)
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {users_default: 50}
},
async getStateEventOuter(roomID, type, key) {
called++
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
t.equal(type, "m.room.create")
t.equal(key, "")
return {
type: "m.room.create",
state_key: "",
sender: "@creator:cadence.moe",
room_id: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
event_id: "$create",
origin_server_ts: 0,
content: {
room_version: "11"
}
}
}
}
}))
t.equal(error.data, "OOYE needs power level 100 (admin) in the target Matrix room")
t.equal(called, 3)
t.equal(called, 4)
})
test("web link room: successfully calls createRoom", async t => {
@@ -568,6 +539,23 @@ test("web link room: successfully calls createRoom", async t => {
return {}
}
},
async getStateEventOuter(roomID, type, key) {
called++
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
t.equal(type, "m.room.create")
t.equal(key, "")
return {
type: "m.room.create",
state_key: "",
sender: "@creator:cadence.moe",
room_id: "!NDbIqNpJyPvfKRnNcr:cadence.moe",
event_id: "$create",
origin_server_ts: 0,
content: {
room_version: "11"
}
}
},
async sendEvent(roomID, type, content) {
called++
t.equal(roomID, "!NDbIqNpJyPvfKRnNcr:cadence.moe")
@@ -584,7 +572,7 @@ test("web link room: successfully calls createRoom", async t => {
}
}
})
t.equal(called, 8)
t.equal(called, 9)
})
// *****