Software /
code /
prosody-modules
Annotate
mod_vcard_muc/mod_vcard_muc.lua @ 3656:3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
When the avatar has been changed, a signal is sent that the room
configuration has changed. Clients then do a disco#info query to find
the SHA-1 of the new avatar. They can then fetch it as before, or not if
they have it cached already.
This is meant to be less disruptive than signaling via presence, which
caused problems for some clients.
If clients transition to the new method, the old one can eventually be removed.
The namespace is made up while waiting for standardization.
Otherwise it is very close to what's described in
https://xmpp.org/extensions/inbox/muc-avatars.html
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 25 Aug 2019 20:46:43 +0200 |
parent | 3655:d7b589dec591 |
child | 4043:a533abe6ffd0 |
rev | line source |
---|---|
3043
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
1 -- Prosody IM |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
2 -- Copyright (C) 2008-2010 Matthew Wild |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
3 -- Copyright (C) 2008-2010 Waqas Hussain |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
4 -- Copyright (C) 2018 Michel Le Bihan |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
5 -- |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
6 -- This project is MIT/X11 licensed. Please see the |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
7 -- COPYING file in the source package for more information. |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
8 -- |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
9 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
10 local st = require "util.stanza" |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
11 local jid_split = require "util.jid".split; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
12 local base64 = require"util.encodings".base64; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
13 local sha1 = require"util.hashes".sha1; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
14 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
15 local mod_muc = module:depends"muc"; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
16 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
17 local vcards = module:open_store(); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
18 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
19 module:add_feature("vcard-temp"); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
20 |
3077
f16b021e8a61
mod_vcard_muc: Get room from rooms table when get_room_from_jid API is not supported
Michel Le Bihan <michel@lebihan.pl>
parents:
3046
diff
changeset
|
21 local get_room_from_jid = rawget(mod_muc, "get_room_from_jid") or |
f16b021e8a61
mod_vcard_muc: Get room from rooms table when get_room_from_jid API is not supported
Michel Le Bihan <michel@lebihan.pl>
parents:
3046
diff
changeset
|
22 function (jid) |
f16b021e8a61
mod_vcard_muc: Get room from rooms table when get_room_from_jid API is not supported
Michel Le Bihan <michel@lebihan.pl>
parents:
3046
diff
changeset
|
23 local rooms = rawget(mod_muc, "rooms"); |
f16b021e8a61
mod_vcard_muc: Get room from rooms table when get_room_from_jid API is not supported
Michel Le Bihan <michel@lebihan.pl>
parents:
3046
diff
changeset
|
24 return rooms[jid]; |
f16b021e8a61
mod_vcard_muc: Get room from rooms table when get_room_from_jid API is not supported
Michel Le Bihan <michel@lebihan.pl>
parents:
3046
diff
changeset
|
25 end |
f16b021e8a61
mod_vcard_muc: Get room from rooms table when get_room_from_jid API is not supported
Michel Le Bihan <michel@lebihan.pl>
parents:
3046
diff
changeset
|
26 |
3655
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
27 local function get_photo_hash(room) |
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
28 local room_node = jid_split(room.jid); |
3043
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
29 local vcard = st.deserialize(vcards:get(room_node)); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
30 if vcard then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
31 local photo = vcard:get_child("PHOTO"); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
32 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
33 if photo then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
34 local photo_b64 = photo:get_child_text("BINVAL"); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
35 local photo_raw = photo_b64 and base64.decode(photo_b64); |
3655
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
36 return sha1(photo_raw, true); |
3043
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
37 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
38 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
39 |
3655
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
40 end |
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
41 |
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
42 local function broadcast_presence(room_jid, to) |
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
43 local room = get_room_from_jid(room_jid); |
d7b589dec591
mod_vcard_muc: Factor out avatar hash retrieval into a function for easier reuse
Kim Alvefur <zash@zash.se>
parents:
3077
diff
changeset
|
44 |
3656
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
45 local photo_hash = get_photo_hash(room); |
3043
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
46 local presence_vcard = st.presence({to = to, from = room_jid}) |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
47 :tag("x", { xmlns = "vcard-temp:x:update" }) |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
48 :tag("photo"):text(photo_hash):up(); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
49 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
50 if to == nil then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
51 room:broadcast_message(presence_vcard); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
52 else |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
53 module:send(presence_vcard); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
54 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
55 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
56 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
57 local function handle_vcard(event) |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
58 local session, stanza = event.origin, event.stanza; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
59 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
60 local room_jid = stanza.attr.to; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
61 local room_node = jid_split(room_jid); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
62 local room = get_room_from_jid(room_jid); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
63 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
64 local from = stanza.attr.from; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
65 local from_affiliation = room:get_affiliation(from); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
66 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
67 if stanza.attr.type == "get" then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
68 local vCard; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
69 vCard = st.deserialize(vcards:get(room_node)); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
70 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
71 if vCard then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
72 session.send(st.reply(stanza):add_child(vCard)); -- send vCard! |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
73 else |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
74 session.send(st.error_reply(stanza, "cancel", "item-not-found")); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
75 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
76 else |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
77 if from_affiliation == "owner" then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
78 if vcards:set(room_node, st.preserialize(stanza.tags[1])) then |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
79 session.send(st.reply(stanza):tag("vCard", { xmlns = "vcard-temp" })); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
80 broadcast_presence(room_jid, nil) |
3656
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
81 |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
82 room:broadcast_message(st.message({ from = room.jid, type = "groupchat" }) |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
83 :tag("x", { xmlns = "http://jabber.org/protocol/muc#user" }) |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
84 :tag("status", { code = "104" })); |
3043
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
85 else |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
86 -- TODO unable to write file, file may be locked, etc, what's the correct error? |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
87 session.send(st.error_reply(stanza, "wait", "internal-server-error")); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
88 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
89 else |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
90 session.send(st.error_reply(stanza, "auth", "forbidden")); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
91 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
92 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
93 return true; |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
94 end |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
95 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
96 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
97 module:hook("iq/bare/vcard-temp:vCard", handle_vcard); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
98 module:hook("iq/host/vcard-temp:vCard", handle_vcard); |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
99 |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
100 module:hook("muc-disco#info", function(event) |
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
101 event.reply:tag("feature", { var = "vcard-temp" }):up(); |
3656
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
102 |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
103 table.insert(event.form, { |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
104 name = "{http://modules.prosody.im/mod_vcard_muc}avatar#sha1", |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
105 type = "text-single", |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
106 }); |
3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
Kim Alvefur <zash@zash.se>
parents:
3655
diff
changeset
|
107 event.formdata["{http://modules.prosody.im/mod_vcard_muc}avatar#sha1"] = get_photo_hash(event.room); |
3043
6cc44e69443a
mod_vcard_muc: Initial commit
Michel Le Bihan <michel@lebihan.pl>
parents:
diff
changeset
|
108 end); |
3046
d0db28768980
mod_vcard_muc: Send presence on muc-occupant-session-new event
Michel Le Bihan <michel@lebihan.pl>
parents:
3043
diff
changeset
|
109 |
d0db28768980
mod_vcard_muc: Send presence on muc-occupant-session-new event
Michel Le Bihan <michel@lebihan.pl>
parents:
3043
diff
changeset
|
110 module:hook("muc-occupant-session-new", function(event) |
d0db28768980
mod_vcard_muc: Send presence on muc-occupant-session-new event
Michel Le Bihan <michel@lebihan.pl>
parents:
3043
diff
changeset
|
111 broadcast_presence(event.room.jid, event.jid); |
d0db28768980
mod_vcard_muc: Send presence on muc-occupant-session-new event
Michel Le Bihan <michel@lebihan.pl>
parents:
3043
diff
changeset
|
112 end) |