Software /
code /
prosody-modules
File
mod_muc_log/mod_muc_log.lua @ 5575:372e59bd45d7
mod_pubsub_feeds: Remove comment, this text is in the README
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 25 Jun 2023 16:48:21 +0200 |
parent | 1567:585bb8ac11bb |
line wrap: on
line source
-- Copyright (C) 2009 Thilo Cestonaro -- Copyright (C) 2009 Waqas Hussain -- Copyright (C) 2009-2013 Matthew Wild -- Copyright (C) 2013 Kim Alvefur -- Copyright (C) 2013 Marco Cirillo local hosts = prosody.hosts; local tostring = tostring; local split_jid = require "util.jid".split; local datamanager = require"core.storagemanager".olddm; local data_load, data_store = datamanager.load, datamanager.store; local datastore = "muc_log"; local muc_form_config_option = "muc#roomconfig_enablelogging" local log_by_default = module:get_option_boolean("muc_log_by_default", false); local log_presences = module:get_option_boolean("muc_log_presences", true); -- Module Definitions local function get_room_from_jid(jid) local node, host = split_jid(jid); local component = hosts[host]; if component then local muc = component.modules.muc if muc and rawget(muc,"rooms") then -- We're running 0.9.x or 0.10 (old MUC API) return muc.rooms[jid]; elseif muc and rawget(muc,"get_room_from_jid") then -- We're running >0.10 (new MUC API) return muc.get_room_from_jid(jid); else return end end end local function logging_enabled(room) local enabled = room._data.logging; if enabled == nil then return log_by_default; end return enabled; end function log_if_needed(event) local stanza = event.stanza; if (stanza.name == "presence") or (stanza.name == "iq") or (stanza.name == "message" and tostring(stanza.attr.type) == "groupchat") then local node, host = split_jid(stanza.attr.to); if node and host then local bare = node .. "@" .. host; if get_room_from_jid(bare) then local room = get_room_from_jid(bare) local today = os.date("!%y%m%d"); local now = os.date("!%H:%M:%S"); local muc_to = nil local muc_from = nil; local already_joined = false; if room._data.hidden then -- do not log any data of private rooms return; end if not logging_enabled(room) then -- do not log where logging is not enabled return; end if stanza.name == "presence" and stanza.attr.type == nil then muc_from = stanza.attr.to; if room._occupants and room._occupants[stanza.attr.to] then already_joined = true; stanza:tag("alreadyJoined"):text("true"); end elseif stanza.name == "iq" and stanza.attr.type == "set" then -- kick, to is the room, from is the admin, nick who is kicked is attr of iq->query->item if stanza.tags[1] and stanza.tags[1].name == "query" then local tmp = stanza.tags[1]; if tmp.tags[1] ~= nil and tmp.tags[1].name == "item" and tmp.tags[1].attr.nick then tmp = tmp.tags[1]; for jid, nick in pairs(room._jid_nick) do if nick == stanza.attr.to .. "/" .. tmp.attr.nick then muc_to = nick; break; end end end end else for jid, nick in pairs(room._jid_nick) do if jid == stanza.attr.from then muc_from = nick; break; end end end if (muc_from or muc_to) then local data = data_load(node, host, datastore .. "/" .. today); local realFrom = stanza.attr.from; local realTo = stanza.attr.to; if data == nil then data = {}; end stanza.attr.from = muc_from; stanza.attr.to = muc_to; data[#data + 1] = "<stanza time=\"".. now .. "\">" .. tostring(stanza) .. "</stanza>\n"; stanza.attr.from = realFrom; stanza.attr.to = realTo; if already_joined == true then if stanza[#stanza].name == "alreadyJoined" then -- normaly the faked element should be the last, remove it when it is the last stanza[#stanza] = nil; else for i = 1, #stanza, 1 do if stanza[i].name == "alreadyJoined" then -- remove the faked element stanza[i] = nil; break; end end end end datamanager.getpath(node, host, datastore, nil, true); -- create the datastore dir data_store(node, host, datastore .. "/" .. today, data); end end end end end module:hook("muc-config-form", function(event) local room, form = event.room, event.form; table.insert(form, { name = muc_form_config_option, type = "boolean", label = "Enable Logging?", value = logging_enabled(room), } ); end); module:hook("muc-config-submitted", function(event) local room, fields, changed = event.room, event.fields, event.changed; local new = fields[muc_form_config_option]; if new ~= room._data.logging then room._data.logging = new; if type(changed) == "table" then changed[muc_form_config_option] = true; else event.changed = true; end end end); module:hook("message/bare", log_if_needed, 1); if log_presences then module:hook("iq/bare", log_if_needed, 1); module:hook("presence/full", log_if_needed, 1); end module:log("debug", "module mod_muc_log loaded!");