forked from cadence/out-of-your-element
		
	Only offer to link channels the bridge can access
This commit is contained in:
		
							parent
							
								
									5631b7e956
								
							
						
					
					
						commit
						20dabf4ad5
					
				
					 4 changed files with 38 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
// @ts-check
 | 
			
		||||
 | 
			
		||||
const DiscordTypes = require("discord-api-types/v10")
 | 
			
		||||
const {Endpoints, SnowTransfer} = require("snowtransfer")
 | 
			
		||||
const {reg} = require("../matrix/read-registration")
 | 
			
		||||
const {Client: CloudStorm} = require("cloudstorm")
 | 
			
		||||
| 
						 | 
				
			
			@ -36,15 +37,15 @@ class DiscordClient {
 | 
			
		|||
			}
 | 
			
		||||
		})
 | 
			
		||||
		this.ready = false
 | 
			
		||||
		/** @type {import("discord-api-types/v10").APIUser} */
 | 
			
		||||
		/** @type {DiscordTypes.APIUser} */
 | 
			
		||||
		// @ts-ignore avoid setting as or null because we know we need to wait for ready anyways
 | 
			
		||||
		this.user = null
 | 
			
		||||
		/** @type {Pick<import("discord-api-types/v10").APIApplication, "id" | "flags">} */
 | 
			
		||||
		/** @type {Pick<DiscordTypes.APIApplication, "id" | "flags">} */
 | 
			
		||||
		// @ts-ignore
 | 
			
		||||
		this.application = null
 | 
			
		||||
		/** @type {Map<string, import("discord-api-types/v10").APIChannel>} */
 | 
			
		||||
		/** @type {Map<string, DiscordTypes.APIChannel>} */
 | 
			
		||||
		this.channels = new Map()
 | 
			
		||||
		/** @type {Map<string, import("discord-api-types/v10").APIGuild>} */
 | 
			
		||||
		/** @type {Map<string, DiscordTypes.APIGuild & {members: DiscordTypes.APIGuildMember[]}>} */ // we get members from the GUILD_CREATE and we do maintain it
 | 
			
		||||
		this.guilds = new Map()
 | 
			
		||||
		/** @type {Map<string, Array<string>>} */
 | 
			
		||||
		this.guildChannelMap = new Map()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ const utils = {
 | 
			
		|||
			console.log(`Discord logged in as ${client.user.username}#${client.user.discriminator} (${client.user.id})`)
 | 
			
		||||
 | 
			
		||||
		} else if (message.t === "GUILD_CREATE") {
 | 
			
		||||
			message.d.members = message.d.members.filter(m => m.user.id === client.user.id) // only keep the bot's own member - it's needed to determine private channels on web
 | 
			
		||||
			client.guilds.set(message.d.id, message.d)
 | 
			
		||||
			const arr = []
 | 
			
		||||
			client.guildChannelMap.set(message.d.id, arr)
 | 
			
		||||
| 
						 | 
				
			
			@ -101,6 +102,13 @@ const utils = {
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else if (message.t === "GUILD_MEMBER_UPDATE") {
 | 
			
		||||
			const guild = client.guilds.get(message.d.guild_id)
 | 
			
		||||
			const member = guild?.members.find(m => m.user.id === message.d.user.id)
 | 
			
		||||
			if (member) { // only update existing members (i.e. the bot's own member) - don't want to inflate the cache with new irrelevant ones
 | 
			
		||||
				Object.assign(member, message.d)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else if (message.t === "THREAD_CREATE") {
 | 
			
		||||
			client.channels.set(message.d.id, message.d)
 | 
			
		||||
			if (message.d["guild_id"]) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -192,12 +192,17 @@ block body
 | 
			
		|||
          .s-card.p0
 | 
			
		||||
            ul.my8.ml24
 | 
			
		||||
              each row in removedUncachedChannels
 | 
			
		||||
                li: a(href=`https://discord.com/channels/${guild_id}/${row.channel_id}`)= row.nick || row.name
 | 
			
		||||
                li: a(href=`https://discord.com/channels/${guild_id}/${row.id}`)= row.nick || row.name
 | 
			
		||||
          h3.mt24 Unavailable channels: Wrong type
 | 
			
		||||
          .s-card.p0
 | 
			
		||||
            ul.my8.ml24
 | 
			
		||||
              each row in removedWrongTypeChannels
 | 
			
		||||
                li: a(href=`https://discord.com/channels/${guild_id}/${row.channel_id}`) (#{row.type}) #{row.name}
 | 
			
		||||
                li: a(href=`https://discord.com/channels/${guild_id}/${row.id}`) (#{row.type}) #{row.name}
 | 
			
		||||
          h3.mt24 Unavailable channels: Bridge can't access
 | 
			
		||||
          .s-card.p0
 | 
			
		||||
            ul.my8.ml24
 | 
			
		||||
              each row in removedPrivateChannels
 | 
			
		||||
                li: a(href=`https://discord.com/channels/${guild_id}/${row.id}`)= row.name
 | 
			
		||||
        div- // Rooms
 | 
			
		||||
          h3.mt24 Unavailable rooms: Already linked
 | 
			
		||||
          .s-card.p0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
// @ts-check
 | 
			
		||||
 | 
			
		||||
const DiscordTypes = require("discord-api-types/v10")
 | 
			
		||||
const assert = require("assert/strict")
 | 
			
		||||
const {z} = require("zod")
 | 
			
		||||
const {H3Event, defineEventHandler, sendRedirect, createError, getValidatedQuery, readValidatedBody, setResponseHeader} = require("h3")
 | 
			
		||||
| 
						 | 
				
			
			@ -8,6 +9,7 @@ const {LRUCache} = require("lru-cache")
 | 
			
		|||
const Ty = require("../../types")
 | 
			
		||||
const uqr = require("uqr")
 | 
			
		||||
 | 
			
		||||
const {id: botID} = require("../../../addbot")
 | 
			
		||||
const {discord, as, sync, select, from, db} = require("../../passthrough")
 | 
			
		||||
/** @type {import("../pug-sync")} */
 | 
			
		||||
const pugSync = sync.require("../pug-sync")
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +17,8 @@ const pugSync = sync.require("../pug-sync")
 | 
			
		|||
const createSpace = sync.require("../../d2m/actions/create-space")
 | 
			
		||||
/** @type {import("../auth")} */
 | 
			
		||||
const auth = require("../auth")
 | 
			
		||||
/** @type {import("../../discord/utils")} */
 | 
			
		||||
const utils = sync.require("../../discord/utils")
 | 
			
		||||
const {reg} = require("../../matrix/read-registration")
 | 
			
		||||
 | 
			
		||||
const schema = {
 | 
			
		||||
| 
						 | 
				
			
			@ -68,10 +72,11 @@ function filterTo(xs, fn) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {string} guildID
 | 
			
		||||
 * @param {DiscordTypes.APIGuild} guild
 | 
			
		||||
 * @param {Ty.R.Hierarchy[]} rooms
 | 
			
		||||
 * @param {string[]} roles
 | 
			
		||||
 */
 | 
			
		||||
function getChannelRoomsLinks(guildID, rooms) {
 | 
			
		||||
function getChannelRoomsLinks(guild, rooms, roles) {
 | 
			
		||||
	function getPosition(channel) {
 | 
			
		||||
		let position = 0
 | 
			
		||||
		let looking = channel
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +88,7 @@ function getChannelRoomsLinks(guildID, rooms) {
 | 
			
		|||
		return position
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let channelIDs = discord.guildChannelMap.get(guildID)
 | 
			
		||||
	let channelIDs = discord.guildChannelMap.get(guild.id)
 | 
			
		||||
	assert(channelIDs)
 | 
			
		||||
 | 
			
		||||
	let linkedChannels = select("channel_room", ["channel_id", "room_id", "name", "nick"], {channel_id: channelIDs}).all()
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +98,13 @@ function getChannelRoomsLinks(guildID, rooms) {
 | 
			
		|||
	linkedChannelsWithDetails.sort((a, b) => getPosition(a.channel) - getPosition(b.channel))
 | 
			
		||||
 | 
			
		||||
	let unlinkedChannelIDs = channelIDs.filter(c => !linkedChannelIDs.includes(c))
 | 
			
		||||
	/** @type {DiscordTypes.APIGuildChannel[]} */ // @ts-ignore
 | 
			
		||||
	let unlinkedChannels = unlinkedChannelIDs.map(c => discord.channels.get(c))
 | 
			
		||||
	let removedWrongTypeChannels = filterTo(unlinkedChannels, c => c && [0, 5].includes(c.type))
 | 
			
		||||
	let removedPrivateChannels = filterTo(unlinkedChannels, c => {
 | 
			
		||||
		const permissions = utils.getPermissions(roles, guild.roles, botID, c["permission_overwrites"])
 | 
			
		||||
		return utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.ViewChannel)
 | 
			
		||||
	})
 | 
			
		||||
	unlinkedChannels.sort((a, b) => getPosition(a) - getPosition(b))
 | 
			
		||||
 | 
			
		||||
	let linkedRoomIDs = linkedChannels.map(c => c.room_id)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +117,7 @@ function getChannelRoomsLinks(guildID, rooms) {
 | 
			
		|||
 | 
			
		||||
	return {
 | 
			
		||||
		linkedChannelsWithDetails, unlinkedChannels, unlinkedRooms,
 | 
			
		||||
		removedUncachedChannels, removedWrongTypeChannels, removedLinkedRooms, removedWrongTypeRooms, removedArchivedThreadRooms
 | 
			
		||||
		removedUncachedChannels, removedWrongTypeChannels, removedPrivateChannels, removedLinkedRooms, removedWrongTypeRooms, removedArchivedThreadRooms
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,16 +140,18 @@ as.router.get("/guild", defineEventHandler(async event => {
 | 
			
		|||
		return pugSync.render(event, "guild_not_linked.pug", {guild, guild_id, spaces})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const roles = guild.members?.find(m => m.user.id === botID)?.roles || []
 | 
			
		||||
 | 
			
		||||
	// Easy mode guild that hasn't been linked yet - need to remove elements that would require an existing space
 | 
			
		||||
	if (!row.space_id) {
 | 
			
		||||
		const links = getChannelRoomsLinks(guild_id, [])
 | 
			
		||||
		const links = getChannelRoomsLinks(guild, [], roles)
 | 
			
		||||
		return pugSync.render(event, "guild.pug", {guild, guild_id, ...links, ...row})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Linked guild
 | 
			
		||||
	const api = getAPI(event)
 | 
			
		||||
	const rooms = await api.getFullHierarchy(row.space_id)
 | 
			
		||||
	const links = getChannelRoomsLinks(guild_id, rooms)
 | 
			
		||||
	const links = getChannelRoomsLinks(guild, rooms, roles)
 | 
			
		||||
	return pugSync.render(event, "guild.pug", {guild, guild_id, ...links, ...row})
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue