Persistent Passwords on Self Hosted Rooms

Thanks a lot for your script! I managed to install it and it works - half-way:

  • It still asks for the operator’s password. Am I supposed to turn the restrict_create_room(?) off again?
  • It’s still possible to delete the password.

Sorry if I misunderstood any of the above instructions. I came from a “quick install” and didn’t expect to deep dive into the system just to set up a password.

(edit: found some details I have to re-read)

To prevent the password from being deleted, you can enable the mod_muc_config_restrict.lua module mentioned above.

You are asked to provide the operator’s password because you setup a secure domain - if everybody should be able to create a room try to undo the respective configuration. Note that in this case whoever joins the room first will be the room’s moderator which is likely not what you want.

Thanks for everyone that’s helped as well, and I think it is working as intended.

  • I have authentication turned on (internal)
  • When I “create” a room and set the password, that password carries over from session to session (i.e. I close out the window completely and go back in), so that is working as intended
  • However, because I have authentication on, when a room does not have a participant anymore (everyone left) and then join back in, it requires someone to authenticate first, and then the room password kicks in; is there a way to not have authentication on a room that had been created?
2 Likes

I’m stuck on the very same problem right now.
I wonder if it makes sense to remove the authentication and just use the room’s password. Using any unknown room would require a password nobody knows.
As soon as I figured out why my settings don’t apply, I’ll start tinkering with the script @plokta provided.

My concern is that I have this running on a public-facing VPS and I don’t want anyone and everyone to use up my bandwidth. With my scenario, ideally I would like to only let authenticated users create persistent rooms that require passwords.

That being said, I think @plokta solution is the best workaround. I have authentication so not everyone can just create a room, and passwords are persistent.

I have an almost working version for my needs (only pre-configured rooms with passwords - no accounts):

I’m not using any secure domain.

/etc/prosody/conf.d/domain.tld.cfg.lua

Component "conference.domain.tld" "muc"
    modules_enabled = {
        "muc_meeting_id";
        "muc_domain_mapper";
	"muc_config_restrict";
	"persist_muc_passwords";
    }
    admins = { "focus@auth.domain.tld" }
    default_storage = "memory";
    storage = {
	persistent_muc_passwds = "internal";
    }
    muc_config_restricted = {
	"muc#roomconfig_roomsecret";
    }

/usr/lib/prosody/modules/mod_persist_muc_passwords.lua (modified script of @plokta )

local store = module:open_store("persistent_muc_passwds", "map");
if not store then
    module:log("error","Failed to open storage.");
    return nil;
end

module:hook("muc-room-created", function (event)    
    local room = event.room;
    module:log("debug","hooked room create for %s", room);

    local old_pass = store:get(room.jid, "password");
    if not old_pass then
        -- default password for unknown rooms; not to be shared with anyone
	old_pass = "some-admin-password" -- should be moved into some config file
        module:log("debug", "No password to restore for room %s", room);
    end

    module:log("debug", "Loaded old password '%s' for room %s", old_pass, room);

    -- restore old pass for the mucroom
    local success = room:set_password(old_pass);
    if not success then 
        module:log("warn", "Failed to set old password %s for restored room %s.", old_pass, room);
    end
    
    module:log("debug", "Set password '%s' for restored room %s.", old_pass, room);
    return nil;
end, 0);

For each room: /var/lib/prosody/conference%2edomain%2etld/persistent_muc_passwds/name_of_the_room%40conference%2edomain%2etld.dat

return {
	["password"] = "shared room password";
};

Current issues:

  • It’s still possible to delete the password when entering the room. But that has only temporary effect. @plokta any idea why my configuration of mod_muc_config_restrict doesn’t work? Is muc#roomconfig_roomsecret available on secured domains only?
4 Likes

My setup is somewhat different but I can confirm that mod_muc_config_restrict also works without secured domain: The Remove Password button is visible but an error message pops up when the button is clicked.

Did you check the prosody logs to see whether the module was loaded successfully? Also, in my config the focus user is only set as admin in the global section and not in the muc component. And I don’t have the modules muc_meeting_id and muc_domain_mapper enabled but to be honest, I don’t know if this could affect the muc_config_restrict module.

1 Like

@plokta Couldn’t you remove the Remove Password button from the react template?

Thanks for the thread, this has been a super helpful discussion.

To remove the password button or to change some other css, i use this trick:

In the start of file config.js some lines can be added;

