mod_push2/mod_push2.lua
author Kim Alvefur <zash@zash.se>
Sun, 03 Mar 2024 11:23:40 +0100
changeset 5857 97c9b76867ca
parent 5849 83ee752f148c
permissions -rw-r--r--
mod_log_ringbuffer: Detach event handlers on logging reload (thanks Menel) Otherwise the global event handlers accumulate, one added each time logging is reoladed, and each invocation of the signal or event triggers one dump of each created ringbuffer.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     1
local os_time = os.time;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     2
local st = require"util.stanza";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     3
local jid = require"util.jid";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     4
local hashes = require"util.hashes";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     5
local random = require"util.random";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     6
local watchdog = require "util.watchdog";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     7
local uuid = require "util.uuid";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     8
local base64 = require "util.encodings".base64;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
     9
local ciphers = require "openssl.cipher";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    10
local pkey = require "openssl.pkey";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    11
local kdf = require "openssl.kdf";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    12
local jwt = require "util.jwt";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    13
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    14
local xmlns_push = "urn:xmpp:push2:0";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    15
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    16
-- configuration
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    17
local contact_uri = module:get_option_string("contact_uri", "xmpp:" .. module.host)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    18
local extended_hibernation_timeout = module:get_option_number("push_max_hibernation_timeout", 72*3600)  -- use same timeout like ejabberd
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    19
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    20
local host_sessions = prosody.hosts[module.host].sessions
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    21
local push2_registrations = module:open_store("push2_registrations", "keyval")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    22
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    23
if _VERSION:match("5%.1") or _VERSION:match("5%.2") then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    24
	module:log("warn", "This module may behave incorrectly on Lua before 5.3. It is recommended to upgrade to a newer Lua version.")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    25
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    26
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    27
local function account_dico_info(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    28
	(event.reply or event.stanza):tag("feature", {var=xmlns_push}):up()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    29
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    30
module:hook("account-disco-info", account_dico_info);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    31
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    32
local function parse_match(matchel)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    33
		local match = { match = matchel.attr.profile }
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    34
		local send = matchel:get_child("send", "urn:xmpp:push2:send:notify-only:0")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    35
		if send then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    36
			match.send = send.attr.xmlns
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    37
			return match
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    38
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    39
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    40
		send = matchel:get_child("send", "urn:xmpp:push2:send:sce+rfc8291+rfc8292:0")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    41
		if send then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    42
			match.send = send.attr.xmlns
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    43
			match.ua_public = send:get_child_text("ua-public")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    44
			match.auth_secret = send:get_child_text("auth-secret")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    45
			match.jwt_alg = send:get_child_text("jwt-alg")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    46
			match.jwt_key = send:get_child_text("jwt-key")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    47
			match.jwt_claims = {}
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    48
			for claim in send:childtags("jwt-claim") do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    49
				match.jwt_claims[claim.attr.name] = claim:get_text()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    50
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    51
			return match
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    52
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    53
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    54
		return nil
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    55
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    56
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    57
local function push_enable(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    58
	local origin, stanza = event.origin, event.stanza;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    59
	local enable = stanza.tags[1];
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    60
	origin.log("debug", "Attempting to enable push notifications")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    61
	-- MUST contain a jid of the push service being enabled
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    62
	local service_jid = enable:get_child_text("service")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    63
	-- MUST contain a string to identify the client fo the push service
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    64
	local client = enable:get_child_text("client")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    65
	if not service_jid then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    66
		origin.log("debug", "Push notification enable request missing service")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    67
		origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing service"))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    68
		return true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    69
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    70
	if not client then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    71
		origin.log("debug", "Push notification enable request missing client")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    72
		origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing client"))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    73
		return true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    74
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    75
	if service_jid == stanza.attr.from then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    76
		origin.log("debug", "Push notification enable request service JID identical to our own")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    77
		origin.send(st.error_reply(stanza, "modify", "bad-request", "JID must be different from ours"))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    78
		return true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    79
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    80
	local matches = {}
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    81
	for matchel in enable:childtags("match") do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    82
		local match = parse_match(matchel)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    83
		if match then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    84
			matches[#matches + 1] = match
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    85
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    86
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    87
	-- Tie registration to client, via client_id with sasl2 or else fallback to resource
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    88
	local registration_id = origin.client_id or origin.resource
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    89
	local push_registration = {
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    90
		service = service_jid;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    91
		client = client;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    92
		timestamp = os_time();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    93
		matches = matches;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    94
	};
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    95
	-- TODO: can we move to keyval+ on trunk?
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    96
	local registrations = push2_registrations:get(origin.username) or {}
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    97
	registrations[registration_id] = push_registration
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    98
	if not push2_registrations:set(origin.username, registrations) then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
    99
		origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   100
	else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   101
		origin.push_registration_id = registration_id
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   102
		origin.push_registration = push_registration
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   103
		origin.first_hibernated_push = nil
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   104
		origin.log("info", "Push notifications enabled for %s (%s)", tostring(stanza.attr.from), tostring(service_jid))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   105
		origin.send(st.reply(stanza))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   106
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   107
	return true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   108
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   109
module:hook("iq-set/self/"..xmlns_push..":enable", push_enable)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   110
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   111
-- urgent stanzas should be delivered without delay
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   112
local function is_voip(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   113
	if stanza.name == "message" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   114
		if stanza:get_child("propose", "urn:xmpp:jingle-message:0") then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   115
			return true, "jingle call"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   116
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   117
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   118
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   119
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   120
local function has_body(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   121
	-- We can't check for body contents in encrypted messages, so let's treat them as important
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   122
	-- Some clients don't even set a body or an empty body for encrypted messages
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   123
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   124
	-- check omemo https://xmpp.org/extensions/inbox/omemo.html
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   125
	if stanza:get_child("encrypted", "eu.siacs.conversations.axolotl") or stanza:get_child("encrypted", "urn:xmpp:omemo:0") then return true; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   126
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   127
	-- check xep27 pgp https://xmpp.org/extensions/xep-0027.html
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   128
	if stanza:get_child("x", "jabber:x:encrypted") then return true; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   129
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   130
	-- check xep373 pgp (OX) https://xmpp.org/extensions/xep-0373.html
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   131
	if stanza:get_child("openpgp", "urn:xmpp:openpgp:0") then return true; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   132
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   133
	local body = stanza:get_child_text("body");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   134
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   135
	return body ~= nil and body ~= ""
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   136
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   137
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   138
-- is this push a high priority one
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   139
local function is_important(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   140
	local is_voip_stanza, urgent_reason = is_voip(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   141
	if is_voip_stanza then return true; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   142
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   143
	local st_name = stanza and stanza.name or nil
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   144
	if not st_name then return false; end -- nonzas are never important here
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   145
	if st_name == "presence" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   146
		return false; -- same for presences
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   147
	elseif st_name == "message" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   148
		-- unpack carbon copied message stanzas
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   149
		local carbon = stanza:find("{urn:xmpp:carbons:2}/{urn:xmpp:forward:0}/{jabber:client}message")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   150
		local stanza_direction = carbon and stanza:child_with_name("sent") and "out" or "in"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   151
		if carbon then stanza = carbon; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   152
		local st_type = stanza.attr.type
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   153
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   154
		-- headline message are always not important
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   155
		if st_type == "headline" then return false; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   156
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   157
		-- carbon copied outgoing messages are not important
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   158
		if carbon and stanza_direction == "out" then return false; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   159
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   160
		-- groupchat subjects are not important here
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   161
		if st_type == "groupchat" and stanza:get_child_text("subject") then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   162
			return false
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   163
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   164
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   165
		-- empty bodies are not important
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   166
		return has_body(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   167
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   168
	return false;		-- this stanza wasn't one of the above cases --> it is not important, too
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   169
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   170
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   171
local function add_sce_rfc8291(match, stanza, push_notification_payload)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   172
	local max_data_size = 2847 -- https://github.com/web-push-libs/web-push-php/issues/108
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   173
	local stanza_clone = st.clone(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   174
	stanza_clone.attr.xmlns = "jabber:client"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   175
	local envelope = st.stanza("envelope", { xmlns = "urn:xmpp:sce:1" })
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   176
		:tag("content")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   177
		:tag("forwarded", { xmlns = "urn:xmpp:forward:0" })
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   178
		:add_child(stanza_clone)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   179
		:up():up():up()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   180
	local envelope_bytes = tostring(envelope)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   181
	if string.len(envelope_bytes) > max_data_size then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   182
		-- If stanza is too big, remove extra elements
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   183
		stanza_clone:maptags(function(el)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   184
			if el.attr.xmlns == nil or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   185
				el.attr.xmlns == "jabber:client" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   186
				el.attr.xmlns == "jabber:x:oob" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   187
				(el.attr.xmlns == "urn:xmpp:sid:0" and el.name == "stanza-id") or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   188
				el.attr.xmlns == "eu.siacs.conversations.axolotl" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   189
				el.attr.xmlns == "urn:xmpp:omemo:0" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   190
				el.attr.xmlns == "jabber:x:encrypted" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   191
				el.attr.xmlns == "urn:xmpp:openpgp:0" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   192
				el.attr.xmlns == "urn:xmpp:sce:1" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   193
				el.attr.xmlns == "urn:xmpp:jingle-message:0" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   194
				el.attr.xmlns == "jabber:x:conference"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   195
			then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   196
				return el
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   197
			else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   198
				return nil
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   199
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   200
		end)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   201
		envelope_bytes = tostring(envelope)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   202
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   203
	if string.len(envelope_bytes) > max_data_size then
5664
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   204
		local body = stanza:get_child_text("body")
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   205
		if string.len(body) > 50 then
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   206
			stanza_clone:maptags(function(el)
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   207
				if el.name == "body" then
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   208
					return nil
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   209
				else
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   210
					return el
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   211
				end
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   212
			end)
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   213
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   214
			body = string.gsub(string.gsub("\n" .. body, "\n>[^\n]*", ""), "^%s", "")
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   215
			stanza_clone:body(body:sub(1, utf8.offset(body, 50)) .. "…")
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   216
			envelope_bytes = tostring(envelope)
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   217
		end
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   218
	end
bebb10fa5787 mod_push2: Add back body truncation logic
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5663
diff changeset
   219
	if string.len(envelope_bytes) > max_data_size then
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   220
		-- If still too big, get aggressive
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   221
		stanza_clone:maptags(function(el)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   222
			if el.name == "body" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   223
				(el.attr.xmlns == "urn:xmpp:sid:0" and el.name == "stanza-id") or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   224
				el.attr.xmlns == "urn:xmpp:jingle-message:0" or
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   225
				el.attr.xmlns == "jabber:x:conference"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   226
			then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   227
				return el
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   228
			else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   229
				return nil
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   230
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   231
		end)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   232
		envelope_bytes = tostring(envelope)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   233
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   234
	if string.len(envelope_bytes) < max_data_size/2 then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   235
		envelope:text_tag("rpad", base64.encode(random.bytes(math.min(150, max_data_size/3 - string.len(envelope_bytes)))))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   236
		envelope_bytes = tostring(envelope)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   237
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   238
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   239
	local p256dh_raw = base64.decode(match.ua_public .. "==")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   240
	local p256dh = pkey.new(p256dh_raw, "*", "public", "prime256v1")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   241
	local one_time_key = pkey.new({ type = "EC", curve = "prime256v1" })
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   242
	local one_time_key_public = one_time_key:getParameters().pub_key:toBinary()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   243
	local info = "WebPush: info\0" .. p256dh_raw .. one_time_key_public
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   244
	local auth_secret = base64.decode(match.auth_secret .. "==")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   245
	local salt = random.bytes(16)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   246
	local shared_secret = one_time_key:derive(p256dh)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   247
	local ikm = kdf.derive({
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   248
		type = "HKDF",
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   249
		outlen = 32,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   250
		salt = auth_secret,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   251
		key = shared_secret,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   252
		info = info,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   253
		md = "sha256"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   254
	})
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   255
	local key = kdf.derive({
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   256
		type = "HKDF",
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   257
		outlen = 16,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   258
		salt = salt,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   259
		key = ikm,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   260
		info = "Content-Encoding: aes128gcm\0",
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   261
		md = "sha256"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   262
	})
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   263
	local nonce = kdf.derive({
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   264
		type = "HKDF",
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   265
		outlen = 12,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   266
		salt = salt,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   267
		key = ikm,
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   268
		info = "Content-Encoding: nonce\0",
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   269
		md = "sha256"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   270
	})
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   271
	local header = salt .. "\0\0\16\0" .. string.char(string.len(one_time_key_public)) .. one_time_key_public
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   272
	local encryptor = ciphers.new("AES-128-GCM"):encrypt(key, nonce)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   273
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   274
	push_notification_payload
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   275
		:tag("encrypted", { xmlns = "urn:xmpp:sce:rfc8291:0" })
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   276
		:text_tag("payload", base64.encode(header .. encryptor:final(envelope_bytes .. "\2") .. encryptor:getTag(16)))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   277
		:up()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   278
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   279
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   280
local function add_rfc8292(match, stanza, push_notification_payload)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   281
	if not match.jwt_alg then return; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   282
	local key = match.jwt_key
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   283
	if match.jwt_alg ~= "HS256" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   284
		-- keypairs are in PKCS#8 PEM format without header/footer
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   285
		key = "-----BEGIN PRIVATE KEY-----\n"..key.."\n-----END PRIVATE KEY-----"
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   286
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   287
5667
a1d22d6efb3d mod_push2: Need to include the public key with the JWT
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5664
diff changeset
   288
	local public_key = pkey.new(key):getParameters().pub_key:toBinary()
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   289
	local signer = jwt.new_signer(match.jwt_alg, key)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   290
	local payload = {}
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   291
	for k, v in pairs(match.jwt_claims or {}) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   292
		payload[k] = v
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   293
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   294
	payload.sub = contact_uri
5667
a1d22d6efb3d mod_push2: Need to include the public key with the JWT
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5664
diff changeset
   295
	push_notification_payload:text_tag("jwt", signer(payload), { key = base64.encode(public_key) })
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   296
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   297
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   298
local function handle_notify_request(stanza, node, user_push_services, log_push_decline)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   299
	local pushes = 0;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   300
	if not #user_push_services then return pushes end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   301
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   302
	local notify_push_services = {};
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   303
	if is_important(stanza) then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   304
		notify_push_services = user_push_services
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   305
	else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   306
		for identifier, push_info in pairs(user_push_services) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   307
			for _, match in ipairs(push_info.matches) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   308
				if match.match == "urn:xmpp:push2:match:important" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   309
					identifier_found.log("debug", "Not pushing because not important")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   310
				else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   311
					notify_push_services[identifier] = push_info;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   312
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   313
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   314
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   315
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   316
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   317
	for push_registration_id, push_info in pairs(notify_push_services) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   318
		local send_push = true;		-- only send push to this node when not already done for this stanza or if no stanza is given at all
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   319
		if stanza then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   320
			if not stanza._push_notify2 then stanza._push_notify2 = {}; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   321
			if stanza._push_notify2[push_registration_id] then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   322
				if log_push_decline then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   323
					module:log("debug", "Already sent push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node));
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   324
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   325
				send_push = false;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   326
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   327
			stanza._push_notify2[push_registration_id] = true;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   328
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   329
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   330
		if send_push then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   331
			local push_notification_payload = st.stanza("notification", { xmlns = xmlns_push })
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   332
			push_notification_payload:text_tag("client", push_info.client)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   333
			push_notification_payload:text_tag("priority", is_voip(stanza) and "high" or (is_important(stanza) and "normal" or "low"))
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   334
			if is_voip(stanza) then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   335
				push_notification_payload:tag("voip"):up()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   336
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   337
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   338
			local sends_added = {};
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   339
			for _, match in ipairs(push_info.matches) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   340
				local does_match = false;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   341
				if match.match == "urn:xmpp:push2:match:all" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   342
					does_match = true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   343
				elseif match.match == "urn:xmpp:push2:match:important" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   344
					does_match = is_important(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   345
				elseif match.match == "urn:xmpp:push2:match:archived" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   346
					does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   347
				elseif match.match == "urn:xmpp:push2:match:archived-with-body" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   348
					does_match = stanza:get_child("stana-id", "urn:xmpp:sid:0") and has_body(stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   349
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   350
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   351
				if does_match and not sends_added[match.send] then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   352
					sends_added[match.send] = true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   353
					if match.send == "urn:xmpp:push2:send:notify-only" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   354
						-- Nothing more to add
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   355
					elseif match.send == "urn:xmpp:push2:send:sce+rfc8291+rfc8292:0" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   356
						add_sce_rfc8291(match, stanza, push_notification_payload)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   357
						add_rfc8292(match, stanza, push_notification_payload)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   358
					else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   359
						module:log("debug", "Unkonwn send profile: " .. push_info.send)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   360
					end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   361
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   362
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   363
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   364
			local push_publish = st.message({ to = push_info.service, from = module.host, id = uuid.generate() })
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   365
				:add_child(push_notification_payload):up()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   366
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   367
			-- TODO: watch for message error replies and count or something
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   368
			module:send(push_publish)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   369
			pushes = pushes + 1
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   370
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   371
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   372
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   373
	return pushes
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   374
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   375
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   376
-- small helper function to extract relevant push settings
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   377
local function get_push_settings(stanza, session)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   378
	local to = stanza.attr.to
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   379
	local node = to and jid.split(to) or session.username
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   380
	local user_push_services = push2_registrations:get(node)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   381
	return node, (user_push_services or {})
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   382
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   383
5668
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   384
-- publish on offline message
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   385
module:hook("message/offline/handle", function(event)
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   386
	local node, user_push_services = get_push_settings(event.stanza, event.origin);
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   387
	module:log("debug", "Invoking handle_notify_request() for offline stanza");
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   388
	handle_notify_request(event.stanza, node, user_push_services, true);
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   389
end, 1);
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   390
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   391
-- publish on bare groupchat
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   392
-- this picks up MUC messages when there are no devices connected
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   393
module:hook("message/bare/groupchat", function(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   394
	local node, user_push_services = get_push_settings(event.stanza, event.origin);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   395
	local notify_push_services = {};
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   396
	for identifier, push_info in pairs(user_push_services) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   397
		for _, match in ipairs(push_info.matches) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   398
			if match.match == "urn:xmpp:push2:match:archived-with-body" or match.match == "urn:xmpp:push2:match:archived" then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   399
				identifier_found.log("debug", "Not pushing because we are not archiving this stanza")
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   400
			else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   401
				notify_push_services[identifier] = push_info;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   402
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   403
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   404
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   405
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   406
	handle_notify_request(event.stanza, node, notify_push_services, true);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   407
end, 1);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   408
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   409
local function process_stanza_queue(queue, session, queue_type)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   410
	if not session.push_registration_id then return; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   411
	local user_push_services = {[session.push_registration_id] = session.push_settings};
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   412
	local notified = { unimportant = false; important = false }
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   413
	for i=1, #queue do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   414
		local stanza = queue[i];
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   415
		-- fast ignore of already pushed stanzas
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   416
		if stanza and not (stanza._push_notify2 and stanza._push_notify2[session.push_registration_id]) then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   417
			local node = get_push_settings(stanza, session);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   418
			local stanza_type = "unimportant";
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   419
			if is_important(stanza) then stanza_type = "important"; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   420
			if not notified[stanza_type] then		-- only notify if we didn't try to push for this stanza type already
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   421
				if handle_notify_request(stanza, node, user_push_services, false) ~= 0 then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   422
					if session.hibernating and not session.first_hibernated_push then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   423
						-- if the message was important
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   424
						-- then record the time of first push in the session for the smack module which will extend its hibernation
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   425
						-- timeout based on the value of session.first_hibernated_push
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   426
						if is_important(stanza) then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   427
							session.first_hibernated_push = os_time();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   428
							-- check for prosody 0.12 mod_smacks
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   429
							if session.hibernating_watchdog and session.original_smacks_callback and session.original_smacks_timeout then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   430
								-- restore old smacks watchdog (--> the start of our original timeout will be delayed until first push)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   431
								session.hibernating_watchdog:cancel();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   432
								session.hibernating_watchdog = watchdog.new(session.original_smacks_timeout, session.original_smacks_callback);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   433
							end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   434
						end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   435
					end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   436
					notified[stanza_type] = true
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   437
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   438
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   439
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   440
		if notified.unimportant and notified.important then break; end		-- stop processing the queue if all push types are exhausted
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   441
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   442
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   443
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   444
-- publish on unacked smacks message (use timer to send out push for all stanzas submitted in a row only once)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   445
local function process_stanza(session, stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   446
	if session.push_registration_id then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   447
		session.log("debug", "adding new stanza to push_queue");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   448
		if not session.push_queue then session.push_queue = {}; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   449
		local queue = session.push_queue;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   450
		queue[#queue+1] = st.clone(stanza);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   451
		if not session.awaiting_push_timer then		-- timer not already running --> start new timer
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   452
			session.awaiting_push_timer = module:add_timer(1.0, function ()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   453
				process_stanza_queue(session.push_queue, session, "push");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   454
				session.push_queue = {};		-- clean up queue after push
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   455
				session.awaiting_push_timer = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   456
			end);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   457
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   458
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   459
	return stanza;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   460
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   461
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   462
local function process_smacks_stanza(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   463
	local session = event.origin;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   464
	local stanza = event.stanza;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   465
	if not session.push_registration_id then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   466
		session.log("debug", "NOT invoking handle_notify_request() for newly smacks queued stanza (session.push_registration_id is not set: %s)",
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   467
			session.push_registration_id
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   468
		);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   469
	else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   470
		process_stanza(session, stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   471
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   472
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   473
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   474
-- smacks hibernation is started
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   475
local function hibernate_session(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   476
	local session = event.origin;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   477
	local queue = event.queue;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   478
	session.first_hibernated_push = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   479
	if session.push_registration_id and session.hibernating_watchdog then -- check for prosody 0.12 mod_smacks
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   480
		-- save old watchdog callback and timeout
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   481
		session.original_smacks_callback = session.hibernating_watchdog.callback;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   482
		session.original_smacks_timeout = session.hibernating_watchdog.timeout;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   483
		-- cancel old watchdog and create a new watchdog with extended timeout
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   484
		session.hibernating_watchdog:cancel();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   485
		session.hibernating_watchdog = watchdog.new(extended_hibernation_timeout, function()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   486
			session.log("debug", "Push-extended smacks watchdog triggered");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   487
			if session.original_smacks_callback then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   488
				session.log("debug", "Calling original smacks watchdog handler");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   489
				session.original_smacks_callback();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   490
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   491
		end);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   492
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   493
	-- process unacked stanzas
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   494
	process_stanza_queue(queue, session, "smacks");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   495
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   496
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   497
-- smacks hibernation is ended
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   498
local function restore_session(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   499
	local session = event.resumed;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   500
	if session then		-- older smacks module versions send only the "intermediate" session in event.session and no session.resumed one
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   501
		if session.awaiting_push_timer then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   502
			session.awaiting_push_timer:stop();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   503
			session.awaiting_push_timer = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   504
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   505
		session.first_hibernated_push = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   506
		-- the extended smacks watchdog will be canceled by the smacks module, no need to anything here
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   507
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   508
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   509
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   510
-- smacks ack is delayed
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   511
local function ack_delayed(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   512
	local session = event.origin;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   513
	local queue = event.queue;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   514
	local stanza = event.stanza;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   515
	if not session.push_registration_id then return; end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   516
	if stanza then process_stanza(session, stanza); return; end		-- don't iterate through smacks queue if we know which stanza triggered this
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   517
	for i=1, #queue do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   518
		local queued_stanza = queue[i];
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   519
		-- process unacked stanzas (handle_notify_request() will only send push requests for new stanzas)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   520
		process_stanza(session, queued_stanza);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   521
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   522
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   523
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   524
-- archive message added
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   525
local function archive_message_added(event)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   526
	-- event is: { origin = origin, stanza = stanza, for_user = store_user, id = id }
5668
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   527
	-- only notify for new mam messages when at least one device is online
4b052598e435 mod_push2: restore offline message hook
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5667
diff changeset
   528
	if not event.for_user or not host_sessions[event.for_user] then return; end
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   529
	-- Note that the stanza in the event is a clone not the same as other hooks, so dedupe doesn't work
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   530
	-- This is a problem if you wan to to also hook offline message storage for example
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   531
	local stanza = st.clone(event.stanza)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   532
	stanza:tag("stanza-id", { xmlns = "urn:xmpp:sid:0", by = event.for_user.."@"..module.host, id = event.id }):up()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   533
	local user_session = host_sessions[event.for_user] and host_sessions[event.for_user].sessions or {}
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   534
	local to = stanza.attr.to
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   535
	to = to and jid.split(to) or event.origin.username
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   536
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   537
	-- only notify if the stanza destination is the mam user we store it for
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   538
	if event.for_user == to then
5849
83ee752f148c mod_push2: empty table instead of nil when not present
Stephen Paul Weber <singpolyma@singpolyma.net>
parents: 5668
diff changeset
   539
		local user_push_services = push2_registrations:get(to) or {}
5663
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   540
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   541
		-- Urgent stanzas are time-sensitive (e.g. calls) and should
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   542
		-- be pushed immediately to avoid getting stuck in the smacks
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   543
		-- queue in case of dead connections, for example
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   544
		local is_voip_stanza, urgent_reason = is_voip(stanza);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   545
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   546
		local notify_push_services;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   547
		if is_voip_stanza then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   548
			module:log("debug", "Urgent push for %s (%s)", to, urgent_reason);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   549
			notify_push_services = user_push_services;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   550
		else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   551
			-- only notify nodes with no active sessions (smacks is counted as active and handled separate)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   552
			notify_push_services = {};
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   553
			for identifier, push_info in pairs(user_push_services) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   554
				local identifier_found = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   555
				for _, session in pairs(user_session) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   556
					if session.push_registration_id == identifier then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   557
						identifier_found = session;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   558
						break;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   559
					end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   560
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   561
				if identifier_found then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   562
					identifier_found.log("debug", "Not pushing '%s' of new MAM stanza (session still alive)", identifier)
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   563
				else
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   564
					notify_push_services[identifier] = push_info
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   565
				end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   566
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   567
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   568
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   569
		handle_notify_request(stanza, to, notify_push_services, true);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   570
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   571
end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   572
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   573
module:hook("smacks-hibernation-start", hibernate_session);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   574
module:hook("smacks-hibernation-end", restore_session);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   575
module:hook("smacks-ack-delayed", ack_delayed);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   576
module:hook("smacks-hibernation-stanza-queued", process_smacks_stanza);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   577
module:hook("archive-message-added", archive_message_added);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   578
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   579
module:log("info", "Module loaded");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   580
function module.unload()
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   581
	module:log("info", "Unloading module");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   582
	-- cleanup some settings, reloading this module can cause process_smacks_stanza() to stop working otherwise
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   583
	for user, _ in pairs(host_sessions) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   584
		for _, session in pairs(host_sessions[user].sessions) do
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   585
			if session.awaiting_push_timer then session.awaiting_push_timer:stop(); end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   586
			session.awaiting_push_timer = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   587
			session.push_queue = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   588
			session.first_hibernated_push = nil;
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   589
			-- check for prosody 0.12 mod_smacks
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   590
			if session.hibernating_watchdog and session.original_smacks_callback and session.original_smacks_timeout then
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   591
				-- restore old smacks watchdog
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   592
				session.hibernating_watchdog:cancel();
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   593
				session.hibernating_watchdog = watchdog.new(session.original_smacks_timeout, session.original_smacks_callback);
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   594
			end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   595
		end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   596
	end
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   597
	module:log("info", "Module unloaded");
4d1a3de56c3d Initial work on Push 2.0
Stephen Paul Weber <singpolyma@singpolyma.net>
parents:
diff changeset
   598
end