aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/offlinemanager.lua32
-rw-r--r--core/stanza_router.lua18
2 files changed, 49 insertions, 1 deletions
diff --git a/core/offlinemanager.lua b/core/offlinemanager.lua
new file mode 100644
index 00000000..283de5e3
--- /dev/null
+++ b/core/offlinemanager.lua
@@ -0,0 +1,32 @@
+
+local datamanager = require "util.datamanager";
+local st = require "util.stanza";
+local datetime = require "util.datetime";
+local ipairs = ipairs;
+
+module "offlinemanager"
+
+function store(node, host, stanza)
+ stanza.attr.stamp = datetime.datetime();
+ stanza.attr.stamp_legacy = datetime.legacy();
+ return datamanager.list_append(node, host, "offline", st.preserialize(stanza));
+end
+
+function load(node, host)
+ local data = datamanager.list_load(node, host, "offline");
+ if not data then return; end
+ for k, v in ipairs(data) do
+ stanza = st.deserialize(v);
+ stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = host, stamp = stanza.attr.stamp}):up(); -- XEP-0203
+ stanza:tag("x", {xmlns = "jabber:x:delay", from = host, stamp = stanza.attr.stamp_legacy}):up(); -- XEP-0091 (deprecated)
+ stanza.attr.stamp, stanza.attr.stamp_legacy = nil, nil;
+ data[k] = stanza;
+ end
+ return data;
+end
+
+function deleteAll(node, host)
+ return datamanager.list_store(node, host, "offline", nil);
+end
+
+return _M;
diff --git a/core/stanza_router.lua b/core/stanza_router.lua
index 9ae98f1c..5d6358ec 100644
--- a/core/stanza_router.lua
+++ b/core/stanza_router.lua
@@ -13,6 +13,7 @@ local user_exists = require "core.usermanager".user_exists;
local rostermanager = require "core.rostermanager";
local sessionmanager = require "core.sessionmanager";
+local offlinemanager = require "core.offlinemanager";
local s2s_verify_dialback = require "core.s2smanager".verify_dialback;
local s2s_make_authenticated = require "core.s2smanager".make_authenticated;
@@ -149,6 +150,10 @@ function core_handle_stanza(origin, stanza)
core_route_stanza(origin, request);
end
end
+ for _, msg in ipairs(offlinemanager.load(node, host) or {}) do
+ origin.send(msg); -- FIXME do we need to modify to/from in any way?
+ end
+ offlinemanager.deleteAll(node, host);
end
origin.priority = 0;
if stanza.attr.type == "unavailable" then
@@ -328,8 +333,14 @@ function core_route_stanza(origin, stanza)
t_insert(recipients, session);
end
end
+ local count = 0;
for _, session in pairs(recipients) do
session.send(stanza);
+ count = count + 1;
+ end
+ if count == 0 then
+ offlinemanager.store(node, host, stanza);
+ -- TODO deal with storage errors
end
else
-- TODO send IQ error
@@ -349,7 +360,12 @@ function core_route_stanza(origin, stanza)
-- TODO send unavailable presence or unsubscribed
end
elseif stanza.name == "message" then
- -- TODO send message error, or store offline messages
+ if stanza.attr.type == "chat" or stanza.attr.type == "normal" or not stanza.attr.type then
+ offlinemanager.store(node, host, stanza);
+ -- FIXME don't store messages with only chat state notifications
+ end
+ -- TODO allow configuration of offline storage
+ -- TODO send error if not storing offline
elseif stanza.name == "iq" then
-- TODO send IQ error
end