changeset 4012:fd582067c732

mod_lastlog2: Store last timestamp per account event Incompatible with mod_lastlog and other modules using its data due to use of map store
author Kim Alvefur <zash@zash.se>
date Sun, 29 Mar 2020 15:09:25 +0200
parents de40686ae9c8
children e1e337dc05b6
files mod_lastlog2/README.markdown mod_lastlog2/mod_lastlog2.lua
diffstat 2 files changed, 116 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_lastlog2/README.markdown	Sun Mar 29 15:09:25 2020 +0200
@@ -0,0 +1,43 @@
+---
+labels:
+- 'Stage-Beta'
+summary: Record last timestamp of events
+---
+
+# Introduction
+
+Similar to [mod_lastlog], this module records the last timestamp of
+various events, but keeps the last timestamp per type of event, instead
+of the last event.
+
+# Usage
+
+As with all modules, copy it to your plugins directory and then add it
+to the modules\_enabled list:
+
+``` {.lua}
+modules_enabled = {
+  -- other modules
+  "lastlog2",
+}
+```
+
+# Configuration
+
+There are some options you can add to your config file:
+
+  Name                   Type      Default   Description
+  ---------------------- --------- --------- ---------------------------------
+  lastlog\_ip\_address   boolean   false     Log the IP address of the user?
+
+# Usage
+
+You can check a user's last activity by running:
+
+    prosodyctl mod_lastlog username@example.com
+
+# Compatibility
+
+  Version   State
+  --------- -------
+  Any       *TBD*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_lastlog2/mod_lastlog2.lua	Sun Mar 29 15:09:25 2020 +0200
@@ -0,0 +1,73 @@
+local jid = require "util.jid";
+local time = os.time;
+local log_ip = module:get_option_boolean("lastlog_ip_address", false);
+
+local store;
+if module.host ~= "*" then -- workaround for prosodyctl loading into global context
+	store = module:open_store(nil, "map");
+end
+
+module:hook("authentication-success", function(event)
+	local session = event.session;
+	if session.username then
+		store:set(session.username, "login", {
+			timestamp = time(),
+			ip = log_ip and session and session.ip or nil,
+		});
+	end
+end);
+
+module:hook("resource-unbind", function(event)
+	local session = event.session;
+	if session.username then
+		store:set(session.username, "logout", {
+			timestamp = time(),
+			ip = log_ip and session and session.ip or nil,
+		});
+	end
+end);
+
+module:hook("user-registered", function(event)
+	local session = event.session;
+	store:set(event.username, "lastlog", {
+		event = "registered";
+		timestamp = time(),
+		ip = log_ip and session and session.ip or nil,
+	});
+end);
+
+
+if module:get_host_type() == "component" then
+	module:hook("message/bare", function(event)
+		local room = jid.split(event.stanza.attr.to);
+		if room then
+			store:set(room, module.host, "message", {
+				timestamp = time(),
+			});
+		end
+	end);
+end
+
+function module.command(arg)
+	if not arg[1] or arg[1] == "--help" then
+		require"util.prosodyctl".show_usage([[mod_lastlog <user@host>]], [[Show when user last logged in or out]]);
+		return 1;
+	end
+	local user, host = jid.prepped_split(table.remove(arg, 1));
+	require"core.storagemanager".initialize_host(host);
+	store = module:context(host):open_store();
+	local lastlog = store:get(user);
+	if lastlog then
+		for event, data in pairs(lastlog) do
+			print(("Last %s: %s"):format(event,
+				data.timestamp and os.date("%Y-%m-%d %H:%M:%S", data.timestamp) or "<unknown>"));
+			if lastlog.ip then
+				print("IP address: "..lastlog.ip);
+			end
+		end
+	else
+		print("No record found");
+		return 1;
+	end
+	return 0;
+end