Backout bcdff2b1d3ec from 0.8 - going to commit a slightly cleaner patch for the...
[prosody.git] / plugins / mod_message.lua
index c0abe9368daccf20cd8ce159c186858814ed186e..df3175325b21f2488e19fa6e847c5ecef81be0c0 100644 (file)
@@ -1,9 +1,65 @@
+-- Prosody IM
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
+-- 
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
 
 local full_sessions = full_sessions;
 local bare_sessions = bare_sessions;
 
+local st = require "util.stanza";
 local jid_bare = require "util.jid".bare;
+local jid_split = require "util.jid".split;
 local user_exists = require "core.usermanager".user_exists;
+local t_insert = table.insert;
+
+local function process_to_bare(bare, origin, stanza)
+       local user = bare_sessions[bare];
+       
+       local t = stanza.attr.type;
+       if t == "error" then
+               -- discard
+       elseif t == "groupchat" then
+               origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
+       elseif t == "headline" then
+               if user and stanza.attr.to == bare then
+                       for _, session in pairs(user.sessions) do
+                               if session.presence and session.priority >= 0 then
+                                       session.send(stanza);
+                               end
+                       end
+               end  -- current policy is to discard headlines if no recipient is available
+       else -- chat or normal message
+               if user then -- some resources are connected
+                       local recipients = user.top_resources;
+                       if recipients then
+                               for i=1,#recipients do
+                                       recipients[i].send(stanza);
+                               end
+                               return true;
+                       end
+               end
+               -- no resources are online
+               local node, host = jid_split(bare);
+               local ok
+               if user_exists(node, host) then
+                       -- TODO apply the default privacy list
+
+                       ok = module:fire_event('message/offline/handle', {
+                           origin = origin,
+                           stanza = stanza,
+                       });
+               end
+
+               if not ok then
+                       origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
+               end
+       end
+       return true;
+end
 
 module:hook("message/full", function(data)
        -- message to full JID recieved
@@ -15,7 +71,7 @@ module:hook("message/full", function(data)
                session.send(stanza);
                return true;
        else -- resource not online
-               -- TODO fire event to send to bare JID
+               return process_to_bare(jid_bare(stanza.attr.to), origin, stanza);
        end
 end);
 
@@ -23,19 +79,7 @@ module:hook("message/bare", function(data)
        -- message to bare JID recieved
        local origin, stanza = data.origin, data.stanza;
 
-       local sessions = bare_sessions[stanza.attr.to];
-       if sessions then sessions = sessions.sessions; end
-       
-       if sessions then
-               -- some resources are online
-               -- TODO find top resources willing to accept this message
-               -- TODO then send them each the stanza
-       else
-               -- no resources are online
-               -- TODO check if the user exists
-               -- TODO if it doesn't, return an error reply
-               -- TODO otherwise, apply the default privacy list
-               -- TODO and store into offline storage
-               -- TODO or maybe the offline store can apply privacy lists
-       end
+       return process_to_bare(stanza.attr.to or (origin.username..'@'..origin.host), origin, stanza);
 end);
+
+module:add_feature("msgoffline");