14 local user_exists = require "core.usermanager".user_exists; |
14 local user_exists = require "core.usermanager".user_exists; |
15 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; |
15 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; |
16 local pairs, ipairs = pairs, ipairs; |
16 local pairs, ipairs = pairs, ipairs; |
17 local next = next; |
17 local next = next; |
18 local type = type; |
18 local type = type; |
19 local sha1 = require "util.hashes".sha1; |
19 local calculate_hash = require "util.caps".calculate_hash; |
20 local base64 = require "util.encodings".base64.encode; |
|
21 |
20 |
22 local NULL = {}; |
21 local NULL = {}; |
23 local data = {}; |
22 local data = {}; |
24 local recipients = {}; |
23 local recipients = {}; |
25 local hash_map = {}; |
24 local hash_map = {}; |
207 return true; |
206 return true; |
208 end |
207 end |
209 end |
208 end |
210 end); |
209 end); |
211 |
210 |
212 local function calculate_hash(disco_info) |
|
213 local identities, features, extensions = {}, {}, {}; |
|
214 for _, tag in pairs(disco_info) do |
|
215 if tag.name == "identity" then |
|
216 table.insert(identities, (tag.attr.category or "").."\0"..(tag.attr.type or "").."\0"..(tag.attr["xml:lang"] or "").."\0"..(tag.attr.name or "")); |
|
217 elseif tag.name == "feature" then |
|
218 table.insert(features, tag.attr.var or ""); |
|
219 elseif tag.name == "x" and tag.attr.xmlns == "jabber:x:data" then |
|
220 local form = {}; |
|
221 local FORM_TYPE; |
|
222 for _, field in pairs(tag.tags) do |
|
223 if field.name == "field" and field.attr.var then |
|
224 local values = {}; |
|
225 for _, val in pairs(field.tags) do |
|
226 val = #val.tags == 0 and table.concat(val); -- FIXME use get_text? |
|
227 if val then table.insert(values, val); end |
|
228 end |
|
229 table.sort(values); |
|
230 if field.attr.var == "FORM_TYPE" then |
|
231 FORM_TYPE = values[1]; |
|
232 elseif #values > 0 then |
|
233 table.insert(form, field.attr.var.."\0"..table.concat(values, "<")); |
|
234 else |
|
235 table.insert(form, field.attr.var); |
|
236 end |
|
237 end |
|
238 end |
|
239 table.sort(form); |
|
240 form = table.concat(form, "<"); |
|
241 if FORM_TYPE then form = FORM_TYPE.."\0"..form; end |
|
242 table.insert(extensions, form); |
|
243 end |
|
244 end |
|
245 table.sort(identities); |
|
246 table.sort(features); |
|
247 table.sort(extensions); |
|
248 if #identities > 0 then identities = table.concat(identities, "<"):gsub("%z", "/").."<"; else identities = ""; end |
|
249 if #features > 0 then features = table.concat(features, "<").."<"; else features = ""; end |
|
250 if #extensions > 0 then extensions = table.concat(extensions, "<"):gsub("%z", "<").."<"; else extensions = ""; end |
|
251 local S = identities..features..extensions; |
|
252 local ver = base64(sha1(S)); |
|
253 return ver, S; |
|
254 end |
|
255 |
|
256 module:hook("iq/bare/disco", function(event) |
211 module:hook("iq/bare/disco", function(event) |
257 local session, stanza = event.origin, event.stanza; |
212 local session, stanza = event.origin, event.stanza; |
258 if stanza.attr.type == "result" then |
213 if stanza.attr.type == "result" then |
259 local disco = stanza.tags[1]; |
214 local disco = stanza.tags[1]; |
260 if disco and disco.name == "query" and disco.attr.xmlns == "http://jabber.org/protocol/disco#info" then |
215 if disco and disco.name == "query" and disco.attr.xmlns == "http://jabber.org/protocol/disco#info" then |