annotate plugins/mod_mam/mod_mam.lua @ 9659:86c431650dfd

net.websocket.frames: Prefer Lua 5.2 built-in bit module over LuaJIT version When running on Lua 5.2 this makes sense since bit32 is usually already loaded. It's sensible to prefer this going forward in case of incompatibilities between the two variants.
author Kim Alvefur <zash@zash.se>
date Thu, 29 Nov 2018 16:53:22 +0100
parents ed5a5ddcef17
children 39ee70fbb009 ddc07fb8dcd4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7851
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
1 -- Prosody IM
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
2 -- Copyright (C) 2008-2017 Matthew Wild
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
3 -- Copyright (C) 2008-2017 Waqas Hussain
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
4 -- Copyright (C) 2011-2017 Kim Alvefur
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
5 --
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
6 -- This project is MIT/X11 licensed. Please see the
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
7 -- COPYING file in the source package for more information.
80ee0d9cd56f mod_mam: Normalize copyright headers
Kim Alvefur <zash@zash.se>
parents: 7850
diff changeset
8 --
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 -- XEP-0313: Message Archive Management for Prosody
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10 --
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11
7903
036c771b842a mod_mam: Update namespace to XEP-0313 v0.6
Kim Alvefur <zash@zash.se>
parents: 7902
diff changeset
12 local xmlns_mam = "urn:xmpp:mam:2";
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 local xmlns_delay = "urn:xmpp:delay";
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 local xmlns_forward = "urn:xmpp:forward:0";
7890
9e4de27e8e08 mod_mam: Move stanza ID namespace to a common variable
Kim Alvefur <zash@zash.se>
parents: 7882
diff changeset
15 local xmlns_st_id = "urn:xmpp:sid:0";
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 local um = require "core.usermanager";
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 local st = require "util.stanza";
7882
1017a4f8929d mod_mam: Correct import of util.rsm
Kim Alvefur <zash@zash.se>
parents: 7856
diff changeset
19 local rsm = require "util.rsm";
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 local get_prefs = module:require"mamprefs".get;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 local set_prefs = module:require"mamprefs".set;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 local prefs_to_stanza = module:require"mamprefsxml".tostanza;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 local prefs_from_stanza = module:require"mamprefsxml".fromstanza;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 local jid_bare = require "util.jid".bare;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 local jid_split = require "util.jid".split;
7845
eeb22f912577 mod_mam: Filter out spoofed XEP-0359 tags
Kim Alvefur <zash@zash.se>
parents: 7844
diff changeset
26 local jid_prepped_split = require "util.jid".prepped_split;
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 local dataform = require "util.dataforms".new;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 local host = module.host;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 local rm_load_roster = require "core.rostermanager".load_roster;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31
7838
e5d5e5946af5 mod_mam: Use is_stanza from util.stanza
Kim Alvefur <zash@zash.se>
parents: 7837
diff changeset
32 local is_stanza = st.is_stanza;
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 local tostring = tostring;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 local time_now = os.time;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 local m_min = math.min;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50);
7849
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
38 local strip_tags = module:get_option_set("dont_archive_namespaces", { "http://jabber.org/protocol/chatstates" });
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39
7850
10d91860172f mod_mam: Change store name to "archive" but make it configurable for people who have data in "archive2"
Kim Alvefur <zash@zash.se>
parents: 7849
diff changeset
40 local archive_store = module:get_option_string("archive_store", "archive");
8047
eb9784561387 mod_mam: Remove extraneous assert when opening the store
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8000
diff changeset
41 local archive = module:open_store(archive_store, "archive");
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42
9553
9a5485550bfd mod_mam: Ignore case of null storage driver
Kim Alvefur <zash@zash.se>
parents: 8905
diff changeset
43 if not archive.find then
9554
cba6e6168d26 mod_mam: Upgrade case of invalid archive store driver to hard error
Kim Alvefur <zash@zash.se>
parents: 9553
diff changeset
44 error("mod_"..(archive._provided_by or archive.name and "storage_"..archive.name).." does not support archiving\n"
cba6e6168d26 mod_mam: Upgrade case of invalid archive store driver to hard error
Kim Alvefur <zash@zash.se>
parents: 9553
diff changeset
45 .."See https://prosody.im/doc/storage and https://prosody.im/doc/archiving for more information");
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 end
8577
75d5eee6fcdf mod_mam: Add an option for whether to include 'total' counts by default in queries
Kim Alvefur <zash@zash.se>
parents: 8576
diff changeset
47 local use_total = module:get_option_boolean("mam_include_total", true);
8132
6ddddfe05a74 mod_mam: Don't ask the storage backend to count all items when expiry is disabled
Kim Alvefur <zash@zash.se>
parents: 8047
diff changeset
48
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 local cleanup;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50
8230
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
51 local function schedule_cleanup(username)
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
52 if cleanup and not cleanup[username] then
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
53 table.insert(cleanup, username);
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
54 cleanup[username] = true;
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
55 end
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
56 end
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
57
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 -- Handle prefs.
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 module:hook("iq/self/"..xmlns_mam..":prefs", function(event)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 local origin, stanza = event.origin, event.stanza;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 local user = origin.username;
8252
63e505578d4f mod_mam: Also return the preferences on set
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8250
diff changeset
62 if stanza.attr.type == "set" then
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 local new_prefs = stanza:get_child("prefs", xmlns_mam);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 local prefs = prefs_from_stanza(new_prefs);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 local ok, err = set_prefs(user, prefs);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 if not ok then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 origin.send(st.error_reply(stanza, "cancel", "internal-server-error", "Error storing preferences: "..tostring(err)));
8252
63e505578d4f mod_mam: Also return the preferences on set
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8250
diff changeset
68 return true;
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 end
8538
3eb4cafb3b64 mod_mam: Implement option to enable MAM implicitly when client support is detected (#867)
Kim Alvefur <zash@zash.se>
parents: 8252
diff changeset
71 local prefs = prefs_to_stanza(get_prefs(user, true));
8252
63e505578d4f mod_mam: Also return the preferences on set
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8250
diff changeset
72 local reply = st.reply(stanza):add_child(prefs);
63e505578d4f mod_mam: Also return the preferences on set
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8250
diff changeset
73 origin.send(reply);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 return true;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 end);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 local query_form = dataform {
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 { name = "FORM_TYPE"; type = "hidden"; value = xmlns_mam; };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 { name = "with"; type = "jid-single"; };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 { name = "start"; type = "text-single" };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 { name = "end"; type = "text-single"; };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 -- Serve form
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 module:hook("iq-get/self/"..xmlns_mam..":query", function(event)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 local origin, stanza = event.origin, event.stanza;
8538
3eb4cafb3b64 mod_mam: Implement option to enable MAM implicitly when client support is detected (#867)
Kim Alvefur <zash@zash.se>
parents: 8252
diff changeset
87 get_prefs(origin.username, true);
7904
c011cecad576 mod_mam: Add missing wrapping <query> element when returning the query form
Kim Alvefur <zash@zash.se>
parents: 7903
diff changeset
88 origin.send(st.reply(stanza):query(xmlns_mam):add_child(query_form:form()));
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 return true;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 end);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
91
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
92 -- Handle archive queries
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
93 module:hook("iq-set/self/"..xmlns_mam..":query", function(event)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
94 local origin, stanza = event.origin, event.stanza;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
95 local query = stanza.tags[1];
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
96 local qid = query.attr.queryid;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97
8538
3eb4cafb3b64 mod_mam: Implement option to enable MAM implicitly when client support is detected (#867)
Kim Alvefur <zash@zash.se>
parents: 8252
diff changeset
98 get_prefs(origin.username, true);
8230
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
99 schedule_cleanup(origin.username);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 -- Search query parameters
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
102 local qwith, qstart, qend;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
103 local form = query:get_child("x", "jabber:x:data");
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
104 if form then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
105 local err;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
106 form, err = query_form:data(form);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
107 if err then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
108 origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err))));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
109 return true;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
110 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
111 qwith, qstart, qend = form["with"], form["start"], form["end"];
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
112 qwith = qwith and jid_bare(qwith); -- dataforms does jidprep
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
113 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
114
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
115 if qstart or qend then -- Validate timestamps
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
116 local vstart, vend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
117 if (qstart and not vstart) or (qend and not vend) then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
118 origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid timestamp"))
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
119 return true;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
120 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
121 qstart, qend = vstart, vend;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
122 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
123
8580
b23da88b3507 mod_mam: Remove unmatched closing paren
Kim Alvefur <zash@zash.se>
parents: 8577
diff changeset
124 module:log("debug", "Archive query, id %s with %s from %s until %s",
8140
2bda04a7b4d4 mod_mam: Format timestamps in log message
Kim Alvefur <zash@zash.se>
parents: 8137
diff changeset
125 tostring(qid), qwith or "anyone",
2bda04a7b4d4 mod_mam: Format timestamps in log message
Kim Alvefur <zash@zash.se>
parents: 8137
diff changeset
126 qstart and timestamp(qstart) or "the dawn of time",
2bda04a7b4d4 mod_mam: Format timestamps in log message
Kim Alvefur <zash@zash.se>
parents: 8137
diff changeset
127 qend and timestamp(qend) or "now");
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
128
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
129 -- RSM stuff
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
130 local qset = rsm.get(query);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
131 local qmax = m_min(qset and qset.max or default_max_items, max_max_items);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
132 local reverse = qset and qset.before or false;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
133 local before, after = qset and qset.before, qset and qset.after;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
134 if type(before) ~= "string" then before = nil; end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
135
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
136 -- Load all the data!
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
137 local data, err = archive:find(origin.username, {
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
138 start = qstart; ["end"] = qend; -- Time range
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
139 with = qwith;
8904
faca839ddbbb mod_mam: Handle edge-case of max=0 so that complete attr is set (fixes #1128)
Kim Alvefur <zash@zash.se>
parents: 8580
diff changeset
140 limit = qmax == 0 and 0 or qmax + 1;
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
141 before = before; after = after;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
142 reverse = reverse;
8172
66e32c34250b mod_mam: Request a total count if no items are requested
Kim Alvefur <zash@zash.se>
parents: 8149
diff changeset
143 total = use_total or qmax == 0;
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
144 });
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
145
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
146 if not data then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
147 origin.send(st.error_reply(stanza, "cancel", "internal-server-error", err));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
148 return true;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
149 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
150 local total = tonumber(err);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
151
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
152 local msg_reply_attr = { to = stanza.attr.from, from = stanza.attr.to };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
153
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
154 local results = {};
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
155
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
156 -- Wrap it in stuff and deliver
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
157 local first, last;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
158 local count = 0;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
159 local complete = "true";
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
160 for id, item, when in data do
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
161 count = count + 1;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
162 if count > qmax then
8905
65d1a80d3565 mod_mam: Add coment on how 'complete' works
Kim Alvefur <zash@zash.se>
parents: 8904
diff changeset
163 -- We requested qmax+1 items. If that many items are retrieved then
65d1a80d3565 mod_mam: Add coment on how 'complete' works
Kim Alvefur <zash@zash.se>
parents: 8904
diff changeset
164 -- there are more results to page through, so:
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
165 complete = nil;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
166 break;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
167 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
168 local fwd_st = st.message(msg_reply_attr)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
169 :tag("result", { xmlns = xmlns_mam, queryid = qid, id = id })
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
170 :tag("forwarded", { xmlns = xmlns_forward })
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
171 :tag("delay", { xmlns = xmlns_delay, stamp = timestamp(when) }):up();
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
172
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
173 if not is_stanza(item) then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
174 item = st.deserialize(item);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
175 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
176 item.attr.xmlns = "jabber:client";
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
177 fwd_st:add_child(item);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
178
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
179 if not first then first = id; end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
180 last = id;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
181
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
182 if reverse then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
183 results[count] = fwd_st;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
184 else
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
185 origin.send(fwd_st);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
186 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
187 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
188
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
189 if reverse then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
190 for i = #results, 1, -1 do
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
191 origin.send(results[i]);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
192 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
193 first, last = last, first;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
194 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
195
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
196 -- That's all folks!
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
197 module:log("debug", "Archive query %s completed", tostring(qid));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
198
7839
f3e1925f29c2 mod_mam: Update to XEP-0313 v0.5.1
Kim Alvefur <zash@zash.se>
parents: 7838
diff changeset
199 origin.send(st.reply(stanza)
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
200 :tag("fin", { xmlns = xmlns_mam, queryid = qid, complete = complete })
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
201 :add_child(rsm.generate {
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
202 first = first, last = last, count = total }));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
203 return true;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
204 end);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
205
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
206 local function has_in_roster(user, who)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
207 local roster = rm_load_roster(user, host);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
208 module:log("debug", "%s has %s in roster? %s", user, who, roster[who] and "yes" or "no");
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
209 return roster[who];
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
210 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
211
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
212 local function shall_store(user, who)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
213 -- TODO Cache this?
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
214 if not um.user_exists(user, host) then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
215 return false;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
216 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
217 local prefs = get_prefs(user);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
218 local rule = prefs[who];
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
219 module:log("debug", "%s's rule for %s is %s", user, who, tostring(rule));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
220 if rule ~= nil then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
221 return rule;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
222 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
223 -- Below could be done by a metatable
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
224 local default = prefs[false];
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
225 module:log("debug", "%s's default rule is %s", user, tostring(default));
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
226 if default == "roster" then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
227 return has_in_roster(user, who);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
228 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
229 return default;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
230 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
231
8207
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
232 local function strip_stanza_id(stanza, user)
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
233 if stanza:get_child("stanza-id", xmlns_st_id) then
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
234 stanza = st.clone(stanza);
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
235 stanza:maptags(function (tag)
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
236 if tag.name == "stanza-id" and tag.attr.xmlns == xmlns_st_id then
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
237 local by_user, by_host, res = jid_prepped_split(tag.attr.by);
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
238 if not res and by_host == host and by_user == user then
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
239 return nil;
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
240 end
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
241 end
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
242 return tag;
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
243 end);
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
244 end
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
245 return stanza;
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
246 end
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
247
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
248 -- Handle messages
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
249 local function message_handler(event, c2s)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
250 local origin, stanza = event.origin, event.stanza;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
251 local log = c2s and origin.log or module._log;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
252 local orig_type = stanza.attr.type or "normal";
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
253 local orig_from = stanza.attr.from;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
254 local orig_to = stanza.attr.to or orig_from;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
255 -- Stanza without 'to' are treated as if it was to their own bare jid
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
256
7844
316f5166eedb mod_mam: Find out which party is the user and which is the 'with' earlier
Kim Alvefur <zash@zash.se>
parents: 7843
diff changeset
257 -- Whos storage do we put it in?
316f5166eedb mod_mam: Find out which party is the user and which is the 'with' earlier
Kim Alvefur <zash@zash.se>
parents: 7843
diff changeset
258 local store_user = c2s and origin.username or jid_split(orig_to);
316f5166eedb mod_mam: Find out which party is the user and which is the 'with' earlier
Kim Alvefur <zash@zash.se>
parents: 7843
diff changeset
259 -- And who are they chatting with?
316f5166eedb mod_mam: Find out which party is the user and which is the 'with' earlier
Kim Alvefur <zash@zash.se>
parents: 7843
diff changeset
260 local with = jid_bare(c2s and orig_to or orig_from);
316f5166eedb mod_mam: Find out which party is the user and which is the 'with' earlier
Kim Alvefur <zash@zash.se>
parents: 7843
diff changeset
261
7845
eeb22f912577 mod_mam: Filter out spoofed XEP-0359 tags
Kim Alvefur <zash@zash.se>
parents: 7844
diff changeset
262 -- Filter out <stanza-id> that claim to be from us
8207
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
263 event.stanza = strip_stanza_id(stanza, store_user);
7845
eeb22f912577 mod_mam: Filter out spoofed XEP-0359 tags
Kim Alvefur <zash@zash.se>
parents: 7844
diff changeset
264
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
265 -- We store chat messages or normal messages that have a body
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
266 if not(orig_type == "chat" or (orig_type == "normal" and stanza:get_child("body")) ) then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
267 log("debug", "Not archiving stanza: %s (type)", stanza:top_tag());
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
268 return;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
269 end
7842
9332b43931f5 mod_mam: Add some comments explaining archive expiry
Kim Alvefur <zash@zash.se>
parents: 7841
diff changeset
270
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
271 -- or if hints suggest we shouldn't
7843
04b09fd144eb mod_mam: Alter hints processing
Kim Alvefur <zash@zash.se>
parents: 7842
diff changeset
272 if not stanza:get_child("store", "urn:xmpp:hints") then -- No hint telling us we should store
04b09fd144eb mod_mam: Alter hints processing
Kim Alvefur <zash@zash.se>
parents: 7842
diff changeset
273 if stanza:get_child("no-permanent-store", "urn:xmpp:hints")
04b09fd144eb mod_mam: Alter hints processing
Kim Alvefur <zash@zash.se>
parents: 7842
diff changeset
274 or stanza:get_child("no-store", "urn:xmpp:hints") then -- Hint telling us we should NOT store
04b09fd144eb mod_mam: Alter hints processing
Kim Alvefur <zash@zash.se>
parents: 7842
diff changeset
275 log("debug", "Not archiving stanza: %s (hint)", stanza:top_tag());
04b09fd144eb mod_mam: Alter hints processing
Kim Alvefur <zash@zash.se>
parents: 7842
diff changeset
276 return;
04b09fd144eb mod_mam: Alter hints processing
Kim Alvefur <zash@zash.se>
parents: 7842
diff changeset
277 end
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
278 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
279
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
280 local clone_for_storage;
7849
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
281 if not strip_tags:empty() then
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
282 clone_for_storage = st.clone(stanza);
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
283 clone_for_storage:maptags(function (tag)
7849
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
284 if strip_tags:contains(tag.attr.xmlns) then
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
285 return nil;
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
286 else
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
287 return tag;
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
288 end
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
289 end);
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
290 if #clone_for_storage.tags == 0 then
8250
9ea5ea53744b mod_mam: Log a message when not archiving because it only had ignored tags
Kim Alvefur <zash@zash.se>
parents: 8231
diff changeset
291 log("debug", "Not archiving stanza: %s (empty when stripped)", stanza:top_tag());
7849
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
292 return;
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
293 end
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
294 else
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
295 clone_for_storage = stanza;
7849
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
296 end
93a068ef4b2c mod_mam: Allow a set of namespaces to be stripped from stored stanzas, default to chat states (fixes #763)
Kim Alvefur <zash@zash.se>
parents: 7848
diff changeset
297
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
298 -- Check with the users preferences
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
299 if shall_store(store_user, with) then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
300 log("debug", "Archiving stanza: %s", stanza:top_tag());
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
301
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
302 -- And stash it
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
303 local ok = archive:append(store_user, nil, clone_for_storage, time_now(), with);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
304 if ok then
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
305 local clone_for_other_handlers = st.clone(stanza);
7908
dbdaa8487ecd mod_mam: Fix to treat first return value from archive:append as assigned ID
Kim Alvefur <zash@zash.se>
parents: 7906
diff changeset
306 local id = ok;
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
307 clone_for_other_handlers:tag("stanza-id", { xmlns = xmlns_st_id, by = store_user.."@"..host, id = id }):up();
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
308 event.stanza = clone_for_other_handlers;
8230
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
309 schedule_cleanup(store_user);
8193
bb0118e46c45 mod_mam: Clone stanzas before mutating (thanks waqas) (fixes #961)
Kim Alvefur <zash@zash.se>
parents: 8172
diff changeset
310 module:fire_event("archive-message-added", { origin = origin, stanza = clone_for_storage, for_user = store_user, id = id });
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
311 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
312 else
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
313 log("debug", "Not archiving stanza: %s (prefs)", stanza:top_tag());
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
314 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
315 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
316
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
317 local function c2s_message_handler(event)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
318 return message_handler(event, true);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
319 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
320
8207
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
321 -- Filter out <stanza-id> before the message leaves the server to prevent privacy leak.
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
322 local function strip_stanza_id_after_other_events(event)
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
323 event.stanza = strip_stanza_id(event.stanza, event.origin.username);
7902
92b70a921acb mod_mam: Strip stanza-id tags after carbons
Kim Alvefur <zash@zash.se>
parents: 7901
diff changeset
324 end
92b70a921acb mod_mam: Strip stanza-id tags after carbons
Kim Alvefur <zash@zash.se>
parents: 7901
diff changeset
325
8207
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
326 module:hook("pre-message/bare", strip_stanza_id_after_other_events, -1);
8ea0484871e8 mod_mam: Factor out <stanza-id> stripping so it can be reused in two places
Kim Alvefur <zash@zash.se>
parents: 8206
diff changeset
327 module:hook("pre-message/full", strip_stanza_id_after_other_events, -1);
7902
92b70a921acb mod_mam: Strip stanza-id tags after carbons
Kim Alvefur <zash@zash.se>
parents: 7901
diff changeset
328
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
329 local cleanup_after = module:get_option_string("archive_expires_after", "1w");
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
330 local cleanup_interval = module:get_option_number("archive_cleanup_interval", 4 * 60 * 60);
8575
5040c8ce32dd Backed out changeset 97a094fdf101, interferes with 6ddddfe05a74
Kim Alvefur <zash@zash.se>
parents: 8538
diff changeset
331 if cleanup_after ~= "never" then
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
332 local day = 86400;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
333 local multipliers = { d = day, w = day * 7, m = 31 * day, y = 365.2425 * day };
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
334 local n, m = cleanup_after:lower():match("(%d+)%s*([dwmy]?)");
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
335 if not n then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
336 module:log("error", "Could not parse archive_expires_after string %q", cleanup_after);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
337 return false;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
338 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
339
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
340 cleanup_after = tonumber(n) * ( multipliers[m] or 1 );
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
341
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
342 module:log("debug", "archive_expires_after = %d -- in seconds", cleanup_after);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
343
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
344 if not archive.delete then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
345 module:log("error", "archive_expires_after set but mod_%s does not support deleting", archive._provided_by);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
346 return false;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
347 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
348
7842
9332b43931f5 mod_mam: Add some comments explaining archive expiry
Kim Alvefur <zash@zash.se>
parents: 7841
diff changeset
349 -- Set of known users to do message expiry for
9332b43931f5 mod_mam: Add some comments explaining archive expiry
Kim Alvefur <zash@zash.se>
parents: 7841
diff changeset
350 -- Populated either below or when new messages are added
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
351 cleanup = {};
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
352
7842
9332b43931f5 mod_mam: Add some comments explaining archive expiry
Kim Alvefur <zash@zash.se>
parents: 7841
diff changeset
353 -- Iterating over users is not supported by all authentication modules
9332b43931f5 mod_mam: Add some comments explaining archive expiry
Kim Alvefur <zash@zash.se>
parents: 7841
diff changeset
354 -- Catch and ignore error if not supported
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
355 pcall(function ()
7901
fc859aed9279 mod_mam: Fix wording of comment
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
356 -- If this works, then we schedule cleanup for all known users on startup
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
357 for user in um.users(module.host) do
8230
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
358 schedule_cleanup(user);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
359 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
360 end);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
361
7842
9332b43931f5 mod_mam: Add some comments explaining archive expiry
Kim Alvefur <zash@zash.se>
parents: 7841
diff changeset
362 -- At odd intervals, delete old messages for one user
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
363 module:add_timer(math.random(10, 60), function()
8230
154852646095 mod_mam: Use a FIFO queue for scheduling archive expiry
Kim Alvefur <zash@zash.se>
parents: 8207
diff changeset
364 local user = table.remove(cleanup, 1);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
365 if user then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
366 module:log("debug", "Removing old messages for user %q", user);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
367 local ok, err = archive:delete(user, { ["end"] = os.time() - cleanup_after; })
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
368 if not ok then
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
369 module:log("warn", "Could not expire archives for user %s: %s", user, err);
7848
efe5232793aa mod_mam: If archive:delete() gives a number, this should be the number of deleted items
Kim Alvefur <zash@zash.se>
parents: 7846
diff changeset
370 elseif type(ok) == "number" then
efe5232793aa mod_mam: If archive:delete() gives a number, this should be the number of deleted items
Kim Alvefur <zash@zash.se>
parents: 7846
diff changeset
371 module:log("debug", "Removed %d messages", ok);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
372 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
373 cleanup[user] = nil;
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
374 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
375 return math.random(cleanup_interval, cleanup_interval * 2);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
376 end);
8132
6ddddfe05a74 mod_mam: Don't ask the storage backend to count all items when expiry is disabled
Kim Alvefur <zash@zash.se>
parents: 8047
diff changeset
377 else
8576
07ff7b8b702b mod_mam: Log a debug message if archive expiry has been disabled
Kim Alvefur <zash@zash.se>
parents: 8575
diff changeset
378 module:log("debug", "Archive expiry disabled");
8132
6ddddfe05a74 mod_mam: Don't ask the storage backend to count all items when expiry is disabled
Kim Alvefur <zash@zash.se>
parents: 8047
diff changeset
379 -- Don't ask the backend to count the potentially unbounded number of items,
6ddddfe05a74 mod_mam: Don't ask the storage backend to count all items when expiry is disabled
Kim Alvefur <zash@zash.se>
parents: 8047
diff changeset
380 -- it'll get slow.
8577
75d5eee6fcdf mod_mam: Add an option for whether to include 'total' counts by default in queries
Kim Alvefur <zash@zash.se>
parents: 8576
diff changeset
381 use_total = module:get_option_boolean("mam_include_total", false);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
382 end
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
383
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
384 -- Stanzas sent by local clients
7840
92b6aa3ea2ce mod_mam: Decrease priority to zero
Kim Alvefur <zash@zash.se>
parents: 7839
diff changeset
385 module:hook("pre-message/bare", c2s_message_handler, 0);
92b6aa3ea2ce mod_mam: Decrease priority to zero
Kim Alvefur <zash@zash.se>
parents: 7839
diff changeset
386 module:hook("pre-message/full", c2s_message_handler, 0);
7905
daf83bd94906 mod_mam: Fix typo in comment
Kim Alvefur <zash@zash.se>
parents: 7904
diff changeset
387 -- Stanzas to local clients
7840
92b6aa3ea2ce mod_mam: Decrease priority to zero
Kim Alvefur <zash@zash.se>
parents: 7839
diff changeset
388 module:hook("message/bare", message_handler, 0);
92b6aa3ea2ce mod_mam: Decrease priority to zero
Kim Alvefur <zash@zash.se>
parents: 7839
diff changeset
389 module:hook("message/full", message_handler, 0);
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
390
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
391 module:hook("account-disco-info", function(event)
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
392 (event.reply or event.stanza):tag("feature", {var=xmlns_mam}):up();
7891
01d2a2af3146 mod_mam: Advertise Stanza ID support (XEP-0359) (thanks iNPUTmice)
Kim Alvefur <zash@zash.se>
parents: 7890
diff changeset
393 (event.reply or event.stanza):tag("feature", {var=xmlns_st_id}):up();
7836
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
394 end);
30fac9154fd4 mod_mam: Import from prosody-modules
Kim Alvefur <zash@zash.se>
parents:
diff changeset
395