Give sims enough power to send to read-only rooms
This commit is contained in:
@@ -40,6 +40,8 @@ const PRIVACY_ENUMS = {
|
||||
|
||||
const DEFAULT_PRIVACY_LEVEL = 0
|
||||
|
||||
const READ_ONLY_ROOM_EVENTS_DEFAULT_POWER = 50
|
||||
|
||||
/** @type {Map<string, Promise<string>>} channel ID -> Promise<room ID> */
|
||||
const inflightRoomCreate = new Map()
|
||||
|
||||
@@ -146,7 +148,7 @@ async function channelToKState(channel, guild, di) {
|
||||
"m.room.join_rules/": join_rules,
|
||||
/** @type {Ty.Event.M_Power_Levels} */
|
||||
"m.room.power_levels/": {
|
||||
events_default: everyoneCanSend ? 0 : 50,
|
||||
events_default: everyoneCanSend ? 0 : READ_ONLY_ROOM_EVENTS_DEFAULT_POWER,
|
||||
events: {
|
||||
"m.reaction": 0,
|
||||
"m.room.redaction": 0 // only affects redactions of own events, required to be able to un-react
|
||||
@@ -557,6 +559,7 @@ async function createAllForGuild(guildID) {
|
||||
}
|
||||
|
||||
module.exports.DEFAULT_PRIVACY_LEVEL = DEFAULT_PRIVACY_LEVEL
|
||||
module.exports.READ_ONLY_ROOM_EVENTS_DEFAULT_POWER = READ_ONLY_ROOM_EVENTS_DEFAULT_POWER
|
||||
module.exports.PRIVACY_ENUMS = PRIVACY_ENUMS
|
||||
module.exports.createRoom = createRoom
|
||||
module.exports.ensureRoom = ensureRoom
|
||||
|
@@ -15,6 +15,8 @@ const file = sync.require("../../matrix/file")
|
||||
const utils = sync.require("../../discord/utils")
|
||||
/** @type {import("../converters/user-to-mxid")} */
|
||||
const userToMxid = sync.require("../converters/user-to-mxid")
|
||||
/** @type {import("./create-room")} */
|
||||
const createRoom = sync.require("./create-room")
|
||||
/** @type {import("xxhash-wasm").XXHashAPI} */ // @ts-ignore
|
||||
let hasher = null
|
||||
// @ts-ignore
|
||||
@@ -139,6 +141,7 @@ function memberToPowerLevel(user, member, guild, channel) {
|
||||
if (!member) return 0
|
||||
|
||||
const permissions = utils.getPermissions(member.roles, guild.roles, user.id, channel.permission_overwrites)
|
||||
const everyonePermissions = utils.getPermissions([], guild.roles, undefined, channel.permission_overwrites)
|
||||
/*
|
||||
* PL 100 = Administrator = People who can brick the room. RATIONALE:
|
||||
* - Administrator.
|
||||
@@ -158,8 +161,14 @@ function memberToPowerLevel(user, member, guild, channel) {
|
||||
* - Moderate Members.
|
||||
*/
|
||||
if (utils.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 */
|
||||
const everyoneCanSend = utils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.SendMessages)
|
||||
const userCanSend = utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.SendMessages)
|
||||
if (!everyoneCanSend && userCanSend) return createRoom.READ_ONLY_ROOM_EVENTS_DEFAULT_POWER
|
||||
/* PL 20 = Mention Everyone for technical reasons. */
|
||||
if (utils.hasSomePermissions(permissions, ["MentionEveryone"])) return 20
|
||||
const everyoneCanMentionEveryone = utils.hasPermission(everyonePermissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)
|
||||
const userCanMentionEveryone = utils.hasPermission(permissions, DiscordTypes.PermissionFlagsBits.MentionEveryone)
|
||||
if (!everyoneCanMentionEveryone && userCanMentionEveryone) return 20
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -250,3 +259,4 @@ module.exports.ensureSim = ensureSim
|
||||
module.exports.ensureSimJoined = ensureSimJoined
|
||||
module.exports.syncUser = syncUser
|
||||
module.exports.syncAllUsersInRoom = syncAllUsersInRoom
|
||||
module.exports._memberToPowerLevel = memberToPowerLevel
|
||||
|
@@ -1,10 +1,12 @@
|
||||
const {_memberToStateContent} = require("./register-user")
|
||||
const {_memberToStateContent, _memberToPowerLevel} = require("./register-user")
|
||||
const {test} = require("supertape")
|
||||
const testData = require("../../../test/data")
|
||||
const data = require("../../../test/data")
|
||||
const mixin = require("@cloudrac3r/mixin-deep")
|
||||
const DiscordTypes = require("discord-api-types/v10")
|
||||
|
||||
test("member2state: without member nick or avatar", async t => {
|
||||
t.deepEqual(
|
||||
await _memberToStateContent(testData.member.kumaccino.user, testData.member.kumaccino, testData.guild.general.id),
|
||||
await _memberToStateContent(data.member.kumaccino.user, data.member.kumaccino, data.guild.general.id),
|
||||
{
|
||||
avatar_url: "mxc://cadence.moe/UpAeIqeclhKfeiZNdIWNcXXL",
|
||||
displayname: "kumaccino",
|
||||
@@ -24,7 +26,7 @@ test("member2state: without member nick or avatar", async t => {
|
||||
|
||||
test("member2state: with global name, without member nick or avatar", async t => {
|
||||
t.deepEqual(
|
||||
await _memberToStateContent(testData.member.papiophidian.user, testData.member.papiophidian, testData.guild.general.id),
|
||||
await _memberToStateContent(data.member.papiophidian.user, data.member.papiophidian, data.guild.general.id),
|
||||
{
|
||||
avatar_url: "mxc://cadence.moe/JPzSmALLirnIprlSMKohSSoX",
|
||||
displayname: "PapiOphidian",
|
||||
@@ -44,7 +46,7 @@ test("member2state: with global name, without member nick or avatar", async t =>
|
||||
|
||||
test("member2state: with member nick and avatar", async t => {
|
||||
t.deepEqual(
|
||||
await _memberToStateContent(testData.member.sheep.user, testData.member.sheep, testData.guild.general.id),
|
||||
await _memberToStateContent(data.member.sheep.user, data.member.sheep, data.guild.general.id),
|
||||
{
|
||||
avatar_url: "mxc://cadence.moe/rfemHmAtcprjLEiPiEuzPhpl",
|
||||
displayname: "The Expert's Submarine",
|
||||
@@ -61,3 +63,57 @@ test("member2state: with member nick and avatar", async t => {
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
test("member2power: default to zero if member roles unknown", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, null, data.guild.data_horde, data.channel.saving_the_world)
|
||||
t.equal(power, 0)
|
||||
})
|
||||
|
||||
test("member2power: unremarkable = 0", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, {
|
||||
roles: []
|
||||
}, data.guild.data_horde, data.channel.general)
|
||||
t.equal(power, 0)
|
||||
})
|
||||
|
||||
test("member2power: can mention everyone = 20", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, {
|
||||
roles: ["684524730274807911"]
|
||||
}, data.guild.data_horde, data.channel.general)
|
||||
t.equal(power, 20)
|
||||
})
|
||||
|
||||
test("member2power: can send messages in protected channel due to role = 50", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, {
|
||||
roles: ["684524730274807911"]
|
||||
}, data.guild.data_horde, data.channel.saving_the_world)
|
||||
t.equal(power, 50)
|
||||
})
|
||||
|
||||
test("member2power: can send messages in protected channel due to user override = 50", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, {
|
||||
roles: []
|
||||
}, data.guild.data_horde, mixin({}, data.channel.saving_the_world, {
|
||||
permission_overwrites: data.channel.saving_the_world.permission_overwrites.concat({
|
||||
type: DiscordTypes.OverwriteType.member,
|
||||
id: data.user.clyde_ai.id,
|
||||
allow: String(DiscordTypes.PermissionFlagsBits.SendMessages),
|
||||
deny: "0"
|
||||
})
|
||||
}))
|
||||
t.equal(power, 50)
|
||||
})
|
||||
|
||||
test("member2power: can kick users = 50", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, {
|
||||
roles: ["682789592390281245"]
|
||||
}, data.guild.data_horde, data.channel.general)
|
||||
t.equal(power, 50)
|
||||
})
|
||||
|
||||
test("member2power: can manage channels = 100", async t => {
|
||||
const power = _memberToPowerLevel(data.user.clyde_ai, {
|
||||
roles: ["665290147377578005"]
|
||||
}, data.guild.data_horde, data.channel.saving_the_world)
|
||||
t.equal(power, 100)
|
||||
})
|
||||
|
34
test/data.js
34
test/data.js
@@ -37,18 +37,31 @@ module.exports = {
|
||||
id: "1161864271370666075",
|
||||
guild_id: "112760669178241024"
|
||||
},
|
||||
/** @type {DiscordTypes.APITextChannel} */
|
||||
saving_the_world: {
|
||||
type: 0,
|
||||
topic: "Anything and everything archiving/preservation related",
|
||||
rate_limit_per_user: 0,
|
||||
position: 0,
|
||||
permission_overwrites: [],
|
||||
permission_overwrites: [
|
||||
{
|
||||
id: "665289423482519565",
|
||||
type: DiscordTypes.OverwriteType.Role,
|
||||
allow: "0",
|
||||
deny: String(DiscordTypes.PermissionFlagsBits.SendMessages)
|
||||
},
|
||||
{
|
||||
id: "684524730274807911",
|
||||
type: DiscordTypes.OverwriteType.Role,
|
||||
allow: String(DiscordTypes.PermissionFlagsBits.SendMessages),
|
||||
deny: "0"
|
||||
}
|
||||
],
|
||||
parent_id: null,
|
||||
name: "saving-the-world",
|
||||
last_pin_timestamp: "2021-04-14T18:39:41+00:00",
|
||||
last_message_id: "1335828749479837750",
|
||||
id: "665310973967597573",
|
||||
flags: 0,
|
||||
guild_id: "665289423482519565"
|
||||
}
|
||||
},
|
||||
@@ -349,7 +362,7 @@ module.exports = {
|
||||
unicode_emoji: null,
|
||||
tags: {},
|
||||
position: 0,
|
||||
permissions: "2221982107557441",
|
||||
permissions: "968619318849",
|
||||
name: "@everyone",
|
||||
mentionable: false,
|
||||
managed: false,
|
||||
@@ -374,6 +387,21 @@ module.exports = {
|
||||
flags: 0,
|
||||
color: 1752220
|
||||
},
|
||||
{
|
||||
version: 1683791258594,
|
||||
unicode_emoji: null,
|
||||
tags: {},
|
||||
position: 22,
|
||||
permissions: "8194",
|
||||
name: "Moderator",
|
||||
mentionable: true,
|
||||
managed: false,
|
||||
id: "682789592390281245",
|
||||
icon: null,
|
||||
hoist: false,
|
||||
flags: 0,
|
||||
color: 1752220
|
||||
},
|
||||
{
|
||||
version: 1683791258580,
|
||||
unicode_emoji: null,
|
||||
|
Reference in New Issue
Block a user