Get the list of rooms

But that does not mean it is not encrypted between endpoints and server.

It’s not as secure because as it’s not e2e encrypted, this means that the jiitmeet team can decrypt the data on the server. This means if served with a valid Swiss court order, these guys do have the ability to turn users over.

You do mean https://jitsi.org/blog/e2ee/, right? Would you please indicate which part of the article states that?

It says:

The need to decrypt information while it traverses Jitsi Videobridge, technically provides whoever controls the JVB machine with an opportunity to access the data. They are hence in a position to hear and see everyone on the meeting.

So far, our only answer to this has been that people who feel they cannot trust existing service providers not to eavesdrop on their meetings, can run their own bridges.

Which is why the team works on E2EE.

If you do not trust the team from the first in any way, I recommend you to verify the source code by yourself (that is what open source is all about) and run your own videobridge to start a self-hosted instance.

My point is not every person that wants to use a videoconference app is a programmer, they can’t check the code themselves.

Sorry but I don’t get your point… The UI is enough easy / straightforward to enable that.

  • “one can’t use any hacking tricks to get the active chat room names?”: answered
  • “the data is not e2e encrypted, as stated in the official website.”: e2ee will fix the issue. answered
  • “It’s not as secure because as it’s not e2e encrypted”: see above. answered
  • “not every person that wants to use a videoconference app is a programmer”: UI will be straightforward enough. answered.

I’m taking off as all of your questions / concerns have been addressed.

Yes, that is the app on the phone. I am talking about the desktop version, on your laptop, web-based.

This is the web based. You need chrome 83 or the latest jitsi-meet-electron desktop app. Mobile support for e2e is still in the works.

1 Like

I don’t see that menu on my right setting pane when I visit https://meet.jit.si/. DO I need to install the chrome extension?

I don’t see that menu on my right setting pane when I visit https://meet.jit.si/. DO I need to install the chrome extension?

Are you running Chrome 83 or jitsi-meet-electron latest version?

Modified mod_muc_size.lua with some fixes

-- Prosody IM
-- Copyright (C) 2017 Atlassian
--
local jid = require "util.jid";
local it = require "util.iterators";
local json = require "util.json";
local iterators = require "util.iterators";
local array = require"util.array";

local have_async = pcall(require, "util.async");
if not have_async then
    module:log("error", "requires a version of Prosody with util.async");
    return;
end

local async_handler_wrapper = module:require "util".async_handler_wrapper;

local tostring = tostring;
local neturl = require "net.url";
local parse = neturl.parseQuery;

local basexx = require "basexx";
-- option to enable/disable room API token verifications
local enableTokenVerification = true

local token_util = module:require "token/util".new(module);


-- no token configuration but required
if token_util == nil and enableTokenVerification then
    log("error", "no token configuration but it is required");
    return;
end

-- required parameter for custom muc component prefix,
-- defaults to "conference"
local muc_domain_prefix
    = module:get_option_string("muc_mapper_domain_prefix", "conference");

local muc_component_host = module:get_option_string("muc_component");

--- Verifies if the user id admin with the values in the token
function checkAffiliation(token)
    if token then
            -- Extract token body and decode it
            local dotFirst = token:find("%.");
            if dotFirst then
                    local dotSecond = token:sub(dotFirst + 1):find("%.");
                    if dotSecond then
                            local bodyB64 = token:sub(dotFirst + 1, dotFirst + dotSecond - 1);
                            local body = json.decode(basexx.from_url64(bodyB64));
                            -- If user is a moderator, set their affiliation to be an owner
                            if body["admin"] == true then
                                    return true
                            else
                                    return false
                            end;
                    end;
            end;
    end;
end;

