aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/muc
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2020-03-12 16:01:31 +0000
committerMatthew Wild <mwild1@gmail.com>2020-03-12 16:01:31 +0000
commit64bb781dfec9b44618da58991aab292b1e360be1 (patch)
treed006ce78b81e596d47d0152a6356ef96939d7b7c /plugins/muc
parent572526d384fa79688a189c2e5d37614036b7ffd3 (diff)
downloadprosody-64bb781dfec9b44618da58991aab292b1e360be1.tar.gz
prosody-64bb781dfec9b44618da58991aab292b1e360be1.zip
MUC: Support for broadcasting unavailable presence for affiliated offline users
Activated when muc#roomconfig_presencebroadcast includes the "none" role.
Diffstat (limited to 'plugins/muc')
-rw-r--r--plugins/muc/muc.lib.lua25
-rw-r--r--plugins/muc/presence_broadcast.lib.lua2
2 files changed, 24 insertions, 3 deletions
diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua
index 42f41831..5f45498a 100644
--- a/plugins/muc/muc.lib.lua
+++ b/plugins/muc/muc.lib.lua
@@ -333,7 +333,9 @@ function room_mt:send_occupant_list(to, filter)
end
end
end
+ local broadcast_bare_jids = {}; -- Track which bare JIDs we have sent presence for
for occupant_jid, occupant in self:each_occupant() do
+ broadcast_bare_jids[occupant.bare_jid] = true;
if filter == nil or filter(occupant_jid, occupant) then
local x = st.stanza("x", {xmlns='http://jabber.org/protocol/muc#user'});
self:build_item_list(occupant, x, is_anonymous and to_bare ~= occupant.bare_jid); -- can always see your own jids
@@ -345,6 +347,25 @@ function room_mt:send_occupant_list(to, filter)
end
end
end
+ if broadcast_roles.none then
+ -- Broadcast stanzas for affiliated users not currently in the MUC
+ for affiliated_jid, affiliation, affiliation_data in self:each_affiliation() do
+ local nick = affiliation_data and affiliation_data.reserved_nickname;
+ if (nick or not is_anonymous) and not broadcast_bare_jids[affiliated_jid]
+ and (filter == nil or filter(affiliated_jid, nil)) then
+ local from = nick and (self.jid.."/"..nick) or self.jid;
+ local pres = st.presence({ to = to, from = from, type = "unavailable" })
+ :tag("x", { xmlns = 'http://jabber.org/protocol/muc#user' })
+ :tag("item", {
+ affiliation = affiliation;
+ role = "none";
+ nick = nick;
+ jid = not is_anonymous and affiliated_jid or nil }):up()
+ :up();
+ self:route_stanza(pres);
+ end
+ end
+ end
end
function room_mt:get_disco_info(stanza)
@@ -670,7 +691,7 @@ function room_mt:handle_normal_presence(origin, stanza)
-- Send occupant list to newly joined or desynced user
self:send_occupant_list(real_jid, function(nick, occupant) -- luacheck: ignore 212
-- Don't include self
- return occupant:get_presence(real_jid) == nil;
+ return (not occupant) or occupant:get_presence(real_jid) == nil;
end)
end
local dest_x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
@@ -1378,7 +1399,7 @@ function room_mt:set_affiliation(actor, jid, affiliation, reason, data)
-- Send everyone else's presences (as jid visibility has changed)
for real_jid in occupant:each_session() do
self:send_occupant_list(real_jid, function(occupant_jid, occupant) --luacheck: ignore 212 433
- return occupant.bare_jid ~= jid;
+ return (not occupant) or occupant.bare_jid ~= jid;
end);
end
end
diff --git a/plugins/muc/presence_broadcast.lib.lua b/plugins/muc/presence_broadcast.lib.lua
index 72e0d76b..82a89fee 100644
--- a/plugins/muc/presence_broadcast.lib.lua
+++ b/plugins/muc/presence_broadcast.lib.lua
@@ -9,7 +9,7 @@
local st = require "util.stanza";
-local valid_roles = { "visitor", "participant", "moderator" };
+local valid_roles = { "none", "visitor", "participant", "moderator" };
local default_broadcast = {
visitor = true;
participant = true;