Software / code / prosody-modules
File
mod_sift/mod_sift.lua @ 6296:1661f6a74141
Multible community modules: Update Readme
diff --git a/mod_admin_blocklist/README.md b/mod_admin_blocklist/README.md
--- a/mod_admin_blocklist/README.md
+++ b/mod_admin_blocklist/README.md
@@ -24,8 +24,9 @@ admin_blocklist_roles = { "prosody:opera
# Compatibility
Prosody-Version Status
- --------------- ------
- trunk* Works
- 0.12 Works
+ -------------- ------
+ trunk* Works
+ 13 Works
+ 0.12 Works
-*as of 2024-12-21
+ *as of 2025-06-13
diff --git a/mod_audit/README.md b/mod_audit/README.md
--- a/mod_audit/README.md
+++ b/mod_audit/README.md
@@ -52,6 +52,7 @@ prosodyctl mod_audit user@example.com
# Compatibilty
-Requires Prosody **trunk** as of 2025-02-11.
-
-Does not work with Prosody 0.12 or earlier.
+ Prosody-Version Status
+ ----- ------
+ 13 Works
+ 0.12 Does not work
diff --git a/mod_csi_grace_period/README.md b/mod_csi_grace_period/README.md
--- a/mod_csi_grace_period/README.md
+++ b/mod_csi_grace_period/README.md
@@ -16,9 +16,9 @@ pocket is not the best use of radio time
Works with [mod_csi_simple][doc:modules:mod_csi_simple] which is
included with Prosody.
- ------- --------------
- trunk* Works
- 0.12 Works
- ------- --------------
+ ------- -------
+ trunk* Works
+ 13 Works
+ 0.12 Works
-*as of 2024-10-22
+ *as of 2025-06-13
diff --git a/mod_http_upload_external/README.md b/mod_http_upload_external/README.md
--- a/mod_http_upload_external/README.md
+++ b/mod_http_upload_external/README.md
@@ -19,7 +19,6 @@ Implementations
* [PHP implementation](https://hg.prosody.im/prosody-modules/raw-file/tip/mod_http_upload_external/share.php)
* [Python3+Flask implementation](https://github.com/horazont/xmpp-http-upload)
* [Go implementation, Prosody Filer](https://github.com/ThomasLeister/prosody-filer)
-* [Go implementation, HMAC File Server](https://github.com/PlusOne/hmac-file-server)
* [Perl implementation for nginx](https://github.com/weiss/ngx_http_upload)
* [Rust implementation](https://gitlab.com/nyovaya/xmpp-http-upload)
@@ -88,9 +87,10 @@ Compatibility
=============
Prosody-Version Status
- ---------------- --------------------
- trunk Works as of 24-12-12
- 0.12 Works
+ ---------------- --------------------
+ trunk Works as of 25-06-13
+ 13 Works
+ 0.12 Works
Implementation
==============
diff --git a/mod_muc_moderation/README.md b/mod_muc_moderation/README.md
--- a/mod_muc_moderation/README.md
+++ b/mod_muc_moderation/README.md
@@ -27,10 +27,11 @@ modules_enabled = {
# Compatibility
- ------- ---------------
- trunk Works^[as of 2024-10-22]
- 0.12 Works
- ------- ---------------
+ ------- ---------------
+ trunk Works^[as of 2025-06-13]
+ 13 Works
+ 0.12 Works
+ ------- ---------------
## XEP version
diff --git a/mod_s2s_idle_timeout/README.md b/mod_s2s_idle_timeout/README.md
--- a/mod_s2s_idle_timeout/README.md
+++ b/mod_s2s_idle_timeout/README.md
@@ -25,9 +25,10 @@ Compatibility
=============
Prosody Version Status
- ----------------- -----------
- trunk[^1] Works
- 0.12 Works
- ----------------- -----------
+ ----------------- -----------
+ trunk[^1] Works
+ 13 Works
+ 0.12 Works
+ ----------------- -----------
-[^1]: as of 2024-10-22
+[^1]: as of 2025-06-13
diff --git a/mod_s2s_keepalive/README.md b/mod_s2s_keepalive/README.md
--- a/mod_s2s_keepalive/README.md
+++ b/mod_s2s_keepalive/README.md
@@ -34,9 +34,10 @@ Compatibility
=============
Prosody Version Status
- ----------------- -----------
- trunk[^1] Works
- 0.12 Works
- ----------------- -----------
+ ----------------- -----------
+ trunk[^1] Works
+ 13 Works
+ 0.12 Works
+ ----------------- -----------
-[^1]: as of 2024-11-11
+[^1]: as of 2025-06-13
| author | Menel <menel@snikket.de> |
|---|---|
| date | Fri, 13 Jun 2025 09:53:41 +0200 |
| parent | 1343:7dbde05b48a9 |
line wrap: on
line source
local st = require "util.stanza"; local jid_bare = require "util.jid".bare; -- advertise disco features module:add_feature("urn:xmpp:sift:1"); -- supported features module:add_feature("urn:xmpp:sift:stanzas:iq"); module:add_feature("urn:xmpp:sift:stanzas:message"); module:add_feature("urn:xmpp:sift:stanzas:presence"); module:add_feature("urn:xmpp:sift:recipients:all"); module:add_feature("urn:xmpp:sift:senders:all"); -- allowed values of 'sender' and 'recipient' attributes local senders = { ["all"] = true; ["local"] = true; ["others"] = true; ["remote"] = true; ["self"] = true; }; local recipients = { ["all"] = true; ["bare"] = true; ["full"] = true; }; -- this function converts a <message/>, <presence/> or <iq/> element in -- the SIFT namespace into a hashtable, for easy lookup local function to_hashtable(element) if element ~= nil then local hash = {}; -- make sure the sender and recipient attributes has a valid value hash.sender = element.attr.sender or "all"; if not senders[hash.sender] then return false; end -- bad value, returning false hash.recipient = element.attr.recipient or "all"; if not recipients[hash.recipient] then return false; end -- bad value, returning false -- next we loop over all <allow/> elements for _, tag in ipairs(element) do if tag.name == "allow" and tag.attr.xmlns == "urn:xmpp:sift:1" then -- make sure the element is valid if not tag.attr.name or not tag.attr.ns then return false; end -- missing required attributes, returning false hash[tag.attr.ns.."|"..tag.attr.name] = true; hash.allowed = true; -- just a flag indicating we have some elements allowed end end return hash; end end local data = {}; -- table with all our data -- handle SIFT set module:hook("iq/self/urn:xmpp:sift:1:sift", function(event) local origin, stanza = event.origin, event.stanza; if stanza.attr.type == "set" then local sifttag = stanza.tags[1]; -- <sift/> -- first, get the elements we are interested in local message = sifttag:get_child("message"); local presence = sifttag:get_child("presence"); local iq = sifttag:get_child("iq"); -- for quick lookup, convert the elements into hashtables message = to_hashtable(message); presence = to_hashtable(presence); iq = to_hashtable(iq); -- make sure elements were valid if message == false or presence == false or iq == false then origin.send(st.error_reply(stanza, "modify", "bad-request")); return true; end local existing = data[origin.full_jid] or {}; -- get existing data, if any data[origin.full_jid] = { presence = presence, message = message, iq = iq }; -- store new data origin.send(st.reply(stanza)); -- send back IQ result if not existing.presence and not origin.presence and presence then -- TODO send probes end return true; end end); -- handle user disconnect module:hook("resource-unbind", function(event) data[event.session.full_jid] = nil; -- discard data end); -- IQ handler module:hook("iq/full", function(event) local origin, stanza = event.origin, event.stanza; local siftdata = data[stanza.attr.to]; if stanza.attr.type == "get" or stanza.attr.type == "set" then if siftdata and siftdata.iq then -- we seem to have an IQ filter local tag = stanza.tags[1]; -- the IQ child if not siftdata.iq[(tag.attr.xmlns or "jabber:client").."|"..tag.name] then -- element not allowed; sending back generic error origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); return true; end end end end, 50); -- Message to full JID handler module:hook("message/full", function(event) local origin, stanza = event.origin, event.stanza; local siftdata = data[stanza.attr.to]; if siftdata and siftdata.message then -- we seem to have an message filter local allowed = false; for _, childtag in ipairs(stanza.tags) do if siftdata.message[(childtag.attr.xmlns or "jabber:client").."|"..childtag.name] then allowed = true; end end if not allowed then -- element not allowed; sending back generic error origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); -- FIXME maybe send to offline storage return true; end end end, 50); -- Message to bare JID handler module:hook("message/bare", function(event) local origin, stanza = event.origin, event.stanza; local user = bare_sessions[jid_bare(stanza.attr.to)]; local allowed = false; for _, session in pairs(user and user.sessions or {}) do local siftdata = data[session.full_jid]; if siftdata and siftdata.message then -- we seem to have an message filter for _, childtag in ipairs(stanza.tags) do if siftdata.message[(childtag.attr.xmlns or "jabber:client").."|"..childtag.name] then allowed = true; end end else allowed = true; end end if user and not allowed then -- element not allowed; sending back generic error origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); -- FIXME maybe send to offline storage return true; end end, 50); -- Presence to full JID handler module:hook("presence/full", function(event) local origin, stanza = event.origin, event.stanza; local siftdata = data[stanza.attr.to]; if siftdata and siftdata.presence then -- we seem to have an presence filter local allowed = false; for _, childtag in ipairs(stanza.tags) do if siftdata.presence[(childtag.attr.xmlns or "jabber:client").."|"..childtag.name] then allowed = true; end end if not allowed then -- element not allowed; sending back generic error --origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); return true; end end end, 50); -- Presence to bare JID handler module:hook("presence/bare", function(event) local origin, stanza = event.origin, event.stanza; local user = bare_sessions[jid_bare(stanza.attr.to)]; local allowed = false; for _, session in pairs(user and user.sessions or {}) do local siftdata = data[session.full_jid]; if siftdata and siftdata.presence then -- we seem to have an presence filter for _, childtag in ipairs(stanza.tags) do if siftdata.presence[(childtag.attr.xmlns or "jabber:client").."|"..childtag.name] then allowed = true; end end else allowed = true; end end if user and not allowed then -- element not allowed; sending back generic error --origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); return true; end end, 50);