view mod_muc_occupant_id/mod_muc_occupant_id.lua @ 3902:341850e8866f

mod_muc_moderation: Broadcast retraction via method that saves it Otherwise the retraction is not saved to history, so that those who join after it was sent are unaware of the retraction
author Kim Alvefur <zash@zash.se>
date Sat, 22 Feb 2020 21:41:31 +0100
parents 7440cffe30e2
children d14fc974efbc
line wrap: on
line source


-- Implementation of https://xmpp.org/extensions/inbox/occupant-id.html
-- XEP-0421: Anonymous unique occupant identifiers for MUCs

module:depends("muc");

local uuid = require "util.uuid";
local hmac_sha256 = require "util.hashes".hmac_sha256;
local b64encode = require "util.encodings".base64.encode;

local xmlns_occupant_id = "urn:xmpp:occupant-id:0";

local function generate_id(occupant, room)
	local bare = occupant.bare_jid;

	if room._data.occupant_id_salt == nil then
		room._data.occupant_id_salt = uuid.generate();
	end

	if room._data.occupant_ids == nil then
		room._data.occupant_ids = {};
	end

	if room._data.occupant_ids[bare] == nil then
		local unique_id = b64encode(hmac_sha256(bare, room._data.occupant_id_salt));
		room._data.occupant_ids[bare] = unique_id;
	end

	return room._data.occupant_ids[bare];
end

local function update_occupant(event)
	local stanza, occupant, room = event.stanza, event.occupant, event.room;

	-- strip any existing <occupant-id/> tags to avoid forgery
	stanza:remove_children("occupant-id", xmlns_occupant_id);

	local unique_id = generate_id(occupant, room);
	stanza:tag("occupant-id", { xmlns = xmlns_occupant_id })
		:text(unique_id)
		:up();
end

module:add_feature(xmlns_occupant_id);
module:hook("muc-disco#info", function (event)
	event.reply:tag("feature", { var = xmlns_occupant_id }):up();
end);

-- TODO: Handle MUC-PMs
module:hook("muc-broadcast-presence", update_occupant);
module:hook("muc-occupant-pre-join", update_occupant);
module:hook("muc-occupant-groupchat", update_occupant);