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

1 Like

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?”

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

This forum is full of lots of great information!

1 Like

Hi Hkhait ,
I am trying the same one but I am getting this error log in prosody container. Can anyone please help me in resolving this issue. And Get Room info other details like Room history

Jul 30 08:14:46 server_epoll debug New connection FD 18 (172.19.0.3, 34820, 172.19.0.2, 5280)
Jul 30 08:14:46 server_epoll debug Watching FD 18 (172.19.0.3, 34820, 172.19.0.2, 5280)
Jul 30 08:14:46 http.server debug Firing event: GET /nbConfPart
Jul 30 08:14:46 http.server debug Firing event: GET example.com/nbConfPart
Jul 30 08:14:46 runneriRyyawJL debug creating new coroutine
Jul 30 08:14:46 runneriRyyawJL debug changed state from ready to error (ready)
Jul 30 08:14:46 runneriRyyawJL error Encountered error: /prosody-plugins/mod_muc_size.lua:209: attempt to index field ‘jitsi_meet_room’ (a nil value)
stack traceback:
/prosody-plugins/mod_muc_size.lua:209: in function ‘handler’
/prosody-plugins/util.lib.lua:75: in function ‘func’
/usr/lib/prosody/util/async.lua:127: in function </usr/lib/prosody/util/async.lua:125>
Jul 30 08:14:46 http.server error Traceback[httpserver]: /usr/lib/prosody/util/async.lua:137: /prosody-plugins/mod_muc_size.lua:209: attempt to index field ‘jitsi_meet_room’ (a nil value)
stack traceback:
/prosody-plugins/mod_muc_size.lua:209: in function ‘handler’
/prosody-plugins/util.lib.lua:75: in function ‘func’
/usr/lib/prosody/util/async.lua:127: in function </usr/lib/prosody/util/async.lua:125>
stack traceback:
[C]: in function ‘error’
/usr/lib/prosody/util/async.lua:137: in function ‘handler’
/usr/lib/prosody/util/async.lua:211: in function ‘run’
/prosody-plugins/util.lib.lua:98: in function </prosody-plugins/util.lib.lua:62>
(…tail calls…)
/usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
(…tail calls…)
/usr/lib/prosody/net/http/server.lua:248: in function </usr/lib/prosody/net/http/server.lua:176>
[C]: in function ‘xpcall’
/usr/lib/prosody/net/http/server.lua:108: in function ‘process_next’
/usr/lib/prosody/net/http/server.lua:124: in function ‘success_cb’
/usr/lib/prosody/net/http/parser.lua:177: in function ‘feed’
/usr/lib/prosody/net/http/server.lua:155: in function </usr/lib/prosody/net/http/server.lua:154>
[C]: in function ‘pcall’
/usr/lib/prosody/net/server_epoll.lua:159: in function ‘on’
/usr/lib/prosody/net/server_epoll.lua:348: in function ‘onreadable’
/usr/lib/prosody/net/server_epoll.lua:734: in function </usr/lib/prosody/net/server_epoll.lua:726>
[C]: in function ‘xpcall’
/usr/bin/prosody:76: in function ‘loop’
/usr/bin/prosody:86: in main chunk
[C]: in ?
Jul 30 08:14:46 server_epoll debug Close FD 18 (172.19.0.3, 34820, 172.19.0.2, 5280) after writing
Jul 30 08:14:46 server_epoll debug Close FD 18 (172.19.0.3, 34820, 172.19.0.2, 5280) now
Jul 30 08:14:46 server_epoll debug Unwatched FD 18 (172.19.0.3, 34820, 172.19.0.2, 5280)

How you have resolved this issue? I am stuck in the same situation

Unfortunately I cant get this to work :frowning:

im really sorry for the partly bad formating but the editor wont recognize the 4 spaces as code :confused:

What have I done:

  1. Copied following lines into “mod_muc_size” ref: Get the list of rooms :

    function tablelength(T)
    local hash = {}
    local res = {}

     for _,v in ipairs(T) do
     if (not hash[v]) then
         res[#res+1] = v
         hash[v] = true
     end
     end
    
     local count = 0
     for _ in pairs(res) do count = count + 1 end
     return count
    

    end

    function getNbConfPart()
    local tab={};

     --conferences count (without eliminating duplicates )
     for key, value in pairs(prosody.full_sessions) do
         if tostring(value["username"]:lower()) ~= "focus" then
                 table.insert(tab,tostring(value["jitsi_meet_room"]:lower()));
         end
     end
    
     local nbPart = 0
         if it.count(it.keys(prosody.full_sessions))-1 >= 0 --participants count
             then nbPart= it.count(it.keys(prosody.full_sessions))-1
     end
    
     local nbConf = tablelength(tab) --conferences count
     if nbPart == 0
             then nbConf=0
     end
    

    –create result as json
    local result_json=array();
    result_json:push({
    part= nbPart,
    conf=tablelength(tab) – eliminates count number of rooms
    });

     -- create json response 
     return json.encode(result_json);
    

    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 () return tostring(it.count(it.keys(prosody.full_sessions))); end;
    [“GET room”] = function (event) return async_handler_wrapper(event,handle_get_room) end;
    [“GET nbConfPart”] = function (event) return wrap_async_run(event,getNbConfPart) end;
    };
    });
    end

  2. Edited “/etc/prosody/conf.avail/localhost.cfg.lua” to ref: Get the list of rooms :

    – Section for localhost

    – This allows clients to connect to localhost. No harm in it.
    VirtualHost “localhost”
    app_id=""
    app_secret=""
    authentication = “anonymous”
    modules_enabled = {
    “muc_size”;
    }

  3. Edited “/etc/prosody/conf.avail/meeting.mydisplayer.stream.cfg.lua” to:

    modules_enabled = {
    “bosh”;
    “pubsub”;
    “ping”; – Enable mod_ping
    “speakerstats”;
    “turncredentials”;
    “conference_duration”;
    “muc_lobby_rooms”;
    “muc_size”; <- added this line
    }

  4. I added the following lines to my nginx config:

    location = /room {
    add_header Access-Control-Allow-Origin *;
    proxy_pass http://localhost:5280/room;
    proxy_set_header Host meeting.mydisplayer.stream;
    proxy_set_header X-Forwarded-For $remote_addr;
    }

    location = /room-size {
    add_header Access-Control-Allow-Origin *;
    proxy_pass http://localhost:5280/room-size;
    proxy_set_header Host meeting.mydisplayer.stream;
    proxy_set_header X-Forwarded-For $remote_addr;
    }

    location = /sessions {
    add_header Access-Control-Allow-Origin *;
    proxy_pass http://localhost:5280/sessions;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host meeting.mydisplayer.stream;
    }

    location = /nbConfPart {
    add_header Access-Control-Allow-Origin *;
    proxy_pass http://localhost:5280/nbConfPart;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host meeting.mydisplayer.stream;
    }

