forked from cadence/out-of-your-element
		
	Give sims enough power to send to read-only rooms
This commit is contained in:
		
							parent
							
								
									65498e6cd1
								
							
						
					
					
						commit
						10a3185823
					
				
					 4 changed files with 107 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue