local jid_bare = require "util.jid".bare;
local jid_split = require "util.jid".split;
local st = require "util.stanza";
-local hosts = hosts;
-local user_exists = require "core.usermanager".user_exists;
local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
-local pairs, ipairs = pairs, ipairs;
+local pairs = pairs;
local next = next;
local type = type;
local calculate_hash = require "util.caps".calculate_hash;
+local core_post_stanza = prosody.core_post_stanza;
+local bare_sessions = prosody.bare_sessions;
+-- Used as canonical 'empty table'
local NULL = {};
+-- data[user_bare_jid][node] = item_stanza
local data = {};
+--- recipients[user_bare_jid][contact_full_jid][subscribed_node] = true
local recipients = {};
+-- hash_map[hash][subscribed_nodes] = true
local hash_map = {};
module.save = function()
end
else
if not user_data then user_data = {}; data[bare] = user_data; end
- user_data[node] = {id or "1", item};
+ user_data[node] = {id, item};
end
-- broadcast
local t = stanza.attr.type;
local self = not stanza.attr.to;
+ -- Only cache subscriptions if user is online
+ if not bare_sessions[user] then return; end
+
if not t then -- available presence
if self or subscription_presence(user, stanza.attr.from) then
local recipient = stanza.attr.from;
recipients[user][recipient] = hash;
local from_bare = origin.type == "c2s" and origin.username.."@"..origin.host;
if self or origin.type ~= "c2s" or (recipients[from_bare] and recipients[from_bare][origin.full_jid]) ~= hash then
- -- COMPAT from ~= stanza.attr.to because OneTeam can't deal with missing from attribute
+ -- COMPAT from ~= stanza.attr.to because OneTeam and Asterisk 1.8 can't deal with missing from attribute
origin.send(
st.stanza("iq", {from=user, to=stanza.attr.from, id="disco", type="get"})
:query("http://jabber.org/protocol/disco#info")
local node = payload.attr.node;
payload = payload.tags[1];
if payload and payload.name == "item" then -- <item>
- local id = payload.attr.id;
+ local id = payload.attr.id or "1";
+ payload.attr.id = id;
session.send(st.reply(stanza));
publish(session, node, id, st.clone(payload));
return true;
end
end
end);
+
+module:hook("resource-unbind", function (event)
+ local user_bare_jid = event.session.username.."@"..event.session.host;
+ if not bare_sessions[user_bare_jid] then -- User went offline
+ -- We don't need this info cached anymore, clear it.
+ recipients[user_bare_jid] = nil;
+ end
+end);