diff options
author | Matthew Wild <mwild1@gmail.com> | 2025-02-06 17:08:46 +0000 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2025-02-06 17:08:46 +0000 |
commit | 857c61ffd3b8411ca27733d698d095ccb0d4c996 (patch) | |
tree | 6f69ee1a2a19fcb821c5ba763e0fb42527833162 /plugins/muc | |
parent | 839498eb5d7f275c21e0f63939b79bf0ff1f5fc1 (diff) | |
download | prosody-857c61ffd3b8411ca27733d698d095ccb0d4c996.tar.gz prosody-857c61ffd3b8411ca27733d698d095ccb0d4c996.zip |
mod_muc: Integrate support for vcards/avatars on MUC rooms
This was previously served by a community module (mod_vcard_muc).
It can be disabled by setting `vcard_muc = false` in the config.
Diffstat (limited to 'plugins/muc')
-rw-r--r-- | plugins/muc/mod_muc.lua | 4 | ||||
-rw-r--r-- | plugins/muc/vcard.lib.lua | 81 |
2 files changed, 85 insertions, 0 deletions
diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 1dc99f07..2ce6e19a 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -116,6 +116,10 @@ module:depends "muc_unique" module:require "muc/hats"; module:require "muc/lock"; +if module:get_option_boolean("muc_vcard", true) ~= false then + module:require "muc/vcard"; +end + module:default_permissions("prosody:admin", { ":automatic-ownership"; ":create-room"; diff --git a/plugins/muc/vcard.lib.lua b/plugins/muc/vcard.lib.lua new file mode 100644 index 00000000..81dce5bd --- /dev/null +++ b/plugins/muc/vcard.lib.lua @@ -0,0 +1,81 @@ +local mod_vcard = module:depends("vcard"); + +local jid = require "prosody.util.jid"; +local st = require "prosody.util.stanza"; + +-- This must be the same event that mod_vcard hooks +local vcard_event = "iq/bare/vcard-temp:vCard"; +local advertise_hashes = module:get_option("muc_avatar_advertise_hashes"); + +--luacheck: ignore 113/get_room_from_jid + +local function get_avatar_hash(room) + if room.avatar_hash then return room.avatar_hash; end + + local room_node = jid.split(room.jid); + local hash = mod_vcard.get_avatar_hash(room_node); + room.avatar_hash = hash; + + return hash; +end + +local function send_avatar_hash(room, to) + local hash = get_avatar_hash(room); + + local presence_vcard = st.presence({to = to, from = room.jid}) + :tag("x", { xmlns = "vcard-temp:x:update" }) + :tag("photo"):text(hash):up(); + + if to == nil then + if not advertise_hashes or advertise_hashes == "presence" then + room:broadcast_message(presence_vcard); + end + if not advertise_hashes or advertise_hashes == "message" then + room:broadcast_message(st.message({ from = room.jid, type = "groupchat" }) + :tag("x", { xmlns = "http://jabber.org/protocol/muc#user" }) + :tag("status", { code = "104" })); + end + + else + module:send(presence_vcard); + end +end + +module:hook(vcard_event, function (event) + local stanza = event.stanza; + local to = stanza.attr.to; + + if stanza.attr.type ~= "set" then + return; + end + + local room = get_room_from_jid(to); + if not room then + return; + end + + local sender_affiliation = room:get_affiliation(stanza.attr.from); + if sender_affiliation == "owner" then + event.allow_vcard_modification = true; + end +end, 10); + +if advertise_hashes ~= "none" then + module:hook("muc-occupant-joined", function (event) + send_avatar_hash(event.room, event.stanza.attr.from); + end); + module:hook("vcard-updated", function (event) + local room = get_room_from_jid(event.stanza.attr.to); + send_avatar_hash(room, nil); + end); +end + +module:hook("muc-disco#info", function (event) + event.reply:tag("feature", { var = "vcard-temp" }):up(); + + table.insert(event.form, { + name = "muc#roominfo_avatarhash", + type = "text-multi", + }); + event.formdata["muc#roominfo_avatarhash"] = get_avatar_hash(event.room); +end); |