mod_muc_cloud_notify/mod_muc_cloud_notify.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 24 Sep 2022 09:26:26 +0100
changeset 5063 5f1120c284c5
parent 4668 524a9103fb45
permissions -rw-r--r--
mod_cloud_notify_extensions: Add note about dependency Noting here because people might not click through to see it on the mod_cloud_notify_encrypted page.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     1
-- XEP-XXX: MUC Push Notifications
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     2
-- Copyright (C) 2015-2016 Kim Alvefur
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     3
-- Copyright (C) 2017-2018 Thilo Molitor
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     4
--
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     5
-- This file is MIT/X11 licensed.
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     6
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     7
local s_match = string.match;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     8
local s_sub = string.sub;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
     9
local os_time = os.time;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    10
local next = next;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    11
local st = require"util.stanza";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    12
local jid = require"util.jid";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    13
local dataform = require"util.dataforms".new;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    14
local hashes = require"util.hashes";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    15
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    16
local xmlns_push = "urn:xmpp:push:0";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    17
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    18
-- configuration
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    19
local include_body = module:get_option_boolean("push_notification_with_body", false);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    20
local include_sender = module:get_option_boolean("push_notification_with_sender", false);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    21
local max_push_errors = module:get_option_number("push_max_errors", 16);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    22
local max_push_devices = module:get_option_number("push_max_devices", 5);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    23
local dummy_body = module:get_option_string("push_notification_important_body", "New Message!");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    24
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    25
local host_sessions = prosody.hosts[module.host].sessions;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    26
local push_errors = {};
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    27
local id2node = {};
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    28
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    29
module:depends("muc");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    30
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    31
-- ordered table iterator, allow to iterate on the natural order of the keys of a table,
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    32
-- see http://lua-users.org/wiki/SortedIteration
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    33
local function __genOrderedIndex( t )
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    34
	local orderedIndex = {}
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    35
	for key in pairs(t) do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    36
		table.insert( orderedIndex, key )
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    37
	end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    38
	-- sort in reverse order (newest one first)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    39
	table.sort( orderedIndex, function(a, b)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    40
		if a == nil or t[a] == nil or b == nil or t[b] == nil then return false end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    41
		-- only one timestamp given, this is the newer one
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    42
		if t[a].timestamp ~= nil and t[b].timestamp == nil then return true end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    43
		if t[a].timestamp == nil and t[b].timestamp ~= nil then return false end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    44
		-- both timestamps given, sort normally
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    45
		if t[a].timestamp ~= nil and t[b].timestamp ~= nil then return t[a].timestamp > t[b].timestamp end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    46
		return false	-- normally not reached
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    47
	end)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    48
	return orderedIndex
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    49
end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    50
local function orderedNext(t, state)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    51
	-- Equivalent of the next function, but returns the keys in timestamp
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    52
	-- order. We use a temporary ordered key table that is stored in the
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    53
	-- table being iterated.
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    54
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    55
	local key = nil
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    56
	--print("orderedNext: state = "..tostring(state) )
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    57
	if state == nil then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    58
		-- the first time, generate the index
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    59
		t.__orderedIndex = __genOrderedIndex( t )
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    60
		key = t.__orderedIndex[1]
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    61
	else
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    62
		-- fetch the next value
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    63
		for i = 1, #t.__orderedIndex do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    64
			if t.__orderedIndex[i] == state then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    65
				key = t.__orderedIndex[i+1]
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    66
			end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    67
		end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    68
	end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    69
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    70
	if key then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    71
		return key, t[key]
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    72
	end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    73
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    74
	-- no more value to return, cleanup
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    75
	t.__orderedIndex = nil
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    76
	return
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    77
end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    78
local function orderedPairs(t)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    79
	-- Equivalent of the pairs() function on tables. Allows to iterate
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    80
	-- in order
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    81
	return orderedNext, t, nil
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    82
end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    83
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    84
-- small helper function to return new table with only "maximum" elements containing only the newest entries
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    85
local function reduce_table(table, maximum)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    86
	local count = 0;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    87
	local result = {};
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    88
	for key, value in orderedPairs(table) do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    89
		count = count + 1;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    90
		if count > maximum then break end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    91
		result[key] = value;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    92
	end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    93
	return result;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    94
