diff --git a/src/mod_muc.erl b/src/mod_muc.erl index e1da09a7e..3af28e156 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -715,6 +715,10 @@ process_disco_info(#iq{type = get, from = From, to = To, lang = Lang, true -> [?NS_MAM_TMP, ?NS_MAM_0, ?NS_MAM_1, ?NS_MAM_2]; false -> [] end, + OccupantIdFeatures = case gen_mod:is_loaded(ServerHost, mod_muc_occupantid) of + true -> [?NS_OCCUPANT_ID]; + false -> [] + end, RSMFeatures = case RMod:rsm_supported() of true -> [?NS_RSM]; false -> [] @@ -725,7 +729,7 @@ process_disco_info(#iq{type = get, from = From, to = To, lang = Lang, end, Features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, ?NS_MUC, ?NS_VCARD, ?NS_MUCSUB, ?NS_MUC_UNIQUE - | RegisterFeatures ++ RSMFeatures ++ MAMFeatures], + | RegisterFeatures ++ RSMFeatures ++ MAMFeatures ++ OccupantIdFeatures], Name = mod_muc_opt:name(ServerHost), Identity = #identity{category = <<"conference">>, type = <<"text">>, diff --git a/src/mod_muc_occupantid.erl b/src/mod_muc_occupantid.erl new file mode 100644 index 000000000..ccb4a2134 --- /dev/null +++ b/src/mod_muc_occupantid.erl @@ -0,0 +1,105 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_muc_occupantid.erl +%%% Author : Badlop +%%% Purpose : Add Occupant Ids to stanzas in anonymous MUC rooms (XEP-0421) +%%% Created : +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2023 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%---------------------------------------------------------------------- + +-module(mod_muc_occupantid). + +-author('badlop@process-one.net'). + +-protocol({xep, 421, '0.1.0'}). + +-behaviour(gen_mod). + +-include_lib("xmpp/include/xmpp.hrl"). +-include("logger.hrl"). +-include("translate.hrl"). +-include("mod_muc_room.hrl"). + +-export([start/2, stop/1, + mod_options/1, mod_doc/0, depends/2]). +-export([filter_packet/3]). + +%%% +%%% gen_mod +%%% + +start(Host, _Opts) -> + ejabberd_hooks:add(muc_filter_presence, Host, + ?MODULE, filter_packet, 10), + ejabberd_hooks:add(muc_filter_message, Host, + ?MODULE, filter_packet, 10), + ok. + +stop(Host) -> + ejabberd_hooks:delete(muc_filter_presence, Host, + ?MODULE, filter_packet, 10), + ejabberd_hooks:delete(muc_filter_message, Host, + ?MODULE, filter_packet, 10), + ok. + +%%% +%%% Hooks +%%% + +filter_packet(Packet, State, _Nick) -> + case (State#state.config)#config.anonymous of + true -> + add_occupantid_packet(Packet, State#state.jid); + false -> + Packet + end. + +%%% +%%% XEP-0421 Occupant-id +%%% + +add_occupantid_packet(Packet, RoomJid) -> + From = xmpp:get_from(Packet), + OccupantId = calculate_occupantid(From, RoomJid), + OccupantElement = #occupant_id{id = OccupantId}, + xmpp:set_subtag(Packet, OccupantElement). + +calculate_occupantid(From, RoomJid) -> + Term = {jid:remove_resource(From), RoomJid, erlang:get_cookie()}, + misc:term_to_base64(crypto:hash(sha256, io_lib:format("~p", [Term]))). + +%%% +%%% Doc +%%% + +mod_options(_Host) -> + []. + +mod_doc() -> + #{desc => + [?T("This module implements " + "https://xmpp.org/extensions/xep-0421.html" + "[XEP-0421: Anonymous unique occupant identifiers for MUCs]."), "", + ?T("When the module is enabled, the feature is enabled " + "in all semi-anonymous rooms."), "", + ?T("This module is available since ejabberd 23.xx.")] + }. + +depends(_, _) -> + [{mod_muc, hard}]. diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index f6c5c4bb3..9c9b328d7 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -4362,6 +4362,12 @@ make_disco_info(_From, StateData) -> true -> [?NS_MUCSUB]; false -> [] end + ++ case gen_mod:is_loaded(StateData#state.server_host, mod_muc_occupantid) of + true -> + [?NS_OCCUPANT_ID]; + _ -> + [] + end ++ case {gen_mod:is_loaded(StateData#state.server_host, mod_mam), Config#config.mam} of {true, true} ->