i tried replacing “localhost” with “127.0.0.1”, nothing changed

None of these routes above return something.
i always get an "404: unknown host "

I suspect it might be an issue with my nginx conf, because its always the same error, i just cant figure out whats wrong.

I tried the steps mentioned by @hasgardee aswell, but it didnt change

Any help or advice would be appreciated.

EDIT:
Jitsi versions ref: How to display Jitsi version?

ii jitsi-meet 2.0.4857-1 all WebRTC JavaScript video conferences
ii jitsi-meet-prosody 1.0.4289-1 all Prosody configuration for Jitsi Meet
ii jitsi-meet-web 1.0.4289-1 all WebRTC JavaScript video conferences
ii jitsi-meet-web-config 1.0.4289-1 all Configuration for web serving of Jitsi Meet
ii jitsi-videobridge2 2.1-273-g072dd44b-1 all WebRTC compatible Selective Forwarding Unit (SFU)

@simonf To debug, I would take Nginx out of the equation.

From the command line on the server try to access 5280 directly, for example:

Run: curl http://localhost:5280/room or curl http://meeting.mydisplayer.stream:5280/room and see what comes back. (Make sure you have a meeting actually active, otherwise the response may be blank)

Also when you restart Prosody, are there any success or error messages about loading mod_mux_size?

Hey corby!

Thanks for your response unfortunately im always getting the same error message.

Meanwhile i managed to destroy my jitsi installation and started again from scratch.

There were several errors that occured, after i enabled “muc_size” in my jitsi config for [domin].cfg.lua. I enabled the default module that is shipped with the jitsi installation without any changes made.

The prosody logs showed that there were missing packages.

What worked:

  • luarocks install net-url
  • luarocks install basexx

What didnt work:
-luajwtjitsi can not be installed because,

  • cjson is not compatible with lua5.2, but i found a fork that sems to work: lua-cjson 2.1.0-1
  • luacrypto cant be installed with lua5.2, i cloned this repo:
    “git clone https://github.com/evanlabs/luacrypto.git”, edited the “dist.cmake” file and replaced
    “find_package(Lua51 REQUIRED)” with “find_package(Lua REQUIRED)”. Now i could build the package. After building the crypto file, it was in the wrong directory and i copied in to the directory
    for luarocks.

Then i had no errors in the prosody logs, besides “portmanager error Error binding encrypted port for https: No certificate present in SSL/TLS configuration for https port 5281”, what can be ignored.
ref: https://github.com/jitsi/jitsi-meet/issues/6473

I thought everything is good and added the folowing to my nginx conf:

location = /room {
    add_header Access-Control-Allow-Origin *;
    proxy_pass  http://localhost:5280/room;
    proxy_set_header Host beta.meeting.mydisplayer.stream;
    proxy_set_header X-Forwarded-For $remote_addr;
}

location = /room-size {
    add_header Access-Control-Allow-Origin *;
    proxy_pass  http://localhost:5280/room-size;
    proxy_set_header Host beta.meeting.mydisplayer.stream;
    proxy_set_header X-Forwarded-For $remote_addr;
}

location = /sessions {
    add_header Access-Control-Allow-Origin *;
    proxy_pass http://localhost:5280/sessions;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host beta.meeting.mydisplayer.stream;
}

Now i tried the url [domain]/sessions or [domain]:5280/sessions and i get the error that i had before.

This is the error message:

Im kind of frustrated, cuz it seems like im the only one that is not able to make this work.
My OS is Ubuntu 20.04 “Focal Fossa”. The normal jitsi installation worked flawlessly and i was able to join and create meetings.

But the “muc_size” module shipped with the installation is a pain in the… :confused:

Besides that im impressed with the software and the amount of configuration switches available and the project overall is really really great.

Greetings Simon

EDIT:
The domain i currently working with is “beta.meeting.mydisplayer.stream”

curl http://localhost:5280/room <- connection refused
curl https://beta.meeting.mydisplayer.stream:5280/room <- connenction refused aswell

What is the result of netstat -anlp | grep 5280