local st = require "util.stanza"; local function get_allow_pm(room) return room._data.allow_pm or 'everyone'; end local function set_allow_pm(room, val) if get_allow_pm(room) == val then return false; end room._data.allow_pm = val; return true; end local function get_allow_modpm(room) return room._data.allow_modpm or false; end local function set_allow_modpm(room, val) if get_allow_modpm(room) == val then return false; end room._data.allow_modpm = val; return true; end module:hook("muc-config-form", function(event) local pmval = get_allow_pm(event.room); table.insert(event.form, { name = 'muc#allow_pm'; type = 'list-single'; label = 'Allow PMs from'; options = { { value = 'everyone', label = 'Everyone', default = pmval == 'everyone' }, { value = 'participants', label = 'Participants', default = pmval == 'participants' }, { value = 'members', label = 'Members', default = pmval == 'members' }, { value = 'moderators', label = 'Moderators', default = pmval == 'moderators' }, { value = 'none', label = 'No one', default = pmval == 'none' } } }); table.insert(event.form, { name = 'muc#allow_modpm'; type = 'boolean'; label = 'Allow PMs to moderators'; value = get_allow_modpm(event.room) }); end); module:hook("muc-config-submitted/muc#allow_pm", function(event) if set_allow_pm(event.room, event.value) then event.status_codes["104"] = true; end end); module:hook("muc-config-submitted/muc#allow_modpm", function(event) if set_allow_modpm(event.room, event.value) then event.status_codes["104"] = true; end end); module:hook("muc-private-message", function(event) local stanza, room = event.stanza, event.room; local from_occupant = room:get_occupant_by_nick(stanza.attr.from); local to_occupant = room:get_occupant_by_nick(stanza.attr.to); -- To self is always okay if to_occupant.bare_jid == from_occupant.bare_jid then return; end if get_allow_modpm(room) and to_occupant and to_occupant.role == 'moderator' then return; end local pmval = get_allow_pm(room); local from_affiliation = room:get_affiliation(from_occupant.bare_jid) or 'none'; local to_affiliation = room:get_affiliation(to_occupant.bare_jid) or 'none'; if pmval == 'everyone' then return; elseif pmval == 'participants' and from_occupant.role ~= 'visitor' then if to_occupant.role ~= 'visitor' or from_occupant.role == 'moderator' then return; end elseif pmval == 'members' and from_affiliation ~= 'none' then if to_affiliation ~= 'none' or from_occupant.role == 'moderator' then return; end elseif pmval == 'moderators' and from_occupant.role == 'moderator' then return; end room:route_to_occupant( from_occupant, st.error_reply(stanza, "cancel", "policy-violation", "Private messages are restricted", room.jid) ); return false; end, 1);