diff --git a/src/d2m/converters/message-to-event.test.js b/src/d2m/converters/message-to-event.test.js index 20630d6..415f48d 100644 --- a/src/d2m/converters/message-to-event.test.js +++ b/src/d2m/converters/message-to-event.test.js @@ -1014,15 +1014,3 @@ test("message2event: @everyone within a link", async t => { "m.mentions": {} }]) }) - -test("message2event: forwarded image", async t => { - const events = await messageToEvent(data.message.forwarded_image) - t.deepEqual(events, [{ - $type: "m.room.message", - msgtype: "m.text", - body: "https://github.com/@everyone", - format: "org.matrix.custom.html", - formatted_body: `https://github.com/@everyone`, - "m.mentions": {} - }]) -}) diff --git a/src/web/pug/guild.pug b/src/web/pug/guild.pug index 1d03b68..acc1acb 100644 --- a/src/web/pug/guild.pug +++ b/src/web/pug/guild.pug @@ -205,7 +205,7 @@ block body p.s-description All of the above, and publicly visible in the Matrix space directory (like Server Discovery) h3.mt32.fs-category Manually link channels - form.d-flex.g16.ai-start(hx-post="/api/privacy-level" hx-trigger="submit" hx-disabled-elt="this") + form.d-flex.g16.ai-start(method="post" action="/api/link") .fl-grow2.s-btn-group.fd-column.w40 each channel in unlinkedChannels input.s-btn--radio(type="radio" name="discord" id=channel.id value=channel.id) @@ -220,8 +220,7 @@ block body +matrix(room, true) else .s-empty-state.p8 All Matrix rooms are linked. - input(type="hidden" name="guild_id" value=guild_id) div - button.s-btn.s-btn__icon.s-btn__filled.htmx-indicator - != icons.Icons.IconMerge - = ` Link` + button.s-btn.s-btn__icon.s-btn__filled + != icons.Icons.IconLink + = ` Connect` diff --git a/src/web/routes/link.js b/src/web/routes/link.js deleted file mode 100644 index 90cfd53..0000000 --- a/src/web/routes/link.js +++ /dev/null @@ -1,63 +0,0 @@ -// @ts-check - -const {z} = require("zod") -const {defineEventHandler, useSession, createError, readValidatedBody} = require("h3") -const Ty = require("../../types") - -const {discord, db, as, sync, select, from} = require("../../passthrough") -/** @type {import("../../d2m/actions/create-space")} */ -const createSpace = sync.require("../../d2m/actions/create-space") -/** @type {import("../../d2m/actions/create-room")} */ -const createRoom = sync.require("../../d2m/actions/create-room") -const {reg} = require("../../matrix/read-registration") - -/** @type {import("../../matrix/api")} */ -const api = sync.require("../../matrix/api") - -const schema = { - link: z.object({ - guild_id: z.string(), - matrix: z.string(), - discord: z.string() - }) -} - -as.router.post("/api/link", defineEventHandler(async event => { - const parsedBody = await readValidatedBody(event, schema.link.parse) - const session = await useSession(event, {password: reg.as_token}) - - // Check guild ID or nonce - const guildID = parsedBody.guild_id - if (!(session.data.managedGuilds || []).includes(guildID)) throw createError({status: 403, message: "Forbidden", data: "Can't edit a guild you don't have Manage Server permissions in"}) - - // Check guild is bridged - const guild = discord.guilds.get(guildID) - if (!guild) throw createError({status: 400, message: "Bad Request", data: "Discord guild does not exist or bot has not joined it"}) - const spaceID = await createSpace.ensureSpace(guild) - - // Check channel exists - const channel = discord.channels.get(parsedBody.discord) - if (!channel) throw createError({status: 400, message: "Bad Request", data: "Discord channel does not exist"}) - - // Check channel and room are not already bridged - const row = from("channel_room").select("channel_id", "room_id").and("WHERE channel_id = ? OR room_id = ?").get(parsedBody.discord, parsedBody.matrix) - if (row) throw createError({status: 400, message: "Bad Request", data: `Channel ID ${row.channel_id} and room ID ${row.room_id} are already bridged and cannot be reused`}) - - // Check room exists and bridge is joined and bridge has PL 100 - const self = `@${reg.sender_localpart}:${reg.ooye.server_name}` - /** @type {Ty.Event.M_Room_Member} */ - const memberEvent = await api.getStateEvent(parsedBody.matrix, "m.room.member", self) - if (memberEvent.membership !== "join") throw createError({status: 400, message: "Bad Request", data: "Matrix room does not exist"}) - /** @type {Ty.Event.M_Power_Levels} */ - const powerLevelsStateContent = await api.getStateEvent(parsedBody.matrix, "m.room.power_levels", "") - const selfPowerLevel = powerLevelsStateContent.users?.[self] || 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"}) - - // Insert database entry - db.prepare("INSERT INTO channel_room (channel_id, room_id, name, guild_id) VALUES (?, ?, ?, ?)").run(parsedBody.discord, parsedBody.matrix, channel.name, guildID) - - // Sync room data and space child - createRoom.syncRoom(parsedBody.discord) - - return null // 204 -})) diff --git a/src/web/server.js b/src/web/server.js index f9f12a1..d1b4cb8 100644 --- a/src/web/server.js +++ b/src/web/server.js @@ -23,9 +23,8 @@ pugSync.createRoute(as.router, "/ok", "ok.pug") sync.require("./routes/download-matrix") sync.require("./routes/download-discord") -sync.require("./routes/guild-settings") sync.require("./routes/invite") -sync.require("./routes/link") +sync.require("./routes/guild-settings") sync.require("./routes/oauth") sync.require("./routes/qr") diff --git a/test/data.js b/test/data.js index 6b49108..9dc2d72 100644 --- a/test/data.js +++ b/test/data.js @@ -2129,67 +2129,6 @@ module.exports = { mention_everyone: false, tts: false } - }, - forwarded_image: { type: 0, - content: "", - mentions: [], - mention_roles: [], - attachments: [], - embeds: [], - timestamp: "2024-10-16T22:25:01.973000+00:00", - edited_timestamp: null, - flags: 16384, - components: [], - id: "1296237495993892916", - channel_id: "112760669178241024", - author: { - id: "113340068197859328", - username: "kumaccino", - avatar: "a8829abe66866d7797b36f0bfac01086", - discriminator: "0", - public_flags: 128, - flags: 128, - banner: null, - accent_color: null, - global_name: "kumaccino", - avatar_decoration_data: null, - banner_color: null, - clan: null - }, - pinned: false, - mention_everyone: false, - tts: false, - message_reference: { - type: 1, - channel_id: "1019762340922663022", - message_id: "1019779830469894234" - }, - position: 0, - message_snapshots: [ - { - message: { - type: 0, - content: "", - mentions: [], - mention_roles: [], - attachments: [ - { - id: "1296237494987133070", - filename: "100km.gif", - size: 2965649, - url: "https://cdn.discordapp.com/attachments/112760669178241024/1296237494987133070/100km.gif?ex=67118ebd&is=67103d3d&hm=8ed76d424f92f11366989f2ebc713d4f8206706ef712571e934da45b59944f77&", proxy_url: "https://media.discordapp.net/attachments/112760669178241024/1296237494987133070/100km.gif?ex=67118ebd&is=67103d3d&hm=8ed76d424f92f11366989f2ebc713d4f8206706ef712571e934da45b59944f77&", width: 300, - height: 300, - content_type: "image/gif" - } - ], - embeds: [], - timestamp: "2022-09-15T01:20:58.177000+00:00", - edited_timestamp: null, - flags: 0, - components: [] - } - } - ] } }, pk_message: {