Lobby room

Hello everyone,
i want to enable lobby feature with some jwt updating
lobby it will be disable when there is a moderator present in the room
and it will be enable if there is no moderator ,
that is work fine ,
but when moderator for some reason send user to lobby it will be re test the first conditions and the user will be join again

this is a part of my code

  host_module:hook('muc-occupant-pre-join', function (event)
    local room = event.room;
    local invitee = event.stanza.attr.from;
    local invitee_bare_jid = jid_bare(invitee);

    local _, invitee_domain = jid_split(invitee);

    local occupant_auth_token = event.origin.auth_token;
    if occupant_auth_token == nil then return end

    local data, err = jwt.decode(occupant_auth_token);
    local affiliation = room:get_affiliation(invitee);
    module:log("info","event.occupant.role it is : %s ",event.occupant.role);
    if data.moderator then
          if not affiliation or affiliation == 0 then
            event.occupant.role = 'participant';
            room:set_affiliation(true, invitee_bare_jid, 'member');
      if not data.autoLobby and is_owner_present(event) then
        module:log("info","participant affiliation it is : %s ",affiliation);
          if not affiliation or affiliation == 0 then
            event.occupant.role = 'participant';
            room:set_affiliation(true, invitee_bare_jid, 'member');

thanks in advance, @damencho @Freddie if you can help me with this issue please

i am using docker with this

@saghul @emrah any body can help me with this please

I didn’t understand your use case. If you have already enable the token authentication, why do you need the lobby?

Did you check lobby autostart and token lobby bypass modules?

thanks for your reply @emrah
we add autoLobby to jwt
if autoLobby false and there is no moderator in the main room
the participant will waiting moderator admit
and we create new modules to kick participant again to lobby by moderator

tunction kick_back_to_lobby(event)
  local origin, stanza = event.origin, event.stanza;

  local node, to_domain = jid_split(stanza.attr.to);
  if to_domain ~= main_muc_component_config then return end

  local room = main_muc_service.get_room_from_jid(jid_bare(node .. '@' .. main_muc_component_config));
  if not room then return end

  local kickee_jid = stanza[1].attr.participant;
  if not kickee_jid then return end

  local kicker_affiliation = room.get_affiliation(room, origin.full_jid)
  if kicker_affiliation ~= 'owner' then
    origin.send(st.stanza('kick_back_to_lobby_error'):tag('reason'):text('Access denied'))

  local kickee_affiliation = room.get_affiliation(room, kickee_jid)
  if kickee_affiliation ~= 'member' then
    origin.send(st.stanza('kick_back_to_lobby_error'):tag('reason'):text('You cannot kick this participant'))

  module:log('debug', 'Kick %s to lobby', kickee_jid);

  local kick_message = st.message({
    type = 'groupchat',
    from = stanza.attr.to,
    to = kickee_jid
    :tag('kick-back-to-lobby', { xmlns='jabber:message:kick_back_to_lobby' })

  room:set_affiliation(true, kickee_jid, 'outcast');


then the participant will re test the first post and rejoin without moderator admit
we need to ignore this conditions when the participant will be kicked

If I understand correctly, you’re saying that when the occupants are kicked they automatically rejoin and the end up bypassing the lobby? Does it behave as expected (user stops in lobby) if after kick they rejoin using same token?

If both above are correct, then my guess (because I don’t really know) is the user may be rejoining using same occupant state and you may need to restore the states properly on kick. To be specific:

when you initially route users around the lobby you set occupant role and affiliation:

But when you kicked you only updated the affiliation:

Perhaps you need to reset event.occupant.role too? :man_shrugging:

If I understand correctly, you’re saying that when the occupants are kicked they automatically rejoin and the end up bypassing the lobby? Does it behave as expected (user stops in lobby) if after kick they rejoin using same token?
that is correct but
it is does not work
role will be nil again :
participant affiliation it is :
event.occupant.role it is :

Not really sure what you expect to happen. If moderator kicks someone, moderator will be in a room so lobby is disable, no?

I’m not sure how you’d expect to get a different behaviour from what is coded unless you somehow blacklist a kicked user and consider that blacklist when deciding if lobby should be bypassed not.

yes, that is true lobby will be disable ,
but we need this just when the participant join to it ,not when the moderator sent him to lobby

It might help if you talk about the use case rather than how you are trying to solve it.

Then in your logic for deciding whether lobby should be used or not, you need to account for users that have been kicked. Right now you’re only looking at moderator presence and autoLobby value in token.

Sounds like the implementation is doing the right thing, but your implementation does not match your requirement.

Ditto what @emrah said :slight_smile:

We have an option with the token to activate the lobby room
If its value is true, we need to activate it for anyone who tries to enter and does not have moderator permissions
If the value is false:
We need to activate the lobby room until there is a moderator in the room… then any new entry will be available without waiting for the moderator’s approval
…to here everything is working properly…
But when the moderator wants to send a someone to the lobby room for some reason, he will test these conditions and therefore does not need to be approved to enter as is the case for new users… We need to distinguish between the new person who wants to enter and the person who was fired by the administrator…

I think so too :joy: but I don’t know where to start
I only dealt with prosody lua modules :neutral_face:

Sounds like you need additional states to track kicked users then. Otherwise I don’t see a way for your logic to differentiate between a user joining for the first time and rejoining after being kicked.

Off the top of my head, here’s how I might approach it. (there may be other/better ways to do it).

  1. Enable lobby automatically for all rooms, and leave it enabled
  2. Make sure you have a unique uuid embedded in JWT
  3. On user join, bypass lobby if and only if:
    • user is a moderator
    • OR user has some flag that allows it to bypass lobby
    • OR (moderator already in room AND user uuid not in room blacklist)
  4. When you kick a user, add their UUID to room blacklist
  5. When moderator admits a user, remove his UUID from room blacklist if it exists.

i will try it and tell you what happen
thanks a lot :smiling_face:

can we use localStorage for this ?

No. LocalStorage is on client side. Prosody has no access to it, and is user modifiable so not idea for control data like that.

You’ll probably want to store it on the room object in lua.

I didn’t know how to do this if you can help me please when you have time :disappointed_relieved: :pray: :pray:

I’m sorry, but I do not currently have the bandwidth to write and test custom functionality like this.

But if you mean just help with how to store data on the room object, your code already has access to the room object :

so you might be able to to store your blacklist under something like room._data.kickedusers. When checking for values, make sure to handle case where that is unitialised. And when adding jids to the array, make sure to initialise to an empty array if uninitialised.