--- Verifies domain name with the values in the token
-- @param token the token we received
-- @param room_address the full room address jid
-- @return true if values are ok or false otherwise
function verify_token(token)
    if not enableTokenVerification then
        return true;
    end

    -- COMMENT BELOW THREE LINES IF YOU DON'T WANT ADMIN CHECK
    if not checkAffiliation(token) then
        return false;
    end

    -- if enableTokenVerification is enabled and we do not have token
    -- stop here, cause the main virtual host can have guest access enabled
    -- (allowEmptyToken = true) and we will allow access to rooms info without
    -- a token
    if token == nil then
        log("warn", "no token provided");
        return false;
    end

    local session = {};
    session.auth_token = token;
    local verified, reason = token_util:process_and_verify_token(session);
    if not verified then
        log("warn", "not a valid token %s", tostring(reason));
        return false;
    end
    -- UNCOMMENT BELOW FOUR LINES IF YOU WANT ROOM CHECK IN TOKEN

    -- if not token_util:verify_room(session, room_address) then
    --     log("warn", "Token %s not allowed to join: %s",
    --         tostring(token), tostring(room_address));
    --     return false;
    -- end

    return true;
end

--- Handles request for retrieving the room size
-- @param event the http event, holds the request query
-- @return GET response, containing a json with participants count,
--         tha value is without counting the focus.
function handle_get_room_size(event)
    if (not event.request.url.query) then
        return { status_code = 400; };
    end

	local params = parse(event.request.url.query);
	local room_name = params["room"];
	local domain_name = params["domain"];
    local subdomain = params["subdomain"];

    local room_address
        = jid.join(room_name, muc_domain_prefix.."."..domain_name);

    if subdomain and subdomain ~= "" then
        room_address = "["..subdomain.."]"..room_address;
    end

    if not verify_token(params["token"]) then
        return { status_code = 403; };
    end

	local room = get_room_from_jid(room_address);
	local participant_count = 0;

	log("debug", "Querying room %s", tostring(room_address));

	if room then
		local occupants = room._occupants;
		if occupants then
			participant_count = iterators.count(room:each_occupant());
		end
		log("debug",
            "there are %s occupants in room", tostring(participant_count));
	else
		return { status_code = 200; body = [[{"participants":]].."0"..[[}]] };
	end

	if participant_count > 1 then
		participant_count = participant_count - 1;
	end

	return { status_code = 200; body = [[{"participants":]]..participant_count..[[}]] };
end

--- Handles request for retrieving the room participants details
-- @param event the http event, holds the request query
-- @return GET response, containing a json with participants details
function handle_get_room (event)
    if (not event.request.url.query) then
        return { status_code = 400; };
    end

	local params = parse(event.request.url.query);
	local room_name = params["room"];
	local domain_name = params["domain"];
    local subdomain = params["subdomain"];
    local room_address
        = jid.join(room_name, muc_domain_prefix.."."..domain_name);

    if subdomain and subdomain ~= "" then
        room_address = "["..subdomain.."]"..room_address;
    end

    if not verify_token(params["token"]) then
        return { status_code = 403; };
    end

	local room = get_room_from_jid(room_address);
	local participant_count = 0;
	local occupants_json = array();

	log("debug", "Querying room %s", tostring(room_address));

	if room then
		local occupants = room._occupants;
		if occupants then
			participant_count = iterators.count(room:each_occupant());
			for _, occupant in room:each_occupant() do
			    -- filter focus as we keep it as hidden participant
			    if string.sub(occupant.nick,-string.len("/focus"))~="/focus" then
				    for _, pr in occupant:each_session() do
					local nick = pr:get_child_text("nick", "http://jabber.org/protocol/nick") or "";
					local email = pr:get_child_text("email") or "";
					occupants_json:push({
					    jid = tostring(occupant.nick),
					    email = tostring(email),
					    display_name = tostring(nick)});
				    end
			    end
			end
		end
		log("debug",
            "there are %s occupants in room", tostring(participant_count));
	else
		return { status_code = 200; body = json.encode(occupants_json); };
	end

	if participant_count > 1 then
		participant_count = participant_count - 1;
	end

	return { status_code = 200; body = json.encode(occupants_json); };
end;

