changeset 6423:d748985de48f

mod_muc_restrict_attention: New Module based on mod_muc_restrict_media to strip Attention. Untested.
author Menel <menel@snikket.de>
date Sun, 08 Mar 2026 10:59:40 +0100
parents c41615686ce4
children ec4a0e4d950e
files mod_muc_restrict_attention/README.md mod_muc_restrict_attention/mod_muc_restrict_attention.lua
diffstat 2 files changed, 107 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_restrict_attention/README.md	Sun Mar 08 10:59:40 2026 +0100
@@ -0,0 +1,41 @@
+---
+summary: Strip XEP-0224 Attention from unaffiliated users in rooms
+labels:
+- Stage-Alpha
+...
+
+# Introduction
+
+This module adds a room configuration option to strip XEP-0224 Attention from
+unaffiliated users in MUCs.
+
+This can prevent spam and noise in clients that don't have precautions against this in place.
+
+# Configuring
+
+## Enabling
+
+``` {.lua}
+Component "rooms.example.net" "muc"
+modules_enabled = {
+    "muc_restrict_attention";
+}
+```
+
+## Settings
+
+A default setting can be provided in the config file, defaults to true:
+
+``` {.lua}
+muc_room_default_restrict_attention = true
+
+```
+
+# Todo
+
+- restrict it for Members too and also strip it from everyone per room.
+- Actually test it. Didn't find a client that allowed me to try as unaffiliated user.
+
+# Compatibility
+
+Should work with Prosody >= 13.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_restrict_attention/mod_muc_restrict_attention.lua	Sun Mar 08 10:59:40 2026 +0100
@@ -0,0 +1,66 @@
+module:depends"muc";
+
+local restrict_by_default = module:get_option_boolean("muc_room_default_restrict_attention", true);
+
+local function should_restrict_attention(room)
+	local restrict_attention = room._data.restrict_attention;
+	if restrict_attention == nil then
+		restrict_attention = restrict_by_default;
+	end
+	return restrict_attention;
+end
+
+module:hook("muc-config-form", function(event)
+	local room, form = event.room, event.form;
+	table.insert(form, {
+		name = "{xmpp:prosody.im}muc#roomconfig_unaffiliated_attention",
+		type = "boolean",
+		label = "Allow \"XEP-0224: Attention\" from non-members",
+		value = not should_restrict_attention(room),
+	});
+end);
+
+module:hook("muc-config-submitted", function(event)
+	local room, fields, changed = event.room, event.fields, event.changed;
+	local new_restrict_attention = not fields["{xmpp:prosody.im}muc#roomconfig_unaffiliated_attention"];
+	if new_restrict_attention ~= should_restrict_attention(room) then
+		if new_restrict_attention == restrict_by_default then
+			room._data.restrict_attention = nil;
+		else
+			room._data.restrict_attention = new_restrict_attention;
+		end
+		if type(changed) == "table" then
+			changed["{xmpp:prosody.im}muc#roomconfig_unaffiliated_attention"] = true;
+		else
+			event.changed = true;
+		end
+	end
+end);
+
+module:hook("muc-disco#info", function (event)
+	local room, form, formdata = event.room, event.form, event.formdata;
+
+	local allow_unaffiliated_attention = not should_restrict_attention(room);
+	table.insert(form, {
+		name = "{xmpp:prosody.im}muc#roomconfig_unaffiliated_attention",
+		type = "boolean",
+	});
+	formdata["{xmpp:prosody.im}muc#roomconfig_unaffiliated_attention"] = allow_unaffiliated_attention;
+end);
+
+local function filter_attention_tags(tag)
+	local xmlns = tag.attr.xmlns;
+	if xmlns == "urn:xmpp:attention:0" then
+		return nil;
+	end
+	return tag;
+end
+
+module:hook("muc-occupant-groupchat", function (event)
+	local stanza = event.stanza;
+	if stanza.attr.type ~= "groupchat" then return; end
+	if event.room:get_affiliation(stanza.attr.from) then return end
+	if should_restrict_attention(event.room) then
+		stanza:maptags(filter_attention_tags);
+	end
+end, 20);