Use same invite logic for display and for linking

This commit is contained in:
Cadence Ember
2026-02-14 00:33:02 +13:00
parent 08323f4512
commit b5143bfe1f
3 changed files with 22 additions and 10 deletions

View File

@@ -844,7 +844,6 @@ async function eventToMessage(event, guild, channel, di) {
// The matrix spec hasn't decided whether \n counts as a newline or not, but I'm going to count it, because if it's in the data it's there for a reason.
// But I should not count it if it's between block elements.
input = input.replace(/(<\/?([^ >]+)[^>]*>)?\n(<\/?([^ >]+)[^>]*>)?/g, (whole, beforeContext, beforeTag, afterContext, afterTag) => {
// console.error(beforeContext, beforeTag, afterContext, afterTag)
if (typeof beforeTag !== "string" && typeof afterTag !== "string") {
return "<br>"
}

View File

@@ -133,6 +133,20 @@ function getChannelRoomsLinks(guild, rooms, roles) {
}
}
/**
* @param {string} mxid
*/
function getInviteTargetSpaces(mxid) {
/** @type {{room_id: string, mxid: string, type: string, name: string, topic: string?, avatar: string?}[]} */
const spaces =
// invited spaces
db.prepare("SELECT room_id, invite.mxid, type, name, topic, avatar FROM invite LEFT JOIN guild_space ON invite.room_id = guild_space.space_id WHERE mxid = ? AND space_id IS NULL AND type = 'm.space'").all(mxid)
// moderated spaces
.concat(db.prepare("SELECT room_id, invite.mxid, type, name, topic, avatar FROM invite LEFT JOIN guild_space ON invite.room_id = guild_space.space_id INNER JOIN member_cache USING (room_id) WHERE member_cache.mxid = ? AND power_level >= 50 AND space_id IS NULL AND type = 'm.space'").all(mxid))
const seen = new Set(spaces.map(s => s.room_id))
return spaces.filter(s => seen.delete(s.room_id))
}
as.router.get("/guild", defineEventHandler(async event => {
const {guild_id} = await getValidatedQuery(event, schema.guild.parse)
const session = await auth.useSession(event)
@@ -148,13 +162,7 @@ as.router.get("/guild", defineEventHandler(async event => {
// Self-service guild that hasn't been linked yet - needs a special page encouraging the link flow
if (!row.space_id && row.autocreate === 0) {
let spaces =
// invited spaces
db.prepare("SELECT room_id, type, name, topic, avatar FROM invite LEFT JOIN guild_space ON invite.room_id = guild_space.space_id WHERE mxid = ? AND space_id IS NULL AND type = 'm.space'").all(session.data.mxid)
// moderated spaces
.concat(db.prepare("SELECT room_id, type, name, topic, avatar FROM invite LEFT JOIN guild_space ON invite.room_id = guild_space.space_id INNER JOIN member_cache USING (room_id) WHERE member_cache.mxid = ? AND power_level >= 50 AND space_id IS NULL AND type = 'm.space'").all(session.data.mxid))
const seen = new Set(spaces.map(s => s.room_id))
spaces = spaces.filter(s => seen.delete(s.room_id))
const spaces = session.data.mxid ? getInviteTargetSpaces(session.data.mxid) : []
return pugSync.render(event, "guild_not_linked.pug", {guild, guild_id, spaces})
}
@@ -257,3 +265,4 @@ as.router.post("/api/invite", defineEventHandler(async event => {
}))
module.exports._getPosition = getPosition
module.exports.getInviteTargetSpaces = getInviteTargetSpaces

View File

@@ -11,6 +11,8 @@ const {discord, db, as, sync, select, from} = require("../../passthrough")
const auth = sync.require("../auth")
/** @type {import("../../matrix/utils")}*/
const utils = sync.require("../../matrix/utils")
/** @type {import("./guild")}*/
const guildRoute = sync.require("./guild")
/**
* @param {H3Event} event
@@ -107,13 +109,15 @@ as.router.post("/api/link-space", defineEventHandler(async event => {
// Check space ID
if (!session.data.mxid) throw createError({status: 403, message: "Forbidden", data: "Can't link with your Matrix space if you aren't logged in to Matrix"})
const spaceID = parsedBody.space_id
const inviteRow = select("invite", ["mxid", "type"], {mxid: session.data.mxid, room_id: spaceID}).get()
if (!inviteRow || inviteRow.type !== "m.space") throw createError({status: 403, message: "Forbidden", data: "You personally must invite OOYE to that space on Matrix"})
// Check they are not already bridged
const existing = select("guild_space", "guild_id", {}, "WHERE guild_id = ? OR space_id = ?").get(guildID, spaceID)
if (existing) throw createError({status: 400, message: "Bad Request", data: `Guild ID ${guildID} or space ID ${spaceID} are already bridged and cannot be reused`})
// Check space ID is a valid invite target
const inviteRow = guildRoute.getInviteTargetSpaces(session.data.mxid).find(s => s.room_id === spaceID)
if (!inviteRow) throw createError({status: 403, message: "Forbidden", data: "You personally must invite OOYE to that space on Matrix"})
const inviteServer = inviteRow.mxid.match(/:(.*)/)?.[1]
assert(inviteServer)
const via = [inviteServer]