From cf756cb0af195618d6fb3d5f506b595910aa234d Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Sun, 29 Sep 2024 03:58:51 +1300 Subject: [PATCH] Create space as needed in oauth flow I have manually tested this with both web flows, the link flow, the /invite command, and the toggle switch, and they all work. --- src/web/pug/guild.pug | 2 +- src/web/pug/includes/template.pug | 3 ++- src/web/routes/invite.js | 16 +++++++++------- src/web/routes/oauth.js | 11 ++++++++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/web/pug/guild.pug b/src/web/pug/guild.pug index 960f30b..1e27f2e 100644 --- a/src/web/pug/guild.pug +++ b/src/web/pug/guild.pug @@ -137,7 +137,7 @@ block body label.s-label.fl-grow1(for="autocreate") | Create new Matrix rooms automatically p.s-description If you want, OOYE can automatically create new Matrix rooms and link them when an unlinked Discord channel is spoken in. - - let value = select("guild_active", "autocreate", {guild_id}).pluck().get() + - let value = !!select("guild_active", "autocreate", {guild_id}).pluck().get() input(type="hidden" name="guild_id" value=guild_id) input.s-toggle-switch.order-last#autocreate(name="autocreate" type="checkbox" hx-post="/api/autocreate" hx-indicator="#autocreate-loading" hx-disabled-elt="this" hx-swap="none" checked=value) .is-loading#autocreate-loading diff --git a/src/web/pug/includes/template.pug b/src/web/pug/includes/template.pug index c117056..94b5e92 100644 --- a/src/web/pug/includes/template.pug +++ b/src/web/pug/includes/template.pug @@ -13,6 +13,7 @@ doctype html html(lang="en") head title Out Of Your Element + link(rel="stylesheet" type="text/css" href="/static/stacks.min.css") meta(name="htmx-config" content='{"indicatorClass":"is-loading"}') @@ -52,7 +53,7 @@ html(lang="en") li(role="menuitem") a.s-topbar--item.s-user-card.d-flex.p4(href=`/guild?guild_id=${guild.id}`) +guild(guild) - .mx-auto.w100.wmx9.py24#content + .mx-auto.w100.wmx9.py24.px8#content block body script. document.querySelectorAll("[popovertarget]").forEach(e => { diff --git a/src/web/routes/invite.js b/src/web/routes/invite.js index eec7a3c..94fa367 100644 --- a/src/web/routes/invite.js +++ b/src/web/routes/invite.js @@ -9,6 +9,8 @@ const {LRUCache} = require("lru-cache") const {discord, as, sync, select} = require("../../passthrough") /** @type {import("../pug-sync")} */ const pugSync = sync.require("../pug-sync") +/** @type {import("../../d2m/actions/create-space")} */ +const createSpace = sync.require("../../d2m/actions/create-space") const {reg} = require("../../matrix/read-registration") /** @type {import("../../matrix/api")} */ @@ -71,20 +73,20 @@ as.router.post("/api/invite", defineEventHandler(async event => { } // Check guild is bridged - const spaceID = select("guild_space", "space_id", {guild_id: guild_id}).pluck().get() - if (!spaceID) throw createError({status: 428, message: "Server not bridged", data: "You can only invite Matrix users to servers that are bridged to Matrix."}) + const guild = discord.guilds.get(guild_id) + assert(guild) + const spaceID = await createSpace.ensureSpace(guild) // Check for existing invite to the space let spaceMember try { spaceMember = await api.getStateEvent(spaceID, "m.room.member", parsedBody.mxid) } catch (e) {} - if (spaceMember && (spaceMember.membership === "invite" || spaceMember.membership === "join")) { - return sendRedirect(event, `/guild?guild_id=${guild_id}`, 302) - } - // Invite - await api.inviteToRoom(spaceID, parsedBody.mxid) + if (!spaceMember || spaceMember.membership !== "invite" || spaceMember.membership !== "join") { + // Invite + await api.inviteToRoom(spaceID, parsedBody.mxid) + } // Permissions if (parsedBody.permissions === "moderator") { diff --git a/src/web/routes/oauth.js b/src/web/routes/oauth.js index f3078ad..2f12dd1 100644 --- a/src/web/routes/oauth.js +++ b/src/web/routes/oauth.js @@ -7,7 +7,7 @@ const {SnowTransfer} = require("snowtransfer") const DiscordTypes = require("discord-api-types/v10") const fetch = require("node-fetch") -const {as} = require("../../passthrough") +const {as, db} = require("../../passthrough") const {id} = require("../../../addbot") const {reg} = require("../../matrix/read-registration") @@ -77,14 +77,19 @@ as.router.get("/oauth", defineEventHandler(async event => { const client = new SnowTransfer(`Bearer ${parsedToken.data.access_token}`) try { const guilds = await client.user.getGuilds() - const managedGuilds = guilds.filter(g => BigInt(g.permissions) & DiscordTypes.PermissionFlagsBits.ManageGuild).map(g => g.id) + var managedGuilds = guilds.filter(g => BigInt(g.permissions) & DiscordTypes.PermissionFlagsBits.ManageGuild).map(g => g.id) await session.update({managedGuilds}) } catch (e) { throw createError({status: 502, message: "API call failed", data: e.message}) } + // Set auto-create for the guild + // @ts-ignore + if (managedGuilds.includes(parsedQuery.data.guild_id)) { + db.prepare("INSERT OR IGNORE INTO guild_active (guild_id, autocreate) VALUES (?, ?)").run(parsedQuery.data.guild_id, +!session.data.selfService) + } + if (parsedQuery.data.guild_id) { - // TODO: we probably need to create a matrix space and database entry immediately here so that self-service settings apply and so matrix users can be invited return sendRedirect(event, `/guild?guild_id=${parsedQuery.data.guild_id}`, 302) }