call_end

    • chevron_right

      ProcessOne: ejabberd 25.03

      news.movim.eu / PlanetJabber • 28 March • 21 minutes

    ejabberd 25.03

    Release Highlights:

    If you are upgrading from a previous version, please check the changes in SQL schemas ; but there aren&apost changes in the configuration, API commands or hooks.

    Other contents:

    Below is a detailed breakdown of the improvements and enhancements:

    Matrix Gateway with Room Support

    ejabberd can bridge communications to Matrix servers since version 24.02 thanks to mod_matrix_gw , but until now only one-to-one conversations were supported.

    Starting with ejabberd 25.03, now you can receive invitations to Matrix rooms and join public Matrix rooms by yourself. The Matrix bridge will be seen a multi-user chat service, as default matrix.yourdomain.net .

    For example, once you have enabled the Matrix bridge, if you wish to join the room #ejabberd-matrix-bridge:matrix.org , you can use XMPP MUC protocol to enter the XMPP room: #ejabberd-matrix-bridge%matrix.org@matrix.yourdomain.net

    Caveats for this release:

    1. Older room protocol version are not supported yet for this release. We only support room protocol version 9, 10 and 11 for now but are planning to add support for older rooms.
    2. One to one conversation will need to be restarted empty after server restart as the persistence is not yet implemented.
    3. matrix room members are those who kind of subscribed to the room, not necessarily online, and mod_matrix_gw sends a presence for each of them, it depends on whether the xmpp client can handle thousands of muc members.

    Note that matrix.org server has also declared an XMPP service in its DNS entries. To communicate with the real Matrix server, you need to block it and add this rule in your firewall on your ejabberd instance:

    iptables -A OUTPUT -d lethe.matrix.org -j REJECT
    

    As a reminder, as encrypted payloads are different in Matrix and XMPP, Matrix payload cannot be end-to-end encrypted. In the future, it could be possible to join Matrix encrypted room, with the decryption happening on the server in the bridge, but it will not be end-to-end encrypted anymore. It would just be a convenience for those trusting their XMPP server. Please, let us know if this is an option you would like to see in the future.

    Support Multiple Simultaneous Password Types

    Faithful to our commitment to help gradually ramp up messaging security, we added the ability to store passwords in multiple formats per account. This feature should help with migration to newer, more secure authentication methods. Using the option auth_stored_password_types , you can specify in what formats the password will be stored in the database. And the stored passwords will be updated each time user changes the password or when the user&aposs client provides the password in a new format using SASL Upgrade Tasks XEP specification.

    This option takes a list of values, currently recognized ones are plain , scram_sha1 , scram_sha256 , scram_sha512 . When this options is set, it overrides old options that allowed to specify password storage - auth_scream_hash and auth_password_format .

    Update SQL Schema

    This release requires SQL database schema update to allow storage of multiple passwords per user. This task can be performed automatically by ejabberd, if your config has enabled update_sql_schema toplevel option.

    If you prefer to perform the SQL schema update manually yourself, check the corresponding instructions, depending if your config has enabled new_sql_schema :

    • MySQL default schema:
    ALTER TABLE users ADD COLUMN type smallint NOT NULL DEFAULT 0;
    ALTER TABLE users ALTER COLUMN type DROP DEFAULT;
    ALTER TABLE users DROP PRIMARY KEY, ADD PRIMARY KEY (username(191), type);
    
    • MySQL new schema:
    ALTER TABLE users ADD COLUMN type smallint NOT NULL DEFAULT 0;
    ALTER TABLE users ALTER COLUMN type DROP DEFAULT;
    ALTER TABLE users DROP PRIMARY KEY, ADD PRIMARY KEY (server_host(191), username(191), type);
    
    • PostgreSQL default schema:
    ALTER TABLE users ADD COLUMN "type" smallint NOT NULL DEFAULT 0;
    ALTER TABLE users ALTER COLUMN type DROP DEFAULT;
    ALTER TABLE users DROP CONSTRAINT users_pkey, ADD PRIMARY KEY (username, type);
    
    • PostgreSQL new schema:
    ALTER TABLE users ADD COLUMN "type" smallint NOT NULL DEFAULT 0;
    ALTER TABLE users ALTER COLUMN type DROP DEFAULT;
    ALTER TABLE users DROP CONSTRAINT users_pkey, ADD PRIMARY KEY (server_host, username, type);
    
    • SQLite default schema:
    ALTER TABLE users ADD COLUMN type smallint NOT NULL DEFAULT 0;
    CREATE TABLE new_users (
        username text NOT NULL,
        type smallint NOT NULL,
        password text NOT NULL,
        serverkey text NOT NULL DEFAULT &apos&apos,
        salt text NOT NULL DEFAULT &apos&apos,
        iterationcount integer NOT NULL DEFAULT 0,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (username, type)
    );
    INSERT INTO new_users SELECT * FROM users;
    DROP TABLE users;
    ALTER TABLE new_users RENAME TO users;
    
    • SQLite new schema:
    ALTER TABLE users ADD COLUMN type smallint NOT NULL DEFAULT 0;
    CREATE TABLE new_users (
        username text NOT NULL,
        server_host text NOT NULL,
        type smallint NOT NULL,
        password text NOT NULL,
        serverkey text NOT NULL DEFAULT &apos&apos,
        salt text NOT NULL DEFAULT &apos&apos,
        iterationcount integer NOT NULL DEFAULT 0,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (server_host, username, type)
    );
    INSERT INTO new_users SELECT * FROM users;
    DROP TABLE users;
    ALTER TABLE new_users RENAME TO users;
    

    New mod_adhoc_api module

    You may remember this paragraph from the ejabberd 24.06 release notes :

    ejabberd already has around 200 commands to perform many administrative tasks, both to get information about the server and its status, and also to perform operations with side-effects. Those commands have its input and output parameters clearly described, and also documented.

    Almost a year ago, ejabberd WebAdmin got support to execute all those 200 API commands ... and now your XMPP client can execute them too!

    The new mod_adhoc_api ejabberd module allows to execute all the ejabberd API commands using a XMPP client that supports XEP-0050 Ad-Hoc Commands and XEP-0030 Service Discovery .

    Simply add this module to modules , setup api_permissions to grant some account permission to execute some command, or tags of commands, or all commands. Reload the ejabberd configuration and login with your client to that account.

    Example configuration:

    acl:
      admin:
        user: jan@localhost
    
    api_permissions:
      "adhoc commands":
        from: mod_adhoc_api
        who: admin
        what:
          - "[tag:roster]"
          - "[tag:session]"
          - stats
          - status
    
    modules:
      mod_adhoc_api:
        default_version: 2
    

    Now you can execute the same commands in the command line, using ReST, in the WebAdmin, and in your XMPP client!

    This feature has been tested with Gajim, Psi, Psi+ and Tkabber. Conversejs allows to list and execute the commands, but doesn&apost show the result to the user.

    Macros and Keyword improvements

    Some options in ejabberd supported the possibility to use hard-coded keywords. For example, many modules like mod_vcard could used HOST in their hosts option. Other example is the captcha_cmd toplevel option: it could use VERSION and SEMVER keywords. All this was implemented for each individual option.

    Now those keywords are predefined and can be used by any option, and this is implemented in ejabberd core, no need to implement the keyword substitution in each option. The predefined keywords are: HOST , HOME , VERSION and SEMVER .

    For example, this configuration is now possible without requiring any specific implementation in the option source code:

    ext_api_url: "http://example.org/@VERSION@/api"
    

    Additionally, now you can define your own keywords, similarly to how macros are defined:

    define_keyword:
      SCRIPT: "captcha.sh"
    
    captcha_cmd: "tools/@SCRIPT@"
    

    And finally, now macros can be used inside string options, similarly to how keywords can be used:

    define_macro:
      SCRIPT: "captcha.sh"
    
    captcha_cmd: "tools/@SCRIPT@"
    

    In summary, now macros and keywords can be defined and used very similarly, so you may be wondering what are their differences. That is explained in detail in the new section Macros and Keywords :

    • Macros are implemented by the yconf library: macros cannot be defined inside host_config .

    • Keywords are implemented by ejabberd itself: keywords can be defined inside host_config but only for usage in module options. And cannot be used in those toplevel options: hosts , loglevel , version .

    ejabberdctl: New option CTL_OVER_HTTP

    The ejabberdctl script is useful not only to start and stop ejabberd, it can also execute the ~200 ejabberd API commands inside the running ejabberd node. For this, the script starts another erlang virtual machine and connects it to the already existing one that is running ejabberd.

    This connection method is acceptable for performing a few administrative tasks (reload configuration, register an account, etc). However, ejabberdctl is noticeably slow for performing multiple calls, for example to register 1000 accounts. In that case, it is preferable to use other API frontend like mod_http_api or ejabberd_xmlrpc.

    And now ejabberdctl can do exactly this! ejabberdctl can be configured to use an HTTP connection to execute the command, which is way faster than starting an erlang node, around 20 times faster.

    To enable this feature, first configure in ejabberd.yml :

    listen:
      -
        port: "unix:sockets/ctl_over_http.sock"
        module: ejabberd_http
        unix_socket:
          mode: &apos0600&apos
        request_handlers:
          /ctl: ejabberd_ctl
    

    Then enable the CTL_OVER_HTTP option in ejabberdctl.cfg :

    CTL_OVER_HTTP=sockets/ctl_over_http.sock
    

    Let&aposs register 100 accounts using the standard method and later using CTL_OVER_HTTP:

    $ time for (( i=100 ; i ; i=i-1 )) ; do ejabberdctl register user-standard-$i localhost pass; done
    ...
    real    0m43,929s
    user    0m41,878s
    sys     0m10,558s
    
    $ time for (( i=100 ; i  ; i=i-1 )) ; do CTL_OVER_HTTP=sockets/ctl_over_http.sock ejabberdctl register user-http-$i localhost pass; done
    ...
    real    0m2,144s
    user    0m1,377s
    sys     0m0,566s
    

    This feature is enabled by default in the ejabberd container image.

    mod_configure: New option access

    mod_configure always had support to configure what accounts can access its features: using the configure access rule . The name of that access rule was hard-coded. Now, thanks to the new access option, that can be configured.

    Container images: Reduce friction, use macros, WebAdmin port

    Several improvements are added in the ejabberd and ecs container images to allow easier migration from one to the other. This also allows to use the same documentation file for both container images, as now there are very few usability differences between both images. Also, a new comparison table in that documentation describes all the differences between both images. The improvements are:

    • Adds support for paths from ecs into ejabberd container image, and viceversa: /opt/ linked to /home/ and /usr/local/bin/ linked to /opt/ejabberd/bin/
    • Include the ejabberdapi binary also in the ejabberd container image, as does ecs
    • Copy captcha scripts to immutable path /usr/local/bin/ for easy calling, and it&aposs included in $PATH
    • Copy sql files to /opt/ejabberd/database/sql/
    • Copy sql also to /opt/ejabberd/database/ for backwards compatibility with ecs
    • Link path to Mnesia spool dir for backwards compatibility
    • CONTAINER.md now documents both images, as there are few differences. Also includes a comparison table

    Macros are used in the default ejabberd.yml configuration files to define host, admin account and port numbers. This way you can overwrite any of them at starttime using environment variables :

         env:
         - name: PORT_HTTP_TLS
           value: 5444
    

    If you use the podman-desktop or docker-desktop applications, you may have noticed they show a button named "Open Browser". When you click that button, it opens a web browser with / URL and the lowest exposed port number. Now the default ejabberd.yml configuration file listens in port number 1880, the lowest of all, so the "Open Browser" button will open directly the ejabberd WebAdmin page.

    ejabberd container image: admin account

    In the ejabberd container image, you can grant admin rights to an account using the EJABBERD_MACRO_ADMIN environment variable. Additionally, if you set the REGISTER_ADMIN_PASSWORD environment variable, that account is automatically registered.

    Example kubernetes yaml file in podman:

         env:
         - name: EJABBERD_MACRO_ADMIN
           value: administrator@example.org
         - name: REGISTER_ADMIN_PASSWORD
           value: somePass0rd
    

    When those environment variables are not set, admin rights are granted to a random account name in the default ejabberd.yml .

    Alternatively, this can be done with the existing CTL_ON_CREATE variable, and then you would need to modify ejabberd.yml accordingly:

         env:
         - name: CTL_ON_CREATE
           value: register administrator example.org somePass0rd
    

    Unix Domain Socket: Relative path

    There are several minor improvements in the Unix Domain Socket support, the most notable being support for socket relative path: if the port option is set to "unix:directory/filename" without absolute path, then the directory and file are created in the Mnesia spool directory.

    Privileged Entity Bugfixes

    Two bugs related to XEP-0356: Privileged Entity have been solved:

    Don&apost rewrite "self-addressed" privileged IQs as results

    process_privilege_iq is meant to rewrite the result of a privileged IQ into the forwarded form required by XEP-0356 so it can be routed back to the original privileged requester. It checks whether the impersonated JID ( ReplacedJid ) of the original request matches the recipient of the IQ being processed to determine if this is a response to a privileged IQ (assuming it has privileged-IQ metadata attached).

    Unfortunately, it doesn&apost check the packet type, and this check will also match a privileged-IQ request that is being sent to the same user that&aposs being impersonated. This results in the request itself being rewritten and forwarded back to the sending component, instead of being processed and having the result send back.

    Instead, just check for IQ results (either a regular result or an error), and as long as it is marked as being a response to a privileged-IQ, always rewrite it and forward it to the sending component. There&aposs no circumstance under which we shouldn&apost forward a privileged-IQ response, so we don&apost need to be tricky about checking whether impersonated-user and recipient match.

    Accept non-privileged IQs from privileged components

    mod_privilege current drops any non-privileged IQ received from a component with an error about it not being properly wrapped. While this might represent a mistake on the part of the component, it means that well- behaved components can no longer send non-privileged IQs (something they normally can do if mod_privilege isn&apost enabled).

    Since mod_privilege is intended to grant additional permissions, and not remove existing ones, route non-privileged IQs received from the component normally.

    This also removes the special-case for roster-query IQ stanzas, since those are also non-privileged and will be routed along with any other non-privileged IQ packet. This mirrors the privileged-IQ/everything-else structure of the XEP, which defined the handling of privileged IQ stanzas and leaves all other IQ stanzas as defined in their own specs.

    To make this clearer, the predicate function now returns distinct results indicating privileged IQs, non-privileged IQs, and error conditions, rather than treating non-privilege IQs as an error that gets handled by routing the packet normally.

    mod_muc_occupantid: Enable in the default configuration

    mod_muc_occupantid was added to the list of modules enabled in the sample configuration file ejabberd.yml.example .

    It&aposs not necessarily obvious that it&aposs required for using certain modern features in group chat, and there&aposs no downside in activating this module.

    mod_http_api returns sorted list elements

    When mod_http_api returns a list of elements, now those elements are sorted alphabetically. If it is a list of tuples, the tuples are sorted alphabetically by the first element in that tuple.

    Notice that the new module mod_adhoc_api uses internally mod_http_api to format the API command arguments and result, this means that mod_adhoc_api benefits from this feature too.

    create_room_with_opts API command separators

    One of the arguments accepted by the create_room_with_opts API command is a list of room options, expressed as tuples of option name and option value. And some room option values are also list of tuples! This is the case of affiliations and subscribers .

    That is not a problem for API frontends that accept structured arguments like mod_http_api and ejabberd_xmlrpc . But this is a problem in ejabberdctl , mod_adhoc_api and WebAdmin, because they don&apost use structured arguments, and instead separate list elements with , and tuple elements with : . In that case, a list of tuples of list of tuples cannot be parsed correctly if all them use the same separators.

    Solution: when using the create_room_with_opts command to set affiliations and subscribers options:

    • list elements were separated with , and now should be with ;
    • tuple elements were separated with : and now should be with =

    All the previous separators are still supported for backwards compatibility, but please use the new recommended separators, specially if using ejabberdctl , mod_adhoc_api and WebAdmin.

    Let&aposs see side by side the old and the new recommended syntax:

    affiliations:owner:user1@localhost,member:user2@localhost
    affiliations:owner=user1@localhost;member=user2@localhost
    

    In a practical example, instead of this (which didn&apost work at all):

    ejabberdctl \
      create_room_with_opts \
      room_old_separators \
      conference.localhost \
      localhost \
      "persistent:true,affiliations:owner:user1@localhost,member:user2@localhost"
    

    please use:

    ejabberdctl \
      create_room_with_opts \
      room_new_separators \
      conference.localhost \
      localhost \
      "persistent:true,affiliations:owner=user1@localhost;member=user2@localhost"
    

    Notice that both the old and new separators are supported by create_room_with_opts . For example, let&aposs use curl to query mod_http_api :

    curl -k -X POST -H "Content-type: application/json" \
         "http://localhost:5280/api/create_room_with_opts" \
         -d &apos{"name": "room_old_separators",
              "service": "conference.localhost",
              "host": "localhost",
              "options": [
               {"name": "persistent",
                "value": "true"},
               {"name": "affiliations",
                "value": "owner:user1@localhost,member:user2@localhost"}
              ]
             }&apos
    
    curl -k -X POST -H "Content-type: application/json" \
         "http://localhost:5280/api/create_room_with_opts" \
         -d &apos{"name": "room_new_separators",
              "service": "conference.localhost",
              "host": "localhost",
              "options": [
               {"name": "persistent",
                "value": "true"},
               {"name": "affiliations",
                "value": "owner=user1@localhost;member=user2@localhost"}
              ]
             }&apos
    

    New API commands to change Mnesia table storage

    There are two new API commands: mnesia_list_tables and mnesia_table_change_storage .

    In fact those commands were already implemented since ejabberd 24.06, but they were tagged as internal as they were only used by WebAdmin. Now they are available for any API frontend, including mod_adhoc_api .

    Erlang/OTP and Elixir versions support

    Let&aposs review the supported Erlang/OTP versions:

    • Erlang/OTP 20.0 up to 24.3 are discouraged: ejabberd 25.03 is the last ejabberd release that fully supports those old erlang versions. If you are still using any of them, please upgrade it before the next ejabberd release.

    • Erlang/OTP 25.0 up to 27.3 are the recommended versions. For example Erlang/OTP 27.3 is used in the ejabberd binary installers and ejabberd container image.

    • Erlang/OTP 28.0-rc2 is mostly supported, but not yet recommended for production deployments.

    Regarding Elixir supported versions:

    • Elixir 1.10.3 up to 1.12.3 are discouraged: ejabberd compilation is not tested with those old Elixir versions.

    • Elixir 1.13.4 up to 1.18.3 are the recommended versions; for instance Elixir 1.18.3 is used in the ejabberd binary installers and container images.

    Acknowledgments

    We would like to thank the contributions to the source code, documentation, and translation provided for this release by:

    And also to all the people contributing in the ejabberd chatroom, issue tracker...

    Improvements in ejabberd Business Edition

    Customers of the ejabberd Business Edition , in addition to all those improvements and bugfixes, also get the floowing fixes

    • Fix mod_unread with s2s messages
    • Fix logic detecting duplicate pushes to not trigger pushes on other backends
    • Fix issue with connection to Apple push servers for APNS delivery
    • Fix server_info commands when a cluster node is not available

    ChangeLog

    This is a more detailed list of changes in this ejabberd release:

    Commands API

    • ejabberdctl : New option CTL_OVER_HTTP ( #4340 )
    • ejabberd_web_admin : Support commands with tuple arguments
    • mod_adhoc_api : New module to execute API Commands using Ad-Hoc Commands ( #4357 )
    • mod_http_api : Sort list elements in a command result
    • Show warning when registering command with an existing name
    • Fix commands unregistration
    • change_room_option : Add forgotten support to set enable_hats room option
    • change_room_option : Verify room option value before setting it ( #4337 )
    • create_room_with_opts : Recommend using ; and = separators
    • list_cluster_detailed : Fix crash when a node is down
    • mnesia_list_tables : Allow using this internal command
    • mnesia_table_change_storage : Allow using this internal command
    • status : Separate command result with newline
    • update_sql : Fix updating tables created by ejabberd internally
    • update_sql : Fix MySQL support

    Configuration

    • acl : Fix bug matching the acl shared_group: NAME
    • define_keyword : New option to define keywords ( #4350 )
    • define_macro : Add option to globals() because it&aposs useless inside host_config
    • ejabberd.yml.example : Enable mod_muc_occupantid by default
    • Add support to use keywords in toplevel, listener and modules
    • Show warning also when deprecated listener option is set as disabled ( #4345 )

    Container

    • Bump versions to Erlang/OTP 27.3 and Elixir 1.18.3
    • Add ERL_FLAGS to compile elixir on qemu cross-platform
    • Copy files to stable path, add ecs backwards compatibility
    • Fix warning about relative workdir
    • Improve entrypoint script: register account, or set random
    • Link path to Mnesia spool dir for backwards compatibility
    • Place sockets/ outside database/
    • Use again direct METHOD, qemu got fixed ( #4280 )
    • ejabberd.yml.example : Copy main example configuration file
    • ejabberd.yml.example : Define and use macros in the default configuration file
    • ejabberd.yml.example : Enable CTL_OVER_HTTP by default
    • ejabberd.yml.example : Listen for webadmin in a port number lower than any other
    • ejabberdapi : Compile during build
    • CONTAINER.md : Include documentation for ecs container image

    Core and Modules

    • ejabberd_auth : Add support for auth_stored_password_types
    • ejabberd_router : Don&apost rewrite "self-addressed" privileged IQs as results ( #4348 )
    • misc : Fix json version of json_encode_with_kv_list for nested kv lists ( #4338 )
    • OAuth: Fix crashes when oauth is feed with invalid jid ( #4355 )
    • PubSub: Bubble up db errors in nodetree_tree_sql:set_node
    • mod_configure : Add option access to let configure the access name
    • mod_mix_pam : Remove Channels roster group of mix channels ( #4297 )
    • mod_muc : Document MUC room option vcard_xupdate
    • mod_privilege : Accept non-privileged IQs from privileged components ( #4341 )
    • mod_private : Improve exception handling
    • mod_private : Don&apost warn on conversion errors
    • mod_private : Handle invalid PEP-native bookmarks
    • mod_private : Don&apost crash on invalid bookmarks
    • mod_s2s_bidi : Stop processing other handlers in s2s_in_handle_info ( #4344 )
    • mod_s2s_bidi : Fix issue with wrong namespace

    Dependencies

    • ex_doc : Bump to 0.37.2
    • stringprep : Bump to 1.0.31
    • provider_asn1 : Bump to 0.4.1
    • xmpp Bump to bring fix for ssdp hash calculation
    • xmpp Bump to get support for webchat_url ( #3041 )
    • xmpp Bump to get XEP-0317 Hats namespaces version 0.2.0
    • xmpp Bump to bring SSDP to XEP version 0.4
    • yconf Bump to support macro inside string

    Development and Testing

    • mix.exs : Keep debug info when building dev release
    • mix.exs : The ex_doc dependency is only relevant for the edoc Mix environment
    • ext_mod : add $libdir/include to include path
    • ext_mod : fix greedy include path ( #4359 )
    • gen_mod : Support registering commands and hook_subscribe in start/2 result
    • c2s_handle_bind : New event in ejabberd_c2s ( #4356 )
    • muc_disco_info_extras : New event mod_muc_room useful for mod_muc_webchat_url ( #3041 )
    • VSCode: Fix compiling support
    • Add tests for config features define_macro and define_keyword
    • Allow test to run using ct_run
    • Fixes to handle re-running test after update_sql
    • Uninstall mod_example when the tests has finished

    Documentation

    • Add XEPs that are indirectly supported and required by XEP-0479
    • Document that XEP-0474 0.4.0 was recently upgraded
    • Don&apost use backtick quotes for ejabberd name
    • Fix values allowed in db_type of mod_auth_fast documentation
    • Reword explanation about ACL names and definitions
    • Update moved or broken URLs in documentation

    Installers

    • Bump Erlang/OTP 27.3 and Elixir 1.18.3
    • Bump OpenSSL 3.4.1
    • Bump crosstool-NG 1.27.0
    • Fix building Termcap and Linux-PAM

    Matrix Gateway

    • Preserve XMPP message IDs in Matrix rooms
    • Better Matrix room topic and room roles to MUC conversion, support room aliases in invites
    • Add muc#user element to presences and an initial empty subject
    • Fix gen_iq_handler:remove_iq_handler call
    • Properly handle IQ requests
    • Support Matrix room aliases
    • Fix handling of 3PI events

    Unix Domain Socket

    • Add support for socket relative path
    • Use /tmp for temporary socket, as path is restricted to 107 chars
    • Handle unix socket when logging remote client
    • When stopping listener, delete Unix Domain Socket file
    • get_auto_url option: Don&apost build auto URL if port is unix domain socket ( #4345 )

    Full Changelog

    https://github.com/processone/ejabberd/compare/24.12...25.03

    ejabberd 25.03 download & feedback

    As usual, the release is tagged in the Git source code repository on GitHub .

    The source package and installers are available in ejabberd Downloads page. To check the *.asc signature files, see How to verify ProcessOne downloads integrity .

    For convenience, there are alternative download locations like the ejabberd DEB/RPM Packages Repository and the GitHub Release / Tags .

    The ecs container image is available in docker.io/ejabberd/ecs and ghcr.io/processone/ecs . The alternative ejabberd container image is available in ghcr.io/processone/ejabberd .

    If you consider that you&aposve found a bug, please search or fill a bug report on GitHub Issues .

    • chevron_right

      Ignite Realtime Blog: It’s time for real interoperability. Let’s make it happen

      news.movim.eu / PlanetJabber • 28 March • 2 minutes

    When I explain to others what I do for a living, I often ask why it is that we are not surprised that one can use a Gmail account to send an email to someone who uses an Outlook account, yet many people fully accept that you can’t send a message to someone using WhatsApp from a Telegram account. We’re not surprised that we can use our phone to set up a call with someone who uses a different brand of phone (or is subscribed to a different provider), yet, for instant messaging, we find ourselves in a world of walled gardens.

    Walled gardens refer to ecosystems where companies control access to their platforms and restrict users’ ability to freely interact with other services, creating barriers that prevent open communication and fair competition.

    Recognizing this, legislation is slowly being put in place to improve things. The Digital Markets Act (DMA) is a regulatory framework established aimed at ensuring fair competition and improving the functioning of the digital economy. One of its primary objectives is to dismantle these walled gardens and promote messaging interoperability . The DMA seeks to break down barriers and ensure that users have more freedom to engage with different platforms and services, while also enabling interoperability between messaging services.

    Meta (of WhatsApp and Facebook fame) is designated as a “gatekeeper” under the DMA. This means that Meta holds a dominant position in the market, controlling key access points that can potentially limit competition or consumer choice. The act outlines various obligations that Meta must comply with to ensure a fairer and more open digital environment.

    The XMPP Standards Foundation is now publishing an Open Letter to Meta , to advocate for the adoption of XMPP for messaging interoperability. It argues that Meta’s proposal falls short: Meta’s current approach to interoperability, which relies on restrictive NDAs, proprietary APIs, and centralized control, is not true interoperability.

    The XSF argues that Meta should adopt XMPP (eXtensible Messaging and Presence Protocol), a proven, open standard that allows for true federation, decentralization, enhanced privacy, and scalability. XMPP enables seamless communication between different services, akin to email or phone networks. Meta has previously utilized XMPP for WhatsApp and Messenger and has embraced federation for other services, showing that adoption and implementation are not only achievable, but has already been proven to work.

    The XSF urges Meta to adopt XMPP for messaging interoperability to comply with the DMA and build a competitive, open messaging ecosystem. The XSF is ready to collaborate and evolve the protocol as needed.

    The Ignite Realtime community is based on the strength and flexibility offered by XMPP. Projects like Openfire, Smack, Pade and Spark are direct implementations of the XMPP protocol. We have firsthand witnessed the flexibility, reliability and maturity of the protocol, and have been successfully applying it for years, if not decades. We should therefore fully endorse the XSF’s call to action!

    It is time for real interoperability. Let’s make it happen!

    You can find the Open Letter of the XSF here: XMPP | Open Letter to Meta: Support True Messaging Interoperability with XMPP

    A accompanying technical briefing is also published: XMPP | Detailed technical briefing: The Case for XMPP – Why Meta Must Embrace True Messaging Interoperability

    For other release announcements and news follow us on Mastodon or X

    1 post - 1 participant

    Read full topic

    • wifi_tethering open_in_new

      This post is public

      discourse.igniterealtime.org /t/it-s-time-for-real-interoperability-let-s-make-it-happen/95342

    • chevron_right

      ProcessOne: Supporting XMPP Standard Foundation's open letter to Meta for true interop

      news.movim.eu / PlanetJabber • 28 March • 1 minute

    Supporting XMPP Standard Foundation's open letter to Meta for true interop

    The XMPP Standards Foundation (XSF) has published an open letter to Meta, asking them to support true messaging interoperability using the XMPP protocol.

    Meta had previously integrated this protocol, and WhatsApp was actually built on an XMPP-based server , and Meta has previously supported XMPP in Facebook Messenger, as explained in XSF&aposs technical briefing :

    A Call to Meta: Build Your Interoperability Stack on XMPP

    We at the XMPP Standards Foundation (XSF) urge Meta to build its interoperability framework on top of XMPP federation.

    If Threads can implement the Fediverse protocol, there is no reason why Meta cannot do the same with XMPP for Facebook Messenger and WhatsApp—especially since WhatsApp itself was originally built on XMPP.

    Why This Matters

    We support this initiative as it represents the best approach for genuine interoperability. The European Digital Markets Act (DMA) is specifically designed to break down walled gardens and enforce messaging interoperability across platforms.

    XMPP has played a crucial role in shaping the modern messaging landscape , and its success demonstrates that true interoperability is achievable across different platforms and services. It remains the most viable and battle-tested solution to meet interoperability requirements.

    As a free and open standard for building and deploying instant messaging systems , XMPP represents the ideal foundation for true messaging interoperability.

    Take Action to #FederateTheWorld

    Federation is the way to go! Learn more by reading the announcement on the XSF website , where they provide both the open letter and a detailed technical briefing explaining the reasoning behind this call to action.

    The XSF, as well as ProcessOne as a long time supporter, is ready to collaborate with Meta and continue to evolve the protocol to meet modern messaging needs.

    • wifi_tethering open_in_new

      This post is public

      www.process-one.net /blog/supporting-xmpp-standard-foundations-open-letter-to-meta-for-true-interop/

    • chevron_right

      Mathieu Pasquet: Poezio 0.15 / 0.15.1

      news.movim.eu / PlanetJabber • 28 March • 1 minute

    About three years since the last version, poezio 0.15 (and 0.15.1 to address a small packaging mishap, version numbers are cheap) was released yesterday!

    Poezio is a terminal-based XMPP client which aims to replicate the feeling of terminal-based IRC clients such as irssi or weechat; to this end, poezio originally only supported multi-user chats.

    Features

    Not a lot this time around… Maybe next time?

    • A new moderate plugin (for XEP-0425 moderation).
    • Better self-ping (through the use of the slixmpp now builtin XEP-0410 plugin).
    • Use the system CA store by default.
    • Add a Ctrl-↑ shortcut to run /correct on the last message.
    • Poezio benefits from the recent slixmpp improvements, which means it can now transparently use Direct TLS as well as StartTLS.

    Fixes

    • Duplicated first message in conversation/private tab.
    • The many "clone" users in a room roster when on a spotty connection.
    • Python 3.13 and 3.14 compatibility (plenty of deprecations and removals).
    • Plenty of type checking mistakes and minor bugs spotted by mypy and pylint.

    Removals

    • Only python 3.11 and up is supported (was: 3.7).
    • The OTR plugin has been removed.
    • The launch/update.sh have been heavily simplified to use the uv tool instead of custom logic. It will be updated in the future to be able to run on pipx too, as uv is not available on some platforms.
    • wifi_tethering open_in_new

      This post is public

      blog.mathieui.net /en/poezio-0-15.html

    • chevron_right

      Erlang Solutions: My Journey from Ruby to Elixir: Lessons from a Developer

      news.movim.eu / PlanetJabber • 27 March • 8 minutes

    Why I Looked Beyond Ruby

    For years, Ruby was my go-to language for building everything from small prototypes to full-fledged production apps. I fell in love with its elegance and expressiveness and how Ruby on Rails could turn an idea into a working web app in record time. The community—with its focus on kindness and collaboration—only deepened my appreciation. In short, Ruby felt like home.

    But as my projects grew in complexity, I started running into bottlenecks. I had apps requiring real-time features, massive concurrency, and high availability. Scaling them with Ruby often meant juggling multiple processes, external services, or creative threading approaches—all of which worked but never felt truly seamless. That’s when I stumbled upon Elixir.

    At first glance, Elixir’s syntax reminded me of Ruby. It looked approachable and developer-friendly. But beneath the surface lies a fundamentally different philosophy, heavily influenced by Erlang’s functional model and the concurrency power of the BEAM. Moving from Ruby’s object-oriented approach to Elixir’s functional core was eye-opening. Here’s how I made that transition and why I think it’s worth considering if you’re a fellow Rubyist.

    The Mindset Shift: From Objects to Functions

    Life Before: Classes and Objects

    In Ruby, I approached problems by modeling them as classes, bundling data and behavior together. It was second nature to create an @name instance variable in an initializer, mutate it, and rely on inheritance or modules to share behavior. This style allowed me to write expressive code, but it also hid state changes behind class boundaries.

    A New Paradigm in Elixir

    Elixir flips that script. Data is immutable, and functions are the stars of the show. Instead of objects, I have modules that hold pure functions. Instead of inheritance, I rely on composition and pattern matching. This required me to unlearn some habits.

    • No more hidden state : Every function receives data as input and returns a new copy of that data, so you always know where transformations happen.

    No more deep class hierarchies : In Elixir, code sharing happens via modules and function imports rather than extending base classes.

    Example: Refactoring a Class into a Module

    Ruby

    class Greeter
      def initialize(name)
        @name = name
      end
    
      def greet
        "Hello, #{@name}!"
      end
    end
    
    greeter = Greeter.new("Ruby")
    puts greeter.greet  # => "Hello, Ruby!"
    

    Elixir

    defmodule Greeter do
    
      def greet(name), do: "Hello, #{name}!"
    
    end
    IO.puts Greeter.greet("Elixir")  # => "Hello, Elixir!"
    

    At first, I missed the idea of storing state inside an object, but soon realized how clean and predictable code can be when data and functions are separated. Immutability drastically cut down on side effects, which in turn cut down on surprises.

    Concurrency: Learning to Trust Processes

    Ruby’s approach

    Ruby concurrency typically means spinning up multiple processes or using multi-threading for IO-bound tasks. If you need to queue background jobs, gems like Sidekiq step in. Sidekiq runs in its own OS processes, separate from the main web server, and these processes can run on multiple cores for true parallelism. This approach is straightforward but often demands more memory and additional infrastructure for scaling.

    On the plus side, Ruby can handle many simultaneous web requests if they’re primarily IO-bound (such as database queries). Even with the Global Interpreter Lock (GIL) limiting the parallel execution of pure Ruby code, IO tasks can still interleave, allowing a single OS process to serve multiple requests concurrently.

    Elixir and the BEAM

    Elixir, on the other hand, was built for concurrency from the ground up, thanks to the BEAM virtual machine. It uses lightweight processes (not OS processes or threads) that are cheap to create and easy to isolate. These processes don’t share memory but communicate via message passing—meaning a crash in one process won’t cascade.

    This design was a game-changer for me: I no longer needed to layer so many external tools just to achieve scalable concurrency. When the language itself embraces concurrency, writing fault-tolerant, parallel code becomes second nature.

    Example: Background Jobs

    Ruby ( Sidekiq )

    class UserSyncJob
      include Sidekiq::Worker
    
      # This job fetches user data from an external API
      # and updates the local database.
      def perform(user_id)
        begin
          # 1. Fetch data from external service
          external_data = ExternalApi.get_user_data(user_id)
    
          # 2. Update local DB (pseudo-code)
          user = User.find(user_id)
          user.update(
            name: external_data[:name],
            email: external_data[:email]
          )
    
          puts "Successfully synced user #{user_id}"
        rescue => e
          # If something goes wrong, Sidekiq can retry
          # automatically, or we can log the error.
          puts "Error syncing user #{user_id}: #{e.message}"
        end
      end
    end
    
    # Trigger the job asynchronously:
    UserSyncJob.perform_async(42)
    
    

    Elixir ( GenServer )

    defmodule UserSyncServer do
      use GenServer
    
      # We'll store a simple state map for demonstration.
      def start_link(_opts) do
        GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
      end
    
      @impl true
      def init(state), do: {:ok, state}
    
      # Public API to sync a user:
      def sync_user(user_id) do
        GenServer.call(__MODULE__, {:sync, user_id})
      end
    
      @impl true
      def handle_call({:sync, user_id}, _from, state) do
        # 1. Fetch data from external API
        case ExternalApi.get_user_data(user_id) do
          {:ok, external_data} ->
            # 2. Update local DB
            user = MyApp.Repo.get(User, user_id)
            MyApp.Repo.update!(User.changeset(user, %{
              name: external_data.name,
              email: external_data.email
            }))
            IO.puts("Successfully synced user #{user_id}")
    
          {:error, reason} ->
            IO.puts("Error syncing user #{user_id}: #{reason}")
        end
    
        {:reply, :ok, state}
      end
    end
    
    # Start the GenServer somewhere in your supervision tree:
    {:ok, _pid} = UserSyncServer.start_link(%{})
    
    # Call the sync_user function to process the job:
    UserSyncServer.sync_user(42)
    
    

    No extra dependencies or external queue systems are needed; Elixir’s native process model just handles it.

    Debugging and Fault Tolerance: A New Perspective

    Catching Exceptions in Ruby

    Error handling in Ruby typically involves begin/rescue blocks. If a critical background job crashes, I might rely on Sidekiq’s retry logic or external monitoring. It worked, but I always worried about a missed exception bringing down crucial parts of the app.

    Supervision Trees in Elixir

    Elixir uses a concept called a supervision tree , inherited from Erlang’s OTP. Supervisors watch over processes, restarting them automatically if they crash. At first, I found it odd to let a process crash on purpose instead of rescuing the error. But once I saw how quickly the supervisor restarted a failed process, I was hooked.

    defmodule Worker do
      use GenServer
    
      def start_link(_) do
    	GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
      end
    
      def init(_), do: {:ok, %{}}
    
      def handle_call(:risky, _from, state) do
        raise "Something went wrong"
        {:reply, :ok, state}
      end
    end
    
    defmodule SupervisorTree do
      use Supervisor
    
      def start_link(_) do
        Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
      end
    
      def init(:ok) do
        children = [
          {Worker, []}
        ]
        Supervisor.init(children, strategy: :one_for_one)
      end
    end
    
    

    Now, if Worker crashes, the supervisor restarts it automatically. No manual intervention, no separate monitoring service, and no global meltdown.

    LiveView: A Game-Changer for Web Development

    Why I Loved Rails

    Rails made it trivial to spin up CRUD apps, handle migrations, and integrate with robust testing tools like RSpec. But building real-time interactions (like chat or real-time dashboards) could be tricky without relying heavily on JavaScript frameworks or ActionCable .

    Phoenix + LiveView

    Elixir’s Phoenix framework parallels Rails in many ways: fast bootstrapping, a clear folder structure, and strong conventions. But Phoenix Channels and LiveView push it even further. With LiveView, I can build highly interactive, real-time features that update the DOM via websockets—all without a dedicated front-end framework.


    Elixir (Phoenix LiveView)

    defmodule ChatLive do
      use Phoenix.LiveView
    
      def mount(_params, _session, socket) do
        {:ok, assign(socket, :messages, [])}
      end
    
      def handle_event("send", %{"message" => msg}, socket) do
        {:noreply, update(socket, :messages, fn msgs -> msgs ++ [msg] end)}
      end
    
      def render(assigns) do
        ~H"""
        <h1>Chat</h1>
        <ul>
          <%= for msg <- @messages do %>
            <li><%= msg %></li>
          <% end %>
        </ul>
    
        <form phx-submit="send">
          <input type="text" name="message" placeholder="Type something"/>
          <button type="submit">Send</button>
        </form>
        """
      end
    end
    
    

    This simple LiveView code handles real-time chat updates directly from the server, minimising the JavaScript I need to write. The reactive UI is all done through server-rendered updates.

    My Takeaways

    Embracing Immutability

    At first, it was tough to break free from the habit of mutating data in place. But once I got comfortable returning new data structures, my code became far more predictable. I stopped chasing side effects and race conditions.

    Let It Crash

    Ruby taught me to rescue and recover from every possible error. Elixir taught me to trust the supervisor process. This “let it crash” philosophy took some getting used to, but it simplifies error handling significantly.

    Less JavaScript, More Productivity

    LiveView drastically cut down my front-end overhead. I don’t need a full client framework for real-time updates. Seeing how quickly I could build a proof-of-concept live chat convinced me that Elixir was onto something big.

    Still Love Ruby

    None of this means I dislike Ruby. I still think Rails is fantastic for many use cases, especially when you need to prototype something quickly or build a classic CRUD app. Ruby fosters a developer-friendly environment that many languages can only aspire to. I simply reached a point where concurrency and fault tolerance became a top priority—and that’s where Elixir really shines.

    Final Advice for Rubyists Curious About Elixir

    1. Start Small : Experiment with a tiny service or background job. Don’t rewrite your entire monolith on day one.
    2. Get Comfortable with Functional Concepts : Embrace immutability and pattern matching. The mental shift is real, but it pays off.
    3. Check Out Phoenix and LiveView : If you’re doing web dev, see how your typical Rails flow translates in Phoenix. And definitely try LiveView.
    4. Utilise Existing Ruby Skills : Your understanding of test-driven development, domain modeling, and code readability all carry over—you’ll just write them differently.

    Ultimately, if you’re running into the same scaling or concurrency issues I did, Elixir might just be the upgrade you need. It brings a breath of fresh air to large-scale, real-time, and fault-tolerant applications while keeping developer happiness front and center. For me, it was worth the leap, and I haven’t looked back since. If you’re looking for a detailed comparison of Elixir and Ruby, our comprehensive Elixir vs. Ruby guide has you covered.

    The post My Journey from Ruby to Elixir: Lessons from a Developer appeared first on Erlang Solutions .

    • wifi_tethering open_in_new

      This post is public

      www.erlang-solutions.com /blog/my-journey-from-ruby-to-elixir-lessons-from-a-developer/

    • chevron_right

      The XMPP Standards Foundation: Open Letter to Meta: Support True Messaging Interoperability with XMPP

      news.movim.eu / PlanetJabber • 27 March • 1 minute

    It has been a little over a year since Meta announced their proposal for third-parties to achieve messaging interoperability with WhatsApp, with Facebook Messenger following half a year later. Not for everyone, and only because these services were designated as Gate Keepers under the recent Digital Markets Act (DMA) in the EU. So only in the EU, and then with many strings attached. In that time, a lot has been written. Element/Matrix have put in efforts to work with Meta to get some interoperability going. Unfortunately, the reference offers don’t provide what we would call true interoperability, and given that virtually nobody has taken up Meta on this offer, their proposal just falls short across the board.

    Over at the IETF, the More Instant Messaging Interoperability (MIMI) working group is working on mechanisms for interoperability. While several of our members are involved with MIMI and working on the implementation of the related MLS protocol for end-to-end encryption, we believe it is time to have true interoperability using a well-tested and widely implemented set of standards: XMPP.

    To that end, we today publish an Open Letter to Meta . A call to action, urging Meta to adopt XMPP for messaging interoperability. For a more in-depth reasoning, we also provide a detailed technical briefing .

    We are ready. Let’s make it happen.

    • wifi_tethering open_in_new

      This post is public

      xmpp.org /2025/03/open-letter-to-meta-support-true-messaging-interoperability-with-xmpp/

    • chevron_right

      Mathieu Pasquet: slixmpp v1.10

      news.movim.eu / PlanetJabber • 26 March • 2 minutes

    This new version does not have many new features, but it has quite a few breaking changes, which should not impact many people, as well as one important security fix.

    Thanks to everyone who contributed with code, issues, suggestions, and reviews!

    Security

    After working on TLS stuff, I noticed that we still allowed unencrypted SCRAM to be negociated, which is really not good. For packagers who only want this security fix, the commit fd66aef38d48b6474654cbe87464d7d416d6a5f3 should apply cleanly on any slixmpp version.

    (most servers in the wild have unencrypted connections entirely disabled, so this is only an issue for Man in the Middle attacks)

    Enhancements

    • slixmpp now supports XEP-0368 and allows to choose easily between direct TLS, or STARTTLS.

    Breaking Changes

    • The security issue mentioned above is a breaking change if you actively want to connect to servers without encryption. If that is a desired behavior, you can still set xmpp['feature_mechanisms'].unencrypted_scram = True on init.

    • Removal of the timeout_callback parameter anywhere it was present. Users are encouraged to await on the coroutine or the future returned by the function, which will raise an IqTimeout exception when appropriate.

    • Removal of the custom google plugins, which I am guessing have not worked in a very long time (both the google and gmail_notify plugin).

    • Removal of the Stream Compression ( XEP-0138 ) plugin. It was not working at all and use of compression is actively discouraged for security reasons .

    • Due to the new connection code, the configuration of the connection parameters has changed quite a bit:

      • The XMLStream (from which inherits the ClientXMPP class) does not have a use_ssl parameter anymore. Instead it has enable_direct_tls and enable_starttls as well as enable_plaintext attributes. Those attributes control whether we want to connect using starttls or direct TLS. The plaintext is for components since we only implement the jabber component protocol ( XEP-0114 ).
      • Handling of custom addresses has changed a bit, now they are set through calling connect() , and kept until connect() is called without arguments again.
      • The DNS code will now fetch both xmpps-client and xmpp-client records (unless direct TLS is explicitly disabled) and prefer direct TLS if it has the same priority as STARTTLS.
      • The SRV targeted by the queries can be customized using the tls_services and starttls_services of ClientXMPP (but have no idea why anyone would do this)

    Fixes

    • Another issue encountered with the Rust JID, trying to compare a JID against strings that cannot be parsed or other objects would raise an InvalidJID exception instead of returning False .
    • The ssl_cert event would only be invoked on STARTTLS.
    • One of the asyncio warnings on program exit (that a coroutine is still running).
    • Traceback with BaseXMPP.get .
    • A potential edge case in the disco ( XEP-0030 ) plugin when using strings instead of JIDs.
    • A traceback in vcard-temp ( XEP-0054 ) and Legacy Delayed Delivery ( XEP-0091 ) when parsing datetimes.
    • A traceback when manipulating conditions in feature mechanisms.
    • A traceback in Ad-hoc commands ( XEP-0050 ) during error handling.
    • Many tracebacks in OAuth over XMPP ( XEP-0235 ) due to urllib API changes.

    Links

    You can find the new release on codeberg , pypi , or the distributions that package it in a short while.

    • wifi_tethering open_in_new

      This post is public

      blog.mathieui.net /en/slixmpp-1.10.html

    • chevron_right

      Kaidan: Kaidan 0.12.0: User Interface Polishing and Account Migration Fixes

      news.movim.eu / PlanetJabber • 20 March • 1 minute

    Kaidan 0.12.0 looks and behaves better than ever before! Chats can now quickly be pinned and moved. In addition, the list of group chat participants to mention them is placed above the cursor if enough space is available. With this release, OMEMO can be used right after migrating an account and migrated contacts are correctly verified.

    Have a look at the changelog for more details.

    Changelog

    Features:

    • Use square selection to crop avatars (fazevedo)
    • Use background with rounded corners for chat list items (melvo)
    • Remove colored availability indicator from chat list item (melvo)
    • Display group chat participant picker above text cursor in large windows (melvo)
    • Do not allow to enter/send messages without visible characters (melvo)
    • Remove leading/trailing whitespace from exchanged messages (melvo)
    • Ignore received messages without displayable content if they cannot be otherwise processed (melvo)
    • Allow to show/hide buttons to pin/move chat list items (melvo)

    Bugfixes:

    • Fix style for Flatpak (melvo)
    • Fix displaying video thumbnails and opening files for Flatpak (melvo)
    • Fix message reaction details not opening a second time (melvo)
    • Fix opening contact addition view on receiving XMPP URIs (melvo)
    • Fix format of text following emojis (melvo)
    • Fix eliding last message text for chat list item (melvo)
    • Fix unit tests (mlaurent, fazevedo, melvo)
    • Fix storing downloaded files with unique names (melvo)
    • Fix overlay to change/open avatars shown before hovered in account/contact details (melvo)
    • Fix verification of moved contacts (fazevedo)
    • Fix setting up end-to-end encryption (OMEMO 2) after account migration (melvo)

    Notes:

    • Kaidan requires KWindowSystem and KDSingleApplication now (mlaurent)
    • Kaidan requires KDE Frameworks 6.11 now
    • Kaidan requires KQuickImageEditor 0.5 now
    • Kaidan requires QXmpp 1.10.3 now

    Download

    Or install Kaidan for your distribution:

    Packaging status

    • wifi_tethering open_in_new

      This post is public

      kaidan.im /2025/03/21/kaidan-0.12.0/

    • chevron_right

      Erlang Solutions: Meet the team: Lorena Mireles

      news.movim.eu / PlanetJabber • 20 March • 3 minutes

    Lorena Mireles is an influential force in the BEAM community, known for her work as an Elixir developer and as a dedicated member of the Code BEAM America programme committee. She’s been instrumental in fostering connections and shaping discussions that help drive the future of Elixir.

    In this interview, Lorena opens up about her journey with Elixir, her role on the committee, and what makes the BEAM community so unique.

    Meet the team: Lorena Mireles

    What first drew you to Elixir, and what keeps you hooked?

    The community was, without a doubt, the first reason I became interested in Elixir. I had no prior knowledge of Elixir the first time I attended a conference, but I felt very comfortable at the talks. The explanations were clear and interesting, which motivated me to investigate the programming language further.

    Also, everyone was very kind and willing to share their knowledge. Over time, I discovered the advantages of this programming language for designing powerful systems. I’m still amazed at how easy it is to create projects with complex technical requirements, all thanks to the way Elixir and BEAM were created, and all the material available to learn about them.

    How did you get involved with the Code BEAM America committee, and what’s that experience been like?

    I joined the committee at the invitation of the organisers, and I’m very grateful, as I’ve been a part of it for three consecutive editions, and I continue to learn and be surprised each time.

    My work focuses primarily on promoting women’s participation at the conference and supporting the diversity program, which has allowed me to meet great women and learn about their projects and experiences. Overall, it’s a great opportunity to get to know the speakers a little better and get involved in the BEAM community.

    I also learn about new topics, as seeing the talks they submit also motivates me to explore them.

    What were your standout moments from this year’s Code BEAM America?

    I’ll start with my favorite- reconnecting with the BEAM community. I admire so many people and their work, so Code BEAM America was a great experience to learn more about it. I also loved seeing the new speakers and first-time attendees. I chatted with some of them, and they loved the experience. It was great to get their feedback.

    The keynotes were also some of my favorites. Machine Learning and AI were discussed, which seemed very appropriate given the current relevance of these topics. There were also a couple of talks focused on social aspects, which are always necessary to foster continuous improvement in teams.

    What excites you most about the future of the BEAM community?

    All the projects that will likely be happening this year. At this year’s Code BEAM, I met new speakers and saw new attendees, which means the knowledge continues to expand and the community grows, and that also means new projects and more material about Elixir and BEAM in general.

    I’m excited to think about all the new things we’ll see and how we continue to encourage new people to participate because, without a doubt, Elixir is a programming language worth learning.

    Final thoughts

    Lorena’s experience with Elixir and her role in the BEAM community show just how powerful collaboration and innovation can be in shaping the ecosystem. Beyond that, her Women in BEAM survey and Women in Elixir webinar are amazing resources she’s put together to foster more inclusivity in the community.

    You can find her on social media channels below, so feel free to reach out and connect!

    The post Meet the team: Lorena Mireles appeared first on Erlang Solutions .