277 module:hook("presence/bare", function(event) |
277 module:hook("presence/bare", function(event) |
278 -- inbound presence to bare JID recieved |
278 -- inbound presence to bare JID recieved |
279 local origin, stanza = event.origin, event.stanza; |
279 local origin, stanza = event.origin, event.stanza; |
280 local user = stanza.attr.to or (origin.username..'@'..origin.host); |
280 local user = stanza.attr.to or (origin.username..'@'..origin.host); |
281 local t = stanza.attr.type; |
281 local t = stanza.attr.type; |
282 local self = not stanza.attr.to; |
282 local is_self = not stanza.attr.to; |
283 |
283 |
284 if not t then -- available presence |
284 if not t then -- available presence |
285 if self or subscription_presence(user, stanza.attr.from) then |
285 if is_self or subscription_presence(user, stanza.attr.from) then |
286 local recipient = stanza.attr.from; |
286 local recipient = stanza.attr.from; |
287 local current = recipients[user] and recipients[user][recipient]; |
287 local current = recipients[user] and recipients[user][recipient]; |
288 local hash, query_node = get_caps_hash_from_presence(stanza, current); |
288 local hash, query_node = get_caps_hash_from_presence(stanza, current); |
289 if current == hash or (current and current == hash_map[hash]) then return; end |
289 if current == hash or (current and current == hash_map[hash]) then return; end |
290 if not hash then |
290 if not hash then |
294 if hash_map[hash] then |
294 if hash_map[hash] then |
295 update_subscriptions(recipient, user, hash_map[hash]); |
295 update_subscriptions(recipient, user, hash_map[hash]); |
296 else |
296 else |
297 recipients[user][recipient] = hash; |
297 recipients[user][recipient] = hash; |
298 local from_bare = origin.type == "c2s" and origin.username.."@"..origin.host; |
298 local from_bare = origin.type == "c2s" and origin.username.."@"..origin.host; |
299 if self or origin.type ~= "c2s" or (recipients[from_bare] and recipients[from_bare][origin.full_jid]) ~= hash then |
299 if is_self or origin.type ~= "c2s" or (recipients[from_bare] and recipients[from_bare][origin.full_jid]) ~= hash then |
300 -- COMPAT from ~= stanza.attr.to because OneTeam can't deal with missing from attribute |
300 -- COMPAT from ~= stanza.attr.to because OneTeam can't deal with missing from attribute |
301 origin.send( |
301 origin.send( |
302 st.stanza("iq", {from=user, to=stanza.attr.from, id="disco", type="get"}) |
302 st.stanza("iq", {from=user, to=stanza.attr.from, id="disco", type="get"}) |
303 :tag("query", {xmlns = "http://jabber.org/protocol/disco#info", node = query_node}) |
303 :tag("query", {xmlns = "http://jabber.org/protocol/disco#info", node = query_node}) |
304 ); |
304 ); |
306 end |
306 end |
307 end |
307 end |
308 end |
308 end |
309 elseif t == "unavailable" then |
309 elseif t == "unavailable" then |
310 update_subscriptions(stanza.attr.from, user); |
310 update_subscriptions(stanza.attr.from, user); |
311 elseif not self and t == "unsubscribe" then |
311 elseif not is_self and t == "unsubscribe" then |
312 local from = jid_bare(stanza.attr.from); |
312 local from = jid_bare(stanza.attr.from); |
313 local subscriptions = recipients[user]; |
313 local subscriptions = recipients[user]; |
314 if subscriptions then |
314 if subscriptions then |
315 for subscriber in pairs(subscriptions) do |
315 for subscriber in pairs(subscriptions) do |
316 if jid_bare(subscriber) == from then |
316 if jid_bare(subscriber) == from then |
327 if not disco then |
327 if not disco then |
328 return; |
328 return; |
329 end |
329 end |
330 |
330 |
331 -- Process disco response |
331 -- Process disco response |
332 local self = not stanza.attr.to; |
332 local is_self = not stanza.attr.to; |
333 local user = stanza.attr.to or (origin.username..'@'..origin.host); |
333 local user = stanza.attr.to or (origin.username..'@'..origin.host); |
334 local contact = stanza.attr.from; |
334 local contact = stanza.attr.from; |
335 local current = recipients[user] and recipients[user][contact]; |
335 local current = recipients[user] and recipients[user][contact]; |
336 if type(current) ~= "string" then return; end -- check if waiting for recipient's response |
336 if type(current) ~= "string" then return; end -- check if waiting for recipient's response |
337 local ver = current; |
337 local ver = current; |
344 local nfeature = feature.attr.var:match("^(.*)%+notify$"); |
344 local nfeature = feature.attr.var:match("^(.*)%+notify$"); |
345 if nfeature then notify:add(nfeature); end |
345 if nfeature then notify:add(nfeature); end |
346 end |
346 end |
347 end |
347 end |
348 hash_map[ver] = notify; -- update hash map |
348 hash_map[ver] = notify; -- update hash map |
349 if self then |
349 if is_self then |
350 for jid, item in pairs(origin.roster) do -- for all interested contacts |
350 for jid, item in pairs(origin.roster) do -- for all interested contacts |
351 if item.subscription == "both" or item.subscription == "from" then |
351 if item.subscription == "both" or item.subscription == "from" then |
352 if not recipients[jid] then recipients[jid] = {}; end |
352 if not recipients[jid] then recipients[jid] = {}; end |
353 update_subscriptions(contact, jid, notify); |
353 update_subscriptions(contact, jid, notify); |
354 end |
354 end |