end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
    95
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    96
-- For keeping state across reloads while caching reads
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    97
local push_store = (function()
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    98
	local store = module:open_store();
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
    99
	local push_services = {};
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   100
	local api = {};
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   101
	function api:get(user)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   102
		if not push_services[user] then
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   103
			local err;
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   104
			push_services[user], err = store:get(user);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   105
			if not push_services[user] and err then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   106
				module:log("warn", "Error reading push notification storage for user '%s': %s", user, tostring(err));
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   107
				push_services[user] = {};
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   108
				return push_services[user], false;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   109
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   110
		end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   111
		if not push_services[user] then push_services[user] = {} end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   112
		return push_services[user], true;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   113
	end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   114
	function api:set(user, data)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   115
		push_services[user] = reduce_table(data, max_push_devices);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   116
		local ok, err = store:set(user, push_services[user]);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   117
		if not ok then
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   118
			module:log("error", "Error writing push notification storage for user '%s': %s", user, tostring(err));
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   119
			return false;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   120
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   121
		return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   122
	end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   123
	function api:set_identifier(user, push_identifier, data)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   124
		local services = self:get(user);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   125
		services[push_identifier] = data;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   126
		return self:set(user, services);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   127
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   128
	return api;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   129
end)();
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   130
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   131
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   132
-- Forward declarations, as both functions need to reference each other
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   133
local handle_push_success, handle_push_error;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   134
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   135
function handle_push_error(event)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   136
	local stanza = event.stanza;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   137
	local error_type, condition = stanza:get_error();
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   138
	local node = id2node[stanza.attr.id];
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   139
	if node == nil then return false; end		-- unknown stanza? Ignore for now!
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   140
	local from = stanza.attr.from;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   141
	local user_push_services = push_store:get(node);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   142
	local changed = false;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   143
	
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   144
	for push_identifier, _ in pairs(user_push_services) do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   145
		local stanza_id = hashes.sha256(push_identifier, true);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   146
		if stanza_id == stanza.attr.id then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   147
			if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and error_type ~= "wait" then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   148
				push_errors[push_identifier] = push_errors[push_identifier] + 1;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   149
				module:log("info", "Got error of type '%s' (%s) for identifier '%s': "
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   150
					.."error count for this identifier is now at %s", error_type, condition, push_identifier,
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   151
					tostring(push_errors[push_identifier]));
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   152
				if push_errors[push_identifier] >= max_push_errors then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   153
					module:log("warn", "Disabling push notifications for identifier '%s'", push_identifier);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   154
					-- remove push settings from sessions
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   155
					if host_sessions[node] then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   156
						for _, session in pairs(host_sessions[node].sessions) do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   157
							if session.push_identifier == push_identifier then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   158
								session.push_identifier = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   159
								session.push_settings = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   160
								session.first_hibernated_push = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   161
							end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   162
						end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   163
					end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   164
					-- save changed global config
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   165
					changed = true;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   166
					user_push_services[push_identifier] = nil
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   167
					push_errors[push_identifier] = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   168
					-- unhook iq handlers for this identifier (if possible)
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   169
					if module.unhook then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   170
						module:unhook("iq-error/host/"..stanza_id, handle_push_error);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   171
						module:unhook("iq-result/host/"..stanza_id, handle_push_success);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   172
						id2node[stanza_id] = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   173
					end
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   174
				end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   175
			elseif user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and error_type == "wait" then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   176
				module:log("debug", "Got error of type '%s' (%s) for identifier '%s': "
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   177
					.."NOT increasing error count for this identifier", error_type, condition, push_identifier);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   178
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   179
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   180
	end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   181
	if changed then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   182
		push_store:set(node, user_push_services);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   183
	end
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   184
	return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   185
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   186
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   187
function handle_push_success(event)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   188
	local stanza = event.stanza;
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   189
	local node = id2node[stanza.attr.id];
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   190
	if node == nil then return false; end		-- unknown stanza? Ignore for now!
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   191
	local from = stanza.attr.from;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   192
	local user_push_services = push_store:get(node);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   193
	
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   194
	for push_identifier, _ in pairs(user_push_services) do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   195
		if hashes.sha256(push_identifier, true) == stanza.attr.id then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   196
			if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and push_errors[push_identifier] > 0 then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   197
				push_errors[push_identifier] = 0;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   198
				module:log("debug", "Push succeeded, error count for identifier '%s' is now at %s again", push_identifier, tostring(push_errors[push_identifier]));
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   199
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   200
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   201
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   202
	return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   203
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   204
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   205
-- http://xmpp.org/extensions/xep-0357.html#disco
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   206
local function account_dico_info(event)
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   207
	(event.reply or event.stanza):tag("feature", {var=xmlns_push}):up();
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   208
end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   209
module:hook("account-disco-info", account_dico_info);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   210
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   211
-- http://xmpp.org/extensions/xep-0357.html#enabling
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   212
local function push_enable(event)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   213
	local origin, stanza = event.origin, event.stanza;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   214
	local enable = stanza.tags[1];
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   215
	origin.log("debug", "Attempting to enable push notifications");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   216
	-- MUST contain a 'jid' attribute of the XMPP Push Service being enabled
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   217
	local push_jid = enable.attr.jid;
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   218
	-- SHOULD contain a 'node' attribute
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   219
	local push_node = enable.attr.node;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   220
	-- CAN contain a 'include_payload' attribute
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   221
	local include_payload = enable.attr.include_payload;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   222
	if not push_jid then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   223
		origin.log("debug", "MUC Push notification enable request missing the 'jid' field");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   224
		origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing jid"));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   225
		return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   226
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   227
	local publish_options = enable:get_child("x", "jabber:x:data");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   228
	if not publish_options then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   229
		-- Could be intentional
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   230
		origin.log("debug", "No publish options in request");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   231
	end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   232
	local push_identifier = push_jid .. "<" .. (push_node or "");
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   233
	local push_service = {
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   234
		jid = push_jid;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   235
		node = push_node;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   236
		include_payload = include_payload;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   237
		options = publish_options and st.preserialize(publish_options);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   238
		timestamp = os_time();
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   239
	};
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   240
	local ok = push_store:set_identifier(origin.username.."@"..origin.host, push_identifier, push_service);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   241
	if not ok then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   242
		origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   243
	else
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   244
		origin.push_identifier = push_identifier;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   245
		origin.push_settings = push_service;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   246
		origin.first_hibernated_push = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   247
		origin.log("info", "MUC Push notifications enabled for %s by %s (%s)",
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   248
			 tostring(stanza.attr.to),
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   249
			 tostring(stanza.attr.from),
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   250
			 tostring(origin.push_identifier)
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   251
			);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   252
		origin.send(st.reply(stanza));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   253
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   254
	return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   255
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   256
module:hook("iq-set/host/"..xmlns_push..":enable", push_enable);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   257
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   258
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   259
-- http://xmpp.org/extensions/xep-0357.html#disabling
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   260
local function push_disable(event)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   261
	local origin, stanza = event.origin, event.stanza;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   262
	local push_jid = stanza.tags[1].attr.jid; -- MUST include a 'jid' attribute
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   263
	local push_node = stanza.tags[1].attr.node; -- A 'node' attribute MAY be included
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   264
	if not push_jid then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   265
		origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing jid"));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   266
		return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   267
	end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   268
	local user_push_services = push_store:get(origin.username);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   269
	for key, push_info in pairs(user_push_services) do
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   270
		if push_info.jid == push_jid and (not push_node or push_info.node == push_node) then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   271
			origin.log("info", "Push notifications disabled (%s)", tostring(key));
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   272
			if origin.push_identifier == key then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   273
				origin.push_identifier = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   274
				origin.push_settings = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   275
				origin.first_hibernated_push = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   276
			end
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   277
			user_push_services[key] = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   278
			push_errors[key] = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   279
			if module.unhook then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   280
				module:unhook("iq-error/host/"..key, handle_push_error);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   281
				module:unhook("iq-result/host/"..key, handle_push_success);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   282
				id2node[key] = nil;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   283
			end
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   284
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   285
	end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   286
	local ok = push_store:set(origin.username, user_push_services);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   287
	if not ok then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   288
		origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   289
	else
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   290
		origin.send(st.reply(stanza));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   291
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   292
	return true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   293
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   294
module:hook("iq-set/host/"..xmlns_push..":disable", push_disable);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   295
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   296
-- Patched version of util.stanza:find() that supports giving stanza names
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   297
-- without their namespace, allowing for every namespace.
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   298
local function find(self, path)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   299
	local pos = 1;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   300
	local len = #path + 1;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   301
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   302
	repeat
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   303
		local xmlns, name, text;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   304
		local char = s_sub(path, pos, pos);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   305
		if char == "@" then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   306
			return self.attr[s_sub(path, pos + 1)];
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   307
		elseif char == "{" then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   308
			xmlns, pos = s_match(path, "^([^}]+)}()", pos + 1);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   309
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   310
		name, text, pos = s_match(path, "^([^@/#]*)([/#]?)()", pos);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   311
		name = name ~= "" and name or nil;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   312
		if pos == len then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   313
			if text == "#" then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   314
				local child = xmlns ~= nil and self:get_child(name, xmlns) or self:child_with_name(name);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   315
				return child and child:get_text() or nil;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   316
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   317
			return xmlns ~= nil and self:get_child(name, xmlns) or self:child_with_name(name);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   318
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   319
		self = xmlns ~= nil and self:get_child(name, xmlns) or self:child_with_name(name);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   320
	until not self
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   321
	return nil;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   322
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   324
-- is this push a high priority one (this is needed for ios apps not using voip pushes)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   325
local function is_important(stanza)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   326
	local st_name = stanza and stanza.name or nil;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   327
	if not st_name then return false; end	-- nonzas are never important here
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   328
	if st_name == "presence" then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   329
		return false;						-- same for presences
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   330
	elseif st_name == "message" then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   331
		-- unpack carbon copies
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   332
		local stanza_direction = "in";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   333
		local carbon;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   334
		local st_type;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   335
		-- support carbon copied message stanzas having an arbitrary message-namespace or no message-namespace at all
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   336
		if not carbon then carbon = find(stanza, "{urn:xmpp:carbons:2}/forwarded/message"); end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   337
		if not carbon then carbon = find(stanza, "{urn:xmpp:carbons:1}/forwarded/message"); end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   338
		stanza_direction = carbon and stanza:child_with_name("sent") and "out" or "in";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   339
		if carbon then stanza = carbon; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   340
		st_type = stanza.attr.type;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   341
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   342
		-- headline message are always not important
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   343
		if st_type == "headline" then return false; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   344
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   345
		-- carbon copied outgoing messages are not important
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   346
		if carbon and stanza_direction == "out" then return false; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   347
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   348
		-- We can't check for body contents in encrypted messages, so let's treat them as important
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   349
		-- Some clients don't even set a body or an empty body for encrypted messages
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   350
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   351
		-- check omemo https://xmpp.org/extensions/inbox/omemo.html
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   352
		if stanza:get_child("encrypted", "eu.siacs.conversations.axolotl") or stanza:get_child("encrypted", "urn:xmpp:omemo:0") then return true; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   353
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   354
		-- check xep27 pgp https://xmpp.org/extensions/xep-0027.html
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   355
		if stanza:get_child("x", "jabber:x:encrypted") then return true; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   356
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   357
		-- check xep373 pgp (OX) https://xmpp.org/extensions/xep-0373.html
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   358
		if stanza:get_child("openpgp", "urn:xmpp:openpgp:0") then return true; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   359
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   360
		local body = stanza:get_child_text("body");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   361
		if st_type == "groupchat" and stanza:get_child_text("subject") then return false; end		-- groupchat subjects are not important here
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   362
		return body ~= nil and body ~= "";			-- empty bodies are not important
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   363
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   364
	return false;		-- this stanza wasn't one of the above cases --> it is not important, too
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   365
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   366
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   367
local push_form = dataform {
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   368
	{ name = "FORM_TYPE"; type = "hidden"; value = "urn:xmpp:push:summary"; };
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   369
	{ name = "message-count"; type = "text-single"; };
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   370
	{ name = "pending-subscription-count"; type = "text-single"; };
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   371
	{ name = "last-message-sender"; type = "jid-single"; };
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   372
	{ name = "last-message-body"; type = "text-single"; };
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   373
};
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   374
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   375
-- http://xmpp.org/extensions/xep-0357.html#publishing
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   376
local function handle_notify_request(stanza, node, user_push_services, log_push_decline)
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   377
	local pushes = 0;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   378
	if not user_push_services or next(user_push_services) == nil then return pushes end
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   379
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   380
	-- XXX: customized
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   381
	local body = stanza:get_child_text("body");
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   382
	if not body then
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   383
		return pushes;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   384
	end
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   385
	
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   386
	for push_identifier, push_info in pairs(user_push_services) do
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   387
		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
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   388
		if stanza then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   389
			if not stanza._push_notify then stanza._push_notify = {}; end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   390
			if stanza._push_notify[push_identifier] then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   391
				if log_push_decline then
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   392
					module:log("debug", "Already sent push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node));
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   393
				end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   394
				send_push = false;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   395
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   396
			stanza._push_notify[push_identifier] = true;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   397
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   398
		
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   399
		if send_push then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   400
			-- construct push stanza
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   401
			local stanza_id = hashes.sha256(push_identifier, true);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   402
			local push_publish = st.iq({ to = push_info.jid, from = module.host, type = "set", id = stanza_id })
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   403
				:tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" })
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   404
					:tag("publish", { node = push_info.node })
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   405
						:tag("item")
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   406
							:tag("notification", { xmlns = xmlns_push });
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   407
			local form_data = {
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   408
				-- hardcode to 1 because other numbers are just meaningless (the XEP does not specify *what exactly* to count)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   409
				["message-count"] = "1";
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   410
			};
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   411
			if stanza and include_sender then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   412
				form_data["last-message-sender"] = stanza.attr.from;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   413
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   414
			if stanza and include_body then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   415
				form_data["last-message-body"] = stanza:get_child_text("body");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   416
			elseif stanza and dummy_body and is_important(stanza) then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   417
				form_data["last-message-body"] = tostring(dummy_body);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   418
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   419
			push_publish:add_child(push_form:form(form_data));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   420
			push_publish:up(); -- / notification
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   421
			push_publish:up(); -- / publish
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   422
			push_publish:up(); -- / pubsub
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   423
			if push_info.options then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   424
				push_publish:tag("publish-options"):add_child(st.deserialize(push_info.options));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   425
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   426
			-- send out push
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   427
			module:log("debug", "Sending%s push notification for %s@%s to %s (%s)", form_data["last-message-body"] and " important" or "", node, module.host, push_info.jid, tostring(push_info.node));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   428
			-- module:log("debug", "PUSH STANZA: %s", tostring(push_publish));
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   429
			-- handle push errors for this node
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   430
			if push_errors[push_identifier] == nil then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   431
				push_errors[push_identifier] = 0;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   432
				module:hook("iq-error/host/"..stanza_id, handle_push_error);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   433
				module:hook("iq-result/host/"..stanza_id, handle_push_success);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   434
				id2node[stanza_id] = node;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   435
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   436
			module:send(push_publish);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   437
			pushes = pushes + 1;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   438
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   439
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   440
	return pushes;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   441
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   442
3574
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   443
local function extract_reference(text, i, j)
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   444
        -- COMPAT w/ pre-Lua 5.3
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   445
        local c, pos, p1 = 0, 0, nil;
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   446
        for char in text:gmatch("([%z\1-\127\194-\244][\128-\191]*)") do
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   447
                c, pos = c + 1, pos + #char;
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   448
                if not p1 and i < c then
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   449
                        p1 = pos;
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   450
                end
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   451
                if c == j then
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   452
                        return text:sub(p1, pos);
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   453
                end
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   454
        end
8a93af85f319 mod_muc_cloud_notify: Count codepoints instead of bytes
Matthew Wild <mwild1@gmail.com>
parents: 3323
diff changeset
   455
end
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   456
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   457
-- archive message added
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   458
local function archive_message_added(event)
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   459
	-- event is: { origin = origin, stanza = stanza, for_user = store_user, id = id }
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   460
	-- only notify for new mam messages when at least one device is online
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   461
	local room = event.room;
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   462
	local stanza = event.stanza;
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   463
	local body = stanza:get_child_text('body');
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   464
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   465
	for reference in stanza:childtags("reference", "urn:xmpp:reference:0") do
4668
524a9103fb45 mod_muc_cloud_notify: Fix comparison between string and number in reference extraction. Fixes #1681.
Matthew Wild <mwild1@gmail.com>
parents: 3887
diff changeset
   466
		local ref_begin, ref_end = tonumber(reference.attr['begin']), tonumber(reference.attr['end']);
524a9103fb45 mod_muc_cloud_notify: Fix comparison between string and number in reference extraction. Fixes #1681.
Matthew Wild <mwild1@gmail.com>
parents: 3887
diff changeset
   467
		if reference.attr['type'] == 'mention' and ref_begin and ref_end then
524a9103fb45 mod_muc_cloud_notify: Fix comparison between string and number in reference extraction. Fixes #1681.
Matthew Wild <mwild1@gmail.com>
parents: 3887
diff changeset
   468
			local nick = extract_reference(body, ref_begin, ref_end);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   469
			local jid = room:get_registered_jid(nick);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   470
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   471
			if room._occupants[room.jid..'/'..nick] then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   472
				-- We only notify for members not currently in the room
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   473
				module:log("debug", "Not notifying %s, because he's currently in the room", jid);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   474
			else
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   475
				-- We only need to notify once, even when there are multiple mentions.
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   476
				local user_push_services = push_store:get(jid);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   477
				handle_notify_request(event.stanza, jid, user_push_services, true);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   478
				return
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   479
			end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   480
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   481
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   482
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   483
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   484
module:hook("muc-add-history", archive_message_added);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   485
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   486
local function send_ping(event)
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   487
	local user = event.user;
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   488
	local user_push_services = push_store:get(user);
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   489
	local push_services = event.push_services or user_push_services;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   490
	handle_notify_request(nil, user, push_services, true);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   491
end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   492
-- can be used by other modules to ping one or more (or all) push endpoints
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   493
module:hook("cloud-notify-ping", send_ping);
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   494
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   495
module:log("info", "Module loaded");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   496
function module.unload()
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   497
	if module.unhook then
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   498
		module:unhook("account-disco-info", account_dico_info);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   499
		module:unhook("iq-set/host/"..xmlns_push..":enable", push_enable);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   500
		module:unhook("iq-set/host/"..xmlns_push..":disable", push_disable);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   501
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   502
		module:unhook("muc-add-history", archive_message_added);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   503
		module:unhook("cloud-notify-ping", send_ping);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   504
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   505
		for push_identifier, _ in pairs(push_errors) do
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   506
			local stanza_id = hashes.sha256(push_identifier, true);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   507
			module:unhook("iq-error/host/"..stanza_id, handle_push_error);
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   508
			module:unhook("iq-result/host/"..stanza_id, handle_push_success);
3887
571249f69577 mod_muc_cloud_notify: Revert last commit
tmolitor <thilo@eightysoft.de>
parents: 3886
diff changeset
   509
			id2node[stanza_id] = nil;
3323
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   510
		end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   511
	end
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   512
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   513
	module:log("info", "Module unloaded");
408f92149774 mod_muc_cloud_notify: New module
JC Brand <jc@opkode.com>
parents:
diff changeset
   514
end