</script>
<style type="text/css">
.remove-password {
        display: none;
}
</style>
<script>

Joachim

3 Likes

Hello,

I have followed the working version of @fyl2xp1 but with the secure domain enabled.

  • modify: /etc/prosody/conf.d/domain.tld.cfg.lua
  • create: /usr/lib/prosody/modules/mod_persist_muc_passwords.lua

I have an error that @fyl2xp1 already solved, maybe I’ve missing something, when I try to open/create a conference, Jitsi asks the login/password for the host, but after the credentials validation I have the following error:
Oops, Something went wrong and we couldn’t connect to the conference: connection.GET_SESSION_ID_ERROR.

Maybe I have miss to configure something ?

1 Like

I have the same problem.

After allowing access to microphone and camera, the “Something went wrong” error appears.
Very rarely I am asked for the password first, but then the same error pops up.

It happens only if I call event.room:set_password(…).

I’m running Prosody 0.10.0 on Ubuntu 18.04.4 LTS.

I only added this simple module:

module:hook("muc-room-created", function (event)
    local room = event.room;

    local pass = "test-pass";
    room:set_password(pass);
end);

and enabled it like this:

Component "conference.domain…" "muc"
    storage = "none";
    modules_enabled = {
        "muc_meeting_id";
        "muc_domain_mapper";
        "muc_max_occupants";
        "my_muc_passwords"; -- ←
    }
    admins = { "focus@auth.domain…" }
    muc_room_locking = false
    muc_room_default_public_jids = true

Here are the JavaScript console errors:

2020-04-09T15:51:32.339Z [JitsiMeetJS.js] <getGlobalOnErrorHandler>:  UnhandledError: null Script: null Line: null Column: null StackTrace:  Error: "Focus error, retry after 1000"
    _allocateConferenceFocusError moderator.js:446
    allocateConferenceFocus moderator.js:373
    s strophe.umd.js:2716
    run strophe.umd.js:1875
    _dataRecv strophe.umd.js:3157
    forEachChild strophe.umd.js:830
    _dataRecv strophe.umd.js:3146
    _onRequestStateChange strophe.umd.js:5012
Logger.js:154:22
    o Logger.js:154
    getGlobalOnErrorHandler JitsiMeetJS.js:612
    onerror middleware.js:100
    callErrorHandler GlobalOnErrorHandler.js:61
    _allocateConferenceFocusError moderator.js:446
    allocateConferenceFocus moderator.js:373
    s strophe.umd.js:2716
    run strophe.umd.js:1875
    _dataRecv strophe.umd.js:3157
    forEachChild strophe.umd.js:830
    _dataRecv strophe.umd.js:3146
    _onRequestStateChange strophe.umd.js:5012
2020-04-09T15:51:32.341Z [modules/xmpp/moderator.js] <l.prototype._allocateConferenceFocusError>:  Focus error, retry after 1000 
<iq id="09f539c6-43b7-4b5a-b9bf-b48aaa7bd48f:sendIQ" type="error" to="78aed5e5-92d8-4844-b698-…-455f-a0fd-859b404d375a" from="focus.domain…" xmlns="jabber:client">
Logger.js:154:22
    o Logger.js:154
    _allocateConferenceFocusError moderator.js:447
    allocateConferenceFocus moderator.js:373
    s strophe.umd.js:2716
    run strophe.umd.js:1875
    _dataRecv strophe.umd.js:3157
    forEachChild strophe.umd.js:830
    _dataRecv strophe.umd.js:3146
    _onRequestStateChange strophe.umd.js:5012
2020-04-09T15:51:32.359Z [features/overlay] <componentDidMount>:  The conference will be reloaded after 26 seconds. Logger.js:154:22
2020-04-09T15:51:32.373Z [conference.js] <_onConferenceFailed>:  CONFERENCE FAILED: conference.focusDisconnected focus.domain… 1

Looks like there is still a problem with jicofo to my untrained eye, even though I use the muc-room-created hook instead of muc-room-pre-create.

I would be very grateful for any hints.

IIRC, this approach has only been verified to work with Prosody >= 0.11 so if you use Prosody 0.10 you may need to check the respective Prosody API and adjust the module accordingly, or upgrade your Prosody to version 0.11 (not sure how complicated an upgrade would be).

1 Like

Due to a storage crash I had to start over with jitsi yesterday, so I pulled the latest docker for jitsi. I re-followed the steps I took in my first install - mostly slight changes to the module you proposed. But somehow I now get:

prosody_1   | modulemanager       error Unable to load module 'muc_config_restrict': /usr/lib/prosody/modules/mod_muc_config_restrict.lua: No such file or directory

When I check the prosody container it is missing. I am not even sure if that file was present in my last jitsi. Am I misunderstanding something?

edit:
never mind, i obviously just had to pull muc_config_restrict from prosody. Must have done that late night last time.

This is very good.

It would be preferable, although we cant complain too much, if we could have administrative users create rooms within jitsi itself. But we can manage this easily enough (larger organizations will find this not scaling very well)

For other peoples sake Ill put clear notes on the mod_muc_config_restrict/mod_muc_config_restrict.lua module:

You can find the most recent version here. Put that script under /usr/lib/prosody/modules/mod_muc_config_restrict.lua

Hallo,

I tried a similar configuration with:

module:hook("muc-room-created", function(event)
            local pass = http.query.for.password for this event.room;
            event.room:set_password(pass);
end);

and the module in the conference.exmaple.com . My prosody version is 0.11.2-1.

It just doesn’t do anything when I create the room. Why?

Mebus

Would be nice if people could use pastebins, so we don’t have to spin the mouse wheel so often :joy:

Mebus

I’m wondering if this is possible while using jwt tokens? I am using the prosody 747 trunk they say you must use for it to work. It would be nice to just pass the password in via the token, but that doesn’t seem possible.

I’m trying to use this module on an out-of-the-box jitsi install, on Ubuntu 19.10 (jitsi 2.10.5550-1, prosody 0.11.5), but I’m stuck in the ‘something has gone wrong’ loop, and seeing errors in the jicofo.log:

Jicofo 2020-04-20 08:54:50.085 SEVERE: [111] org.jivesoftware.smack.parsing.ExceptionLoggingCallback.handleUnparsableStanza() Smack message parsing exception. Content: '</field><field type='fixed'><value>Other options</value></field><field label='Maximum number of history messages returned by room' var='muc#roomconfig_historylength' type='text-single'><desc>Specify the maximum number of previous messages that should be sent to users when they join the room</desc><value>20</value></field><field label='Default number of history messages returned by room' var='muc#roomconfig_defaulthistorymessages' type='text-single'><desc>Specify the number of previous messages sent to new users when they join the room</desc><value>20</value></field></x></query></iq>'
java.lang.IllegalArgumentException: This data form already contains a form field with the variable name 'muc#roomconfig_whois'
at org.jivesoftware.smackx.xdata.packet.DataForm.addField(DataForm.java:229)
at org.jivesoftware.smackx.xdata.provider.DataFormProvider.parse(DataFormProvider.java:66)
at org.jivesoftware.smackx.xdata.provider.DataFormProvider.parse(DataFormProvider.java:43)
at org.jivesoftware.smack.provider.Provider.parse(Provider.java:43)
at org.jivesoftware.smack.util.PacketParserUtils.parseExtensionElement(PacketParserUtils.java:935)
at org.jivesoftware.smack.util.PacketParserUtils.addExtensionElement(PacketParserUtils.java:1045)
at org.jivesoftware.smack.util.PacketParserUtils.addExtensionElement(PacketParserUtils.java:1040)
at org.jivesoftware.smackx.muc.provider.MUCOwnerProvider.parse(MUCOwnerProvider.java:50)
at org.jivesoftware.smackx.muc.provider.MUCOwnerProvider.parse(MUCOwnerProvider.java:32)
at org.jivesoftware.smack.provider.Provider.parse(Provider.java:43)
at org.jivesoftware.smack.util.PacketParserUtils.parseIQ(PacketParserUtils.java:633)
at org.jivesoftware.smack.util.PacketParserUtils.parseStanza(PacketParserUtils.java:153)
at org.jivesoftware.smack.AbstractXMPPConnection.parseAndProcessStanza(AbstractXMPPConnection.java:1083)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$500(XMPPTCPConnection.java:151)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1044)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:1000)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1016)
at java.base/java.lang.Thread.run(Thread.java:834)

Has anybody experienced/overcome this?
I’ve not added any form of authentication, if that helps?

There are other threads about Prosody 0.11 upgrades not working, refer to those and get involved there.

So this setup doesnt seem to conceal the password as it is typed in.

This is a particular issue for my setup since it is often used during livestreams where users risk exposing the password to the stream audience.

Is there any modification that can be made to fix this?