Changeset

6156:bcad6baa4fc3

mod_muc_moderation: partial support for XEP-0425 v0.3.0 (no tombstones)
author nicoco <nicoco@nicoco.fr>
date Fri, 17 Jan 2025 10:20:00 +0100
parents 6155:d80e398a2acc
children 6157:ddb0fac151ac
files mod_muc_moderation/README.md mod_muc_moderation/mod_muc_moderation.lua
diffstat 2 files changed, 50 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mod_muc_moderation/README.md	Fri Jan 17 11:02:02 2025 +0000
+++ b/mod_muc_moderation/README.md	Fri Jan 17 10:20:00 2025 +0100
@@ -32,6 +32,11 @@
   0.12    Works
   ------- ---------------
 
+## XEP version
+
+This module implements [XEP-0425] v0.2.1 (tombstones included) and v0.3.0
+(except for tombstones).
+
 ## Clients
 
 -   [Converse.js](https://conversejs.org/)
--- a/mod_muc_moderation/mod_muc_moderation.lua	Fri Jan 17 11:02:02 2025 +0000
+++ b/mod_muc_moderation/mod_muc_moderation.lua	Fri Jan 17 10:20:00 2025 +0100
@@ -27,12 +27,15 @@
 -- Namespaces
 local xmlns_fasten = "urn:xmpp:fasten:0";
 local xmlns_moderate = "urn:xmpp:message-moderate:0";
+local xmlns_moderate_1 = "urn:xmpp:message-moderate:1";
 local xmlns_occupant_id = "urn:xmpp:occupant-id:0";
 local xmlns_retract = "urn:xmpp:message-retract:0";
+local xmlns_retract_1 = "urn:xmpp:message-retract:1";
 
 -- Discovering support
 module:hook("muc-disco#info", function (event)
 	event.reply:tag("feature", { var = xmlns_moderate }):up();
+	event.reply:tag("feature", { var = xmlns_moderate_1 }):up();
 end);
 
 -- TODO error registry, requires Prosody 0.12+
@@ -107,8 +110,20 @@
 		announcement:add_direct_child(moderated_occupant_id);
 	end
 
+	-- XEP 0425 v0.3.0
+
 	announcement:reset();
 
+	if retract then
+		announcement:tag("retract", { xmlns = xmlns_retract_1 })
+			:tag("moderated", { xmlns = xmlns_moderate_1 })
+			:tag("occupant-id", { xmlns = xmlns_occupant_id; id = room:get_occupant_id(actor_occupant) });
+		if reason then
+			announcement:up():up():text_tag("reason", reason);
+		end
+	end
+
+
 	local tombstone = nil;
 	if muc_log_archive.set and retract then
 		tombstone = st.message({ from = original.attr.from, type = "groupchat", id = original.attr.id })
@@ -189,6 +204,36 @@
 	return true;
 end);
 
+module:hook("iq-set/bare/" .. xmlns_moderate_1 .. ":moderate", function (event)
+	local stanza, origin = event.stanza, event.origin;
+
+	local actor = stanza.attr.from;
+	local room_jid = stanza.attr.to;
+
+	local moderate_tag = stanza:get_child("moderate", xmlns_moderate_1)
+	local retract_tag = moderate_tag:get_child("retract", xmlns_retract_1)
+
+	if not retract_tag then return end -- other kind of moderation?
+
+	local reason = moderate_tag:get_child_text("reason");
+	local stanza_id = moderate_tag.attr.id
+
+	local ok, error_type, error_condition, error_text = moderate(
+		actor,
+		room_jid,
+		stanza_id,
+		retract_tag,
+		reason
+	);
+	if not ok then
+		origin.send(st.error_reply(stanza, error_type, error_condition, error_text));
+		return true;
+	end
+
+	origin.send(st.reply(stanza));
+	return true;
+end);
+
 module:hook("muc-message-is-historic", function (event)
 	-- Ensure moderation messages are stored
 	if event.stanza.attr.from == event.room.jid then