Comparison

mod_mam/mod_mam.lua @ 2506:5941aac79f06

mod_mam: Add support for XEP-0313 v0.5
author Kim Alvefur <zash@zash.se>
date Mon, 20 Feb 2017 00:41:13 +0100
parent 2505:1398f3f76c0f
child 2510:d81882aa0e1e
comparison
equal deleted inserted replaced
2505:1398f3f76c0f 2506:5941aac79f06
1 -- XEP-0313: Message Archive Management for Prosody 1 -- XEP-0313: Message Archive Management for Prosody
2 -- Copyright (C) 2011-2016 Kim Alvefur 2 -- Copyright (C) 2011-2016 Kim Alvefur
3 -- 3 --
4 -- This file is MIT/X11 licensed. 4 -- This file is MIT/X11 licensed.
5 5
6 local xmlns_mam = "urn:xmpp:mam:0"; 6 local xmlns_mam0 = "urn:xmpp:mam:0";
7 local xmlns_mam1 = "urn:xmpp:mam:1";
7 local xmlns_delay = "urn:xmpp:delay"; 8 local xmlns_delay = "urn:xmpp:delay";
8 local xmlns_forward = "urn:xmpp:forward:0"; 9 local xmlns_forward = "urn:xmpp:forward:0";
9 10
10 local um = require "core.usermanager"; 11 local um = require "core.usermanager";
11 local st = require "util.stanza"; 12 local st = require "util.stanza";
52 end 53 end
53 54
54 local cleanup; 55 local cleanup;
55 56
56 -- Handle prefs. 57 -- Handle prefs.
57 module:hook("iq/self/"..xmlns_mam..":prefs", function(event) 58 local function handle_prefs(event)
58 local origin, stanza = event.origin, event.stanza; 59 local origin, stanza = event.origin, event.stanza;
60 local xmlns_mam = stanza.tags[1].attr.xmlns;
59 local user = origin.username; 61 local user = origin.username;
60 if stanza.attr.type == "get" then 62 if stanza.attr.type == "get" then
61 local prefs = prefs_to_stanza(get_prefs(user)); 63 local prefs = prefs_to_stanza(get_prefs(user), xmlns_mam);
62 local reply = st.reply(stanza):add_child(prefs); 64 local reply = st.reply(stanza):add_child(prefs);
63 origin.send(reply); 65 origin.send(reply);
64 else -- type == "set" 66 else -- type == "set"
65 local new_prefs = stanza:get_child("prefs", xmlns_mam); 67 local new_prefs = stanza:get_child("prefs", xmlns_mam);
66 local prefs = prefs_from_stanza(new_prefs); 68 local prefs = prefs_from_stanza(new_prefs);
70 else 72 else
71 origin.send(st.reply(stanza)); 73 origin.send(st.reply(stanza));
72 end 74 end
73 end 75 end
74 return true; 76 return true;
75 end); 77 end
78
79 module:hook("iq/self/"..xmlns_mam0..":prefs", handle_prefs);
80 module:hook("iq/self/"..xmlns_mam1..":prefs", handle_prefs);
76 81
77 local query_form = dataform { 82 local query_form = dataform {
78 { name = "FORM_TYPE"; type = "hidden"; value = xmlns_mam; }; 83 { name = "FORM_TYPE"; type = "hidden"; value = xmlns_mam0; };
79 { name = "with"; type = "jid-single"; }; 84 { name = "with"; type = "jid-single"; };
80 { name = "start"; type = "text-single" }; 85 { name = "start"; type = "text-single" };
81 { name = "end"; type = "text-single"; }; 86 { name = "end"; type = "text-single"; };
82 }; 87 };
83 88
84 -- Serve form 89 -- Serve form
85 module:hook("iq-get/self/"..xmlns_mam..":query", function(event) 90 local function handle_get_form(event)
86 local origin, stanza = event.origin, event.stanza; 91 local origin, stanza = event.origin, event.stanza;
92 local xmlns_mam = stanza.tags[1].attr.xmlns;
93 query_form[1].value = xmlns_mam;
87 origin.send(st.reply(stanza):query(xmlns_mam):add_child(query_form:form())); 94 origin.send(st.reply(stanza):query(xmlns_mam):add_child(query_form:form()));
88 return true; 95 return true;
89 end); 96 end
97
98 module:hook("iq-get/self/"..xmlns_mam0..":query", handle_get_form);
99 module:hook("iq-get/self/"..xmlns_mam1..":query", handle_get_form);
90 100
91 -- Handle archive queries 101 -- Handle archive queries
92 module:hook("iq-set/self/"..xmlns_mam..":query", function(event) 102 local function handle_mam_query(event)
93 local origin, stanza = event.origin, event.stanza; 103 local origin, stanza = event.origin, event.stanza;
104 local xmlns_mam = stanza.tags[1].attr.xmlns;
94 local query = stanza.tags[1]; 105 local query = stanza.tags[1];
95 local qid = query.attr.queryid; 106 local qid = query.attr.queryid;
96 107
97 if cleanup then cleanup[origin.username] = true; end 108 if cleanup then cleanup[origin.username] = true; end
98 109
99 -- Search query parameters 110 -- Search query parameters
100 local qwith, qstart, qend; 111 local qwith, qstart, qend;
101 local form = query:get_child("x", "jabber:x:data"); 112 local form = query:get_child("x", "jabber:x:data");
102 if form then 113 if form then
103 local err; 114 local err;
115 query_form[1].value = xmlns_mam;
104 form, err = query_form:data(form); 116 form, err = query_form:data(form);
105 if err then 117 if err then
106 origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err)))); 118 origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err))));
107 return true; 119 return true;
108 end 120 end
144 origin.send(st.error_reply(stanza, "cancel", "internal-server-error", err)); 156 origin.send(st.error_reply(stanza, "cancel", "internal-server-error", err));
145 return true; 157 return true;
146 end 158 end
147 local total = tonumber(err); 159 local total = tonumber(err);
148 160
149 origin.send(st.reply(stanza)); 161 if xmlns_mam == xmlns_mam0 then
162 origin.send(st.reply(stanza));
163 end
150 local msg_reply_attr = { to = stanza.attr.from, from = stanza.attr.to }; 164 local msg_reply_attr = { to = stanza.attr.from, from = stanza.attr.to };
151 165
152 local results = {}; 166 local results = {};
153 167
154 -- Wrap it in stuff and deliver 168 -- Wrap it in stuff and deliver
190 end 204 end
191 205
192 -- That's all folks! 206 -- That's all folks!
193 module:log("debug", "Archive query %s completed", tostring(qid)); 207 module:log("debug", "Archive query %s completed", tostring(qid));
194 208
195 origin.send(st.message(msg_reply_attr) 209 local fin;
196 :tag("fin", { xmlns = xmlns_mam, queryid = qid, complete = complete }) 210 if xmlns_mam == xmlns_mam0 then
211 fin = st.message(msg_reply_attr);
212 else
213 fin = st.reply(stanza);
214 end
215 do
216 fin:tag("fin", { xmlns = xmlns_mam, queryid = qid, complete = complete })
197 :add_child(rsm.generate { 217 :add_child(rsm.generate {
198 first = first, last = last, count = total })); 218 first = first, last = last, count = total })
219 end
220 origin.send(fin);
199 return true; 221 return true;
200 end); 222 end
223 module:hook("iq-set/self/"..xmlns_mam0..":query", handle_mam_query);
224 module:hook("iq-set/self/"..xmlns_mam1..":query", handle_mam_query);
201 225
202 local function has_in_roster(user, who) 226 local function has_in_roster(user, who)
203 local roster = rm_load_roster(user, host); 227 local roster = rm_load_roster(user, host);
204 module:log("debug", "%s has %s in roster? %s", user, who, roster[who] and "yes" or "no"); 228 module:log("debug", "%s has %s in roster? %s", user, who, roster[who] and "yes" or "no");
205 return roster[who]; 229 return roster[who];
328 module:hook("pre-message/full", c2s_message_handler, 2); 352 module:hook("pre-message/full", c2s_message_handler, 2);
329 -- Stanszas to local clients 353 -- Stanszas to local clients
330 module:hook("message/bare", message_handler, 2); 354 module:hook("message/bare", message_handler, 2);
331 module:hook("message/full", message_handler, 2); 355 module:hook("message/full", message_handler, 2);
332 356
333 module:add_feature(xmlns_mam); -- COMPAT with XEP-0313 v 0.1 357 module:add_feature(xmlns_mam0); -- COMPAT with XEP-0313 v 0.1
334 358
335 module:hook("account-disco-info", function(event) 359 module:hook("account-disco-info", function(event)
336 (event.reply or event.stanza):tag("feature", {var=xmlns_mam}):up(); 360 (event.reply or event.stanza):tag("feature", {var=xmlns_mam0}):up();
361 (event.reply or event.stanza):tag("feature", {var=xmlns_mam1}):up();
337 end); 362 end);
338 363