--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_cloud_notify_filters/mod_cloud_notify_filters.lua Wed Jan 13 16:50:47 2021 +0000
@@ -0,0 +1,99 @@
+local jid = require "util.jid";
+
+local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
+
+local xmlns_push = "urn:xmpp:push:0";
+local xmlns_push_filter_unknown = "tigase:push:filter:ignore-unknown:0";
+local xmlns_push_filter_muted = "tigase:push:filter:muted:0";
+local xmlns_push_filter_groupchat = "tigase:push:filter:groupchat:0";
+local xmlns_references = "urn:xmpp:reference:0";
+
+-- https://xeps.tigase.net//docs/push-notifications/encrypt/#41-discovering-support
+local function account_disco_info(event)
+ event.reply:tag("feature", {var=xmlns_push_filter_unknown}):up();
+ event.reply:tag("feature", {var=xmlns_push_filter_muted}):up();
+ event.reply:tag("feature", {var=xmlns_push_filter_groupchat}):up();
+end
+module:hook("account-disco-info", account_disco_info);
+
+function handle_register(event)
+ local enable = event.stanza:get_child("enable", xmlns_push);
+
+ local filter_unknown = enable:get_child("ignore-unknown", xmlns_push_filter_unknown);
+ if filter_unknown then
+ event.push_info.filter_unknown = true;
+ end
+
+ local filter_muted = enable:get_child("muted", xmlns_push_filter_muted);
+ if filter_muted then
+ local muted_jids = {};
+ for item in filter_muted:childtags("item") do
+ muted_jids[jid.prep(item.attr.jid)] = true;
+ end
+ event.push_info.muted_jids = muted_jids;
+ end
+
+ local filter_groupchat = enable:get_child("groupchat", xmlns_push_filter_groupchat);
+ if filter_groupchat then
+ local groupchat_rules = {};
+ for item in filter_groupchat:childtags("room") do
+ groupchat_rules[jid.prep(item.attr.jid)] = {
+ when = item.attr.allow;
+ nick = item.attr.nick;
+ };
+ end
+ event.push_info.groupchat_rules = groupchat_rules;
+ end
+end
+
+function handle_push(event)
+ local push_info = event.push_info;
+ local stanza = event.original_stanza;
+ local user_name, user_host = jid.split(stanza.attr.to);
+ local sender_jid = jid.bare(stanza.attr.from);
+
+ if push_info.filter_unknown then
+ if user_host == module.host and not is_contact_subscribed(user_name, user_host, sender_jid) then
+ event.reason = "Filtering: unknown sender";
+ return true;
+ end
+ end
+
+ if push_info.muted_jids then
+ if push_info.muted_jids[sender_jid] then
+ event.reason = "Filtering: muted";
+ return true;
+ end
+ end
+
+ if stanza.attr.type == "groupchat" and push_info.groupchat_rules then
+ local rule = push_info.groupchat_rules[sender_jid];
+ if rule then
+ if rule.when == "never" then
+ event.reason = "Filtering: muted group chat";
+ return true;
+ elseif rule.when == "mentioned" then
+ local mentioned = false;
+ local our_uri = "xmpp:"..jid.bare(stanza.attr.to);
+ local our_muc_uri = rule.nick and "xmpp:"..sender_jid.."/"..rule.nick;
+ for reference in stanza:childtags("reference", xmlns_references) do
+ if reference.attr.type == "mention" then
+ local mention_uri = reference.attr.uri;
+ if mention_uri == our_uri or mention_uri == our_muc_uri then
+ mentioned = true;
+ break;
+ end
+ end
+ end
+ if not mentioned then
+ event.reason = "Filtering: not mentioned";
+ return true;
+ end
+ end
+ end
+ end
+end
+
+module:hook("cloud_notify/registration", handle_register);
+module:hook("cloud_notify/push", handle_push);
+