function handle_list_room(event)
    if (not event.request.url.query) then
        return { status_code = 400; };
    end

	local params = parse(event.request.url.query);
	local room_name = params["room"];
	local domain_name = params["domain"];
    local subdomain = params["subdomain"];

    local room_address
        = jid.join(room_name, muc_domain_prefix.."."..domain_name);

    if subdomain and subdomain ~= "" then
        room_address = "["..subdomain.."]"..room_address;
    end

    if not verify_token(params["token"]) then
        return { status_code = 403; };
    end

    local _, host = jid.split(room_address);
    local component = hosts[host];
    local room_names = array()
    if component then
        local muc = component.modules.muc
        for room in muc.all_rooms() do
            table.insert(room_names, tostring(room:get_name()))
        end 
    end
    return { status_code = 200; body = json.encode(room_names); };
end;


function get_room_from_jid(room_jid)
    local _, host = jid.split(room_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[room_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(room_jid);
        else
           
            return
        end
    end
end

function get_sessions(event)
    if (not event.request.url.query) then
        return { status_code = 400; };
    end

    local params = parse(event.request.url.query);
    
    if not verify_token(params["token"]) then
        return { status_code = 403; };
    else
        local session_count = it.count(it.keys(prosody.full_sessions)) - 2;
        if (session_count > 0) then
            return { status_code = 200; body = tostring(session_count) };
        else
            return { status_code = 200; body = tostring(0) };
        end
    end
end

function module.load()
    module:depends("http");
	module:provides("http", {
		default_path = "/";
		route = {
			["GET room-size"] = function (event) return async_handler_wrapper(event,handle_get_room_size) end;
			["GET sessions"] = function (event) return async_handler_wrapper(event,get_sessions) end;
            ["GET room"] = function (event) return async_handler_wrapper(event,handle_get_room) end;
            ["GET room-list"] = function (event) return async_handler_wrapper(event,handle_list_room) end;
		};
	});
end

Added these lines in nginx config file (/etc/nginx/sites-available/.conf}

    location = /room-size {
        proxy_pass http://localhost:5280/room-size?$args&domain=meeting.yepdesk.com;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host meeting.yepdesk.com;
        add_header Content-Type "application/json; charset=UTF-8";
        add_header 'Access-Control-Allow-Origin' '*';
    }

    location = /room-info {
        proxy_pass http://localhost:5280/room?$args&domain=meeting.yepdesk.com;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host meeting.yepdesk.com;
        add_header Content-Type "application/json; charset=UTF-8";
        add_header 'Access-Control-Allow-Origin' '*';
    }

    location = /sessions-info {
        proxy_pass http://localhost:5280/sessions?$args&domain=meeting.yepdesk.com;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host meeting.yepdesk.com;
        add_header 'Access-Control-Allow-Origin' '*';
    }

    location = /rooms {
        proxy_pass http://localhost:5280/room-list?$args&domain=meeting.yepdesk.com;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host meeting.yepdesk.com;
        add_header Content-Type "application/json; charset=UTF-8";
        add_header 'Access-Control-Allow-Origin' '*';
    }

Note: This mod_muc_size.lua file must require token with "admin": true field if you don’t want that you can uncomment those checks. Not checked docker

Thanks for all these hints - but the muc_size module does not run here, because:

Jun 30 13:10:38 conference.domain:muc_size error requires a version of Prosody with util.async

because:

if not have_async then
    module:log("error", "requires a version of Prosody with util.async");
    return;
end

async.lua is missing - its a default jitsi installations. What did I missed?

You need a newer prosody

@WebCF,

To answer your next logical question, “How do I update prosody?”

  1. echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list
  2. wget https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add -
  3. sudo apt-get update
  4. sudo apt-get install prosody
  5. sudo mv /etc/prosody/prosody.cfg.lua /etc/prosody/prosody.cfg.lua.new && sudo mv /etc/prosody/prosody.cfg.lua.dpkg-old /etc/prosody/prosody.cfg.lua
  6. service prosody restart && service jicofo restart

Also, check out this post, also by @damencho. Error while installing luajwtjitsi

This forum is full of lots of great information!

1 Like