mod_bosh: Add support for stanza filters to BOSH sessions (needed by some plugins)
[prosody.git] / plugins / mod_presence.lua
index 09a6f9f264ee6efcd2720b056666654b83f7dc8d..20d0adf0504182e32ac7b28dfd33c1bc033a0acd 100644 (file)
@@ -14,6 +14,7 @@ local t_concat, t_insert = table.concat, table.insert;
 local s_find = string.find;
 local tonumber = tonumber;
 
+local core_post_stanza = prosody.core_post_stanza;
 local st = require "util.stanza";
 local jid_split = require "util.jid".split;
 local jid_bare = require "util.jid".bare;
@@ -115,8 +116,8 @@ function handle_normal_presence(origin, stanza)
                end
 
                if priority >= 0 then
-                        local event = { origin = origin }
-                        module:fire_event('message/offline/broadcast', event);
+                       local event = { origin = origin }
+                       module:fire_event('message/offline/broadcast', event);
                end
        end
        if stanza.attr.type == "unavailable" then
@@ -160,7 +161,7 @@ function send_presence_of_available_resources(user, host, jid, recipient_session
                        end
                end
        end
-       log("debug", "broadcasted presence of "..count.." resources from "..user.."@"..host.." to "..jid);
+       log("debug", "broadcasted presence of %d resources from %s@%s to %s", count, user, host, jid);
        return count;
 end
 
@@ -169,7 +170,7 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_
        if to_bare == from_bare then return; end -- No self contacts
        local st_from, st_to = stanza.attr.from, stanza.attr.to;
        stanza.attr.from, stanza.attr.to = from_bare, to_bare;
-       log("debug", "outbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare);
+       log("debug", "outbound presence %s from %s for %s", stanza.attr.type, from_bare, to_bare);
        if stanza.attr.type == "probe" then
                stanza.attr.from, stanza.attr.to = st_from, st_to;
                return;
@@ -197,12 +198,19 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_
                core_post_stanza(origin, stanza);
                send_presence_of_available_resources(node, host, to_bare, origin);
        elseif stanza.attr.type == "unsubscribed" then
-               -- 1. route stanza
-               -- 2. roster push (subscription = none or to)
-               if rostermanager.unsubscribed(node, host, to_bare) then
-                       rostermanager.roster_push(node, host, to_bare);
+               -- 1. send unavailable
+               -- 2. route stanza
+               -- 3. roster push (subscription = from or both)
+               local success, pending_in, subscribed = rostermanager.unsubscribed(node, host, to_bare);
+               if success then
+                       if subscribed then
+                               rostermanager.roster_push(node, host, to_bare);
+                       end
+                       core_post_stanza(origin, stanza);
+                       if subscribed then
+                               send_presence_of_available_resources(node, host, to_bare, origin, st.presence({ type = "unavailable" }));
+                       end
                end
-               core_post_stanza(origin, stanza);
        else
                origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid presence type"));
        end
@@ -214,7 +222,7 @@ function handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_b
        local node, host = jid_split(to_bare);
        local st_from, st_to = stanza.attr.from, stanza.attr.to;
        stanza.attr.from, stanza.attr.to = from_bare, to_bare;
-       log("debug", "inbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare);
+       log("debug", "inbound presence %s from %s for %s", stanza.attr.type, from_bare, to_bare);
        
        if stanza.attr.type == "probe" then
                local result, err = rostermanager.is_contact_subscribed(node, host, from_bare);