Why did I make it this way??? #13

Merged
Guzio merged 121 commits from main into mergable-fr-fr 2026-04-15 20:05:01 +00:00
5 changed files with 37 additions and 12 deletions
Showing only changes of commit e6c3013993 - Show all commits

View file

@ -122,7 +122,7 @@ async function channelToKState(channel, guild, di) {
join_rules = {join_rule: PRIVACY_ENUMS.ROOM_JOIN_RULES[privacyLevel]} join_rules = {join_rule: PRIVACY_ENUMS.ROOM_JOIN_RULES[privacyLevel]}
} }
const everyonePermissions = dUtils.getPermissions(guild.id, [], guild.roles, undefined, channel.permission_overwrites) const everyonePermissions = dUtils.getDefaultPermissions(guild, channel.permission_overwrites)
const everyoneCanSend = dUtils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.SendMessages) const everyoneCanSend = dUtils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.SendMessages)
const everyoneCanMentionEveryone = dUtils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.MentionEveryone) const everyoneCanMentionEveryone = dUtils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)

View file

@ -154,7 +154,7 @@ function memberToPowerLevel(user, member, guild, channel) {
if (!member) return 0 if (!member) return 0
const permissions = dUtils.getPermissions(guild.id, member.roles, guild.roles, user.id, channel.permission_overwrites) const permissions = dUtils.getPermissions(guild.id, member.roles, guild.roles, user.id, channel.permission_overwrites)
const everyonePermissions = dUtils.getPermissions(guild.id, [], guild.roles, undefined, channel.permission_overwrites) const everyonePermissions = dUtils.getDefaultPermissions(guild, channel.permission_overwrites)
/* /*
* PL 100 = Administrator = People who can brick the room. RATIONALE: * PL 100 = Administrator = People who can brick the room. RATIONALE:
* - Administrator. * - Administrator.

View file

@ -5,7 +5,7 @@ const assert = require("assert").strict
const {reg} = require("../matrix/read-registration") const {reg} = require("../matrix/read-registration")
const {db} = require("../passthrough") const {db, select} = require("../passthrough")
/** @type {import("xxhash-wasm").XXHashAPI} */ // @ts-ignore /** @type {import("xxhash-wasm").XXHashAPI} */ // @ts-ignore
let hasher = null let hasher = null
@ -58,6 +58,15 @@ function getPermissions(guildID, userRoles, guildRoles, userID, channelOverwrite
return allowed return allowed
} }
/**
* @param {{id: string, roles: DiscordTypes.APIGuild["roles"]}} guild
* @param {DiscordTypes.APIGuildChannel["permission_overwrites"]} [channel]
*/
function getDefaultPermissions(guild, channel) {
const defaultRoles = select("role_default", "role_id", {guild_id: guild.id}).pluck().all()
return getPermissions(guild.id, defaultRoles, guild.roles, undefined, channel)
}
/** /**
* Note: You can only provide one permission bit to permissionToCheckFor. To check multiple permissions, call `hasAllPermissions` or `hasSomePermissions`. * Note: You can only provide one permission bit to permissionToCheckFor. To check multiple permissions, call `hasAllPermissions` or `hasSomePermissions`.
* It is designed like this to avoid developer error with bit manipulations. * It is designed like this to avoid developer error with bit manipulations.
@ -174,6 +183,7 @@ function filterTo(xs, fn) {
} }
module.exports.getPermissions = getPermissions module.exports.getPermissions = getPermissions
module.exports.getDefaultPermissions = getDefaultPermissions
module.exports.hasPermission = hasPermission module.exports.hasPermission = hasPermission
module.exports.hasSomePermissions = hasSomePermissions module.exports.hasSomePermissions = hasSomePermissions
module.exports.hasAllPermissions = hasAllPermissions module.exports.hasAllPermissions = hasAllPermissions

View file

@ -898,7 +898,7 @@ async function eventToMessage(event, guild, channel, di) {
let shouldSuppress = inBody !== -1 && event.content.body[inBody-1] === "<" let shouldSuppress = inBody !== -1 && event.content.body[inBody-1] === "<"
if (!shouldSuppress && guild?.roles) { if (!shouldSuppress && guild?.roles) {
// Suppress if regular users don't have permission // Suppress if regular users don't have permission
const permissions = dUtils.getPermissions(guild.id, [], guild.roles) const permissions = dUtils.getDefaultPermissions(guild, channel?.permission_overwrites)
const canEmbedLinks = dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.EmbedLinks) const canEmbedLinks = dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.EmbedLinks)
shouldSuppress = !canEmbedLinks shouldSuppress = !canEmbedLinks
} }
@ -961,7 +961,7 @@ async function eventToMessage(event, guild, channel, di) {
// Suppress if regular users don't have permission // Suppress if regular users don't have permission
if (!shouldSuppress && guild?.roles) { if (!shouldSuppress && guild?.roles) {
const permissions = dUtils.getPermissions(guild.id, [], guild.roles, undefined, channel.permission_overwrites) const permissions = dUtils.getDefaultPermissions(guild, channel.permission_overwrites)
const canEmbedLinks = dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.EmbedLinks) const canEmbedLinks = dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.EmbedLinks)
shouldSuppress = !canEmbedLinks shouldSuppress = !canEmbedLinks
} }

View file

@ -105,7 +105,8 @@ const commands = [{
// Guard // Guard
/** @type {string} */ // @ts-ignore /** @type {string} */ // @ts-ignore
const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get() const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get()
const guildID = discord.channels.get(channelID)?.["guild_id"] const channel = discord.channels.get(channelID)
const guildID = channel?.["guild_id"]
let matrixOnlyReason = null let matrixOnlyReason = null
const matrixOnlyConclusion = "So the emoji will be uploaded on Matrix-side only. It will still be usable over the bridge, but may have degraded functionality." const matrixOnlyConclusion = "So the emoji will be uploaded on Matrix-side only. It will still be usable over the bridge, but may have degraded functionality."
// Check if we can/should upload to Discord, for various causes // Check if we can/should upload to Discord, for various causes
@ -115,7 +116,7 @@ const commands = [{
const guild = discord.guilds.get(guildID) const guild = discord.guilds.get(guildID)
assert(guild) assert(guild)
const slots = getSlotCount(guild.premium_tier) const slots = getSlotCount(guild.premium_tier)
const permissions = dUtils.getPermissions(guild.id, [], guild.roles) const permissions = dUtils.getDefaultPermissions(guild, channel["permission_overwrites"])
if (guild.emojis.length >= slots) { if (guild.emojis.length >= slots) {
matrixOnlyReason = "CAPACITY" matrixOnlyReason = "CAPACITY"
} else if (!(permissions & 0x40000000n)) { // MANAGE_GUILD_EXPRESSIONS (apparently CREATE_GUILD_EXPRESSIONS isn't good enough...) } else if (!(permissions & 0x40000000n)) { // MANAGE_GUILD_EXPRESSIONS (apparently CREATE_GUILD_EXPRESSIONS isn't good enough...)
@ -240,7 +241,8 @@ const commands = [{
// Guard // Guard
/** @type {string} */ // @ts-ignore /** @type {string} */ // @ts-ignore
const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get() const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get()
const guildID = discord.channels.get(channelID)?.["guild_id"] const channel = discord.channels.get(channelID)
const guildID = channel?.["guild_id"]
if (!guildID) { if (!guildID) {
return api.sendEvent(event.room_id, "m.room.message", { return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
@ -251,7 +253,7 @@ const commands = [{
const guild = discord.guilds.get(guildID) const guild = discord.guilds.get(guildID)
assert(guild) assert(guild)
const permissions = dUtils.getPermissions(guild.id, [], guild.roles) const permissions = dUtils.getDefaultPermissions(guild, channel["permission_overwrites"])
if (!(permissions & 0x800000000n)) { // CREATE_PUBLIC_THREADS if (!(permissions & 0x800000000n)) { // CREATE_PUBLIC_THREADS
return api.sendEvent(event.room_id, "m.room.message", { return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
@ -270,7 +272,8 @@ const commands = [{
// Guard // Guard
/** @type {string} */ // @ts-ignore /** @type {string} */ // @ts-ignore
const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get() const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get()
const guildID = discord.channels.get(channelID)?.["guild_id"] const channel = discord.channels.get(channelID)
const guildID = channel?.["guild_id"]
if (!guildID) { if (!guildID) {
return api.sendEvent(event.room_id, "m.room.message", { return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
@ -281,7 +284,7 @@ const commands = [{
const guild = discord.guilds.get(guildID) const guild = discord.guilds.get(guildID)
assert(guild) assert(guild)
const permissions = dUtils.getPermissions(guild.id, [], guild.roles) const permissions = dUtils.getDefaultPermissions(guild, channel["permission_overwrites"])
if (!dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.CreateInstantInvite)) { if (!dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.CreateInstantInvite)) {
return api.sendEvent(event.room_id, "m.room.message", { return api.sendEvent(event.room_id, "m.room.message", {
...ctx, ...ctx,
@ -290,7 +293,19 @@ const commands = [{
}) })
} }
const invite = await discord.snow.channel.createChannelInvite(channelID) try {
var invite = await discord.snow.channel.createChannelInvite(channelID)
} catch (e) {
if (e.message === `{"message": "Missing Permissions", "code": 50013}`) {
return api.sendEvent(event.room_id, "m.room.message", {
...ctx,
msgtype: "m.text",
body: "I don't have permission to create invites to the Discord channel/server."
})
} else {
throw e
}
}
const validHours = Math.ceil(invite.max_age / (60 * 60)) const validHours = Math.ceil(invite.max_age / (60 * 60))
const validUses = const validUses =
( invite.max_uses === 0 ? "unlimited uses" ( invite.max_uses === 0 ? "unlimited uses"