setUserPower should account for room version 12
This commit is contained in:
@@ -37,7 +37,9 @@ const createRoom = sync.require("../d2m/actions/create-room")
|
|||||||
/** @type {import("../src/matrix/mreq")} */
|
/** @type {import("../src/matrix/mreq")} */
|
||||||
const mreq = sync.require("../matrix/mreq")
|
const mreq = sync.require("../matrix/mreq")
|
||||||
/** @type {import("../src/matrix/api")} */
|
/** @type {import("../src/matrix/api")} */
|
||||||
const api = sync.require("../matrix/api")
|
const api = sync.require("../src/matrix/api")
|
||||||
|
/** @type {import("../src/matrix/utils")} */
|
||||||
|
const utils = sync.require("../src/matrix/utils")
|
||||||
|
|
||||||
const sema = new Semaphore()
|
const sema = new Semaphore()
|
||||||
|
|
||||||
@@ -89,7 +91,7 @@ async function migrateGuild(guild) {
|
|||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await api.setUserPower(roomID, newBridgeMxid, 100)
|
await utils.setUserPower(roomID, newBridgeMxid, 100, api)
|
||||||
})
|
})
|
||||||
await api.joinRoom(roomID)
|
await api.joinRoom(roomID)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const passthrough = require("../src/passthrough")
|
|||||||
Object.assign(passthrough, {db, sync})
|
Object.assign(passthrough, {db, sync})
|
||||||
|
|
||||||
const api = require("../src/matrix/api")
|
const api = require("../src/matrix/api")
|
||||||
|
const utils = require("../src/matrix/utils")
|
||||||
const mreq = require("../src/matrix/mreq")
|
const mreq = require("../src/matrix/mreq")
|
||||||
|
|
||||||
const rooms = db.prepare("select room_id from channel_room").pluck().all()
|
const rooms = db.prepare("select room_id from channel_room").pluck().all()
|
||||||
@@ -25,7 +26,7 @@ const rooms = db.prepare("select room_id from channel_room").pluck().all()
|
|||||||
await api.leaveRoom(roomID, mxid)
|
await api.leaveRoom(roomID, mxid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await api.setUserPower(roomID, "@_discord_bot:cadence.moe", 0)
|
await utils.setUserPower(roomID, "@_discord_bot:cadence.moe", 0, api)
|
||||||
await api.leaveRoom(roomID)
|
await api.leaveRoom(roomID)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message.includes("Appservice not in room")) {
|
if (e.message.includes("Appservice not in room")) {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ const mreq = sync.require("../../matrix/mreq")
|
|||||||
const ks = sync.require("../../matrix/kstate")
|
const ks = sync.require("../../matrix/kstate")
|
||||||
/** @type {import("../../discord/utils")} */
|
/** @type {import("../../discord/utils")} */
|
||||||
const dUtils = sync.require("../../discord/utils")
|
const dUtils = sync.require("../../discord/utils")
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const mUtils = sync.require("../../m2d/converters/utils")
|
const mUtils = sync.require("../../matrix/utils")
|
||||||
/** @type {import("./create-space")} */
|
/** @type {import("./create-space")} */
|
||||||
const createSpace = sync.require("./create-space")
|
const createSpace = sync.require("./create-space")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ const api = sync.require("../../matrix/api")
|
|||||||
/** @type {import("../../matrix/file")} */
|
/** @type {import("../../matrix/file")} */
|
||||||
const file = sync.require("../../matrix/file")
|
const file = sync.require("../../matrix/file")
|
||||||
/** @type {import("../../discord/utils")} */
|
/** @type {import("../../discord/utils")} */
|
||||||
const utils = sync.require("../../discord/utils")
|
const dUtils = sync.require("../../discord/utils")
|
||||||
|
/** @type {import("../../matrix/utils")} */
|
||||||
|
const mxUtils = sync.require("../../matrix/utils")
|
||||||
/** @type {import("../converters/user-to-mxid")} */
|
/** @type {import("../converters/user-to-mxid")} */
|
||||||
const userToMxid = sync.require("../converters/user-to-mxid")
|
const userToMxid = sync.require("../converters/user-to-mxid")
|
||||||
/** @type {import("./create-room")} */
|
/** @type {import("./create-room")} */
|
||||||
@@ -159,8 +161,8 @@ async function memberToStateContent(user, member, guildID) {
|
|||||||
function memberToPowerLevel(user, member, guild, channel) {
|
function memberToPowerLevel(user, member, guild, channel) {
|
||||||
if (!member) return 0
|
if (!member) return 0
|
||||||
|
|
||||||
const permissions = utils.getPermissions(member.roles, guild.roles, user.id, channel.permission_overwrites)
|
const permissions = dUtils.getPermissions(member.roles, guild.roles, user.id, channel.permission_overwrites)
|
||||||
const everyonePermissions = utils.getPermissions([], guild.roles, undefined, channel.permission_overwrites)
|
const everyonePermissions = dUtils.getPermissions([], guild.roles, undefined, 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.
|
||||||
@@ -169,7 +171,7 @@ function memberToPowerLevel(user, member, guild, channel) {
|
|||||||
* - Manage Channels: People who can manage the channel can delete it.
|
* - Manage Channels: People who can manage the channel can delete it.
|
||||||
* (Setting sim users to PL 100 is safe because even though we can't demote the sims we can use code to make the sims demote themselves.)
|
* (Setting sim users to PL 100 is safe because even though we can't demote the sims we can use code to make the sims demote themselves.)
|
||||||
*/
|
*/
|
||||||
if (guild.owner_id === user.id || utils.hasSomePermissions(permissions, ["Administrator", "ManageWebhooks", "ManageGuild", "ManageChannels"])) return 100
|
if (guild.owner_id === user.id || dUtils.hasSomePermissions(permissions, ["Administrator", "ManageWebhooks", "ManageGuild", "ManageChannels"])) return 100
|
||||||
/*
|
/*
|
||||||
* PL 50 = Moderator = People who can manage people and messages in many ways. RATIONALE:
|
* PL 50 = Moderator = People who can manage people and messages in many ways. RATIONALE:
|
||||||
* - Manage Messages: Can moderate by pinning or deleting the conversation.
|
* - Manage Messages: Can moderate by pinning or deleting the conversation.
|
||||||
@@ -179,14 +181,14 @@ function memberToPowerLevel(user, member, guild, channel) {
|
|||||||
* - Mute Members & Deafen Members: Can moderate by silencing disruptive people in ways they can't undo.
|
* - Mute Members & Deafen Members: Can moderate by silencing disruptive people in ways they can't undo.
|
||||||
* - Moderate Members.
|
* - Moderate Members.
|
||||||
*/
|
*/
|
||||||
if (utils.hasSomePermissions(permissions, ["ManageMessages", "ManageNicknames", "ManageThreads", "KickMembers", "BanMembers", "MuteMembers", "DeafenMembers", "ModerateMembers"])) return 50
|
if (dUtils.hasSomePermissions(permissions, ["ManageMessages", "ManageNicknames", "ManageThreads", "KickMembers", "BanMembers", "MuteMembers", "DeafenMembers", "ModerateMembers"])) return 50
|
||||||
/* PL 50 = if room is read-only but the user has been specially allowed to send messages */
|
/* PL 50 = if room is read-only but the user has been specially allowed to send messages */
|
||||||
const everyoneCanSend = utils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.SendMessages)
|
const everyoneCanSend = dUtils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.SendMessages)
|
||||||
const userCanSend = utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.SendMessages)
|
const userCanSend = dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.SendMessages)
|
||||||
if (!everyoneCanSend && userCanSend) return createRoom.READ_ONLY_ROOM_EVENTS_DEFAULT_POWER
|
if (!everyoneCanSend && userCanSend) return createRoom.READ_ONLY_ROOM_EVENTS_DEFAULT_POWER
|
||||||
/* PL 20 = Mention Everyone for technical reasons. */
|
/* PL 20 = Mention Everyone for technical reasons. */
|
||||||
const everyoneCanMentionEveryone = utils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)
|
const everyoneCanMentionEveryone = dUtils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)
|
||||||
const userCanMentionEveryone = utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)
|
const userCanMentionEveryone = dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)
|
||||||
if (!everyoneCanMentionEveryone && userCanMentionEveryone) return 20
|
if (!everyoneCanMentionEveryone && userCanMentionEveryone) return 20
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -247,7 +249,7 @@ async function _sendSyncUser(roomID, mxid, content, powerLevel, options) {
|
|||||||
actions.push(api.sendState(roomID, "m.room.member", mxid, content, mxid))
|
actions.push(api.sendState(roomID, "m.room.member", mxid, content, mxid))
|
||||||
// Update power levels
|
// Update power levels
|
||||||
if (powerLevel != null) {
|
if (powerLevel != null) {
|
||||||
actions.push(api.setUserPower(roomID, mxid, powerLevel))
|
actions.push(mxUtils.setUserPower(roomID, mxid, powerLevel, api))
|
||||||
}
|
}
|
||||||
// Update global profile (if supported by server)
|
// Update global profile (if supported by server)
|
||||||
if (await supportsMsc4069) {
|
if (await supportsMsc4069) {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ const passthrough = require("../../passthrough")
|
|||||||
const {sync, select, from} = passthrough
|
const {sync, select, from} = passthrough
|
||||||
/** @type {import("./message-to-event")} */
|
/** @type {import("./message-to-event")} */
|
||||||
const messageToEvent = sync.require("../converters/message-to-event")
|
const messageToEvent = sync.require("../converters/message-to-event")
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const utils = sync.require("../../m2d/converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
|
|
||||||
function eventCanBeEdited(ev) {
|
function eventCanBeEdited(ev) {
|
||||||
// Discord does not allow files, images, attachments, or videos to be edited.
|
// Discord does not allow files, images, attachments, or videos to be edited.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const {test} = require("supertape")
|
const {test} = require("supertape")
|
||||||
const {messageToEvent} = require("./message-to-event")
|
const {messageToEvent} = require("./message-to-event")
|
||||||
const data = require("../../../test/data")
|
const data = require("../../../test/data")
|
||||||
const {mockGetEffectivePower} = require("../../m2d/converters/utils.test")
|
const {mockGetEffectivePower} = require("../../matrix/utils.test")
|
||||||
const {db} = require("../../passthrough")
|
const {db} = require("../../passthrough")
|
||||||
|
|
||||||
test("message2event embeds: nothing but a field", async t => {
|
test("message2event embeds: nothing but a field", async t => {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ const file = sync.require("../../matrix/file")
|
|||||||
const emojiToKey = sync.require("./emoji-to-key")
|
const emojiToKey = sync.require("./emoji-to-key")
|
||||||
/** @type {import("../actions/lottie")} */
|
/** @type {import("../actions/lottie")} */
|
||||||
const lottie = sync.require("../actions/lottie")
|
const lottie = sync.require("../actions/lottie")
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const mxUtils = sync.require("../../m2d/converters/utils")
|
const mxUtils = sync.require("../../matrix/utils")
|
||||||
/** @type {import("../../discord/utils")} */
|
/** @type {import("../../discord/utils")} */
|
||||||
const dUtils = sync.require("../../discord/utils")
|
const dUtils = sync.require("../../discord/utils")
|
||||||
const {reg} = require("../../matrix/read-registration")
|
const {reg} = require("../../matrix/read-registration")
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const {test} = require("supertape")
|
|||||||
const {messageToEvent} = require("./message-to-event")
|
const {messageToEvent} = require("./message-to-event")
|
||||||
const {MatrixServerError} = require("../../matrix/mreq")
|
const {MatrixServerError} = require("../../matrix/mreq")
|
||||||
const data = require("../../../test/data")
|
const data = require("../../../test/data")
|
||||||
const {mockGetEffectivePower} = require("../../m2d/converters/utils.test")
|
const {mockGetEffectivePower} = require("../../matrix/utils.test")
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ const DiscordTypes = require("discord-api-types/v10")
|
|||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {discord, sync, select} = passthrough
|
const {discord, sync, select} = passthrough
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const utils = sync.require("../../m2d/converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef ReactionRemoveRequest
|
* @typedef ReactionRemoveRequest
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ const assert = require("assert").strict
|
|||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {discord, sync, db, select} = passthrough
|
const {discord, sync, db, select} = passthrough
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const mxUtils = sync.require("../../m2d/converters/utils")
|
const mxUtils = sync.require("../../matrix/utils")
|
||||||
const {reg} = require("../../matrix/read-registration.js")
|
const {reg} = require("../../matrix/read-registration.js")
|
||||||
|
|
||||||
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
|
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const {test} = require("supertape")
|
|||||||
const {threadToAnnouncement} = require("./thread-to-announcement")
|
const {threadToAnnouncement} = require("./thread-to-announcement")
|
||||||
const data = require("../../../test/data")
|
const data = require("../../../test/data")
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
const {mockGetEffectivePower} = require("../../m2d/converters/utils.test")
|
const {mockGetEffectivePower} = require("../../matrix/utils.test")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} roomID
|
* @param {string} roomID
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ const {InteractionMethods} = require("snowtransfer")
|
|||||||
|
|
||||||
/** @type {import("../../matrix/api")} */
|
/** @type {import("../../matrix/api")} */
|
||||||
const api = sync.require("../../matrix/api")
|
const api = sync.require("../../matrix/api")
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const utils = sync.require("../../m2d/converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.APIContextMenuGuildInteraction} interaction
|
* @param {DiscordTypes.APIContextMenuGuildInteraction} interaction
|
||||||
@@ -126,7 +126,7 @@ async function* _interactEdit({data, guild_id, message}, {api}) {
|
|||||||
assert(spaceID)
|
assert(spaceID)
|
||||||
|
|
||||||
// Do it
|
// Do it
|
||||||
await api.setUserPowerCascade(spaceID, mxid, power)
|
await utils.setUserPowerCascade(spaceID, mxid, power, api)
|
||||||
|
|
||||||
// ACK
|
// ACK
|
||||||
yield {editOriginalInteractionResponse: {
|
yield {editOriginalInteractionResponse: {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const {test} = require("supertape")
|
|||||||
const DiscordTypes = require("discord-api-types/v10")
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const {select, db} = require("../../passthrough")
|
const {select, db} = require("../../passthrough")
|
||||||
const {_interact, _interactEdit} = require("./permissions")
|
const {_interact, _interactEdit} = require("./permissions")
|
||||||
const {mockGetEffectivePower} = require("../../m2d/converters/utils.test")
|
const {mockGetEffectivePower} = require("../../matrix/utils.test")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @template T
|
* @template T
|
||||||
@@ -156,7 +156,7 @@ test("permissions: reports permissions of selected matrix user (admin v11 cannot
|
|||||||
})
|
})
|
||||||
|
|
||||||
test("permissions: can update user to moderator", async t => {
|
test("permissions: can update user to moderator", async t => {
|
||||||
let called = 0
|
let called = []
|
||||||
const msgs = await fromAsync(_interactEdit({
|
const msgs = await fromAsync(_interactEdit({
|
||||||
data: {
|
data: {
|
||||||
target_id: "1128118177155526666",
|
target_id: "1128118177155526666",
|
||||||
@@ -168,22 +168,48 @@ test("permissions: can update user to moderator", async t => {
|
|||||||
guild_id: "112760669178241024"
|
guild_id: "112760669178241024"
|
||||||
}, {
|
}, {
|
||||||
api: {
|
api: {
|
||||||
async setUserPowerCascade(roomID, mxid, power) {
|
async getStateEvent(roomID, type, key) {
|
||||||
called++
|
called.push("get power levels")
|
||||||
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe") // space ID
|
t.equal(type, "m.room.power_levels")
|
||||||
t.equal(mxid, "@cadence:cadence.moe")
|
return {}
|
||||||
t.equal(power, 50)
|
},
|
||||||
|
async getStateEventOuter(roomID, type, key) {
|
||||||
|
called.push("get room create")
|
||||||
|
return {
|
||||||
|
type: "m.room.create",
|
||||||
|
state_key: "",
|
||||||
|
sender: "@_ooye_bot:cadence.moe",
|
||||||
|
event_id: "$create",
|
||||||
|
origin_server_ts: 0,
|
||||||
|
room_id: roomID,
|
||||||
|
content: {
|
||||||
|
room_version: "11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async *generateFullHierarchy(spaceID) {
|
||||||
|
called.push("generate full hierarchy")
|
||||||
|
},
|
||||||
|
async sendState(roomID, type, key, content) {
|
||||||
|
called.push("set power levels")
|
||||||
|
t.ok(["!hierarchy", "!jjmvBegULiLucuWEHU:cadence.moe"].includes(roomID), `expected room ID to be in hierarchy, but was ${roomID}`)
|
||||||
|
t.equal(type, "m.room.power_levels")
|
||||||
|
t.equal(key, "")
|
||||||
|
t.deepEqual(content, {
|
||||||
|
users: {"@cadence:cadence.moe": 50}
|
||||||
|
})
|
||||||
|
return "$updated"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
t.equal(msgs.length, 2)
|
t.equal(msgs.length, 2)
|
||||||
t.equal(msgs[0].createInteractionResponse.data.content, "Updating `@cadence:cadence.moe` to **moderator**, please wait...")
|
t.equal(msgs[0].createInteractionResponse.data.content, "Updating `@cadence:cadence.moe` to **moderator**, please wait...")
|
||||||
t.equal(msgs[1].editOriginalInteractionResponse.content, "Updated `@cadence:cadence.moe` to **moderator**.")
|
t.equal(msgs[1].editOriginalInteractionResponse.content, "Updated `@cadence:cadence.moe` to **moderator**.")
|
||||||
t.equal(called, 1)
|
t.deepEqual(called, ["generate full hierarchy", "get room create", "get power levels", "set power levels"])
|
||||||
})
|
})
|
||||||
|
|
||||||
test("permissions: can update user to default", async t => {
|
test("permissions: can update user to default", async t => {
|
||||||
let called = 0
|
let called = []
|
||||||
const msgs = await fromAsync(_interactEdit({
|
const msgs = await fromAsync(_interactEdit({
|
||||||
data: {
|
data: {
|
||||||
target_id: "1128118177155526666",
|
target_id: "1128118177155526666",
|
||||||
@@ -195,16 +221,44 @@ test("permissions: can update user to default", async t => {
|
|||||||
guild_id: "112760669178241024"
|
guild_id: "112760669178241024"
|
||||||
}, {
|
}, {
|
||||||
api: {
|
api: {
|
||||||
async setUserPowerCascade(roomID, mxid, power) {
|
async getStateEvent(roomID, type, key) {
|
||||||
called++
|
called.push("get power levels")
|
||||||
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe") // space ID
|
t.equal(type, "m.room.power_levels")
|
||||||
t.equal(mxid, "@cadence:cadence.moe")
|
return {
|
||||||
t.equal(power, 0)
|
users: {"@cadence:cadence.moe": 50}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getStateEventOuter(roomID, type, key) {
|
||||||
|
called.push("get room create")
|
||||||
|
return {
|
||||||
|
type: "m.room.create",
|
||||||
|
state_key: "",
|
||||||
|
sender: "@_ooye_bot:cadence.moe",
|
||||||
|
event_id: "$create",
|
||||||
|
origin_server_ts: 0,
|
||||||
|
room_id: roomID,
|
||||||
|
content: {
|
||||||
|
room_version: "11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async *generateFullHierarchy(spaceID) {
|
||||||
|
called.push("generate full hierarchy")
|
||||||
|
},
|
||||||
|
async sendState(roomID, type, key, content) {
|
||||||
|
called.push("set power levels")
|
||||||
|
t.ok(["!hierarchy", "!jjmvBegULiLucuWEHU:cadence.moe"].includes(roomID), `expected room ID to be in hierarchy, but was ${roomID}`)
|
||||||
|
t.equal(type, "m.room.power_levels")
|
||||||
|
t.equal(key, "")
|
||||||
|
t.deepEqual(content, {
|
||||||
|
users: {}
|
||||||
|
})
|
||||||
|
return "$updated"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
t.equal(msgs.length, 2)
|
t.equal(msgs.length, 2)
|
||||||
t.equal(msgs[0].createInteractionResponse.data.content, "Updating `@cadence:cadence.moe` to **default**, please wait...")
|
t.equal(msgs[0].createInteractionResponse.data.content, "Updating `@cadence:cadence.moe` to **default**, please wait...")
|
||||||
t.equal(msgs[1].editOriginalInteractionResponse.content, "Updated `@cadence:cadence.moe` to **default**.")
|
t.equal(msgs[1].editOriginalInteractionResponse.content, "Updated `@cadence:cadence.moe` to **default**.")
|
||||||
t.equal(called, 1)
|
t.deepEqual(called, ["generate full hierarchy", "get room create", "get power levels", "set power levels"])
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ const {InteractionMethods} = require("snowtransfer")
|
|||||||
|
|
||||||
/** @type {import("../../matrix/api")} */
|
/** @type {import("../../matrix/api")} */
|
||||||
const api = sync.require("../../matrix/api")
|
const api = sync.require("../../matrix/api")
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const utils = sync.require("../../m2d/converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction
|
* @param {DiscordTypes.APIMessageApplicationCommandGuildInteraction} interaction
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ const Ty = require("../../types")
|
|||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {discord, sync, db, select} = passthrough
|
const {discord, sync, db, select} = passthrough
|
||||||
/** @type {import("../converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const utils = sync.require("../converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
/** @type {import("../converters/emoji")} */
|
/** @type {import("../converters/emoji")} */
|
||||||
const emoji = sync.require("../converters/emoji")
|
const emoji = sync.require("../converters/emoji")
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ const Ty = require("../../types")
|
|||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {discord, sync, db, select, from} = passthrough
|
const {discord, sync, db, select, from} = passthrough
|
||||||
/** @type {import("../converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const utils = sync.require("../converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Ty.Event.Outer_M_Room_Redaction} event
|
* @param {Ty.Event.Outer_M_Room_Redaction} event
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ const {tag} = require("@cloudrac3r/html-template-tag")
|
|||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const {sync, db, discord, select, from} = passthrough
|
const {sync, db, discord, select, from} = passthrough
|
||||||
const {reg} = require("../../matrix/read-registration")
|
const {reg} = require("../../matrix/read-registration")
|
||||||
/** @type {import("../converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const mxUtils = sync.require("../converters/utils")
|
const mxUtils = sync.require("../../matrix/utils")
|
||||||
/** @type {import("../../discord/utils")} */
|
/** @type {import("../../discord/utils")} */
|
||||||
const dUtils = sync.require("../../discord/utils")
|
const dUtils = sync.require("../../discord/utils")
|
||||||
/** @type {import("../../matrix/file")} */
|
/** @type {import("../../matrix/file")} */
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ const redact = sync.require("./actions/redact")
|
|||||||
const updatePins = sync.require("./actions/update-pins")
|
const updatePins = sync.require("./actions/update-pins")
|
||||||
/** @type {import("../matrix/matrix-command-handler")} */
|
/** @type {import("../matrix/matrix-command-handler")} */
|
||||||
const matrixCommandHandler = sync.require("../matrix/matrix-command-handler")
|
const matrixCommandHandler = sync.require("../matrix/matrix-command-handler")
|
||||||
/** @type {import("./converters/utils")} */
|
/** @type {import("../matrix/utils")} */
|
||||||
const utils = sync.require("./converters/utils")
|
const utils = sync.require("../matrix/utils")
|
||||||
/** @type {import("../matrix/api")}) */
|
/** @type {import("../matrix/api")}) */
|
||||||
const api = sync.require("../matrix/api")
|
const api = sync.require("../matrix/api")
|
||||||
/** @type {import("../d2m/actions/create-room")} */
|
/** @type {import("../d2m/actions/create-room")} */
|
||||||
|
|||||||
@@ -358,55 +358,6 @@ async function profileSetAvatarUrl(mxid, avatar_url, inhibitPropagate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a user's power level within a room.
|
|
||||||
* @param {string} roomID
|
|
||||||
* @param {string} mxid
|
|
||||||
* @param {number} newPower
|
|
||||||
*/
|
|
||||||
async function setUserPower(roomID, mxid, newPower) {
|
|
||||||
assert(roomID[0] === "!")
|
|
||||||
assert(mxid[0] === "@")
|
|
||||||
// Yes there's no shortcut https://github.com/matrix-org/matrix-appservice-bridge/blob/2334b0bae28a285a767fe7244dad59f5a5963037/src/components/intent.ts#L352
|
|
||||||
const power = await getStateEvent(roomID, "m.room.power_levels", "")
|
|
||||||
power.users = power.users || {}
|
|
||||||
|
|
||||||
// Check if it has really changed to avoid sending a useless state event
|
|
||||||
// (Can't diff kstate here because of (a) circular imports (b) kstate has special behaviour diffing power levels)
|
|
||||||
const oldPowerLevel = power.users?.[mxid] ?? power.users_default ?? 0
|
|
||||||
if (oldPowerLevel === newPower) return
|
|
||||||
|
|
||||||
// Bridge bot can't demote equal power users, so need to decide which user will send the event
|
|
||||||
const botPowerLevel = power.users?.[`@${reg.sender_localpart}:${reg.ooye.server_name}`] ?? power.users_default ?? 0
|
|
||||||
const eventSender = oldPowerLevel >= botPowerLevel ? mxid : undefined
|
|
||||||
|
|
||||||
// Update the event content
|
|
||||||
if (newPower == null || newPower === (power.users_default ?? 0)) {
|
|
||||||
delete power.users[mxid]
|
|
||||||
} else {
|
|
||||||
power.users[mxid] = newPower
|
|
||||||
}
|
|
||||||
|
|
||||||
await sendState(roomID, "m.room.power_levels", "", power, eventSender)
|
|
||||||
return power
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a user's power level for a whole room hierarchy.
|
|
||||||
* @param {string} spaceID
|
|
||||||
* @param {string} mxid
|
|
||||||
* @param {number} power
|
|
||||||
*/
|
|
||||||
async function setUserPowerCascade(spaceID, mxid, power) {
|
|
||||||
assert(spaceID[0] === "!")
|
|
||||||
assert(mxid[0] === "@")
|
|
||||||
const rooms = await getFullHierarchy(spaceID)
|
|
||||||
await setUserPower(spaceID, mxid, power)
|
|
||||||
for (const room of rooms) {
|
|
||||||
await setUserPower(room.room_id, mxid, power)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function ping() {
|
async function ping() {
|
||||||
// not using mreq so that we can read the status code
|
// not using mreq so that we can read the status code
|
||||||
const res = await fetch(`${mreq.baseUrl}/client/v1/appservice/${reg.id}/ping`, {
|
const res = await fetch(`${mreq.baseUrl}/client/v1/appservice/${reg.id}/ping`, {
|
||||||
@@ -579,8 +530,6 @@ module.exports.redactEvent = redactEvent
|
|||||||
module.exports.sendTyping = sendTyping
|
module.exports.sendTyping = sendTyping
|
||||||
module.exports.profileSetDisplayname = profileSetDisplayname
|
module.exports.profileSetDisplayname = profileSetDisplayname
|
||||||
module.exports.profileSetAvatarUrl = profileSetAvatarUrl
|
module.exports.profileSetAvatarUrl = profileSetAvatarUrl
|
||||||
module.exports.setUserPower = setUserPower
|
|
||||||
module.exports.setUserPowerCascade = setUserPowerCascade
|
|
||||||
module.exports.ping = ping
|
module.exports.ping = ping
|
||||||
module.exports.getMedia = getMedia
|
module.exports.getMedia = getMedia
|
||||||
module.exports.sendReadReceipt = sendReadReceipt
|
module.exports.sendReadReceipt = sendReadReceipt
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ const {sync} = passthrough
|
|||||||
const file = sync.require("./file")
|
const file = sync.require("./file")
|
||||||
/** @type {import("./api")} */
|
/** @type {import("./api")} */
|
||||||
const api = sync.require("./api")
|
const api = sync.require("./api")
|
||||||
/** @type {import("../m2d/converters/utils")} */
|
/** @type {import("./utils")} */
|
||||||
const utils = sync.require("../m2d/converters/utils")
|
const utils = sync.require("./utils")
|
||||||
|
|
||||||
/** Mutates the input. Not recursive - can only include or exclude entire state events. */
|
/** Mutates the input. Not recursive - can only include or exclude entire state events. */
|
||||||
function kstateStripConditionals(kstate) {
|
function kstateStripConditionals(kstate) {
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ const sharp = require("sharp")
|
|||||||
const {discord, sync, db, select} = require("../passthrough")
|
const {discord, sync, db, select} = require("../passthrough")
|
||||||
/** @type {import("./api")}) */
|
/** @type {import("./api")}) */
|
||||||
const api = sync.require("./api")
|
const api = sync.require("./api")
|
||||||
/** @type {import("../m2d/converters/utils")} */
|
/** @type {import("./utils")} */
|
||||||
const mxUtils = sync.require("../m2d/converters/utils")
|
const mxUtils = sync.require("./utils")
|
||||||
/** @type {import("../discord/utils")} */
|
/** @type {import("../discord/utils")} */
|
||||||
const dUtils = sync.require("../discord/utils")
|
const dUtils = sync.require("../discord/utils")
|
||||||
/** @type {import("./kstate")} */
|
/** @type {import("./kstate")} */
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ const {discord, db, sync, as, select, from} = require("../passthrough")
|
|||||||
const api = sync.require("./api")
|
const api = sync.require("./api")
|
||||||
/** @type {import("../d2m/actions/create-room")}) */
|
/** @type {import("../d2m/actions/create-room")}) */
|
||||||
const createRoom = sync.require("../d2m/actions/create-room")
|
const createRoom = sync.require("../d2m/actions/create-room")
|
||||||
/** @type {import("../m2d/converters/utils")}) */
|
/** @type {import("./utils")}) */
|
||||||
const utils = sync.require("../m2d/converters/utils")
|
const utils = sync.require("./utils")
|
||||||
|
|
||||||
const roomUpgradeSema = new Semaphore()
|
const roomUpgradeSema = new Semaphore()
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
const Ty = require("../../types")
|
const Ty = require("../types")
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../passthrough")
|
||||||
const {db} = passthrough
|
const {db} = passthrough
|
||||||
|
|
||||||
const {reg} = require("../../matrix/read-registration")
|
const {reg} = require("./read-registration")
|
||||||
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
|
const userRegex = reg.namespaces.users.map(u => new RegExp(u.regex))
|
||||||
|
|
||||||
/** @type {import("xxhash-wasm").XXHashAPI} */ // @ts-ignore
|
/** @type {import("xxhash-wasm").XXHashAPI} */ // @ts-ignore
|
||||||
@@ -129,7 +129,7 @@ class MatrixStringBuilder {
|
|||||||
* https://spec.matrix.org/v1.9/appendices/#routing
|
* https://spec.matrix.org/v1.9/appendices/#routing
|
||||||
* https://gitdab.com/cadence/out-of-your-element/issues/11
|
* https://gitdab.com/cadence/out-of-your-element/issues/11
|
||||||
* @param {string} roomID
|
* @param {string} roomID
|
||||||
* @param {{[K in "getStateEvent" | "getStateEventOuter" | "getJoinedMembers"]: import("../../matrix/api")[K]} | {getEffectivePower: (roomID: string, mxids: string[], api: any) => Promise<{powers: Record<string, number>, allCreators: string[], tombstone: number, roomCreate: Ty.Event.StateOuter<Ty.Event.M_Room_Create>, powerLevels: Ty.Event.M_Power_Levels}>, getJoinedMembers: import("../../matrix/api")["getJoinedMembers"]}} api
|
* @param {{[K in "getStateEvent" | "getStateEventOuter" | "getJoinedMembers"]: import("./api")[K]} | {getEffectivePower: (roomID: string, mxids: string[], api: any) => Promise<{powers: Record<string, number>, allCreators: string[], tombstone: number, roomCreate: Ty.Event.StateOuter<Ty.Event.M_Room_Create>, powerLevels: Ty.Event.M_Power_Levels}>, getJoinedMembers: import("./api")["getJoinedMembers"]}} api
|
||||||
*/
|
*/
|
||||||
async function getViaServers(roomID, api) {
|
async function getViaServers(roomID, api) {
|
||||||
const candidates = []
|
const candidates = []
|
||||||
@@ -188,7 +188,7 @@ async function getViaServers(roomID, api) {
|
|||||||
* https://spec.matrix.org/v1.9/appendices/#routing
|
* https://spec.matrix.org/v1.9/appendices/#routing
|
||||||
* https://gitdab.com/cadence/out-of-your-element/issues/11
|
* https://gitdab.com/cadence/out-of-your-element/issues/11
|
||||||
* @param {string} roomID
|
* @param {string} roomID
|
||||||
* @param {{[K in "getStateEvent" | "getStateEventOuter" | "getJoinedMembers"]: import("../../matrix/api")[K]}} api
|
* @param {{[K in "getStateEvent" | "getStateEventOuter" | "getJoinedMembers"]: import("./api")[K]}} api
|
||||||
* @returns {Promise<URLSearchParams>}
|
* @returns {Promise<URLSearchParams>}
|
||||||
*/
|
*/
|
||||||
async function getViaServersQuery(roomID, api) {
|
async function getViaServersQuery(roomID, api) {
|
||||||
@@ -273,7 +273,7 @@ function removeCreatorsFromPowerLevels(roomCreateOuter, powerLevels) {
|
|||||||
* @template {string} T
|
* @template {string} T
|
||||||
* @param {string} roomID
|
* @param {string} roomID
|
||||||
* @param {T[]} mxids
|
* @param {T[]} mxids
|
||||||
* @param {{[K in "getStateEvent" | "getStateEventOuter"]: import("../../matrix/api")[K]}} api
|
* @param {{[K in "getStateEvent" | "getStateEventOuter"]: import("./api")[K]}} api
|
||||||
* @returns {Promise<{powers: Record<T, number>, allCreators: string[], tombstone: number, roomCreate: Ty.Event.StateOuter<Ty.Event.M_Room_Create>, powerLevels: Ty.Event.M_Power_Levels}>}
|
* @returns {Promise<{powers: Record<T, number>, allCreators: string[], tombstone: number, roomCreate: Ty.Event.StateOuter<Ty.Event.M_Room_Create>, powerLevels: Ty.Event.M_Power_Levels}>}
|
||||||
*/
|
*/
|
||||||
async function getEffectivePower(roomID, mxids, api) {
|
async function getEffectivePower(roomID, mxids, api) {
|
||||||
@@ -300,6 +300,56 @@ async function getEffectivePower(roomID, mxids, api) {
|
|||||||
return {powers, allCreators, tombstone, roomCreate, powerLevels}
|
return {powers, allCreators, tombstone, roomCreate, powerLevels}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a user's power level within a room.
|
||||||
|
* @param {string} roomID
|
||||||
|
* @param {string} mxid
|
||||||
|
* @param {number} newPower
|
||||||
|
* @param {{[K in "getStateEvent" | "getStateEventOuter" | "sendState"]: import("./api")[K]}} api
|
||||||
|
*/
|
||||||
|
async function setUserPower(roomID, mxid, newPower, api) {
|
||||||
|
assert(roomID[0] === "!")
|
||||||
|
assert(mxid[0] === "@")
|
||||||
|
// Yes there's no shortcut https://github.com/matrix-org/matrix-appservice-bridge/blob/2334b0bae28a285a767fe7244dad59f5a5963037/src/components/intent.ts#L352
|
||||||
|
const {powerLevels, powers: {[mxid]: oldPowerLevel, [bot]: botPowerLevel}} = await getEffectivePower(roomID, [mxid, bot], api)
|
||||||
|
|
||||||
|
// Check if it has really changed to avoid sending a useless state event
|
||||||
|
if (oldPowerLevel === newPower) return
|
||||||
|
|
||||||
|
// Bridge bot can't demote equal power users, so need to decide which user will send the event
|
||||||
|
const eventSender = oldPowerLevel >= botPowerLevel ? mxid : undefined
|
||||||
|
|
||||||
|
// Update the event content
|
||||||
|
powerLevels.users ??= {}
|
||||||
|
if (newPower == null || newPower === (powerLevels.users_default ?? 0)) {
|
||||||
|
delete powerLevels.users[mxid]
|
||||||
|
} else {
|
||||||
|
powerLevels.users[mxid] = newPower
|
||||||
|
}
|
||||||
|
|
||||||
|
await api.sendState(roomID, "m.room.power_levels", "", powerLevels, eventSender)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a user's power level for a whole room hierarchy.
|
||||||
|
* @param {string} spaceID
|
||||||
|
* @param {string} mxid
|
||||||
|
* @param {number} power
|
||||||
|
* @param {{[K in "getStateEvent" | "getStateEventOuter" | "sendState" | "generateFullHierarchy"]: import("./api")[K]}} api
|
||||||
|
*/
|
||||||
|
async function setUserPowerCascade(spaceID, mxid, power, api) {
|
||||||
|
assert(spaceID[0] === "!")
|
||||||
|
assert(mxid[0] === "@")
|
||||||
|
let seenSpace = false
|
||||||
|
for await (const room of api.generateFullHierarchy(spaceID)) {
|
||||||
|
if (room.room_id === spaceID) seenSpace = true
|
||||||
|
await setUserPower(room.room_id, mxid, power, api)
|
||||||
|
}
|
||||||
|
if (!seenSpace) {
|
||||||
|
await setUserPower(spaceID, mxid, power, api)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.bot = bot
|
module.exports.bot = bot
|
||||||
module.exports.BLOCK_ELEMENTS = BLOCK_ELEMENTS
|
module.exports.BLOCK_ELEMENTS = BLOCK_ELEMENTS
|
||||||
module.exports.eventSenderIsFromDiscord = eventSenderIsFromDiscord
|
module.exports.eventSenderIsFromDiscord = eventSenderIsFromDiscord
|
||||||
@@ -311,3 +361,5 @@ module.exports.getViaServersQuery = getViaServersQuery
|
|||||||
module.exports.roomHasAtLeastVersion = roomHasAtLeastVersion
|
module.exports.roomHasAtLeastVersion = roomHasAtLeastVersion
|
||||||
module.exports.removeCreatorsFromPowerLevels = removeCreatorsFromPowerLevels
|
module.exports.removeCreatorsFromPowerLevels = removeCreatorsFromPowerLevels
|
||||||
module.exports.getEffectivePower = getEffectivePower
|
module.exports.getEffectivePower = getEffectivePower
|
||||||
|
module.exports.setUserPower = setUserPower
|
||||||
|
module.exports.setUserPowerCascade = setUserPowerCascade
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const e = new Error("Custom error")
|
|
||||||
|
|
||||||
const {test} = require("supertape")
|
const {test} = require("supertape")
|
||||||
const {eventSenderIsFromDiscord, getEventIDHash, MatrixStringBuilder, getViaServers, roomHasAtLeastVersion} = require("./utils")
|
const {eventSenderIsFromDiscord, getEventIDHash, MatrixStringBuilder, getViaServers, roomHasAtLeastVersion} = require("./utils")
|
||||||
const util = require("util")
|
const util = require("util")
|
||||||
@@ -41,8 +39,14 @@ test("event hash: hash is different for different inputs", t => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test("MatrixStringBuilder: add, addLine, add same text", t => {
|
test("MatrixStringBuilder: add, addLine, add same text", t => {
|
||||||
|
const e = {
|
||||||
|
stack: "Error: Custom error\n at ./example.test.js:3:11)",
|
||||||
|
toString() {
|
||||||
|
return "Error: Custom error"
|
||||||
|
}
|
||||||
|
}
|
||||||
const gatewayMessage = {t: "MY_MESSAGE", d: {display: "Custom message data"}}
|
const gatewayMessage = {t: "MY_MESSAGE", d: {display: "Custom message data"}}
|
||||||
let stackLines = e.stack?.split("\n")
|
let stackLines = e.stack.split("\n")
|
||||||
|
|
||||||
const builder = new MatrixStringBuilder()
|
const builder = new MatrixStringBuilder()
|
||||||
builder.addLine("\u26a0 Bridged event from Discord not delivered", "\u26a0 <strong>Bridged event from Discord not delivered</strong>")
|
builder.addLine("\u26a0 Bridged event from Discord not delivered", "\u26a0 <strong>Bridged event from Discord not delivered</strong>")
|
||||||
@@ -63,12 +67,12 @@ test("MatrixStringBuilder: add, addLine, add same text", t => {
|
|||||||
+ "\nError: Custom error"
|
+ "\nError: Custom error"
|
||||||
+ "\nError trace:"
|
+ "\nError trace:"
|
||||||
+ "\nError: Custom error"
|
+ "\nError: Custom error"
|
||||||
+ "\n at ./m2d/converters/utils.test.js:3:11)\n",
|
+ "\n at ./example.test.js:3:11)\n",
|
||||||
format: "org.matrix.custom.html",
|
format: "org.matrix.custom.html",
|
||||||
formatted_body: "\u26a0 <strong>Bridged event from Discord not delivered</strong>"
|
formatted_body: "\u26a0 <strong>Bridged event from Discord not delivered</strong>"
|
||||||
+ "<br>Gateway event: MY_MESSAGE"
|
+ "<br>Gateway event: MY_MESSAGE"
|
||||||
+ "<br>Error: Custom error"
|
+ "<br>Error: Custom error"
|
||||||
+ "<br><details><summary>Error trace</summary><pre>Error: Custom error\n at ./m2d/converters/utils.test.js:3:11)</pre></details>"
|
+ "<br><details><summary>Error trace</summary><pre>Error: Custom error\n at ./example.test.js:3:11)</pre></details>"
|
||||||
+ `<details><summary>Original payload</summary><pre>{ display: 'Custom message data' }</pre></details>`
|
+ `<details><summary>Original payload</summary><pre>{ display: 'Custom message data' }</pre></details>`
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -18,7 +18,9 @@ const createSpace = sync.require("../../d2m/actions/create-space")
|
|||||||
/** @type {import("../auth")} */
|
/** @type {import("../auth")} */
|
||||||
const auth = require("../auth")
|
const auth = require("../auth")
|
||||||
/** @type {import("../../discord/utils")} */
|
/** @type {import("../../discord/utils")} */
|
||||||
const utils = sync.require("../../discord/utils")
|
const dUtils = sync.require("../../discord/utils")
|
||||||
|
/** @type {import("../../matrix/utils")} */
|
||||||
|
const mxUtils = sync.require("../../matrix/utils")
|
||||||
const {reg} = require("../../matrix/read-registration")
|
const {reg} = require("../../matrix/read-registration")
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
@@ -102,8 +104,8 @@ function getChannelRoomsLinks(guild, rooms, roles) {
|
|||||||
let unlinkedChannels = unlinkedChannelIDs.map(c => discord.channels.get(c))
|
let unlinkedChannels = unlinkedChannelIDs.map(c => discord.channels.get(c))
|
||||||
let removedWrongTypeChannels = filterTo(unlinkedChannels, c => c && [0, 5].includes(c.type))
|
let removedWrongTypeChannels = filterTo(unlinkedChannels, c => c && [0, 5].includes(c.type))
|
||||||
let removedPrivateChannels = filterTo(unlinkedChannels, c => {
|
let removedPrivateChannels = filterTo(unlinkedChannels, c => {
|
||||||
const permissions = utils.getPermissions(roles, guild.roles, botID, c["permission_overwrites"])
|
const permissions = dUtils.getPermissions(roles, guild.roles, botID, c["permission_overwrites"])
|
||||||
return utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.ViewChannel)
|
return dUtils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.ViewChannel)
|
||||||
})
|
})
|
||||||
unlinkedChannels.sort((a, b) => getPosition(a) - getPosition(b))
|
unlinkedChannels.sort((a, b) => getPosition(a) - getPosition(b))
|
||||||
|
|
||||||
@@ -228,7 +230,7 @@ as.router.post("/api/invite", defineEventHandler(async event => {
|
|||||||
( parsedBody.permissions === "admin" ? 100
|
( parsedBody.permissions === "admin" ? 100
|
||||||
: parsedBody.permissions === "moderator" ? 50
|
: parsedBody.permissions === "moderator" ? 50
|
||||||
: 0)
|
: 0)
|
||||||
if (powerLevel) await api.setUserPowerCascade(spaceID, parsedBody.mxid, powerLevel)
|
if (powerLevel) await mxUtils.setUserPowerCascade(spaceID, parsedBody.mxid, powerLevel, api)
|
||||||
|
|
||||||
if (parsedBody.guild_id) {
|
if (parsedBody.guild_id) {
|
||||||
setResponseHeader(event, "HX-Refresh", true)
|
setResponseHeader(event, "HX-Refresh", true)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ const {z} = require("zod")
|
|||||||
const {defineEventHandler, getValidatedQuery, H3Event} = require("h3")
|
const {defineEventHandler, getValidatedQuery, H3Event} = require("h3")
|
||||||
const {as, from, sync, select} = require("../../passthrough")
|
const {as, from, sync, select} = require("../../passthrough")
|
||||||
|
|
||||||
/** @type {import("../../m2d/converters/utils")} */
|
/** @type {import("../../matrix/utils")} */
|
||||||
const mUtils = sync.require("../../m2d/converters/utils")
|
const mUtils = sync.require("../../matrix/utils")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {H3Event} event
|
* @param {H3Event} event
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ const {discord, db, as, sync, select, from} = require("../../passthrough")
|
|||||||
const auth = sync.require("../auth")
|
const auth = sync.require("../auth")
|
||||||
/** @type {import("../../matrix/mreq")} */
|
/** @type {import("../../matrix/mreq")} */
|
||||||
const mreq = sync.require("../../matrix/mreq")
|
const mreq = sync.require("../../matrix/mreq")
|
||||||
/** @type {import("../../m2d/converters/utils")}*/
|
/** @type {import("../../matrix/utils")}*/
|
||||||
const utils = sync.require("../../m2d/converters/utils")
|
const utils = sync.require("../../matrix/utils")
|
||||||
const {reg} = require("../../matrix/read-registration")
|
const {reg} = require("../../matrix/read-registration")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-2
@@ -13,8 +13,8 @@ const reg = require("../matrix/read-registration")
|
|||||||
const {sync, discord, as, select} = require("../passthrough")
|
const {sync, discord, as, select} = require("../passthrough")
|
||||||
/** @type {import("./pug-sync")} */
|
/** @type {import("./pug-sync")} */
|
||||||
const pugSync = sync.require("./pug-sync")
|
const pugSync = sync.require("./pug-sync")
|
||||||
/** @type {import("../m2d/converters/utils")} */
|
/** @type {import("../matrix/utils")} */
|
||||||
const mUtils = sync.require("../m2d/converters/utils")
|
const mUtils = sync.require("../matrix/utils")
|
||||||
const {id} = require("../../addbot")
|
const {id} = require("../../addbot")
|
||||||
|
|
||||||
// Pug
|
// Pug
|
||||||
|
|||||||
+1
-1
@@ -147,6 +147,7 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
|
|||||||
require("../src/matrix/mreq.test")
|
require("../src/matrix/mreq.test")
|
||||||
require("../src/matrix/read-registration.test")
|
require("../src/matrix/read-registration.test")
|
||||||
require("../src/matrix/txnid.test")
|
require("../src/matrix/txnid.test")
|
||||||
|
require("../src/matrix/utils.test")
|
||||||
require("../src/d2m/actions/create-room.test")
|
require("../src/d2m/actions/create-room.test")
|
||||||
require("../src/d2m/actions/create-space.test")
|
require("../src/d2m/actions/create-space.test")
|
||||||
require("../src/d2m/actions/register-user.test")
|
require("../src/d2m/actions/register-user.test")
|
||||||
@@ -164,7 +165,6 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
|
|||||||
require("../src/m2d/converters/diff-pins.test")
|
require("../src/m2d/converters/diff-pins.test")
|
||||||
require("../src/m2d/converters/event-to-message.test")
|
require("../src/m2d/converters/event-to-message.test")
|
||||||
require("../src/m2d/converters/emoji.test")
|
require("../src/m2d/converters/emoji.test")
|
||||||
require("../src/m2d/converters/utils.test")
|
|
||||||
require("../src/m2d/converters/emoji-sheet.test")
|
require("../src/m2d/converters/emoji-sheet.test")
|
||||||
require("../src/discord/interactions/invite.test")
|
require("../src/discord/interactions/invite.test")
|
||||||
require("../src/discord/interactions/matrix-info.test")
|
require("../src/discord/interactions/matrix-info.test")
|
||||||
|
|||||||
Reference in New Issue
Block a user