diff --git a/resources/prosody-plugins/mod_muc_allowners.lua b/resources/prosody-plugins/mod_muc_allowners.lua index 2a4ca19a3..c1f9f2a2e 100644 --- a/resources/prosody-plugins/mod_muc_allowners.lua +++ b/resources/prosody-plugins/mod_muc_allowners.lua @@ -1,8 +1,12 @@ +local filters = require 'util.filters'; local jid = require "util.jid"; +local jid_bare = require "util.jid".bare; local um_is_admin = require "core.usermanager".is_admin; local util = module:require "util"; local is_healthcheck_room = util.is_healthcheck_room; local extract_subdomain = util.extract_subdomain; +local presence_check_status = util.presence_check_status; +local MUC_NS = 'http://jabber.org/protocol/muc'; local moderated_subdomains; local moderated_rooms; @@ -17,6 +21,11 @@ local function is_admin(jid) return um_is_admin(jid, module.host); end +-- List of the bare_jids of all occupants that are currently joining (went through pre-join) and will be promoted +-- as moderators. As pre-join (where added) and joined event (where removed) happen one after another this list should +-- have length of 1 +local joining_moderator_participants = {}; + -- Checks whether the jid is moderated, the room name is in moderated_rooms -- or if the subdomain is in the moderated_subdomains -- @return returns on of the: @@ -43,10 +52,10 @@ local function is_moderated(room_jid) return false; end -module:hook("muc-occupant-joined", function (event) +module:hook("muc-occupant-pre-join", function (event) local room, occupant = event.room, event.occupant; - if is_healthcheck_room(room.jid) or is_admin(occupant.jid) then + if is_healthcheck_room(room.jid) or is_admin(occupant.bare_jid) then return; end @@ -71,7 +80,20 @@ module:hook("muc-occupant-joined", function (event) end end - room:set_affiliation(true, occupant.bare_jid, "owner"); + -- mark this participant that it will be promoted and is currently joining + joining_moderator_participants[occupant.bare_jid] = true; +end, 2); + +module:hook("muc-occupant-joined", function (event) + local room, occupant = event.room, event.occupant; + + local promote_to_moderator = joining_moderator_participants[occupant.bare_jid]; + -- clear it + joining_moderator_participants[occupant.bare_jid] = nil; + + if promote_to_moderator ~= nil then + room:set_affiliation(true, occupant.bare_jid, "owner"); + end end, 2); module:hook("muc-occupant-left", function (event) @@ -85,3 +107,29 @@ module:hook("muc-occupant-left", function (event) end, 2); module:hook_global('config-reloaded', load_config); + +-- Filters self-presences to a jid that exist in joining_participants array +-- We want to filter those presences where we send first `participant` and just after it `moderator` +function filter_stanza(stanza) + if not stanza.attr or not stanza.attr.to or stanza.name ~= "presence" then + return stanza; + end + + -- Allow self-presence (code=110) + local bare_to = jid_bare(stanza.attr.to); + + if joining_moderator_participants[bare_to] then + if presence_check_status(stanza:get_child('x', MUC_NS..'#user'), '110') then + return nil; + end + end + + return stanza; +end +function filter_session(session) + -- domain mapper is filtering on default priority 0, and we need it after that + filters.add_filter(session, 'stanzas/out', filter_stanza, -1); +end + +-- enable filtering presences +filters.add_filter_hook(filter_session); diff --git a/resources/prosody-plugins/mod_muc_lobby_rooms.lua b/resources/prosody-plugins/mod_muc_lobby_rooms.lua index 0c7fad4a5..ac2da1dda 100644 --- a/resources/prosody-plugins/mod_muc_lobby_rooms.lua +++ b/resources/prosody-plugins/mod_muc_lobby_rooms.lua @@ -38,7 +38,9 @@ local NOTIFY_LOBBY_ENABLED = 'LOBBY-ENABLED'; local NOTIFY_LOBBY_ACCESS_GRANTED = 'LOBBY-ACCESS-GRANTED'; local NOTIFY_LOBBY_ACCESS_DENIED = 'LOBBY-ACCESS-DENIED'; -local is_healthcheck_room = module:require 'util'.is_healthcheck_room; +local util = module:require "util"; +local is_healthcheck_room = util.is_healthcheck_room; +local presence_check_status = util.presence_check_status; local main_muc_component_config = module:get_option_string('main_muc'); if main_muc_component_config == nil then @@ -63,21 +65,6 @@ load_config(); local lobby_muc_service; local main_muc_service; --- Checks whether there is status in the